# HG changeset patch # User John W. Eaton # Date 1380986529 14400 # Node ID c702371ff6df692d02895450e92b9d98c5c92ef9 # Parent 20d1b911b4e78f4cf6c8222cd365e9c5243ef62f# Parent 387ecd448b30d69498bfc6fba3ef92ac8e94ffcb maint: periodic merge of default to classdef diff -r 20d1b911b4e7 -r c702371ff6df .hgsubstate --- a/.hgsubstate Thu Sep 12 21:08:07 2013 -0400 +++ b/.hgsubstate Sat Oct 05 11:22:09 2013 -0400 @@ -1,1 +1,1 @@ -5a51fb7777a9950502965a043a70bd6ca5e0498b gnulib-hg +6057744acd2c71c069a4b171c5fe1ff0d86c9e5f gnulib-hg diff -r 20d1b911b4e7 -r c702371ff6df .hgtags --- a/.hgtags Thu Sep 12 21:08:07 2013 -0400 +++ b/.hgtags Sat Oct 05 11:22:09 2013 -0400 @@ -78,3 +78,5 @@ b29b10fbb7448cdfe29322446e1a589e7fe1a40a release-3-6-4 4e50bd2946d8563d3e201cc04b3ba0720c991b06 ss-3-7-4 608e307b49149b32a6d09c2f06493d04d3af9be4 ss-3-7-5 +3a9efb68272df556dccb84c87933dd8238e88902 ss-3-7-6 +cc13924a4266fb0359f59fabdce11071e6051d48 ss-3-7-7 diff -r 20d1b911b4e7 -r c702371ff6df Makefile.am --- a/Makefile.am Thu Sep 12 21:08:07 2013 -0400 +++ b/Makefile.am Sat Oct 05 11:22:09 2013 -0400 @@ -42,7 +42,6 @@ bootstrap.conf \ build-aux/find-files-with-tests.sh \ build-aux/mk-opts.pl \ - build-aux/mkinstalldirs \ build-aux/move-if-change \ build-aux/OctJavaQry.class \ etc/NEWS.1 \ @@ -146,6 +145,10 @@ NEWS \ CITATION +doxyhtml: + $(MAKE) -C doc/doxyhtml doxyhtml +.PHONY: doxyhtml + DIRS_TO_MAKE = \ $(localfcnfiledir) \ $(localapifcnfiledir) \ diff -r 20d1b911b4e7 -r c702371ff6df NEWS --- a/NEWS Thu Sep 12 21:08:07 2013 -0400 +++ b/NEWS Sat Oct 05 11:22:09 2013 -0400 @@ -17,6 +17,16 @@ Summary of important user-visible changes for version 3.8: --------------------------------------------------------- + ** Octave now uses OpenGL graphics by default with FLTK widgets. If + OpenGL libraries or FLTK widgets are not available when Octave is + built, gnuplot is used. You may also choose to use gnuplot for + graphics by executing the command + + graphics_toolkit ("gnuplot") + + Adding this command to your ~/.octaverc file will set the default + for each session. + ** Octave now supports nested functions with scoping rules that are compatible with Matlab. A nested function is one declared and defined within the body of another function. The nested function is only @@ -43,6 +53,67 @@ endfunction endfunction + ** Line continuations inside character strings have changed. + + The sequence '...' is no longer recognized as a line continuation + inside a character string. A backslash '\' followed by a newline + character is no longer recognized as a line continuation inside + single-quoted character strings. Inside double-quoted character + strings, a backslash followed by a newline character is still + recognized as a line continuation, but the backslash character must + be followed *immediately* by the newline character. No whitespace or + end-of-line comment may appear between them. + + ** Backslash as a continuation marker outside of double-quoted strings + is now deprecated. + + Using '\' as a continuation marker outside of double quoted strings + is now deprecated and will be removed from a future version of + Octave. When that is done, the behavior of + + (a \ + b) + + will be consistent with other binary operators. + + ** Redundant terminal comma accepted by parser + + A redundant terminal comma is now accepted in matrix + definitions which allows writing code such as + + [a,... + b,... + c,... + ] = deal (1,2,3) + + ** Octave now has limited support for named exceptions + + The following syntax is now accepted: + + try + statements + catch exception-id + statements + end + + The exception-id is a structure with the fields "message" and + "identifier". For example + + try + error ("Octave:error-id", "error message"); + catch myerr + printf ("identifier: %s\n", myerr.identifier); + printf ("message: %s\n", myerr.message); + end_try_catch + + When classdef-style classes are added to Octave, the exception-id + will become an MException object. + + ** Warning IDs renamed: + + Octave:array-as-scalar => Octave:array-to-scalar + Octave:array-as-vector => Octave:array-to-vector + ** 'emptymatch', 'noemptymatch' options added to regular expressions. With this addition Octave now accepts the entire set of Matlab options @@ -67,20 +138,34 @@ expression would have searched for a literal '\' followed by 't' and replaced the two characters with the sequence '\', 'n'. - ** Redundant terminal comma accepted by parser + ** A TeX parser has been implemented for the FLTK toolkit and is the default + for any text object including titles and axis labels. The TeX parser is + supported only for display on a monitor, not for printing. - A redundant terminal comma is now accepted in matrix - definitions which allows writing code such as + A quick summary of features: - [a,... - b,... - c,... - ] = deal (1,2,3) + Code Feature Example Comment + ----------------------------------------------------------------- + _ subscript H_2O formula for water + ^ exponent y=x^2 formula for parabola + \char symbol \beta Greek symbol beta + \fontname font \fontname{Arial} set Arial font + \fontsize fontsize \fontsize{16} set fontsize 16 + \color[rgb] fontcolor \color[rgb]{1 0 1} set magenta color + \bf bold \bfBold Text bold font + \it italic \itItalic Text italic font + \sl slanted \slOblique Text slanted font + \rm normal \bfBold\rmNormal normal font + {} group {\bf Bold}Normal group objects + e^{i*\pi} = -1 complex example - ** Warning IDs renamed: + ** The m-files in the plot directory have been overhauled. - Octave:array-as-scalar => Octave:array-to-scalar - Octave:array-as-vector => Octave:array-to-vector + The plot functions now produce output that is nearly visually compatible + with Matlab. Plot performance has also increased, dramatically for some + functions such as comet and waitbar. Finally, the documentation for most + functions has been updated so it should be clearer both how to use a + function and when a function is appropriate. ** The m-files in the image directory have been overhauled. @@ -94,6 +179,28 @@ colormap depending on the image class (integer images have a -1 offset to the colormap row number). + ** The imread and imwrite functions have been completely rewritten. + + The main changes relate to the alpha channel, support for reading and + writing of floating point images, implemented writing of indexed images, + and appending images to multipage image files. + + The issues that may arise due to backwards incompatibility are: + + * imwrite no longer interprets a length of 2 or 4 in the third dimension + as grayscale or RGB with alpha channel (a length of 4 will be saved + as a CMYK image). Alpha channel must be passed as separate argument. + + * imread will always return the colormap indexes when reading an indexed + image, even if the colormap is not requested as output. + + * transparency values are now inverted from previous Octave versions + (0 is for completely transparent instead of completely opaque). + + In addition, the function imformats has been implemented to expand + reading and writing of images of different formats through imread + and imwrite. + ** The colormap function now provides new options--"list", "register", and "unregister"--to list all available colormap functions, and to add or remove a function name from the list of known colormap @@ -125,11 +232,11 @@ [1,2] = 3 } - (2) By default, Matlab treats consecutive delimiters are as a single + (2) By default, Matlab treats consecutive delimiters as a single delimiter. By default, Octave's legacy behavior was to return an empty string for the part between the delmiters. - Where the legacy behavior is desired, the call to strsplit() may be + Where legacy behavior is desired, the call to strsplit() may be replaced by ostrsplit(), which is Octave's original implementation of strsplit(). @@ -148,8 +255,13 @@ In addition two new error functions erfi (imaginary error function) and dawson (scaled imaginary error function) have been added. - ** The default name of the Octave crash dump file is now called - octave-workspace instead of octave-core. + ** The glpk function has been modified to reflect changes in the GLPK + library. The "round" and "itcnt" options have been removed. The + "relax" option has been replaced by the "rtest" option. The numeric + values of error codes and of some options have also changed. + + ** The default name of the Octave crash dump file is now + "octave-workspace" instead of "octave-core". ** A citation command has been added to display information on how to cite Octave and packages in publications. The package system will @@ -176,19 +288,23 @@ ** Other new functions added in 3.8.0: - base64_decode ellipke lines - base64_encode erfcinv polyeig - betaincinv erfi readline_re_read_init_file - built_in_docstrings_file expint readline_read_init_file - cmpermute findfigs rgbplot - cmunique fminsearch save_default_options - colorcube gallery shrinkfaces - copyobj gco splinefit - dawson hdl2struct stemleaf - dblist history_save strjoin - debug_jit importdata struct2hdl - doc_cache_create iscolormap tetramesh - ellipj jit_enable waterfall + atan2d erfi lines + base64_decode expint linsolve + base64_encode findfigs missing_component_hook + betaincinv flintmax polyeig + built_in_docstrings_file fminsearch prefdir + cmpermute gallery preferences + cmunique gco readline_re_read_init_file + colorcube hdl2struct readline_read_init_file + copyobj history_save rgbplot + dawson imformats save_default_options + dblist importdata shrinkfaces + debug_jit isaxes splinefit + desktop iscolormap stemleaf + doc_cache_create isequaln strjoin + ellipj jit_debug struct2hdl + ellipke jit_enable tetramesh + erfcinv jit_startcnt waterfall ** Deprecated functions. @@ -207,12 +323,13 @@ default_save_options java_set gen_doc_cache java_unsigned_conversion - java_convert_matrix javafields - java_debug javamethods - java_get re_read_readline_init_file - java_invoke read_readline_init_file - java_new saving_history - + isequalwithequalnans javafields + java_convert_matrix javamethods + java_debug re_read_readline_init_file + java_get read_readline_init_file + java_invoke saving_history + java_new + The following keywords have been deprecated in Octave 3.8 and will be removed from Octave 3.12 (or whatever version is the second major release after 3.8): @@ -226,6 +343,11 @@ CC_VERSION (now GCC_VERSION) CXX_VERSION (now GXX_VERSION) + The internal class has been deprecated in Octave 3.8 and will + be removed from Octave 3.12 (or whatever version is the second major + release after 3.8). Replacement classes are (struct array) + or for a single structure. + Summary of important user-visible changes for version 3.6: --------------------------------------------------------- diff -r 20d1b911b4e7 -r c702371ff6df bootstrap --- a/bootstrap Thu Sep 12 21:08:07 2013 -0400 +++ b/bootstrap Sat Oct 05 11:22:09 2013 -0400 @@ -1,10 +1,10 @@ #! /bin/sh # Print a version string. -scriptversion=2012-07-19.14; # UTC +scriptversion=2013-08-15.22; # UTC # Bootstrap this package from checked-out sources. -# Copyright (C) 2003-2012 Free Software Foundation, Inc. +# Copyright (C) 2003-2013 Free Software Foundation, Inc. # 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 @@ -140,20 +140,21 @@ "wget --mirror -nd -q -np -A.po -P '%s' \ http://translationproject.org/latest/%s/" +# Prefer a non-empty tarname (4th argument of AC_INIT if given), else +# fall back to the package name (1st argument with munging) extract_package_name=' - /^AC_INIT(/{ - /.*,.*,.*, */{ - s/// - s/[][]//g - s/)$// + /^AC_INIT(\[*/{ + s/// + /^[^,]*,[^,]*,[^,]*,[ []*\([^][ ,)]\)/{ + s//\1/ + s/[],)].*// p q } - s/AC_INIT(\[*// - s/]*,.*// + s/[],)].*// s/^GNU // y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ - s/[^A-Za-z0-9_]/-/g + s/[^abcdefghijklmnopqrstuvwxyz0123456789_]/-/g p } ' @@ -205,10 +206,8 @@ # default. bootstrap_sync=false -# Don't use git to update gnulib sources. We keep gnulib under a -# Mercurial subrepository instead -use_git=false -GNULIB_SRCDIR=gnulib-hg +# Use git to update gnulib sources +use_git=true # find_tool ENVVAR NAMES... # ------------------------- @@ -225,27 +224,21 @@ find_tool_names=$@ eval "find_tool_res=\$$find_tool_envvar" if test x"$find_tool_res" = x; then - for i - do + for i; do if ($i --version /dev/null 2>&1; then - find_tool_res=$i - break + find_tool_res=$i + break fi done - else - find_tool_error_prefix="\$$find_tool_envvar: " fi - test x"$find_tool_res" != x \ - || die "one of these is required: $find_tool_names" - ($find_tool_res --version /dev/null 2>&1 \ - || die "${find_tool_error_prefix}cannot run $find_tool_res --version" + if test x"$find_tool_res" = x; then + warn_ "one of these is required: $find_tool_names;" + die "alternatively set $find_tool_envvar to a compatible tool" + fi eval "$find_tool_envvar=\$find_tool_res" eval "export $find_tool_envvar" } -# Find sha1sum, named gsha1sum on MacPorts, and shasum on Mac OS X 10.6. -find_tool SHA1SUM sha1sum gsha1sum shasum - # Override the default configuration, if necessary. # Make sure that bootstrap.conf is sourced from the current directory # if we were invoked as "sh bootstrap". @@ -257,12 +250,12 @@ # Extra files from gnulib, which override files from other sources. test -z "${gnulib_extra_files}" && \ gnulib_extra_files=" - $build_aux/install-sh - $build_aux/mdate-sh - $build_aux/texinfo.tex - $build_aux/depcomp - $build_aux/config.guess - $build_aux/config.sub + build-aux/install-sh + build-aux/mdate-sh + build-aux/texinfo.tex + build-aux/depcomp + build-aux/config.guess + build-aux/config.sub doc/INSTALL " @@ -308,34 +301,34 @@ die "Bootstrapping from a non-checked-out distribution is risky." fi -# Ensure that lines starting with ! sort last, per gitignore conventions -# for whitelisting exceptions after a more generic blacklist pattern. -sort_patterns() { - sort -u "$@" | sed '/^!/ { - H - d - } - $ { - P - x - s/^\n// - }' | sed '/^$/d' +# Strip blank and comment lines to leave significant entries. +gitignore_entries() { + sed '/^#/d; /^$/d' "$@" } -# If $STR is not already on a line by itself in $FILE, insert it, -# sorting the new contents of the file and replacing $FILE with the result. -insert_sorted_if_absent() { +# If $STR is not already on a line by itself in $FILE, insert it at the start. +# Entries are inserted at the start of the ignore list to ensure existing +# entries starting with ! are not overridden. Such entries support +# whitelisting exceptions after a more generic blacklist pattern. +insert_if_absent() { file=$1 str=$2 test -f $file || touch $file - echo "$str" | sort_patterns - $file | cmp -s - $file > /dev/null \ - || { echo "$str" | sort_patterns - $file > $file.bak \ - && mv $file.bak $file; } \ - || die "insert_sorted_if_absent $file $str: failed" + test -r $file || die "Error: failed to read ignore file: $file" + duplicate_entries=$(gitignore_entries $file | sort | uniq -d) + if [ "$duplicate_entries" ] ; then + die "Error: Duplicate entries in $file: " $duplicate_entries + fi + linesold=$(gitignore_entries $file | wc -l) + linesnew=$( { echo "$str"; cat $file; } | gitignore_entries | sort -u | wc -l) + if [ $linesold != $linesnew ] ; then + { echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \ + || die "insert_if_absent $file $str: failed" + fi } # Adjust $PATTERN for $VC_IGNORE_FILE and insert it with -# insert_sorted_if_absent. +# insert_if_absent. insert_vc_ignore() { vc_ignore_file="$1" pattern="$2" @@ -346,7 +339,7 @@ # .gitignore entry. pattern=$(echo "$pattern" | sed s,^,/,);; esac - insert_sorted_if_absent "$vc_ignore_file" "$pattern" + insert_if_absent "$vc_ignore_file" "$pattern" } # Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac. @@ -470,7 +463,7 @@ if [ "$req_ver" = "-" ]; then # Merely require app to exist; not all prereq apps are well-behaved # so we have to rely on $? rather than get_version. - $app --version >/dev/null 2>&1 + $app --version >/dev/null 2>&1 /dev/null 2>/dev/null ; then +if $use_git && test -d .git && (git --version) >/dev/null 2>/dev/null ; then if git config merge.merge-changelog.driver >/dev/null ; then : elif (git-merge-changelog --version) >/dev/null 2>/dev/null ; then @@ -575,13 +574,17 @@ test -f .gitmodules && git config --file .gitmodules "$@" } -gnulib_path=$(git_modules_config submodule.gnulib.path) -test -z "$gnulib_path" && gnulib_path=gnulib +if $use_git; then + gnulib_path=$(git_modules_config submodule.gnulib.path) + test -z "$gnulib_path" && gnulib_path=gnulib +fi -# Get gnulib files. +# Get gnulib files. Populate $GNULIB_SRCDIR, possibly updating a +# submodule, for use in the rest of the script. case ${GNULIB_SRCDIR--} in -) + # Note that $use_git is necessarily true in this case. if git_modules_config submodule.gnulib.url >/dev/null; then echo "$0: getting gnulib files..." git submodule init || exit $? @@ -602,8 +605,8 @@ GNULIB_SRCDIR=$gnulib_path ;; *) - # Use GNULIB_SRCDIR as a reference. - if test -d "$GNULIB_SRCDIR"/.git && \ + # Use GNULIB_SRCDIR directly or as a reference. + if $use_git && test -d "$GNULIB_SRCDIR"/.git && \ git_modules_config submodule.gnulib.url >/dev/null; then echo "$0: getting gnulib files..." if git submodule -h|grep -- --reference > /dev/null; then @@ -629,12 +632,19 @@ ;; esac +# $GNULIB_SRCDIR now points to the version of gnulib to use, and +# we no longer need to use git or $gnulib_path below here. + if $bootstrap_sync; then cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || { echo "$0: updating bootstrap and restarting..." + case $(sh -c 'echo "$1"' -- a) in + a) ignored=--;; + *) ignored=ignored;; + esac exec sh -c \ 'cp "$1" "$2" && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \ - -- "$GNULIB_SRCDIR/build-aux/bootstrap" \ + $ignored "$GNULIB_SRCDIR/build-aux/bootstrap" \ "$0" "$@" --no-bootstrap-sync } fi @@ -682,11 +692,10 @@ cksum_file="$ref_po_dir/$po.s1" if ! test -f "$cksum_file" || ! test -f "$po_dir/$po.po" || - ! $SHA1SUM -c --status "$cksum_file" \ - < "$new_po" > /dev/null; then + ! $SHA1SUM -c "$cksum_file" < "$new_po" > /dev/null 2>&1; then echo "$me: updated $po_dir/$po.po..." cp "$new_po" "$po_dir/$po.po" \ - && $SHA1SUM < "$new_po" > "$cksum_file" + && $SHA1SUM < "$new_po" > "$cksum_file" || return fi done } @@ -891,20 +900,21 @@ -depth \( -name '*.m4' -o -name '*.[ch]' \) \ -type l -xtype l -delete > /dev/null 2>&1 +# Invoke autoreconf with --force --install to ensure upgrades of tools +# such as ylwrap. +AUTORECONFFLAGS="--verbose --install --force -I $m4_base $ACLOCAL_FLAGS" + # Some systems (RHEL 5) are using ancient autotools, for which the # --no-recursive option had not been invented. Detect that lack and # omit the option when it's not supported. FIXME in 2017: remove this # hack when RHEL 5 autotools are updated, or when they become irrelevant. -no_recursive= case $($AUTORECONF --help) in - *--no-recursive*) no_recursive=--no-recursive;; + *--no-recursive*) AUTORECONFFLAGS="$AUTORECONFFLAGS --no-recursive";; esac # Tell autoreconf not to invoke autopoint or libtoolize; they were run above. -echo "running: AUTOPOINT=true LIBTOOLIZE=true " \ - "$AUTORECONF --verbose --install $no_recursive -I $m4_base $ACLOCAL_FLAGS" -AUTOPOINT=true LIBTOOLIZE=true \ - $AUTORECONF --verbose --install $no_recursive -I $m4_base $ACLOCAL_FLAGS \ +echo "running: AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS" +AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS \ || die "autoreconf failed" # Get some extra files from gnulib, overriding existing files. diff -r 20d1b911b4e7 -r c702371ff6df bootstrap.conf --- a/bootstrap.conf Thu Sep 12 21:08:07 2013 -0400 +++ b/bootstrap.conf Sat Oct 05 11:22:09 2013 -0400 @@ -49,6 +49,7 @@ link lstat malloc-gnu + mbrtowc mkdir mkfifo mkostemp @@ -143,11 +144,14 @@ gnulib_name="libgnu" source_base="libgnu" -## Use --foreign since we auto-generate the AUTHORS file and the default -## --gnu strictness level doesn't like it if the AUTHORS file is missing. +# Don't use git to update gnulib sources. We keep gnulib under a +# Mercurial subrepository instead. +use_git=false +GNULIB_SRCDIR=gnulib-hg -AUTOMAKE="automake --foreign --warnings=no-portability" -export AUTOMAKE +# Don't check for translations since we don't have any in Octave yet. +# This avoids the need for sha1sum or compatible utility in bootstrap. +SKIP_PO=true bootstrap_post_import_hook () { diff -r 20d1b911b4e7 -r c702371ff6df build-aux/mk-opts.pl --- a/build-aux/mk-opts.pl Thu Sep 12 21:08:07 2013 -0400 +++ b/build-aux/mk-opts.pl Sat Oct 05 11:22:09 2013 -0400 @@ -240,7 +240,7 @@ } } -#FIXME: What does this routine do? And can it be simpler to understand? +## FIXME: What does this routine do? And can it be simpler to understand? sub get_min_match_len_info { my ($i, $j, $k); @@ -924,7 +924,7 @@ for (my $i = 0; $i < $OPT_NUM; $i++) { - print '@item \"', $NAME[$i], '\"\n\\', "\n"; + print '@item @qcode{\"', $NAME[$i], '\"}\n\\', "\n"; print $DOC_ITEM[$i] if $DOC_ITEM[$i]; } diff -r 20d1b911b4e7 -r c702371ff6df build-aux/mkinstalldirs --- a/build-aux/mkinstalldirs Thu Sep 12 21:08:07 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,162 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy - -scriptversion=2009-04-28.21; # UTC - -# Original author: Noah Friedman -# Created: 1993-05-16 -# Public domain. -# -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -nl=' -' -IFS=" "" $nl" -errstatus=0 -dirmode= - -usage="\ -Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... - -Create each directory DIR (with mode MODE, if specified), including all -leading file name components. - -Report bugs to ." - -# process command line arguments -while test $# -gt 0 ; do - case $1 in - -h | --help | --h*) # -h for help - echo "$usage" - exit $? - ;; - -m) # -m PERM arg - shift - test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } - dirmode=$1 - shift - ;; - --version) - echo "$0 $scriptversion" - exit $? - ;; - --) # stop option processing - shift - break - ;; - -*) # unknown option - echo "$usage" 1>&2 - exit 1 - ;; - *) # first non-opt arg - break - ;; - esac -done - -for file -do - if test -d "$file"; then - shift - else - break - fi -done - -case $# in - 0) exit 0 ;; -esac - -# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and -# mkdir -p a/c at the same time, both will detect that a is missing, -# one will create a, then the other will try to create a and die with -# a "File exists" error. This is a problem when calling mkinstalldirs -# from a parallel make. We use --version in the probe to restrict -# ourselves to GNU mkdir, which is thread-safe. -case $dirmode in - '') - if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then - echo "mkdir -p -- $*" - exec mkdir -p -- "$@" - else - # On NextStep and OpenStep, the `mkdir' command does not - # recognize any option. It will interpret all options as - # directories to create, and then abort because `.' already - # exists. - test -d ./-p && rmdir ./-p - test -d ./--version && rmdir ./--version - fi - ;; - *) - if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && - test ! -d ./--version; then - echo "mkdir -m $dirmode -p -- $*" - exec mkdir -m "$dirmode" -p -- "$@" - else - # Clean up after NextStep and OpenStep mkdir. - for d in ./-m ./-p ./--version "./$dirmode"; - do - test -d $d && rmdir $d - done - fi - ;; -esac - -for file -do - case $file in - /*) pathcomp=/ ;; - *) pathcomp= ;; - esac - oIFS=$IFS - IFS=/ - set fnord $file - shift - IFS=$oIFS - - for d - do - test "x$d" = x && continue - - pathcomp=$pathcomp$d - case $pathcomp in - -*) pathcomp=./$pathcomp ;; - esac - - if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" - - mkdir "$pathcomp" || lasterr=$? - - if test ! -d "$pathcomp"; then - errstatus=$lasterr - else - if test ! -z "$dirmode"; then - echo "chmod $dirmode $pathcomp" - lasterr= - chmod "$dirmode" "$pathcomp" || lasterr=$? - - if test ! -z "$lasterr"; then - errstatus=$lasterr - fi - fi - fi - fi - - pathcomp=$pathcomp/ - done -done - -exit $errstatus - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff -r 20d1b911b4e7 -r c702371ff6df configure.ac --- a/configure.ac Thu Sep 12 21:08:07 2013 -0400 +++ b/configure.ac Sat Oct 05 11:22:09 2013 -0400 @@ -19,13 +19,13 @@ ### . AC_PREREQ([2.62]) -AC_INIT([GNU Octave], [3.7.5], [http://octave.org/bugs.html], [octave]) +AC_INIT([GNU Octave], [3.7.7+], [http://octave.org/bugs.html], [octave]) dnl PACKAGE_VERSION is set by the AC_INIT VERSION arg OCTAVE_VERSION="$PACKAGE_VERSION" OCTAVE_API_VERSION_NUMBER="48" OCTAVE_API_VERSION="api-v$OCTAVE_API_VERSION_NUMBER+" -OCTAVE_RELEASE_DATE="2013-05-14" +OCTAVE_RELEASE_DATE="2013-09-23" OCTAVE_COPYRIGHT="Copyright (C) 2013 John W. Eaton and others." AC_SUBST(OCTAVE_VERSION) AC_SUBST(OCTAVE_API_VERSION_NUMBER) @@ -41,7 +41,11 @@ AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) -AM_INIT_AUTOMAKE([1.11 tar-ustar]) +AM_INIT_AUTOMAKE([1.11 foreign -Wno-portability -Wno-override tar-ustar subdir-objects]) + +## Add the option to enable silent rules, available since Automake 1.11 +## and included by default starting with Automake 1.13. +AM_SILENT_RULES OCTAVE_CANONICAL_HOST @@ -712,7 +716,7 @@ AC_DEFINE(HAVE_ZLIB, 1, [Define to 1 if ZLIB is available.]) fi -### Check for the LLVM library + ### Check for the LLVM library build_jit=no AC_ARG_ENABLE([jit], @@ -742,6 +746,7 @@ save_CPPFLAGS="$CPPFLAGS" save_CXXFLAGS="$CXXFLAGS" + save_LDFLAGS="$LDFLAGS" ## Use -isystem if available because we don't want to see warnings in LLVM LLVM_INCLUDE_FLAG=-I @@ -753,7 +758,11 @@ LLVM_CPPFLAGS="$LLVM_INCLUDE_FLAG `$LLVM_CONFIG --includedir`" LLVM_CXXFLAGS= LLVM_LDFLAGS="-L`$LLVM_CONFIG --libdir`" - LLVM_LIBS=`$LLVM_CONFIG --libs` + + + LDFLAGS="$LDFLAGS $LLVM_LDFLAGS" + LLVM_SO=LLVM-`$LLVM_CONFIG --version` + AC_CHECK_LIB([$LLVM_SO], [LLVMBuildAdd], [LLVM_LIBS="-l$LLVM_SO"], [LLVM_LIBS=`$LLVM_CONFIG --libs`]) dnl dnl Define some extra flags that LLVM requires in order to include headers. @@ -766,9 +775,33 @@ AC_CHECK_HEADER([llvm/Support/TargetSelect.h], [ warn_llvm= XTRA_CXXFLAGS="$XTRA_CXXFLAGS $LLVM_CXXFLAGS $LLVM_CPPFLAGS"]) + + have_function_h=no + AC_CHECK_HEADERS([llvm/IR/Function.h llvm/Function.h], + [have_function_h=yes; break]) + if test $have_function_h = no; then + warn_llvm="Missing LLVM file Function.h. JIT compiler is disabled." + fi + have_irbuilder_h=no + AC_CHECK_HEADERS([llvm/Support/IRBuilder.h llvm/IR/IRBuilder.h \ + llvm/IRBuilder.h], [have_irbuilder_h=yes; break]) + if test $have_irbuilder_h = no; then + warn_llvm="Missing LLVM file IRBuilder.h. JIT compiler is disabled." + fi + have_llvm_data_h=no + AC_CHECK_HEADERS([llvm/Target/TargetData.h llvm/IR/DataLayout.h \ + llvm/DataLayout.h], [have_llvm_data_h=yes; break]) + if test $have_llvm_data_h = no; then + warn_llvm="Missing LLVM file TargetData.h. JIT compiler is disabled." + fi + + OCTAVE_LLVM_FUNCTION_ADDATTRIBUTE_API + OCTAVE_LLVM_FUNCTION_ADDFNATTR_API + OCTAVE_LLVM_CALLINST_ADDATTRIBUTE_API AC_LANG_POP(C++) CPPFLAGS="$save_CPPFLAGS" CXXFLAGS="$save_CXXFLAGS" + LDFLAGS="$save_LDFLAGS" fi if test -z "$warn_llvm"; then @@ -863,7 +896,12 @@ LIBS="$Z_LDFLAGS $Z_LIBS $LIBS" OCTAVE_CHECK_LIB(glpk, GLPK, [GLPK library not found. The glpk function for solving linear programs will be disabled.], - [glpk/glpk.h glpk.h], [_glp_lpx_simplex]) + [glpk/glpk.h glpk.h], [glp_simplex], [], [], + [warn_glpk= + OCTAVE_CHECK_LIB_GLPK_OK( + [TEXINFO_GLPK="@set HAVE_GLPK" + AC_DEFINE(HAVE_GLPK, 1, [Define to 1 if GLPK is available.])], + [warn_glpk="GLPK library found, but does not seem to work properly -- disabling glpk function"])]) LIBS="$save_LIBS" CPPFLAGS="$save_CPPFLAGS" @@ -1041,6 +1079,10 @@ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_FREETYPE, 1, [Define to 1 if you have Freetype library.]) XTRA_CXXFLAGS="$XTRA_CXXFLAGS $FT2_CFLAGS" + save_LIBS="$LIBS" + LIBS="$FT2_LIBS $LIBS" + AC_CHECK_FUNCS([FT_Reference_Face]) + LIBS="$save_LIBS" else AC_MSG_RESULT(no) warn_freetype="FreeType library not found. Native graphics will be disabled." @@ -1928,7 +1970,7 @@ AC_CHECK_HEADERS([curses.h direct.h dlfcn.h floatingpoint.h fpu_control.h]) AC_CHECK_HEADERS([grp.h ieeefp.h inttypes.h locale.h memory.h ncurses.h]) AC_CHECK_HEADERS([poll.h pthread.h pwd.h sunmath.h sys/ioctl.h]) -AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/resource.h ]) +AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/resource.h]) AC_CHECK_HEADERS([sys/select.h sys/utsname.h termcap.h]) ## C++ headers @@ -2040,7 +2082,7 @@ dnl These checks define/undefine HAVE_FUNCNAME in config.h. dnl Code tests HAVE_FUNCNAME and either uses function or provides workaround. dnl Use multiple AC_CHECKs to avoid line continuations '\' in list -AC_CHECK_FUNCS([canonicalize_file_name dup2]) +AC_CHECK_FUNCS([canonicalize_file_name ctermid dup2]) AC_CHECK_FUNCS([endgrent endpwent execvp expm1 expm1f fork]) AC_CHECK_FUNCS([getegid geteuid getgid getgrent getgrgid getgrnam]) AC_CHECK_FUNCS([getpgrp getpid getppid getpwent getpwuid getuid]) @@ -2527,6 +2569,7 @@ JAVA_CPPFLAGS="-I${JAVA_HOME}/include -I${JAVA_HOME}/include/win32" fi JAVA_LIBS=-ladvapi32 + LDFLAGS="$LDFLAGS -Wl,--export-all-symbols" ;; *) if test -n "$JAVA_CPPFLAGS"; then @@ -2601,7 +2644,7 @@ if test $build_gui = yes; then AC_CHECK_TOOLS(MOC, [moc-qt5 moc-qt4 moc]) AC_CHECK_TOOLS(UIC, [uic-qt5 uic-qt4 uic]) - AC_CHECK_TOOLS(RCC, [rcc]) + AC_CHECK_TOOLS(RCC, [rcc-qt5 rcc-qt4 rcc]) AC_CHECK_TOOLS(LRELEASE, [lrelease-qt5 lrelease-qt4 lrelease]) if test -n "$MOC" && test -n "$UIC" && test -n "$RCC" && test -n "$LRELEASE"; then AC_DEFINE(HAVE_QT, 1, @@ -2613,6 +2656,14 @@ fi if test $build_gui = yes; then + OCTAVE_CHECK_FUNC_QABSTRACTITEMMODEL_BEGINRESETMODEL + if test $octave_cv_func_qabstractitemmodel_beginresetmodel = no; then + AC_MSG_WARN([QAbstractItemModel::beginResetModel() not found -- disabling GUI]) + build_gui=no + fi + fi + + if test $build_gui = yes; then OCTAVE_CHECK_FUNC_SETPLACEHOLDERTEXT fi @@ -2712,6 +2763,7 @@ Makefile doc/Makefile doc/doxyhtml/Makefile + doc/doxyhtml/Doxyfile doc/icons/Makefile doc/interpreter/Makefile doc/liboctave/Makefile diff -r 20d1b911b4e7 -r c702371ff6df doc/doxyhtml/Doxyfile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/doxyhtml/Doxyfile.in Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,317 @@ +# -*- mode: conf; -*- + +# Doxyfile for Doxygen 1.7.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for GNU Octave. +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the +# config file that follow. We don't use anything but ASCII, but +# there's no problem using UTF-8 from now on + +DOXYFILE_ENCODING = UTF-8 + +# Who we are. :-) + +PROJECT_NAME = "GNU Octave" + +PROJECT_BRIEF = "A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab" + +# The public stable API version (unrelated to the internal API +# version). + +PROJECT_NUMBER = @PACKAGE_VERSION@ + +# Our logo! + +PROJECT_LOGO = @top_srcdir@/doc/icons/octave-logo.png + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. + +OUTPUT_DIRECTORY = @abs_top_builddir@/doc + +# Create 4096 sub-directories (in 2 levels) under the output directory +# of each output format and will distribute the generated files over +# these directories. Enabling this option is useful for us, since +# feeding doxygen a huge amount of source files would put all +# generated files in the same directory would otherwise cause +# performance problems for the file system. + +CREATE_SUBDIRS = YES + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. + +OUTPUT_LANGUAGE = English + +# Include brief member descriptions after the members that are listed +# in the file and class documentation (similar to JavaDoc). Set to NO +# to disable this. + +BRIEF_MEMBER_DESC = YES + +# Prepend the brief description of a member or function before the +# detailed description. Note: if both HIDE_UNDOC_MEMBERS and +# BRIEF_MEMBER_DESC are set to NO, the brief descriptions will be +# completely suppressed. + +REPEAT_BRIEF = YES + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# Show inherited members as if they were part of the current class + +INLINE_INHERITED_MEMB = YES + +# Prepend the full path before files name in the file list and in the +# header files. + +FULL_PATH_NAMES = YES + +# Remove from the full path names the absolute prefix + +STRIP_FROM_PATH = @top_srcdir@ + +# Interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description (without needing the @brief +# command). + +JAVADOC_AUTOBRIEF = YES + +# Interpret the first line (until the first dot) of a Qt-style comment +# as the brief descriptio (without needing the \brief command). + +QT_AUTOBRIEF = NO + +# Undocumented member inherits the documentation from any documented +# member that it re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. +# We shouldn't have any tabs in the source code to begin with, however. + +TAB_SIZE = 2 + +# Figure out C++ stdlib classes without needing to parse those files. + +BUILTIN_STL_SUPPORT = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# Assume all entities in documentation are documented, even if no +# documentation was available. + +EXTRACT_ALL = YES + +# Include all private members of a class. + +EXTRACT_PRIVATE = YES + +# Include all static members of a file. + +EXTRACT_STATIC = YES + +# Include classes (and structs) defined locally in source files in the +# documentation. + +EXTRACT_LOCAL_CLASSES = YES + +# We have very few namespaces, so show the ones we have + +SHOW_NAMESPACES = YES + +# We don't use namespaces, but if we did, this would extract the +# anonymous one. + +EXTRACT_ANON_NSPACES = YES + +# Hide internal docs, those with the \internal command. + +INTERNAL_DOCS = NO + +# Case-sensitive filenames + +CASE_SENSE_NAMES = YES + +# List include files with double quotes in the documentation rather +# than with sharp brackets. + +FORCE_LOCAL_INCLUDES = YES + +# Show members alphabetically + +SORT_MEMBER_DOCS = YES + +# Also sort the brief descriptions + +SORT_BRIEF_DOCS = YES + +# Put ctors first. + +SORT_MEMBERS_CTORS_1ST = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# On by default, but let's be explicit + +ENABLE_PREPROCESSING = YES + +# Expand all macros + +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = NO + +# So that features that are behind #ifdef HAVE_FOO macros get processed by Doxygen + +PREDEFINED = HAVE_ARPACK=1 \ + HAVE_CHOLMOD=1 \ + HAVE_CCOLAMD=1 \ + HAVE_CURL=1 \ + HAVE_CXSPARSE=1 \ + HAVE_FFTW=1 \ + HAVE_FFTW3=1 \ + HAVE_FFTW3F=1 \ + HAVE_FFTW3F_THREADS=1 \ + HAVE_FFTW3_THREADS=1 \ + HAVE_FREETYPE=1 \ + HAVE_GLPK=1 \ + HAVE_HDF5=1 \ + HAVE_LLVM=1 \ + HAVE_MAGICK=1 \ + HAVE_OPENMP=1 \ + HAVE_PCRE_H=1 \ + HAVE_PCRE_COMPILE=1 \ + HAVE_QHULL=1 \ + HAVE_QRUPDATE=1 \ + HAVE_QRUPDATE_LUU=1 \ + HAVE_QT=1 \ + HAVE_UMFPACK=1 \ + HAVE_X_WINDOWS=1 \ + HAVE_ZLIB=1 + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# Which directories contain Octave source code + +INPUT = @top_srcdir@/src/ @top_srcdir@/liboctave/ +INPUT += @top_srcdir@/libinterp @top_srcdir@/libgui + +# Search subdirectories for input. + +RECURSIVE = YES + +# Our examples. + +EXAMPLE_PATH = @top_srcdir@/examples/ + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# There are no extra C++ files in the examples subdir + +EXAMPLE_RECURSIVE = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# Generate a list of source files will be generated. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Don't hide the special Doxygen comment blocks + +STRIP_CODE_COMMENTS = NO + +# For each documented function, list all documented functions +# referencing it. + +REFERENCED_BY_RELATION = YES + +# For each documented function all documented entities called/used by +# that function will be listed. + +REFERENCES_RELATION = YES + +# References link to documentation, not source code. + +REFERENCES_LINK_SOURCE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# Generate HTML + +GENERATE_HTML = YES + +# i.e. @abs_top_builddir@/doc/doxyhtml + +HTML_OUTPUT = doxyhtml + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# No LaTeX + +GENERATE_LATEX = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# Show undocumented relations + +HIDE_UNDOC_RELATIONS = NO + +# Use dot from graphviz to generate class diagrams. + +HAVE_DOT = YES + +# Remove intermediate dot files. + +DOT_CLEANUP = YES + +# Some of our dependency graphs are really huge... + +DOT_GRAPH_MAX_NODES = 100 \ No newline at end of file diff -r 20d1b911b4e7 -r c702371ff6df doc/doxyhtml/Doxygen.cfg --- a/doc/doxyhtml/Doxygen.cfg Thu Sep 12 21:08:07 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,267 +0,0 @@ -# -*- mode: conf; -*- - -# Doxyfile for Doxygen 1.7.1 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for GNU Octave. -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the -# config file that follow. We don't use anything but ASCII, but -# there's no problem using UTF-8 from now on - -DOXYFILE_ENCODING = UTF-8 - -# Who we are. :-) - -PROJECT_NAME = "GNU Octave" - -# The public stable API version (unrelated to the internal API -# version). - -PROJECT_NUMBER = 3.7 - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. - -OUTPUT_DIRECTORY = doc/ - -# Create 4096 sub-directories (in 2 levels) under the output directory -# of each output format and will distribute the generated files over -# these directories. Enabling this option is useful for us, since -# feeding doxygen a huge amount of source files would put all -# generated files in the same directory would otherwise cause -# performance problems for the file system. - -CREATE_SUBDIRS = YES - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. - -OUTPUT_LANGUAGE = English - -# Include brief member descriptions after the members that are listed -# in the file and class documentation (similar to JavaDoc). Set to NO -# to disable this. - -BRIEF_MEMBER_DESC = YES - -# Prepend the brief description of a member or function before the -# detailed description. Note: if both HIDE_UNDOC_MEMBERS and -# BRIEF_MEMBER_DESC are set to NO, the brief descriptions will be -# completely suppressed. - -REPEAT_BRIEF = YES - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# Show inherited members as if they were part of the current class - -INLINE_INHERITED_MEMB = YES - -# Prepend the full path before files name in the file list and in the -# header files. - -FULL_PATH_NAMES = YES - -# Interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description (without needing the @brief -# command). - -JAVADOC_AUTOBRIEF = YES - -# Interpret the first line (until the first dot) of a Qt-style comment -# as the brief descriptio (without needing the \brief command). - -QT_AUTOBRIEF = NO - -# Undocumented member inherits the documentation from any documented -# member that it re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. -# We shouldn't have any tabs in the source code to begin with, however. - -TAB_SIZE = 2 - -# Figure out C++ stdlib classes without needing to parse those files. - -BUILTIN_STL_SUPPORT = YES - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# Assume all entities in documentation are documented, even if no -# documentation was available. - -EXTRACT_ALL = YES - -# Include all private members of a class. - -EXTRACT_PRIVATE = YES - -# Include all static members of a file. - -EXTRACT_STATIC = YES - -# Include classes (and structs) defined locally in source files in the -# documentation. - -EXTRACT_LOCAL_CLASSES = YES - -# We don't use namespaces, but if we did, this would extract the -# anonymous one. - -EXTRACT_ANON_NSPACES = YES - -# Hide internal docs, those with the \internal command. - -INTERNAL_DOCS = NO - -# Case-sensitive filenames - -CASE_SENSE_NAMES = YES - -# List include files with double quotes in the documentation rather -# than with sharp brackets. - -FORCE_LOCAL_INCLUDES = YES - -# Show members alphabetically - -SORT_MEMBER_DOCS = YES - -# Also sort the brief descriptions - -SORT_BRIEF_DOCS = YES - -# Put ctors first. - -SORT_MEMBERS_CTORS_1ST = YES - -# Show which directories the file is in. - -SHOW_DIRECTORIES = YES - -# We don't have namespaces, so don't show them. - -SHOW_NAMESPACES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# Which directories contain Octave source code - -INPUT = src/ liboctave/ libinterp/ - -# Search subdirectories for input. - -RECURSIVE = YES - -# Our examples. - -EXAMPLE_PATH = examples/ - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# There are no extra C++ files in the examples subdir - -EXAMPLE_RECURSIVE = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# Generate a list of source files will be generated. - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# For each documented function, list all documented functions -# referencing it. - -REFERENCED_BY_RELATION = YES - -# For each documented function all documented entities called/used by -# that function will be listed. - -REFERENCES_RELATION = YES - -# References link to documenation, not source code. - -REFERENCES_LINK_SOURCE = NO - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# Generate HTML - -GENERATE_HTML = YES - -# i.e. doc/doxyhtml - -HTML_OUTPUT = doxyhtml - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# No LaTeX - -GENERATE_LATEX = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# Show undocumented relations - -HIDE_UNDOC_RELATIONS = NO - -# Use dot from graphviz to generate class diagrams. - -HAVE_DOT = YES - -# Remove intermediate dot files. - -DOT_CLEANUP = YES - diff -r 20d1b911b4e7 -r c702371ff6df doc/doxyhtml/Makefile.am --- a/doc/doxyhtml/Makefile.am Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/doxyhtml/Makefile.am Sat Oct 05 11:22:09 2013 -0400 @@ -21,12 +21,12 @@ include $(top_srcdir)/build-aux/common.mk doxyhtml: - cd ../..; doxygen doc/doxyhtml/Doxygen.cfg + doxygen Doxyfile EXTRA_DIST = \ - Doxygen.cfg \ + Doxyfile.in \ Makefile.am \ README maintainer-clean-local: - rm -rf `ls | $(GREP) -v Doxygen.cfg | $(GREP) -v Makefile.am | $(GREP) -v Makefile.in | $(GREP) -v README` + rm -rf `ls | $(GREP) -v Doxyfile | $(GREP) -v Makefile.am | $(GREP) -v Makefile.in | $(GREP) -v README` diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/Makefile.am --- a/doc/interpreter/Makefile.am Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/Makefile.am Sat Oct 05 11:22:09 2013 -0400 @@ -30,7 +30,7 @@ TEXMFCNF := "..$(PATH_SEPARATOR)$(srcdir)/..$(PATH_SEPARATOR)$(TEXMFCNF)$(PATH_SEPARATOR)" export TEXMFCNF -dist_man1_MANS = \ +dist_man_MANS = \ mkoctfile.1 \ octave-config.1 \ octave.1 @@ -225,19 +225,19 @@ cp $(srcdir)/contributors.texi contributors.texi; \ touch -r $(srcdir)/contributors.texi contributors.texi; \ fi - -$(MAKEINFO) -D AUTHORSONLY \ + -$(MAKEINFO) -D AUTHORSONLY -I $(srcdir) \ --no-validate --no-headers --no-split --output AUTHORS $< mv AUTHORS ../../AUTHORS ../../BUGS: bugs.texi rm -f BUGS - -$(MAKEINFO) -D BUGSONLY \ + -$(MAKEINFO) -D BUGSONLY -I $(srcdir) \ --no-validate --no-headers --no-split --output BUGS $< mv BUGS ../../BUGS ../../INSTALL.OCTAVE: install.texi rm -f INSTALL - -$(MAKEINFO) -D INSTALLONLY \ + -$(MAKEINFO) -D INSTALLONLY -I $(srcdir) \ --no-validate --no-headers --no-split --output INSTALL $< mv INSTALL ../../INSTALL.OCTAVE diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/arith.txi --- a/doc/interpreter/arith.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/arith.txi Sat Oct 05 11:22:09 2013 -0400 @@ -34,14 +34,14 @@ @menu * Exponents and Logarithms:: -* Complex Arithmetic:: -* Trigonometry:: -* Sums and Products:: -* Utility Functions:: -* Special Functions:: +* Complex Arithmetic:: +* Trigonometry:: +* Sums and Products:: +* Utility Functions:: +* Special Functions:: * Rational Approximations:: * Coordinate Transformations:: -* Mathematical Constants:: +* Mathematical Constants:: @end menu @node Exponents and Logarithms @@ -190,6 +190,7 @@ @DOCSTRING(asind) @DOCSTRING(acosd) @DOCSTRING(atand) +@DOCSTRING(atan2d) @DOCSTRING(asecd) @DOCSTRING(acscd) @DOCSTRING(acotd) @@ -311,7 +312,7 @@ @DOCSTRING(legendre) -@anchor{docXgammaln} +@anchor{XREFgammaln} @DOCSTRING(lgamma) @node Rational Approximations diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/basics.txi --- a/doc/interpreter/basics.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/basics.txi Sat Oct 05 11:22:09 2013 -0400 @@ -25,13 +25,13 @@ from your shell. @menu -* Invoking Octave from the Command Line:: -* Quitting Octave:: -* Getting Help:: -* Command Line Editing:: -* Errors:: -* Executable Octave Programs:: -* Comments:: +* Invoking Octave from the Command Line:: +* Quitting Octave:: +* Getting Help:: +* Command Line Editing:: +* Errors:: +* Executable Octave Programs:: +* Comments:: @end menu @node Invoking Octave from the Command Line @@ -52,8 +52,8 @@ shorter equivalent). @menu -* Command Line Options:: -* Startup Files:: +* Command Line Options:: +* Startup Files:: @end menu @node Command Line Options @@ -154,7 +154,7 @@ @cindex @code{-i} Force interactive behavior. This can be useful for running Octave via a remote shell command or inside an Emacs shell buffer. For another way -to run Octave within Emacs, see @ref{Emacs Octave Support}. +to run Octave within Emacs, @pxref{Emacs Octave Support}. @item --line-editing @cindex @code{--line-editing} @@ -272,8 +272,8 @@ @noindent Note that this does not enable the @code{Octave:matlab-incompatible} warning, which you might want if you want to be told about writing code -that works in Octave but not @sc{matlab} (@pxref{docXwarning}, -@pxref{docXwarning_ids}). +that works in Octave but not @sc{matlab} (@pxref{XREFwarning,,warning}, +@ref{XREFwarning_ids,,warning_ids}). @item --verbose @itemx -V @@ -484,14 +484,14 @@ @menu -* Cursor Motion:: -* Killing and Yanking:: -* Commands For Text:: -* Commands For Completion:: -* Commands For History:: -* Customizing readline:: -* Customizing the Prompt:: -* Diary and Echo Commands:: +* Cursor Motion:: +* Killing and Yanking:: +* Commands For Text:: +* Commands For Completion:: +* Commands For History:: +* Customizing readline:: +* Customizing the Prompt:: +* Diary and Echo Commands:: @end menu @node Cursor Motion @@ -530,7 +530,7 @@ @item C-l Clear the screen, reprinting the current line at the top. -@item C-_ +@item C-_ @itemx C-/ Undo the last action. You can undo all the way back to an empty line. @@ -610,7 +610,7 @@ for quickly correcting typing mistakes. @table @kbd -@item C-q +@item C-q @itemx C-v Add the next character that you type to the line verbatim. This is how to insert things like @kbd{C-q} for example. @@ -678,7 +678,7 @@ list. @table @kbd -@item @key{LFD} +@item @key{LFD} @itemx @key{RET} Accept the current line regardless of where the cursor is. If the line is non-empty, add it to the history list. If the line was a history @@ -1047,7 +1047,7 @@ @menu * Single Line Comments:: * Block Comments:: -* Comments and the Help System:: +* Comments and the Help System:: @end menu @node Single Line Comments @@ -1099,8 +1099,8 @@ @end example @noindent -will produce a very quick countdown from '3' to 'Blast Off' as the -lines "@code{disp (2);}" and "@code{disp (1);}" won't be executed. +will produce a very quick countdown from @qcode{'3'} to @qcode{"Blast Off"} as +the lines "@code{disp (2);}" and "@code{disp (1);}" won't be executed. The block comment markers must appear alone as the only characters on a line (excepting whitespace) in order to be parsed correctly. diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/bugs.txi --- a/doc/interpreter/bugs.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/bugs.txi Sat Oct 05 11:22:09 2013 -0400 @@ -52,8 +52,8 @@ @menu * Actual Bugs:: Bugs we will fix later. -* Reporting Bugs:: -* Service:: +* Reporting Bugs:: +* Service:: @end menu @node Actual Bugs @@ -105,7 +105,7 @@ information that makes it possible to fix the bug. @menu -* Bug Criteria:: +* Bug Criteria:: * Bug Tracker:: Where to submit your bug report. * Bug Reporting:: How to report a bug effectively. * Sending Patches:: How to send a patch for Octave. diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/container.txi --- a/doc/interpreter/container.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/container.txi Sat Oct 05 11:22:09 2013 -0400 @@ -372,9 +372,9 @@ @subsection Creating Structures @cindex dynamic naming -Besides the index operator ".", Octave can use dynamic naming "(var)" or the -@code{struct} function to create structures. Dynamic naming uses the string -value of a variable as the field name. For example: +Besides the index operator @qcode{"."}, Octave can use dynamic naming +@qcode{"(var)"} or the @code{struct} function to create structures. Dynamic +naming uses the string value of a variable as the field name. For example: @example @group @@ -410,7 +410,7 @@ @noindent The warning id @code{Octave:matlab-incompatible} can be enabled to warn -about this usage. @xref{docXwarning_ids}. +about this usage. @xref{XREFwarning_ids,,warning_ids}. More realistically, all of the functions that operate on strings can be used to build the correct field name before it is entered into the data structure. @@ -484,12 +484,12 @@ @result{} ans = @{ field1 = - + @{ [1,1] = 1 [1,2] = one @} - + field2 = 2 @} @end group @@ -529,7 +529,8 @@ The simplest way to process data in a structure is within a @code{for} loop (@pxref{Looping Over Structure Elements}). A similar effect can be achieved with the @code{structfun} function, where a user defined -function is applied to each field of the structure. @xref{docXstructfun}. +function is applied to each field of the structure. +@xref{XREFstructfun,,structfun}. Alternatively, to process the data in a structure, the structure might be converted to another type of container before being treated. @@ -586,7 +587,7 @@ c@{1:2@} @result{} ans = a string @result{} ans = - + 0.593993 0.627732 0.377037 0.033643 @end group @@ -600,14 +601,14 @@ @group c@{3@} = 3 @result{} c = - + @{ [1,1] = a string [1,2] = - + 0.593993 0.627732 0.377037 0.033643 - + [1,3] = 3 @} @end group @@ -639,7 +640,7 @@ @DOCSTRING(iscell) @node Creating Cell Arrays -@subsection Creating Cell Array +@subsection Creating Cell Arrays The introductory example (@pxref{Basic Usage of Cell Arrays}) showed how to create a cell array containing currently available variables. @@ -655,7 +656,7 @@ @group c = cell (2,2) @result{} c = - + @{ [1,1] = [](0x0) [2,1] = [](0x0) @@ -683,11 +684,10 @@ @end example @noindent -As can be seen, the @ref{docXsize, @code{size}} function also works +As can be seen, the @ref{XREFsize,,size} function also works for cell arrays. As do other functions describing the size of an -object, such as @ref{docXlength, @code{length}}, @ref{docXnumel, -@code{numel}}, @ref{docXrows, @code{rows}}, and @ref{docXcolumns, -@code{columns}}. +object, such as @ref{XREFlength,,length}, @ref{XREFnumel,, numel}, +@ref{XREFrows,,rows}, and @ref{XREFcolumns,,columns}. @DOCSTRING(cell) @@ -907,7 +907,7 @@ is to iterate through it using one or more @code{for} loops. The same idea can be implemented more easily through the use of the @code{cellfun} function that calls a user-specified function on all elements of a cell -array. @xref{docXcellfun}. +array. @xref{XREFcellfun,,cellfun}. An alternative is to convert the data to a different container, such as a matrix or a data structure. Depending on the data this is possible diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/contrib.txi --- a/doc/interpreter/contrib.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/contrib.txi Sat Oct 05 11:22:09 2013 -0400 @@ -355,7 +355,7 @@ @noindent The function name should start in column 1, and multi-line argument lists should be aligned on the first char after the open parenthesis. -You should put a space after the left open parenthesis and after commas, +You should put a space before the left open parenthesis and after commas, for both function definitions and function calls. Recommended indent is 2 spaces. When indenting, indent the statement diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/contributors.in --- a/doc/interpreter/contributors.in Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/contributors.in Sat Oct 05 11:22:09 2013 -0400 @@ -42,9 +42,9 @@ Michael Creel Jeff Cunningham Martin Dalecki +Jacob Dawid Jorge Barros de Abreu Carlo de Falco -Jacob Dawid Thomas D. Dean Philippe Defert Bill Denney @@ -75,6 +75,7 @@ Klaus Gebhardt Driss Ghaddab Nicolo Giorgetti +Arun Giridhar Michael D. Godfrey Michael Goffioul Glenn Golden @@ -140,6 +141,7 @@ Piotr Krzyzanowski Volker Kuhlmann Tetsuro Kurita +Philipp Kutin Miroslaw Kwasniak Rafael Laboissiere Kai Labusch @@ -159,21 +161,21 @@ Massimo Lorenzin Emil Lucretiu Hoxide Ma +Colin Macdonald James Macnicol Jens-Uwe Mager -Colin Macdonald Rob Mahurin +Alexander Mamonov Ricardo Marranita Orestes Mas Axel Mathéi Makoto Matsumoto Tatsuro Matsuoka +Christoph Mayer Laurent Mazet G. D. McBain -Alexander Mamonov -Christoph Mayer +Ronald van der Meer Júlio Hoffimann Mendes -Ronald van der Meer Thorsten Meyer Petr Mikulik Mike Miller @@ -222,11 +224,13 @@ Joshua Redstone Lukas Reichlin Michael Reifenberger +Jens Restemeier Anthony Richardson Jason Riedy E. Joshua Rigler Petter Risholm Matthew W. Roberts +Peter Rosin Andrew Ross Fabio Rossi Mark van Rossum @@ -272,23 +276,24 @@ John Swensen Daisuke Takago Ariel Tankus +Falk Tannhäuser +Duncan Temple Lang Matthew Tenny +Kris Thielemans Georg Thimm -Duncan Temple Lang -Kris Thielemans Olaf Till Christophe Tournery Thomas Treichl Karsten Trulsen Frederick Umminger Utkarsh Upadhyay -Daniel Wagenaar Stefan van der Walt Peter Van Wieren James R. Van Zandt Risto Vanhanen Gregory Vanuxem Ivana Varekova +Daniel Wagenaar Thomas Walter Andreas Weber Olaf Weber diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/data.txi --- a/doc/interpreter/data.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/data.txi Sat Oct 05 11:22:09 2013 -0400 @@ -35,9 +35,9 @@ @DOCSTRING(typeinfo) @menu -* Built-in Data Types:: -* User-defined Data Types:: -* Object Sizes:: +* Built-in Data Types:: +* User-defined Data Types:: +* Object Sizes:: @end menu @node Built-in Data Types @@ -70,11 +70,11 @@ @DOCSTRING(bitunpack) @menu -* Numeric Objects:: -* Missing Data:: -* String Objects:: -* Data Structure Objects:: -* Cell Array Objects:: +* Numeric Objects:: +* Missing Data:: +* String Objects:: +* Data Structure Objects:: +* Cell Array Objects:: @end menu @node Numeric Objects diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/debug.txi --- a/doc/interpreter/debug.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/debug.txi Sat Oct 05 11:22:09 2013 -0400 @@ -43,7 +43,7 @@ @section Entering Debug Mode There are two basic means of interrupting the execution of an Octave -script. These are breakpoints @pxref{Breakpoints}, discussed in the next +script. These are breakpoints (@pxref{Breakpoints}), discussed in the next section and interruption based on some condition. Octave supports three means to stop execution based on the values set in @@ -241,8 +241,8 @@ @node Profiler Example @section Profiler Example -Below, we will give a short example of a profiler session. See also -@ref{Profiling} for the documentation of the profiler functions in +Below, we will give a short example of a profiler session. +@xref{Profiling}, for the documentation of the profiler functions in detail. Consider the code: @example diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/diagperm.txi --- a/doc/interpreter/diagperm.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/diagperm.txi Sat Oct 05 11:22:09 2013 -0400 @@ -16,19 +16,19 @@ @c along with Octave; see the file COPYING. If not, see @c . -@node Diagonal and Permutation Matrices +@node Diagonal and Permutation Matrices @chapter Diagonal and Permutation Matrices @menu -* Basic Usage:: Creation and Manipulation of Diagonal and Permutation Matrices -* Matrix Algebra:: Linear Algebra with Diagonal and Permutation Matrices +* Basic Usage:: Creation and Manipulation of Diagonal/Permutation Matrices +* Matrix Algebra:: Linear Algebra with Diagonal/Permutation Matrices * Function Support:: Functions That Are Aware of These Matrices -* Example Code:: Some Examples of Usage -* Zeros Treatment:: The Differences in Treatment of Zero Elements +* Example Code:: Examples of Usage +* Zeros Treatment:: Differences in Treatment of Zero Elements @end menu @node Basic Usage -@section Creating and Manipulating Diagonal and Permutation Matrices +@section Creating and Manipulating Diagonal/Permutation Matrices A diagonal matrix is defined as a matrix that has zero entries outside the main diagonal; that is, @@ -210,7 +210,7 @@ be very cheap. @node Matrix Algebra -@section Linear Algebra with Diagonal and Permutation Matrices +@section Linear Algebra with Diagonal/Permutation Matrices As has been already said, diagonal and permutation matrices make it possible to use efficient algorithms while preserving natural linear @@ -413,7 +413,7 @@ making it possible to conveniently obtain the permutation indices. @node Example Code -@section Some Examples of Usage +@section Examples of Usage The following can be used to solve a linear system @code{A*x = b} using the pivoted LU@tie{}factorization: @@ -436,8 +436,7 @@ @end example @noindent -The same can also be accomplished with broadcasting -(@pxref{Broadcasting}): +The same can also be accomplished with broadcasting (@pxref{Broadcasting}): @example @group @@ -477,7 +476,7 @@ @node Zeros Treatment -@section The Differences in Treatment of Zero Elements +@section Differences in Treatment of Zero Elements Making diagonal and permutation matrices special matrix objects in their own right and the consequent usage of smarter algorithms for certain operations diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/diffeq.txi --- a/doc/interpreter/diffeq.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/diffeq.txi Sat Oct 05 11:22:09 2013 -0400 @@ -24,8 +24,8 @@ All solvers are based on reliable ODE routines written in Fortran. @menu -* Ordinary Differential Equations:: -* Differential-Algebraic Equations:: +* Ordinary Differential Equations:: +* Differential-Algebraic Equations:: @end menu @cindex differential equations diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/doccheck/aspell-octave.en.pws --- a/doc/interpreter/doccheck/aspell-octave.en.pws Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/doccheck/aspell-octave.en.pws Sat Oct 05 11:22:09 2013 -0400 @@ -29,6 +29,7 @@ arpack ascii Ashok +ast async atan Attr @@ -53,6 +54,7 @@ backends bartlett BaseValue +basevalue Bateman BDF bdf @@ -126,6 +128,7 @@ chol Cholesky cholmod +chromaticity chrominance cindex circ @@ -136,11 +139,14 @@ Clenshaw CLI clim +climmode cloglog +closerequestfcn clubsuit CMatrix cmd cmember +CMYK cntrl codebases cof @@ -151,6 +157,7 @@ colormap colormaps ColorOrder +colororder colperm Comint Commandline @@ -183,7 +190,10 @@ cumprod cumsum cURL +CurrentAxes +CurrentFigure CurrentObject +currentpoint Cuthill cxsparse Cygwin @@ -195,6 +205,7 @@ dataset datasets datasource +datenum datestr datestrings davis @@ -226,6 +237,7 @@ Dobkin docstrings dOmega +doNotSpecify dotall dotexceptnewline Downarrow @@ -240,6 +252,8 @@ dx dy EastOutside +edgecolor +Ei EIDORS eigenpairs eigenvector @@ -275,12 +289,14 @@ errorbars errordlg ErrorHandler +ESC Esmond et etree etreeplot eval Executables +Exif exitflag expcdf expinv @@ -330,12 +346,15 @@ Frobenius Fs FSF +fullpath +fullpathext FunValCheck gamcdf gaminv gampdf gamrnd Gautschi +gca gcbo GCC gcd @@ -346,6 +365,7 @@ geoinv geopdf geornd +geotagging geq gesdd gesvd @@ -387,6 +407,7 @@ Hackbusch Hadamard Haddad +HandleVisibility Hankel Hanning hardcode @@ -427,6 +448,7 @@ Hypergeometric hypergeometric IEC +ieee IEEE ifelse ifft @@ -457,6 +479,7 @@ inv involutory ipermute +isdir ishandle ishghandle isolines @@ -473,6 +496,7 @@ Jacobians javaaddpath javamem +jbig JIT jpeg JPEG @@ -481,8 +505,10 @@ JVM's Kac Kahan +kendall keybindings keypress +keypressfcn Kolmogorov kolmogorov Konrod @@ -505,6 +531,7 @@ ldivide ldots le +leaveInPlace Leftarrow leftarrow Leftrightarrow @@ -527,6 +554,8 @@ linesearch linespec linespoints +linestyle +linewidth linkprop listdlg ListSize @@ -562,6 +591,8 @@ lx ly lz +lzma +lzw Magnus Mahalanobis makefile @@ -570,6 +601,10 @@ Mandriva MANOVA manova +markeredgecolor +markerfacecolor +markersize +markerstyle Marsaglia Maschhoff matchcase @@ -583,6 +618,7 @@ McNemar's meansq Mendelsohn +menubars Mersenne meshgrid meshgridded @@ -624,6 +660,7 @@ multi multibyte multiline +multipage multipledelimsasone MultiSelect mxArray @@ -647,6 +684,7 @@ Neudecker Neumann NeXT +NextPlot nfev nfft Ng @@ -688,6 +726,7 @@ OpenGL oplus Oppenheim +Ord oregonator Orthogonalize oslash @@ -697,13 +736,16 @@ overridable paperorientation paperposition +PaperPosition papersize paperunits +PaperUnits parseparams Parter pbm PBM PBMplus +pc pcg PCG pchip @@ -714,6 +756,7 @@ pcx pdf PDF +pearson pentadiagonal periodogram perp @@ -737,6 +780,8 @@ polyeig polyfit polyval +pos +POSDEF POSIX postorder PostScript @@ -796,6 +841,7 @@ rdivide Readline readline +RECT recursing Redheffer reentrant @@ -806,6 +852,7 @@ ren renderer repelems +replacechildren repmat resampled resampling @@ -814,6 +861,8 @@ resized resnorm resparsify +restoreBG +restorePrevious RET returnonerror rfloor @@ -822,6 +871,7 @@ Riccati Rightarrow rightarrow +rle rline rmdir RMS @@ -896,6 +946,7 @@ Stallman startup Startup +statinfo stdnormal stdout Stegun @@ -941,6 +992,7 @@ subsref substring substrings +subwindows SuiteSparse sumsq SunOS @@ -977,6 +1029,7 @@ tif Tikhonov TikZ +Timestamp tinv Tisseur Tisseur's @@ -988,16 +1041,21 @@ TolX toolkits Toolkits +toplevel tp tpdf traceback +TRANSA trapz treatasempty treelayout treeplot tridiagonal +trimesh triplot trnd +truecolor +TrueColor Tsang Tukey tuples @@ -1008,6 +1066,7 @@ ub UB uchar +UHESS UID uimenu uint @@ -1020,6 +1079,7 @@ unary uncomment Uncomments +unconvertible unformatted unidcdf unidinv @@ -1034,6 +1094,8 @@ Uninstall uninstalled univariate +unix +unnorm unnormalized unpadded unpermuted @@ -1072,6 +1134,7 @@ warndlg Wathen WAV +WayPoints wblcdf wblinv wblpdf @@ -1092,9 +1155,13 @@ Wildcards wildcards Wilks +windowbuttondownfcn +windowbuttonmotionfcn +windowbuttonupfcn windowstyle WinRand WIPO +wireframe wp wspace xb diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/emacs.txi --- a/doc/interpreter/emacs.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/emacs.txi Sat Oct 05 11:22:09 2013 -0400 @@ -44,10 +44,10 @@ or suggestions on using EOS. @menu -* Installing EOS:: -* Using Octave Mode:: -* Running Octave from Within Emacs:: -* Using the Emacs Info Reader for Octave:: +* Installing EOS:: +* Using Octave Mode:: +* Running Octave from Within Emacs:: +* Using the Emacs Info Reader for Octave:: @end menu @node Installing EOS @@ -251,7 +251,7 @@ @samp{,} (@code{Info-index-next}) command of the Info reader. The variable @code{octave-help-files} is a list of files to search -through and defaults to @code{'("octave")}. If there is also an Octave +through and defaults to @qcode{'("octave")}. If there is also an Octave Local Guide with corresponding info file, say, @file{octave-LG}, you can have @code{octave-help} search both files by @lisp @@ -390,7 +390,7 @@ This will start Octave in a special buffer the name of which is specified by the variable @code{inferior-octave-buffer} and defaults to -@code{"*Inferior Octave*"}. From within this buffer, you can +@qcode{"*Inferior Octave*"}. From within this buffer, you can interact with the inferior Octave process `as usual', i.e., by entering Octave commands at the prompt. The buffer is in Inferior Octave mode, which is derived from the standard Comint mode, a major mode for @@ -456,7 +456,7 @@ The variable @code{inferior-octave-startup-args} can be used for specifying command lines arguments to be passed to Octave on startup as a list of strings. For example, to suppress the startup message and -use `traditional' mode, set this to @code{'("-q" "--traditional")}. +use `traditional' mode, set this to @qcode{'("-q" "--traditional")}. You can also specify a startup file of Octave commands to be loaded on startup; note that these commands will not produce any visible output in the process buffer. Which file to use is controlled by the variable diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/errors.txi --- a/doc/interpreter/errors.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/errors.txi Sat Oct 05 11:22:09 2013 -0400 @@ -185,8 +185,8 @@ as will be shown in the next example. To assign an ID to an error, simply call @code{error} with two string arguments, where the first is the identification string, and the second is the actual error. Note -that error IDs are in the format "NAMESPACE:ERROR-NAME". The namespace -"Octave" is used for Octave's own errors. Any other string is available +that error IDs are in the format @qcode{"NAMESPACE:ERROR-NAME"}. The namespace +@qcode{"Octave"} is used for Octave's own errors. Any other string is available as a namespace for user's own errors. The next example counts indexing errors. The errors are caught using the @@ -330,9 +330,9 @@ as will be described in the next section. To assign an ID to a warning, simply call @code{warning} with two string arguments, where the first is the identification string, and the second is the actual warning. Note -that warning IDs are in the format "NAMESPACE:WARNING-NAME". The namespace -"Octave" is used for Octave's own warnings. Any other string is available -as a namespace for user's own warnings. +that warning IDs are in the format @qcode{"NAMESPACE:WARNING-NAME"}. The +namespace @qcode{"Octave"} is used for Octave's own warnings. Any other string +is available as a namespace for user's own warnings. @DOCSTRING(warning) @@ -348,7 +348,7 @@ The @code{warning} function also allows you to control which warnings are actually printed to the screen. If the @code{warning} function -is called with a string argument that is either @code{"on"} or @code{"off"} +is called with a string argument that is either @qcode{"on"} or @qcode{"off"} all warnings will be enabled or disabled. It is also possible to enable and disable individual warnings through diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/eval.txi --- a/doc/interpreter/eval.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/eval.txi Sat Oct 05 11:22:09 2013 -0400 @@ -79,8 +79,8 @@ functions and should not be taken too seriously. In addition to using a more robust algorithm, any serious code would check the number and type of all the arguments, ensure that the supplied function really was a -function, etc. @xref{Predicates for Numeric Objects}, for example, -for a list of predicates for numeric objects, and see @ref{Status of +function, etc. @xref{Predicates for Numeric Objects}, +for a list of predicates for numeric objects, and @pxref{Status of Variables}, for a description of the @code{exist} function. @DOCSTRING(feval) @@ -135,7 +135,7 @@ @noindent Here, @samp{caller} is the @code{create_data} function and @code{name1} -is the string @code{"x"}, which evaluates simply as the value of @code{x}. +is the string @qcode{"x"}, which evaluates simply as the value of @code{x}. You later want to load the values back from @code{mydata} in a different context: diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/expr.txi --- a/doc/interpreter/expr.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/expr.txi Sat Oct 05 11:22:09 2013 -0400 @@ -32,14 +32,14 @@ combinations of these with various operators. @menu -* Index Expressions:: -* Calling Functions:: -* Arithmetic Ops:: -* Comparison Ops:: -* Boolean Expressions:: -* Assignment Ops:: -* Increment Ops:: -* Operator Precedence:: +* Index Expressions:: +* Calling Functions:: +* Arithmetic Ops:: +* Comparison Ops:: +* Boolean Expressions:: +* Assignment Ops:: +* Increment Ops:: +* Operator Precedence:: @end menu @node Index Expressions @@ -385,8 +385,8 @@ expressions. See also @ref{Index Expressions}, and @ref{Assignment Ops}. @menu -* Call by Value:: -* Recursion:: +* Call by Value:: +* Recursion:: @end menu @node Call by Value @@ -433,7 +433,7 @@ @noindent you should not think of the argument as being ``the variable @code{foo}.'' Instead, think of the argument as the string value, -@code{"bar"}. +@qcode{"bar"}. Even though Octave uses pass-by-value semantics for function arguments, values are not copied unnecessarily. For example, @@ -583,7 +583,7 @@ Element-by-element left division. Each element of @var{y} is divided by each corresponding element of @var{x}. -@item @var{x} ^ @var{y} +@item @var{x} ^ @var{y} @itemx @var{x} ** @var{y} @opindex ** @opindex ^ @@ -597,7 +597,7 @@ The implementation of this operator needs to be improved. -@item @var{x} .^ @var{y} +@item @var{x} .^ @var{y} @itemx @var{x} .** @var{y} @opindex .** @opindex .^ @@ -759,7 +759,7 @@ @opindex > True if @var{x} is greater than @var{y}. -@item @var{x} != @var{y} +@item @var{x} != @var{y} @itemx @var{x} ~= @var{y} @opindex != @opindex ~= @@ -796,7 +796,7 @@ @DOCSTRING(isequal) -@DOCSTRING(isequalwithequalnans) +@DOCSTRING(isequaln) @opindex <= @DOCSTRING(le) @@ -823,8 +823,8 @@ @cindex not operator @menu -* Element-by-element Boolean Operators:: -* Short-circuit Boolean Operators:: +* Element-by-element Boolean Operators:: +* Short-circuit Boolean Operators:: @end menu @node Element-by-element Boolean Operators @@ -863,7 +863,7 @@ Elements of the result are true if either of the corresponding elements of @var{boolean1} or @var{boolean2} is true. -@item ! @var{boolean} +@item ! @var{boolean} @itemx ~ @var{boolean} @opindex ~ @opindex ! @@ -1043,7 +1043,7 @@ The @samp{=} sign is called an @dfn{assignment operator}. Assignments can store string values also. For example, the following -expression would store the value @code{"this food is good"} in the +expression would store the value @qcode{"this food is good"} in the variable @code{message}: @example diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/external.txi --- a/doc/interpreter/external.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/external.txi Sat Oct 05 11:22:09 2013 -0400 @@ -104,9 +104,9 @@ bridge to hardware resources which often have device drivers written in C. @menu -* Oct-Files:: -* Mex-Files:: -* Standalone Programs:: +* Oct-Files:: +* Mex-Files:: +* Standalone Programs:: @end menu @node Oct-Files @@ -116,19 +116,19 @@ @cindex oct @menu -* Getting Started with Oct-Files:: -* Matrices and Arrays in Oct-Files:: -* Character Strings in Oct-Files:: -* Cell Arrays in Oct-Files:: -* Structures in Oct-Files:: -* Sparse Matrices in Oct-Files:: -* Accessing Global Variables in Oct-Files:: -* Calling Octave Functions from Oct-Files:: -* Calling External Code from Oct-Files:: -* Allocating Local Memory in Oct-Files:: -* Input Parameter Checking in Oct-Files:: -* Exception and Error Handling in Oct-Files:: -* Documentation and Test of Oct-Files:: +* Getting Started with Oct-Files:: +* Matrices and Arrays in Oct-Files:: +* Character Strings in Oct-Files:: +* Cell Arrays in Oct-Files:: +* Structures in Oct-Files:: +* Sparse Matrices in Oct-Files:: +* Accessing Global Variables in Oct-Files:: +* Calling Octave Functions from Oct-Files:: +* Calling External Code from Oct-Files:: +* Allocating Local Memory in Oct-Files:: +* Input Parameter Checking in Oct-Files:: +* Exception and Error Handling in Oct-Files:: +* Documentation and Test of Oct-Files:: @c * Application Programming Interface for Oct-Files:: @end menu @@ -305,8 +305,8 @@ a resemblance to functions that exist in the interpreter. A selection of useful methods include -@deftypefn Method T& {operator ()} (octave_idx_type) -@deftypefnx Method T& elem (octave_idx_type) +@deftypefn {Method} {T&} operator () (octave_idx_type) +@deftypefnx {Method} {T&} elem (octave_idx_type) The @code{()} operator or @code{elem} method allow the values of the matrix or array to be read or set. These can take a single argument, which is of type @code{octave_idx_type}, that is the index into the matrix or @@ -319,30 +319,30 @@ circumstances the user might prefer to access the data of the array or matrix directly through the @nospell{fortran_vec} method discussed below. -@deftypefn Method octave_idx_type numel (void) const +@deftypefn {Method} {} octave_idx_type numel (void) const The total number of elements in the matrix or array. @end deftypefn -@deftypefn Method size_t byte_size (void) const +@deftypefn {Method} {size_t} byte_size (void) const The number of bytes used to store the matrix or array. @end deftypefn -@deftypefn Method dim_vector dims (void) const +@deftypefn {Method} {dim_vector} dims (void) const The dimensions of the matrix or array in value of type dim_vector. @end deftypefn -@deftypefn Method int ndims (void) const +@deftypefn {Method} {int} ndims (void) const The number of dimensions of the matrix or array. Matrices are 2-D, but arrays can be N-dimensional. @end deftypefn -@deftypefn Method void resize (const dim_vector&) +@deftypefn {Method} {void} resize (const dim_vector&) A method taking either an argument of type @code{dim_vector}, or in the case of a matrix two arguments of type @code{octave_idx_type} defining the number of rows and columns in the matrix. @end deftypefn -@deftypefn Method T* fortran_vec (void) +@deftypefn {Method} {T*} fortran_vec (void) This method returns a pointer to the underlying data of the matrix or array so that it can be manipulated directly, either within Octave or by an external library. @@ -357,9 +357,7 @@ @w{@code{DEFUN_DLD}} function is as follows @example -@group @EXAMPLEFILE(addtwomatrices.cc) -@end group @end example To avoid segmentation faults causing Octave to abort this function @@ -484,9 +482,7 @@ example is @example -@group @EXAMPLEFILE(celldemo.cc) -@end group @end example Note that cell arrays are used less often in standard oct-files and so @@ -584,13 +580,13 @@ more similar to Octave's @code{Matrix} class than its @code{NDArray} class. @menu -* Array and Sparse Differences:: -* Creating Sparse Matrices in Oct-Files:: -* Using Sparse Matrices in Oct-Files:: +* Array and Sparse Class Differences:: +* Creating Sparse Matrices in Oct-Files:: +* Using Sparse Matrices in Oct-Files:: @end menu -@node Array and Sparse Differences -@subsubsection The Differences between the Array and Sparse Classes +@node Array and Sparse Class Differences +@subsubsection Array and Sparse Class Differences The number of elements in a sparse matrix is considered to be the number of non-zero elements rather than the product of the dimensions. Therefore @@ -616,7 +612,7 @@ The use of @code{numel} should therefore be avoided useless it is known it won't overflow. -Extreme care must be take with the elem method and the "()" operator, +Extreme care must be take with the elem method and the @qcode{"()"} operator, which perform basically the same function. The reason is that if a sparse object is non-const, then Octave will assume that a request for a zero element in a sparse matrix is in fact a request @@ -1201,7 +1197,7 @@ The documentation of an oct-file is the fourth string parameter of the @w{@code{DEFUN_DLD}} macro. This string can be formatted in the same manner -as the help strings for user functions (@ref{Documentation Tips}), +as the help strings for user functions (@pxref{Documentation Tips}), however there are some issue that are particular to the formatting of help strings within oct-files. @@ -1231,7 +1227,7 @@ character on the line. Octave also includes the ability to embed test and demonstration -code for a function within the code itself (@ref{Test and Demo Functions}). +code for a function within the code itself (@pxref{Test and Demo Functions}). This can be used from within oct-files (or in fact any file) with certain provisos. First, the test and demo functions of Octave look for @code{%!} as the first two characters of a line to identify test @@ -1274,13 +1270,13 @@ be written with the oct-file interface previously discussed. @menu -* Getting Started with Mex-Files:: -* Working with Matrices and Arrays in Mex-Files:: -* Character Strings in Mex-Files:: -* Cell Arrays with Mex-Files:: -* Structures with Mex-Files:: -* Sparse Matrices with Mex-Files:: -* Calling Other Functions in Mex-Files:: +* Getting Started with Mex-Files:: +* Working with Matrices and Arrays in Mex-Files:: +* Character Strings in Mex-Files:: +* Cell Arrays with Mex-Files:: +* Structures with Mex-Files:: +* Sparse Matrices with Mex-Files:: +* Calling Other Functions in Mex-Files:: @c * Application Programming Interface for Mex-Files:: @end menu @@ -1307,9 +1303,9 @@ The first line @code{#include "mex.h"} makes available all of the definitions necessary for a mex-file. One important difference between Octave and -@sc{matlab} is that the header file @code{"matrix.h"} is implicitly included -through the inclusion of @code{"mex.h"}. This is necessary to avoid a conflict -with the Octave file @code{"Matrix.h"} for operating systems and compilers that +@sc{matlab} is that the header file @qcode{"matrix.h"} is implicitly included +through the inclusion of @qcode{"mex.h"}. This is necessary to avoid a conflict +with the Octave file @qcode{"Matrix.h"} for operating systems and compilers that don't distinguish between filenames in upper and lower case. The entry point into the mex-file is defined by @code{mexFunction}. The @@ -1517,9 +1513,7 @@ as shown below. @example -@group @EXAMPLEFILE(mycell.c) -@end group @end example @noindent @@ -1617,23 +1611,23 @@ b = @{ this = - + (, [1] = this1 [2] = this2 [3] = this3 [4] = this4 ,) - + that = - + (, [1] = that1 [2] = that2 [3] = that3 [4] = that4 ,) - + @} @end example @@ -1737,9 +1731,7 @@ @file{liboctave.so}. @example -@group @EXAMPLEFILE(standalone.cc) -@end group @end example @noindent @@ -1766,9 +1758,7 @@ seen in the code @example -@group @EXAMPLEFILE(embedded.cc) -@end group @end example @noindent diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/func.txi --- a/doc/interpreter/func.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/func.txi Sat Oct 05 11:22:09 2013 -0400 @@ -30,18 +30,18 @@ @menu * Introduction to Function and Script Files:: -* Defining Functions:: -* Multiple Return Values:: -* Variable-length Argument Lists:: -* Ignoring Arguments:: -* Variable-length Return Lists:: -* Returning from a Function:: -* Default Arguments:: -* Function Files:: -* Script Files:: -* Function Handles Inline Functions and Anonymous Functions:: +* Defining Functions:: +* Multiple Return Values:: +* Variable-length Argument Lists:: +* Ignoring Arguments:: +* Variable-length Return Lists:: +* Returning from a Function:: +* Default Arguments:: +* Function Files:: +* Script Files:: +* Function Handles Anonymous Functions Inline Functions:: * Commands:: -* Organization of Functions:: +* Organization of Functions:: @end menu @node Introduction to Function and Script Files @@ -114,7 +114,7 @@ @end example The @code{printf} statement (@pxref{Input and Output}) simply tells -Octave to print the string @code{"\a"}. The special character @samp{\a} +Octave to print the string @qcode{"\a"}. The special character @samp{\a} stands for the alert character (ASCII 7). @xref{Strings}. Once this function is defined, you can ask Octave to evaluate it by @@ -325,7 +325,7 @@ It is possible to use the @code{nthargout} function to obtain only some of the return values or several at once in a cell array. -@ref{Cell Array Objects} +@xref{Cell Array Objects}. @DOCSTRING(nthargout) @@ -402,7 +402,7 @@ @DOCSTRING(nargoutchk) -@anchor{docXvarargin} @anchor{docXvarargout} +@anchor{XREFvarargin} @anchor{XREFvarargout} @node Variable-length Argument Lists @section Variable-length Argument Lists @cindex variable-length argument lists @@ -737,7 +737,7 @@ running Octave, you can improve performance by calling @code{ignore_function_time_stamp ("all")}, so that Octave will ignore the time stamps for all function files. Passing -@code{"system"} to this function resets the default behavior. +@qcode{"system"} to this function resets the default behavior. @c FIXME -- note about time stamps on files in NFS environments? @@ -1150,7 +1150,7 @@ A function that has been defined on the command-line. @item Autoload function -A function that is marked as autoloaded with @xref{docXautoload}. +A function that is marked as autoloaded with @xref{XREFautoload,,autoload}. @item A Function on the Path A function that can be found on the users load-path. There can also be @@ -1266,11 +1266,11 @@ @DOCSTRING(source) -@node Function Handles Inline Functions and Anonymous Functions -@section Function Handles, Inline Functions, and Anonymous Functions +@node Function Handles Anonymous Functions Inline Functions +@section Function Handles, Anonymous Functions, Inline Functions @cindex handle, function handles +@cindex anonymous functions @cindex inline, inline functions -@cindex anonymous functions It can be very convenient store a function in a variable so that it can be passed to a different function. For example, a function that diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/geometryimages.m --- a/doc/interpreter/geometryimages.m Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/geometryimages.m Sat Oct 05 11:22:09 2013 -0400 @@ -26,20 +26,19 @@ if (strcmp (typ, "eps")) d_typ = "-depsc2"; else - d_typ = cstrcat ("-d", typ); + d_typ = ["-d" typ]; endif if (! __have_feature__ ("QHULL") - && (strcmp (nm, "voronoi") || strcmp (nm, "griddata") - || strcmp (nm, "convhull") || strcmp (nm, "delaunay") - || strcmp (nm, "triplot"))) - sombreroimage (nm, typ); + && any (strcmp (nm, {"voronoi", "griddata", "convhull", "delaunay", ... + "triplot"}))) + sombreroimage (nm, typ, d_typ); elseif (strcmp (typ, "txt")) image_as_txt (nm); elseif (strcmp (nm, "voronoi")) - rand("state",9); - x = rand(10,1); - y = rand(10,1); + rand ("state", 9); + x = rand (10, 1); + y = rand (10, 1); tri = delaunay (x, y); [vx, vy] = voronoi (x, y, tri); triplot (tri, x, y, "b"); @@ -47,34 +46,34 @@ plot (vx, vy, "r"); [r, c] = tri2circ (tri(end,:), x, y); pc = [-1:0.01:1]; - xc = r * sin(pi*pc) + c(1); - yc = r * cos(pi*pc) + c(2); + xc = r * sin (pi*pc) + c(1); + yc = r * cos (pi*pc) + c(2); plot (xc, yc, "g-", "LineWidth", 3); axis([0, 1, 0, 1]); legend ("Delaunay Triangulation", "Voronoi Diagram"); - print (cstrcat (nm, ".", typ), d_typ) + print ([nm "." typ], d_typ); elseif (strcmp (nm, "triplot")) rand ("state", 2) x = rand (20, 1); y = rand (20, 1); tri = delaunay (x, y); triplot (tri, x, y); - print (cstrcat (nm, ".", typ), d_typ) + print ([nm "." typ], d_typ); elseif (strcmp (nm, "griddata")) - rand("state",1); - x=2*rand(1000,1)-1; - y=2*rand(size(x))-1; - z=sin(2*(x.^2+y.^2)); - [xx,yy]=meshgrid(linspace(-1,1,32)); - griddata(x,y,z,xx,yy); - print (cstrcat (nm, ".", typ), d_typ) + rand ("state", 1); + x = 2 * rand (1000,1) - 1; + y = 2 * rand (size (x)) - 1; + z = sin (2 * (x.^2 + y.^2)); + [xx,yy] = meshgrid (linspace (-1,1,32)); + griddata (x,y,z,xx,yy); + print ([nm "." typ], d_typ); elseif (strcmp (nm, "convhull")) x = -3:0.05:3; y = abs (sin (x)); k = convhull (x, y); - plot (x(k),y(k),'r-',x,y,'b+'); + plot (x(k),y(k),'r-', x,y,'b+'); axis ([-3.05, 3.05, -0.05, 1.05]); - print (cstrcat (nm, ".", typ), d_typ) + print ([nm "." typ], d_typ); elseif (strcmp (nm, "delaunay")) rand ("state", 1); x = rand (1, 10); @@ -83,8 +82,8 @@ X = [ x(T(:,1)); x(T(:,2)); x(T(:,3)); x(T(:,1)) ]; Y = [ y(T(:,1)); y(T(:,2)); y(T(:,3)); y(T(:,1)) ]; axis ([0, 1, 0, 1]); - plot(X, Y, "b", x, y, "r*"); - print (cstrcat (nm, ".", typ), d_typ) + plot (X,Y,"b", x,y,"r*"); + print ([nm "." typ], d_typ); elseif (strcmp (nm, "inpolygon")) randn ("state", 2); x = randn (100, 1); @@ -92,9 +91,9 @@ vx = cos (pi * [-1 : 0.1: 1]); vy = sin (pi * [-1 : 0.1 : 1]); in = inpolygon (x, y, vx, vy); - plot(vx, vy, x(in), y(in), "r+", x(!in), y(!in), "bo"); + plot (vx, vy, x(in), y(in), "r+", x(!in), y(!in), "bo"); axis ([-2, 2, -2, 2]); - print (cstrcat (nm, ".", typ), d_typ) + print ([nm "." typ], d_typ); else error ("unrecognized plot requested"); endif @@ -129,7 +128,7 @@ set (f, "visible", "off"); endfunction -function sombreroimage (nm, typ) +function sombreroimage (nm, typ, d_typ) if (strcmp (typ, "txt")) fid = fopen (sprintf ("%s.txt", nm), "wt"); fputs (fid, "+-----------------------------+\n"); @@ -141,28 +140,20 @@ else ## if (!strcmp (typ, "txt")) hide_output (); - if (strcmp (typ, "eps")) - d_typ = "-depsc2"; - else - d_typ = cstrcat ("-d", typ); - endif - x = y = linspace (-8, 8, 41)'; - [xx, yy] = meshgrid (x, y); - r = sqrt (xx .^ 2 + yy .^ 2) + eps; - z = sin (r) ./ r; + [x, y, z] = sombrero (); unwind_protect mesh (x, y, z); title ("Sorry, graphics not available because octave was\\ncompiled without the QHULL library."); unwind_protect_cleanup - print (cstrcat (nm, ".", typ), d_typ); + print ([nm "." typ], d_typ); hide_output (); end_unwind_protect endif endfunction ## generate something for the texinfo @image command to process -function image_as_txt(nm) +function image_as_txt (nm) fid = fopen (sprintf ("%s.txt", nm), "wt"); fputs (fid, "\n"); fputs (fid, "+---------------------------------+\n"); @@ -170,3 +161,4 @@ fputs (fid, "+---------------------------------+\n"); fclose (fid); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/grammar.txi --- a/doc/interpreter/grammar.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/grammar.txi Sat Oct 05 11:22:09 2013 -0400 @@ -25,8 +25,8 @@ Octave's language. @menu -* Keywords:: -* Parser:: +* Keywords:: +* Parser:: @end menu @node Keywords @@ -78,9 +78,9 @@ @DOCSTRING(remove_input_event_hook) Finally, when the parser cannot identify an input token it calls a particular -function to handle this. By default, this is the function "unimplemented" -which makes suggestions about possible Octave substitutes for @sc{matlab} -functions. +function to handle this. By default, this is the internal function +@qcode{"__unimplemented__"} which makes suggestions about possible Octave +substitutes for @sc{matlab} functions. @DOCSTRING(missing_function_hook) diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/gui.txi --- a/doc/interpreter/gui.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/gui.txi Sat Oct 05 11:22:09 2013 -0400 @@ -36,10 +36,10 @@ preferences. @menu -* I/O Dialogs:: -* Progress Bar:: -* GUI Utility Functions:: -* User-Defined Preferences:: +* I/O Dialogs:: +* Progress Bar:: +* GUI Utility Functions:: +* User-Defined Preferences:: @end menu @node I/O Dialogs @@ -81,13 +81,17 @@ @node User-Defined Preferences @section User-Defined Preferences +@DOCSTRING(getpref) + +@DOCSTRING(setpref) + @DOCSTRING(addpref) -@DOCSTRING(getpref) +@DOCSTRING(rmpref) @DOCSTRING(ispref) -@DOCSTRING(rmpref) +@DOCSTRING(prefdir) -@DOCSTRING(setpref) +@DOCSTRING(preferences) diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/image.txi --- a/doc/interpreter/image.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/image.txi Sat Oct 05 11:22:09 2013 -0400 @@ -19,7 +19,7 @@ @node Image Processing @chapter Image Processing -Since an image basically is a matrix Octave is a very powerful +Since an image is basically a matrix, Octave is a very powerful environment for processing and analyzing images. To illustrate how easy it is to do image processing in Octave, the following example will load an image, smooth it by a 5-by-5 averaging filter, @@ -38,20 +38,19 @@ and @code{Dy} contains the partial spatial derivatives of the image. @menu -* Loading and Saving Images:: -* Displaying Images:: -* Representing Images:: -* Plotting on top of Images:: -* Color Conversion:: +* Loading and Saving Images:: +* Displaying Images:: +* Representing Images:: +* Plotting on top of Images:: +* Color Conversion:: @end menu @node Loading and Saving Images @section Loading and Saving Images The first step in most image processing tasks is to load an image -into Octave. This is done using the @code{imread} function, which uses the -@code{GraphicsMagick} library for reading. This means a vast number of image -formats is supported. The @code{imwrite} function is the corresponding function +into Octave which is done with the @code{imread} function. +The @code{imwrite} function is the corresponding function for writing images to the disk. In summary, most image processing code will follow the structure of this code @@ -77,6 +76,30 @@ @DOCSTRING(imfinfo) +By default, Octave's image IO functions (@code{imread}, @code{imwrite}, +and @code{imfinfo}) use the @code{GraphicsMagick} library for their +operations. This means a vast number of image formats is supported +but considering the large amount of image formats in science and +its commonly closed nature, it is impossible to have a library +capable of reading them all. Because of this, the function +@code{imformats} keeps a configurable list of available formats, +their extensions, and what functions should the image IO functions +use. This allows to expand Octave's image IO capabilities by +creating functions aimed at acting on specific file formats. + +While it would be possible to call the extra functions directly, +properly configuring Octave with @code{imformats} allows to keep a +consistent code that is abstracted from file formats. + +It is important to note that a file format is not actually defined by its +file extension and that @code{GraphicsMagick} is capable to read and write +more file formats than the ones listed by @code{imformats}. What this +means is that even with an incorrect or missing extension the image may +still be read correctly, and that even unlisted formats are not necessarily +unsupported. + +@DOCSTRING(imformats) + @node Displaying Images @section Displaying Images @@ -181,7 +204,7 @@ @DOCSTRING(gmap40) The following three functions modify the existing colormap rather than -replace it. +replace it. @DOCSTRING(brighten) diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/install.txi --- a/doc/interpreter/install.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/install.txi Sat Oct 05 11:22:09 2013 -0400 @@ -25,6 +25,7 @@ @end ifclear @ifset INSTALLONLY +@include macros.texi This file documents the installation of Octave. @@ -179,7 +180,7 @@ @table @asis @item BLAS Basic Linear Algebra Subroutine library -(@url{http://www.netlib.org/blas}). Accelerated BLAS libraries such as +(@url{http://www.netlib.org/blas}). Accelerated @sc{blas} libraries such as ATLAS (@url{http://math-atlas.sourceforge.net}) are recommeded for better performance. @@ -205,7 +206,7 @@ @table @asis @item ARPACK Library for the solution of large-scale eigenvalue problems -(@url{http://forge.scilab.org/index.php/p/arpack-ng}). ARPACK is +(@url{http://forge.scilab.org/index.php/p/arpack-ng}). @sc{arpack} is required to provide the functions @code{eigs} and @code{svds}. @item cURL @@ -247,7 +248,7 @@ @item HDF5 Library for manipulating portable data files -(@url{http://www.hdfgroup.org/HDF5}). HDF5 is required for Octave's +(@url{http://www.hdfgroup.org/HDF5}). @sc{hdf5} is required for Octave's @code{load} and @code{save} commands to read and write HDF data files. @item LLVM @@ -383,7 +384,7 @@ @item --with-magick= Select the library to use for image I/O@. The two possible values are -"GraphicsMagick" (default) or "ImageMagick". +@qcode{"GraphicsMagick"} (default) or @qcode{"ImageMagick"}. @item --with-sepchar= Use as the path separation character. This option can help when @@ -517,7 +518,7 @@ known problems below to see if there is a workaround or solution for your problem. If not, @ifclear INSTALLONLY -see @ref{Trouble}, +@pxref{Trouble}, @end ifclear @ifset INSTALLONLY see the file BUGS @@ -569,7 +570,7 @@ @end table @end itemize -@node Compiling Octave with 64-bit Indexing +@node Compiling Octave with 64-bit Indexing @section Compiling Octave with 64-bit Indexing Note: the following only applies to systems that have 64-bit pointers. @@ -1064,7 +1065,7 @@ @env{CFLAGS}, @env{CXXFLAGS}, @env{FFLAGS}, and @env{LDFLAGS}. Passing them as options to the configure script also records them in the @file{config.status} file. By default, @env{CPPFLAGS} and @env{LDFLAGS} -are empty, @env{CFLAGS} and @env{CXXFLAGS} are set to @code{"-g -O"} and -@env{FFLAGS} is set to @code{"-O"}. +are empty, @env{CFLAGS} and @env{CXXFLAGS} are set to @qcode{"-g -O"} and +@env{FFLAGS} is set to @qcode{"-O"}. @end itemize diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/interp.txi --- a/doc/interpreter/interp.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/interp.txi Sat Oct 05 11:22:09 2013 -0400 @@ -29,18 +29,18 @@ Octave supports several methods for one-dimensional interpolation, most of which are described in this section. @ref{Polynomial Interpolation} -and @ref{Interpolation on Scattered Data} describe further methods. +and @ref{Interpolation on Scattered Data} describe additional methods. @DOCSTRING(interp1) There are some important differences between the various interpolation -methods. The 'spline' method enforces that both the first and second +methods. The @qcode{"spline"} method enforces that both the first and second derivatives of the interpolated values have a continuous derivative, whereas the other methods do not. This means that the results of the -'spline' method are generally smoother. If the function to be -interpolated is in fact smooth, then 'spline' will give excellent +@qcode{"spline"} method are generally smoother. If the function to be +interpolated is in fact smooth, then @qcode{"spline"} will give excellent results. However, if the function to be evaluated is in some manner -discontinuous, then 'pchip' interpolation might give better results. +discontinuous, then @qcode{"pchip"} interpolation might give better results. This can be demonstrated by the code @@ -51,16 +51,16 @@ ti =-2:0.025:2; dti = 0.025; y = sign (t); -ys = interp1 (t,y,ti,'spline'); -yp = interp1 (t,y,ti,'pchip'); +ys = interp1 (t,y,ti,"spline"); +yp = interp1 (t,y,ti,"pchip"); ddys = diff (diff (ys)./dti) ./ dti; ddyp = diff (diff (yp)./dti) ./ dti; figure (1); plot (ti,ys,'r-', ti,yp,'g-'); -legend ('spline', 'pchip', 4); +legend ("spline", "pchip", 4); figure (2); plot (ti,ddys,'r+', ti,ddyp,'g*'); -legend ('spline', 'pchip'); +legend ("spline", "pchip"); @end group @end example @@ -71,13 +71,13 @@ @float Figure,fig:interpderiv1 @center @image{interpderiv1,4in} -@caption{Comparison of 'pchip' and 'spline' interpolation methods for a +@caption{Comparison of @qcode{"pchip"} and @qcode{"spline"} interpolation methods for a step function} @end float @float Figure,fig:interpderiv2 @center @image{interpderiv2,4in} -@caption{Comparison of the second derivative of the 'pchip' and 'spline' +@caption{Comparison of the second derivative of the @qcode{"pchip"} and @qcode{"spline"} interpolation methods for a step function} @end float @end ifnotinfo @@ -107,9 +107,9 @@ ti = t(1) + [0 : k-1]*dt*n/k; y = sin (4*t + 0.3) .* cos (3*t - 0.1); yp = sin (4*ti + 0.3) .* cos (3*ti - 0.1); -plot (ti, yp, 'g', ti, interp1 (t, y, ti, 'spline'), 'b', ... - ti, interpft (y, k), 'c', t, y, 'r+'); -legend ('sin(4t+0.3)cos(3t-0.1', 'spline', 'interpft', 'data'); +plot (ti, yp, "g", ti, interp1 (t, y, ti, "spline"), "b", ... + ti, interpft (y, k), "c", t, y, 'r+'); +legend ('sin(4t+0.3)cos(3t-0.1', "spline", "interpft", "data"); @end group @end example @@ -128,9 +128,8 @@ @end float @end ifnotinfo -In additional the support function @code{spline} and @code{lookup} that +In addition, the support functions @code{spline} and @code{lookup} that underlie the @code{interp1} function can be called directly. -@ref{Finding Elements and Checking Conditions} @DOCSTRING(spline) @@ -149,12 +148,11 @@ A significant difference between @code{interpn} and the other two multi-dimensional interpolation functions is the fashion in which the -dimensions are treated. For @code{interp2} and @code{interp3}, the 'y' -axis is considered to be the columns of the matrix, whereas the 'x' -axis corresponds to the rows of the array. As Octave indexes arrays in -column major order, the first dimension of any array is the columns, and -so @code{interpn} effectively reverses the 'x' and 'y' dimensions. -Consider the example, +dimensions are treated. For @code{interp2} and @code{interp3}, the y-axis is +considered to be the columns of the matrix, whereas the x-axis corresponds to +the rows of the array. As Octave indexes arrays in column major order, the +first dimension of any array is the columns, and so @code{interpn} effectively +reverses the 'x' and 'y' dimensions. Consider the example, @example @group @@ -164,9 +162,9 @@ v = f (xx,yy,zz); xi = yi = zi = -1:0.1:1; [xxi, yyi, zzi] = meshgrid (xi, yi, zi); -vi = interp3 (x, y, z, v, xxi, yyi, zzi, 'spline'); +vi = interp3 (x, y, z, v, xxi, yyi, zzi, "spline"); [xxi, yyi, zzi] = ndgrid (xi, yi, zi); -vi2 = interpn (x, y, z, v, xxi, yyi, zzi, 'spline'); +vi2 = interpn (x, y, z, v, xxi, yyi, zzi, "spline"); mesh (zi, yi, squeeze (vi2(1,:,:))); @end group @end example diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/interpimages.m --- a/doc/interpreter/interpimages.m Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/interpimages.m Sat Oct 05 11:22:09 2013 -0400 @@ -26,7 +26,7 @@ if (strcmp (typ, "eps")) d_typ = "-depsc2"; else - d_typ = cstrcat ("-d", typ); + d_typ = ["-d", typ]; endif if (strcmp (typ, "txt")) @@ -37,10 +37,10 @@ ti = t(1) + [0 : k-1]*dt*n/k; y = sin (4*t + 0.3) .* cos (3*t - 0.1); yp = sin (4*ti + 0.3) .* cos (3*ti - 0.1); - plot (ti, yp, 'g', ti, interp1(t, y, ti, 'spline'), 'b', ... - ti, interpft (y, k), 'c', t, y, 'r+'); - legend ('sin(4t+0.3)cos(3t-0.1)','spline','interpft','data'); - print (cstrcat (nm, ".", typ), d_typ) + plot (ti, yp, "g", ti, interp1 (t, y, ti, "spline"), "b", ... + ti, interpft (y, k), "c", t, y, "r+"); + legend ("sin(4t+0.3)cos(3t-0.1)", "spline", "interpft", "data"); + print ([nm "." typ], d_typ); elseif (strcmp (nm, "interpn")) x = y = z = -1:1; f = @(x,y,z) x.^2 - y - z.^2; @@ -48,31 +48,31 @@ v = f (xx,yy,zz); xi = yi = zi = -1:0.1:1; [xxi, yyi, zzi] = ndgrid (xi, yi, zi); - vi = interpn(x, y, z, v, xxi, yyi, zzi, 'spline'); + vi = interpn (x, y, z, v, xxi, yyi, zzi, "spline"); mesh (zi, yi, squeeze (vi(1,:,:))); - print (cstrcat (nm, ".", typ), d_typ) + print ([nm "." typ], d_typ); elseif (strcmp (nm, "interpderiv1")) t = -2:2; dt = 1; ti =-2:0.025:2; dti = 0.025; - y = sign(t); - ys = interp1(t,y,ti,'spline'); - yp = interp1(t,y,ti,'pchip'); - plot (ti, ys,'r-', ti, yp,'g-'); - legend('spline','pchip', 4); - print (cstrcat (nm, ".", typ), d_typ) + y = sign (t); + ys = interp1 (t,y,ti,"spline"); + yp = interp1 (t,y,ti,"pchip"); + plot (ti, ys,"r-", ti, yp,"g-"); + legend ("spline","pchip", 4); + print ([nm "." typ], d_typ); elseif (strcmp (nm, "interpderiv2")) t = -2:2; dt = 1; ti =-2:0.025:2; dti = 0.025; - y = sign(t); - ddys = diff(diff(interp1(t,y,ti,'spline'))./dti)./dti; - ddyp = diff(diff(interp1(t,y,ti,'pchip'))./dti)./dti; - plot (ti(2:end-1),ddys,'r*', ti(2:end-1),ddyp,'g+'); - legend('spline','pchip'); - print (cstrcat (nm, ".", typ), d_typ) + y = sign (t); + ddys = diff (diff (interp1 (t,y,ti,"spline"))./dti)./dti; + ddyp = diff (diff (interp1 (t,y,ti,"pchip"))./dti)./dti; + plot (ti(2:end-1),ddys,"r*", ti(2:end-1),ddyp,"g+"); + legend ("spline", "pchip"); + print ([nm "." typ], d_typ); endif hide_output (); endfunction @@ -103,3 +103,4 @@ fputs (fid, "+---------------------------------+\n"); fclose (fid); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/intro.txi --- a/doc/interpreter/intro.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/intro.txi Sat Oct 05 11:22:09 2013 -0400 @@ -29,7 +29,7 @@ GNU Octave is freely redistributable software. You may redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. The GPL is included in -this manual in @ref{Copying}. +this manual, @pxref{Copying}. This manual provides comprehensive documentation on how to install, run, use, and extend GNU Octave. Additional chapters describe how @@ -38,9 +38,9 @@ This document corresponds to Octave version @value{VERSION}. @menu -* Running Octave:: -* Simple Examples:: -* Conventions:: +* Running Octave:: +* Simple Examples:: +* Conventions:: @end menu @node Running Octave @@ -374,7 +374,7 @@ on the line, etc. A complete description of the command line editing capability is given -in this manual in @ref{Command Line Editing}. +in this manual, @pxref{Command Line Editing}. @subsection Help and Documentation @@ -410,7 +410,7 @@ text of the printed manual from within Octave normally uses a separate program called Info. When you invoke Info you will be put into a menu driven program that contains the entire Octave manual. Help for using -Info is provided in this manual in @ref{Getting Help}. +Info is provided in this manual, @pxref{Getting Help}. @node Conventions @section Conventions @@ -419,11 +419,11 @@ manual. You may want to skip this section and refer back to it later. @menu -* Fonts:: -* Evaluation Notation:: -* Printing Notation:: -* Error Messages:: -* Format of Descriptions:: +* Fonts:: +* Evaluation Notation:: +* Printing Notation:: +* Error Messages:: +* Format of Descriptions:: @end menu @node Fonts @@ -532,23 +532,22 @@ @subsection Format of Descriptions @cindex description format -Functions, commands, and variables are described in this manual in a +Functions and commands are described in this manual in a uniform format. The first line of a description contains the name of the item followed by its arguments, if any. @ifnottex -The category---function, variable, or whatever---appears at the +The category---function, command, or whatever---appears at the beginning of the line. @end ifnottex @iftex -The category---function, variable, or whatever---is printed next to the +The category---function, command, or whatever---is printed next to the right margin. @end iftex The description follows on succeeding lines, sometimes with examples. @menu -* A Sample Function Description:: -* A Sample Command Description:: -* A Sample Variable Description:: +* A Sample Function Description:: +* A Sample Command Description:: @end menu @node A Sample Function Description @@ -643,27 +642,3 @@ printed and the working directory is not changed. @end deftypefn -@node A Sample Variable Description -@subsubsection A Sample Variable Description -@cindex variable descriptions - -A @dfn{variable} is a name that can hold a value. Although any variable -can be set by the user, @dfn{built-in variables} typically exist -specifically so that users can change them to alter the way Octave -behaves (built-in variables are also sometimes called @dfn{user -options}). Ordinary variables and built-in variables are described -using a format like that for functions except that there are no -arguments. - -Here is a description of the imaginary variable -@code{do_what_i_mean_not_what_i_say}. - -@defvr {Built-in Variable} do_what_i_mean_not_what_i_say -If the value of this variable is nonzero, Octave will do what you -actually wanted, even if you have typed a completely different and -meaningless list of commands. -@end defvr - -Other variable descriptions have the same format, but `Built-in -Variable' is replaced by `Variable', for ordinary variables, or -`Constant' for symbolic constants whose values cannot be changed. diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/io.txi --- a/doc/interpreter/io.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/io.txi Sat Oct 05 11:22:09 2013 -0400 @@ -26,8 +26,8 @@ after the C standard library are also provided by Octave. @menu -* Basic Input and Output:: -* C-Style I/O Functions:: +* Basic Input and Output:: +* C-Style I/O Functions:: @end menu @node Basic Input and Output @@ -36,9 +36,9 @@ @c We could use a two-line introduction here... @menu -* Terminal Output:: -* Terminal Input:: -* Simple File I/O:: +* Terminal Output:: +* Terminal Input:: +* Simple File I/O:: @end menu @node Terminal Output @@ -284,25 +284,25 @@ @DOCSTRING(stderr) @menu -* Opening and Closing Files:: -* Simple Output:: -* Line-Oriented Input:: -* Formatted Output:: -* Output Conversion for Matrices:: -* Output Conversion Syntax:: -* Table of Output Conversions:: -* Integer Conversions:: +* Opening and Closing Files:: +* Simple Output:: +* Line-Oriented Input:: +* Formatted Output:: +* Output Conversion for Matrices:: +* Output Conversion Syntax:: +* Table of Output Conversions:: +* Integer Conversions:: * Floating-Point Conversions:: -* Other Output Conversions:: -* Formatted Input:: -* Input Conversion Syntax:: -* Table of Input Conversions:: -* Numeric Input Conversions:: -* String Input Conversions:: -* Binary I/O:: -* Temporary Files:: -* EOF and Errors:: -* File Positioning:: +* Other Output Conversions:: +* Formatted Input:: +* Input Conversion Syntax:: +* Table of Input Conversions:: +* Numeric Input Conversions:: +* String Input Conversions:: +* Binary I/O:: +* Temporary Files:: +* EOF and Errors:: +* File Positioning:: @end menu @node Opening and Closing Files @@ -702,8 +702,8 @@ followed by a digit. The following flags can be used to modify the behavior: +@c Not @samp so we can have ' ' as an item. -@c Not @samp so we can have ' ' as an item. @table @asis @item @samp{-} Left-justify the result in the field. Normally the result is @@ -977,9 +977,9 @@ @end example @noindent -with the conversion @samp{%10c} produces @code{" hello, wo"}, but +with the conversion @samp{%10c} produces @qcode{" hello, wo"}, but reading the same input with the conversion @samp{%10s} produces -@code{"hello,"}. +@qcode{"hello,"}. @node Binary I/O @subsection Binary I/O @@ -1008,7 +1008,7 @@ @DOCSTRING(tmpnam) -@node EOF and Errors, File Positioning, Temporary Files, C-Style I/O Functions +@node EOF and Errors @subsection End of File and Errors Once a file has been opened its status can be acquired. As an example diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/java.txi --- a/doc/interpreter/java.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/java.txi Sat Oct 05 11:22:09 2013 -0400 @@ -145,13 +145,13 @@ * How to make Java classes available?:: * How to create an instance of a Java class?:: * How can I handle memory limitations?:: -* Which @TeX{} symbols are implemented in the dialog functions?:: +* Which @TeX{} symbols are implemented in dialog functions?:: @end menu @c ------------------------------------------------------------------------ @node How to distinguish between Octave and Matlab? @subsection How to distinguish between Octave and Matlab? -@anchor{docXFAQ} +@anchor{XREFFAQ} @c - index - @cindex Octave and @sc{matlab}, how to distinguish between @c - index - @@ -234,7 +234,7 @@ @item Finally, Octave looks for a next occurrence of file @file{javaclasspath.txt} in the m-files directory where Octave Java functions live. This is where @file{javaclasspath.m} resides, usually something like -@file{@env{OCTAVE_HOME}/share/octave/@env{OCTAVE_VERSION}/m/java/}. You can +@file{@w{@env{OCTAVE_HOME}}/share/octave/@w{@env{OCTAVE_VERSION}}/m/java/}. You can find this directory by executing the command @example @@ -316,7 +316,7 @@ In order to execute Java code Octave creates a Java Virtual Machine (JVM). Such a JVM allocates a fixed amount of initial memory and may expand this pool up to a fixed maximum memory limit. The default values depend on the Java -version (see @ref{docXjavamem,,javamem}). The memory pool is shared by all +version (@pxref{XREFjavamem,,javamem}). The memory pool is shared by all Java objects running in the JVM@. This strict memory limit is intended mainly to avoid that runaway applications inside web browsers or in enterprise servers can consume all memory and crash the system. When the maximum memory limit is @@ -330,7 +330,7 @@ The directory where the Java options file is located is specified by the environment variable @w{@env{OCTAVE_JAVA_DIR}}. If unset the directory where @file{javaclasspath.m} resides is used instead (typically -@file{@env{OCTAVE_HOME}/share/octave/@env{OCTAVE_VERSION}/m/java/}). You can +@file{@w{@env{OCTAVE_HOME}}/share/octave/@w{@env{OCTAVE_VERSION}}/m/java/}). You can find this directory by executing @example @@ -385,8 +385,8 @@ @seealso{javamem} @c ------------------------------------------------------------------------ -@node Which @TeX{} symbols are implemented in the dialog functions? -@subsection Which @TeX{} symbols are implemented in the dialog functions? +@node Which @TeX{} symbols are implemented in dialog functions? +@subsection Which @TeX{} symbols are implemented in dialog functions? @c - index - @cindex symbols, translation table @cindex @TeX{} symbols, translation table diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/linalg.txi --- a/doc/interpreter/linalg.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/linalg.txi Sat Oct 05 11:22:09 2013 -0400 @@ -26,9 +26,9 @@ @menu * Techniques Used for Linear Algebra:: -* Basic Matrix Functions:: -* Matrix Factorizations:: -* Functions of a Matrix:: +* Basic Matrix Functions:: +* Matrix Factorizations:: +* Functions of a Matrix:: * Specialized Solvers:: @end menu @@ -96,6 +96,8 @@ @DOCSTRING(inv) +@DOCSTRING(linsolve) + @DOCSTRING(matrix_type) @DOCSTRING(norm) diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/macros.texi --- a/doc/interpreter/macros.texi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/macros.texi Sat Oct 05 11:22:09 2013 -0400 @@ -16,12 +16,27 @@ @c along with Octave; see the file COPYING. If not, see @c . -@c FIXME -- someday, we might replace this with @backslashchar, which -@c has been added to Texinfo. +@c The following macro marks words that aspell should ignore during +@c spellchecking. Within Texinfo it has no effect as it merely replaces +@c the macro call with the argument itself. + +@macro nospell {arg} +\arg\ +@end macro -@macro xbackslashchar -\\ +@c The following macro works around the Info/plain text expansion of @code{XXX} +@c which is `XXX'. This looks particularly bad when the macro body is +@c single or double-quoted text, such as a property value `"position"' +@ifinfo +@macro qcode{arg} +\arg\ @end macro +@end ifinfo +@ifnotinfo +@macro qcode{arg} +@code{\arg\} +@end macro +@end ifnotinfo @c The following macro is used for the on-line help system, but we don't @c want lots of `See also: foo, bar, and baz' strings cluttering the @@ -30,7 +45,7 @@ @c @c Implementation Note: @c For TeX, @vskip produces a nice separation. -@c For Texinfo '@sp 1' should work, but in practice produces ugly results +@c For Texinfo, '@sp 1' should work, but in practice produces ugly results @c for HTML. We use a simple blank line to produce the correct behavior. @macro seealso {args} @@ -40,34 +55,34 @@ @ifnottex @end ifnottex -@ifinfo -@noindent -See also: \args\. -@end ifinfo @ifnotinfo @noindent @strong{See also:} \args\. @end ifnotinfo -@end macro - -@c The following macro marks words that aspell should ignore during -@c spellchecking. Within Texinfo it has no effect as it merely replaces -@c the macro call with the argument itself. - -@macro nospell {arg} -\arg\ +@ifinfo +@noindent +See also: \args\. +@end ifinfo @end macro @c The following macro works around a situation where the Info/plain text @c expansion of the @code{XXX} macro is `XXX'. The use of the apostrophe @c can be confusing if the code segment itself ends with a transpose operator. @ifinfo -@macro xcode{arg} +@macro tcode{arg} \arg\ @end macro @end ifinfo @ifnotinfo -@macro xcode{arg} +@macro tcode{arg} @code{\arg\} @end macro @end ifnotinfo + +@c FIXME: someday, when Texinfo 5.X is standard, we might replace this with +@c @backslashchar, which is a new addition to Texinfo. + +@macro xbackslashchar +\\ +@end macro + diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/matrix.txi --- a/doc/interpreter/matrix.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/matrix.txi Sat Oct 05 11:22:09 2013 -0400 @@ -27,10 +27,10 @@ lower-triangular parts, or sort the columns of a matrix. @menu -* Finding Elements and Checking Conditions:: -* Rearranging Matrices:: -* Special Utility Matrices:: -* Famous Matrices:: +* Finding Elements and Checking Conditions:: +* Rearranging Matrices:: +* Special Utility Matrices:: +* Famous Matrices:: @end menu @node Finding Elements and Checking Conditions @@ -77,7 +77,7 @@ @DOCSTRING(common_size) @DOCSTRING(find) - + @DOCSTRING(lookup) If you wish to check if a variable exists at all, instead of properties @@ -124,7 +124,7 @@ @DOCSTRING(nth_element) -@anchor{docXtriu} +@anchor{XREFtriu} @DOCSTRING(tril) @DOCSTRING(vec) @@ -174,7 +174,7 @@ The generators operate in the new or old style together, it is not possible to mix the two. Initializing any generator with -@code{"state"} or @code{"seed"} causes the others to switch to the +@qcode{"state"} or @qcode{"seed"} causes the others to switch to the same style for future calls. The state of each generator is independent and calls to different @@ -208,7 +208,7 @@ @noindent produce equivalent results. When the generators are initialized in -the old style with @code{"seed"} only @code{rand} and @code{randn} are +the old style with @qcode{"seed"} only @code{rand} and @code{randn} are independent, because the old @code{rande}, @code{randg} and @code{randp} generators make calls to @code{rand} and @code{randn}. diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/mk_doc_cache.m --- a/doc/interpreter/mk_doc_cache.m Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/mk_doc_cache.m Sat Oct 05 11:22:09 2013 -0400 @@ -24,7 +24,7 @@ docstrings_files = args(2:end); ## Special character used as break between DOCSTRINGS -doc_delim = char (31); +doc_delim = char (0x1d); ## Read the contents of all the DOCSTRINGS files into TEXT. ## It is more efficient to fork to shell for makeinfo only once on large data @@ -48,11 +48,23 @@ endif endif endfor -text = [text{:}, doc_delim]; +text = [text{:}]; + +## Strip Texinfo marker +text = regexprep (text, "-\\*- texinfo -\\*-[ \t]*[\r\n]*", ""); -## Strip Texinfo markers and docstring separators. -text = regexprep (text, "-\\*- texinfo -\\*-[ \t]*[\r\n]*", ""); -text = strrep (text, '@', "@@"); +## Add keywords and operators +other_docstrings = [__keywords__; __operators__]; +for i = 1 : numel (other_docstrings) + name = other_docstrings{i}; + ## Special handling of block comment operators such as '#{' + esc_name = regexprep (name, '([{}])', '@$1'); + text = [text doc_delim esc_name get_help_text(name) "\n"]; +endfor +text(end+1) = doc_delim; + +## Double '@' symbol for Texinfo +text = strrep (text, [doc_delim "@"], [doc_delim "@@"]); ## Write data to temporary file for input to makeinfo [fid, name, msg] = mkstemp ("octave_doc_XXXXXX", true); diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/munge-texi.pl --- a/doc/interpreter/munge-texi.pl Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/munge-texi.pl Sat Oct 05 11:22:09 2013 -0400 @@ -6,7 +6,7 @@ $top_srcdir = shift (@ARGV); # Constant patterns -$doc_delim = qr/^\c_/; +$doc_delim = qr/^\x{1d}/; $tex_delim = qr/\Q-*- texinfo -*-\E/; $comment_line = qr/^\s*(?:$|#)/; # Pre-declare hash size for efficiency @@ -61,7 +61,7 @@ } $func =~ s/^@/@@/; # Texinfo uses @@ to produce '@' - $docstring =~ s/^$tex_delim$/\@anchor{docX$func}/m; + $docstring =~ s/^$tex_delim$/\@anchor{XREF$func}/m; print $docstring,"\n"; next TXI_LINE; @@ -110,7 +110,7 @@ foreach $func (split (/,/, $func_list)) { $func =~ s/^@/@@/; # Texinfo uses @@ to produce '@' - $repl .= "\@ref{docX$func,,$func}, "; + $repl .= "\@ref{XREF$func,,$func}, "; } substr($repl,-2) = ""; # Remove last ', ' $_ = "\@seealso{$repl}$rest_of_line"; diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/nonlin.txi --- a/doc/interpreter/nonlin.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/nonlin.txi Sat Oct 05 11:22:09 2013 -0400 @@ -23,7 +23,7 @@ @menu * Solvers:: -* Minimizers:: +* Minimizers:: @end menu @node Solvers diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/numbers.txi --- a/doc/interpreter/numbers.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/numbers.txi Sat Oct 05 11:22:09 2013 -0400 @@ -29,7 +29,7 @@ (exponential) notation, or a complex number. Note that by default numeric constants are represented within Octave in double-precision floating point format (complex constants are stored as pairs of double-precision -floating point values). It is however possible to represent real +floating point values). It is, however, possible to represent real integers as described in @ref{Integer Data Types}. Here are some examples of real-valued numeric constants, which all have the same value: @@ -93,9 +93,9 @@ * Single Precision Data Types:: * Integer Data Types:: * Bit Manipulations:: -* Logical Values:: +* Logical Values:: * Promotion and Demotion of Data Types:: -* Predicates for Numeric Objects:: +* Predicates for Numeric Objects:: @end menu @node Matrices @@ -304,7 +304,7 @@ @DOCSTRING(fixed_point_format) @menu -* Empty Matrices:: +* Empty Matrices:: @end menu @node Empty Matrices @@ -359,7 +359,7 @@ Empty matrices may also be used in assignment statements as a convenient way to delete rows or columns of matrices. -@xref{Assignment Ops, ,Assignment Expressions}. +@xref{Assignment Ops,,Assignment Expressions}. When Octave parses a matrix expression, it examines the elements of the list to determine whether they are all constants. If they are, it @@ -546,6 +546,8 @@ @DOCSTRING(intmin) +@DOCSTRING(flintmax) + @menu * Integer Arithmetic:: @end menu @@ -616,10 +618,10 @@ @DOCSTRING(bitmax) -This is the double precision version of the functions @code{intmax}, +This is the double precision version of the function @code{intmax}, previously discussed. -Octave also includes the basic bitwise 'and', 'or' and 'exclusive or' +Octave also includes the basic bitwise 'and', 'or', and 'exclusive or' operators. @DOCSTRING(bitand) @@ -839,4 +841,4 @@ If instead of knowing properties of variables, you wish to know which variables are defined and to gather other information about the -workspace itself, see @ref{Status of Variables}. +workspace itself, @pxref{Status of Variables}. diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/octave.texi --- a/doc/interpreter/octave.texi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/octave.texi Sat Oct 05 11:22:09 2013 -0400 @@ -17,6 +17,7 @@ % . \input texinfo + @setfilename octave.info @include macros.texi @@ -30,10 +31,14 @@ @end format @end ifinfo -@c Settings for printing on 8-1/2 by 11 inch paper: -@c ----------------------------------------------- +@c Settings for printing on 8-1/2 by 11 inch paper (default): +@c -------------------------------------------------------- @setchapternewpage odd +@c Fix TOC margins for printed manual +@tex +{\globaldefs = 1 \contentsrightmargin = 0pt} +@end tex @c Settings for small book format: @c ------------------------------ @@ -101,6 +106,7 @@ @author John W. Eaton @author David Bateman @author S@o{}ren Hauberg +@author Rik Wehbring @page @vskip 0pt plus 1filll Copyright @copyright{} 1996, 1997, 1999, 2000, 2001, 2002, 2005, 2006, @@ -141,54 +147,54 @@ @c ------------------------------------------------------------------------ @menu -* Preface:: +* Preface:: * Introduction:: A brief introduction to Octave. -* Getting Started:: -* Data Types:: -* Numeric Data Types:: -* Strings:: -* Data Containers:: -* Variables:: -* Expressions:: -* Evaluation:: +* Getting Started:: +* Data Types:: +* Numeric Data Types:: +* Strings:: +* Data Containers:: +* Variables:: +* Expressions:: +* Evaluation:: * Statements:: Looping and program flow control. -* Functions and Scripts:: -* Errors and Warnings:: +* Functions and Scripts:: +* Errors and Warnings:: * Debugging:: -* Input and Output:: -* Plotting:: -* Matrix Manipulation:: -* Arithmetic:: +* Input and Output:: +* Plotting:: +* Matrix Manipulation:: +* Arithmetic:: * Linear Algebra:: * Vectorization and Faster Code Execution:: * Nonlinear Equations:: * Diagonal and Permutation Matrices:: * Sparse Matrices:: -* Numerical Integration:: -* Differential Equations:: -* Optimization:: -* Statistics:: -* Sets:: -* Polynomial Manipulations:: +* Numerical Integration:: +* Differential Equations:: +* Optimization:: +* Statistics:: +* Sets:: +* Polynomial Manipulations:: * Interpolation:: * Geometry:: -* Signal Processing:: -* Image Processing:: -* Audio Processing:: -* Object Oriented Programming:: -* GUI Development:: -* System Utilities:: +* Signal Processing:: +* Image Processing:: +* Audio Processing:: +* Object Oriented Programming:: +* GUI Development:: +* System Utilities:: * Java Interface:: * Packages:: * External Code Interface:: * Test and Demo Functions:: -* Tips and Standards:: +* Tips and Standards:: * Contributing Guidelines:: * Obsolete Functions:: * Trouble:: If you have trouble installing Octave. * Installation:: How to configure, compile and install Octave. -* Emacs Octave Support:: -* Grammar and Parser:: +* Emacs Octave Support:: +* Grammar and Parser:: * Copying:: The GNU General Public License. * Concept Index:: An item for each concept. * Function Index:: An item for each documented function. @@ -199,76 +205,75 @@ Preface -* Acknowledgements:: +* Acknowledgements:: * Citing Octave in Publications:: -* How You Can Contribute to Octave:: -* Distribution:: +* How You Can Contribute to Octave:: +* Distribution:: Introduction -* Running Octave:: -* Simple Examples:: -* Conventions:: +* Running Octave:: +* Simple Examples:: +* Conventions:: Conventions -* Fonts:: -* Evaluation Notation:: -* Printing Notation:: -* Error Messages:: -* Format of Descriptions:: +* Fonts:: +* Evaluation Notation:: +* Printing Notation:: +* Error Messages:: +* Format of Descriptions:: Format of Descriptions -* A Sample Function Description:: -* A Sample Command Description:: -* A Sample Variable Description:: +* A Sample Function Description:: +* A Sample Command Description:: Getting Started -* Invoking Octave from the Command Line:: -* Quitting Octave:: -* Getting Help:: -* Command Line Editing:: -* Errors:: -* Executable Octave Programs:: -* Comments:: +* Invoking Octave from the Command Line:: +* Quitting Octave:: +* Getting Help:: +* Command Line Editing:: +* Errors:: +* Executable Octave Programs:: +* Comments:: Invoking Octave from the Command Line -* Command Line Options:: -* Startup Files:: +* Command Line Options:: +* Startup Files:: Command Line Editing -* Cursor Motion:: -* Killing and Yanking:: -* Commands For Text:: -* Commands For Completion:: -* Commands For History:: -* Customizing readline:: -* Customizing the Prompt:: -* Diary and Echo Commands:: +* Cursor Motion:: +* Killing and Yanking:: +* Commands For Text:: +* Commands For Completion:: +* Commands For History:: +* Customizing readline:: +* Customizing the Prompt:: +* Diary and Echo Commands:: Comments * Single Line Comments:: * Block Comments:: -* Comments and the Help System:: +* Comments and the Help System:: Data Types -* Built-in Data Types:: -* User-defined Data Types:: -* Object Sizes:: +* Built-in Data Types:: +* User-defined Data Types:: +* Object Sizes:: Built-in Data Types -* Numeric Objects:: -* Missing Data:: -* String Objects:: -* Data Structure Objects:: -* Cell Array Objects:: +* Numeric Objects:: +* Missing Data:: +* String Objects:: +* Data Structure Objects:: +* Cell Array Objects:: Numeric Data Types @@ -277,13 +282,13 @@ * Single Precision Data Types:: * Integer Data Types:: * Bit Manipulations:: -* Logical Values:: +* Logical Values:: * Promotion and Demotion of Data Types:: -* Predicates for Numeric Objects:: +* Predicates for Numeric Objects:: Matrices -* Empty Matrices:: +* Empty Matrices:: Integer Data Types @@ -293,16 +298,16 @@ * Escape Sequences in String Constants:: * Character Arrays:: -* Creating Strings:: -* Comparing Strings:: -* Manipulating Strings:: -* String Conversions:: -* Character Class Functions:: +* Creating Strings:: +* Comparing Strings:: +* Manipulating Strings:: +* String Conversions:: +* Character Class Functions:: Creating Strings -* Concatenating Strings:: -* Conversion of Numerical Data to Strings:: +* Concatenating Strings:: +* Converting Numerical Data to Strings:: Data Containers @@ -333,20 +338,20 @@ Variables -* Global Variables:: -* Persistent Variables:: -* Status of Variables:: +* Global Variables:: +* Persistent Variables:: +* Status of Variables:: Expressions -* Index Expressions:: -* Calling Functions:: -* Arithmetic Ops:: -* Comparison Ops:: -* Boolean Expressions:: -* Assignment Ops:: -* Increment Ops:: -* Operator Precedence:: +* Index Expressions:: +* Calling Functions:: +* Arithmetic Ops:: +* Comparison Ops:: +* Boolean Expressions:: +* Assignment Ops:: +* Increment Ops:: +* Operator Precedence:: Index Expressions @@ -354,13 +359,13 @@ Calling Functions -* Call by Value:: -* Recursion:: +* Call by Value:: +* Recursion:: Boolean Expressions -* Element-by-element Boolean Operators:: -* Short-circuit Boolean Operators:: +* Element-by-element Boolean Operators:: +* Short-circuit Boolean Operators:: Evaluation @@ -369,40 +374,40 @@ Statements -* The if Statement:: -* The switch Statement:: -* The while Statement:: -* The do-until Statement:: -* The for Statement:: -* The break Statement:: -* The continue Statement:: -* The unwind_protect Statement:: -* The try Statement:: -* Continuation Lines:: +* The if Statement:: +* The switch Statement:: +* The while Statement:: +* The do-until Statement:: +* The for Statement:: +* The break Statement:: +* The continue Statement:: +* The unwind_protect Statement:: +* The try Statement:: +* Continuation Lines:: The switch Statement -* Notes for the C Programmer:: +* Notes for the C Programmer:: The for Statement -* Looping Over Structure Elements:: +* Looping Over Structure Elements:: Functions and Scripts * Introduction to Function and Script Files:: -* Defining Functions:: -* Multiple Return Values:: -* Variable-length Argument Lists:: -* Ignoring Arguments:: -* Variable-length Return Lists:: -* Returning from a Function:: -* Default Arguments:: -* Function Files:: -* Script Files:: -* Function Handles Inline Functions and Anonymous Functions:: +* Defining Functions:: +* Multiple Return Values:: +* Variable-length Argument Lists:: +* Ignoring Arguments:: +* Variable-length Return Lists:: +* Returning from a Function:: +* Default Arguments:: +* Function Files:: +* Script Files:: +* Function Handles Anonymous Functions Inline Functions:: * Commands:: -* Organization of Functions:: +* Organization of Functions:: Function Files @@ -414,7 +419,7 @@ * Function Locking:: * Function Precedence:: -Function Handles Inline Functions and Anonymous Functions +Function Handles Anonymous Functions Inline Functions * Function Handles:: * Anonymous Functions:: @@ -448,14 +453,14 @@ Input and Output -* Basic Input and Output:: -* C-Style I/O Functions:: +* Basic Input and Output:: +* C-Style I/O Functions:: Basic Input and Output -* Terminal Output:: -* Terminal Input:: -* Simple File I/O:: +* Terminal Output:: +* Terminal Input:: +* Simple File I/O:: Terminal Output @@ -467,131 +472,130 @@ C-Style I/O Functions -* Opening and Closing Files:: -* Simple Output:: -* Line-Oriented Input:: -* Formatted Output:: -* Output Conversion for Matrices:: -* Output Conversion Syntax:: -* Table of Output Conversions:: -* Integer Conversions:: +* Opening and Closing Files:: +* Simple Output:: +* Line-Oriented Input:: +* Formatted Output:: +* Output Conversion for Matrices:: +* Output Conversion Syntax:: +* Table of Output Conversions:: +* Integer Conversions:: * Floating-Point Conversions:: -* Other Output Conversions:: -* Formatted Input:: -* Input Conversion Syntax:: -* Table of Input Conversions:: -* Numeric Input Conversions:: -* String Input Conversions:: -* Binary I/O:: -* Temporary Files:: -* EOF and Errors:: -* File Positioning:: +* Other Output Conversions:: +* Formatted Input:: +* Input Conversion Syntax:: +* Table of Input Conversions:: +* Numeric Input Conversions:: +* String Input Conversions:: +* Binary I/O:: +* Temporary Files:: +* EOF and Errors:: +* File Positioning:: Plotting -* Introduction to Plotting:: -* High-Level Plotting:: -* Graphics Data Structures:: -* Advanced Plotting:: +* Introduction to Plotting:: +* High-Level Plotting:: +* Graphics Data Structures:: +* Advanced Plotting:: High-Level Plotting -* Two-Dimensional Plots:: -* Three-Dimensional Plots:: -* Plot Annotations:: -* Multiple Plots on One Page:: -* Multiple Plot Windows:: -* Use of axis@comma{} line@comma{} and patch Functions:: +* Two-Dimensional Plots:: +* Three-Dimensional Plots:: +* Plot Annotations:: +* Multiple Plots on One Page:: +* Multiple Plot Windows:: * Manipulation of Plot Windows:: * Use of the @code{interpreter} Property:: -* Printing and Saving Plots:: -* Interacting with Plots:: -* Test Plotting Functions:: +* Printing and Saving Plots:: +* Interacting with Plots:: +* Test Plotting Functions:: Two-Dimensional Plots -* Axis Configuration:: -* Two-dimensional Function Plotting:: -* Two-dimensional Geometric Shapes:: +* Axis Configuration:: +* Two-dimensional Function Plotting:: +* Two-dimensional Geometric Shapes:: Three-Dimensional Plots * Aspect Ratio:: -* Three-dimensional Function Plotting:: -* Three-dimensional Geometric Shapes:: +* Three-dimensional Function Plotting:: +* Three-dimensional Geometric Shapes:: Graphics Data Structures -* Introduction to Graphics Structures:: -* Graphics Objects:: -* Graphics Object Properties:: -* Searching Properties:: -* Managing Default Properties:: +* Introduction to Graphics Structures:: +* Graphics Objects:: +* Graphics Object Properties:: +* Searching Properties:: +* Managing Default Properties:: Graphics Object Properties -* Root Figure Properties:: -* Figure Properties:: -* Axes Properties:: -* Line Properties:: -* Text Properties:: -* Image Properties:: -* Patch Properties:: -* Surface Properties:: +* Root Figure Properties:: +* Figure Properties:: +* Axes Properties:: +* Line Properties:: +* Text Properties:: +* Image Properties:: +* Patch Properties:: +* Surface Properties:: Advanced Plotting -* Colors:: -* Line Styles:: -* Marker Styles:: -* Callbacks:: +* Colors:: +* Line Styles:: +* Marker Styles:: +* Callbacks:: * Application-defined Data:: -* Object Groups:: -* Graphics Toolkits:: +* Object Groups:: +* Graphics Toolkits:: Object Groups -* Data Sources in Object Groups:: -* Area Series:: -* Bar Series:: -* Contour Groups:: -* Error Bar Series:: -* Line Series:: -* Quiver Group:: -* Scatter Group:: -* Stair Group:: -* Stem Series:: -* Surface Group:: +* Data Sources in Object Groups:: +* Area Series:: +* Bar Series:: +* Contour Groups:: +* Error Bar Series:: +* Line Series:: +* Quiver Group:: +* Scatter Group:: +* Stair Group:: +* Stem Series:: +* Surface Group:: Graphics Toolkits -* Customizing Toolkit Behavior:: +* Customizing Toolkit Behavior:: Matrix Manipulation -* Finding Elements and Checking Conditions:: -* Rearranging Matrices:: -* Special Utility Matrices:: -* Famous Matrices:: +* Finding Elements and Checking Conditions:: +* Rearranging Matrices:: +* Special Utility Matrices:: +* Famous Matrices:: Arithmetic * Exponents and Logarithms:: -* Complex Arithmetic:: -* Trigonometry:: -* Sums and Products:: -* Utility Functions:: -* Special Functions:: +* Complex Arithmetic:: +* Trigonometry:: +* Sums and Products:: +* Utility Functions:: +* Special Functions:: * Rational Approximations:: * Coordinate Transformations:: -* Mathematical Constants:: +* Mathematical Constants:: Linear Algebra * Techniques Used for Linear Algebra:: -* Basic Matrix Functions:: -* Matrix Factorizations:: -* Functions of a Matrix:: +* Basic Matrix Functions:: +* Matrix Factorizations:: +* Functions of a Matrix:: * Specialized Solvers:: Vectorization and Faster Code Execution @@ -607,15 +611,15 @@ Nonlinear Equations * Solvers:: -* Minimizers:: +* Minimizers:: Diagonal and Permutation Matrices -* Basic Usage:: Creation and Manipulation of Diagonal and Permutation Matrices -* Matrix Algebra:: Linear Algebra with Diagonal and Permutation Matrices +* Basic Usage:: Creation and Manipulation of Diagonal/Permutation Matrices +* Matrix Algebra:: Linear Algebra with Diagonal/Permutation Matrices * Function Support:: Functions That Are Aware of These Matrices -* Example Code:: Some Examples of Usage -* Zeros Treatment:: The Differences in Treatment of Zero Elements +* Example Code:: Examples of Usage +* Zeros Treatment:: Differences in Treatment of Zero Elements Basic Usage @@ -649,37 +653,37 @@ Operators and Functions -* Sparse Functions:: -* Return Types of Operators and Functions:: -* Mathematical Considerations:: +* Sparse Functions:: +* Return Types of Operators and Functions:: +* Mathematical Considerations:: Numerical Integration -* Functions of One Variable:: -* Orthogonal Collocation:: -* Functions of Multiple Variables:: +* Functions of One Variable:: +* Orthogonal Collocation:: +* Functions of Multiple Variables:: Differential Equations -* Ordinary Differential Equations:: -* Differential-Algebraic Equations:: +* Ordinary Differential Equations:: +* Differential-Algebraic Equations:: Optimization -* Linear Programming:: -* Quadratic Programming:: -* Nonlinear Programming:: -* Linear Least Squares:: +* Linear Programming:: +* Quadratic Programming:: +* Nonlinear Programming:: +* Linear Least Squares:: Statistics * Descriptive Statistics:: -* Basic Statistical Functions:: -* Statistical Plots:: -* Correlation and Regression Analysis:: -* Distributions:: -* Tests:: -* Random Number Generation:: +* Basic Statistical Functions:: +* Statistical Plots:: +* Correlation and Regression Analysis:: +* Distributions:: +* Tests:: +* Random Number Generation:: Sets @@ -713,11 +717,11 @@ Image Processing -* Loading and Saving Images:: -* Displaying Images:: -* Representing Images:: -* Plotting on top of Images:: -* Color Conversion:: +* Loading and Saving Images:: +* Displaying Images:: +* Representing Images:: +* Plotting on top of Images:: +* Color Conversion:: Object Oriented Programming @@ -740,24 +744,24 @@ GUI Development -* I/O Dialogs:: -* Progress Bar:: -* GUI Utility Functions:: -* User-Defined Preferences:: +* I/O Dialogs:: +* Progress Bar:: +* GUI Utility Functions:: +* User-Defined Preferences:: System Utilities -* Timing Utilities:: -* Filesystem Utilities:: +* Timing Utilities:: +* Filesystem Utilities:: * File Archiving Utilities:: * Networking Utilities:: -* Controlling Subprocesses:: -* Process ID Information:: -* Environment Variables:: -* Current Working Directory:: -* Password Database Functions:: -* Group Database Functions:: -* System Information:: +* Controlling Subprocesses:: +* Process ID Information:: +* Environment Variables:: +* Current Working Directory:: +* Password Database Functions:: +* Group Database Functions:: +* System Information:: * Hashing Functions:: Networking Utilities @@ -778,58 +782,58 @@ * How to make Java classes available?:: * How to create an instance of a Java class?:: * How can I handle memory limitations?:: -* Which @TeX{} symbols are implemented in the dialog functions?:: +* Which @TeX{} symbols are implemented in dialog functions?:: Packages -* Installing and Removing Packages:: -* Using Packages:: -* Administrating Packages:: -* Creating Packages:: +* Installing and Removing Packages:: +* Using Packages:: +* Administrating Packages:: +* Creating Packages:: Creating Packages -* The DESCRIPTION File:: -* The INDEX File:: -* PKG_ADD and PKG_DEL Directives:: +* The DESCRIPTION File:: +* The INDEX File:: +* PKG_ADD and PKG_DEL Directives:: External Code Interface -* Oct-Files:: -* Mex-Files:: -* Standalone Programs:: +* Oct-Files:: +* Mex-Files:: +* Standalone Programs:: Oct-Files -* Getting Started with Oct-Files:: -* Matrices and Arrays in Oct-Files:: -* Character Strings in Oct-Files:: -* Cell Arrays in Oct-Files:: -* Structures in Oct-Files:: -* Sparse Matrices in Oct-Files:: -* Accessing Global Variables in Oct-Files:: -* Calling Octave Functions from Oct-Files:: -* Calling External Code from Oct-Files:: -* Allocating Local Memory in Oct-Files:: -* Input Parameter Checking in Oct-Files:: -* Exception and Error Handling in Oct-Files:: -* Documentation and Test of Oct-Files:: +* Getting Started with Oct-Files:: +* Matrices and Arrays in Oct-Files:: +* Character Strings in Oct-Files:: +* Cell Arrays in Oct-Files:: +* Structures in Oct-Files:: +* Sparse Matrices in Oct-Files:: +* Accessing Global Variables in Oct-Files:: +* Calling Octave Functions from Oct-Files:: +* Calling External Code from Oct-Files:: +* Allocating Local Memory in Oct-Files:: +* Input Parameter Checking in Oct-Files:: +* Exception and Error Handling in Oct-Files:: +* Documentation and Test of Oct-Files:: Sparse Matrices in Oct-Files -* Array and Sparse Differences:: -* Creating Sparse Matrices in Oct-Files:: -* Using Sparse Matrices in Oct-Files:: +* Array and Sparse Class Differences:: +* Creating Sparse Matrices in Oct-Files:: +* Using Sparse Matrices in Oct-Files:: Mex-Files -* Getting Started with Mex-Files:: -* Working with Matrices and Arrays in Mex-Files:: -* Character Strings in Mex-Files:: -* Cell Arrays with Mex-Files:: -* Structures with Mex-Files:: -* Sparse Matrices with Mex-Files:: -* Calling Other Functions in Mex-Files:: +* Getting Started with Mex-Files:: +* Working with Matrices and Arrays in Mex-Files:: +* Character Strings in Mex-Files:: +* Cell Arrays with Mex-Files:: +* Structures with Mex-Files:: +* Sparse Matrices with Mex-Files:: +* Calling Other Functions in Mex-Files:: Test and Demo Functions @@ -856,12 +860,12 @@ Trouble * Actual Bugs:: Bugs we will fix later. -* Reporting Bugs:: -* Service:: +* Reporting Bugs:: +* Service:: Reporting Bugs -* Bug Criteria:: +* Bug Criteria:: * Bug Tracker:: Where to submit your bug report. * Bug Reporting:: How to report a bug effectively. * Sending Patches:: How to send a patch for Octave. @@ -881,15 +885,15 @@ Emacs Octave Support -* Installing EOS:: -* Using Octave Mode:: -* Running Octave from Within Emacs:: -* Using the Emacs Info Reader for Octave:: +* Installing EOS:: +* Using Octave Mode:: +* Running Octave from Within Emacs:: +* Using the Emacs Info Reader for Octave:: Grammar and Parser -* Keywords:: -* Parser:: +* Keywords:: +* Parser:: @end detailmenu @end menu diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/oop.txi --- a/doc/interpreter/oop.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/oop.txi Sat Oct 05 11:22:09 2013 -0400 @@ -94,9 +94,7 @@ our polynomial might look like @example -@group @EXAMPLEFILE(@polynomial/polynomial.m) -@end group @end example Note that the return value of the constructor must be the output of @@ -177,9 +175,7 @@ An example of a display method for the polynomial class might be @example -@group @EXAMPLEFILE(@polynomial/display.m) -@end group @end example @noindent @@ -195,9 +191,7 @@ all of the properties of the class. For example: @example -@group @EXAMPLEFILE(@polynomial/get.m) -@end group @end example @noindent @@ -205,9 +199,7 @@ object to modify, and then take property/value pairs to be modified. @example -@group @EXAMPLEFILE(@polynomial/set.m) -@end group @end example @noindent @@ -276,15 +268,13 @@ @DOCSTRING(subsref) -For example we might decide that indexing with "()" evaluates the -polynomial and indexing with "@{@}" returns the @var{n}-th coefficient (of -@var{n}-th power). In this case the @code{subsref} method of our polynomial -class might look like +For example we might decide that indexing with @qcode{"()"} evaluates the +polynomial and indexing with @qcode{"@{@}"} returns the @var{n}-th coefficient +(of @var{n}-th power). In this case the @code{subsref} method of our +polynomial class might look like @example -@group @EXAMPLEFILE(@polynomial/subsref.m) -@end group @end example The equivalent functionality for subscripted assignments uses the @@ -640,21 +630,19 @@ @end example @noindent -That mixes an object of the class "double" with an object of the class -"polynomial". In this case we like to ensure that the return type of -the above is of the type "polynomial" and so we use the +That mixes an object of the class @qcode{"double"} with an object of the class +@qcode{"polynomial"}. In this case we like to ensure that the return type of +the above is of the type @qcode{"polynomial"} and so we use the @code{superiorto} function in the class constructor. In particular our polynomial class constructor would be modified to be @example -@group @EXAMPLEFILE(@polynomial/polynomial_superiorto.m) -@end group @end example Note that user classes always have higher precedence than built-in Octave types. So in fact marking our polynomial class higher than the -"double" class is in fact not necessary. +@qcode{"double"} class is in fact not necessary. When faced with two objects that have the same precedence, Octave will use the method of the object that appears first on the list of arguments. @@ -692,9 +680,7 @@ FIRfilter.m in the class directory. @example -@group @EXAMPLEFILE(@FIRfilter/FIRfilter.m) -@end group @end example As before, the leading comments provide command-line documentation for @@ -758,12 +744,10 @@ to access the fields. The @code{subsref} method may be used for both. @example -@group @EXAMPLEFILE(@FIRfilter/subsref.m) -@end group @end example -The "()" case allows us to filter data using the polynomial provided +The @qcode{"()"} case allows us to filter data using the polynomial provided to the constructor. @example @@ -781,7 +765,7 @@ @end group @end example -The "." case allows us to view the contents of the polynomial field. +The @qcode{"."} case allows us to view the contents of the polynomial field. @example @group @@ -819,9 +803,7 @@ constructor for this case might be @example -@group @EXAMPLEFILE(@FIRfilter/FIRfilter_aggregation.m) -@end group @end example For our example, the remaining class methods remain unchanged. diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/optim.txi --- a/doc/interpreter/optim.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/optim.txi Sat Oct 05 11:22:09 2013 -0400 @@ -25,10 +25,10 @@ Minimization. @menu -* Linear Programming:: -* Quadratic Programming:: -* Nonlinear Programming:: -* Linear Least Squares:: +* Linear Programming:: +* Quadratic Programming:: +* Nonlinear Programming:: +* Linear Least Squares:: @end menu @c @cindex linear programming diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/package.txi --- a/doc/interpreter/package.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/package.txi Sat Oct 05 11:22:09 2013 -0400 @@ -71,7 +71,7 @@ @noindent In this case only version 1.0.0 of the @code{image} package is -installed. The '*' character next to the package name shows that the +installed. The @qcode{'*'} character next to the package name shows that the image package is loaded and ready for use. It is possible to remove a package from the system using the @@ -217,7 +217,7 @@ This is an optional file describing old entries from the @file{NEWS} file. @cindex PKG_ADD -@anchor{docXPKG_ADD} +@anchor{XREFPKG_ADD} @item package/PKG_ADD An optional file that includes commands that are run when the package is added to the users path. Note that @w{@code{PKG_ADD}} directives in the @@ -242,7 +242,7 @@ directives. @cindex PKG_DEL -@anchor{docXPKG_DEL} +@anchor{XREFPKG_DEL} @item package/PKG_DEL An optional file that includes commands that are run when the package is removed from the users path. Note that @w{@code{PKG_DEL}} directives in @@ -469,7 +469,7 @@ @end itemize @noindent -The format can be summarized with the following example. +The format can be summarized with the following example: @example @group @@ -571,6 +571,7 @@ @noindent In both cases @code{some_octave_command} should be replaced by the command that should be placed in the @w{@code{PKG_ADD}} file. -@w{@code{PKG_DEL}} directives work in the same way, except the @w{@code{PKG_ADD}} -keyword is replaced with @w{@code{PKG_DEL}} and the commands get added -to the @w{@code{PKG_DEL}} file. +@w{@code{PKG_DEL}} directives work in the same way, except the +@w{@code{PKG_ADD}} keyword is replaced with @w{@code{PKG_DEL}} and the commands +get added to the @w{@code{PKG_DEL}} file. + diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/plot.txi --- a/doc/interpreter/plot.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/plot.txi Sat Oct 05 11:22:09 2013 -0400 @@ -22,10 +22,10 @@ @cindex graphics @menu -* Introduction to Plotting:: -* High-Level Plotting:: -* Graphics Data Structures:: -* Advanced Plotting:: +* Introduction to Plotting:: +* High-Level Plotting:: +* Graphics Data Structures:: +* Advanced Plotting:: @end menu @node Introduction to Plotting @@ -34,8 +34,8 @@ Earlier versions of Octave provided plotting through the use of gnuplot. This capability is still available. But, a newer plotting capability is provided by access to OpenGL@. Which plotting system -is used is controlled by the @code{graphics_toolkit} function. (See -@ref{Graphics Toolkits}.) +is used is controlled by the @code{graphics_toolkit} function. +@xref{Graphics Toolkits}. The function call @code{graphics_toolkit ("fltk")} selects the FLTK/OpenGL system, and @code{graphics_toolkit ("gnuplot")} selects the @@ -57,26 +57,25 @@ and @ref{Advanced Plotting}. @menu -* Two-Dimensional Plots:: -* Three-Dimensional Plots:: -* Plot Annotations:: -* Multiple Plots on One Page:: -* Multiple Plot Windows:: -* Use of axis@comma{} line@comma{} and patch Functions:: +* Two-Dimensional Plots:: +* Three-Dimensional Plots:: +* Plot Annotations:: +* Multiple Plots on One Page:: +* Multiple Plot Windows:: * Manipulation of Plot Windows:: * Use of the @code{interpreter} Property:: -* Printing and Saving Plots:: -* Interacting with Plots:: -* Test Plotting Functions:: +* Printing and Saving Plots:: +* Interacting with Plots:: +* Test Plotting Functions:: @end menu @node Two-Dimensional Plots @subsection Two-Dimensional Plots @menu -* Axis Configuration:: -* Two-dimensional Function Plotting:: -* Two-dimensional Geometric Shapes:: +* Axis Configuration:: +* Two-dimensional Function Plotting:: +* Two-dimensional Geometric Shapes:: @end menu The @code{plot} function allows you to create simple x-y plots with @@ -253,8 +252,11 @@ The @code{xlim}, @code{ylim}, and @code{zlim} functions may be used to get or set individual axis limits. Each has the same form. -@anchor{docXylim} -@anchor{docXzlim} +@c Add cross-references and function index entries for other limit functions. +@anchor{XREFylim} +@anchor{XREFzlim} +@findex ylim +@findex zlim @DOCSTRING(xlim) @node Two-dimensional Function Plotting @@ -396,16 +398,16 @@ @menu * Aspect Ratio:: -* Three-dimensional Function Plotting:: -* Three-dimensional Geometric Shapes:: +* Three-dimensional Function Plotting:: +* Three-dimensional Geometric Shapes:: @end menu @node Aspect Ratio @subsubsection Aspect Ratio For three-dimensional plots the aspect ratio can be set for data with -@code{daspect} and for the plot box with @code{pbaspect}. -See @ref{Axis Configuration} for controlling the x-, y-, and z-limits for +@code{daspect} and for the plot box with @code{pbaspect}. +@xref{Axis Configuration}, for controlling the x-, y-, and z-limits for plotting. @DOCSTRING(daspect) @@ -464,8 +466,8 @@ See @ref{Text Properties} for the properties that you can set. -@anchor{docXylabel} -@anchor{docXzlabel} +@anchor{XREFylabel} +@anchor{XREFzlabel} @DOCSTRING(xlabel) @DOCSTRING(clabel) @@ -523,23 +525,6 @@ @DOCSTRING(figure) -@node Use of axis@comma{} line@comma{} and patch Functions -@subsection Use of axis@comma{} line@comma{} and patch Functions - -You can create axes, line, and patch objects directly using the -@code{axes}, @code{line}, and @code{patch} functions. These objects -become children of the current axes object. - -@DOCSTRING(axes) - -@DOCSTRING(line) - -@DOCSTRING(patch) - -@DOCSTRING(fill) - -@DOCSTRING(surface) - @node Manipulation of Plot Windows @subsection Manipulation of Plot Windows @@ -603,16 +588,16 @@ @subsection Use of the @code{interpreter} Property All text objects, including titles, labels, legends, and text, include -the property 'interpreter', this property determines the manner in which +the property @qcode{"interpreter"}, this property determines the manner in which special control sequences in the text are rendered. If the interpreter -is set to 'none', then no rendering occurs. At this point the 'latex' -option is not implemented and so the 'latex' interpreter also does not -interpret the text. - -The 'tex' option implements a subset of @TeX{} functionality in the +is set to @qcode{"none"}, then no rendering occurs. At this point the +@qcode{"latex"} option is not implemented and so the @qcode{"latex"} +interpreter also does not interpret the text. + +The @qcode{"tex"} option implements a subset of @TeX{} functionality in the rendering of the text. This allows the insertion of special characters such as Greek or mathematical symbols within the text. The special -characters are also inserted with a code starting with the back-slash +characters are also inserted with a code starting with the backslash (\) character, as in the table @ref{tab:extended}. In addition, the formatting of the text can be changed within the string @@ -633,7 +618,7 @@ @end example @noindent -where the character 'a' will not appear in a bold font. Note that to +where the character @qcode{'a'} will not appear in a bold font. Note that to avoid having Octave interpret the backslash characters in the strings, the strings should be in single quotes. @@ -645,178 +630,251 @@ use @tab @end multitable -Finally, the superscript and subscripting can be controlled with the '^' -and '_' characters. If the '^' or '_' is followed by a @{ character, -then all of the block surrounded by the @{ @} pair is super- or -sub-scripted. Without the @{ @} pair, only the character immediately -following the '^' or '_' is super- or sub-scripted. +Finally, the superscript and subscripting can be controlled with the @qcode{'^'} +and @qcode{'_'} characters. If the @qcode{'^'} or @qcode{'_'} is followed by a +@{ character, then all of the block surrounded by the @{ @} pair is super- or +sub-scripted. Without the @{ @} pair, only the character immediately following +the @qcode{'^'} or @qcode{'_'} is super- or sub-scripted. @float Table,tab:extended @tex \vskip 6pt -{\hbox to \hsize {\hfill\vbox{\offinterlineskip \tabskip=0pt +\newdimen\cola \cola=78pt +\newdimen\colb \colb=78pt +\newdimen\colc \colc=78pt +\def\symtable#1#2#3{ +\hbox to \hsize {\hfill\vbox{\offinterlineskip \tabskip=0pt +\hskip36pt #1 +\vskip6pt \halign{ -\vrule height2.0ex depth1.ex width 0.6pt #\tabskip=0.3em & -# \hfil & \vrule # & # \hfil & # \vrule & -# \hfil & \vrule # & # \hfil & # \vrule & -# \hfil & \vrule # & # \hfil & # \vrule +\vrule height2.0ex depth1.ex width 0.6pt #2\tabskip=0.3em & +#2 \hfil & \vrule #2 & #2 \hfil & #2 \vrule & +#2 \hfil & \vrule #2 & #2 \hfil & #2 \vrule & +#2 \hfil & \vrule #2 & #2 \hfil & #2 \vrule width 0.6pt \tabskip=0pt\cr \noalign{\hrule height 0.6pt} & Code && Sym && Code && Sym && Code && Sym &\cr \noalign{\hrule} -& $\backslash$forall && $\forall$ -&& $\backslash$exists && $\exists$ -&& $\backslash$ni && $\ni$ &\cr -& $\backslash$cong && $\cong$ -&& $\backslash$Delta && $\Delta$ -&& $\backslash$Phi && $\Phi$ &\cr -& $\backslash$Gamma && $\Gamma$ -&& $\backslash$vartheta && $\vartheta$ -&& $\backslash$Lambda && $\Lambda$ &\cr -& $\backslash$Pi && $\Pi$ -&& $\backslash$Theta && $\Theta$ -&& $\backslash$Sigma && $\Sigma$ &\cr -& $\backslash$varsigma && $\varsigma$ -&& $\backslash$Omega && $\Omega$ -&& $\backslash$Xi && $\Xi$ &\cr -& $\backslash$Psi && $\Psi$ -&& $\backslash$perp && $\perp$ -&& $\backslash$alpha && $\alpha$ &\cr -& $\backslash$beta && $\beta$ -&& $\backslash$chi && $\chi$ -&& $\backslash$delta && $\delta$ &\cr -& $\backslash$epsilon && $\epsilon$ -&& $\backslash$phi && $\phi$ -&& $\backslash$gamma && $\gamma$ &\cr -& $\backslash$eta && $\eta$ -&& $\backslash$iota && $\iota$ -&& $\backslash$varphi && $\varphi$ &\cr -& $\backslash$kappa && $\kappa$ -&& $\backslash$lambda && $\lambda$ -&& $\backslash$mu && $\mu$ &\cr -& $\backslash$nu && $\nu$ -&& $\backslash$o && $\o$ -&& $\backslash$pi && $\pi$ &\cr -& $\backslash$theta && $\theta$ -&& $\backslash$rho && $\rho$ -&& $\backslash$sigma && $\sigma$ &\cr -& $\backslash$tau && $\tau$ -&& $\backslash$upsilon && $\upsilon$ -&& $\backslash$varpi && $\varpi$ &\cr -& $\backslash$omega && $\omega$ -&& $\backslash$xi && $\xi$ -&& $\backslash$psi && $\psi$ &\cr -& $\backslash$zeta && $\zeta$ -&& $\backslash$sim && $\sim$ -&& $\backslash$Upsilon && $\Upsilon$ &\cr -& $\backslash$prime && $\prime$ -&& $\backslash$leq && $\leq$ -&& $\backslash$infty && $\infty$ &\cr -& $\backslash$clubsuit && $\clubsuit$ -&& $\backslash$diamondsuit && $\diamondsuit$ -&& $\backslash$heartsuit && $\heartsuit$ &\cr -& $\backslash$spadesuit && $\spadesuit$ -&& $\backslash$leftrightarrow && $\leftrightarrow$ -&& $\backslash$leftarrow && $\leftarrow$ &\cr -& $\backslash$uparrow && $\uparrow$ -&& $\backslash$rightarrow && $\rightarrow$ -&& $\backslash$downarrow && $\downarrow$ &\cr -& $\backslash$circ && $\circ$ -&& $\backslash$pm && $\pm$ -&& $\backslash$geq && $\geq$ &\cr -& $\backslash$times && $\times$ -&& $\backslash$propto && $\propto$ -&& $\backslash$partial && $\partial$ &\cr -& $\backslash$bullet && $\bullet$ -&& $\backslash$div && $\div$ -&& $\backslash$neq && $\neq$ &\cr -& $\backslash$equiv && $\equiv$ -&& $\backslash$approx && $\approx$ -&& $\backslash$ldots && $\ldots$ &\cr -& $\backslash$mid && $\mid$ -&& $\backslash$aleph && $\aleph$ -&& $\backslash$Im && $\Im$ &\cr -& $\backslash$Re && $\Re$ -&& $\backslash$wp && $\wp$ -&& $\backslash$otimes && $\otimes$ &\cr -& $\backslash$oplus && $\oplus$ -&& $\backslash$oslash && $\oslash$ -&& $\backslash$cap && $\cap$ &\cr -& $\backslash$cup && $\cup$ -&& $\backslash$supset && $\supset$ -&& $\backslash$supseteq && $\supseteq$ &\cr -& $\backslash$subset && $\subset$ -&& $\backslash$subseteq && $\subseteq$ -&& $\backslash$in && $\in$ &\cr -& $\backslash$notin && $\notin$ -&& $\backslash$angle && $\angle$ -&& $\backslash$bigtriangledown && $\bigtriangledown$ &\cr -& $\backslash$langle && $\langle$ -&& $\backslash$rangle && $\rangle$ -&& $\backslash$nabla && $\nabla$ &\cr -& $\backslash$prod && $\prod$ -&& $\backslash$surd && $\surd$ -&& $\backslash$cdot && $\cdot$ &\cr -& $\backslash$neg && $\neg$ -&& $\backslash$wedge && $\wedge$ -&& $\backslash$vee && $\vee$ &\cr -& $\backslash$Leftrightarrow && $\Leftrightarrow$ -&& $\backslash$Leftarrow && $\Leftarrow$ -&& $\backslash$Uparrow && $\Uparrow$ &\cr -& $\backslash$Rightarrow && $\Rightarrow$ -&& $\backslash$Downarrow && $\Downarrow$ -&& $\backslash$diamond && $\diamond$ &\cr -& $\backslash$copyright && $\copyright$ -&& $\backslash$rfloor && $\rfloor$ -&& $\backslash$lceil && $\lceil$ &\cr -& $\backslash$lfloor && $\lfloor$ -&& $\backslash$rceil && $\rceil$ -&& $\backslash$int && $\int$ &\cr +#3 \noalign{\hrule height 0.6pt} -}}\hfill}} +} +}\hfill}} +\hoffset72pt +\symtable{Greek Lowercase Letters} {#} +{& \hbox to \cola{$\backslash$alpha } && $\alpha$ +&& \hbox to \colb{$\backslash$beta } && $\beta$ +&& \hbox to \colc{$\backslash$gamma} && $\gamma$ &\cr +& $\backslash$delta && $\delta$ +&& $\backslash$epsilon && $\epsilon$ +&& $\backslash$zeta && $\zeta$ &\cr +& $\backslash$eta && $\eta$ +&& $\backslash$theta && $\theta$ +&& $\backslash$vartheta && $\vartheta$ &\cr +& $\backslash$iota && $\iota$ +&& $\backslash$kappa && $\kappa$ +&& $\backslash$lambda && $\lambda$ &\cr +& $\backslash$mu && $\mu$ +&& $\backslash$nu && $\nu$ +&& $\backslash$xi && $\xi$ &\cr +& $\backslash$o && $o$ +&& $\backslash$pi && $\pi$ +&& $\backslash$varpi && $\varpi$ &\cr +& $\backslash$rho && $\rho$ +&& $\backslash$sigma && $\sigma$ +&& $\backslash$varsigma && $\varsigma$ &\cr +& $\backslash$tau && $\tau$ +&& $\backslash$upsilon && $\upsilon$ +&& $\backslash$phi && $\phi$ &\cr +& $\backslash$chi && $\chi$ +&& $\backslash$psi && $\psi$ +&& $\backslash$omega && $\omega$ &\cr} +\vskip12pt +\symtable{Greek Uppercase Letters} {#} +{& \hbox to \cola{$\backslash$Gamma} && $\Gamma$ +&& \hbox to \colb{$\backslash$Delta} && $\Delta$ +&& \hbox to \colc{$\backslash$Theta} && $\Theta$ &\cr +& $\backslash$Lambda && $\Lambda$ +&& $\backslash$Xi && $\Xi$ +&& $\backslash$Pi && $\Pi$ &\cr +& $\backslash$Sigma && $\Sigma$ +&& $\backslash$Upsilon && $\Upsilon$ +&& $\backslash$Phi && $\Phi$ &\cr +& $\backslash$Psi && $\Psi$ +&& $\backslash$Omega && $\Omega$ +&& && &\cr} +\vskip12pt +\symtable{Misc Symbols Type Ord} {#} +{& \hbox to \cola{$\backslash$aleph} && $\aleph$ +&& \hbox to \colb{$\backslash$wp} && $\wp$ +&& \hbox to \colc{$\backslash$Re} && $\Re$ &\cr +& $\backslash$Im && $\Im$ +&& $\backslash$partial && $\partial$ +&& $\backslash$infty && $\infty$ &\cr +& $\backslash$prime && $\prime$ +&& $\backslash$nabla && $\nabla$ +&& $\backslash$surd && $\surd$ &\cr +& $\backslash$angle && $\angle$ +&& $\backslash$forall && $\forall$ +&& $\backslash$exists && $\exists$ &\cr +& $\backslash$neg && $\neg$ +&& $\backslash$clubsuit && $\clubsuit$ +&& $\backslash$diamondsuit && $\diamondsuit$ &\cr +& $\backslash$heartsuit && $\heartsuit$ +&& $\backslash$spadesuit && $\spadesuit$ +&& && &\cr} +\vskip12pt +\symtable{``Large'' Operators} {#} +{& \hbox to \cola{$\backslash$int} && $\int$ +&& \hbox to \colb{} && +&& \hbox to \colc{} && &\cr} +\vskip12pt +\symtable{Binary operators} {#} +{& \hbox to \cola{$\backslash$pm} && $\pm$ +&& \hbox to \colb{$\backslash$cdot} && $\cdot$ +&& \hbox to \colc{$\backslash$times} && $\times$ &\cr +& $\backslash$ast && $\ast$ +&& $\backslash$circ && $\circ$ +&& $\backslash$bullet && $\bullet$ &\cr +& $\backslash$div && $\div$ +&& $\backslash$cap && $\cap$ +&& $\backslash$cup && $\cup$ &\cr +& $\backslash$vee && $\vee$ +&& $\backslash$wedge && $\wedge$ +&& $\backslash$oplus && $\oplus$ &\cr +& $\backslash$otimes && $\otimes$ +&& $\backslash$oslash && $\oslash$ +&& && &\cr} @end tex @ifnottex -@multitable @columnfractions .125 .25 .25 .25 .125 -@item @tab \forall @tab \exists @tab \ni @tab -@item @tab \cong @tab \Delta @tab \Phi @tab -@item @tab \Gamma @tab \vartheta @tab \Lambda @tab -@item @tab \Pi @tab \Theta @tab \Sigma @tab -@item @tab \varsigma @tab \Omega @tab \Xi @tab -@item @tab \Psi @tab \perp @tab \alpha @tab -@item @tab \beta @tab \chi @tab \delta @tab -@item @tab \epsilon @tab \phi @tab \gamma @tab -@item @tab \eta @tab \iota @tab \varphi @tab -@item @tab \kappa @tab \lambda @tab \mu @tab -@item @tab \nu @tab \o @tab \pi @tab -@item @tab \theta @tab \rho @tab \sigma @tab -@item @tab \tau @tab \upsilon @tab \varpi @tab -@item @tab \omega @tab \xi @tab \psi @tab -@item @tab \zeta @tab \sim @tab \Upsilon @tab -@item @tab \prime @tab \leq @tab \infty @tab -@item @tab \clubsuit @tab \diamondsuit @tab \heartsuit @tab -@item @tab \spadesuit @tab \leftrightarrow @tab \leftarrow @tab -@item @tab \uparrow @tab \rightarrow @tab \downarrow @tab -@item @tab \circ @tab \pm @tab \geq @tab -@item @tab \times @tab \propto @tab \partial @tab -@item @tab \bullet @tab \div @tab \neq @tab -@item @tab \equiv @tab \approx @tab \ldots @tab -@item @tab \mid @tab \aleph @tab \Im @tab -@item @tab \Re @tab \wp @tab \otimes @tab -@item @tab \oplus @tab \oslash @tab \cap @tab -@item @tab \cup @tab \supset @tab \supseteq @tab -@item @tab \subset @tab \subseteq @tab \in @tab -@item @tab \notin @tab \angle @tab \bigrightriangledown @tab -@item @tab \langle @tab \rangle @tab \nabla @tab -@item @tab \prod @tab \surd @tab \cdot @tab -@item @tab \neg @tab \wedge @tab \vee @tab -@item @tab \Leftrightarrow @tab \Leftarrow @tab \Uparrow @tab -@item @tab \Rightarrow @tab \Downarrow @tab \diamond @tab -@item @tab \copyright @tab \lfloor @tab \lceil @tab -@item @tab \rfloor @tab \rceil @tab \int @tab +@multitable @columnfractions .25 .25 .25 .25 +@item Greek Lowercase Letters +@item @tab \alpha @tab \beta @tab \gamma +@item @tab \delta @tab \epsilon @tab \zeta +@item @tab \eta @tab \theta @tab \vartheta +@item @tab \iota @tab \kappa @tab \lambda +@item @tab \mu @tab \nu @tab \xi +@item @tab \o @tab \pi @tab \varpi +@item @tab \rho @tab \sigma @tab \varsigma +@item @tab \tau @tab \upsilon @tab \phi +@item @tab \chi @tab \psi @tab \omega +@item Greek Uppercase Letters +@item @tab \Gamma @tab \Delta @tab \Theta +@item @tab \Lambda @tab \Xi @tab \Pi +@item @tab \Sigma @tab \Upsilon @tab \Phi +@item @tab \Psi @tab \Omega @tab +@item Misc Symbols Type Ord +@item @tab \aleph @tab \wp @tab \Re +@item @tab \Im @tab \partial @tab \infty +@item @tab \prime @tab \nabla @tab \surd +@item @tab \angle @tab \forall @tab \exists +@item @tab \neg @tab \clubsuit @tab \diamondsuit +@item @tab \heartsuit @tab \spadesuit @tab +@item ``Large'' Operators +@item @tab \int +@item Binary Operators +@item @tab \pm @tab \cdot @tab \times +@item @tab \ast @tab \circ @tab \bullet +@item @tab \div @tab \cap @tab \cup +@item @tab \vee @tab \wedge @tab \oplus +@item @tab \otimes @tab \oslash @tab +@item Relations +@item @tab \leq @tab \subset @tab \subseteq +@item @tab \in @tab \geq @tab \supset +@item @tab \supseteq @tab \ni @tab \mid +@item @tab \equiv @tab \sim @tab \approx +@item @tab \cong @tab \propto @tab \perp +@item Arrows +@item @tab \leftarrow @tab \Leftarrow @tab \rightarrow +@item @tab \Rightarrow @tab \leftrightarrow @tab \uparrow +@item @tab \downarrow @tab @tab +@item Openings and Closings +@item @tab \lfloor @tab \langle @tab \lceil +@item @tab \rfloor @tab \rangle @tab \rceil +@item Alternate Names +@item @tab \neq +@item Other +@item @tab \ldots @tab \0 @tab \copyright +@item @tab \deg @end multitable @end ifnottex @caption{Available special characters in @TeX{} mode} @end float +@float +@tex +\vskip 6pt +\newdimen\cola \cola=78pt +\newdimen\colb \colb=78pt +\newdimen\colc \colc=78pt +\def\symtable#1#2#3{\hbox to \hsize {\hfill\vbox{\offinterlineskip \tabskip=0pt +\hskip36pt #1 +\vskip6pt +\halign{ +\vrule height2.0ex depth1.ex width 0.6pt #2\tabskip=0.3em & +#2 \hfil & \vrule #2 & #2 \hfil & #2 \vrule & +#2 \hfil & \vrule #2 & #2 \hfil & #2 \vrule & +#2 \hfil & \vrule #2 & #2 \hfil & #2 \vrule +width 0.6pt \tabskip=0pt\cr +\noalign{\hrule height 0.6pt} +& Code && Sym && Code && Sym && Code && Sym &\cr +\noalign{\hrule} +#3 +\noalign{\hrule height 0.6pt} +} +}\hfill}} +\hoffset72pt +\vskip12pt +\symtable{Relations} {#} +{& \hbox to \cola{$\backslash$leq} && $\leq$ +&& \hbox to \colb{$\backslash$subset} && $\subset$ +&& \hbox to \colc{$\backslash$subseteq} && $\subseteq$ &\cr +& $\backslash$in && $\in$ +&& $\backslash$geq && $\geq$ +&& $\backslash$supset && $\supset$ &\cr +& $\backslash$supseteq && $\supseteq$ +&& $\backslash$ni && $\ni$ +&& $\backslash$mid && $\mid$ &\cr +& $\backslash$equiv && $\equiv$ +&& $\backslash$sim && $\sim$ +&& $\backslash$approx && $\approx$ &\cr +& $\backslash$cong && $\cong$ +&& $\backslash$propto && $\propto$ +&& $\backslash$perp && $\perp$ &\cr} +\vskip12pt +\symtable{Arrows} {#} +{& \hbox to \cola{$\backslash$leftarrow} && $\leftarrow$ +&& \hbox to \colb{$\backslash$Leftarrow} && $\Leftarrow$ +&& \hbox to \colc{$\backslash$rightarrow} && $\rightarrow$ &\cr +& $\backslash$Rightarrow && $\Rightarrow$ +&& $\backslash$leftrightarrow && $\leftrightarrow$ +&& $\backslash$uparrow && $\uparrow$ &\cr +& $\backslash$downarrow && $\downarrow$ +&& && +&& && &\cr} +\vskip12pt +\symtable{Openings and Closings} {#} +{& \hbox to \cola{$\backslash$lfloor } && $\lfloor$ +&& \hbox to \colb{$\backslash$langle } && $\langle$ +&& \hbox to \colc{$\backslash$lceil } && $\lceil$ &\cr +& $\backslash$rfloor && $\rfloor$ +&& $\backslash$rangle && $\rangle$ +&& $\backslash$rceil && $\rceil$ &\cr} +\vskip12pt +\symtable{Alternate Names} {#} +{& \hbox to \cola{$\backslash$neq} && $\neq$ +&& \hbox to \colb{} && +&& \hbox to \colc{} && &\cr} +\vskip12pt +\symtable{Other (not in Appendix F Tables)} {#} +{& \hbox to \cola{$\backslash$ldots} && $\ldots$ +&& \hbox to \colb{$\backslash$0} && $\oslash$ +&& \hbox to \colc{$\backslash$copyright} && $\copyright$ &\cr +& $\backslash$deg && $^\circ$ +&& && +&& && &\cr} +\vskip12pt +\hskip36pt Table 15.1: Available special characters in \TeX\ mode (cont.) +@end tex +@end float A complete example showing the capabilities of the extended text is @@ -903,17 +961,17 @@ @cindex graphics data structures @menu -* Introduction to Graphics Structures:: -* Graphics Objects:: -* Graphics Object Properties:: -* Searching Properties:: -* Managing Default Properties:: +* Introduction to Graphics Structures:: +* Graphics Objects:: +* Graphics Object Properties:: +* Searching Properties:: +* Managing Default Properties:: @end menu @node Introduction to Graphics Structures @subsection Introduction to Graphics Structures @cindex introduction to graphics structures -@anchor{docXgraphics structures} +@anchor{XREFgraphics structures} The graphics functions use pointers, which are of class graphics_handle, in order to address the data structures which control graphical displays. A @@ -933,7 +991,7 @@ @code{contourf}, @code{contour3}, @code{surf}, @code{mesh}, @code{surfc}, @code{meshc}, @code{errorbar}, @code{quiver}, @code{quiver3}, @code{scatter}, @code{scatter3}, @code{stair}, @code{stem}, @code{stem3} each return a handle -as documented in @ref{docXdatasources,, Data Sources}. +as documented in @ref{XREFdatasources,,Data Sources}. The graphics objects are arranged in a hierarchy: @@ -950,9 +1008,9 @@ @code{surface}, and @code{image} objects. Graphics handles may be distinguished from function handles -(@ref{Function Handles}) by means of the function @code{ishandle}. -@code{ishandle} returns true if its argument is a handle of a graphics object. -In addition, the figure object may be tested using @code{isfigure}. +(@pxref{Function Handles}) by means of the function @code{ishandle}. +@code{ishandle} returns true if its argument is a handle of a graphics object. +In addition, the figure object may be tested using @code{isfigure}. @code{isfigure} returns true only if its argument is a handle of a figure. The @code{whos} function can be used to show the object type of each currently defined graphics handle. (Note: this is not true today, but it is, I hope, @@ -965,8 +1023,8 @@ properties of graphics objects. In addition, the @code{get} command may be used to obtain property names. -For example, the property "type" of the graphics object pointed to by the -graphics handle h may be displayed by: +For example, the property @qcode{"type"} of the graphics object pointed to by +the graphics handle h may be displayed by: @example get (h, "type") @@ -977,7 +1035,7 @@ allowed properties are wanted they may be displayed by: @code{get (h, "")}. -Thus, for example, +Thus, for example: @smallexample h = figure (); @@ -1001,7 +1059,7 @@ color paperposition windowbuttondownfcn colormap paperpositionmode windowbuttonmotionfcn createfcn papersize windowbuttonupfcn -currentaxes papertype windowbuttonwheelfcn +currentaxes papertype windowscrollwheelfcn currentcharacter paperunits windowstyle currentobject parent wvisual currentpoint pointer wvisualmode @@ -1016,7 +1074,7 @@ @code{get (0, "")}. The uses of @code{get} and @code{set} are further explained in -@ref{docXget,,get}, @ref{docXset,,set}. +@ref{XREFget,,get}, @ref{XREFset,,set}. @DOCSTRING(isprop) @@ -1024,8 +1082,8 @@ @subsection Graphics Objects @cindex graphics objects -The hierarchy of graphics objects was explained above. (See -@ref{Introduction to Graphics Structures}. Here the +The hierarchy of graphics objects was explained above. +@xref{Introduction to Graphics Structures}. Here the specific objects are described, and the properties contained in these objects are discussed. Keep in mind that graphics objects are always referenced by @dfn{handle}. @@ -1077,16 +1135,36 @@ @c @end group @end table +@subsubsection Creating Graphics Objects +@cindex creating graphics objects + +You can create axes, line, patch, and surface objects directly using the +@code{axes}, @code{line}, @code{patch}, @code{fill}, and @code{surface} +functions. These objects become children of the current axes object. + +@DOCSTRING(axes) + +@DOCSTRING(line) + +@DOCSTRING(patch) + +@DOCSTRING(fill) + +@DOCSTRING(surface) + @subsubsection Handle Functions @cindex handle functions -To determine whether a variable is a graphics object index or a figure -index, use the functions @code{ishandle} and @code{isfigure}. +To determine whether a variable is a graphics object index, or an index +to an axes or figure, use the functions @code{ishandle}, @code{isaxes}, and +@code{isfigure}. @DOCSTRING(ishandle) @DOCSTRING(ishghandle) +@DOCSTRING(isaxes) + @DOCSTRING(isfigure) The function @code{gcf} returns an index to the current figure object, @@ -1175,9 +1253,9 @@ Figures can be printed or saved in many graphics formats with @code{print} and @code{saveas}. Occasionally, however, it may be useful to save the original Octave handle graphic directly so that further modifications can be made such -as modifying a title or legend. - -This can be accomplished with the following functions by +as modifying a title or legend. + +This can be accomplished with the following functions by @example @group @@ -1200,14 +1278,14 @@ @cindex graphics object properties @menu -* Root Figure Properties:: -* Figure Properties:: -* Axes Properties:: -* Line Properties:: -* Text Properties:: -* Image Properties:: -* Patch Properties:: -* Surface Properties:: +* Root Figure Properties:: +* Figure Properties:: +* Axes Properties:: +* Line Properties:: +* Text Properties:: +* Image Properties:: +* Patch Properties:: +* Surface Properties:: @end menu In this Section the object properties are discussed in detail, starting @@ -1221,13 +1299,13 @@ The @code{root figure} properties are: @table @code -@item __modified__ ---- Values: "on," "off" +@item __modified__ +--- Values: @qcode{"on"}, @qcode{"off"} @item __myhandle__ -@item beingdeleted ---- Values: "on," "off" +@item beingdeleted +--- Values: @qcode{"on"}, @qcode{"off"} @item busyaction @@ -1238,7 +1316,7 @@ @item children @item clipping - --- Values: "on," "off" + --- Values: @qcode{"on"}, @qcode{"off"} @item createfcn @@ -1246,14 +1324,14 @@ @item deletefcn -@item handlevisibility ---- Values: "on," "off" +@item handlevisibility +--- Values: @qcode{"on"}, @qcode{"off"} @item hittest ---- Values: "on," "off" - -@item interruptible ---- Values: "on," "off" +--- Values: @qcode{"on"}, @qcode{"off"} + +@item interruptible +--- Values: @qcode{"on"}, @qcode{"off"} @item parent @@ -1271,8 +1349,8 @@ @item screenpixelsperinch -@item showhiddenhandles ---- Values: "on," "off" +@item showhiddenhandles +--- Values: @qcode{"on"}, @qcode{"off"} @item tag @@ -1294,7 +1372,7 @@ The @code{figure} properties are: @table @code -@item __graphics_toolkit__ +@item __graphics_toolkit__ --- The graphics toolkit currently in use. @item __enhanced__ @@ -1307,8 +1385,8 @@ @item alphamap -@item beingdeleted ---- Values: "on," "off" +@item beingdeleted +--- Values: @qcode{"on"}, @qcode{"off"} @item busyaction @@ -1318,9 +1396,9 @@ Handle to children. @item clipping ---- Values: "on," "off" - -@item closerequestfcn +--- Values: @qcode{"on"}, @qcode{"off"} + +@item closerequestfcn --- Handle of function to call on close. @item color @@ -1332,7 +1410,7 @@ @item createfcn -@item currentaxes +@item currentaxes Handle to graphics object of current axes. @item currentcharacter @@ -1342,36 +1420,36 @@ @item currentpoint Holds the coordinates of the point over which the mouse pointer was when the mouse button was pressed. If a mouse callback function is defined, -@code{"currentpoint"} holds the coordinates of the point over which the +@qcode{"currentpoint"} holds the coordinates of the point over which the mouse pointer is when the function gets called. @item deletefcn -@item dockcontrols ---- Values: "on," "off" - -@item doublebuffer ---- Values: "on," "off" +@item dockcontrols +--- Values: @qcode{"on"}, @qcode{"off"} + +@item doublebuffer +--- Values: @qcode{"on"}, @qcode{"off"} @item filename -@item handlevisibility ---- Values: "on," "off" +@item handlevisibility +--- Values: @qcode{"on"}, @qcode{"off"} @item hittest @item integerhandle -@item interruptible ---- Values: "on," "off" +@item interruptible +--- Values: @qcode{"on"}, @qcode{"off"} @item inverthardcopy @item keypressfcn -see @code{"keypressfcn"} +see @qcode{"keypressfcn"} @item keyreleasefcn -With @code{"keypressfcn"}, The keyboard callback functions. These +With @qcode{"keypressfcn"}, the keyboard callback functions. These callback functions get called when a key is pressed/released respectively. The functions are called with two input arguments. The first argument holds the handle of the calling figure. The second @@ -1386,8 +1464,8 @@ @item Modifier A cell array containing strings representing the modifiers pressed with -the key. Possible values are @code{"shift"}, @code{"alt"}, and -@code{"control"}. +the key. Possible values are @qcode{"shift"}, @qcode{"alt"}, and +@qcode{"control"}. @end table @item menubar @@ -1399,21 +1477,21 @@ @item nextplot May be one of -@table @code -@item "new" - -@item "add" - -@item "replace" - -@item "replacechildren" +@table @asis +@item @qcode{"new"} + +@item @qcode{"add"} + +@item @qcode{"replace"} + +@item @qcode{"replacechildren"} @end table @item numbertitle @item paperorientation -Indicates the orientation for printing. Either @code{"landscape"} or -@code{"portrait"}. +Indicates the orientation for printing. Either @qcode{"landscape"} or +@qcode{"portrait"}. @item paperposition @@ -1443,8 +1521,8 @@ @item selected -@item selectionhighlight ---- Values: "on," "off" +@item selectionhighlight +--- Values: @qcode{"on"}, @qcode{"off"} @item selectiontype @@ -1459,22 +1537,22 @@ @item userdata @item visible -Either @code{"on"} or @code{"off"} to toggle display of the figure. +Either @qcode{"on"} or @qcode{"off"} to toggle display of the figure. @item windowbuttondownfcn -See @code{"windowbuttonupfcn"} +See @qcode{"windowbuttonupfcn"} @item windowbuttonmotionfcn -See @code{"windowbuttonupfcn"} +See @qcode{"windowbuttonupfcn"} @item windowbuttonupfcn -With @code{"windowbuttondownfcn"} and @code{"windowbuttonmotionfcn"}, -The mouse callback functions. These callback functions get called when +With @qcode{"windowbuttondownfcn"} and @qcode{"windowbuttonmotionfcn"}, +the mouse callback functions. These callback functions get called when the mouse button is pressed, dragged, and released respectively. When -these callback functions are called, the @code{"currentpoint"} property +these callback functions are called, the @qcode{"currentpoint"} property holds the current coordinates of the cursor. -@item windowbuttonwheelfcn +@item windowscrollwheelfcn @item windowstyle @@ -1511,8 +1589,8 @@ @item beingdeleted @item box -Box surrounding axes. ---- Values: "on," "off" +Box surrounding axes. +--- Values: @qcode{"on"}, @qcode{"off"} @item busyaction @@ -1540,10 +1618,10 @@ Two-element vector defining the limits for the c axis of an image. See @code{pcolor} property. Setting this property also forces the corresponding mode -property to be set to @code{"manual"}. +property to be set to @qcode{"manual"}. @item climmode -Either @code{"manual"} or @code{"auto"}. +Either @qcode{"manual"} or @qcode{"auto"}. @item clipping @@ -1556,7 +1634,7 @@ @item currentpoint Holds the coordinates of the point over which the mouse pointer was when the mouse button was pressed. If a mouse callback function is defined, -@code{"currentpoint"} holds the coordinates of the point over which the +@qcode{"currentpoint"} holds the coordinates of the point over which the mouse pointer is when the function gets called. @item dataaspectratio @@ -1565,10 +1643,10 @@ 2]} causes the length of one unit as displayed on the y-axis to be the same as the length of 2 units on the x-axis. Setting @code{dataaspectratio} also forces the @code{dataaspectratiomode} -property to be set to @code{"manual"}. - -@item dataaspectratiomode -Either @code{"manual"} or @code{"auto"}. +property to be set to @qcode{"manual"}. + +@item dataaspectratiomode +Either @qcode{"manual"} or @qcode{"auto"}. @item deletefcn @@ -1605,14 +1683,12 @@ @item nextplot May be one of -@table @code -@item "new" - -@item "add" - -@item "replace" - -@item "replacechildren" +@table @asis +@item @qcode{"add"} + +@item @qcode{"replace"} + +@item @qcode{"replacechildren"} @end table @item outerposition @@ -1670,7 +1746,7 @@ A three element vector specifying the view point for three-dimensional plots. @item visible -Either @code{"on"} or @code{"off"} to toggle display of the axes. +Either @qcode{"on"} or @qcode{"off"} to toggle display of the axes. @item x_normrendertransform @@ -1682,16 +1758,16 @@ @item x_viewtransform -@item xaxislocation -Either @code{"top"} or @code{"bottom"}. +@item xaxislocation +Either @qcode{"top"} or @qcode{"bottom"}. @item xcolor @item xdir -Either @code{"forward"} or @code{"reverse"}. +Either @qcode{"forward"} or @qcode{"reverse"}. @item xgrid -Either @code{"on"} or @code{"off"} to toggle display of grid lines. +Either @qcode{"on"} or @qcode{"off"} to toggle display of grid lines. @item xlabel Indices to text objects for the axes labels. @@ -1699,44 +1775,44 @@ @item xlim Two-element vector defining the limits for the x-axis. Setting this property also forces the corresponding mode -property to be set to @code{"manual"}. +property to be set to @qcode{"manual"}. @item xlimmode -Either @code{"manual"} or @code{"auto"}. - -@item xminorgrid -Either @code{"on"} or @code{"off"} to toggle display of minor grid lines. +Either @qcode{"manual"} or @qcode{"auto"}. + +@item xminorgrid +Either @qcode{"on"} or @qcode{"off"} to toggle display of minor grid lines. @item xminortick @item xscale -Either @code{"linear"} or @code{"log"}. +Either @qcode{"linear"} or @qcode{"log"}. @item xtick Set position of tick marks. Setting this property also forces the corresponding mode -property to be set to @code{"manual"}. +property to be set to @qcode{"manual"}. @item xticklabel Setting this property also forces the corresponding mode -property to be set to @code{"manual"}. - -@item xticklabelmode -Either @code{"manual"} or @code{"auto"}. - -@item xtickmode -Either @code{"manual"} or @code{"auto"}. - -@item yaxislocation -Either @code{"left"} or @code{"right"} +property to be set to @qcode{"manual"}. + +@item xticklabelmode +Either @qcode{"manual"} or @qcode{"auto"}. + +@item xtickmode +Either @qcode{"manual"} or @qcode{"auto"}. + +@item yaxislocation +Either @qcode{"left"} or @qcode{"right"} @item ycolor @item ydir -Either @code{"forward"} or @code{"reverse"}. +Either @qcode{"forward"} or @qcode{"reverse"}. @item ygrid -Either @code{"on"} or @code{"off"} to toggle display of grid lines. +Either @qcode{"on"} or @qcode{"off"} to toggle display of grid lines. @item ylabel Indices to text objects for the axes labels. @@ -1744,41 +1820,41 @@ @item ylim Two-element vectors defining the limits for the x, y, and z axes and the Setting one of these properties also forces the corresponding mode -property to be set to @code{"manual"}. +property to be set to @qcode{"manual"}. @item ylimmode -Either @code{"manual"} or @code{"auto"}. - -@item yminorgrid -Either @code{"on"} or @code{"off"} to toggle display of minor grid lines. +Either @qcode{"manual"} or @qcode{"auto"}. + +@item yminorgrid +Either @qcode{"on"} or @qcode{"off"} to toggle display of minor grid lines. @item yminortick @item yscale -Either @code{"linear"} or @code{"log"}. +Either @qcode{"linear"} or @qcode{"log"}. @item ytick Set position of tick marks. Setting this property also forces the corresponding mode -property to be set to @code{"manual"}. +property to be set to @qcode{"manual"}. @item yticklabel Setting this property also forces the corresponding mode -property to be set to @code{"manual"}. - -@item yticklabelmode -Either @code{"manual"} or @code{"auto"}. - -@item ytickmode -Either @code{"manual"} or @code{"auto"}. +property to be set to @qcode{"manual"}. + +@item yticklabelmode +Either @qcode{"manual"} or @qcode{"auto"}. + +@item ytickmode +Either @qcode{"manual"} or @qcode{"auto"}. @item zcolor @item zdir -Either @code{"forward"} or @code{"reverse"}. +Either @qcode{"forward"} or @qcode{"reverse"}. @item zgrid -Either @code{"on"} or @code{"off"} to toggle display of grid lines. +Either @qcode{"on"} or @qcode{"off"} to toggle display of grid lines. @item zlabel Indices to text objects for the axes labels. @@ -1786,33 +1862,33 @@ @item zlim Two-element vector defining the limits for z-axis. Setting this property also forces the corresponding mode -property to be set to @code{"manual"}. +property to be set to @qcode{"manual"}. @item zlimmode -Either @code{"manual"} or @code{"auto"}. - -@item zminorgrid -Either @code{"on"} or @code{"off"} to toggle display of minor grid lines. +Either @qcode{"manual"} or @qcode{"auto"}. + +@item zminorgrid +Either @qcode{"on"} or @qcode{"off"} to toggle display of minor grid lines. @item zminortick @item zscale -Either @code{"linear"} or @code{"log"}. +Either @qcode{"linear"} or @qcode{"log"}. @item ztick Set position of tick marks. Setting this property also forces the corresponding mode -property to be set to @code{"manual"}. - -@item zticklabel +property to be set to @qcode{"manual"}. + +@item zticklabel Setting this property also forces the corresponding mode -property to be set to @code{"manual"}. - -@item zticklabelmode -Either @code{"manual"} or @code{"auto"}. +property to be set to @qcode{"manual"}. + +@item zticklabelmode +Either @qcode{"manual"} or @qcode{"auto"}. @item ztickmode -Either @code{"manual"} or @code{"auto"}. +Either @qcode{"manual"} or @qcode{"auto"}. @end table @@ -1860,7 +1936,7 @@ @item ldata The lower errorbar in the y direction to be plotted. -@item linestyle +@item linestyle @itemx linewidth @xref{Line Styles}. @@ -1968,8 +2044,8 @@ @item erasemode @item fontangle -Flag whether the font is italic or normal. Valid values are 'normal', -'italic' and 'oblique'. +Flag whether the font is italic or normal. Valid values are @qcode{"normal"}, +@qcode{"italic"}, and @qcode{"oblique"}. @item fontname The font used for the text. @@ -1980,19 +2056,19 @@ @item fontunits @item fontweight -Flag whether the font is bold, etc. Valid values are 'normal', 'bold', -'demi' or 'light'. +Flag whether the font is bold, etc. Valid values are @qcode{"normal"}, +@qcode{"bold"}, @qcode{"demi"}, or @qcode{"light"}. @item handlevisibility @item hittest @item horizontalalignment -May be @code{"left"}, @code{"center"}, or @code{"right"}. +May be @qcode{"left"}, @qcode{"center"}, or @qcode{"right"}. @item interpreter -Determines how the text is rendered. Valid values are 'none', 'tex' or -'latex'. +Determines how the text is rendered. Valid values are @qcode{"none"}, +@qcode{"tex"}, or @qcode{"latex"}. @item interruptible @@ -2024,7 +2100,7 @@ @item uicontextmenu @item units -May be @code{"normalized"} or @code{"graph"}. +May be @qcode{"normalized"} or @qcode{"graph"}. @item userdata @@ -2435,8 +2511,8 @@ Although default values may be set for any object, they are set in parent objects and apply to child objects, of the specified object type. For example, setting the default @code{color} property of @code{line} -objects to "green", for the @code{root} object, will result in all -@code{line} objects inheriting the @code{color} "green" as the default +objects to @qcode{"green"}, for the @code{root} object, will result in all +@code{line} objects inheriting the @code{color} @qcode{"green"} as the default value. @example @@ -2484,7 +2560,7 @@ from the global root figure parent object. To remove a user-defined default setting, set the default property to -the value @code{"remove"}. For example, +the value @qcode{"remove"}. For example, @example set (gca (), "defaultlinecolor", "remove"); @@ -2497,7 +2573,7 @@ @DOCSTRING(reset) -Getting the @code{"default"} property of an object returns a list of +Getting the @qcode{"default"} property of an object returns a list of user-defined defaults set for the object. For example, @example @@ -2523,13 +2599,13 @@ @menu -* Colors:: -* Line Styles:: -* Marker Styles:: -* Callbacks:: +* Colors:: +* Line Styles:: +* Marker Styles:: +* Callbacks:: * Application-defined Data:: -* Object Groups:: -* Graphics Toolkits:: +* Object Groups:: +* Graphics Toolkits:: @end menu @@ -2539,9 +2615,9 @@ @cindex colors, graphics Colors may be specified as RGB triplets with values ranging from zero to -one, or by name. Recognized color names include @code{"blue"}, -@code{"black"}, @code{"cyan"}, @code{"green"}, @code{"magenta"}, -@code{"red"}, @code{"white"}, and @code{"yellow"}. +one, or by name. Recognized color names include @qcode{"blue"}, +@qcode{"black"}, @qcode{"cyan"}, @qcode{"green"}, @qcode{"magenta"}, +@qcode{"red"}, @qcode{"white"}, and @qcode{"yellow"}. @node Line Styles @subsection Line Styles @@ -2567,7 +2643,7 @@ @item "-." A dash-dot line. -@item "none" +@item @qcode{"none"} No line. Points will still be marked using the current Marker Style. @end table @@ -2586,14 +2662,14 @@ @table @code @item marker A character indicating a plot marker to be place at each data point, or -@code{"none"}, meaning no markers should be displayed. +@qcode{"none"}, meaning no markers should be displayed. @item markeredgecolor -The color of the edge around the marker, or @code{"auto"}, meaning that +The color of the edge around the marker, or @qcode{"auto"}, meaning that the edge color is the same as the face color. @xref{Colors}. @item markerfacecolor -The color of the marker, or @code{"none"} to indicate that the marker +The color of the marker, or @qcode{"none"} to indicate that the marker should not be filled. @xref{Colors}. @item markersize @@ -2681,7 +2757,7 @@ function described below. @node Application-defined Data -@subsection Application-defined Data +@subsection Application-defined Data @cindex application-defined data Octave has a provision for attaching application-defined data to a graphics @@ -2824,23 +2900,23 @@ corresponding hggroup elements. @menu -* Data Sources in Object Groups:: -* Area Series:: -* Bar Series:: -* Contour Groups:: -* Error Bar Series:: -* Line Series:: -* Quiver Group:: -* Scatter Group:: -* Stair Group:: -* Stem Series:: -* Surface Group:: +* Data Sources in Object Groups:: +* Area Series:: +* Bar Series:: +* Contour Groups:: +* Error Bar Series:: +* Line Series:: +* Quiver Group:: +* Scatter Group:: +* Stair Group:: +* Stem Series:: +* Surface Group:: @end menu @node Data Sources in Object Groups @subsubsection Data Sources in Object Groups @cindex data sources in object groups -@anchor{docXdatasources} +@anchor{XREFdatasources} All of the group objects contain data source parameters. There are string parameters that contain an expression that is evaluated to update the relevant data property of the group when the @code{refreshdata} @@ -2848,7 +2924,7 @@ @DOCSTRING(refreshdata) -@anchor{docXlinkdata} +@anchor{XREFlinkdata} @c add the description of the linkdata function here when it is written @c remove the explicit anchor when you add the corresponding @DOCSTRING @c command @@ -2866,23 +2942,23 @@ @item basevalue The value where the base of the area plot is drawn. -@item linewidth +@item linewidth @itemx linestyle The line width and style of the edge of the patch objects making up the areas. @xref{Line Styles}. -@item edgecolor +@item edgecolor @itemx facecolor -The line and fill color of the patch objects making up the areas. +The line and fill color of the patch objects making up the areas. @xref{Colors}. -@item xdata +@item xdata @itemx ydata The x and y coordinates of the original columns of the data passed to @code{area} prior to the cumulative summation used in the @code{area} function. -@item xdatasource +@item xdatasource @itemx ydatasource Data source variables. @end table @@ -2897,12 +2973,12 @@ The properties of the bar series are @table @code -@item showbaseline +@item showbaseline @itemx baseline @itemx basevalue The property @code{showbaseline} flags whether the baseline of the bar -series is displayed (default is "on"). The handle of the graphics object -representing the baseline is given by the @code{baseline} property and +series is displayed (default is @qcode{"on"}). The handle of the graphics +object representing the baseline is given by the @code{baseline} property and the y-value of the baseline by the @code{basevalue} property. Changes to any of these property are propagated to the other members of @@ -2910,24 +2986,24 @@ properties of the base line itself are propagated to the members of the corresponding bar series. -@item barwidth +@item barwidth @itemx barlayout @itemx horizontal The property @code{barwidth} is the width of the bar corresponding to the @var{width} variable passed to @code{bar} or @var{barh}. Whether the -bar series is "grouped" or "stacked" is determined by the +bar series is @qcode{"grouped"} or @qcode{"stacked"} is determined by the @code{barlayout} property and whether the bars are horizontal or vertical by the @code{horizontal} property. Changes to any of these property are propagated to the other members of the bar series. -@item linewidth +@item linewidth @itemx linestyle The line width and style of the edge of the patch objects making up the bars. @xref{Line Styles}. -@item edgecolor +@item edgecolor @itemx facecolor The line and fill color of the patch objects making up the bars. @xref{Colors}. @@ -2938,7 +3014,7 @@ @item ydata The y value of the bars in the @code{hggroup}. -@item xdatasource +@item xdatasource @itemx ydatasource Data source variables. @end table @@ -2959,37 +3035,37 @@ create the contours of the plot. @item fill -A radio property that can have the values "on" or "off" that flags whether the -contours to plot are to be filled. - -@item zlevelmode +A radio property that can have the values @qcode{"on"} or @qcode{"off"} that +flags whether the contours to plot are to be filled. + +@item zlevelmode @itemx zlevel -The radio property @code{zlevelmode} can have the values "none", "auto" or -"manual". When its value is "none" there is no z component to the plotted -contours. When its value is "auto" the z value of the plotted contours is -at the same value as the contour itself. If the value is "manual", then the -z value at which to plot the contour is determined by the @code{zlevel} -property. - -@item levellistmode +The radio property @code{zlevelmode} can have the values @qcode{"none"}, +@qcode{"auto"}, or @qcode{"manual"}. When its value is @qcode{"none"} there is +no z component to the plotted contours. When its value is @qcode{"auto"} the z +value of the plotted contours is at the same value as the contour itself. If +the value is @qcode{"manual"}, then the z value at which to plot the contour is +determined by the @code{zlevel} property. + +@item levellistmode @itemx levellist @itemx levelstepmode @itemx levelstep -If @code{levellistmode} is "manual", then the levels at which to plot the -contours is determined by @code{levellist}. If @code{levellistmode} is -set to "auto", then the distance between contours is determined by -@code{levelstep}. If both @code{levellistmode} and @code{levelstepmode} -are set to "auto", then there are assumed to be 10 equal spaced contours. - -@item textlistmode +If @code{levellistmode} is @qcode{"manual"}, then the levels at which to plot +the contours is determined by @code{levellist}. If @code{levellistmode} is set +to @qcode{"auto"}, then the distance between contours is determined by +@code{levelstep}. If both @code{levellistmode} and @code{levelstepmode} are +set to @qcode{"auto"}, then there are assumed to be 10 equal spaced contours. + +@item textlistmode @itemx textlist @itemx textstepmode @itemx textstep -If @code{textlistmode} is "manual", then the labeled contours +If @code{textlistmode} is @qcode{"manual"}, then the labeled contours is determined by @code{textlist}. If @code{textlistmode} is set to -"auto", then the distance between labeled contours is determined by +@qcode{"auto"}, then the distance between labeled contours is determined by @code{textstep}. If both @code{textlistmode} and @code{textstepmode} -are set to "auto", then there are assumed to be 10 equal spaced +are set to @qcode{"auto"}, then there are assumed to be 10 equal spaced labeled contours. @item showtext @@ -3006,16 +3082,16 @@ The properties of the contour lines. The properties @code{linewidth} and @code{linestyle} are similar to the corresponding properties for lines. The property @code{linecolor} is a color property (@pxref{Colors}), that can also -have the values of "none" or "auto". If @code{linecolor} is "none", then no -contour line is drawn. If @code{linecolor} is "auto" then the line color is -determined by the colormap. - -@item xdata +have the values of @qcode{"none"} or @qcode{"auto"}. If @code{linecolor} is +@qcode{"none"}, then no contour line is drawn. If @code{linecolor} is +@qcode{"auto"} then the line color is determined by the colormap. + +@item xdata @itemx ydata @itemx zdata The original x, y, and z data of the contour lines. -@item xdatasource +@item xdatasource @itemx ydatasource @itemx zdatasource Data source variables. @@ -3032,21 +3108,21 @@ @table @code @item color -The RGB color or color name of the line objects of the error bars. +The RGB color or color name of the line objects of the error bars. @xref{Colors}. -@item linewidth +@item linewidth @itemx linestyle The line width and style of the line objects of the error bars. @xref{Line Styles}. -@item marker +@item marker @itemx markeredgecolor @itemx markerfacecolor @itemx markersize The line and fill color of the markers on the error bars. @xref{Colors}. -@item xdata +@item xdata @itemx ydata @itemx ldata @itemx udata @@ -3054,7 +3130,7 @@ @itemx xudata The original x, y, l, u, xl, xu data of the error bars. -@item xdatasource +@item xdatasource @itemx ydatasource @itemx ldatasource @itemx udatasource @@ -3076,22 +3152,22 @@ @item color The RGB color or color name of the line objects. @xref{Colors}. -@item linewidth +@item linewidth @itemx linestyle The line width and style of the line objects. @xref{Line Styles}. -@item marker +@item marker @itemx markeredgecolor @itemx markerfacecolor @itemx markersize The line and fill color of the markers. @xref{Colors}. -@item xdata +@item xdata @itemx ydata @itemx zdata The original x, y and z data. -@item xdatasource +@item xdatasource @itemx ydatasource @itemx zdatasource Data source variables. @@ -3109,7 +3185,7 @@ properties of the quiver series are @table @code -@item autoscale +@item autoscale @itemx autoscalefactor Flag whether the length of the arrows is scaled or defined directly from the @var{u}, @var{v} and @var{w} data. If the arrow length is flagged @@ -3126,27 +3202,27 @@ @item color The RGB color or color name of the line objects of the quiver. @xref{Colors}. -@item linewidth +@item linewidth @itemx linestyle The line width and style of the line objects of the quiver. @xref{Line Styles}. -@item marker +@item marker @itemx markerfacecolor @itemx markersize The line and fill color of the marker objects at the original of the arrows. @xref{Colors}. -@item xdata +@item xdata @itemx ydata @itemx zdata The origins of the values of the vector field. -@item udata +@item udata @itemx vdata @itemx wdata The values of the vector field to plot. -@item xdatasource +@item xdatasource @itemx ydatasource @itemx zdatasource @itemx udatasource @@ -3169,12 +3245,12 @@ @item linewidth The line width of the line objects of the points. @xref{Line Styles}. -@item marker +@item marker @itemx markeredgecolor @itemx markerfacecolor The line and fill color of the markers of the points. @xref{Colors}. -@item xdata +@item xdata @itemx ydata @itemx zdata The original x, y and z data of the stems. @@ -3187,7 +3263,7 @@ The size data for the points of the plot. Each point can its own size or a unique size can be specified. -@item xdatasource +@item xdatasource @itemx ydatasource @itemx zdatasource @itemx cdatasource @@ -3208,21 +3284,21 @@ @item color The RGB color or color name of the line objects of the stairs. @xref{Colors}. -@item linewidth +@item linewidth @itemx linestyle The line width and style of the line objects of the stairs. @xref{Line Styles}. -@item marker +@item marker @itemx markeredgecolor @itemx markerfacecolor @itemx markersize The line and fill color of the markers on the stairs. @xref{Colors}. -@item xdata +@item xdata @itemx ydata The original x and y data of the stairs. -@item xdatasource +@item xdatasource @itemx ydatasource Data source variables. @end table @@ -3238,11 +3314,11 @@ are @table @code -@item showbaseline +@item showbaseline @itemx baseline @itemx basevalue The property @code{showbaseline} flags whether the baseline of the -stem series is displayed (default is "on"). The handle of the graphics +stem series is displayed (default is @qcode{"on"}). The handle of the graphics object representing the baseline is given by the @code{baseline} property and the y-value (or z-value for @code{stem3}) of the baseline by the @code{basevalue} property. @@ -3255,22 +3331,22 @@ @item color The RGB color or color name of the line objects of the stems. @xref{Colors}. -@item linewidth +@item linewidth @itemx linestyle The line width and style of the line objects of the stems. @xref{Line Styles}. -@item marker +@item marker @itemx markeredgecolor @itemx markerfacecolor @itemx markersize The line and fill color of the markers on the stems. @xref{Colors}. -@item xdata +@item xdata @itemx ydata @itemx zdata The original x, y and z data of the stems. -@item xdatasource +@item xdatasource @itemx ydatasource @itemx zdatasource Data source variables. @@ -3291,26 +3367,26 @@ @item edgecolor @item facecolor -The RGB color or color name of the edges or faces of the surface. +The RGB color or color name of the edges or faces of the surface. @xref{Colors}. -@item linewidth +@item linewidth @itemx linestyle The line width and style of the lines on the surface. @xref{Line Styles}. -@item marker +@item marker @itemx markeredgecolor @itemx markerfacecolor @itemx markersize The line and fill color of the markers on the surface. @xref{Colors}. -@item xdata +@item xdata @itemx ydata @itemx zdata @itemx cdata The original x, y, z and c data. -@item xdatasource +@item xdatasource @itemx ydatasource @itemx zdatasource @itemx cdatasource @@ -3331,7 +3407,7 @@ @DOCSTRING(register_graphics_toolkit) @menu -* Customizing Toolkit Behavior:: +* Customizing Toolkit Behavior:: @end menu @node Customizing Toolkit Behavior diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/plotimages.m --- a/doc/interpreter/plotimages.m Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/plotimages.m Sat Oct 05 11:22:09 2013 -0400 @@ -26,7 +26,7 @@ if (strcmp (typ, "eps")) d_typ = "-depsc2"; else - d_typ = cstrcat ("-d", typ); + d_typ = ["-d", typ]; endif if (strcmp(typ , "txt")) @@ -34,11 +34,17 @@ elseif (strcmp (nm, "plot")) x = -10:0.1:10; plot (x, sin (x)); - print (cstrcat (nm, ".", typ), d_typ) + xlabel ("x"); + ylabel ("sin (x)"); + title ("Simple 2-D Plot"); + print ([nm "." typ], d_typ); elseif (strcmp (nm, "hist")) rand ("state", 2); hist (randn (10000, 1), 30); - print (cstrcat (nm, ".", typ), d_typ) + xlabel ("Value"); + ylabel ("Count"); + title ("Histogram of 10,000 normally distributed random numbers"); + print ([nm "." typ], d_typ); elseif (strcmp (nm, "errorbar")) rand ("state", 2); x = 0:0.1:10; @@ -47,32 +53,47 @@ yu = 0.1 .* rand (size (x)); errorbar (x, sin (x), yl, yu); axis ([0, 10, -1.1, 1.1]); - print (cstrcat (nm, ".", typ), d_typ) + xlabel ("x"); + ylabel ("sin (x)"); + title ("Errorbar plot of sin (x)"); + print ([nm "." typ], d_typ); elseif (strcmp (nm, "polar")) polar (0:0.1:10*pi, 0:0.1:10*pi); - print (cstrcat (nm, ".", typ), d_typ) + title ("Example polar plot from 0 to 10*pi"); + print ([nm "." typ], d_typ); elseif (strcmp (nm, "mesh")) tx = ty = linspace (-8, 8, 41)'; [xx, yy] = meshgrid (tx, ty); r = sqrt (xx .^ 2 + yy .^ 2) + eps; tz = sin (r) ./ r; mesh (tx, ty, tz); - print (cstrcat (nm, ".", typ), d_typ) + xlabel ("tx"); + ylabel ("ty"); + zlabel ("tz"); + title ("3-D Sombrero plot"); + print ([nm "." typ], d_typ); elseif (strcmp (nm, "plot3")) t = 0:0.1:10*pi; r = linspace (0, 1, numel (t)); z = linspace (0, 1, numel (t)); plot3 (r.*sin(t), r.*cos(t), z); - print (cstrcat (nm, ".", typ), d_typ) + xlabel ("r.*sin (t)"); + ylabel ("r.*cos (t)"); + zlabel ("z"); + title ("plot3 display of 3-D helix"); + print ([nm "." typ], d_typ); elseif (strcmp (nm, "extended")) x = 0:0.01:3; - plot(x,erf(x)); + plot (x,erf(x)); hold on; - plot(x,x,"r"); - axis([0, 3, 0, 1]); - text(0.65, 0.6175, cstrcat('\leftarrow x = {2/\surd\pi {\fontsize{16}', - '\int_{\fontsize{8}0}^{\fontsize{8}x}} e^{-t^2} dt} = 0.6175')) - print (cstrcat (nm, ".", typ), d_typ) + plot (x,x,"r"); + axis ([0, 3, 0, 1]); + text (0.65, 0.6175, ['\leftarrow x = {2/\surd\pi {\fontsize{16}' ... + '\int_{\fontsize{8}0}^{\fontsize{8}x}} e^{-t^2} dt} = 0.6175']); + xlabel ("x"); + ylabel ("erf (x)"); + title ("erf (x) with text annotation"); + print ([nm "." typ], d_typ); else error ("unrecognized plot requested"); endif diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/preface.txi --- a/doc/interpreter/preface.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/preface.txi Sat Oct 05 11:22:09 2013 -0400 @@ -63,10 +63,10 @@ you may have. @menu -* Acknowledgements:: +* Acknowledgements:: * Citing Octave in Publications:: -* How You Can Contribute to Octave:: -* Distribution:: +* How You Can Contribute to Octave:: +* Distribution:: @end menu @node Acknowledgements diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/quad.txi --- a/doc/interpreter/quad.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/quad.txi Sat Oct 05 11:22:09 2013 -0400 @@ -24,9 +24,9 @@ 1-dimensional integration problems. @menu -* Functions of One Variable:: -* Orthogonal Collocation:: -* Functions of Multiple Variables:: +* Functions of One Variable:: +* Orthogonal Collocation:: +* Functions of Multiple Variables:: @end menu @node Functions of One Variable @@ -134,9 +134,10 @@ is reasonably accurate (to see why, examine what happens to the result if you move the lower bound to 0.1, then 0.01, then 0.001, etc.). -The function "f" can be the string name of a function, a function handle, or -an inline function. These options make it quite easy to do integration -without having to fully define a function in an m-file. For example: +The function @qcode{"f"} can be the string name of a function, a function +handle, or an inline function. These options make it quite easy to do +integration without having to fully define a function in an m-file. For +example: @example @group diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/signal.txi --- a/doc/interpreter/signal.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/signal.txi Sat Oct 05 11:22:09 2013 -0400 @@ -19,18 +19,23 @@ @node Signal Processing @chapter Signal Processing - This chapter describes the signal processing and fast Fourier transform functions available in Octave. Fast Fourier transforms are computed with the @sc{fftw} or @sc{fftpack} libraries depending on how Octave is built. - - - -@DOCSTRING(detrend) @DOCSTRING(fft) +@DOCSTRING(ifft) + +@DOCSTRING(fft2) + +@DOCSTRING(ifft2) + +@DOCSTRING(fftn) + +@DOCSTRING(ifftn) + Octave uses the @sc{fftw} libraries to perform FFT computations. When Octave starts up and initializes the @sc{fftw} libraries, they read a system wide file (on a Unix system, it is typically @file{/etc/fftw/wisdom}) that @@ -45,16 +50,6 @@ @DOCSTRING(fftw) -@DOCSTRING(ifft) - -@DOCSTRING(fft2) - -@DOCSTRING(ifft2) - -@DOCSTRING(fftn) - -@DOCSTRING(ifftn) - @DOCSTRING(fftconv) @DOCSTRING(fftfilt) @@ -71,7 +66,7 @@ @DOCSTRING(unwrap) -@c FIXME -- someone needs to organize these... +@c FIXME: someone needs to organize these ... @DOCSTRING(arch_fit) @@ -87,6 +82,8 @@ @DOCSTRING(blackman) +@DOCSTRING(detrend) + @DOCSTRING(diffpara) @DOCSTRING(durbinlevinson) @@ -107,10 +104,6 @@ @DOCSTRING(periodogram) -@DOCSTRING(rectangle_lw) - -@DOCSTRING(rectangle_sw) - @DOCSTRING(sinetone) @DOCSTRING(sinewave) @@ -125,8 +118,5 @@ @DOCSTRING(synthesis) -@DOCSTRING(triangle_lw) +@DOCSTRING(yulewalker) -@DOCSTRING(triangle_sw) - -@DOCSTRING(yulewalker) diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/sparse.txi --- a/doc/interpreter/sparse.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/sparse.txi Sat Oct 05 11:22:09 2013 -0400 @@ -23,7 +23,7 @@ @set htmltex @end iftex -@node Sparse Matrices +@node Sparse Matrices @chapter Sparse Matrices @menu @@ -34,7 +34,7 @@ @end menu @node Basics -@section The Creation and Manipulation of Sparse Matrices +@section Creation and Manipulation of Sparse Matrices The size of mathematical problems that can be treated at any particular time is generally limited by the available computing resources. Both, @@ -307,12 +307,11 @@ The above problem of memory reallocation can be avoided in oct-files. However, the construction of a sparse matrix from an oct-file -is more complex than can be discussed here, and -you are referred to chapter @ref{External Code Interface}, to have -a full description of the techniques involved. +is more complex than can be discussed here. @xref{External Code Interface}, +for a full description of the techniques involved. @node Information -@subsection Finding out Information about Sparse Matrices +@subsection Finding Information about Sparse Matrices There are a number of functions that allow information concerning sparse matrices to be obtained. The most basic of these is @@ -342,7 +341,7 @@ When solving linear equations involving sparse matrices Octave determines the means to solve the equation based on the type of the -matrix as discussed in @ref{Sparse Linear Algebra}. Octave probes the +matrix (@pxref{Sparse Linear Algebra}). Octave probes the matrix type when the div (/) or ldiv (\) operator is first used with the matrix and then caches the type. However the @dfn{matrix_type} function can be used to determine the type of the sparse matrix prior @@ -443,9 +442,9 @@ @subsection Basic Operators and Functions on Sparse Matrices @menu -* Sparse Functions:: -* Return Types of Operators and Functions:: -* Mathematical Considerations:: +* Sparse Functions:: +* Return Types of Operators and Functions:: +* Mathematical Considerations:: @end menu @node Sparse Functions @@ -505,7 +504,7 @@ details. @node Return Types of Operators and Functions -@subsubsection The Return Types of Operators and Functions +@subsubsection Return Types of Operators and Functions The two basic reasons to use sparse matrices are to reduce the memory usage and to not have to do calculations on zero elements. The two are @@ -574,8 +573,8 @@ same manner as there full counterparts. However, there are certain differences and especially differences with other products sparse implementations. -Firstly, the "./" and ".^" operators must be used with care. Consider what -the examples +Firstly, the @qcode{"./"} and @qcode{".^"} operators must be used with care. +Consider what the examples @example @group @@ -856,7 +855,7 @@ @DOCSTRING(svds) @node Iterative Techniques -@section Iterative Techniques applied to sparse matrices +@section Iterative Techniques Applied to Sparse Matrices The left division @code{\} and right division @code{/} operators, discussed in the previous section, use direct solvers to resolve a @@ -877,7 +876,7 @@ @DOCSTRING(luinc) @node Real Life Example -@section Real Life Example of the use of Sparse Matrices +@section Real Life Example using Sparse Matrices A common application for sparse matrices is in the solution of Finite Element Models. Finite element models allow numerical solution of diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/sparseimages.m --- a/doc/interpreter/sparseimages.m Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/sparseimages.m Sat Oct 05 11:22:09 2013 -0400 @@ -26,7 +26,7 @@ if (__have_feature__ ("COLAMD") && __have_feature__ ("CHOLMOD") && __have_feature__ ("UMFPACK")) - if (strcmp(typ,"txt")) + if (strcmp (typ,"txt")) txtimages (nm, 15, typ); else if (strcmp (nm, "gplot")) @@ -62,20 +62,20 @@ if (strcmp (typ, "eps")) d_typ = "-depsc2"; else - d_typ = cstrcat ("-d", typ); + d_typ = ["-d" typ]; endif A = sparse ([2,6,1,3,2,4,3,5,4,6,1,5], [1,1,2,2,3,3,4,4,5,5,6,6], 1, 6, 6); xy = [0,4,8,6,4,2;5,0,5,7,5,7]'; - gplot (A, xy) - print (cstrcat (nm, ".", typ), d_typ) + gplot (A, xy); + print ([nm "." typ], d_typ); hide_output (); endfunction -function txtimages(nm, n, typ) - a = 10*speye(n) + sparse(1:n,ceil([1:n]/2),1,n,n) + ... - sparse(ceil([1:n]/2),1:n,1,n,n); +function txtimages (nm, n, typ) + a = 10*speye (n) + sparse (1:n,ceil([1:n]/2),1,n,n) + ... + sparse (ceil ([1:n]/2),1:n,1,n,n); if (strcmp (nm, "gplot") || strcmp (nm, "grid")) fid = fopen (sprintf ("%s.txt", nm), "wt"); fputs (fid, "\n"); @@ -84,51 +84,49 @@ fputs (fid, "+---------------------------------+\n"); fclose (fid); elseif (strcmp (nm, "spmatrix")) - printsparse(a,cstrcat("spmatrix.",typ)); + printsparse (a, ["spmatrix." typ]); else - if (__have_feature__ ("COLAMD") - && __have_feature__ ("CHOLMOD")) + if (__have_feature__ ("COLAMD") && __have_feature__ ("CHOLMOD")) if (strcmp (nm, "spchol")) - r1 = chol(a); - printsparse(r1,cstrcat("spchol.",typ)); + r1 = chol (a); + printsparse (r1, ["spchol." typ]); elseif (strcmp (nm, "spcholperm")) - [r2,p2,q2]=chol(a); - printsparse(r2,cstrcat("spcholperm.",typ)); + [r2,p2,q2] = chol (a); + printsparse(r2, ["spcholperm." typ]); endif ## printf("Text NNZ: Matrix %d, Chol %d, PermChol %d\n",nnz(a),nnz(r1),nnz(r2)); endif endif endfunction -function otherimages(nm, n, typ) +function otherimages (nm, n, typ) hide_output (); if (strcmp (typ, "eps")) d_typ = "-depsc2"; else - d_typ = cstrcat ("-d", typ); + d_typ = ["-d" typ]; endif - a = 10*speye(n) + sparse(1:n,ceil([1:n]/2),1,n,n) + ... - sparse(ceil([1:n]/2),1:n,1,n,n); + a = 10*speye (n) + sparse (1:n,ceil([1:n]/2),1,n,n) + ... + sparse (ceil ([1:n]/2),1:n,1,n,n); if (strcmp (nm, "spmatrix")) - spy(a); - axis("ij") - print(cstrcat("spmatrix.",typ), d_typ) + spy (a); + axis ("ij"); + print (["spmatrix." typ], d_typ); hide_output (); else - if (__have_feature__ ("COLAMD") - && __have_feature__ ("CHOLMOD")) + if (__have_feature__ ("COLAMD") && __have_feature__ ("CHOLMOD")) if (strcmp (nm, "spchol")) - r1 = chol(a); - spy(r1); - axis("ij") - print(cstrcat("spchol.",typ), d_typ) + r1 = chol (a); + spy (r1); + axis ("ij"); + print (["spchol." typ], d_typ); hide_output (); elseif (strcmp (nm, "spcholperm")) - [r2,p2,q2]=chol(a); - spy(r2); - axis("ij") - print(cstrcat("spcholperm.",typ), d_typ) + [r2,p2,q2] = chol (a); + spy (r2); + axis ("ij"); + print (["spcholperm." typ], d_typ); hide_output (); endif ## printf("Image NNZ: Matrix %d, Chol %d, PermChol %d\n",nnz(a),nnz(r1),nnz(r2)); @@ -136,42 +134,42 @@ endif endfunction -function printsparse(a, nm) +function printsparse (a, nm) fid = fopen (nm,"wt"); fputs (fid, "\n"); - for i = 1:size(a,1) - if (rem(i,5) == 0) + for i = 1:rows (a) + if (rem (i,5) == 0) fprintf (fid," %2d - ", i); else fprintf (fid," | "); endif - for j = 1:size(a,2) + for j = 1:columns (a) if (a(i,j) == 0) - fprintf(fid," ") + fprintf (fid," "); else - fprintf(fid," *") + fprintf (fid," *"); endif endfor - fprintf(fid,"\n") + fprintf (fid,"\n"); endfor - fprintf(fid," |-"); - for j=1:size(a,2) - if (rem(j,5)==0) - fprintf(fid,"-|"); + fprintf (fid," |-"); + for j = 1:columns (a) + if (rem (j,5) == 0) + fprintf (fid,"-|"); else - fprintf(fid,"--"); + fprintf (fid,"--"); endif endfor - fprintf(fid,"\n") - fprintf(fid," "); - for j=1:size(a,2) - if (rem(j,5)==0) - fprintf(fid,"%2d",j); + fprintf (fid,"\n"); + fprintf (fid," "); + for j = 1:columns (a) + if (rem (j,5) == 0) + fprintf (fid,"%2d",j); else - fprintf(fid," "); + fprintf (fid," "); endif endfor - fclose(fid); + fclose (fid); endfunction function femimages (nm, typ) @@ -179,36 +177,36 @@ if (strcmp (typ, "eps")) d_typ = "-depsc2"; else - d_typ = cstrcat ("-d", typ); + d_typ = ["-d" typ]; endif if (__have_feature__ ("COLAMD") && __have_feature__ ("CHOLMOD") && __have_feature__ ("UMFPACK")) ## build a rectangle - node_y = [1;1.2;1.5;1.8;2]*ones(1,11); - node_x = ones(5,1)*[1,1.05,1.1,1.2,1.3,1.5,1.7,1.8,1.9,1.95,2]; + node_y = [1;1.2;1.5;1.8;2] * ones (1,11); + node_x = ones (5,1) * [1,1.05,1.1,1.2,1.3,1.5,1.7,1.8,1.9,1.95,2]; nodes = [node_x(:), node_y(:)]; - [h,w] = size(node_x); + [h,w] = size (node_x); elems = []; - for idx = 1:w-1 + for idx = 1 : w-1 widx = (idx-1)*h; elems = [elems; widx+[(1:h-1);(2:h);h+(1:h-1)]']; elems = [elems; widx+[(2:h);h+(2:h);h+(1:h-1)]']; endfor - E = size(elems,1); #No. of elements - N = size(nodes,1); #No. of elements - D = size(elems,2); #dimensions+1 + E = size (elems,1); # No. of elements + N = size (nodes,1); # No. of elements + D = size (elems,2); # dimensions+1 ## Plot FEM Geometry elemx = elems(:,[1,2,3,1])'; - xelems = reshape( nodes(elemx, 1), 4, E); - yelems = reshape( nodes(elemx, 2), 4, E); + xelems = reshape (nodes(elemx, 1), 4, E); + yelems = reshape (nodes(elemx, 2), 4, E); ## Set element conductivity - conductivity = [1*ones(1,16),2*ones(1,48),1*ones(1,16)]; + conductivity = [1*ones(1,16), 2*ones(1,48), 1*ones(1,16)]; ## Dirichlet boundary conditions D_nodes = [1:5, 51:55]; @@ -221,43 +219,41 @@ N_value = []; ## Calculate connectivity matrix - C = sparse((1:D*E), reshape(elems',D*E,1),1, D*E, N); + C = sparse ((1:D*E), reshape (elems',D*E,1),1, D*E, N); ## Calculate stiffness matrix - Siidx = floor([0:D*E-1]'/D)*D*ones(1,D) + ones(D*E,1)*(1:D) ; - Sjidx = [1:D*E]'*ones(1,D); - Sdata = zeros(D*E,D); - dfact = prod(2:(D-1)); + Siidx = floor ([0:D*E-1]'/D)*D*ones(1,D) + ones(D*E,1)*(1:D); + Sjidx = [1:D*E]'*ones (1,D); + Sdata = zeros (D*E,D); + dfact = prod (2:(D-1)); for j = 1:E - a = inv([ ones(D,1), nodes( elems(j,:), : ) ]); - const = conductivity(j)*2/dfact/abs(det(a)); - Sdata(D*(j-1)+(1:D),:)= const * a(2:D,:)'*a(2:D,:); + a = inv ([ ones(D,1), nodes( elems(j,:), : ) ]); + const = conductivity(j)*2/dfact/abs (det (a)); + Sdata(D*(j-1)+(1:D),:) = const * a(2:D,:)'*a(2:D,:); endfor ## Element-wise system matrix - SE = sparse(Siidx,Sjidx,Sdata); + SE = sparse (Siidx,Sjidx,Sdata); ## Global system matrix S = C'* SE *C; ## Set Dirichlet boundary - V = zeros(N,1); + V = zeros (N,1); V(D_nodes) = D_value; idx = 1:N; idx(D_nodes) = []; ## Set Neumann boundary - Q = zeros(N,1); + Q = zeros (N,1); Q(N_nodes) = N_value; # FIXME - V(idx) = S(idx,idx)\( Q(idx) - S(idx,D_nodes)*V(D_nodes) ); + V(idx) = S(idx,idx) \ ( Q(idx) - S(idx,D_nodes)*V(D_nodes) ); - velems = reshape( V(elemx), 4, E); - - sz = size(xelems,2); + velems = reshape (V(elemx), 4, E); plot3 (xelems, yelems, velems); view (10, 10); - print(cstrcat(nm,".",typ), d_typ) + print ([nm "." typ], d_typ); hide_output (); endif endfunction @@ -281,25 +277,22 @@ if (strcmp (typ, "eps")) d_typ = "-depsc2"; else - d_typ = cstrcat ("-d", typ); + d_typ = ["-d" typ]; endif - x = y = linspace (-8, 8, 41)'; - [xx, yy] = meshgrid (x, y); - r = sqrt (xx .^ 2 + yy .^ 2) + eps; - z = sin (r) ./ r; + [x, y, z] = sombrero (); unwind_protect mesh (x, y, z); title ("Sorry, graphics are unavailable because Octave was\ncompiled without a sparse matrix implementation."); unwind_protect_cleanup - print (cstrcat (nm, ".", typ), d_typ); + print ([nm "." typ], d_typ); hide_output (); end_unwind_protect endif endfunction ## generate something for the texinfo @image command to process -function image_as_txt(nm) +function image_as_txt (nm) fid = fopen (sprintf ("%s.txt", nm), "wt"); fputs (fid, "\n"); fputs (fid, "+---------------------------------+\n"); @@ -307,3 +300,4 @@ fputs (fid, "+---------------------------------+\n"); fclose (fid); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/splineimages.m --- a/doc/interpreter/splineimages.m Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/splineimages.m Sat Oct 05 11:22:09 2013 -0400 @@ -26,7 +26,7 @@ if (strcmp (typ, "eps")) d_typ = "-depsc2"; else - d_typ = cstrcat ("-d", typ); + d_typ = ["-d" typ]; endif if (strcmp (typ, "txt")) @@ -43,11 +43,11 @@ xx = linspace (0, 2 * pi, 400); y1 = ppval (pp1, xx); y2 = ppval (pp2, xx); - plot (x, y, ".", xx, [y1; y2]) - axis tight - ylim ([-2.5 2.5]) - legend ("data", "41 breaks, 40 pieces", "11 breaks, 10 pieces") - print (cstrcat (nm, ".", typ), d_typ) + plot (x, y, ".", xx, [y1; y2]); + axis tight; + ylim ([-2.5 2.5]); + legend ("data", "41 breaks, 40 pieces", "11 breaks, 10 pieces"); + print ([nm "." typ], d_typ); elseif (strcmp (nm, "splinefit2")) ## Spline orders ## Data (200 points) x = 2 * pi * rand (1, 200); @@ -65,11 +65,11 @@ y3 = ppval (pp3, xx); y4 = ppval (pp4, xx); y5 = ppval (pp5, xx); - plot (x, y, ".", xx, [y1; y2; y3; y4; y5]) - axis tight - ylim ([-2.5 2.5]) - legend ({"data", "order 0", "order 1", "order 2", "order 3", "order 4"}) - print (cstrcat (nm, ".", typ), d_typ) + plot (x, y, ".", xx, [y1; y2; y3; y4; y5]); + axis tight; + ylim ([-2.5 2.5]); + legend ({"data", "order 0", "order 1", "order 2", "order 3", "order 4"}); + print ([nm, "." typ], d_typ); elseif (strcmp (nm, "splinefit3")) ## Data (100 points) x = 2 * pi * [0, (rand (1, 98)), 1]; @@ -82,11 +82,11 @@ xx = linspace (0, 2 * pi, 400); y1 = ppval (pp1, xx); y2 = ppval (pp2, xx); - plot (x, y, ".", xx, [y1; y2]) - axis tight - ylim ([-2 3]) - legend ({"data", "no constraints", "periodic"}) - print (cstrcat (nm, ".", typ), d_typ) + plot (x, y, ".", xx, [y1; y2]); + axis tight; + ylim ([-2 3]); + legend ({"data", "no constraints", "periodic"}); + print ([nm "." typ], d_typ); elseif (strcmp (nm, "splinefit4")) ## Data (200 points) x = 2 * pi * rand (1, 200); @@ -105,11 +105,11 @@ xx = linspace (0, 2 * pi, 400); y1 = ppval (pp1, xx); y2 = ppval (pp2, xx); - plot (x, y, ".", xx, [y1; y2]) - axis tight - ylim ([-1.5 1.5]) - legend({"data", "clamped", "hinged periodic"}) - print (cstrcat (nm, ".", typ), d_typ) + plot (x, y, ".", xx, [y1; y2]); + axis tight; + ylim ([-1.5 1.5]); + legend({"data", "clamped", "hinged periodic"}); + print ([nm "." typ], d_typ); elseif (strcmp (nm, "splinefit5")) ## Truncated data x = [0, 1, 2, 4, 8, 16, 24, 40, 56, 72, 80] / 80; @@ -125,12 +125,12 @@ ## Plot ss = linspace (0, s(end), 400); xyfit = ppval (pp, ss); - xyb = ppval(pp, pp.breaks); - plot (x, y, ".", xyfit(1,:), xyfit(2,:), "r", xyb(1,:), xyb(2,:), "ro") - legend ({"data", "spline", "breaks"}) - axis tight - ylim ([0 0.1]) - print (cstrcat (nm, ".", typ), d_typ) + xyb = ppval (pp, pp.breaks); + plot (x, y, ".", xyfit(1,:), xyfit(2,:), "r", xyb(1,:), xyb(2,:), "ro"); + legend ({"data", "spline", "breaks"}); + axis tight; + ylim ([0 0.1]); + print ([nm "." typ], d_typ); elseif (strcmp (nm, "splinefit6")) ## Data x = linspace (0, 2*pi, 200); @@ -148,12 +148,12 @@ y1 = ppval (pp1, xx); y2 = ppval (pp2, xx); y3 = ppval (pp3, xx); - plot (x, y, ".", xx, [y1; y2; y3]) - legend({"data with outliers","robust, beta = 0.25", ... - "robust, beta = 0.75", "no robust fitting"}) - axis tight - ylim ([-2 2]) - print (cstrcat (nm, ".", typ), d_typ) + plot (x, y, ".", xx, [y1; y2; y3]); + legend ({"data with outliers","robust, beta = 0.25", ... + "robust, beta = 0.75", "no robust fitting"}); + axis tight; + ylim ([-2 2]); + print ([nm "." typ], d_typ); endif hide_output (); endfunction @@ -185,6 +185,7 @@ fclose (fid); endfunction + %!demo %! for s = 1:6 %! splineimages (sprintf ("splinefit##d", s), "pdf") diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/stats.txi --- a/doc/interpreter/stats.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/stats.txi Sat Oct 05 11:22:09 2013 -0400 @@ -42,17 +42,17 @@ It should be noted that the statistics functions don't test for data containing NaN, NA, or Inf. These values need to be detected and dealt -with explicitly. See @ref{docXisnan,,isnan}, @ref{docXisna,,isna}, -@ref{docXisinf,,isinf}, @ref{docXisfinite,,isfinite}. +with explicitly. See @ref{XREFisnan,,isnan}, @ref{XREFisna,,isna}, +@ref{XREFisinf,,isinf}, @ref{XREFisfinite,,isfinite}. @menu * Descriptive Statistics:: -* Basic Statistical Functions:: -* Statistical Plots:: -* Correlation and Regression Analysis:: -* Distributions:: -* Tests:: -* Random Number Generation:: +* Basic Statistical Functions:: +* Statistical Plots:: +* Correlation and Regression Analysis:: +* Distributions:: +* Tests:: +* Random Number Generation:: @end menu @node Descriptive Statistics diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/stmt.txi --- a/doc/interpreter/stmt.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/stmt.txi Sat Oct 05 11:22:09 2013 -0400 @@ -46,16 +46,16 @@ @dfn{body} of a control statement. @menu -* The if Statement:: -* The switch Statement:: -* The while Statement:: -* The do-until Statement:: -* The for Statement:: -* The break Statement:: -* The continue Statement:: -* The unwind_protect Statement:: -* The try Statement:: -* Continuation Lines:: +* The if Statement:: +* The switch Statement:: +* The while Statement:: +* The do-until Statement:: +* The for Statement:: +* The break Statement:: +* The continue Statement:: +* The unwind_protect Statement:: +* The try Statement:: +* Continuation Lines:: @end menu @node The if Statement @@ -259,7 +259,7 @@ @example @group -switch @var{expression} +switch (@var{expression}) case @var{label} @var{command_list} case @var{label} @@ -288,7 +288,7 @@ @example @group A = 7; -switch A +switch (A) case @{ 6, 7 @} printf ("variable is either 6 or 7\n"); otherwise @@ -328,7 +328,7 @@ @end example @menu -* Notes for the C Programmer:: +* Notes for the C Programmer:: @end menu @node Notes for the C Programmer @@ -601,7 +601,7 @@ something to do inside the loop. @menu -* Looping Over Structure Elements:: +* Looping Over Structure Elements:: @end menu @node Looping Over Structure Elements @@ -850,50 +850,55 @@ @var{catch} statements are evaluated. @xref{Errors and Warnings}, for more information about the @code{lasterr} function. +@node Continuation Lines +@section Continuation Lines @cindex continuation lines @cindex @code{...} continuation marker @cindex @code{\} continuation marker -@node Continuation Lines -@section Continuation Lines - In the Octave language, most statements end with a newline character and you must tell Octave to ignore the newline character in order to continue a statement from one line to the next. Lines that end with the -characters @code{...} or @code{\} are joined with the following line -before they are divided into tokens by Octave's parser. For example, -the lines +characters @code{...} are joined with the following line before they are +divided into tokens by Octave's parser. For example, the lines @example @group x = long_variable_name ... - + longer_variable_name \ + + longer_variable_name ... - 42 @end group @end example @noindent -form a single statement. The backslash character on the second line -above is interpreted as a continuation character, @emph{not} as a division -operator. +form a single statement. -For continuation lines that do not occur inside string constants, -whitespace and comments may appear between the continuation marker and -the newline character. For example, the statement +Any text between the continuation marker and the newline character is +ignored. For example, the statement @example @group -x = long_variable_name ... # comment one - + longer_variable_name \ # comment two - - 42 # last comment +x = long_variable_name ... # comment one + + longer_variable_name ...comment two + - 42 # last comment @end group @end example @noindent -is equivalent to the one shown above. Inside string constants, the -continuation marker must appear at the end of the line just before the -newline character. +is equivalent to the one shown above. + +Inside double-quoted string constants, the character @code{\} has to be +used as continuation marker. The @code{\} must appear at the end of the +line just before the newline character: +@example +@group +s = "This text starts in the first line \ +and is continued in the second line." +@end group +@end example + +@noindent Input that occurs inside parentheses can be continued to the next line without having to use a continuation marker. For example, it is possible to write statements like diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/strings.txi --- a/doc/interpreter/strings.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/strings.txi Sat Oct 05 11:22:09 2013 -0400 @@ -56,11 +56,11 @@ @menu * Escape Sequences in String Constants:: * Character Arrays:: -* Creating Strings:: -* Comparing Strings:: -* Manipulating Strings:: -* String Conversions:: -* Character Class Functions:: +* Creating Strings:: +* Comparing Strings:: +* Manipulating Strings:: +* String Conversions:: +* Character Class Functions:: @end menu @node Escape Sequences in String Constants @@ -119,21 +119,17 @@ @item \v Represents a vertical tab, control-k, ASCII code 11. -@c We don't do octal or hex this way yet. -@c -@c @item \@var{nnn} -@c Represents the octal value @var{nnn}, where @var{nnn} are one to three -@c digits between 0 and 7. For example, the code for the ASCII ESC -@c (escape) character is @samp{\033}.@refill -@c -@c @item \x@var{hh}@dots{} -@c Represents the hexadecimal value @var{hh}, where @var{hh} are hexadecimal -@c digits (@samp{0} through @samp{9} and either @samp{A} through @samp{F} or -@c @samp{a} through @samp{f}). Like the same construct in @sc{ansi} C, -@c the escape -@c sequence continues until the first non-hexadecimal digit is seen. However, -@c using more than two hexadecimal digits produces undefined results. (The -@c @samp{\x} escape sequence is not allowed in @sc{posix} @code{awk}.)@refill +@item \@var{nnn} +Represents the octal value @var{nnn}, where @var{nnn} are one to three +digits between 0 and 7. For example, the code for the ASCII ESC +(escape) character is @samp{\033}. + +@item \x@var{hh}@dots{} +Represents the hexadecimal value @var{hh}, where @var{hh} are hexadecimal +digits (@samp{0} through @samp{9} and either @samp{A} through @samp{F} or +@samp{a} through @samp{f}). Like the same construct in @sc{ansi} C, +the escape sequence continues until the first non-hexadecimal digit is seen. +However, using more than two hexadecimal digits produces undefined results. @end table In a single-quoted string there is only one escape sequence: you may insert a @@ -158,13 +154,13 @@ @section Character Arrays The string representation used by Octave is an array of characters, so -internally the string @nospell{"dddddddddd"} is actually a row vector of length -10 containing the value 100 in all places (100 is the ASCII code of "d"). This -lends itself to the obvious generalization to character matrices. Using a -matrix of characters, it is possible to represent a collection of same-length -strings in one variable. The convention used in Octave is that each row in a -character matrix is a separate string, but letting each column represent a -string is equally possible. +internally the string @nospell{@qcode{"dddddddddd"}} is actually a row vector +of length 10 containing the value 100 in all places (100 is the ASCII code of +@qcode{"d"}). This lends itself to the obvious generalization to character +matrices. Using a matrix of characters, it is possible to represent a +collection of same-length strings in one variable. The convention used in +Octave is that each row in a character matrix is a separate string, but letting +each column represent a string is equally possible. The easiest way to create a character matrix is to put several strings together into a matrix. @@ -222,19 +218,36 @@ @DOCSTRING(blanks) @menu -* Concatenating Strings:: -* Conversion of Numerical Data to Strings:: +* Concatenating Strings:: +* Converting Numerical Data to Strings:: @end menu @node Concatenating Strings @subsection Concatenating Strings -It has been shown above that strings can be concatenated using matrix notation -(@pxref{Strings}, @ref{Character Arrays}). Apart from that, there are several -functions to concatenate string objects: @code{char}, -@code{strvcat}, @code{strcat} and @code{cstrcat}. In addition, the general -purpose concatenation functions can be used: see @ref{docXcat,,cat}, -@ref{docXhorzcat,,horzcat} and @ref{docXvertcat,,vertcat}. +Strings can be concatenated using matrix notation +(@pxref{Strings}, @ref{Character Arrays}) which is often the most natural +method. For example: + +@example +@group +fullname = [fname ".txt"]; +email = ["<" user "@@" domain ">"]; +@end group +@end example + +@noindent +In each case it is easy to see what the final string will look like. This +method is also the most efficient. When using matrix concatenation the parser +immediately begins joining the strings without having to process +the overhead of a function call and the input validation of the associated +function. + +Nevertheless, there are several other functions for concatenating string +objects which can be useful in specific circumstances: @code{char}, +@code{strvcat}, @code{strcat}, and @code{cstrcat}. Finally, the general +purpose concatenation functions can be used: see @ref{XREFcat,,cat}, +@ref{XREFhorzcat,,horzcat}, and @ref{XREFvertcat,,vertcat}. @itemize @bullet @item All string concatenation functions except @code{cstrcat} @@ -275,8 +288,8 @@ char ("orange", "green", "", "red") @result{} orange green - - red + + red @end group @group @@ -318,7 +331,7 @@ @example @group strcat (["dir1";"directory2"], ["/";"/"], ["file1";"file2"]) - @result{} dir1/file1 + @result{} dir1/file1 directory2/file2 @end group @group @@ -342,8 +355,8 @@ @DOCSTRING(cstrcat) -@node Conversion of Numerical Data to Strings -@subsection Conversion of Numerical Data to Strings +@node Converting Numerical Data to Strings +@subsection Converting Numerical Data to Strings Apart from the string concatenation functions (@pxref{Concatenating Strings}) which cast numerical data to the corresponding ASCII characters, there are several functions that format numerical data as strings. @code{mat2str} and @@ -351,7 +364,7 @@ integer matrices. @code{int2str} takes the real part of complex values and round fractional values to integer. A more flexible way to format numerical data as strings is the @code{sprintf} function (@pxref{Formatted Output}, -@ref{docXsprintf}). +@ref{XREFsprintf,,sprintf}). @DOCSTRING(mat2str) diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/system.txi --- a/doc/interpreter/system.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/system.txi Sat Oct 05 11:22:09 2013 -0400 @@ -26,17 +26,17 @@ and even start other programs from the Octave prompt. @menu -* Timing Utilities:: -* Filesystem Utilities:: +* Timing Utilities:: +* Filesystem Utilities:: * File Archiving Utilities:: * Networking Utilities:: -* Controlling Subprocesses:: -* Process ID Information:: -* Environment Variables:: -* Current Working Directory:: -* Password Database Functions:: -* Group Database Functions:: -* System Information:: +* Controlling Subprocesses:: +* Process ID Information:: +* Environment Variables:: +* Current Working Directory:: +* Password Database Functions:: +* Group Database Functions:: +* System Information:: * Hashing Functions:: @end menu @@ -121,7 +121,7 @@ @DOCSTRING(is_leap_year) -@anchor{docXtoc} +@anchor{XREFtoc} @DOCSTRING(tic) @DOCSTRING(pause) @@ -177,7 +177,7 @@ @DOCSTRING(umask) -@anchor{docXlstat} +@anchor{XREFlstat} @DOCSTRING(stat) @DOCSTRING(S_ISBLK) @@ -491,7 +491,7 @@ @DOCSTRING(getgrent) @DOCSTRING(getgrgid) - + @DOCSTRING(getgrnam) @DOCSTRING(setgrent) diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/tips.txi --- a/doc/interpreter/tips.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/tips.txi Sat Oct 05 11:22:09 2013 -0400 @@ -352,7 +352,7 @@ Help text in Texinfo format. Code samples should be marked like @@code@{sample of code@} and variables should be marked as @@var@{variable@}. -@@seealso@{fn2@} +@@seealso@{fn2, fn3@} @@end deftypefn @end group @end example @@ -385,7 +385,13 @@ All samples of code should be marked with this macro for the same reasons as the @@var macro. -@item @@seealso@{function2@} +@item @nospell{@@qcode@{"sample_code"@}} +@itemx @nospell{@@qcode@{'sample_code'@}} +All samples of code which are quoted should use this more specialized macro. +This happens frequently when discussing graphics properties such as "position" +or options such as "on"/"off". + +@item @@seealso@{function2, function3@} This is a comma separated list of function names that allows cross referencing from one function documentation string to another. @end table @@ -467,8 +473,8 @@ The @code{@@group} block prevents the example from being split across a page boundary, while the @code{@@result@{@}} macro produces a right arrow signifying the result of a command. If your example is larger than -20 lines it is better NOT to use grouping so that a reasonable page boundary -can be calculated. +20 lines it is better @emph{NOT} to use grouping so that a reasonable page +boundary can be calculated. In many cases a function has multiple ways in which it can be called, and the @code{@@deftypefnx} macro can be used to give alternatives. For @@ -556,14 +562,15 @@ @@seealso@{bincoeff, perms@} @@end deftypefn @end example + @noindent which demonstrates most of the concepts discussed above. @iftex This documentation string renders as - @c Note: use the actual output of info below, rather than try and @c reproduce it here to prevent it looking different from how it would @c appear with info. + @example -- Function File: C = nchoosek (N, K) -- Function File: C = nchoosek (SET, K) diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/var.txi --- a/doc/interpreter/var.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/var.txi Sat Oct 05 11:22:09 2013 -0400 @@ -49,7 +49,7 @@ A variable name is a valid expression by itself. It represents the variable's current value. Variables are given new values with @dfn{assignment operators} and @dfn{increment operators}. -@xref{Assignment Ops, ,Assignment Expressions}. +@xref{Assignment Ops,,Assignment Expressions}. There is one built-in variable with a special meaning. The @code{ans} variable always contains the result of the last computation, where the output wasn't @@ -72,9 +72,9 @@ @DOCSTRING(namelengthmax) @menu -* Global Variables:: -* Persistent Variables:: -* Status of Variables:: +* Global Variables:: +* Persistent Variables:: +* Status of Variables:: @end menu @node Global Variables @@ -178,7 +178,7 @@ @cindex persistent variables @cindex @code{persistent} statement @cindex variables, persistent -@anchor{docXpersistent} +@anchor{XREFpersistent} A variable that has been declared @dfn{persistent} within a function will retain its contents in memory between subsequent calls to the @@ -299,8 +299,8 @@ variable will be cleared by a simple @code{clear} command as the entire function definition will be removed from memory. If you do not want a persistent variable to be removed from memory even if the function is -cleared, you should use the @code{mlock} function as described in -@xref{Function Locking}. +cleared, you should use the @code{mlock} function +(@pxref{Function Locking}). @node Status of Variables @section Status of Variables diff -r 20d1b911b4e7 -r c702371ff6df doc/interpreter/vectorize.txi --- a/doc/interpreter/vectorize.txi Thu Sep 12 21:08:07 2013 -0400 +++ b/doc/interpreter/vectorize.txi Sat Oct 05 11:22:09 2013 -0400 @@ -112,7 +112,7 @@ @example @group for i = 1:n - if a(i) > 5 + if (a(i) > 5) a(i) -= 20 endif endfor @@ -457,7 +457,7 @@ that may have relied on matrices of different size producing an error. Due to how broadcasting changes semantics with older versions of Octave, by default Octave warns if a broadcasting operation is performed. To -disable this warning, refer to its ID (@pxref{docXwarning_ids}): +disable this warning, refer to its ID (@pxref{XREFwarning_ids,,warning_ids}): @example warning ("off", "Octave:broadcast"); @@ -519,8 +519,8 @@ statements into another language, compiling the new code segment into an executable, and then running the executable and collecting any results. The process is not simple and there is a significant amount of work to perform for -each step. It can still make sense, however, if the loop counter is a -large number. Because Octave is an interpreted language every time through a +each step. It can still make sense, however, if the number of loop iterations +is large. Because Octave is an interpreted language every time through a loop Octave must parse the statements in the loop body before executing them. With a JIT compiler this is done just once when the body is translated to another language. @@ -528,12 +528,16 @@ The JIT compiler is a very new feature in Octave and not all valid Octave statements can currently be accelerated. However, if no other technique is available it may be worth benchmarking the code with JIT enabled. The -function @code{jit_enable} is used to turn compilation on or off. The function -@code{debug_jit} is not likely to be of use to anyone not working directly on -the implementation of the JIT compiler. +function @code{jit_enable} is used to turn compilation on or off. The +function @code{jit_startcnt} sets the threshold for acceleration. Loops +with iteration counts above @code{jit_startcnt} will be accelerated. The +function @code{debug_jit} is not likely to be of use to anyone not working +directly on the implementation of the JIT compiler. @DOCSTRING(jit_enable) +@DOCSTRING(jit_startcnt) + @DOCSTRING(debug_jit) @node Miscellaneous Techniques @@ -602,7 +606,7 @@ @group a = zeros (1000); # create a 1000x1000 matrix b = a(:,10:100); # lazy slice -a = []; # the original a array is still allocated +a = []; # the original "a" array is still allocated c@{1@} = b; # b is reallocated at this point @end group @end example @@ -670,7 +674,7 @@ @item Use @code{ignore_function_time_stamp} when appropriate. If you are calling lots of functions, and none of them will need to change during your run, set the variable @code{ignore_function_time_stamp} to -@code{"all"}. This will stop Octave from checking the time stamp of a function +@qcode{"all"}. This will stop Octave from checking the time stamp of a function file to see if it has been updated while the program is being run. @end itemize diff -r 20d1b911b4e7 -r c702371ff6df etc/HACKING --- a/etc/HACKING Thu Sep 12 21:08:07 2013 -0400 +++ b/etc/HACKING Sat Oct 05 11:22:09 2013 -0400 @@ -271,6 +271,8 @@ geometry geometry algorithms + gui User-Interface (UI) functions + help help subsystem functions image image processing @@ -318,15 +320,15 @@ test_ .m fixed tests for the interpreter - fntests.m script to run function tests embedded in C++ and .m - files + fntests.m script to run function tests embedded in C++ and + .m files ---- John W. Eaton jwe@octave.org +Last updated: Fri, 4 Oct 2013 16:58:52 PDT -Last updated: Wed, 15 May 2013 03:02:45 EDT ################################################################################ diff -r 20d1b911b4e7 -r c702371ff6df etc/OLD-ChangeLogs/scripts-ChangeLog --- a/etc/OLD-ChangeLogs/scripts-ChangeLog Thu Sep 12 21:08:07 2013 -0400 +++ b/etc/OLD-ChangeLogs/scripts-ChangeLog Sat Oct 05 11:22:09 2013 -0400 @@ -6297,7 +6297,7 @@ * plot/grid.m: Document handle argument. -2009-01-15 Peter L. S�ndergaard +2009-01-15 Peter L. Søndergaard * general/nargoutchk.m: Doc fix. * general/nargchk.m: Improve compatibility. New tests. @@ -6503,7 +6503,7 @@ systems. Simplify & fix indexing. Use left division for step problem. Fix output args. -2008-12-13 Francesco Potort� +2008-12-13 Francesco Potortì * specfun/nchoosek.m: Check for input arguments, signal loss of precision, correctly handle k==0 and k==n cases, add proper tests. @@ -6592,7 +6592,7 @@ 2008-11-10 John W. Eaton * polynomial/spline.m: Delete debugging statements. From - Sebastian Sch�ps . + Sebastian Schöps . 2008-11-07 Thorsten Meyer diff -r 20d1b911b4e7 -r c702371ff6df examples/@FIRfilter/subsref.m --- a/examples/@FIRfilter/subsref.m Thu Sep 12 21:08:07 2013 -0400 +++ b/examples/@FIRfilter/subsref.m Sat Oct 05 11:22:09 2013 -0400 @@ -1,5 +1,5 @@ function out = subsref (f, x) - switch x.type + switch (x.type) case "()" n = f.polynomial; out = filter (n.poly, 1, x.subs{1}); diff -r 20d1b911b4e7 -r c702371ff6df examples/mysparse.c --- a/examples/mysparse.c Thu Sep 12 21:08:07 2013 -0400 +++ b/examples/mysparse.c Sat Oct 05 11:22:09 2013 -0400 @@ -11,14 +11,14 @@ double *pr2, *pi2; mwIndex *ir, *jc; mwIndex *ir2, *jc2; - + if (nrhs != 1 || ! mxIsSparse (prhs[0])) mexErrMsgTxt ("ARG1 must be a sparse matrix"); m = mxGetM (prhs[0]); n = mxGetN (prhs[0]); nz = mxGetNzmax (prhs[0]); - + if (mxIsComplex (prhs[0])) { mexPrintf ("Matrix is %d-by-%d complex sparse matrix", m, n); @@ -40,7 +40,7 @@ pi2 = mxGetPi (v); ir2 = mxGetIr (v); jc2 = mxGetJc (v); - + for (i = 0; i < nz; i++) { pr2[i] = 2 * pr[i]; @@ -72,7 +72,7 @@ pbr2 = mxGetLogicals (v); ir2 = mxGetIr (v); jc2 = mxGetJc (v); - + for (i = 0; i < nz; i++) { pbr2[i] = pbr[i]; @@ -102,7 +102,7 @@ pr2 = mxGetPr (v); ir2 = mxGetIr (v); jc2 = mxGetJc (v); - + for (i = 0; i < nz; i++) { pr2[i] = 2 * pr[i]; diff -r 20d1b911b4e7 -r c702371ff6df libgui/Makefile.am --- a/libgui/Makefile.am Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/Makefile.am Sat Oct 05 11:22:09 2013 -0400 @@ -20,8 +20,6 @@ include $(top_srcdir)/build-aux/common.mk -AUTOMAKE_OPTIONS = subdir-objects - MOC_CPPFLAGS = octlib_LTLIBRARIES = liboctgui.la @@ -109,5 +107,6 @@ $(LRELEASE) -qm $@ $< DISTCLEANFILES = \ + default-qt-settings \ $(LOCALES) diff -r 20d1b911b4e7 -r c702371ff6df libgui/languages/be_BY.ts --- a/libgui/languages/be_BY.ts Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/languages/be_BY.ts Sat Oct 05 11:22:09 2013 -0400 @@ -41,6 +41,645 @@ persistent + + + foreground + + + + + background + + + + + selection + + + + + cursor + + + + + QTerminal + + + Copy + + + + + Paste + + + + + Clear All + + + + + QWinTerminalImpl + + + copied selection to clipboard + + + + + QsciLexerBatch + + + Default + + + + + Comment + + + + + Keyword + + + + + Label + + + + + Hide command character + + + + + External command + + + + + Variable + + + + + Operator + + + + + QsciLexerCPP + + + Default + + + + + Inactive default + + + + + C comment + + + + + Inactive C comment + + + + + C++ comment + + + + + Inactive C++ comment + + + + + JavaDoc style C comment + + + + + Inactive JavaDoc style C comment + + + + + Number + + + + + Inactive number + + + + + Keyword + + + + + Inactive keyword + + + + + Double-quoted string + + + + + Inactive double-quoted string + + + + + Single-quoted string + + + + + Inactive single-quoted string + + + + + IDL UUID + + + + + Inactive IDL UUID + + + + + Pre-processor block + + + + + Inactive pre-processor block + + + + + Operator + + + + + Inactive operator + + + + + Identifier + + + + + Inactive identifier + + + + + Unclosed string + + + + + Inactive unclosed string + + + + + C# verbatim string + + + + + Inactive C# verbatim string + + + + + JavaScript regular expression + + + + + Inactive JavaScript regular expression + + + + + JavaDoc style C++ comment + + + + + Inactive JavaDoc style C++ comment + + + + + Secondary keywords and identifiers + + + + + Inactive secondary keywords and identifiers + + + + + JavaDoc keyword + + + + + Inactive JavaDoc keyword + + + + + JavaDoc keyword error + + + + + Inactive JavaDoc keyword error + + + + + Global classes and typedefs + + + + + Inactive global classes and typedefs + + + + + C++ raw string + + + + + Inactive C++ raw string + + + + + QsciLexerDiff + + + Default + + + + + Comment + + + + + Command + + + + + Header + + + + + Position + + + + + Removed line + + + + + Added line + + + + + Changed line + + + + + QsciLexerMatlab + + + Default + + + + + Comment + + + + + Command + + + + + Number + + + + + Keyword + + + + + Single-quoted string + + + + + Operator + + + + + Identifier + + + + + Double-quoted string + + + + + QsciLexerPerl + + + Default + + + + + Error + + + + + Comment + + + + + POD + + + + + Number + + + + + Keyword + + + + + Double-quoted string + + + + + Single-quoted string + + + + + Operator + + + + + Identifier + + + + + Scalar + + + + + Array + + + + + Hash + + + + + Symbol table + + + + + Regular expression + + + + + Substitution + + + + + Backticks + + + + + Data section + + + + + Here document delimiter + + + + + Single-quoted here document + + + + + Double-quoted here document + + + + + Backtick here document + + + + + Quoted string (q) + + + + + Quoted string (qq) + + + + + Quoted string (qx) + + + + + Quoted string (qr) + + + + + Quoted string (qw) + + + + + POD verbatim + + + + + Subroutine prototype + + + + + Format identifier + + + + + Format body + + + + + Double-quoted string (interpolated variable) + + + + + Translation + + + + + Regular expression (interpolated variable) + + + + + Substitution (interpolated variable) + + + + + Backticks (interpolated variable) + + + + + Double-quoted here document (interpolated variable) + + + + + Backtick here document (interpolated variable) + + + + + Quoted string (qq, interpolated variable) + + + + + Quoted string (qx, interpolated variable) + + + + + Quoted string (qr, interpolated variable) + + + + + QsciScintilla + + + &Undo + &Ðдрабіць + + + + &Redo + &Паўтарыць + + + + Cu&t + Ð’Ñ‹&разаць + + + + &Copy + &КапіÑваць + + + + &Paste + + + + + Delete + + + + + Select All + + documentation_dock_widget @@ -58,19 +697,19 @@ file_editor - + Octave Editor - + Octave Files (*.m);;All Files (*) - + Could not open file %1 for read: %2. @@ -93,7 +732,7 @@ - + &New File &Ðовы файл @@ -108,12 +747,12 @@ &Захаваць файл - + Save File &As Захаваць файл &Ñк - + Print @@ -143,17 +782,17 @@ - + &Next Bookmark &ÐаÑÑ‚ÑƒÐ¿Ð½Ð°Ñ Ð·Ð°ÐºÐ»Ð°Ð´ÐºÐ° - + Pre&vious Bookmark Па&пÑÑ€ÑднÑÑ Ð·Ð°ÐºÐ»Ð°Ð´ÐºÐ° - + Toggle &Bookmark &ПаÑтавіць/прыбраць закладку @@ -193,27 +832,27 @@ - + &Recent Editor Files - + &Close + + Close All + + + - Close All - - - - Close Other Files - + &Find and Replace @@ -228,12 +867,12 @@ - + &File &Файл - + &Edit &ЗмÑніць @@ -278,14 +917,14 @@ - + Octave Editor - + The file %1 is about to be closed but has been modified. @@ -293,7 +932,7 @@ - + Octave Files (*.m);;All Files (*) @@ -319,13 +958,13 @@ - + Could not open file %1 for write: %2. - + It seems that '%1' has been modified by another application. Do you want to reload it? @@ -475,7 +1114,7 @@ - Are you sre you want to delete + Are you sure you want to delete @@ -485,12 +1124,12 @@ - + Set directory of file browser - + Create File @@ -585,7 +1224,7 @@ - + Search from end @@ -708,12 +1347,12 @@ - + Search results - + Idle. @@ -748,7 +1387,7 @@ - + Searching... @@ -761,7 +1400,7 @@ find_files_model - + Filename @@ -774,7 +1413,7 @@ history_dock_widget - + Browse and search the command history. ÐглÑд Ñ– пошук па гіÑторыі загадаў. @@ -812,23 +1451,23 @@ main_window - + Load Workspace Загрузіць праÑтору зменных - - + + About Octave Пра Octave - + &File &Файл - + New @@ -838,7 +1477,7 @@ - + Function @@ -848,12 +1487,12 @@ - + Open... - + Preferences... @@ -863,7 +1502,7 @@ ВыйÑці - + &Edit &ЗмÑніць @@ -878,28 +1517,33 @@ - + Paste - - + + Save Workspace As - + Set working directory - + + Clear Clipboard + + + + Find Files... - + Clear Command Window @@ -914,7 +1558,7 @@ - + De&bug @@ -959,7 +1603,27 @@ - + + Octave Packages + + + + + Share Code + + + + + Contribute to Octave + + + + + Octave Developer Resources + + + + On Disk @@ -989,12 +1653,12 @@ - + Load workspace - + &Window @@ -1045,12 +1709,12 @@ - + Documentation Ð”Ð°ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ñ‹Ñ - + &Help @@ -1059,39 +1723,25 @@ Report Bug Паведаміць пра хібу - - - Visit Agora - - - - - Visit Octave Forge - - octave_dock_widget + Undock widget - + Hide widget - + Dock widget - - - Unock widget - - octave_qscintilla @@ -1157,12 +1807,7 @@ - - Graphic icons - - - - + Editor РÑдактар @@ -1272,12 +1917,12 @@ - + Font - + Show line numbers @@ -1297,7 +1942,12 @@ - + + Graphic icons + + + + emacs emacs @@ -1317,7 +1967,7 @@ - + Font size @@ -1387,7 +2037,7 @@ HttpProxy - + Icon set for dock widgets @@ -1402,7 +2052,7 @@ - + Socks5Proxy Socks5Proxy @@ -1434,8 +2084,23 @@ - - Difference to the defalt size + + IBeam Cursor + + + + + Block Cursor + + + + + Underline Cursor + + + + + Difference to the default size @@ -1470,7 +2135,7 @@ webinfo - + Type here and press 'Return' to search @@ -1483,48 +2148,38 @@ welcome_wizard - + Welcome to GNU Octave - - It appears that you have launched Octave GUI for the first time on this computer, since no configuration file could be found at '~/.octave-gui'. This wizard will guide you through the essential settings you should make before you can start using Octave GUI. If you want to transfer your settings you have previously made just close this dialog and copy over the settings file to your home folder. The presence of that file will automatically be detected and will skip this wizard. IMPORTANT: This wizard is not fully functional yet. Just click your way to the end and it will create a standard settings file. + + You seem to be using the Octave graphical interface for the first time on this computer. Click 'Finish' to write a configuration file and launch Octave GUI. + + + + + The configuration file is stored in __%1__. If that file exists, you will not see this dialog when Octave starts again. - - - - - Next + + <html><head/><body><p>For more information about Octave,</p> +<ul> +<li>visit <a href="http://octave.org"><span style=" text-decoration: underline; color:#0000ff;">http://octave.org</span></a>,</li> +<li> get the documentation online as <a href="http://www.gnu.org/software/octave/doc/interpreter/index.html"><span style=" text-decoration: underline; color:#0000ff;">html</span></a>- or <a href="http://www.gnu.org/software/octave/octave.pdf"><span style=" text-decoration: underline; color:#0000ff;">pdf</span></a>-document, or</li> +<li>open the documentation browser of Octave GUI with the help menu.</li> +</ul> +</body></html> - - - - - Previous - - - - + Welcome to Octave! - - This is the development version of Octave with the first official GUI. - - - - - You seem to run Octave GUI for the first time on this computer. This assistant will help you to configure this software installation. Click 'Finish' to write a configuration file and launch Octave GUI. - - - - + Finish diff -r 20d1b911b4e7 -r c702371ff6df libgui/languages/de_DE.ts --- a/libgui/languages/de_DE.ts Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/languages/de_DE.ts Sat Oct 05 11:22:09 2013 -0400 @@ -83,7 +83,7 @@ QWinTerminalImpl - + copied selection to clipboard Auswahl in die Zwischenablage kopiert @@ -104,19 +104,19 @@ file_editor - + Octave Editor Octave Editor - + Octave Files (*.m);;All Files (*) Octave Dateien (*.m);;Alle Dateien (*) - + Could not open file %1 for read: %2. Kann die Datei <b>%1</b> nicht zum Lesen öffnen: @@ -142,7 +142,7 @@ &%1 %2 - + &New File &Neue Datei @@ -157,12 +157,12 @@ Datei &speichern - + Save File &As Datei speichern &als - + Print Drucken @@ -192,17 +192,17 @@ Einfügen - + &Next Bookmark &Nächstes Lesezeichen - + Pre&vious Bookmark &Voriges Lesezeichen - + Toggle &Bookmark &Lesezeichen setzen @@ -242,34 +242,34 @@ Kommentar &entfernen - + &Recent Editor Files &Zuletzt bearbeitete Dateien - + &Close S&chließen - + Close All Alle schließen - + Close Other Files Andere Dokumente schließen - + &Find and Replace &Suchen und Ersetzen Save File And Run - Datei speichern und ausrühren + Datei speichern und ausführen @@ -277,12 +277,12 @@ &Gehe zu Zeile - + &File &Datei - + &Edit &Editieren @@ -327,14 +327,14 @@ - + Octave Editor Octave Editor - + The file %1 is about to be closed but has been modified. @@ -345,7 +345,7 @@ %2 - + Octave Files (*.m);;All Files (*) Octave Dateien (*.m);;All Files (*) @@ -375,14 +375,14 @@ wurde gelöscht oder umbenannt. Soll die Datei jetzt gespeichert werden?%2 - + Could not open file %1 for write: %2. - Die Datei %1 konnte nicht zum Schrieben geöffnet werden: + Die Datei %1 konnte nicht zum Schreiben geöffnet werden: %2. - + It seems that '%1' has been modified by another application. Do you want to reload it? Die Datei %1 wurde von einer anderen Anwendung verändert. Soll der neue Inhalt geladen werden? @@ -437,7 +437,7 @@ Show Home directory - Wechlse zum Heimatverzeichnis + Wechsle zum Heimatverzeichnis @@ -544,12 +544,12 @@ Verzeichnis ist nicht leer und kann daher nicht gelöscht werden - + Set directory of file browser Setze aktuelles Browser Verzeichnis - + Create File Neue Datei @@ -644,7 +644,7 @@ In Auswah&l suchen - + Search from end Vom Ende suchen @@ -689,7 +689,7 @@ Enter the filename expression - EIngabe eines Ausdrucks für den Dateinamen + Eingabe eines Ausdrucks für den Dateinamen @@ -729,7 +729,7 @@ Include matching directories in search results - Auch Verzeichnisse berücksichitgen, die die Suchanfrage erfüllen + Auch Verzeichnisse berücksichtigen, die die Suchanfrage erfüllen @@ -739,7 +739,7 @@ Set matching name is case insensitive - Groß-/Kleinschriebung bei der Dateisuche ignorieren + Groß-/Kleinschreibung bei der Dateisuche ignorieren @@ -767,12 +767,12 @@ Groß-/Kleinschreibung beim Text beachten - + Search results Suchergebnisse - + Idle. Leerlauf. @@ -820,7 +820,7 @@ find_files_model - + Filename Dateiname @@ -833,7 +833,7 @@ history_dock_widget - + Browse and search the command history. Durchsuchen Sie die Befehlshistorie. @@ -871,23 +871,23 @@ main_window - + Load Workspace Lade Arbeitsumgebung - - + + About Octave Ãœber Octave - + &File &Datei - + New Neu @@ -897,7 +897,7 @@ Skript - + Function Funktion @@ -907,12 +907,12 @@ Abbildung - + Open... Öffnen... - + Preferences... Einstellungen... @@ -922,7 +922,7 @@ Beenden - + &Edit &Editieren @@ -937,28 +937,33 @@ Kopieren - + Paste Einfügen - - + + Save Workspace As Arbeitsumgebung speichern als - + Set working directory Arbeitsverzeichnis setzen - + + Clear Clipboard + Zwischenablage leeren + + + Find Files... Suche Dateien... - + Clear Command Window Befehlsfenster löschen @@ -973,14 +978,14 @@ Arbeitsumgebung löschen - + De&bug De&bug Step - EInzelschritt + Einzelschritt @@ -995,7 +1000,7 @@ Continue - Fortführen + Fortfahren @@ -1018,7 +1023,27 @@ Fensterlayout auf Grundeinstellung zurücksetzen - + + Octave Packages + Octave Pakete + + + + Share Code + Code teilen + + + + Contribute to Octave + Bei Octave mitwirken + + + + Octave Developer Resources + Ressourcen für Octave Entwickler + + + On Disk Auf der Festplatte @@ -1048,12 +1073,12 @@ Verzeichnis suchen - + Load workspace Arbeitsumgebung laden - + &Window &Fenster @@ -1104,12 +1129,12 @@ - + Documentation Dokumentation - + &Help &Hilfe @@ -1118,32 +1143,22 @@ Report Bug Fehler melden - - - Visit Agora - Agora Webseite - - - - Visit Octave Forge - Octave Forge Webseite - octave_dock_widget - + Undock widget Fenster lösen - + Hide widget Fenster verbergen - + Dock widget Fenster andocken @@ -1166,7 +1181,7 @@ The file %1 is shadowed by a file with the same name in the load path. To debug the function you are editing, change to the directory %2. - Die Datei %1 wird von einer gleichnamigen Datei im Suchpfad überdeckt. Um die editierte Funktion zu debuggen, in das Verzeichnis %2 gewechselt werden. + Die Datei %1 wird von einer gleichnamigen Datei im Suchpfad überdeckt. Um die editierte Funktion zu debuggen, muss in das Verzeichnis %2 gewechselt werden. @@ -1224,7 +1239,7 @@ Do not show white spaces used for indentation - Keine Leezeichen der Einrückung anzeigen + Keine Leerzeichen der Einrückung anzeigen @@ -1279,7 +1294,7 @@ Replace word by suggested one - Wort durch Vorschalg ersetzen + Wort durch Vorschlag ersetzen @@ -1409,7 +1424,7 @@ Alternating row colors - Alternierende Farben verwenden + Alternierende Farben für die Zeilen verwenden @@ -1506,7 +1521,7 @@ Difference to the default size - Differenz zur Stnadgröße + Differenz zur Standardgröße @@ -1540,9 +1555,9 @@ webinfo - + Type here and press 'Return' to search - Suchbegriff eingeben und mit 'Enter' die Scuhe starten + Suchbegriff eingeben und mit 'Enter' die Suche starten @@ -1553,52 +1568,44 @@ welcome_wizard - + Welcome to GNU Octave Willkommen zu GNU Octave - - It appears that you have launched Octave GUI for the first time on this computer, since no configuration file could be found at '~/.octave-gui'. This wizard will guide you through the essential settings you should make before you can start using Octave GUI. If you want to transfer your settings you have previously made just close this dialog and copy over the settings file to your home folder. The presence of that file will automatically be detected and will skip this wizard. IMPORTANT: This wizard is not fully functional yet. Just click your way to the end and it will create a standard settings file. - Es scheint, dass Sie Octave-GUI das erste Mal auf diesem Computer ausführen, da die Konfigurationsdatei -~/.config/octave/qt-settings -nicht gefunden wurde. Die Default-Konfiguration wird beim Fortfahren an diese Stelle kopiert. Wenn bestehende Einstellungen verwendet werden sollen, muss dieser Dialog geschlossen und die vorhandene Datei an die oben angegebene Stelle kopiert werden. Eine vorhandene Konfigurationsdatei wird beim nächsten Start automatisch erkannt. - -Nach dem Programmstart können die Einstellungen im Menü "Datei/Einstellungen" angepasst werden. + + You seem to be using the Octave graphical interface for the first time on this computer. Click 'Finish' to write a configuration file and launch Octave GUI. + Die grafische Nutzerschnittstelle von Octave wird offenbar das erste Mal gestartet. Ein Klick auf 'Beenden' erstellt eine Standard-Konfigurationsdatei und startet Octave GUI. + + + + The configuration file is stored in __%1__. If that file exists, you will not see this dialog when Octave starts again. + Die Konfigurationsdatei wid in __%1__ gespeichert. Wenn diese Datei existiert, erscheint dieser Dialog beim nächsten Start von Octave nicht mehr. - - - - - Next - Weiter + + <html><head/><body><p>For more information about Octave,</p> +<ul> +<li>visit <a href="http://octave.org"><span style=" text-decoration: underline; color:#0000ff;">http://octave.org</span></a>,</li> +<li> get the documentation online as <a href="http://www.gnu.org/software/octave/doc/interpreter/index.html"><span style=" text-decoration: underline; color:#0000ff;">html</span></a>- or <a href="http://www.gnu.org/software/octave/octave.pdf"><span style=" text-decoration: underline; color:#0000ff;">pdf</span></a>-document, or</li> +<li>open the documentation browser of Octave GUI with the help menu.</li> +</ul> +</body></html> + <html><head/><body><p>Weitere Informationsquellen zu Octave:</p> +<ul> +<li>Homepage <a href="http://octave.org"><span style=" text-decoration: underline; color:#0000ff;">http://octave.org</span></a>,</li> +<li> Online-Dokumentation als <a href="http://www.gnu.org/software/octave/doc/interpreter/index.html"><span style=" text-decoration: underline; color:#0000ff;">html</span></a>- oder <a href="http://www.gnu.org/software/octave/octave.pdf"><span style=" text-decoration: underline; color:#0000ff;">pdf</span></a>-Dokument</li> +<li>Dokumentations-Browser von Octave GUI im Hilfe-Menü</li> +</ul> +</body></html> - - - - - Previous - Zurück - - - + Welcome to Octave! Willkommen zu Octave! - - This is the development version of Octave with the first official GUI. - Dieses ist die Entwicklungsversion von Octave mit der ersten offiziellen GUI. - - - - You seem to run Octave GUI for the first time on this computer. This assistant will help you to configure this software installation. Click 'Finish' to write a configuration file and launch Octave GUI. - Die GUI von Octave wird offenbar das erste mal auf diesem Computer ausgeführt. Dieser Assistent erstellt beim Klick auf 'Beenden' eine Standarkonfiguration und startet Octve-GUI. - - - + Finish Beenden @@ -1633,7 +1640,7 @@ Right click to copy, rename, or display - Rechtsklick zum Kopeiren, Umbenennen oder Anzeigen + Rechtsklick zum Kopieren, Umbenennen oder Anzeigen @@ -1661,12 +1668,12 @@ Only top-level symbols may be renamed. - Nur Varaiblen auf höchster Ebene können umbenannt werden. + Nur Variablen auf höchster Ebene können umbenannt werden. View the variables in the active workspace.<br> - Einsehen der Varaiblen der aktiven Arbeitsumgebung.<br> + Einsehen der Variablen der aktiven Arbeitsumgebung.<br> diff -r 20d1b911b4e7 -r c702371ff6df libgui/languages/en_US.ts --- a/libgui/languages/en_US.ts Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/languages/en_US.ts Sat Oct 05 11:22:09 2013 -0400 @@ -41,6 +41,52 @@ persistent + + + foreground + + + + + background + + + + + selection + + + + + cursor + + + + + QTerminal + + + Copy + + + + + Paste + + + + + Clear All + + + + + QWinTerminalImpl + + + copied selection to clipboard + + documentation_dock_widget @@ -58,19 +104,19 @@ file_editor - + Octave Editor - + Octave Files (*.m);;All Files (*) - + Could not open file %1 for read: %2. @@ -93,7 +139,7 @@ - + &New File @@ -108,12 +154,12 @@ - + Save File &As - + Print @@ -143,17 +189,17 @@ - + &Next Bookmark - + Pre&vious Bookmark - + Toggle &Bookmark @@ -193,27 +239,27 @@ - + &Recent Editor Files - + &Close + + Close All + + + - Close All - - - - Close Other Files - + &Find and Replace @@ -228,12 +274,12 @@ - + &File - + &Edit @@ -278,14 +324,14 @@ - + Octave Editor - + The file %1 is about to be closed but has been modified. @@ -293,7 +339,7 @@ - + Octave Files (*.m);;All Files (*) @@ -319,13 +365,13 @@ - + Could not open file %1 for write: %2. - + It seems that '%1' has been modified by another application. Do you want to reload it? @@ -475,7 +521,7 @@ - Are you sre you want to delete + Are you sure you want to delete @@ -485,12 +531,12 @@ - + Set directory of file browser - + Create File @@ -585,7 +631,7 @@ - + Search from end @@ -708,12 +754,12 @@ - + Search results - + Idle. @@ -748,7 +794,7 @@ - + Searching... @@ -761,7 +807,7 @@ find_files_model - + Filename @@ -774,7 +820,7 @@ history_dock_widget - + Browse and search the command history. @@ -812,23 +858,23 @@ main_window - + Load Workspace - - + + About Octave - + &File - + New @@ -838,7 +884,7 @@ - + Function @@ -848,12 +894,12 @@ - + Open... - + Preferences... @@ -863,7 +909,7 @@ - + &Edit @@ -878,28 +924,33 @@ - + Paste - - + + Save Workspace As - + Set working directory - + + Clear Clipboard + + + + Find Files... - + Clear Command Window @@ -914,7 +965,7 @@ - + De&bug @@ -959,7 +1010,27 @@ - + + Octave Packages + + + + + Share Code + + + + + Contribute to Octave + + + + + Octave Developer Resources + + + + On Disk @@ -989,12 +1060,12 @@ - + Load workspace - + &Window @@ -1045,12 +1116,12 @@ - + Documentation - + &Help @@ -1059,39 +1130,25 @@ Report Bug - - - Visit Agora - - - - - Visit Octave Forge - - octave_dock_widget + Undock widget - + Hide widget - + Dock widget - - - Unock widget - - octave_qscintilla @@ -1157,12 +1214,7 @@ - - Graphic icons - - - - + Editor @@ -1272,12 +1324,12 @@ - + Font - + Show line numbers @@ -1297,7 +1349,12 @@ - + + Graphic icons + + + + emacs @@ -1317,7 +1374,7 @@ - + Font size @@ -1387,7 +1444,7 @@ - + Icon set for dock widgets @@ -1402,7 +1459,7 @@ - + Socks5Proxy @@ -1434,8 +1491,23 @@ - - Difference to the defalt size + + IBeam Cursor + + + + + Block Cursor + + + + + Underline Cursor + + + + + Difference to the default size @@ -1470,7 +1542,7 @@ webinfo - + Type here and press 'Return' to search @@ -1483,48 +1555,38 @@ welcome_wizard - + Welcome to GNU Octave - - It appears that you have launched Octave GUI for the first time on this computer, since no configuration file could be found at '~/.octave-gui'. This wizard will guide you through the essential settings you should make before you can start using Octave GUI. If you want to transfer your settings you have previously made just close this dialog and copy over the settings file to your home folder. The presence of that file will automatically be detected and will skip this wizard. IMPORTANT: This wizard is not fully functional yet. Just click your way to the end and it will create a standard settings file. + + You seem to be using the Octave graphical interface for the first time on this computer. Click 'Finish' to write a configuration file and launch Octave GUI. + + + + + The configuration file is stored in __%1__. If that file exists, you will not see this dialog when Octave starts again. - - - - - Next + + <html><head/><body><p>For more information about Octave,</p> +<ul> +<li>visit <a href="http://octave.org"><span style=" text-decoration: underline; color:#0000ff;">http://octave.org</span></a>,</li> +<li> get the documentation online as <a href="http://www.gnu.org/software/octave/doc/interpreter/index.html"><span style=" text-decoration: underline; color:#0000ff;">html</span></a>- or <a href="http://www.gnu.org/software/octave/octave.pdf"><span style=" text-decoration: underline; color:#0000ff;">pdf</span></a>-document, or</li> +<li>open the documentation browser of Octave GUI with the help menu.</li> +</ul> +</body></html> - - - - - Previous - - - - + Welcome to Octave! - - This is the development version of Octave with the first official GUI. - - - - - You seem to run Octave GUI for the first time on this computer. This assistant will help you to configure this software installation. Click 'Finish' to write a configuration file and launch Octave GUI. - - - - + Finish diff -r 20d1b911b4e7 -r c702371ff6df libgui/languages/es_ES.ts --- a/libgui/languages/es_ES.ts Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/languages/es_ES.ts Sat Oct 05 11:22:09 2013 -0400 @@ -41,6 +41,52 @@ persistent persistente + + + foreground + primer plano + + + + background + plano de fondo + + + + selection + selección + + + + cursor + cursor + + + + QTerminal + + + Copy + Copiar + + + + Paste + Pegar + + + + Clear All + Limpiar todo + + + + QWinTerminalImpl + + + copied selection to clipboard + selección copiada al portapapeles + documentation_dock_widget @@ -58,19 +104,19 @@ file_editor - + Octave Editor Editor de Octave - + Octave Files (*.m);;All Files (*) Archivos de Octave (*.m);;Todos los archivos (*) - + Could not open file %1 for read: %2. No se ha podido abrir el archivo %1 para su lectura:\n%2. @@ -93,7 +139,7 @@ &%1 %2 - + &New File Archivo &nuevo @@ -108,12 +154,12 @@ &Guardar archivo - + Save File &As Guardar archivo &como - + Print Imprimir @@ -143,17 +189,17 @@ Pegar - + &Next Bookmark &Marcador siguiente - + Pre&vious Bookmark Marcador &anterior - + Toggle &Bookmark &Alternar marcadores @@ -193,27 +239,27 @@ &Eliminar comentario - + &Recent Editor Files Archivos &recientes - + &Close C&errar - + Close All Cerrar todo - + Close Other Files Cerrar otros archivos - + &Find and Replace &Buscar y reemplazar @@ -228,12 +274,12 @@ &Ir a línea - + &File &Archivo - + &Edit &Editar @@ -278,14 +324,14 @@ - + Octave Editor Editor de Octave - + The file %1 is about to be closed but has been modified. @@ -293,7 +339,7 @@ El archivo\n%1\n está a punto de ser cerrado pero ha sido modificado.\n%2 - + Octave Files (*.m);;All Files (*) Archivos de Octave(*.m);;Todos los archivos(*) @@ -319,13 +365,13 @@ Al parecer el archivo\n%1\n ha sido eliminado o renombrado.¿Desea guardarlo ahora?%2 - + Could not open file %1 for write: %2. No se ha podido abrir el archivo %1 para escritura:\n%2. - + It seems that '%1' has been modified by another application. Do you want to reload it? Al parecer el archivo \'%1\' ha sido modificado por otra aplicación. ¿Desea recargarlo? @@ -485,12 +531,12 @@ No se puede eliminar un directorio que no esté vacio - + Set directory of file browser Fijar directorio de explorador de archivos - + Create File Crear archivo @@ -585,7 +631,7 @@ Buscar se&lección - + Search from end Buscar desde el final @@ -708,12 +754,12 @@ Establecer distinción entre mayúsculas y minúsculas en el texto - + Search results Resultados de la búsqueda - + Idle. Inactivo. @@ -748,7 +794,7 @@ Contenido del archivo - + Searching... Buscando... @@ -761,7 +807,7 @@ find_files_model - + Filename Nombre de archivo @@ -774,7 +820,7 @@ history_dock_widget - + Browse and search the command history. Explorar y buscar en el historial de comandos. @@ -813,23 +859,23 @@ main_window - + Load Workspace Cargar espacio de trabajo - - + + About Octave Acerca de Octave - + &File &Archivo - + New Nuevo @@ -840,7 +886,7 @@ Guión - + Function Función @@ -850,12 +896,12 @@ Figura - + Open... Abrir... - + Preferences... Preferencias... @@ -865,7 +911,7 @@ Salir - + &Edit &Editar @@ -880,28 +926,33 @@ Copiar - + Paste Pegar - - + + Save Workspace As Guardar espacio de trabajo como - + Set working directory Fijar directorio de trabajo - + + Clear Clipboard + Limpiar el Portapapeles + + + Find Files... Buscar archivos... - + Clear Command Window Limpiar ventana de comandos @@ -916,7 +967,7 @@ Limpiar espacio de trabajo - + De&bug &Depurar @@ -961,7 +1012,27 @@ Reestablecer esquema de ventana predeterminado - + + Octave Packages + Paquetes de Octave + + + + Share Code + Compartir código + + + + Contribute to Octave + Contribuir a octave + + + + Octave Developer Resources + Recursos para el desarrollador de Octave + + + On Disk En disco @@ -991,12 +1062,12 @@ Explorar directorios - + Load workspace Cargar espacio de trabajo - + &Window &Ventana @@ -1047,12 +1118,12 @@ - + Documentation Documentación - + &Help &Ayuda @@ -1061,33 +1132,24 @@ Report Bug Informar de fallo - - - Visit Agora - Visitar Agora - - - - Visit Octave Forge - Visitar Octave Forge - octave_dock_widget + Undock widget Uso "widget" por ser el término usual: http://es.wikipedia.org/wiki/Widget Desacoplar widget - + Hide widget Uso "widget" por ser el término usual: http://es.wikipedia.org/wiki/Widget Ocultar widget - + Dock widget Uso "widget" por ser el término usual: http://es.wikipedia.org/wiki/Widget Acoplar widget @@ -1274,12 +1336,12 @@ Colores de la terminal - + Font Tipo de fuente - + Show line numbers Mostrar numeros de línea @@ -1319,7 +1381,7 @@ Cursor parpadeante - + Font size Tamaño de fuente @@ -1389,7 +1451,7 @@ HttpProxy - + Icon set for dock widgets Ãconos para widget acoplados @@ -1404,7 +1466,7 @@ Tamaño de ícono - + Socks5Proxy "Socks5Proxy" @@ -1436,7 +1498,22 @@ Configuración del sistema - + + IBeam Cursor + cursor IBeam + + + + Block Cursor + cursor de bloque + + + + Underline Cursor + cursor subrayado + + + Difference to the default size Diferencia con el tamaño predeterminado @@ -1472,7 +1549,7 @@ webinfo - + Type here and press 'Return' to search Escriba aquí y pulse la tecla de 'Retorno' para buscar @@ -1485,53 +1562,44 @@ welcome_wizard - + Welcome to GNU Octave Bienvenido a GNU Octave - - It appears that you have launched Octave GUI for the first time on this computer, since no configuration file could be found at '~/.octave-gui'. This wizard will guide you through the essential settings you should make before you can start using Octave GUI. If you want to transfer your settings you have previously made just close this dialog and copy over the settings file to your home folder. The presence of that file will automatically be detected and will skip this wizard. IMPORTANT: This wizard is not fully functional yet. Just click your way to the end and it will create a standard settings file. - Al parecer ha iniciado Octave GUI por primera vez en su - computadora/ordenador, ya que no se ha encontrado un archivo - de configuración en '~/.octave-gui'. Este asistente lo guiará con los ajustes esenciales que - debe hacer antes de empezar a usar Octave GUI. Si desea transferir su configuración hecha con anterioridad - solamente cierre este diálogo y copie el archivo de configuración en su carpeta de inicio. La presencia de dicho archivo de configuración será detectada automáticamente y evitará esta ventana de asistencia. - IMPORTANTE: Este asistente no es completamente funcional aún. Simplemente haga clic de inicio a fin y el asistente creará un archivo de configuración estándar. + + You seem to be using the Octave graphical interface for the first time on this computer. Click 'Finish' to write a configuration file and launch Octave GUI. + Al parecer usted utiiza la interfase gráfica de Octave por primera vez en este ordenador. Presione 'Finalizar' para generar un archivo de configuración e iniciar Octave GUI. + + + + The configuration file is stored in __%1__. If that file exists, you will not see this dialog when Octave starts again. + La configuración ha sido guardada en __%1__. Si ese archivo existe, usted no verá este diálogo cuando Octave inicie de nuevo. - - - - - Next - Siguiente + + <html><head/><body><p>For more information about Octave,</p> +<ul> +<li>visit <a href="http://octave.org"><span style=" text-decoration: underline; color:#0000ff;">http://octave.org</span></a>,</li> +<li> get the documentation online as <a href="http://www.gnu.org/software/octave/doc/interpreter/index.html"><span style=" text-decoration: underline; color:#0000ff;">html</span></a>- or <a href="http://www.gnu.org/software/octave/octave.pdf"><span style=" text-decoration: underline; color:#0000ff;">pdf</span></a>-document, or</li> +<li>open the documentation browser of Octave GUI with the help menu.</li> +</ul> +</body></html> + <html><head/><body><p>Para mayor información acerca de Octave,</p> +<ul> +<li>visite <a href="http://octave.org"><span style=" text-decoration: underline; color:#0000ff;">http://octave.org</span></a>,</li> +<li> para obtener la documentación en linea como <a href="http://www.gnu.org/software/octave/doc/interpreter/index.html"><span style=" text-decoration: underline; color:#0000ff;">html</span></a>- o <a href="http://www.gnu.org/software/octave/octave.pdf"><span style=" text-decoration: underline; color:#0000ff;">como documento </span></a>-pdf, o</li> +<li>abrir el navegador de documentación de Octave GUI con el menú de ayuda.</li> +</ul> +</body></html> - - - - - Previous - Anterior - - - + Welcome to Octave! ¡Bienvenido a Octave! - - This is the development version of Octave with the first official GUI. - Esta es la versión en desarrollo de Octave con su primer GUI oficial. - - - - You seem to run Octave GUI for the first time on this computer. This assistant will help you to configure this software installation. Click 'Finish' to write a configuration file and launch Octave GUI. - Parece que ejecuta Octave GUI por primera vez en esta computadora/ordenador. Este asistente le ayudará a configurar la instalación del programa. Presione "Terminar" para escribir un archivo de configuración e iniciar Octave GUI. - - - + Finish Terminar diff -r 20d1b911b4e7 -r c702371ff6df libgui/languages/fr_FR.ts --- a/libgui/languages/fr_FR.ts Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/languages/fr_FR.ts Sat Oct 05 11:22:09 2013 -0400 @@ -83,9 +83,9 @@ QWinTerminalImpl - + copied selection to clipboard - sélection copiée vers le clipboard + sélection copiée vers le presse-papier @@ -104,19 +104,19 @@ file_editor - + Octave Editor - Editeur d'Octave + Éditeur d'Octave - + Octave Files (*.m);;All Files (*) - Fichiers d'Octave (*.);;Tous les fichiers (*) + Fichiers d'Octave (*.m);;Tous les fichiers (*) - + Could not open file %1 for read: %2. Impossible d'ouvrir le fichier %1 pour lecture : @@ -127,14 +127,14 @@ File not saved! A file with the selected name %1 is already open in the editor - Fichier non-enregistré! Un fichier avec le nom sélectionné + Fichier non-enregistré! Un fichier ayant le nom sélectionné %1 -est déjà ouvert dans l'editeur +est déjà ouvert dans l'éditeur The associated file editor tab has disappeared. It was likely closed by some means. - L'onglet editeur de fichier associé a disparu. Il a probablement été fermé par un moyen quelconque. + L'onglet éditeur de fichier associé a disparu. Il a probablement été fermé par un moyen quelconque. @@ -142,14 +142,14 @@ &%1 %2 - + &New File &Nouveau &Open File - &Ouvrir... + &Ouvrir @@ -157,14 +157,14 @@ &Enregistrer - + Save File &As Enregistrer &sous - + Print - &Imprimer + Imprimer @@ -174,7 +174,7 @@ &Redo - &Refaire + &Rétablir @@ -189,20 +189,20 @@ Paste - C&oller + Coller - + &Next Bookmark Marque page &suivant - + Pre&vious Bookmark - Marque page &precedent + Marque page &précédent - + Toggle &Bookmark Basculer &marque page @@ -219,7 +219,7 @@ Pre&vious breakpoint - Point d'arrêt &precendent + Point d'arrêt &précédent @@ -242,27 +242,27 @@ &Décommenter - + &Recent Editor Files - Fichiers &recents + Fichiers &récents - + &Close &Fermer - + Close All Tout fermer - + Close Other Files Fermer les autres fichiers - + &Find and Replace &Rechercher et remplacer @@ -277,19 +277,19 @@ &Aller à la ligne - + &File &Fichier - + &Edit &Editer &Debug - &Deboguer + &Déboguer @@ -327,25 +327,25 @@ - + Octave Editor - Editeur d'Octave + Éditeur d'Octave - + The file %1 is about to be closed but has been modified. %2 Le fichier %1 -est en cours de fermeture, mais il à été modifié. +est en cours de fermeture mais il a été modifié. %2 - + Octave Files (*.m);;All Files (*) Fichiers d'Octave (*.m);;Tous les fichiers (*) @@ -365,7 +365,7 @@ Warning: The contents in the editor is modified! -Avertissement: Le contenu dans l'editeur est modifié! +Avertissement: Le contenu dans l'éditeur est modifié! @@ -377,14 +377,14 @@ a été supprimé ou rénommé. Voulez-vous l'enregistrer maintenant ?%2 - + Could not open file %1 for write: %2. - Impossible d'ouvrir le fichier %1 pour ecrire : + Impossible d'ouvrir le fichier %1 pour écrire : %2. - + It seems that '%1' has been modified by another application. Do you want to reload it? Il semblerait que '%1' a été modifié par une autre application. Voulez-vous le récharger ? @@ -547,12 +547,12 @@ Impossible de supprimer un répertoire qui n'est pas vide - + Set directory of file browser Définir le répertoire de l'explorateur de fichiers - + Create File Créer un fichier @@ -591,7 +591,7 @@ Match &case - Respecter &les majuscules/minuscules + Respecter &la casse @@ -611,7 +611,7 @@ Find &Previous - Rechercher le &precedant + Rechercher le &précédent @@ -636,7 +636,7 @@ Regular E&xpressions - E&xpressions regulières + E&xpressions régulières @@ -649,7 +649,7 @@ Recherche dans la sé&lection - + Search from end Rechercher depuis la fin @@ -666,7 +666,7 @@ %1 items replaced - %1 instances remplacés + %1 instances remplacées @@ -676,7 +676,7 @@ No more matches found - Aucune correspondance trouvée + Plus aucune correspondance trouvée @@ -719,7 +719,7 @@ Recurse directories - Parcourir recursivement les sous-répertoires + Parcourir récursivement les sous-répertoires @@ -739,12 +739,12 @@ Name case insensitive - Nom insensible aux majuscules/minuscules + Nom insensible à la casse Set matching name is case insensitive - Les noms concordant sont insensible aux majuscules/minuscules + Les noms concordant sont insensible à la casse @@ -759,25 +759,25 @@ Text to match - Texte concordant + Texte à rechercher Text case insensitive - Texte insensible aux majuscules/minuscules + Texte insensible à la casse Set text content is case insensitive - Le texte concordant est insensible aux majuscules/minuscules + Le texte recherché est insensible à la casse - + Search results Résultats de la recherche - + Idle. Inoccupé. @@ -789,7 +789,7 @@ Start search for matching files - Démarrer la recherche pour les fichiers concordants + Démarrer la recherche des fichiers concordants @@ -799,12 +799,12 @@ Stop searching - Arreter la recherche + Arrêter la recherche File name/location - Nom de fichier/chemin + Nom/Chemin de fichier @@ -825,9 +825,9 @@ find_files_model - + Filename - Fichier + Nom du fichier @@ -838,9 +838,9 @@ history_dock_widget - + Browse and search the command history. - Naviguer et rechercher le historique des commandes. + Naviguer et rechercher l'historique des commandes. @@ -876,23 +876,23 @@ main_window - + Load Workspace Charger l'espace de travail - - + + About Octave À propos d'Octave - + &File &Fichier - + New Nouveau @@ -902,7 +902,7 @@ Fichier de script - + Function Fonction @@ -912,12 +912,12 @@ Figure - + Open... Ouvrir... - + Preferences... Préférences... @@ -927,14 +927,14 @@ Quitter - + &Edit &Editer Undo - Defaire + Annuler @@ -942,28 +942,33 @@ Copier - + Paste Coller - - + + Save Workspace As Enregistrer l'espace de travail sous - + Set working directory Définir le répertoire de travail - + + Clear Clipboard + + + + Find Files... Rechercher des fichiers... - + Clear Command Window Nettoyer la fenêtre de commande @@ -978,9 +983,9 @@ Nettoyer l'espace de travail - + De&bug - De&boguer + Dé&boguer @@ -995,7 +1000,7 @@ Step out - Executer jusqu'à l'instruction de retour + Exécuter jusqu'à l'instruction de retour @@ -1023,7 +1028,27 @@ Rétablir la disposition par défaut des fenêtres - + + Octave Packages + + + + + Share Code + + + + + Contribute to Octave + + + + + Octave Developer Resources + + + + On Disk Installé localement @@ -1050,15 +1075,15 @@ Browse directories - Naviguer les répertoires + Naviguer dans les répertoires - + Load workspace Charger l'espace de travail - + &Window &Fenêtre @@ -1080,7 +1105,7 @@ Show Editor - Afficher l'editeur + Afficher l'éditeur @@ -1105,49 +1130,40 @@ Editor - Editeur + Éditeur - + Documentation Documentation - + &Help &Aide Report Bug - Signaler un bug - - - - Visit Agora - Visiter Agora - - - - Visit Octave Forge - Visiter Octave Forge + Signaler un bogue octave_dock_widget + Undock widget Détacher le widget - + Hide widget Cacher le widget - + Dock widget Attacher le widget @@ -1165,12 +1181,12 @@ The file %1 does not exist in the load path. To debug the function you are editing, you must either change to the directory %2 or add that directory to the load path. - Le fichier %1 n'existe pas dans les chemins accessibles. Pour déboguer la fonction que vous éditez, vous devez soit modifier le répertoire pour %2 ou ajouter le répertoire au chemin. + Le fichier %1 n'existe pas dans les chemins accessibles. Pour déboguer la fonction que vous éditez, vous devez soit modifier le répertoire pour %2 ou ajouter le répertoire aux chemins accessibles. The file %1 is shadowed by a file with the same name in the load path. To debug the function you are editing, change to the directory %2. - Le fichier %1 est occulté par un fichier avec le même nom dans le chemin. Pour déboguer la fonction que vous éditez, vous devez modifier le répertoire pour %2. + Le fichier %1 est occulté par un fichier du même nom dans les chemins accessibles. Pour déboguer la fonction que vous éditez, vous devez modifier le répertoire pour %2. @@ -1223,17 +1239,17 @@ Editor - Editeur + Éditeur Show white space - Montrer les espaces blancs + Montrer les espaces Do not show white spaces used for indentation - Ne pas montrer les espaces blancs utilisés pour l'indentation + Ne pas montrer les espaces utilisés pour l'indentation @@ -1283,7 +1299,7 @@ Case sensitive - Sensible au maj/minuscules + Sensible à la casse @@ -1293,17 +1309,17 @@ Match words in document - Checher dans le document + Inclure les mots du document Restore editor tabs from previous session on startup - Restaurer les onglets de la session precedente + Restaurer les onglets de la session précédente Use custom file editor - Utiliser un editeur externe + Utiliser un éditeur externe @@ -1318,7 +1334,7 @@ <html><head/><body><p>Select font, font size (as difference to the default size), font decoration (bold, italic, underline), textcolor and background color (for the latter, the color pink (255,0,255) is a placeholder for the default background color)</p></body></html> - <html><head/><body><p>Choisir le font, la taille (difference à la taille par défaut), le style (gras, italique, sous-ligné), la couleur du texte et la couleur du fond (dans ce cas, la couleur rose [255,0,255] designé la couleur de fond par défaut)</p></body></html> + <html><head/><body><p>Choisir la police, la taille (différence avec à la taille par défaut), le style (gras, italique, souligné), la couleur du texte et du fond (pour ce dernier, la couleur rose [255,0,255] designe la couleur par défaut)</p></body></html> @@ -1333,7 +1349,7 @@ Font - Font + Police @@ -1343,7 +1359,7 @@ Highlight current line - Sous-ligner la ligne courante + Surligner la ligne courante @@ -1368,17 +1384,17 @@ Cursor type: - Type de courseur : + Type de curseur : Cursor blinking - Courseur clignotant + Curseur clignotant Font size - Taille du font + Taille de police @@ -1433,7 +1449,7 @@ Use proxy server - Serveur proxy + Utiliser un serveur proxy @@ -1453,7 +1469,7 @@ Language (requires restart) - Langue (necessite un redemarrage) + Langue (nécessite un redémarrage) @@ -1463,12 +1479,12 @@ Socks5Proxy - Proxy Sock 5 + Proxy Socks5 Hostname: - Nom du hote : + Nom de l'hote : @@ -1510,7 +1526,7 @@ Difference to the default size - Difference avecla taille par défaut + Différence avec la taille par défaut @@ -1538,15 +1554,15 @@ Command Window - Fenetre de commandes + Fenêtre de commandes webinfo - + Type here and press 'Return' to search - Entrez le texte ici et appuyez 'Entrée' pour lancer la recherche + Entrez le texte ici et appuyez sur 'Entrée' pour lancer la recherche @@ -1557,48 +1573,38 @@ welcome_wizard - + Welcome to GNU Octave - Bienvenu dans Octave + Bienvenu dans GNU Octave - - It appears that you have launched Octave GUI for the first time on this computer, since no configuration file could be found at '~/.octave-gui'. This wizard will guide you through the essential settings you should make before you can start using Octave GUI. If you want to transfer your settings you have previously made just close this dialog and copy over the settings file to your home folder. The presence of that file will automatically be detected and will skip this wizard. IMPORTANT: This wizard is not fully functional yet. Just click your way to the end and it will create a standard settings file. - Il semble que vous avez lancé Octave GUI pour la premiere fois sur cet ordinateur, puisque aucun fichier de configuration n'a été trouvé au '~/.octave-gui'. Cet assistant va vous guider à travers les reglages necessaires avant de pouvoir utiliser Octave GUI. Si vous voulez transferer des reglages que vous avez déjà fait, fermez ce dialogue et copiez le fichier de configuration dans votre repertoire personnel. La presence de ce fichier va etre detecté et cet assistant ne s'affichera plus. IMPORTANT : Cet assistant n'est pas encore completement fonctionnel. Passez les pages jusqu'à la fin et il va créer un fichier de configuration standard. + + You seem to be using the Octave graphical interface for the first time on this computer. Click 'Finish' to write a configuration file and launch Octave GUI. + - - - - - Next - Suivant + + The configuration file is stored in __%1__. If that file exists, you will not see this dialog when Octave starts again. + - - - - - Previous - Precedent + + <html><head/><body><p>For more information about Octave,</p> +<ul> +<li>visit <a href="http://octave.org"><span style=" text-decoration: underline; color:#0000ff;">http://octave.org</span></a>,</li> +<li> get the documentation online as <a href="http://www.gnu.org/software/octave/doc/interpreter/index.html"><span style=" text-decoration: underline; color:#0000ff;">html</span></a>- or <a href="http://www.gnu.org/software/octave/octave.pdf"><span style=" text-decoration: underline; color:#0000ff;">pdf</span></a>-document, or</li> +<li>open the documentation browser of Octave GUI with the help menu.</li> +</ul> +</body></html> + - + Welcome to Octave! Bienvenu dans Octave! - - This is the development version of Octave with the first official GUI. - Ceci est la version de developpement de Octave avec le premier GUI officiel. - - - - You seem to run Octave GUI for the first time on this computer. This assistant will help you to configure this software installation. Click 'Finish' to write a configuration file and launch Octave GUI. - Il semble que vous executez Octave GUI pour la premiere fois sur cet ordinateur. Cet assistant va vous aider a configurer ce logiciel. Appuyez sur 'Fin' pour créer le fichier de configuration et lancer Octave GUI. - - - + Finish Fin @@ -1633,7 +1639,7 @@ Right click to copy, rename, or display - Clique droit pour copier, renommer ou afficher + Cliquez droit pour copier, renommer ou afficher @@ -1661,7 +1667,7 @@ Only top-level symbols may be renamed. - Seuls les variables de plus haut niveau peuvent etre renommés. + Seules les variables de plus haut niveau peuvent être renommées. diff -r 20d1b911b4e7 -r c702371ff6df libgui/languages/nl_NL.ts --- a/libgui/languages/nl_NL.ts Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/languages/nl_NL.ts Sat Oct 05 11:22:09 2013 -0400 @@ -83,7 +83,7 @@ QWinTerminalImpl - + copied selection to clipboard selectie naar klembord gekopieerd @@ -246,7 +246,7 @@ Identifier - + Identifier @@ -697,19 +697,19 @@ file_editor - + Octave Editor - + Octave Files (*.m);;All Files (*) Octave bestanden (*.m);;Alle bestanden (*) - + Could not open file %1 for read: %2. Bestand %1 kon niet geopend worden om te lezen: @@ -735,7 +735,7 @@ - + &New File &Nieuw Bestand @@ -750,12 +750,12 @@ Op&slaan - + Save File &As Opslaan &als - + Print Afdrukken @@ -785,17 +785,17 @@ Plakken - + &Next Bookmark Volge&nde bladwijzer - + Pre&vious Bookmark &Vorige bladwijzer - + Toggle &Bookmark &Bladwijzer invoegen @@ -835,27 +835,27 @@ Zet om naar code - + &Recent Editor Files Recent geopend - + &Close Sluit bestand - + Close All Alle bestanden sluiten - + Close Other Files Andere bestanden sluiten - + &Find and Replace Zoek en Vervang @@ -870,12 +870,12 @@ Ga naar regel - + &File Bestand - + &Edit B&ewerken @@ -920,14 +920,14 @@ - + Octave Editor - + The file %1 is about to be closed but has been modified. @@ -937,7 +937,7 @@ dat gesloten moet worden is gewijzigd. - + Octave Files (*.m);;All Files (*) Octave bestanden (*.m);;Alle bestanden (*) @@ -968,14 +968,14 @@ is gewist of hernoemd. Wil je het nu opslaan? - + Could not open file %1 for write: %2. Kon bestand %1 niet openen om te schrijven: %2. - + It seems that '%1' has been modified by another application. Do you want to reload it? Het lijkt erop dat '%1' is gewijzigd door een ander programma. Wil je het opnieuw laden? @@ -1137,12 +1137,12 @@ Kan geen niet-lege map wissen - + Set directory of file browser Stel file browser map in - + Create File Maak nieuw bestand @@ -1239,7 +1239,7 @@ In se&lectie zoeken - + Search from end vanaf einde terug zoeken @@ -1362,12 +1362,12 @@ Tekst instellen op niet-hoofdlettergevoelig - + Search results Zoekresultaten - + Idle. Niet bezig. @@ -1415,7 +1415,7 @@ find_files_model - + Filename Bestandsnaam @@ -1428,7 +1428,7 @@ history_dock_widget - + Browse and search the command history. Bladeren en zoeken door de opdrachtgeschiedenis. @@ -1466,23 +1466,23 @@ main_window - + Load Workspace Werkruimte laden - - + + About Octave Over Octave - + &File Bestand - + New Nieuw @@ -1492,7 +1492,7 @@ Script - + Function Functie @@ -1502,12 +1502,12 @@ Figuur - + Open... Open... - + Preferences... Voorkeuren... @@ -1517,7 +1517,7 @@ Afsluiten - + &Edit B&ewerken @@ -1532,28 +1532,33 @@ Kopiëren - + Paste Plakken - - + + Save Workspace As Bewaar werkruimte als ... - + Set working directory Stel werkmap in - + + Clear Clipboard + + + + Find Files... Zoek bestanden... - + Clear Command Window Veeg opdrachtvenster schoon @@ -1568,7 +1573,7 @@ Wis werkruimte - + De&bug De&buggen @@ -1613,7 +1618,27 @@ Stel oorspronkelijke window layout opnieuw in - + + Octave Packages + + + + + Share Code + + + + + Contribute to Octave + + + + + Octave Developer Resources + + + + On Disk Op schijf @@ -1643,12 +1668,12 @@ Blader door mappen - + Load workspace Werkruimte laden - + &Window Venster @@ -1699,12 +1724,12 @@ - + Documentation Documentatie - + &Help Hulp @@ -1713,31 +1738,22 @@ Report Bug Probleem rapporteren - - - Visit Agora - Bezoek Agora - - - - Visit Octave Forge - Bezoek Octave Forge - octave_dock_widget + Undock widget Widget laten zweven - + Hide widget Widget verbergen - + Dock widget Widget in venster opnemen @@ -2134,7 +2150,7 @@ webinfo - + Type here and press 'Return' to search Typ hier en druk op 'Enter' om te zoeken @@ -2147,48 +2163,38 @@ welcome_wizard - + Welcome to GNU Octave Welkom bij GNU Octave - - It appears that you have launched Octave GUI for the first time on this computer, since no configuration file could be found at '~/.octave-gui'. This wizard will guide you through the essential settings you should make before you can start using Octave GUI. If you want to transfer your settings you have previously made just close this dialog and copy over the settings file to your home folder. The presence of that file will automatically be detected and will skip this wizard. IMPORTANT: This wizard is not fully functional yet. Just click your way to the end and it will create a standard settings file. - Het lijkt erop dat je de Octave GUI voor de eerste keer opstart op deze computer omdat er geen configuratiebestand in '~/.octave-gui' is gevonden. Deze wizard zal je begeleiden tijdens het instellen van de belangrijkste zaken voordat je de Octave GUI kan gebruiken. Wil je eerder gemaakte instellingen overzetten, sluit dan dit dialoogvenster en kopieer het configuratiebestand naar je home map. De aanwezigheid van het bestand zal automatisch gedetecteerd worden en deze wizard doen overslaan. BELANGRIJK: Deze wizard is nog niet volledig functioneel. Klik door tot het einde voor standaardinstellingen. + + You seem to be using the Octave graphical interface for the first time on this computer. Click 'Finish' to write a configuration file and launch Octave GUI. + + + + + The configuration file is stored in __%1__. If that file exists, you will not see this dialog when Octave starts again. + - - - - - Next - Volgende + + <html><head/><body><p>For more information about Octave,</p> +<ul> +<li>visit <a href="http://octave.org"><span style=" text-decoration: underline; color:#0000ff;">http://octave.org</span></a>,</li> +<li> get the documentation online as <a href="http://www.gnu.org/software/octave/doc/interpreter/index.html"><span style=" text-decoration: underline; color:#0000ff;">html</span></a>- or <a href="http://www.gnu.org/software/octave/octave.pdf"><span style=" text-decoration: underline; color:#0000ff;">pdf</span></a>-document, or</li> +<li>open the documentation browser of Octave GUI with the help menu.</li> +</ul> +</body></html> + - - - - - Previous - Vorige - - - + Welcome to Octave! Welkom bij Octave! - - This is the development version of Octave with the first official GUI. - Dit is de ontwikkelvariant van Octave met de eerste officiële GUI. - - - - You seem to run Octave GUI for the first time on this computer. This assistant will help you to configure this software installation. Click 'Finish' to write a configuration file and launch Octave GUI. - Het lijkt erop dat je de Octave GUI voor de eerste keer uitvoert op deze computer. Deze assistent zal je helpen het programma te configureren. Klik 'Voltooien' om een configuratiebestand te maken en de Octave GUI te starten. - - - + Finish Voltooien diff -r 20d1b911b4e7 -r c702371ff6df libgui/languages/pt_BR.ts --- a/libgui/languages/pt_BR.ts Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/languages/pt_BR.ts Sat Oct 05 11:22:09 2013 -0400 @@ -83,7 +83,7 @@ QWinTerminalImpl - + copied selection to clipboard @@ -104,19 +104,19 @@ file_editor - + Octave Editor Editor Octave - + Octave Files (*.m);;All Files (*) Scripts Octave (*.m);;Todos Arquivos (*) - + Could not open file %1 for read: %2. Não foi possível abrir arquivo %1 para leitura: %2. @@ -139,7 +139,7 @@ &%1 %2 - + &New File &Novo Arquivo @@ -154,12 +154,12 @@ &Salvar Arquivo - + Save File &As Salvar Arquivo &Como - + Print Imprimir @@ -189,17 +189,17 @@ Co&lar - + &Next Bookmark &Próximo Marcador - + Pre&vious Bookmark Marcardor &Anterior - + Toggle &Bookmark Visualizar &Marcador @@ -239,27 +239,27 @@ &Descomentar - + &Recent Editor Files Arquivos &recentes - + &Close &Fechar - + Close All Fechar &Todos - + Close Other Files Fechar Outros Arquivos - + &Find and Replace Procurar e Substituir @@ -274,12 +274,12 @@ Vá para Linha - + &File &Arquivo - + &Edit &Editar @@ -324,14 +324,14 @@ - + Octave Editor Editor Octave - + The file %1 is about to be closed but has been modified. @@ -342,7 +342,7 @@ %2 - + Octave Files (*.m);;All Files (*) Scripts Octave (*.m);; Todos Arquivos (*) @@ -374,14 +374,14 @@ foi removido ou renomeado. Pretende salvá-lo agora?%2 - + Could not open file %1 for write: %2. Não foi possível abrir arquivo %1 para escrita: %2. - + It seems that '%1' has been modified by another application. Do you want to reload it? Parece que o arquivo '%1' foi modificado por outra aplicação. Deseja recarregá-lo? @@ -542,12 +542,12 @@ Não é possível remover um diretório que não está vázio - + Set directory of file browser Alterar diretório do navegador de arquivos - + Create File Criar Arquivo @@ -642,7 +642,7 @@ Seleção de busca - + Search from end Procurar do final @@ -765,12 +765,12 @@ Altere se conteúdo do texto é insensível a caixa alta/baixa - + Search results Resultados de Busca - + Idle. Ocupado. @@ -818,7 +818,7 @@ find_files_model - + Filename Nome do Arquivo @@ -831,7 +831,7 @@ history_dock_widget - + Browse and search the command history. Pesquise no histórico de comandos. @@ -869,23 +869,23 @@ main_window - + Load Workspace Carregar ambiente de trabalho - - + + About Octave Sobre o Octave - + &File Arquivo - + New Novo @@ -895,7 +895,7 @@ Script - + Function Função @@ -905,12 +905,12 @@ Figura - + Open... Abrir... - + Preferences... Preferências... @@ -920,7 +920,7 @@ Sair - + &Edit Editar @@ -935,28 +935,33 @@ Copiar - + Paste Colar - - + + Save Workspace As Salvar Ambiente de Trabalho como - + Set working directory Alterar diretório de trabalho - + + Clear Clipboard + + + + Find Files... Encontrar Arquivos... - + Clear Command Window Limpar Janela de Comandos @@ -971,7 +976,7 @@ Limpar Ambiente de Trabalho - + De&bug Depurar @@ -1016,7 +1021,27 @@ Recuperar Disposição de Janelas Padrão - + + Octave Packages + + + + + Share Code + + + + + Contribute to Octave + + + + + Octave Developer Resources + + + + On Disk No Disco @@ -1046,12 +1071,12 @@ Procurar diretórios - + Load workspace Carregar ambiente de trabalho - + &Window &Janela @@ -1102,12 +1127,12 @@ - + Documentation Documentação - + &Help &Ajuda @@ -1116,31 +1141,22 @@ Report Bug Reportar Bug - - - Visit Agora - Visite Agora - - - - Visit Octave Forge - Visite Octave Forge - octave_dock_widget + Undock widget Desacoplar widget - + Hide widget Esconder widget - + Dock widget Acoplar widget @@ -1537,7 +1553,7 @@ webinfo - + Type here and press 'Return' to search Digite aqui e pressione 'Enter' para procurar @@ -1550,48 +1566,38 @@ welcome_wizard - + Welcome to GNU Octave Bem-vindo ao GNU Octave - - It appears that you have launched Octave GUI for the first time on this computer, since no configuration file could be found at '~/.octave-gui'. This wizard will guide you through the essential settings you should make before you can start using Octave GUI. If you want to transfer your settings you have previously made just close this dialog and copy over the settings file to your home folder. The presence of that file will automatically be detected and will skip this wizard. IMPORTANT: This wizard is not fully functional yet. Just click your way to the end and it will create a standard settings file. - Aparentemente o Octave GUI foi lançado pela primeira vez neste computador, já que nenhum arquivo de configuração foi encontrado em '~/.octave-gui'. Este tutorial irá guiá-lo para realizar configurações essenciais antes de utilizar o Octave. Se deseja transferir suas configurações definidas previamente, feche este diálogo e copie os arquivos para o local apropriado. IMPORTANT: Este tutorial não é totalmente funcional ainda. Simplesmente prossiga e configurações padrão serão criadas. + + You seem to be using the Octave graphical interface for the first time on this computer. Click 'Finish' to write a configuration file and launch Octave GUI. + + + + + The configuration file is stored in __%1__. If that file exists, you will not see this dialog when Octave starts again. + - - - - - Next - Próximo + + <html><head/><body><p>For more information about Octave,</p> +<ul> +<li>visit <a href="http://octave.org"><span style=" text-decoration: underline; color:#0000ff;">http://octave.org</span></a>,</li> +<li> get the documentation online as <a href="http://www.gnu.org/software/octave/doc/interpreter/index.html"><span style=" text-decoration: underline; color:#0000ff;">html</span></a>- or <a href="http://www.gnu.org/software/octave/octave.pdf"><span style=" text-decoration: underline; color:#0000ff;">pdf</span></a>-document, or</li> +<li>open the documentation browser of Octave GUI with the help menu.</li> +</ul> +</body></html> + - - - - - Previous - Anterior - - - + Welcome to Octave! Bem-vindo ao Octave! - - This is the development version of Octave with the first official GUI. - Esta é a versão de desenvolvimento do Octave com a primeira GUI oficial. - - - - You seem to run Octave GUI for the first time on this computer. This assistant will help you to configure this software installation. Click 'Finish' to write a configuration file and launch Octave GUI. - Você parece ter executado o Octave GUI pela primeira vez neste computador. Este assistente irá ajudá-lo. Clique 'Finalizar' para escrever um arquivo de configuração padrão e lançar o Octave GUI. - - - + Finish Finalizar diff -r 20d1b911b4e7 -r c702371ff6df libgui/languages/ru_RU.ts --- a/libgui/languages/ru_RU.ts Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/languages/ru_RU.ts Sat Oct 05 11:22:09 2013 -0400 @@ -41,6 +41,52 @@ persistent + + + foreground + + + + + background + + + + + selection + + + + + cursor + + + + + QTerminal + + + Copy + + + + + Paste + + + + + Clear All + + + + + QWinTerminalImpl + + + copied selection to clipboard + + documentation_dock_widget @@ -58,19 +104,19 @@ file_editor - + Octave Editor - + Octave Files (*.m);;All Files (*) - + Could not open file %1 for read: %2. @@ -93,7 +139,7 @@ - + &New File Созд&ать @@ -108,12 +154,12 @@ &Сохранить - + Save File &As Сохранить &как - + Print @@ -143,17 +189,17 @@ - + &Next Bookmark С&Ð»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ Ð·Ð°ÐºÐ»Ð°Ð´ÐºÐ° - + Pre&vious Bookmark Пр&ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð°Ñ Ð·Ð°ÐºÐ»Ð°Ð´ÐºÐ° - + Toggle &Bookmark &УÑтановить/ÑнÑÑ‚ÑŒ закладку @@ -193,27 +239,27 @@ - + &Recent Editor Files - + &Close + + Close All + + + - Close All - - - - Close Other Files - + &Find and Replace @@ -228,12 +274,12 @@ - + &File &Файл - + &Edit &Правка @@ -278,14 +324,14 @@ - + Octave Editor - + The file %1 is about to be closed but has been modified. @@ -293,7 +339,7 @@ - + Octave Files (*.m);;All Files (*) @@ -319,13 +365,13 @@ - + Could not open file %1 for write: %2. - + It seems that '%1' has been modified by another application. Do you want to reload it? @@ -475,7 +521,7 @@ - Are you sre you want to delete + Are you sure you want to delete @@ -485,12 +531,12 @@ - + Set directory of file browser - + Create File @@ -585,7 +631,7 @@ - + Search from end @@ -708,12 +754,12 @@ - + Search results - + Idle. @@ -748,7 +794,7 @@ - + Searching... @@ -761,7 +807,7 @@ find_files_model - + Filename @@ -774,7 +820,7 @@ history_dock_widget - + Browse and search the command history. ПроÑмотр и поиÑк в журнале выполненных команд. @@ -812,23 +858,23 @@ main_window - + Load Workspace Загрузить облаÑÑ‚ÑŒ переменных - - + + About Octave Об Octave - + &File &Файл - + New @@ -838,7 +884,7 @@ - + Function @@ -848,12 +894,12 @@ - + Open... - + Preferences... @@ -863,7 +909,7 @@ Выход - + &Edit &Правка @@ -878,28 +924,33 @@ - + Paste - - + + Save Workspace As - + Set working directory - + + Clear Clipboard + + + + Find Files... - + Clear Command Window @@ -914,7 +965,7 @@ - + De&bug @@ -959,7 +1010,27 @@ - + + Octave Packages + + + + + Share Code + + + + + Contribute to Octave + + + + + Octave Developer Resources + + + + On Disk @@ -989,12 +1060,12 @@ - + Load workspace - + &Window @@ -1045,12 +1116,12 @@ - + Documentation Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ - + &Help @@ -1059,39 +1130,25 @@ Report Bug Сообщить об ошибке - - - Visit Agora - - - - - Visit Octave Forge - - octave_dock_widget + Undock widget - + Hide widget - + Dock widget - - - Unock widget - - octave_qscintilla @@ -1157,12 +1214,7 @@ - - Graphic icons - - - - + Editor Редактор @@ -1272,12 +1324,12 @@ - + Font - + Show line numbers @@ -1297,7 +1349,12 @@ - + + Graphic icons + + + + emacs emacs @@ -1317,7 +1374,7 @@ - + Font size @@ -1387,7 +1444,7 @@ - + Icon set for dock widgets @@ -1402,7 +1459,7 @@ - + Socks5Proxy @@ -1434,8 +1491,23 @@ - - Difference to the defalt size + + IBeam Cursor + + + + + Block Cursor + + + + + Underline Cursor + + + + + Difference to the default size @@ -1470,7 +1542,7 @@ webinfo - + Type here and press 'Return' to search @@ -1483,48 +1555,38 @@ welcome_wizard - + Welcome to GNU Octave - - It appears that you have launched Octave GUI for the first time on this computer, since no configuration file could be found at '~/.octave-gui'. This wizard will guide you through the essential settings you should make before you can start using Octave GUI. If you want to transfer your settings you have previously made just close this dialog and copy over the settings file to your home folder. The presence of that file will automatically be detected and will skip this wizard. IMPORTANT: This wizard is not fully functional yet. Just click your way to the end and it will create a standard settings file. + + You seem to be using the Octave graphical interface for the first time on this computer. Click 'Finish' to write a configuration file and launch Octave GUI. + + + + + The configuration file is stored in __%1__. If that file exists, you will not see this dialog when Octave starts again. - - - - - Next + + <html><head/><body><p>For more information about Octave,</p> +<ul> +<li>visit <a href="http://octave.org"><span style=" text-decoration: underline; color:#0000ff;">http://octave.org</span></a>,</li> +<li> get the documentation online as <a href="http://www.gnu.org/software/octave/doc/interpreter/index.html"><span style=" text-decoration: underline; color:#0000ff;">html</span></a>- or <a href="http://www.gnu.org/software/octave/octave.pdf"><span style=" text-decoration: underline; color:#0000ff;">pdf</span></a>-document, or</li> +<li>open the documentation browser of Octave GUI with the help menu.</li> +</ul> +</body></html> - - - - - Previous - - - - + Welcome to Octave! - - This is the development version of Octave with the first official GUI. - - - - - You seem to run Octave GUI for the first time on this computer. This assistant will help you to configure this software installation. Click 'Finish' to write a configuration file and launch Octave GUI. - - - - + Finish diff -r 20d1b911b4e7 -r c702371ff6df libgui/languages/uk_UA.ts --- a/libgui/languages/uk_UA.ts Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/languages/uk_UA.ts Sat Oct 05 11:22:09 2013 -0400 @@ -41,6 +41,645 @@ persistent + + + foreground + + + + + background + + + + + selection + + + + + cursor + + + + + QTerminal + + + Copy + + + + + Paste + + + + + Clear All + + + + + QWinTerminalImpl + + + copied selection to clipboard + + + + + QsciLexerBatch + + + Default + + + + + Comment + + + + + Keyword + + + + + Label + + + + + Hide command character + + + + + External command + + + + + Variable + + + + + Operator + + + + + QsciLexerCPP + + + Default + + + + + Inactive default + + + + + C comment + + + + + Inactive C comment + + + + + C++ comment + + + + + Inactive C++ comment + + + + + JavaDoc style C comment + + + + + Inactive JavaDoc style C comment + + + + + Number + + + + + Inactive number + + + + + Keyword + + + + + Inactive keyword + + + + + Double-quoted string + + + + + Inactive double-quoted string + + + + + Single-quoted string + + + + + Inactive single-quoted string + + + + + IDL UUID + + + + + Inactive IDL UUID + + + + + Pre-processor block + + + + + Inactive pre-processor block + + + + + Operator + + + + + Inactive operator + + + + + Identifier + + + + + Inactive identifier + + + + + Unclosed string + + + + + Inactive unclosed string + + + + + C# verbatim string + + + + + Inactive C# verbatim string + + + + + JavaScript regular expression + + + + + Inactive JavaScript regular expression + + + + + JavaDoc style C++ comment + + + + + Inactive JavaDoc style C++ comment + + + + + Secondary keywords and identifiers + + + + + Inactive secondary keywords and identifiers + + + + + JavaDoc keyword + + + + + Inactive JavaDoc keyword + + + + + JavaDoc keyword error + + + + + Inactive JavaDoc keyword error + + + + + Global classes and typedefs + + + + + Inactive global classes and typedefs + + + + + C++ raw string + + + + + Inactive C++ raw string + + + + + QsciLexerDiff + + + Default + + + + + Comment + + + + + Command + + + + + Header + + + + + Position + + + + + Removed line + + + + + Added line + + + + + Changed line + + + + + QsciLexerMatlab + + + Default + + + + + Comment + + + + + Command + + + + + Number + + + + + Keyword + + + + + Single-quoted string + + + + + Operator + + + + + Identifier + + + + + Double-quoted string + + + + + QsciLexerPerl + + + Default + + + + + Error + + + + + Comment + + + + + POD + + + + + Number + + + + + Keyword + + + + + Double-quoted string + + + + + Single-quoted string + + + + + Operator + + + + + Identifier + + + + + Scalar + + + + + Array + + + + + Hash + + + + + Symbol table + + + + + Regular expression + + + + + Substitution + + + + + Backticks + + + + + Data section + + + + + Here document delimiter + + + + + Single-quoted here document + + + + + Double-quoted here document + + + + + Backtick here document + + + + + Quoted string (q) + + + + + Quoted string (qq) + + + + + Quoted string (qx) + + + + + Quoted string (qr) + + + + + Quoted string (qw) + + + + + POD verbatim + + + + + Subroutine prototype + + + + + Format identifier + + + + + Format body + + + + + Double-quoted string (interpolated variable) + + + + + Translation + + + + + Regular expression (interpolated variable) + + + + + Substitution (interpolated variable) + + + + + Backticks (interpolated variable) + + + + + Double-quoted here document (interpolated variable) + + + + + Backtick here document (interpolated variable) + + + + + Quoted string (qq, interpolated variable) + + + + + Quoted string (qx, interpolated variable) + + + + + Quoted string (qr, interpolated variable) + + + + + QsciScintilla + + + &Undo + Ð’&ернути + + + + &Redo + П&овторити + + + + Cu&t + Виріза&ти + + + + &Copy + &Копіювати + + + + &Paste + + + + + Delete + + + + + Select All + + documentation_dock_widget @@ -58,19 +697,19 @@ file_editor - + Octave Editor - + Octave Files (*.m);;All Files (*) - + Could not open file %1 for read: %2. @@ -93,7 +732,7 @@ - + &New File &Створити @@ -108,12 +747,12 @@ &Зберегти - + Save File &As Зберегти &Ñк - + Print @@ -143,17 +782,17 @@ - + &Next Bookmark До &наÑтупної закладки - + Pre&vious Bookmark До &попередньої закладки - + Toggle &Bookmark Ð’&Ñтановити/видалити закладку @@ -193,27 +832,27 @@ - + &Recent Editor Files - + &Close + + Close All + + + - Close All - - - - Close Other Files - + &Find and Replace @@ -228,12 +867,12 @@ - + &File &Файл - + &Edit &Правка @@ -278,14 +917,14 @@ - + Octave Editor - + The file %1 is about to be closed but has been modified. @@ -293,7 +932,7 @@ - + Octave Files (*.m);;All Files (*) @@ -319,13 +958,13 @@ - + Could not open file %1 for write: %2. - + It seems that '%1' has been modified by another application. Do you want to reload it? @@ -475,7 +1114,7 @@ - Are you sre you want to delete + Are you sure you want to delete @@ -485,12 +1124,12 @@ - + Set directory of file browser - + Create File @@ -585,7 +1224,7 @@ - + Search from end @@ -708,12 +1347,12 @@ - + Search results - + Idle. @@ -748,7 +1387,7 @@ - + Searching... @@ -761,7 +1400,7 @@ find_files_model - + Filename @@ -774,7 +1413,7 @@ history_dock_widget - + Browse and search the command history. ПереглÑд Ñ– пошук Ñеред Ñ–Ñторії виконаних команд. @@ -812,23 +1451,23 @@ main_window - + Load Workspace Завантажити облаÑÑ‚ÑŒ змінних - - + + About Octave Про Octave - + &File &Файл - + New @@ -838,7 +1477,7 @@ - + Function @@ -848,12 +1487,12 @@ - + Open... - + Preferences... @@ -863,7 +1502,7 @@ Вийти - + &Edit &Правка @@ -878,28 +1517,33 @@ - + Paste - - + + Save Workspace As - + Set working directory - + + Clear Clipboard + + + + Find Files... - + Clear Command Window @@ -914,7 +1558,7 @@ - + De&bug @@ -959,7 +1603,27 @@ - + + Octave Packages + + + + + Share Code + + + + + Contribute to Octave + + + + + Octave Developer Resources + + + + On Disk @@ -989,12 +1653,12 @@ - + Load workspace - + &Window @@ -1045,12 +1709,12 @@ - + Documentation Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ñ–Ñ - + &Help @@ -1059,39 +1723,25 @@ Report Bug Повідомити про помилку - - - Visit Agora - - - - - Visit Octave Forge - - octave_dock_widget + Undock widget - + Hide widget - + Dock widget - - - Unock widget - - octave_qscintilla @@ -1157,12 +1807,7 @@ - - Graphic icons - - - - + Editor Редактор @@ -1272,12 +1917,12 @@ - + Font - + Show line numbers @@ -1297,7 +1942,12 @@ - + + Graphic icons + + + + emacs emacs @@ -1317,7 +1967,7 @@ - + Font size @@ -1387,7 +2037,7 @@ - + Icon set for dock widgets @@ -1402,7 +2052,7 @@ - + Socks5Proxy @@ -1434,8 +2084,23 @@ - - Difference to the defalt size + + IBeam Cursor + + + + + Block Cursor + + + + + Underline Cursor + + + + + Difference to the default size @@ -1470,7 +2135,7 @@ webinfo - + Type here and press 'Return' to search @@ -1483,48 +2148,38 @@ welcome_wizard - + Welcome to GNU Octave - - It appears that you have launched Octave GUI for the first time on this computer, since no configuration file could be found at '~/.octave-gui'. This wizard will guide you through the essential settings you should make before you can start using Octave GUI. If you want to transfer your settings you have previously made just close this dialog and copy over the settings file to your home folder. The presence of that file will automatically be detected and will skip this wizard. IMPORTANT: This wizard is not fully functional yet. Just click your way to the end and it will create a standard settings file. + + You seem to be using the Octave graphical interface for the first time on this computer. Click 'Finish' to write a configuration file and launch Octave GUI. + + + + + The configuration file is stored in __%1__. If that file exists, you will not see this dialog when Octave starts again. - - - - - Next + + <html><head/><body><p>For more information about Octave,</p> +<ul> +<li>visit <a href="http://octave.org"><span style=" text-decoration: underline; color:#0000ff;">http://octave.org</span></a>,</li> +<li> get the documentation online as <a href="http://www.gnu.org/software/octave/doc/interpreter/index.html"><span style=" text-decoration: underline; color:#0000ff;">html</span></a>- or <a href="http://www.gnu.org/software/octave/octave.pdf"><span style=" text-decoration: underline; color:#0000ff;">pdf</span></a>-document, or</li> +<li>open the documentation browser of Octave GUI with the help menu.</li> +</ul> +</body></html> - - - - - Previous - - - - + Welcome to Octave! - - This is the development version of Octave with the first official GUI. - - - - - You seem to run Octave GUI for the first time on this computer. This assistant will help you to configure this software installation. Click 'Finish' to write a configuration file and launch Octave GUI. - - - - + Finish diff -r 20d1b911b4e7 -r c702371ff6df libgui/qterminal/libqterminal/QTerminal.cc --- a/libgui/qterminal/libqterminal/QTerminal.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/qterminal/libqterminal/QTerminal.cc Sat Oct 05 11:22:09 2013 -0400 @@ -77,11 +77,10 @@ // Set terminal font: QFont term_font = QFont (); + term_font.setStyleHint (QFont::TypeWriter); term_font.setFamily (settings->value ("terminal/fontName", "Courier New").toString ()); - term_font.setPointSize (settings->value ("terminal/fontSize", 10).toInt ()); - setTerminalFont (term_font); QString cursorType diff -r 20d1b911b4e7 -r c702371ff6df libgui/qterminal/libqterminal/unix/Screen.cpp --- a/libgui/qterminal/libqterminal/unix/Screen.cpp Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/qterminal/libqterminal/unix/Screen.cpp Sat Oct 05 11:22:09 2013 -0400 @@ -788,8 +788,8 @@ lastPos = loc(cuX,cuY); - // check if selection is still valid. - checkSelection(cuX,cuY); + // clear selection on text input + clearSelection (); Character& currentChar = screenLines[cuY][cuX]; diff -r 20d1b911b4e7 -r c702371ff6df libgui/qterminal/libqterminal/unix/TerminalView.cpp --- a/libgui/qterminal/libqterminal/unix/TerminalView.cpp Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/qterminal/libqterminal/unix/TerminalView.cpp Sat Oct 05 11:22:09 2013 -0400 @@ -319,6 +319,10 @@ _gridLayout->setMargin(0); setLayout( _gridLayout ); + + connect (this, SIGNAL (set_global_shortcuts_signal (bool)), + parent->parent (), SLOT (set_global_shortcuts (bool))); + } TerminalView::~TerminalView() @@ -1058,6 +1062,8 @@ void TerminalView::focusInEvent(QFocusEvent *focusEvent) { + emit set_global_shortcuts_signal (false); // disable some shortcuts + setBlinkingCursorState(true); updateImage(); repaint(); @@ -1068,6 +1074,8 @@ void TerminalView::focusOutEvent(QFocusEvent *focusEvent) { + emit set_global_shortcuts_signal (true); // re-enable shortcuts + // Force the cursor to be redrawn. _cursorBlinking = true; setBlinkingCursorState(false); @@ -2267,9 +2275,6 @@ if (text.isEmpty ()) { - // FIXME -- interrupt is only appropriate here if CTRL-C is bound - // to the copy action. How can we determine that? - ::raise (SIGINT); } else diff -r 20d1b911b4e7 -r c702371ff6df libgui/qterminal/libqterminal/unix/TerminalView.h --- a/libgui/qterminal/libqterminal/unix/TerminalView.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/qterminal/libqterminal/unix/TerminalView.h Sat Oct 05 11:22:09 2013 -0400 @@ -476,6 +476,12 @@ void tripleClicked( const QString& text ); + /** + * Emitted when focus changes + */ + void set_global_shortcuts_signal (bool); + + protected: virtual bool event( QEvent * ); diff -r 20d1b911b4e7 -r c702371ff6df libgui/qterminal/libqterminal/win32/QWinTerminalImpl.cpp --- a/libgui/qterminal/libqterminal/win32/QWinTerminalImpl.cpp Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/qterminal/libqterminal/win32/QWinTerminalImpl.cpp Sat Oct 05 11:22:09 2013 -0400 @@ -40,7 +40,9 @@ #include #include #define WIN32_LEAN_AND_MEAN -#define _WIN32_WINNT 0x0500 +#if ! defined (_WIN32_WINNT) && ! defined (NTDDI_VERSION) +#define _WIN32_WINNT 0x0500 +#endif #include #include #include @@ -92,6 +94,68 @@ ////////////////////////////////////////////////////////////////////////////// +static QString translateKey (QKeyEvent *ev) +{ + QString esc = "\x1b"; + QString s; + + if (ev->key () == Qt::Key_Delete) + s = esc + "[C\b"; + else if (!ev->text ().isEmpty ()) + s = ev->text (); + else + { + + switch (ev->key ()) + { + case Qt::Key_Up: + s = esc + "[A"; + break; + + case Qt::Key_Down: + s = esc + "[B"; + break; + + case Qt::Key_Right: + s = esc + "[C"; + break; + + case Qt::Key_Left: + s = esc + "[D"; + break; + + case Qt::Key_Home: + s = esc + "[H"; + break; + + case Qt::Key_End: + s = esc + "[F"; + break; + + case Qt::Key_Insert: + s = esc + "[2~"; + break; + + case Qt::Key_PageUp: + s = esc + "[5~"; + break; + + case Qt::Key_PageDown: + s = esc + "[6~"; + break; + + case Qt::Key_Escape: + s = esc; + break; + + default: + break; + } + } + + return s; +} + class QConsolePrivate { friend class QWinTerminalImpl; @@ -1099,6 +1163,9 @@ #define TEXT_CHUNK_SIZE 512 + // clear any selection on inserting text + clearSelection(); + int len = s.length (); INPUT_RECORD events[TEXT_CHUNK_SIZE]; DWORD nEvents = 0, written; @@ -1162,6 +1229,10 @@ QWinTerminalImpl::QWinTerminalImpl (QWidget* parent) : QTerminal (parent), d (new QConsolePrivate (this)) { + installEventFilter (this); + + connect (this, SIGNAL (set_global_shortcuts_signal (bool)), + parent, SLOT (set_global_shortcuts (bool))); } ////////////////////////////////////////////////////////////////////////////// @@ -1290,27 +1361,6 @@ ////////////////////////////////////////////////////////////////////////////// -bool QWinTerminalImpl::winEvent (MSG* msg, long* result) -{ - switch (msg->message) - { - case WM_KEYDOWN: - case WM_KEYUP: - //case WM_CHAR: - // Forward Win32 message to the console window - PostMessage (d->m_consoleWindow, - msg->message, - msg->wParam, - msg->lParam); - result = 0; - return true; - default: - return false; - } -} - -////////////////////////////////////////////////////////////////////////////// - void QWinTerminalImpl::scrollValueChanged (int value) { d->setScrollValue (value); @@ -1332,6 +1382,8 @@ void QWinTerminalImpl::focusInEvent (QFocusEvent* event) { + emit set_global_shortcuts_signal (false); // disable some shortcuts + setBlinkingCursorState (true); QWidget::focusInEvent (event); @@ -1339,6 +1391,8 @@ void QWinTerminalImpl::focusOutEvent (QFocusEvent* event) { + emit set_global_shortcuts_signal (true); // re-enable shortcuts + // Force the cursor to be redrawn. d->m_cursorBlinking = true; @@ -1347,8 +1401,28 @@ QWidget::focusOutEvent (event); } +bool QWinTerminalImpl::eventFilter (QObject *obj, QEvent * event) +{ + // if a keypress, filter out tab keys so that the next/prev tabbing is + // disabled - but we still need to pass along to the console . + if (event->type () == QEvent::KeyPress) + { + QKeyEvent* k = static_cast(event); + if (k->key () == Qt::Key_Tab) + { + sendText ("\t"); + return true; + } + } + return false; +} + void QWinTerminalImpl::keyPressEvent (QKeyEvent* event) { + QString s = translateKey (event); + if (!s.isEmpty ()) + sendText (s); + if (d->m_hasBlinkingCursor) { d->m_blinkCursorTimer->start (d->BLINK_DELAY); diff -r 20d1b911b4e7 -r c702371ff6df libgui/qterminal/libqterminal/win32/QWinTerminalImpl.h --- a/libgui/qterminal/libqterminal/win32/QWinTerminalImpl.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/qterminal/libqterminal/win32/QWinTerminalImpl.h Sat Oct 05 11:22:09 2013 -0400 @@ -70,6 +70,7 @@ signals: void terminated (void); void titleChanged (const QString&); + void set_global_shortcuts_signal (bool); protected: void viewPaintEvent (QConsoleView*, QPaintEvent*); @@ -80,12 +81,13 @@ void focusInEvent (QFocusEvent*); void focusOutEvent (QFocusEvent*); void keyPressEvent (QKeyEvent*); - bool winEvent (MSG*, long*); virtual void start (void); void mouseMoveEvent (QMouseEvent *event); void mousePressEvent (QMouseEvent *event); void mouseReleaseEvent (QMouseEvent *event); + bool eventFilter(QObject *obj, QEvent *ev); + private slots: void scrollValueChanged (int value); void monitorConsole (void); diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/dialog.cc --- a/libgui/src/dialog.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/dialog.cc Sat Oct 05 11:22:09 2013 -0400 @@ -420,7 +420,7 @@ buttonCancel_clicked (); } -FileDialog::FileDialog (const QStringList& filters, const QString& title, +FileDialog::FileDialog (const QStringList& name_filters, const QString& title, const QString& filename, const QString& dirname, const QString& multimode) : QFileDialog() @@ -456,7 +456,7 @@ setAcceptMode (QFileDialog::AcceptOpen); } - setNameFilters (filters); + setNameFilters (name_filters); selectFile (filename); @@ -493,8 +493,8 @@ path = directory ().absolutePath (); - QStringList filters = nameFilters (); - idx = filters.indexOf (selectedNameFilter ()) + 1; + QStringList name_filters = nameFilters (); + idx = name_filters.indexOf (selectedNameFilter ()) + 1; // send the selected info emit finish_input (string_result, path, idx); diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/documentation-dock-widget.cc --- a/libgui/src/documentation-dock-widget.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/documentation-dock-widget.cc Sat Oct 05 11:22:09 2013 -0400 @@ -36,6 +36,9 @@ _webinfo = new webinfo (this); setWidget (_webinfo); + + connect (p, SIGNAL(show_doc_signal(const QString &)), + this, SLOT(showDoc(const QString &))); } void @@ -48,3 +51,15 @@ { _webinfo->pasteClipboard (); } +void +documentation_dock_widget::showDoc (const QString &name) +{ + // show the doc pane + if (!isVisible ()) + setVisible (true); + setFocus (); + raise (); + + _webinfo->load_ref (name); + +} diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/documentation-dock-widget.h --- a/libgui/src/documentation-dock-widget.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/documentation-dock-widget.h Sat Oct 05 11:22:09 2013 -0400 @@ -39,6 +39,7 @@ void copyClipboard (); void pasteClipboard (); + void showDoc (const QString & name); private: webinfo *_webinfo; diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/files-dock-widget.cc --- a/libgui/src/files-dock-widget.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/files-dock-widget.cc Sat Oct 05 11:22:09 2013 -0400 @@ -636,7 +636,10 @@ void files_dock_widget::popdownmenu_home (bool) { - QString dir = QDir::homePath (); + QString dir = qgetenv ("HOME"); + if (dir.isEmpty()) + dir = QDir::homePath (); + set_current_directory (dir); } @@ -644,7 +647,8 @@ files_dock_widget::popdownmenu_search_dir (bool) { QString dir = QFileDialog::getExistingDirectory - (this, tr ("Set directory of file browser"),_file_system_model->rootPath()); + (this, tr ("Set directory of file browser"),_file_system_model->rootPath(), + QFileDialog::DontUseNativeDialog); set_current_directory (dir); } diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/find-files-dialog.cc --- a/libgui/src/find-files-dialog.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/find-files-dialog.cc Sat Oct 05 11:22:09 2013 -0400 @@ -96,7 +96,8 @@ _content_case_check->setChecked (settings->value ("findfiles/content_case", false).toBool()); _content_case_check->setToolTip (tr ("Set text content is case insensitive")); - find_files_model * model = new find_files_model (); + find_files_model * model = new find_files_model (this); + _file_list = new QTableView; _file_list->setWordWrap (false); _file_list->setModel (model); @@ -105,7 +106,10 @@ _file_list->setSelectionMode(QAbstractItemView::SingleSelection); _file_list->setAlternatingRowColors(true); _file_list->setToolTip (tr ("Search results")); + _file_list->setSortingEnabled (true); _file_list->horizontalHeader ()->restoreState (settings->value ("findfiles/column_state").toByteArray ()); + _file_list->horizontalHeader ()->setSortIndicatorShown (true); + _file_list->horizontalHeader ()->setClickable (true); _file_list->horizontalHeader ()->setStretchLastSection (true); _file_list->sortByColumn ( settings->value ("findfiles/sort_files_by_column",0).toInt (), diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/find-files-model.cc --- a/libgui/src/find-files-model.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/find-files-model.cc Sat Oct 05 11:22:09 2013 -0400 @@ -22,12 +22,60 @@ #include "find-files-model.h" #include +#include + +class find_file_less_than +{ +public: + find_file_less_than (int ord) + { + _sortorder = ord; + } + QVariant getValue (const QFileInfo &f) const + { + QVariant val; + int col = (_sortorder > 0) ? _sortorder : -_sortorder; + + switch (col-1) + { + case 0: + val = QVariant (f.fileName()); + break; + + case 1: + val = QVariant (f.absolutePath()); + break; + + default: + break; + } + return val; + } + bool lessThan (const QVariant &left, const QVariant &right) const + { + return left.toString ().compare (right.toString (), Qt::CaseInsensitive) < 0; + } + bool operator () (const QFileInfo &left, const QFileInfo &right) const + { + QVariant leftval = getValue(left); + QVariant rightval = getValue(right); + + if (_sortorder > 0) + return lessThan(leftval, rightval); + else + return ! lessThan(leftval, rightval); + } +private: + int _sortorder; +}; + find_files_model::find_files_model (QObject *p) : QAbstractListModel(p) { _columnNames.append (tr ("Filename")); _columnNames.append (tr ("Directory")); + _sortorder = 0; } find_files_model::~find_files_model () @@ -47,21 +95,29 @@ void find_files_model::addFile (const QFileInfo &info) { - beginInsertRows(QModelIndex(), _files.size(), _files.size() ); + beginInsertRows (QModelIndex (), _files.size (), _files.size () ); + + QList::Iterator it; + find_file_less_than less_than(_sortorder); - _files.append(info); + for (it=_files.begin ();it!=_files.end ();it++) + { + if (less_than (info, *it)) break; + } - endInsertRows(); + _files.insert (it, info); + + endInsertRows (); } int -find_files_model::rowCount (const QModelIndex & p) const +find_files_model::rowCount (const QModelIndex &) const { return _files.size(); } int -find_files_model::columnCount (const QModelIndex & p) const +find_files_model::columnCount (const QModelIndex &) const { return _columnNames.size (); } @@ -113,6 +169,27 @@ return QVariant (); } +void +find_files_model::sort (int column, Qt::SortOrder order) +{ + if(column >= 0) + { + if (order == Qt::DescendingOrder) + _sortorder = -(column+1); + else + _sortorder = column+1; + } + else + _sortorder = 0; + + if (_sortorder != 0) + { + beginResetModel (); + qSort (_files.begin (), _files.end (), find_file_less_than (_sortorder)); + endResetModel (); + } +} + QFileInfo find_files_model::fileInfo (const QModelIndex & p) const { diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/find-files-model.h --- a/libgui/src/find-files-model.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/find-files-model.h Sat Oct 05 11:22:09 2013 -0400 @@ -50,11 +50,14 @@ QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + void sort (int column, Qt::SortOrder order=Qt::AscendingOrder); + QFileInfo fileInfo (const QModelIndex & p) const; QIcon fileIcon (const QModelIndex &p) const; private: QList _files; QStringList _columnNames; + int _sortorder; }; #endif // find_files_model_h diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/history-dock-widget.cc --- a/libgui/src/history-dock-widget.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/history-dock-widget.cc Sat Oct 05 11:22:09 2013 -0400 @@ -28,6 +28,7 @@ #include #include #include +#include #include "error.h" @@ -104,11 +105,17 @@ QItemSelectionModel *selectionModel = _history_list_view->selectionModel(); QModelIndexList rows = selectionModel->selectedRows(); QModelIndexList::iterator it; - for (it=rows.begin() ; it != rows.end(); it++) { - if ((*it).isValid()) { - text += (*it).data().toString()+"\n"; + bool prev_valid_row = false; + for (it = rows.begin(); it != rows.end(); it++) + { + if ((*it).isValid()) + { + if (prev_valid_row) + text += "\n"; + text += (*it).data().toString(); + prev_valid_row = true; + } } - } QApplication::clipboard()->setText(text); } @@ -117,11 +124,11 @@ QItemSelectionModel *selectionModel = _history_list_view->selectionModel(); QModelIndexList rows = selectionModel->selectedRows(); QModelIndexList::iterator it; - for (it=rows.begin() ; it != rows.end(); it++) { - if ((*it).isValid()) { - emit command_double_clicked ((*it).data().toString()+"\n"); + for (it = rows.begin() ; it != rows.end(); it++) + { + if ((*it).isValid()) + emit command_double_clicked ((*it).data().toString()); } - } } void @@ -131,10 +138,16 @@ QItemSelectionModel *selectionModel = _history_list_view->selectionModel (); QModelIndexList rows = selectionModel->selectedRows (); + bool prev_valid_row = false; for (QModelIndexList::iterator it = rows.begin (); it != rows.end (); it++) { if ((*it).isValid ()) - text += (*it).data().toString() + "\n"; + { + if (prev_valid_row) + text += "\n"; + text += (*it).data().toString(); + prev_valid_row = true; + } } if (text.length () > 0) @@ -145,7 +158,7 @@ void history_dock_widget::handle_double_click (QModelIndex modelIndex) { - emit command_double_clicked (modelIndex.data().toString()+"\n"); + emit command_double_clicked (modelIndex.data().toString()); } void @@ -160,8 +173,16 @@ { QStringList lst = _history_model->stringList (); lst.append (hist_entry); + + QScrollBar *scroll_bar = _history_list_view->verticalScrollBar (); + + bool at_bottom = scroll_bar->maximum () - scroll_bar->value () < 1; + _history_model->setStringList (lst); - _history_list_view->scrollToBottom (); + + // Scroll if slider position at bottom. + if (at_bottom) + _history_list_view->scrollToBottom (); } void @@ -186,11 +207,11 @@ history_dock_widget::pasteClipboard () { if(_filter_line_edit->hasFocus ()) - { - QClipboard *clipboard = QApplication::clipboard (); - QString str = clipboard->text (); - if (str.length() > 0) - _filter_line_edit->insert (str); - } + { + QClipboard *clipboard = QApplication::clipboard (); + QString str = clipboard->text (); + if (str.length() > 0) + _filter_line_edit->insert (str); + } } diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/m-editor/file-editor-tab.cc --- a/libgui/src/m-editor/file-editor-tab.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/m-editor/file-editor-tab.cc Sat Oct 05 11:22:09 2013 -0400 @@ -1010,6 +1010,11 @@ else fileDialog = new QFileDialog (this); + // Giving trouble under KDE (problem is related to Qt signal handling on unix, + // see https://bugs.kde.org/show_bug.cgi?id=260719 , + // it had/has no effect on Windows, though) + fileDialog->setOption(QFileDialog::DontUseNativeDialog, true); + if (!_file_name.isEmpty () && _file_name.at (_file_name.count () - 1) != '/') { fileDialog->selectFile (_file_name); diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/m-editor/file-editor.cc --- a/libgui/src/m-editor/file-editor.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/m-editor/file-editor.cc Sat Oct 05 11:22:09 2013 -0400 @@ -176,6 +176,12 @@ // Create a NonModal message. QFileDialog *fileDialog = new QFileDialog (this); fileDialog->setNameFilter (tr ("Octave Files (*.m);;All Files (*)")); + + // Giving trouble under KDE (problem is related to Qt signal handling on unix, + // see https://bugs.kde.org/show_bug.cgi?id=260719 , + // it had/has no effect on Windows, though) + fileDialog->setOption(QFileDialog::DontUseNativeDialog, true); + fileDialog->setAcceptMode (QFileDialog::AcceptOpen); fileDialog->setViewMode (QFileDialog::Detail); fileDialog->setDirectory (ced); @@ -668,6 +674,7 @@ } } } + check_actions (); } void @@ -738,21 +745,19 @@ QAction *open_action = new QAction (QIcon (":/actions/icons/fileopen.png"), tr ("&Open File"), _tool_bar); - QAction *save_action = new QAction (QIcon (":/actions/icons/filesave.png"), + _save_action = new QAction (QIcon (":/actions/icons/filesave.png"), tr ("&Save File"), _tool_bar); - QAction *save_as_action - = new QAction (QIcon (":/actions/icons/filesaveas.png"), - tr ("Save File &As"), _tool_bar); + _save_as_action = new QAction (QIcon (":/actions/icons/filesaveas.png"), + tr ("Save File &As"), _tool_bar); - QAction *print_action - = new QAction ( QIcon (":/actions/icons/fileprint.png"), - tr ("Print"), _tool_bar); + _print_action = new QAction ( QIcon (":/actions/icons/fileprint.png"), + tr ("Print"), _tool_bar); - QAction *undo_action = new QAction (QIcon (":/actions/icons/undo.png"), + _undo_action = new QAction (QIcon (":/actions/icons/undo.png"), tr ("&Undo"), _tool_bar); - QAction *redo_action = new QAction (QIcon (":/actions/icons/redo.png"), + _redo_action = new QAction (QIcon (":/actions/icons/redo.png"), tr ("&Redo"), _tool_bar); _copy_action = new QAction (QIcon (":/actions/icons/editcopy.png"), @@ -761,20 +766,17 @@ _cut_action = new QAction (QIcon (":/actions/icons/editcut.png"), tr ("Cu&t"), _tool_bar); - QAction *paste_action + _paste_action = new QAction (QIcon (":/actions/icons/editpaste.png"), tr ("Paste"), _tool_bar); - QAction *next_bookmark_action - = new QAction (tr ("&Next Bookmark"), _tool_bar); + _next_bookmark_action = new QAction (tr ("&Next Bookmark"), _tool_bar); + + _previous_bookmark_action = new QAction (tr ("Pre&vious Bookmark"), _tool_bar); - QAction *previous_bookmark_action - = new QAction (tr ("Pre&vious Bookmark"), _tool_bar); + _toggle_bookmark_action = new QAction (tr ("Toggle &Bookmark"), _tool_bar); - QAction *toggle_bookmark_action - = new QAction (tr ("Toggle &Bookmark"), _tool_bar); - - QAction *remove_bookmark_action + _remove_bookmark_action = new QAction (tr ("&Remove All Bookmarks"), _tool_bar); QAction *next_breakpoint_action @@ -790,19 +792,19 @@ = new QAction (QIcon (":/actions/icons/bp_rm_all.png"), tr ("&Remove All breakpoints"), _tool_bar); - QAction *comment_selection_action + _comment_selection_action = new QAction (tr ("&Comment"), _tool_bar); - QAction *uncomment_selection_action + _uncomment_selection_action = new QAction (tr ("&Uncomment"), _tool_bar); - QAction *find_action = new QAction (QIcon (":/actions/icons/search.png"), + _find_action = new QAction (QIcon (":/actions/icons/search.png"), tr ("&Find and Replace"), _tool_bar); _run_action = new QAction (QIcon (":/actions/icons/artsbuilderexecute.png"), tr ("Save File And Run"), _tool_bar); - QAction *goto_line_action = new QAction (tr ("Go&to Line"), _tool_bar); + _goto_line_action = new QAction (tr ("Go&to Line"), _tool_bar); // the mru-list and an empty array of actions QSettings *settings = resource_manager::get_settings (); @@ -817,46 +819,36 @@ // some actions are disabled from the beginning _copy_action->setEnabled (false); _cut_action->setEnabled (false); - _run_action->setShortcut (Qt::ControlModifier+ Qt::Key_R); + _run_action->setShortcutContext (Qt::WindowShortcut); - save_action->setShortcut (QKeySequence::Save); - save_action->setShortcutContext (Qt::WindowShortcut); - save_as_action->setShortcut (QKeySequence::SaveAs); - save_as_action->setShortcutContext (Qt::WindowShortcut); + _save_action->setShortcutContext (Qt::WindowShortcut); + _save_as_action->setShortcutContext (Qt::WindowShortcut); - print_action->setShortcut (QKeySequence::Print); - print_action->setShortcutContext (Qt::WindowShortcut); + _print_action->setShortcutContext (Qt::WindowShortcut); - next_bookmark_action->setShortcut (Qt::Key_F2); - next_bookmark_action->setShortcutContext (Qt::WindowShortcut); - previous_bookmark_action->setShortcut (Qt::SHIFT + Qt::Key_F2); - previous_bookmark_action->setShortcutContext (Qt::WindowShortcut); - toggle_bookmark_action->setShortcut (Qt::Key_F7); - toggle_bookmark_action->setShortcutContext (Qt::WindowShortcut); - comment_selection_action->setShortcut (Qt::ControlModifier + Qt::Key_7); - comment_selection_action->setShortcutContext (Qt::WindowShortcut); - uncomment_selection_action->setShortcut (Qt::ControlModifier + Qt::Key_8); - uncomment_selection_action->setShortcutContext (Qt::WindowShortcut); - find_action->setShortcut (QKeySequence::Find); - find_action->setShortcutContext (Qt::WindowShortcut); - goto_line_action->setShortcut (Qt::ControlModifier+ Qt::Key_G); - goto_line_action->setShortcutContext (Qt::WindowShortcut); + _next_bookmark_action->setShortcutContext (Qt::WindowShortcut); + _previous_bookmark_action->setShortcutContext (Qt::WindowShortcut); + _toggle_bookmark_action->setShortcutContext (Qt::WindowShortcut); + _comment_selection_action->setShortcutContext (Qt::WindowShortcut); + _uncomment_selection_action->setShortcutContext (Qt::WindowShortcut); + _find_action->setShortcutContext (Qt::WindowShortcut); + _goto_line_action->setShortcutContext (Qt::WindowShortcut); // toolbar _tool_bar->addAction (new_action); _tool_bar->addAction (open_action); - _tool_bar->addAction (save_action); - _tool_bar->addAction (save_as_action); + _tool_bar->addAction (_save_action); + _tool_bar->addAction (_save_as_action); _tool_bar->addSeparator (); - _tool_bar->addAction (print_action); + _tool_bar->addAction (_print_action); _tool_bar->addSeparator (); - _tool_bar->addAction (undo_action); - _tool_bar->addAction (redo_action); + _tool_bar->addAction (_undo_action); + _tool_bar->addAction (_redo_action); _tool_bar->addAction (_copy_action); _tool_bar->addAction (_cut_action); - _tool_bar->addAction (paste_action); + _tool_bar->addAction (_paste_action); _tool_bar->addSeparator (); - _tool_bar->addAction (find_action); + _tool_bar->addAction (_find_action); _tool_bar->addAction (_run_action); _tool_bar->addSeparator (); _tool_bar->addAction (toggle_breakpoint_action); @@ -876,49 +868,50 @@ fileMenu->addMenu (_mru_file_menu); fileMenu->addSeparator (); - fileMenu->addAction (save_action); - fileMenu->addAction (save_as_action); + fileMenu->addAction (_save_action); + fileMenu->addAction (_save_as_action); fileMenu->addSeparator (); - fileMenu->addAction (QIcon::fromTheme("window-close", - QIcon (":/actions/icons/fileclose.png")), - tr ("&Close"), - this, SLOT (request_close_file (bool)), - QKeySequence::Close); - fileMenu->addAction (QIcon::fromTheme("window-close", + _close_action = + fileMenu->addAction (QIcon::fromTheme("window-close", + QIcon (":/actions/icons/fileclose.png")), + tr ("&Close"), this, SLOT (request_close_file (bool))); + _close_all_action = + fileMenu->addAction (QIcon::fromTheme("window-close", QIcon (":/actions/icons/fileclose.png")), tr ("Close All"), this, SLOT (request_close_all_files (bool))); + _close_others_action = fileMenu->addAction (QIcon::fromTheme("window-close", QIcon (":/actions/icons/fileclose.png")), tr ("Close Other Files"), this, SLOT (request_close_other_files (bool))); fileMenu->addSeparator (); - fileMenu->addAction (print_action); + fileMenu->addAction (_print_action); _menu_bar->addMenu (fileMenu); QMenu *editMenu = new QMenu (tr ("&Edit"), _menu_bar); - editMenu->addAction (undo_action); - editMenu->addAction (redo_action); + editMenu->addAction (_undo_action); + editMenu->addAction (_redo_action); editMenu->addSeparator (); editMenu->addAction (_copy_action); editMenu->addAction (_cut_action); - editMenu->addAction (paste_action); + editMenu->addAction (_paste_action); editMenu->addSeparator (); - editMenu->addAction (find_action); + editMenu->addAction (_find_action); editMenu->addSeparator (); - editMenu->addAction (comment_selection_action); - editMenu->addAction (uncomment_selection_action); + editMenu->addAction (_comment_selection_action); + editMenu->addAction (_uncomment_selection_action); editMenu->addSeparator (); - editMenu->addAction (toggle_bookmark_action); - editMenu->addAction (next_bookmark_action); - editMenu->addAction (previous_bookmark_action); - editMenu->addAction (remove_bookmark_action); + editMenu->addAction (_toggle_bookmark_action); + editMenu->addAction (_next_bookmark_action); + editMenu->addAction (_previous_bookmark_action); + editMenu->addAction (_remove_bookmark_action); editMenu->addSeparator (); - editMenu->addAction (goto_line_action); + editMenu->addAction (_goto_line_action); _menu_bar->addMenu (editMenu); _debug_menu = new QMenu (tr ("&Debug"), _menu_bar); @@ -934,6 +927,10 @@ _run_menu->addAction (_run_action); _menu_bar->addMenu (_run_menu); + // shortcuts + set_shortcuts (true); + + // layout QVBoxLayout *vbox_layout = new QVBoxLayout (); vbox_layout->addWidget (_menu_bar); vbox_layout->addWidget (_tool_bar); @@ -942,6 +939,7 @@ editor_widget->setLayout (vbox_layout); setWidget (editor_widget); + // signals connect (main_win (), SIGNAL (new_file_signal (const QString&)), this, SLOT (request_new_file (const QString&))); @@ -954,10 +952,10 @@ connect (open_action, SIGNAL (triggered ()), this, SLOT (request_open_file ())); - connect (undo_action, SIGNAL (triggered ()), + connect (_undo_action, SIGNAL (triggered ()), this, SLOT (request_undo ())); - connect (redo_action, SIGNAL (triggered ()), + connect (_redo_action, SIGNAL (triggered ()), this, SLOT (request_redo ())); connect (_copy_action, SIGNAL (triggered ()), @@ -966,31 +964,31 @@ connect (_cut_action, SIGNAL (triggered ()), this, SLOT (request_cut ())); - connect (paste_action, SIGNAL (triggered ()), + connect (_paste_action, SIGNAL (triggered ()), this, SLOT (request_paste ())); - connect (save_action, SIGNAL (triggered ()), + connect (_save_action, SIGNAL (triggered ()), this, SLOT (request_save_file ())); - connect (save_as_action, SIGNAL (triggered ()), + connect (_save_as_action, SIGNAL (triggered ()), this, SLOT (request_save_file_as ())); - connect (print_action, SIGNAL (triggered ()), + connect (_print_action, SIGNAL (triggered ()), this, SLOT (request_print_file ())); connect (_run_action, SIGNAL (triggered ()), this, SLOT (request_run_file ())); - connect (toggle_bookmark_action, SIGNAL (triggered ()), + connect (_toggle_bookmark_action, SIGNAL (triggered ()), this, SLOT (request_toggle_bookmark ())); - connect (next_bookmark_action, SIGNAL (triggered ()), + connect (_next_bookmark_action, SIGNAL (triggered ()), this, SLOT (request_next_bookmark ())); - connect (previous_bookmark_action, SIGNAL (triggered ()), + connect (_previous_bookmark_action, SIGNAL (triggered ()), this, SLOT (request_previous_bookmark ())); - connect (remove_bookmark_action, SIGNAL (triggered ()), + connect (_remove_bookmark_action, SIGNAL (triggered ()), this, SLOT (request_remove_bookmark ())); connect (toggle_breakpoint_action, SIGNAL (triggered ()), @@ -1005,16 +1003,16 @@ connect (remove_all_breakpoints_action, SIGNAL (triggered ()), this, SLOT (request_remove_breakpoint ())); - connect (comment_selection_action, SIGNAL (triggered ()), + connect (_comment_selection_action, SIGNAL (triggered ()), this, SLOT (request_comment_selected_text ())); - connect (uncomment_selection_action, SIGNAL (triggered ()), + connect (_uncomment_selection_action, SIGNAL (triggered ()), this, SLOT (request_uncomment_selected_text ())); - connect (find_action, SIGNAL (triggered ()), + connect (_find_action, SIGNAL (triggered ()), this, SLOT (request_find ())); - connect (goto_line_action, SIGNAL (triggered ()), + connect (_goto_line_action, SIGNAL (triggered ()), this, SLOT (request_goto_line ())); connect (_mru_file_menu, SIGNAL (triggered (QAction *)), @@ -1041,6 +1039,8 @@ for (int n = 0; n < sessionFileNames.count (); ++n) request_open_file (sessionFileNames.at (n)); } + + check_actions (); } void @@ -1169,6 +1169,8 @@ f, SLOT (do_breakpoint_marker (bool, const QWidget*, int))); _tab_widget->setCurrentWidget (f); + + check_actions (); } void @@ -1192,4 +1194,96 @@ } } +void +file_editor::set_shortcuts (bool set) +{ + if (set) + { + _comment_selection_action->setShortcut (Qt::ControlModifier + Qt::Key_7); + _uncomment_selection_action->setShortcut (Qt::ControlModifier + Qt::Key_8); + + _copy_action->setShortcut (QKeySequence::Copy); + _cut_action->setShortcut (QKeySequence::Cut); + _paste_action->setShortcut (QKeySequence::Paste); + + _find_action->setShortcut (QKeySequence::Find); + _goto_line_action->setShortcut (Qt::ControlModifier+ Qt::Key_G); + + _next_bookmark_action->setShortcut (Qt::Key_F2); + _previous_bookmark_action->setShortcut (Qt::SHIFT + Qt::Key_F2); + _toggle_bookmark_action->setShortcut (Qt::Key_F7); + + _print_action->setShortcut (QKeySequence::Print); + _run_action->setShortcut (Qt::ControlModifier+ Qt::Key_R); + + _save_action->setShortcut (QKeySequence::Save); + _save_as_action->setShortcut (QKeySequence::SaveAs); + _close_action->setShortcut (QKeySequence::Close); + + _redo_action->setShortcut (QKeySequence::Redo); + _undo_action->setShortcut (QKeySequence::Undo); + } + else + { + QKeySequence no_key = QKeySequence (); + + _comment_selection_action->setShortcut (no_key); + _uncomment_selection_action->setShortcut (no_key); + + _copy_action->setShortcut (no_key); + _cut_action->setShortcut (no_key); + _paste_action->setShortcut (no_key); + + _find_action->setShortcut (no_key); + _goto_line_action->setShortcut (no_key); + + _next_bookmark_action->setShortcut (no_key); + _previous_bookmark_action->setShortcut (no_key); + _toggle_bookmark_action->setShortcut (no_key); + + _print_action->setShortcut (no_key); + _run_action->setShortcut (no_key); + + _save_action->setShortcut (no_key); + _save_as_action->setShortcut (no_key); + _close_action->setShortcut (no_key); + + _redo_action->setShortcut (no_key); + _undo_action->setShortcut (no_key); + } +} + +void +file_editor::check_actions () +{ + bool have_tabs = _tab_widget->count () > 0; + + _comment_selection_action->setEnabled (have_tabs); + _uncomment_selection_action->setEnabled (have_tabs); + + _copy_action->setEnabled (have_tabs); + _cut_action->setEnabled (have_tabs); + _paste_action->setEnabled (have_tabs); + + _find_action->setEnabled (have_tabs); + _goto_line_action->setEnabled (have_tabs); + + _next_bookmark_action->setEnabled (have_tabs); + _previous_bookmark_action->setEnabled (have_tabs); + _toggle_bookmark_action->setEnabled (have_tabs); + + _print_action->setEnabled (have_tabs); + _run_action->setEnabled (have_tabs); + + _save_action->setEnabled (have_tabs); + _save_as_action->setEnabled (have_tabs); + _close_action->setEnabled (have_tabs); + _close_all_action->setEnabled (have_tabs); + _close_others_action->setEnabled (have_tabs && _tab_widget->count () > 1); + + _undo_action->setEnabled (have_tabs); + _redo_action->setEnabled (have_tabs); +} + + #endif diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/m-editor/file-editor.h --- a/libgui/src/m-editor/file-editor.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/m-editor/file-editor.h Sat Oct 05 11:22:09 2013 -0400 @@ -57,6 +57,7 @@ void handle_enter_debug_mode (void); void handle_exit_debug_mode (void); + void check_actions (void); signals: void fetab_settings_changed (const QSettings *settings); @@ -152,6 +153,10 @@ // Tells the editor to react on changed settings. void notice_settings (const QSettings *settings); + // Tells the ditor to dis- or enable some shortcuts + void set_shortcuts (bool set_shortcuts); + + protected slots: void copyClipboard (); void pasteClipboard (); @@ -178,10 +183,36 @@ QMenuBar *_menu_bar; QToolBar *_tool_bar; QMenu *_debug_menu; + + QAction *_comment_selection_action; + QAction *_uncomment_selection_action; + QAction *_copy_action; QAction *_cut_action; + QAction *_paste_action; + + QAction *_find_action; + QAction *_goto_line_action; + + QAction *_next_bookmark_action; + QAction *_previous_bookmark_action; + QAction *_toggle_bookmark_action; + QAction * _remove_bookmark_action; + + QAction *_print_action; QAction *_run_action; + + QAction *_save_action; + QAction *_save_as_action; + QAction *_close_action; + QAction *_close_all_action; + QAction *_close_others_action; + + QAction *_redo_action; + QAction *_undo_action; + QTabWidget *_tab_widget; + int _marker_breakpoint; enum { MaxMRUFiles = 10 }; diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/m-editor/find-dialog.cc --- a/libgui/src/m-editor/find-dialog.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/m-editor/find-dialog.cc Sat Oct 05 11:22:09 2013 -0400 @@ -158,7 +158,17 @@ _find_next_button->setDefault (true); _find_result_available = false; - move (p->x() + p->frameGeometry ().width (), p->y()); + // move to dialog to side of the parent if there is room on the desktop to do so. + QWidget * desktop = QApplication::desktop (); + int xp = p->x () + p->frameGeometry ().width (); + int yp= p->y (); + if (desktop != 0 && sizeHint ().isValid ()) + { + if (xp + sizeHint ().width () > desktop->width ()) + xp = desktop->width () - sizeHint ().width (); + } + + move (xp, yp); } diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/main-window.cc --- a/libgui/src/main-window.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/main-window.cc Sat Oct 05 11:22:09 2013 -0400 @@ -77,7 +77,11 @@ workspace_window (new workspace_view (this)), find_files_dlg (0), _octave_main_thread (0), - _octave_qt_link (0) + _octave_qt_link (0), + _clipboard (QApplication::clipboard ()), + _cmd_queue (new QStringList ()), // no command pending + _cmd_processing (1), + _cmd_queue_mutex () { // We have to set up all our windows, before we finally launch octave. construct (); @@ -103,6 +107,7 @@ } delete _octave_main_thread; delete _octave_qt_link; + delete _cmd_queue; } bool @@ -139,7 +144,7 @@ main_window::handle_save_workspace_request (void) { QString file = - QFileDialog::getSaveFileName (this, tr ("Save Workspace As"), "."); + QFileDialog::getSaveFileName (this, tr ("Save Workspace As"), ".", 0, 0, QFileDialog::DontUseNativeDialog); if (! file.isEmpty ()) octave_link::post_event (this, &main_window::save_workspace_callback, @@ -152,7 +157,7 @@ QString file = file_arg; if (file.isEmpty ()) - file = QFileDialog::getOpenFileName (this, tr ("Load Workspace"), "."); + file = QFileDialog::getOpenFileName (this, tr ("Load Workspace"), ".", 0, 0, QFileDialog::DontUseNativeDialog); if (! file.isEmpty ()) octave_link::post_event (this, &main_window::load_workspace_callback, @@ -197,9 +202,7 @@ void main_window::execute_command_in_terminal (const QString& command) { - octave_link::post_event (this, &main_window::execute_command_callback, - command.toStdString ()); - + queue_command (command); focus_command_window (); } @@ -210,6 +213,28 @@ } void +main_window::run_file_callback (const QFileInfo& info) +{ + QString dir = info.absolutePath (); + QString function_name = info.fileName (); + function_name.chop (info.suffix ().length () + 1); + if (octave_qt_link::file_in_path (info.absoluteFilePath ().toStdString (), + dir.toStdString ())) + queue_command (function_name); +} + +void +main_window::queue_command (QString command) +{ + _cmd_queue_mutex.lock (); + _cmd_queue->append (command); // queue command + _cmd_queue_mutex.unlock (); + + if (_cmd_processing.tryAcquire ()) // if callback is not processing, post event + octave_link::post_event (this, &main_window::execute_command_callback); +} + +void main_window::handle_new_figure_request (void) { octave_link::post_event (this, &main_window::new_figure_callback); @@ -218,25 +243,37 @@ void main_window::open_online_documentation_page (void) { - QDesktopServices::openUrl (QUrl ("http://gnu.org/software/octave/doc/interpreter")); + QDesktopServices::openUrl (QUrl ("http://octave.org/doc/interpreter")); } void main_window::open_bug_tracker_page (void) { - QDesktopServices::openUrl (QUrl ("http://bugs.octave.org")); + QDesktopServices::openUrl (QUrl ("http://octave.org/bugs.html")); } void -main_window::open_octave_forge_page (void) +main_window::open_octave_packages_page (void) { - QDesktopServices::openUrl (QUrl ("http://octave.sourceforge.net/")); + QDesktopServices::openUrl (QUrl ("http://octave.org/packages.html")); } void main_window::open_agora_page (void) { - QDesktopServices::openUrl (QUrl ("http://agora.octave.org/")); + QDesktopServices::openUrl (QUrl ("http://agora.octave.org")); +} + +void +main_window::open_contribute_page (void) +{ + QDesktopServices::openUrl (QUrl ("http://octave.org/donate.html")); +} + +void +main_window::open_developer_page (void) +{ + QDesktopServices::openUrl (QUrl ("http://octave.org/get-involved.html")); } void @@ -354,7 +391,7 @@ main_window::browse_for_directory (void) { QString dir - = QFileDialog::getExistingDirectory (this, tr ("Set working directory")); + = QFileDialog::getExistingDirectory (this, tr ("Set working directory"), 0, QFileDialog::DontUseNativeDialog); set_current_working_directory (dir); @@ -505,9 +542,11 @@ void main_window::show_about_octave (void) { - QString message = OCTAVE_STARTUP_MESSAGE; + std::string message + = octave_name_version_copyright_copying_warranty_and_bugs (true); - QMessageBox::about (this, tr ("About Octave"), message); + QMessageBox::about (this, tr ("About Octave"), + QString::fromStdString (message)); } void @@ -542,6 +581,8 @@ void main_window::set_window_layout (QSettings *settings) { + QList float_and_visible; + // Restore the geometry of all dock-widgets foreach (octave_dock_widget *widget, dock_widget_list ()) { @@ -555,7 +596,7 @@ if (floating) widget->make_window (); else if (! widget->parent ()) // should not be floating but is - widget->setParent (this); // reparent + widget->make_widget (false); // no docking, just reparent // restore geometry QVariant val = settings->value (name); @@ -564,12 +605,24 @@ // make widget visible if desired bool visible = settings->value ("DockWidgets/" + name + "Visible", true).toBool (); - widget->setVisible (visible); + if (floating && visible) // floating and visible + float_and_visible.append (widget); // not show before main win + else + { + widget->make_widget (); + widget->setVisible (visible); // not floating -> show + } } } restoreState (settings->value ("MainWindow/windowState").toByteArray ()); restoreGeometry (settings->value ("MainWindow/geometry").toByteArray ()); + show (); // main window is ready and can be shown (as first window) + + // show floating widgets after main win to ensure "Octave" in central menu + foreach (octave_dock_widget *widget, float_and_visible) + widget->setVisible (true); + } void @@ -799,6 +852,9 @@ connect (file_browser_window, SIGNAL (find_files_signal (const QString&)), this, SLOT (find_files (const QString&))); + connect (this, SIGNAL (set_widget_shortcuts_signal (bool)), + editor_window, SLOT (set_shortcuts (bool))); + connect_uiwidget_links (); setWindowTitle ("Octave"); @@ -856,6 +912,9 @@ set_current_working_directory (curr_dir.absolutePath ()); octave_link::post_event (this, &main_window::resize_command_window_callback); + + set_global_shortcuts (true); + } void @@ -907,6 +966,10 @@ connect (_octave_qt_link, SIGNAL (exit_debugger_signal ()), this, SLOT (handle_exit_debugger ())); + connect (_octave_qt_link, + SIGNAL (show_preferences_signal (void)), + this, SLOT (process_settings_dialog_request ())); + #ifdef HAVE_QSCINTILLA connect (_octave_qt_link, SIGNAL (edit_file_signal (const QString&)), @@ -929,6 +992,10 @@ this, SLOT (handle_update_breakpoint_marker_request (bool, const QString&, int))); + connect (_octave_qt_link, + SIGNAL (show_doc_signal (const QString &)), + this, SLOT (handle_show_doc (const QString &))); + connect (_workspace_model, SIGNAL (rename_variable (const QString&, const QString&)), this, @@ -966,6 +1033,8 @@ _open_action = file_menu->addAction (QIcon (":/actions/icons/fileopen.png"), tr ("Open...")); + _open_action->setShortcutContext (Qt::ApplicationShortcut); + #ifdef HAVE_QSCINTILLA file_menu->addMenu (editor_window->get_mru_menu ()); @@ -987,8 +1056,8 @@ file_menu->addSeparator (); - QAction *exit_action = file_menu->addAction (tr ("Exit")); - exit_action->setShortcut (QKeySequence::Quit); + _exit_action = file_menu->addAction (tr ("Exit")); + _exit_action->setShortcutContext (Qt::ApplicationShortcut); connect (preferences_action, SIGNAL (triggered ()), this, SLOT (process_settings_dialog_request ())); @@ -1004,7 +1073,7 @@ connect (save_workspace_action, SIGNAL (triggered ()), this, SLOT (handle_save_workspace_request ())); - connect (exit_action, SIGNAL (triggered ()), + connect (_exit_action, SIGNAL (triggered ()), this, SLOT (close ())); } @@ -1016,6 +1085,7 @@ _new_script_action = new_menu->addAction (QIcon (":/actions/icons/filenew.png"), tr ("Script")); + _new_script_action->setShortcutContext (Qt::ApplicationShortcut); QAction *new_function_action = new_menu->addAction (tr ("Function")); new_function_action->setEnabled (true); @@ -1051,18 +1121,21 @@ _copy_action = edit_menu->addAction (QIcon (":/actions/icons/editcopy.png"), tr ("Copy"), this, SLOT (copyClipboard ())); - _copy_action->setShortcut (ctrl_shift + Qt::Key_C); + _copy_action->setShortcut (QKeySequence::Copy); + _paste_action = edit_menu->addAction (QIcon (":/actions/icons/editpaste.png"), tr ("Paste"), this, SLOT (pasteClipboard ())); - _paste_action->setShortcut (ctrl_shift + Qt::Key_V); + _paste_action->setShortcut (QKeySequence::Paste); + + _clear_clipboard_action + = edit_menu->addAction (tr ("Clear Clipboard"), this, + SLOT (clear_clipboard ())); edit_menu->addSeparator (); - QAction *find_files_action - = edit_menu->addAction (tr ("Find Files...")); - find_files_action->setShortcut (ctrl_shift + Qt::Key_F); + _find_files_action = edit_menu->addAction (tr ("Find Files...")); edit_menu->addSeparator (); @@ -1075,7 +1148,7 @@ QAction *clear_workspace_action = edit_menu->addAction (tr ("Clear Workspace")); - connect (find_files_action, SIGNAL (triggered()), + connect (_find_files_action, SIGNAL (triggered()), this, SLOT (find_files ())); connect (clear_command_window_action, SIGNAL (triggered ()), @@ -1086,6 +1159,10 @@ connect (clear_workspace_action, SIGNAL (triggered ()), this, SLOT (handle_clear_workspace_request ())); + + connect (_clipboard, SIGNAL (changed (QClipboard::Mode)), + this, SLOT (clipboard_has_changed (QClipboard::Mode))); + clipboard_has_changed (QClipboard::Clipboard); } QAction * @@ -1288,11 +1365,17 @@ QAction *report_bug_action = help_menu->addAction (tr ("Report Bug")); - QAction *octave_forge_action - = help_menu->addAction (tr ("Visit Octave Forge")); + QAction *octave_packages_action + = help_menu->addAction (tr ("Octave Packages")); QAction *agora_action - = help_menu->addAction (tr ("Visit Agora")); + = help_menu->addAction (tr ("Share Code")); + + QAction *contribute_action + = help_menu->addAction (tr ("Contribute to Octave")); + + QAction *developer_action + = help_menu->addAction (tr ("Octave Developer Resources")); help_menu->addSeparator (); @@ -1302,12 +1385,18 @@ connect (report_bug_action, SIGNAL (triggered ()), this, SLOT (open_bug_tracker_page ())); - connect (octave_forge_action, SIGNAL (triggered ()), - this, SLOT (open_octave_forge_page ())); + connect (octave_packages_action, SIGNAL (triggered ()), + this, SLOT (open_octave_packages_page ())); connect (agora_action, SIGNAL (triggered ()), this, SLOT (open_agora_page ())); + connect (contribute_action, SIGNAL (triggered ()), + this, SLOT (open_contribute_page ())); + + connect (developer_action, SIGNAL (triggered ()), + this, SLOT (open_developer_page ())); + connect (about_octave_action, SIGNAL (triggered ()), this, SLOT (show_about_octave ())); } @@ -1443,29 +1532,34 @@ } void -main_window::execute_command_callback (const std::string& command) +main_window::execute_command_callback () { - std::string pending_input = command_editor::get_current_line (); + bool repost = false; // flag for reposting event for this callback - command_editor::set_initial_input (pending_input); - - command_editor::replace_line (command); - command_editor::redisplay (); + if (!_cmd_queue->isEmpty ()) // list can not be empty here, just to make sure + { + std::string pending_input = command_editor::get_current_line (); + command_editor::set_initial_input (pending_input); - // We are executing inside the command editor event loop. Force - // the current line to be returned for processing. - command_editor::interrupt (); -} + _cmd_queue_mutex.lock (); // critical path + std::string command = _cmd_queue->takeFirst ().toStdString (); + if (_cmd_queue->isEmpty ()) + _cmd_processing.release (); // command queue empty, processing will stop + else + repost = true; // not empty, repost at end + _cmd_queue_mutex.unlock (); + + command_editor::replace_line (command); -void -main_window::run_file_callback (const QFileInfo& info) -{ - QString dir = info.absolutePath (); - QString function_name = info.fileName (); - function_name.chop (info.suffix ().length () + 1); - if (octave_qt_link::file_in_path (info.absoluteFilePath ().toStdString (), - dir.toStdString ())) - execute_command_callback (function_name.toStdString ()); + command_editor::redisplay (); + // We are executing inside the command editor event loop. Force + // the current line to be returned for processing. + command_editor::interrupt (); + } + + if (repost) // queue not empty, so repost event for further processing + octave_link::post_event (this, &main_window::execute_command_callback); + } void @@ -1571,4 +1665,64 @@ } +void +main_window::set_global_shortcuts (bool set_shortcuts) +{ + if (set_shortcuts) + { + _open_action->setShortcut (QKeySequence::Open); + _new_script_action->setShortcut (QKeySequence::New); + + _exit_action->setShortcut (QKeySequence::Quit); + + _find_files_action->setShortcut (Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_F); + + } + else + { + + QKeySequence no_key = QKeySequence (); + + _open_action->setShortcut (no_key); + _new_script_action->setShortcut (no_key); + + _exit_action->setShortcut (no_key); + + _find_files_action->setShortcut (no_key); + + } + + emit set_widget_shortcuts_signal (set_shortcuts); +} + +void +main_window::handle_show_doc (const QString& file) +{ + doc_browser_window->setVisible (true); + emit show_doc_signal (file); +} + +void +main_window::clipboard_has_changed (QClipboard::Mode cp_mode) +{ + if (cp_mode == QClipboard::Clipboard) + { + if (_clipboard->text ().isEmpty ()) + { + _paste_action->setEnabled (false); + _clear_clipboard_action->setEnabled (false); + } + else + { + _paste_action->setEnabled (true); + _clear_clipboard_action->setEnabled (true); + } + } +} + +void +main_window::clear_clipboard () +{ + _clipboard->clear (QClipboard::Clipboard); +} diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/main-window.h --- a/libgui/src/main-window.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/main-window.h Sat Oct 05 11:22:09 2013 -0400 @@ -36,6 +36,7 @@ #include #include #include +#include // Editor includes #include "file-editor-interface.h" @@ -82,6 +83,8 @@ void new_file_signal (const QString&); void open_file_signal (const QString&); + void show_doc_signal (const QString&); + void insert_debugger_pointer_signal (const QString& file, int line); void delete_debugger_pointer_signal (const QString& file, int line); void update_breakpoint_marker_signal (bool insert, const QString& file, @@ -90,6 +93,8 @@ void copyClipboard_signal (void); void pasteClipboard_signal (void); + void set_widget_shortcuts_signal (bool); + public slots: void report_status_message (const QString& statusMessage); void handle_save_workspace_request (void); @@ -104,8 +109,10 @@ void open_file (const QString& file_name = QString ()); void open_online_documentation_page (void); void open_bug_tracker_page (void); - void open_octave_forge_page (void); + void open_octave_packages_page (void); void open_agora_page (void); + void open_contribute_page (void); + void open_developer_page (void); void process_settings_dialog_request (void); void show_about_octave (void); void notice_settings (const QSettings *settings); @@ -169,9 +176,20 @@ const QString &dirname, const QString& multimode); + void handle_show_doc (const QString &file); + // find files dialog void find_files(const QString &startdir=QDir::currentPath()); void find_files_finished(int); + + // setting global shortcuts + void set_global_shortcuts (bool enable); + + // handling the clipboard + void clipboard_has_changed (QClipboard::Mode); + void clear_clipboard (); + + protected: void closeEvent (QCloseEvent * closeEvent); @@ -218,7 +236,7 @@ void clear_history_callback (void); - void execute_command_callback (const std::string& command); + void execute_command_callback (); void run_file_callback (const QFileInfo& info); void new_figure_callback (void); @@ -237,7 +255,8 @@ void exit_callback (void); - // Data models. + void queue_command (QString command); // Data models. + workspace_model *_workspace_model; // Toolbars. @@ -257,7 +276,9 @@ list.append (static_cast (history_window)); list.append (static_cast (file_browser_window)); list.append (static_cast (doc_browser_window)); +#ifdef HAVE_QSCINTILLA list.append (static_cast (editor_window)); +#endif list.append (static_cast (workspace_window)); return list; } @@ -276,8 +297,12 @@ QAction *_copy_action; QAction *_paste_action; + QAction *_clear_clipboard_action; QAction *_undo_action; + QAction *_find_files_action; + QAction *_exit_action; + // Toolbars. QComboBox *_current_directory_combo_box; static const int current_directory_width = 300; @@ -292,8 +317,15 @@ octave_qt_link *_octave_qt_link; + QClipboard *_clipboard; + // Flag for closing whole application. bool _closing; + + // semaphore to synchronize execution signals and related callback + QStringList *_cmd_queue; + QSemaphore _cmd_processing; + QMutex _cmd_queue_mutex; }; #endif // MAINWINDOW_H diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/octave-dock-widget.cc --- a/libgui/src/octave-dock-widget.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/octave-dock-widget.cc Sat Oct 05 11:22:09 2013 -0400 @@ -55,6 +55,7 @@ QToolButton *dock_button = new QToolButton (this); dock_button->setDefaultAction (_dock_action); dock_button->setFocusPolicy(Qt::NoFocus); + dock_button->setIconSize(QSize(12,12)); QAction *close_action = new QAction (QIcon (":/actions/icons/widget-close.png"), "", this ); @@ -64,6 +65,7 @@ QToolButton *close_button = new QToolButton (this); close_button->setDefaultAction (close_action); close_button->setFocusPolicy(Qt::NoFocus); + close_button->setIconSize(QSize(12,12)); QHBoxLayout *h_layout = new QHBoxLayout (); h_layout->addStretch (100); @@ -152,7 +154,7 @@ // dock the widget void -octave_dock_widget::make_widget () +octave_dock_widget::make_widget (bool dock) { QSettings *settings = resource_manager::get_settings (); @@ -161,14 +163,18 @@ saveGeometry ()); settings->sync (); - // add widget to last saved docking area - int area = settings->value ("DockWidgets/" + objectName () + "_dock_area", - Qt::TopDockWidgetArea).toInt (); - _parent->addDockWidget (static_cast (area), this); + if (dock) + { // add widget to last saved docking area (dock=true is default) + int area = settings->value ("DockWidgets/" + objectName () + "_dock_area", + Qt::TopDockWidgetArea).toInt (); + _parent->addDockWidget (static_cast (area), this); - // FIXME: restoreGeometry is ignored for docked widgets and its child widget - // restoreGeometry (settings->value - // ("DockWidgets/" + objectName ()).toByteArray ()); + // FIXME: restoreGeometry is ignored for docked widgets and its child widget + // restoreGeometry (settings->value + // ("DockWidgets/" + objectName ()).toByteArray ()); + } + else // only reparent, no docking + setParent (_parent); // adjust the (un)dock icon _dock_action->setIcon (QIcon (":/actions/icons/widget-undock.png")); diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/octave-dock-widget.h --- a/libgui/src/octave-dock-widget.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/octave-dock-widget.h Sat Oct 05 11:22:09 2013 -0400 @@ -40,7 +40,7 @@ virtual void connect_visibility_changed (void); void make_window (void); - void make_widget (void); + void make_widget (bool dock=true); void set_title (const QString&); signals: diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/octave-gui.cc --- a/libgui/src/octave-gui.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/octave-gui.cc Sat Oct 05 11:22:09 2013 -0400 @@ -38,8 +38,11 @@ #include "lo-utils.h" #include "oct-env.h" +#include "oct-syscalls.h" #include "syswait.h" +#include "sighandlers.h" + #include "welcome-wizard.h" #include "resource-manager.h" #include "main-window.h" @@ -73,8 +76,7 @@ { // Parent - // FIXME -- we should catch signals and pass them on to the child - // process in some way, possibly translating SIGINT to SIGTERM. + install_gui_driver_signal_handlers (pid); int status; @@ -88,12 +90,20 @@ } int -octave_start_gui (int argc, char *argv[]) +octave_start_gui (int argc, char *argv[], bool fork) { - dissociate_terminal (); + if (fork) + dissociate_terminal (); QApplication application (argc, argv); + // install translators for the gui and qt text + QTranslator gui_tr, qt_tr, qsci_tr; + resource_manager::config_translators (&qt_tr,&qsci_tr,&gui_tr); + application.installTranslator (&qt_tr); + application.installTranslator (&qsci_tr); + application.installTranslator (&gui_tr); + while (true) { if (resource_manager::is_first_run ()) @@ -104,13 +114,6 @@ } else { - // install translators for the gui and qt text - QTranslator gui_tr, qt_tr, qsci_tr; - resource_manager::config_translators (&qt_tr,&qsci_tr,&gui_tr); - application.installTranslator (&qt_tr); - application.installTranslator (&qsci_tr); - application.installTranslator (&gui_tr); - // update network-settings resource_manager::update_network_settings (); @@ -123,13 +126,16 @@ if (term.empty ()) octave_env::putenv ("TERM", "xterm"); +#else + std::string term = octave_env::getenv ("TERM"); + + if (term.empty ()) + octave_env::putenv ("TERM", "cygwin"); #endif // create main window, read settings, and show window main_window w; - w.read_settings (); // get widget settings after construction - // but before showing - w.show (); + w.read_settings (); // get widget settings and window layout w.focus_command_window (); w.connect_visibility_changed (); // connect signals for changes in // visibility not before w is shown diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/octave-gui.h --- a/libgui/src/octave-gui.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/octave-gui.h Sat Oct 05 11:22:09 2013 -0400 @@ -23,6 +23,7 @@ #if !defined (octave_octave_gui_h) #define octave_octave_gui_h 1 -extern OCTGUI_API int octave_start_gui (int argc, char **argv); +extern OCTGUI_API int octave_start_gui (int argc, char **argv, + bool fork = true); #endif diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/octave-qt-link.cc --- a/libgui/src/octave-qt-link.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/octave-qt-link.cc Sat Oct 05 11:22:09 2013 -0400 @@ -491,3 +491,17 @@ return ok; } + +void +octave_qt_link::do_show_preferences () +{ + emit show_preferences_signal (); +} + +void +octave_qt_link::do_show_doc (const std::string& file) +{ + emit show_doc_signal (QString::fromStdString (file)); +} + + diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/octave-qt-link.h --- a/libgui/src/octave-qt-link.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/octave-qt-link.h Sat Oct 05 11:22:09 2013 -0400 @@ -121,6 +121,9 @@ static bool file_in_path (const std::string& file, const std::string& dir); + void do_show_preferences (void); + + void do_show_doc (const std::string& file); private: // No copying! @@ -166,6 +169,10 @@ void insert_debugger_pointer_signal (const QString&, int); void delete_debugger_pointer_signal (const QString&, int); + + void show_preferences_signal (void); + + void show_doc_signal (const QString &file); }; #endif diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/qtinfo/parser.cc --- a/libgui/src/qtinfo/parser.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/qtinfo/parser.cc Sat Oct 05 11:22:09 2013 -0400 @@ -179,9 +179,29 @@ parser::get_next_node (QIODevice *io) { QString text; + QByteArray line, line_buffer; + char c; + int i; + while (!io->atEnd ()) { - QByteArray line = io->readLine (); + io->getChar (&c); + if (c) + { // first char is not equal 0 + io->ungetChar (c); + line = io->readLine (); + } + else + { // 0 was read -> image -> text length changes + line_buffer = io->readLine (); // image tag that is not needed + line = io->readLine (); // firsts line of text message + for (i=1; i" + text2; + text = text1 + "
 " + + text2; } else { @@ -371,7 +393,9 @@ text.append (navigationLinks); text.prepend ("\n"); text.append ("\n"); + return text; + } void @@ -592,3 +616,24 @@ results.append (""); return results; } + +QString +parser::find_ref (const QString &ref_name) +{ + QString text = ""; + + QHash::iterator it; + for (it=_ref_map.begin ();it!=_ref_map.end ();++it) + { + QString k = it.key (); + node_position p = it.value (); + + if (k == "XREF" + ref_name) + { + // found ref, so return its name + text = "XREF" + ref_name; + } + } + return text; +} + diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/qtinfo/parser.h --- a/libgui/src/qtinfo/parser.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/qtinfo/parser.h Sat Oct 05 11:22:09 2013 -0400 @@ -57,6 +57,8 @@ QString search_node (const QString& node); QString global_search (const QString& text, int maxFounds); + QString find_ref (const QString &name); + /** Checks if this node is reference. If node is reference, it will be returned its position * in text, else it will be returned -1. */ diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/qtinfo/webinfo.cc --- a/libgui/src/qtinfo/webinfo.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/qtinfo/webinfo.cc Sat Oct 05 11:22:09 2013 -0400 @@ -93,6 +93,7 @@ resize (500, 300); set_info_path (QString::fromStdString (Vinfo_file)); + } void @@ -190,6 +191,24 @@ } void +webinfo::load_ref (const QString &ref_name) +{ + QString text = _parser.find_ref (ref_name); + if (text.length () > 0) + { + load_node (text); + } + else + { + // not found + load_node("Top"); + } + + if (_text_browser) + _text_browser->setFocus(); +} + +void webinfo::search () { if (_search_check_box->isChecked ()) diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/qtinfo/webinfo.h --- a/libgui/src/qtinfo/webinfo.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/qtinfo/webinfo.h Sat Oct 05 11:22:09 2013 -0400 @@ -40,6 +40,8 @@ webinfo (QWidget *parent = 0); void set_info_path (const QString& info_path); void load_node (const QString& node_name); + + void load_ref (const QString &ref_name); public slots: void link_clicked (const QUrl& link); diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/resource-manager.cc --- a/libgui/src/resource-manager.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/resource-manager.cc Sat Oct 05 11:22:09 2013 -0400 @@ -153,13 +153,28 @@ return home_path; } +QString +resource_manager::do_get_settings_path (void) +{ + QDesktopServices desktopServices; + home_path = desktopServices.storageLocation (QDesktopServices::HomeLocation); + QString settings_path = home_path + "/.config/octave/"; + return settings_path; +} + +QString +resource_manager::do_get_settings_file (void) +{ + return do_get_settings_path () + "qt-settings"; +} + void resource_manager::do_reload_settings (void) { QDesktopServices desktopServices; home_path = desktopServices.storageLocation (QDesktopServices::HomeLocation); - QString settings_path = home_path + "/.config/octave/"; - QString settings_file = settings_path + "qt-settings"; + QString settings_path = do_get_settings_path (); + QString settings_file = do_get_settings_file (); if (!QFile::exists (settings_file)) { @@ -235,1564 +250,3 @@ { return QTerminal::default_colors (); } - -const char* -resource_manager::octave_keywords (void) -{ - return - ".nargin. " - "EDITOR " - "EXEC_PATH " - "F_DUPFD " - "F_GETFD " - "F_GETFL " - "F_SETFD " - "F_SETFL " - "I " - "IMAGE_PATH " - "Inf " - "J " - "NA " - "NaN " - "OCTAVE_HOME " - "OCTAVE_VERSION " - "O_APPEND " - "O_ASYNC " - "O_CREAT " - "O_EXCL " - "O_NONBLOCK " - "O_RDONLY " - "O_RDWR " - "O_SYNC " - "O_TRUNC " - "O_WRONLY " - "PAGER " - "PAGER_FLAGS " - "PS1 " - "PS2 " - "PS4 " - "P_tmpdir " - "SEEK_CUR " - "SEEK_END " - "SEEK_SET " - "SIG " - "S_ISBLK " - "S_ISCHR " - "S_ISDIR " - "S_ISFIFO " - "S_ISLNK " - "S_ISREG " - "S_ISSOCK " - "WCONTINUE " - "WCOREDUMP " - "WEXITSTATUS " - "WIFCONTINUED " - "WIFEXITED " - "WIFSIGNALED " - "WIFSTOPPED " - "WNOHANG " - "WSTOPSIG " - "WTERMSIG " - "WUNTRACED " - "__accumarray_max__ " - "__accumarray_min__ " - "__accumarray_sum__ " - "__accumdim_sum__ " - "__all_opts__ " - "__builtins__ " - "__calc_dimensions__ " - "__contourc__ " - "__current_scope__ " - "__delaunayn__ " - "__dispatch__ " - "__display_tokens__ " - "__dsearchn__ " - "__dump_symtab_info__ " - "__end__ " - "__error_text__ " - "__finish__ " - "__fltk_ginput__ " - "__fltk_print__ " - "__fltk_uigetfile__ " - "__ftp__ " - "__ftp_ascii__ " - "__ftp_binary__ " - "__ftp_close__ " - "__ftp_cwd__ " - "__ftp_delete__ " - "__ftp_dir__ " - "__ftp_mget__ " - "__ftp_mkdir__ " - "__ftp_mode__ " - "__ftp_mput__ " - "__ftp_pwd__ " - "__ftp_rename__ " - "__ftp_rmdir__ " - "__get__ " - "__glpk__ " - "__gnuplot_drawnow__ " - "__gnuplot_get_var__ " - "__gnuplot_ginput__ " - "__gnuplot_has_feature__ " - "__gnuplot_open_stream__ " - "__gnuplot_print__ " - "__gnuplot_version__ " - "__go_axes__ " - "__go_axes_init__ " - "__go_close_all__ " - "__go_delete__ " - "__go_draw_axes__ " - "__go_draw_figure__ " - "__go_execute_callback__ " - "__go_figure__ " - "__go_figure_handles__ " - "__go_handles__ " - "__go_hggroup__ " - "__go_image__ " - "__go_line__ " - "__go_patch__ " - "__go_surface__ " - "__go_text__ " - "__go_uimenu__ " - "__gud_mode__ " - "__image_pixel_size__ " - "__init_fltk__ " - "__isa_parent__ " - "__keywords__ " - "__lexer_debug_flag__ " - "__lin_interpn__ " - "__list_functions__ " - "__magick_finfo__ " - "__magick_format_list__ " - "__magick_read__ " - "__magick_write__ " - "__makeinfo__ " - "__marching_cube__ " - "__next_line_color__ " - "__next_line_style__ " - "__operators__ " - "__parent_classes__ " - "__parser_debug_flag__ " - "__pathorig__ " - "__pchip_deriv__ " - "__plt_get_axis_arg__ " - "__print_parse_opts__ " - "__qp__ " - "__request_drawnow__ " - "__sort_rows_idx__ " - "__strip_html_tags__ " - "__token_count__ " - "__unimplemented__ " - "__varval__ " - "__version_info__ " - "__voronoi__ " - "__which__ " - "abs " - "accumarray " - "accumdim " - "acos " - "acosd " - "acosh " - "acot " - "acotd " - "acoth " - "acsc " - "acscd " - "acsch " - "add_input_event_hook " - "addlistener " - "addpath " - "addproperty " - "addtodate " - "airy " - "all " - "allchild " - "allow_noninteger_range_as_index " - "amd " - "ancestor " - "and " - "angle " - "anova " - "ans " - "any " - "arch_fit " - "arch_rnd " - "arch_test " - "area " - "arg " - "argnames " - "argv " - "arma_rnd " - "arrayfun " - "asctime " - "asec " - "asecd " - "asech " - "asin " - "asind " - "asinh " - "assert " - "assignin " - "atan " - "atan2 " - "atand " - "atanh " - "atexit " - "autocor " - "autocov " - "autoload " - "autoreg_matrix " - "autumn " - "available_graphics_toolkits " - "axes " - "axis " - "balance " - "bar " - "barh " - "bartlett " - "bartlett_test " - "base2dec " - "beep " - "beep_on_error " - "bessel " - "besselh " - "besseli " - "besselj " - "besselk " - "bessely " - "beta " - "betacdf " - "betai " - "betainc " - "betainv " - "betaln " - "betapdf " - "betarnd " - "bicgstab " - "bicubic " - "bin2dec " - "bincoeff " - "binocdf " - "binoinv " - "binopdf " - "binornd " - "bitand " - "bitcmp " - "bitget " - "bitmax " - "bitor " - "bitpack " - "bitset " - "bitshift " - "bitunpack " - "bitxor " - "blackman " - "blanks " - "blkdiag " - "blkmm " - "bone " - "box " - "break " - "brighten " - "bsxfun " - "bug_report " - "builtin " - "bunzip2 " - "bzip2 " - "calendar " - "canonicalize_file_name " - "cart2pol " - "cart2sph " - "case " - "cast " - "cat " - "catch " - "cauchy_cdf " - "cauchy_inv " - "cauchy_pdf " - "cauchy_rnd " - "caxis " - "cbrt " - "ccolamd " - "cd " - "ceil " - "cell " - "cell2mat " - "cell2struct " - "celldisp " - "cellfun " - "cellidx " - "cellindexmat " - "cellslices " - "cellstr " - "center " - "cgs " - "char " - "chdir " - "chi2cdf " - "chi2inv " - "chi2pdf " - "chi2rnd " - "chisquare_test_homogeneity " - "chisquare_test_independence " - "chol " - "chol2inv " - "choldelete " - "cholinsert " - "cholinv " - "cholshift " - "cholupdate " - "chop " - "circshift " - "cla " - "clabel " - "class " - "clc " - "clear " - "clf " - "clg " - "clock " - "cloglog " - "close " - "closereq " - "colamd " - "colloc " - "colon " - "colorbar " - "colormap " - "colperm " - "colstyle " - "columns " - "comet " - "comet3 " - "comma " - "command_line_path " - "common_size " - "commutation_matrix " - "compan " - "compare_versions " - "compass " - "complement " - "completion_append_char " - "completion_matches " - "complex " - "computer " - "cond " - "condest " - "confirm_recursive_rmdir " - "conj " - "continue " - "contour " - "contour3 " - "contourc " - "contourf " - "contrast " - "conv " - "conv2 " - "convhull " - "convhulln " - "convn " - "cool " - "copper " - "copyfile " - "cor " - "cor_test " - "corrcoef " - "cos " - "cosd " - "cosh " - "cot " - "cotd " - "coth " - "cov " - "cplxpair " - "cputime " - "cquad " - "crash_dumps_octave_core " - "create_set " - "cross " - "csc " - "cscd " - "csch " - "cstrcat " - "csvread " - "csvwrite " - "csymamd " - "ctime " - "ctranspose " - "cummax " - "cummin " - "cumprod " - "cumsum " - "cumtrapz " - "curl " - "cut " - "cylinder " - "daspect " - "daspk " - "daspk_options " - "dasrt " - "dasrt_options " - "dassl " - "dassl_options " - "date " - "datenum " - "datestr " - "datetick " - "datevec " - "dbclear " - "dbcont " - "dbdown " - "dblquad " - "dbnext " - "dbquit " - "dbstack " - "dbstatus " - "dbstep " - "dbstop " - "dbtype " - "dbup " - "dbwhere " - "deal " - "deblank " - "debug " - "debug_on_error " - "debug_on_interrupt " - "debug_on_warning " - "dec2base " - "dec2bin " - "dec2hex " - "deconv " - "del2 " - "delaunay " - "delaunay3 " - "delaunayn " - "delete " - "dellistener " - "demo " - "det " - "detrend " - "diag " - "diary " - "diff " - "diffpara " - "diffuse " - "dir " - "discrete_cdf " - "discrete_inv " - "discrete_pdf " - "discrete_rnd " - "disp " - "dispatch " - "display " - "divergence " - "dlmread " - "dlmwrite " - "dmperm " - "dmult " - "do " - "do_braindead_shortcircuit_evaluation " - "do_string_escapes " - "doc " - "doc_cache_create " - "doc_cache_file " - "dos " - "dot " - "double " - "drawnow " - "dsearch " - "dsearchn " - "dump_prefs " - "dup2 " - "duplication_matrix " - "durbinlevinson " - "e " - "echo " - "echo_executing_commands " - "edit " - "edit_history " - "eig " - "eigs " - "ellipsoid " - "else " - "elseif " - "empirical_cdf " - "empirical_inv " - "empirical_pdf " - "empirical_rnd " - "end " - "end_try_catch " - "end_unwind_protect " - "endfor " - "endfunction " - "endgrent " - "endif " - "endpwent " - "endswitch " - "endwhile " - "eomday " - "eps " - "eq " - "erf " - "erfc " - "erfcx " - "erfinv " - "errno " - "errno_list " - "error " - "error_text " - "errorbar " - "etime " - "etree " - "etreeplot " - "eval " - "evalin " - "example " - "exec " - "exist " - "exit " - "exp " - "expcdf " - "expinv " - "expm " - "expm1 " - "exppdf " - "exprnd " - "eye " - "ezcontour " - "ezcontourf " - "ezmesh " - "ezmeshc " - "ezplot " - "ezplot3 " - "ezpolar " - "ezsurf " - "ezsurfc " - "f_test_regression " - "factor " - "factorial " - "fail " - "false " - "fcdf " - "fclear " - "fclose " - "fcntl " - "fdisp " - "feather " - "feof " - "ferror " - "feval " - "fflush " - "fft " - "fft2 " - "fftconv " - "fftfilt " - "fftn " - "fftshift " - "fftw " - "fgetl " - "fgets " - "fieldnames " - "figure " - "file_in_loadpath " - "file_in_path " - "fileattrib " - "filemarker " - "fileparts " - "fileread " - "filesep " - "fill " - "filter " - "filter2 " - "find " - "find_dir_in_path " - "findall " - "findobj " - "findstr " - "finite " - "finv " - "fix " - "fixed_point_format " - "flag " - "flipdim " - "fliplr " - "flipud " - "floor " - "fminbnd " - "fminunc " - "fmod " - "fnmatch " - "fopen " - "for " - "fork " - "format " - "formula " - "fpdf " - "fplot " - "fprintf " - "fputs " - "fractdiff " - "fread " - "freport " - "freqz " - "freqz_plot " - "frewind " - "frnd " - "fscanf " - "fseek " - "fskipl " - "fsolve " - "fstat " - "ftell " - "full " - "fullfile " - "func2str " - "function " - "functions " - "fwrite " - "fzero " - "gamcdf " - "gaminv " - "gamma " - "gammai " - "gammainc " - "gammaln " - "gampdf " - "gamrnd " - "gca " - "gcbf " - "gcbo " - "gcd " - "gcf " - "ge " - "genpath " - "genvarname " - "geocdf " - "geoinv " - "geopdf " - "geornd " - "get " - "get_first_help_sentence " - "get_help_text " - "get_help_text_from_file " - "getappdata " - "getegid " - "getenv " - "geteuid " - "getfield " - "getgid " - "getgrent " - "getgrgid " - "getgrnam " - "gethostname " - "getpgrp " - "getpid " - "getppid " - "getpwent " - "getpwnam " - "getpwuid " - "getrusage " - "getuid " - "ginput " - "givens " - "glob " - "global " - "glpk " - "glpkmex " - "gls " - "gmap40 " - "gmres " - "gmtime " - "gnuplot_binary " - "gplot " - "gradient " - "graphics_toolkit " - "gray " - "gray2ind " - "grid " - "griddata " - "griddata3 " - "griddatan " - "gt " - "gtext " - "gunzip " - "gzip " - "hadamard " - "hamming " - "hankel " - "hanning " - "help " - "hess " - "hex2dec " - "hex2num " - "hggroup " - "hidden " - "hilb " - "hist " - "histc " - "history " - "history_control " - "history_file " - "history_save " - "history_size " - "history_timestamp_format_string " - "hold " - "home " - "horzcat " - "hot " - "hotelling_test " - "hotelling_test_2 " - "housh " - "hsv " - "hsv2rgb " - "hurst " - "hygecdf " - "hygeinv " - "hygepdf " - "hygernd " - "hypot " - "i " - "idivide " - "if " - "ifelse " - "ifft " - "ifft2 " - "ifftn " - "ifftshift " - "ignore_function_time_stamp " - "imag " - "image " - "imagesc " - "imfinfo " - "imread " - "imshow " - "imwrite " - "ind2gray " - "ind2rgb " - "ind2sub " - "index " - "inf " - "inferiorto " - "info " - "info_file " - "info_program " - "inline " - "inpolygon " - "input " - "inputname " - "int16 " - "int2str " - "int32 " - "int64 " - "int8 " - "interp1 " - "interp1q " - "interp2 " - "interp3 " - "interpft " - "interpn " - "intersect " - "intmax " - "intmin " - "intwarning " - "inv " - "inverse " - "invhilb " - "ipermute " - "iqr " - "is_absolute_filename " - "is_duplicate_entry " - "is_global " - "is_leap_year " - "is_rooted_relative_filename " - "is_valid_file_id " - "isa " - "isalnum " - "isalpha " - "isappdata " - "isargout " - "isascii " - "isbool " - "iscell " - "iscellstr " - "ischar " - "iscntrl " - "iscolumn " - "iscommand " - "iscomplex " - "isdebugmode " - "isdefinite " - "isdeployed " - "isdigit " - "isdir " - "isempty " - "isequal " - "isequalwithequalnans " - "isfield " - "isfigure " - "isfinite " - "isfloat " - "isglobal " - "isgraph " - "ishandle " - "ishermitian " - "ishghandle " - "ishold " - "isieee " - "isindex " - "isinf " - "isinteger " - "iskeyword " - "isletter " - "islogical " - "islower " - "ismac " - "ismatrix " - "ismember " - "ismethod " - "isna " - "isnan " - "isnull " - "isnumeric " - "isobject " - "isocolors " - "isonormals " - "isosurface " - "ispc " - "isprime " - "isprint " - "isprop " - "ispunct " - "israwcommand " - "isreal " - "isrow " - "isscalar " - "issorted " - "isspace " - "issparse " - "issquare " - "isstr " - "isstrprop " - "isstruct " - "issymmetric " - "isunix " - "isupper " - "isvarname " - "isvector " - "isxdigit " - "j " - "jet " - "kbhit " - "kendall " - "keyboard " - "kill " - "kolmogorov_smirnov_cdf " - "kolmogorov_smirnov_test " - "kolmogorov_smirnov_test_2 " - "kron " - "kruskal_wallis_test " - "krylov " - "krylovb " - "kurtosis " - "laplace_cdf " - "laplace_inv " - "laplace_pdf " - "laplace_rnd " - "lasterr " - "lasterror " - "lastwarn " - "lchol " - "lcm " - "ldivide " - "le " - "legend " - "legendre " - "length " - "lgamma " - "license " - "lin2mu " - "line " - "link " - "linkprop " - "linspace " - "list " - "list_in_columns " - "list_primes " - "load " - "loadaudio " - "loadimage " - "loadobj " - "localtime " - "log " - "log10 " - "log1p " - "log2 " - "logical " - "logistic_cdf " - "logistic_inv " - "logistic_pdf " - "logistic_regression " - "logistic_rnd " - "logit " - "loglog " - "loglogerr " - "logm " - "logncdf " - "logninv " - "lognpdf " - "lognrnd " - "logspace " - "lookfor " - "lookup " - "lower " - "ls " - "ls_command " - "lsode " - "lsode_options " - "lsqnonneg " - "lstat " - "lt " - "lu " - "luinc " - "luupdate " - "magic " - "mahalanobis " - "make_absolute_filename " - "makeinfo_program " - "manova " - "mark_as_command " - "mark_as_rawcommand " - "mat2cell " - "mat2str " - "matlabroot " - "matrix_type " - "max " - "max_recursion_depth " - "mcnemar_test " - "md5sum " - "mean " - "meansq " - "median " - "menu " - "merge " - "mesh " - "meshc " - "meshgrid " - "meshz " - "methods " - "mex " - "mexext " - "mfilename " - "mgorth " - "min " - "minus " - "mislocked " - "missing_function_hook " - "mist " - "mkdir " - "mkfifo " - "mkoctfile " - "mkpp " - "mkstemp " - "mktime " - "mldivide " - "mlock " - "mod " - "mode " - "moment " - "more " - "most " - "movefile " - "mpoles " - "mpower " - "mrdivide " - "mtimes " - "mu2lin " - "munlock " - "namelengthmax " - "nan " - "nargchk " - "nargin " - "nargout " - "nargoutchk " - "native_float_format " - "nbincdf " - "nbininv " - "nbinpdf " - "nbinrnd " - "nchoosek " - "ndgrid " - "ndims " - "ne " - "newplot " - "news " - "nextpow2 " - "nfields " - "nnz " - "nonzeros " - "norm " - "normcdf " - "normest " - "norminv " - "normpdf " - "normrnd " - "not " - "now " - "nproc " - "nth_element " - "nthroot " - "ntsc2rgb " - "null " - "num2cell " - "num2hex " - "num2str " - "numel " - "nzmax " - "ocean " - "octave_config_info " - "octave_core_file_limit " - "octave_core_file_name " - "octave_core_file_options " - "octave_tmp_file_name " - "ols " - "onCleanup " - "onenormest " - "ones " - "optimget " - "optimize_subsasgn_calls " - "optimset " - "or " - "orderfields " - "orient " - "orth " - "otherwise " - "output_max_field_width " - "output_precision " - "pack " - "page_output_immediately " - "page_screen_output " - "paren " - "pareto " - "parseparams " - "pascal " - "patch " - "path " - "pathdef " - "pathsep " - "pause " - "pbaspect " - "pcg " - "pchip " - "pclose " - "pcolor " - "pcr " - "peaks " - "periodogram " - "perl " - "perms " - "permute " - "perror " - "persistent " - "pi " - "pie " - "pie3 " - "pink " - "pinv " - "pipe " - "pkg " - "planerot " - "playaudio " - "plot " - "plot3 " - "plotmatrix " - "plotyy " - "plus " - "poisscdf " - "poissinv " - "poisspdf " - "poissrnd " - "pol2cart " - "polar " - "poly " - "polyaffine " - "polyarea " - "polyder " - "polyderiv " - "polyfit " - "polygcd " - "polyint " - "polyout " - "polyreduce " - "polyval " - "polyvalm " - "popen " - "popen2 " - "postpad " - "pow2 " - "power " - "powerset " - "ppder " - "ppint " - "ppjumps " - "ppplot " - "ppval " - "pqpnonneg " - "prctile " - "prepad " - "primes " - "print " - "print_empty_dimensions " - "print_struct_array_contents " - "print_usage " - "printf " - "prism " - "probit " - "prod " - "program_invocation_name " - "program_name " - "prop_test_2 " - "putenv " - "puts " - "pwd " - "qp " - "qqplot " - "qr " - "qrdelete " - "qrinsert " - "qrshift " - "qrupdate " - "quad " - "quad_options " - "quadcc " - "quadgk " - "quadl " - "quadv " - "quantile " - "quit " - "quiver " - "quiver3 " - "qz " - "qzhess " - "rainbow " - "rand " - "rande " - "randg " - "randi " - "randn " - "randp " - "randperm " - "range " - "rank " - "ranks " - "rat " - "rats " - "rcond " - "rdivide " - "re_read_readline_init_file " - "readdir " - "readline_re_read_init_file " - "readline_read_init_file " - "readlink " - "real " - "reallog " - "realmax " - "realmin " - "realpow " - "realsqrt " - "record " - "rectangle " - "rectint " - "refresh " - "refreshdata " - "regexp " - "regexpi " - "regexprep " - "regexptranslate " - "rehash " - "rem " - "remove_input_event_hook " - "rename " - "repelems " - "replot " - "repmat " - "reset " - "reshape " - "residue " - "resize " - "restoredefaultpath " - "rethrow " - "return " - "rgb2hsv " - "rgb2ind " - "rgb2ntsc " - "ribbon " - "rindex " - "rmappdata " - "rmdir " - "rmfield " - "rmpath " - "roots " - "rose " - "rosser " - "rot90 " - "rotdim " - "round " - "roundb " - "rows " - "rref " - "rsf2csf " - "run " - "run_count " - "run_history " - "run_test " - "rundemos " - "runlength " - "runtests " - "save " - "save_default_options " - "save_header_format_string " - "save_precision " - "saveas " - "saveaudio " - "saveimage " - "saveobj " - "savepath " - "scanf " - "scatter " - "scatter3 " - "schur " - "sec " - "secd " - "sech " - "semicolon " - "semilogx " - "semilogxerr " - "semilogy " - "semilogyerr " - "set " - "setappdata " - "setaudio " - "setdiff " - "setenv " - "setfield " - "setgrent " - "setpwent " - "setstr " - "setxor " - "shading " - "shell_cmd " - "shg " - "shift " - "shiftdim " - "sighup_dumps_octave_core " - "sign " - "sign_test " - "sigterm_dumps_octave_core " - "silent_functions " - "sin " - "sinc " - "sind " - "sinetone " - "sinewave " - "single " - "sinh " - "size " - "size_equal " - "sizemax " - "sizeof " - "skewness " - "sleep " - "slice " - "sombrero " - "sort " - "sortrows " - "source " - "spalloc " - "sparse " - "sparse_auto_mutate " - "spatan2 " - "spaugment " - "spchol " - "spchol2inv " - "spcholinv " - "spconvert " - "spcumprod " - "spcumsum " - "spdet " - "spdiag " - "spdiags " - "spearman " - "spectral_adf " - "spectral_xdf " - "specular " - "speed " - "spencer " - "speye " - "spfind " - "spfun " - "sph2cart " - "sphcat " - "sphere " - "spinmap " - "spinv " - "spkron " - "splchol " - "spline " - "split " - "split_long_rows " - "splu " - "spmax " - "spmin " - "spones " - "spparms " - "spprod " - "spqr " - "sprand " - "sprandn " - "sprandsym " - "sprank " - "spring " - "sprintf " - "spstats " - "spsum " - "spsumsq " - "spvcat " - "spy " - "sqp " - "sqrt " - "sqrtm " - "squeeze " - "sscanf " - "stairs " - "stat " - "static " - "statistics " - "std " - "stderr " - "stdin " - "stdnormal_cdf " - "stdnormal_inv " - "stdnormal_pdf " - "stdnormal_rnd " - "stdout " - "stem " - "stem3 " - "stft " - "str2double " - "str2func " - "str2mat " - "str2num " - "strcat " - "strchr " - "strcmp " - "strcmpi " - "strerror " - "strfind " - "strftime " - "string_fill_char " - "strjust " - "strmatch " - "strncmp " - "strncmpi " - "strptime " - "strread " - "strrep " - "strsplit " - "strtok " - "strtrim " - "strtrunc " - "struct " - "struct2cell " - "struct_levels_to_print " - "structfun " - "strvcat " - "studentize " - "sub2ind " - "subplot " - "subsasgn " - "subsindex " - "subspace " - "subsref " - "substr " - "substruct " - "sum " - "summer " - "sumsq " - "superiorto " - "suppress_verbose_help_message " - "surf " - "surface " - "surfc " - "surfl " - "surfnorm " - "svd " - "svd_driver " - "svds " - "swapbytes " - "switch " - "syl " - "sylvester_matrix " - "symamd " - "symbfact " - "symlink " - "symrcm " - "symvar " - "synthesis " - "system " - "t_test " - "t_test_2 " - "t_test_regression " - "table " - "tan " - "tand " - "tanh " - "tar " - "tcdf " - "tempdir " - "tempname " - "terminal_size " - "test " - "test2 " - "test3 " - "text " - "textread " - "textscan " - "tic " - "tilde_expand " - "time " - "times " - "tinv " - "title " - "tmpfile " - "tmpnam " - "toascii " - "toc " - "toeplitz " - "tolower " - "toupper " - "tpdf " - "trace " - "transpose " - "trapz " - "treelayout " - "treeplot " - "tril " - "trimesh " - "triplequad " - "triplot " - "trisurf " - "triu " - "trnd " - "true " - "try " - "tsearch " - "tsearchn " - "type " - "typecast " - "typeinfo " - "u_test " - "uigetdir " - "uigetfile " - "uimenu " - "uint16 " - "uint32 " - "uint64 " - "uint8 " - "uiputfile " - "umask " - "uminus " - "uname " - "undo_string_escapes " - "unidcdf " - "unidinv " - "unidpdf " - "unidrnd " - "unifcdf " - "unifinv " - "unifpdf " - "unifrnd " - "union " - "unique " - "unix " - "unlink " - "unmark_command " - "unmark_rawcommand " - "unmkpp " - "unpack " - "untabify " - "untar " - "until " - "unwind_protect " - "unwind_protect_cleanup " - "unwrap " - "unzip " - "uplus " - "upper " - "urlread " - "urlwrite " - "usage " - "usleep " - "validatestring " - "values " - "vander " - "var " - "var_test " - "varargin " - "varargout " - "vec " - "vech " - "vectorize " - "ver " - "version " - "vertcat " - "view " - "voronoi " - "voronoin " - "waitforbuttonpress " - "waitpid " - "warning " - "warning_ids " - "warranty " - "wavread " - "wavwrite " - "wblcdf " - "wblinv " - "wblpdf " - "wblrnd " - "weekday " - "weibcdf " - "weibinv " - "weibpdf " - "weibrnd " - "welch_test " - "what " - "which " - "while " - "white " - "whitebg " - "who " - "whos " - "whos_line_format " - "wienrnd " - "wilcoxon_test " - "wilkinson " - "winter " - "xlabel " - "xlim " - "xor " - "yes_or_no " - "ylabel " - "ylim " - "yulewalker " - "z_test " - "z_test_2 " - "zeros " - "zip " - "zlabel " - "zlim "; - /* "break case catch continue do else elseif end end_unwind_protect " - "endfor endfunction endif endswitch endwhile for function " - "global if otherwise persistent return switch try until " - "unwind_protect unwind_protect_cleanup while"; - */ -} diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/resource-manager.h --- a/libgui/src/resource-manager.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/resource-manager.h Sat Oct 05 11:22:09 2013 -0400 @@ -54,6 +54,11 @@ return instance_ok () ? instance->do_get_home_path () : QString (); } + static QString get_settings_file (void) + { + return instance_ok () ? instance->do_get_settings_file () : QString (); + } + static void reload_settings (void) { if (instance_ok ()) @@ -81,8 +86,6 @@ return instance_ok () ? instance->do_is_first_run () : true; } - static const char *octave_keywords (void); - static QString storage_class_chars (void) { return "afghip"; } static QStringList storage_class_names (void); static QList storage_class_default_colors (void); @@ -119,6 +122,10 @@ QString do_get_home_path (void) const; + QString do_get_settings_file (void); + + QString do_get_settings_path (void); + void do_reload_settings (void); void do_set_settings (const QString& file); diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/welcome-wizard.cc --- a/libgui/src/welcome-wizard.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/welcome-wizard.cc Sat Oct 05 11:22:09 2013 -0400 @@ -25,37 +25,20 @@ #endif #include "welcome-wizard.h" +#include "resource-manager.h" #include "ui-welcome-wizard.h" welcome_wizard::welcome_wizard (QWidget *p) : QDialog (p), _ui (new Ui::welcome_wizard) { _ui->setupUi (this); - connect (_ui->nextButton1, SIGNAL (clicked ()), this, SLOT (next ())); - connect (_ui->nextButton2, SIGNAL (clicked ()), this, SLOT (next ())); - connect (_ui->nextButton3, SIGNAL (clicked ()), this, SLOT (next ())); - connect (_ui->nextButton4, SIGNAL (clicked ()), this, SLOT (next ())); - - connect (_ui->previousButton2, SIGNAL (clicked ()), this, SLOT (previous ())); - connect (_ui->previousButton3, SIGNAL (clicked ()), this, SLOT (previous ())); - connect (_ui->previousButton4, SIGNAL (clicked ()), this, SLOT (previous ())); - connect (_ui->previousButton5, SIGNAL (clicked ()), this, SLOT (previous ())); + QString label_text = _ui->label_config_file->text (); + label_text.replace (QString ("__%1__"), + resource_manager::get_settings_file ()); + _ui->label_config_file->setText (label_text); } welcome_wizard::~welcome_wizard() { delete _ui; } - -void -welcome_wizard::next () -{ - _ui->stackedWidget->setCurrentIndex (_ui->stackedWidget->currentIndex () + 1); -} - -void -welcome_wizard::previous () -{ - _ui->stackedWidget->setCurrentIndex (_ui->stackedWidget->currentIndex () - 1); -} - diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/welcome-wizard.h --- a/libgui/src/welcome-wizard.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/welcome-wizard.h Sat Oct 05 11:22:09 2013 -0400 @@ -38,8 +38,6 @@ ~welcome_wizard (); public slots: - void next (); - void previous (); private: Ui::welcome_wizard *_ui; diff -r 20d1b911b4e7 -r c702371ff6df libgui/src/welcome-wizard.ui --- a/libgui/src/welcome-wizard.ui Thu Sep 12 21:08:07 2013 -0400 +++ b/libgui/src/welcome-wizard.ui Sat Oct 05 11:22:09 2013 -0400 @@ -2,24 +2,27 @@ welcome_wizard + + true + 0 0 - 647 - 400 + 480 + 320 - 647 - 400 + 480 + 320 - 647 - 400 + 480 + 320 @@ -27,308 +30,96 @@ - - - 4 - - - + + + + + + 20 + + + + Welcome to Octave! + + + + + + + You seem to be using the Octave graphical interface for the first time on this computer. Click 'Finish' to write a configuration file and launch Octave GUI. + + + true + + + + + + + The configuration file is stored in __%1__. If that file exists, you will not see this dialog when Octave starts again. + + + true + + + + + + + <html><head/><body><p>For more information about Octave,</p> +<ul> +<li>visit <a href="http://octave.org"><span style=" text-decoration: underline; color:#0000ff;">http://octave.org</span></a>,</li> +<li> get the documentation online as <a href="http://www.gnu.org/software/octave/doc/interpreter/index.html"><span style=" text-decoration: underline; color:#0000ff;">html</span></a>- or <a href="http://www.gnu.org/software/octave/octave.pdf"><span style=" text-decoration: underline; color:#0000ff;">pdf</span></a>-document, or</li> +<li>open the documentation browser of Octave GUI with the help menu.</li> +</ul> +</body></html> + + + true + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + - - - It appears that you have launched Octave GUI for the first time on this computer, since no configuration file could be found at '~/.octave-gui'. This wizard will guide you through the essential settings you should make before you can start using Octave GUI. If you want to transfer your settings you have previously made just close this dialog and copy over the settings file to your home folder. The presence of that file will automatically be detected and will skip this wizard. IMPORTANT: This wizard is not fully functional yet. Just click your way to the end and it will create a standard settings file. - - - Qt::AlignJustify|Qt::AlignVCenter - - - true - - - - - + - Qt::Vertical + Qt::Horizontal - 20 - 218 + 40 + 20 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Next - - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Previous - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Next - - - - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Previous - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Next - - - - - - + + + Finish + + - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Previous - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Next - - - - - - - - - - - - - - - - - - 20 - - - - Welcome to Octave! - - - - - - - This is the development version of Octave with the first official GUI. - - - true - - - - - - - You seem to run Octave GUI for the first time on this computer. This assistant will help you to configure this software installation. Click 'Finish' to write a configuration file and launch Octave GUI. - - - true - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - false - - - Previous - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Finish - - - - - - - - - - + + diff -r 20d1b911b4e7 -r c702371ff6df libinterp/Makefile.am --- a/libinterp/Makefile.am Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/Makefile.am Sat Oct 05 11:22:09 2013 -0400 @@ -20,8 +20,6 @@ include $(top_srcdir)/build-aux/common.mk -AUTOMAKE_OPTIONS = subdir-objects - ## Search local directories before those specified by the user. AM_CPPFLAGS = \ -I$(top_srcdir)/liboctave/cruft/misc \ @@ -51,6 +49,9 @@ corefcn/defaults.h \ corefcn/graphics-props.cc \ corefcn/graphics.h \ + corefcn/oct-tex-lexer.cc \ + corefcn/oct-tex-parser.cc \ + corefcn/oct-tex-symbols.cc \ operators/ops.cc \ parse-tree/lex.cc \ parse-tree/oct-gperf.h \ @@ -62,6 +63,9 @@ builtins.cc BUILT_DISTFILES = \ + corefcn/oct-tex-lexer.ll \ + corefcn/oct-tex-parser.h \ + corefcn/oct-tex-symbols.cc \ parse-tree/oct-gperf.h \ parse-tree/oct-parse.h \ parse-tree/oct-parse.yy @@ -96,7 +100,6 @@ mkdefs \ mkops \ oct-conf.in.h \ - parse-tree/oct-parse.in.yy \ version.in.h \ $(BUILT_DISTFILES) @@ -121,10 +124,12 @@ DIST_SRC = \ octave.cc \ + version.cc \ $(OCTAVE_VALUE_SRC) \ $(PARSE_TREE_SRC) \ $(PARSER_SRC) \ - $(COREFCN_SRC) + $(COREFCN_SRC) \ + $(TEX_PARSER_SRC) noinst_LTLIBRARIES = @@ -150,6 +155,7 @@ liboctinterp_la_SOURCES = \ octave.cc \ + version.cc \ $(OPERATORS_SRC) \ $(TEMPLATE_INST_SRC) @@ -175,6 +181,7 @@ parse-tree/libparse-tree.la \ parse-tree/libparser.la \ corefcn/libcorefcn.la \ + corefcn/libtex_parser.la \ $(top_builddir)/liboctave/liboctave.la \ $(LIBOCTINTERP_LINK_DEPS) @@ -194,7 +201,7 @@ ## Section for defining and creating DEF_FILES ULT_DIST_SRC := \ - $(filter-out parse-tree/oct-parse.yy, $(DIST_SRC)) parse-tree/oct-parse.in.yy + $(filter-out corefcn/oct-tex-lexer.ll parse-tree/oct-parse.yy, $(DIST_SRC)) corefcn/oct-tex-lexer.in.ll parse-tree/oct-parse.in.yy SRC_DEF_FILES := $(shell $(srcdir)/find-defun-files.sh "$(srcdir)" $(ULT_DIST_SRC)) @@ -248,7 +255,7 @@ ## though we don't want it. It would be super awesome if automake ## would allow users to choose the header file extension. .yy.cc: - $(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h $*.h y.output $*.output -- $(YACCCOMPILE) + $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h $*.h y.output $*.output -- $(YACCCOMPILE) ## Special rules: ## Mostly for sources which must be built before rest of compilation. @@ -316,7 +323,7 @@ if AMCOND_ENABLE_DYNAMIC_LINKING install-oct: - $(top_srcdir)/build-aux/mkinstalldirs $(DESTDIR)$(octfiledir) + $(MKDIR_P) $(DESTDIR)$(octfiledir) if [ -n "`cat $(DLDFCN_PKG_ADD_FILE)`" ]; then \ $(INSTALL_DATA) $(DLDFCN_PKG_ADD_FILE) $(DESTDIR)$(octfiledir)/PKG_ADD; \ fi @@ -357,6 +364,7 @@ CLEANFILES = \ $(DLDFCN_PKG_ADD_FILE) \ corefcn/graphics-props.cc \ + corefcn/oct-tex-parser.output \ parse-tree/oct-parse.output DISTCLEANFILES = \ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/action-container.h --- a/libinterp/corefcn/action-container.h Thu Sep 12 21:08:07 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,341 +0,0 @@ -/* - -Copyright (C) 1993-2012 John W. Eaton -Copyright (C) 2009-2010 VZLU Prague - -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 -. - -*/ - -#if !defined (octave_action_container_h) -#define octave_action_container_h 1 - -// This class allows registering actions in a list for later -// execution, either explicitly or when the container goes out of -// scope. - -// FIXME -- is there a better name for this class? - -class -action_container -{ -public: - - // A generic unwind_protect element. Knows how to run itself and - // discard itself. Also, contains a pointer to the next element. - class elem - { - public: - elem (void) { } - - virtual void run (void) { } - - virtual ~elem (void) { } - - friend class action_container; - - private: - - // No copying! - - elem (const elem&); - - elem& operator = (const elem&); - }; - - // An element that merely runs a void (*)(void) function. - - class fcn_elem : public elem - { - public: - fcn_elem (void (*fptr) (void)) - : e_fptr (fptr) { } - - void run (void) { e_fptr (); } - - private: - void (*e_fptr) (void); - }; - - // An element that stores a variable of type T along with a void (*) (T) - // function pointer, and calls the function with the parameter. - - template - class fcn_arg_elem : public elem - { - public: - fcn_arg_elem (void (*fcn) (T), T arg) - : e_fcn (fcn), e_arg (arg) { } - - void run (void) { e_fcn (e_arg); } - - private: - - // No copying! - - fcn_arg_elem (const fcn_arg_elem&); - - fcn_arg_elem& operator = (const fcn_arg_elem&); - - void (*e_fcn) (T); - T e_arg; - }; - - // An element that stores a variable of type T along with a - // void (*) (const T&) function pointer, and calls the function with - // the parameter. - - template - class fcn_crefarg_elem : public elem - { - public: - fcn_crefarg_elem (void (*fcn) (const T&), const T& arg) - : e_fcn (fcn), e_arg (arg) { } - - void run (void) { e_fcn (e_arg); } - - private: - void (*e_fcn) (const T&); - T e_arg; - }; - - // An element for calling a member function. - - template - class method_elem : public elem - { - public: - method_elem (T *obj, void (T::*method) (void)) - : e_obj (obj), e_method (method) { } - - void run (void) { (e_obj->*e_method) (); } - - private: - - T *e_obj; - void (T::*e_method) (void); - - // No copying! - - method_elem (const method_elem&); - - method_elem operator = (const method_elem&); - }; - - // An element for calling a member function with a single argument - - template - class method_arg_elem : public elem - { - public: - method_arg_elem (T *obj, void (T::*method) (A), A arg) - : e_obj (obj), e_method (method), e_arg (arg) { } - - void run (void) { (e_obj->*e_method) (e_arg); } - - private: - - T *e_obj; - void (T::*e_method) (A); - A e_arg; - - // No copying! - - method_arg_elem (const method_arg_elem&); - - method_arg_elem operator = (const method_arg_elem&); - }; - - // An element for calling a member function with a single argument - - template - class method_crefarg_elem : public elem - { - public: - method_crefarg_elem (T *obj, void (T::*method) (const A&), const A& arg) - : e_obj (obj), e_method (method), e_arg (arg) { } - - void run (void) { (e_obj->*e_method) (e_arg); } - - private: - - T *e_obj; - void (T::*e_method) (const A&); - A e_arg; - - // No copying! - - method_crefarg_elem (const method_crefarg_elem&); - - method_crefarg_elem operator = (const method_crefarg_elem&); - }; - - // An element that stores arbitrary variable, and restores it. - - template - class restore_var_elem : public elem - { - public: - restore_var_elem (T& ref, const T& val) - : e_ptr (&ref), e_val (val) { } - - void run (void) { *e_ptr = e_val; } - - private: - - // No copying! - - restore_var_elem (const restore_var_elem&); - - restore_var_elem& operator = (const restore_var_elem&); - - T *e_ptr, e_val; - }; - - // Deletes a class allocated using new. - - template - class delete_ptr_elem : public elem - { - public: - delete_ptr_elem (T *ptr) - : e_ptr (ptr) { } - - void run (void) { delete e_ptr; } - - private: - - T *e_ptr; - - // No copying! - - delete_ptr_elem (const delete_ptr_elem&); - - delete_ptr_elem operator = (const delete_ptr_elem&); - }; - - action_container (void) { } - - virtual ~action_container (void) { } - - virtual void add (elem *new_elem) = 0; - - // Call to void func (void). - void add_fcn (void (*fcn) (void)) - { - add (new fcn_elem (fcn)); - } - - // Call to void func (T). - template - void add_fcn (void (*action) (T), T val) - { - add (new fcn_arg_elem (action, val)); - } - - // Call to void func (const T&). - template - void add_fcn (void (*action) (const T&), const T& val) - { - add (new fcn_crefarg_elem (action, val)); - } - - // Call to T::method (void). - template - void add_method (T *obj, void (T::*method) (void)) - { - add (new method_elem (obj, method)); - } - - // Call to T::method (A). - template - void add_method (T *obj, void (T::*method) (A), A arg) - { - add (new method_arg_elem (obj, method, arg)); - } - - // Call to T::method (const A&). - template - void add_method (T *obj, void (T::*method) (const A&), const A& arg) - { - add (new method_crefarg_elem (obj, method, arg)); - } - - // Call to delete (T*). - - template - void add_delete (T *obj) - { - add (new delete_ptr_elem (obj)); - } - - // Protect any variable. - template - void protect_var (T& var) - { - add (new restore_var_elem (var, var)); - } - - // Protect any variable, value given. - template - void protect_var (T& var, const T& val) - { - add (new restore_var_elem (var, val)); - } - - operator bool (void) const { return ! empty (); } - - virtual void run_first (void) = 0; - - void run (size_t num) - { - if (num > size ()) - num = size (); - - for (size_t i = 0; i < num; i++) - run_first (); - } - - void run (void) { run (size ()); } - - virtual void discard_first (void) = 0; - - void discard (size_t num) - { - if (num > size ()) - num = size (); - - for (size_t i = 0; i < num; i++) - discard_first (); - } - - void discard (void) { discard (size ()); } - - virtual size_t size (void) const = 0; - - bool empty (void) const { return size () == 0; } - -private: - - // No copying! - - action_container (const action_container&); - - action_container& operator = (const action_container&); -}; - -#endif diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/balance.cc --- a/libinterp/corefcn/balance.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/balance.cc Sat Oct 05 11:22:09 2013 -0400 @@ -75,10 +75,10 @@ The eigenvalue balancing option @var{opt} may be one of:\n\ \n\ @table @asis\n\ -@item \"noperm\", \"S\"\n\ +@item @qcode{\"noperm\"}, @qcode{\"S\"}\n\ Scale only; do not permute.\n\ \n\ -@item \"noscal\", \"P\"\n\ +@item @qcode{\"noscal\"}, @qcode{\"P\"}\n\ Permute only; do not scale.\n\ @end table\n\ \n\ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/besselj.cc --- a/libinterp/corefcn/besselj.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/besselj.cc Sat Oct 05 11:22:09 2013 -0400 @@ -649,11 +649,10 @@ } /* -%! # Test values computed with GP/PARI version 2.3.3 -%! +## Test values computed with GP/PARI version 2.3.3 %!shared alpha, x, jx, yx, ix, kx, nix %! -%! # Bessel functions, even order, positive and negative x +%! ## Bessel functions, even order, positive and negative x %! alpha = 2; x = 1.25; %! jx = 0.1710911312405234823613091417; %! yx = -1.193199310178553861283790424; @@ -706,7 +705,7 @@ %!assert (besselh (alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps) %!assert (besselh (alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps) %! -%! # Bessel functions, odd order, positive and negative x +%! ## Bessel functions, odd order, positive and negative x %! alpha = 3; x = 2.5; %! jx = 0.2166003910391135247666890035; %! yx = -0.7560554967536709968379029772; @@ -761,7 +760,7 @@ %!assert (besselh (alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps) %!assert (besselh (alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps) %! -%! # Bessel functions, fractional order, positive and negative x +%! ## Bessel functions, fractional order, positive and negative x %! %! alpha = 3.5; x = 2.75; %! jx = 0.1691636439842384154644784389; @@ -819,7 +818,7 @@ %!assert (besselh (alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps) %!assert (besselh (alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps) %! -%! # Bessel functions, even order, complex x +%! ## Bessel functions, even order, complex x %! %! alpha = 2; x = 1.25 + 3.625 * I; %! jx = -1.299533366810794494030065917 + 4.370833116012278943267479589*I; @@ -855,7 +854,7 @@ %!assert (besselh (-alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps) %!assert (besselh (-alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps) %! -%! # Bessel functions, odd order, complex x +%! ## Bessel functions, odd order, complex x %! %! alpha = 3; x = 2.5 + 1.875 * I; %! jx = 0.1330721523048277493333458596 + 0.5386295217249660078754395597*I; @@ -891,7 +890,7 @@ %!assert (besselh (-alpha,1,x,1), -(jx + I*yx)*exp(-I*x), 100*eps) %!assert (besselh (-alpha,2,x,1), -(jx - I*yx)*exp(I*x), 100*eps) %! -%! # Bessel functions, fractional order, complex x +%! ## Bessel functions, fractional order, complex x %! %! alpha = 3.5; x = 1.75 + 4.125 * I; %! jx = -3.018566131370455929707009100 - 0.7585648436793900607704057611*I; @@ -913,7 +912,7 @@ %!assert (besselh (alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps) %!assert (besselh (alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps) %! -%! nix = 0.09822388691172060573913739253 - 0.7110230642207380127317227407*I; +%! nix = 0.09822388691172060573913739253 - 0.7110230642207380127317227407*I; %! %!assert (besselj (-alpha,x), yx, 100*eps) %!assert (bessely (-alpha,x), -jx, 100*eps) diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/bitfcns.cc --- a/libinterp/corefcn/bitfcns.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/bitfcns.cc Sat Oct 05 11:22:09 2013 -0400 @@ -24,6 +24,8 @@ #include #endif +#include + #include "str-vec.h" #include "quit.h" @@ -38,6 +40,7 @@ #include "ov-int32.h" #include "ov-int16.h" #include "ov-int8.h" +#include "ov-float.h" #include "ov-scalar.h" #include "ov-re-mat.h" #include "ov-bool.h" @@ -138,25 +141,55 @@ if (nargin == 2) { if ((args(0).class_name () == octave_scalar::static_class_name ()) + || (args(0).class_name () == octave_float_scalar::static_class_name ()) || (args(0).class_name () == octave_bool::static_class_name ()) || (args(1).class_name () == octave_scalar::static_class_name ()) + || (args(1).class_name () == octave_float_scalar::static_class_name ()) || (args(1).class_name () == octave_bool::static_class_name ())) { bool arg0_is_int = (args(0).class_name () != octave_scalar::static_class_name () && args(0).class_name () != + octave_float_scalar::static_class_name () && + args(0).class_name () != octave_bool::static_class_name ()); bool arg1_is_int = (args(1).class_name () != octave_scalar::static_class_name () && args(1).class_name () != + octave_float_scalar::static_class_name () && + args(1).class_name () != octave_bool::static_class_name ()); + bool arg0_is_float = args(0).class_name () == + octave_float_scalar::static_class_name (); + bool arg1_is_float = args(1).class_name () == + octave_float_scalar::static_class_name (); if (! (arg0_is_int || arg1_is_int)) { - uint64NDArray x (args(0).array_value ()); - uint64NDArray y (args(1).array_value ()); - if (! error_state) - retval = bitopx (fname, x, y).array_value (); + if (! (arg0_is_float || arg1_is_float)) + { + uint64NDArray x (args(0).array_value ()); + uint64NDArray y (args(1).array_value ()); + if (! error_state) + retval = bitopx (fname, x, y).array_value (); + } + else if (arg0_is_float && arg1_is_float) + { + uint64NDArray x (args(0).float_array_value ()); + uint64NDArray y (args(1).float_array_value ()); + if (! error_state) + retval = bitopx (fname, x, y).float_array_value (); + } + else + { + int p = (arg0_is_float ? 1 : 0); + int q = (arg0_is_float ? 0 : 1); + + uint64NDArray x (args(p).array_value ()); + uint64NDArray y (args(q).float_array_value ()); + if (! error_state) + retval = bitopx (fname, x, y).float_array_value (); + } } else { @@ -344,6 +377,13 @@ return bitop ("bitxor", args); } +template +static int64_t +max_mantissa_value () +{ + return (static_cast (1) << std::numeric_limits::digits) - 1; +} + static int64_t bitshift (double a, int n, int64_t mask) { @@ -543,16 +583,30 @@ DO_SBITSHIFT (int64, nbits < 64 ? nbits : 64); else if (cname == "double") { - nbits = (nbits < 53 ? nbits : 53); - int64_t mask = 0x1FFFFFFFFFFFFFLL; - if (nbits < 53) - mask = mask >> (53 - nbits); + static const int bits_in_mantissa = std::numeric_limits::digits; + nbits = (nbits < bits_in_mantissa ? nbits : bits_in_mantissa); + int64_t mask = max_mantissa_value (); + if (nbits < bits_in_mantissa) + mask = mask >> (bits_in_mantissa - nbits); else if (nbits < 1) mask = 0; - int bits_in_type = 64; + int bits_in_type = sizeof (double) * std::numeric_limits::digits; NDArray m = m_arg.array_value (); DO_BITSHIFT ( ); } + else if (cname == "single") + { + static const int bits_in_mantissa = std::numeric_limits::digits; + nbits = (nbits < bits_in_mantissa ? nbits : bits_in_mantissa); + int64_t mask = max_mantissa_value (); + if (nbits < bits_in_mantissa) + mask = mask >> (bits_in_mantissa - nbits); + else if (nbits < 1) + mask = 0; + int bits_in_type = sizeof (float) * std::numeric_limits::digits; + FloatNDArray m = m_arg.float_array_value (); + DO_BITSHIFT (Float); + } else error ("bitshift: not defined for %s objects", cname.c_str ()); } @@ -568,8 +622,11 @@ @deftypefnx {Built-in Function} {} bitmax (\"double\")\n\ @deftypefnx {Built-in Function} {} bitmax (\"single\")\n\ Return the largest integer that can be represented within a floating point\n\ -value. The default class is \"double\", but \"single\" is a valid option.\n\ -On IEEE-754 compatible systems, @code{bitmax} is @w{@math{2^{53} - 1}}.\n\ +value. The default class is @qcode{\"double\"}, but @qcode{\"single\"} is a\n\ +valid option. On IEEE-754 compatible systems, @code{bitmax} is\n\ +@w{@math{2^{53} - 1}} for @qcode{\"double\"} and @w{@math{2^{24} -1}} for\n\ +@qcode{\"single\"}.\n\ +@seealso{flintmax, intmax, realmax, realmin}\n\ @end deftypefn") { octave_value retval; @@ -585,15 +642,50 @@ } if (cname == "double") - retval = (static_cast (0x1FFFFFFFFFFFFFLL)); + retval = (static_cast (max_mantissa_value ())); else if (cname == "single") - retval = (static_cast (0xFFFFFFL)); + retval = (static_cast (max_mantissa_value ())); else error ("bitmax: not defined for class '%s'", cname.c_str ()); return retval; } +DEFUN (flintmax, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} flintmax ()\n\ +@deftypefnx {Built-in Function} {} flintmax (\"double\")\n\ +@deftypefnx {Built-in Function} {} flintmax (\"single\")\n\ +Return the largest integer that can be represented consecutively in a\n\ +floating point value. The default class is @qcode{\"double\"}, but\n\ +@qcode{\"single\"} is a valid option. On IEEE-754 compatible systems,\n\ +@code{flintmax} is @w{@math{2^53}} for @qcode{\"double\"} and\n\ +@w{@math{2^24}} for @qcode{\"single\"}.\n\ +@seealso{bitmax, intmax, realmax, realmin}\n\ +@end deftypefn") +{ + octave_value retval; + std::string cname = "double"; + int nargin = args.length (); + + if (nargin == 1 && args(0).is_string ()) + cname = args(0).string_value (); + else if (nargin != 0) + { + print_usage (); + return retval; + } + + if (cname == "double") + retval = (static_cast (max_mantissa_value () + 1)); + else if (cname == "single") + retval = (static_cast (max_mantissa_value () + 1)); + else + error ("flintmax: not defined for class '%s'", cname.c_str ()); + + return retval; +} + DEFUN (intmax, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} intmax (@var{type})\n\ @@ -627,7 +719,7 @@ @end table\n\ \n\ The default for @var{type} is @code{uint32}.\n\ -@seealso{intmin, bitmax}\n\ +@seealso{intmin, flintmax, bitmax}\n\ @end deftypefn") { octave_value retval; @@ -697,7 +789,7 @@ @end table\n\ \n\ The default for @var{type} is @code{uint32}.\n\ -@seealso{intmax, bitmax}\n\ +@seealso{intmax, flintmax, bitmax}\n\ @end deftypefn") { octave_value retval; diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/bsxfun.cc --- a/libinterp/corefcn/bsxfun.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/bsxfun.cc Sat Oct 05 11:22:09 2013 -0400 @@ -773,12 +773,12 @@ %% Test automatic bsxfun % %!test -%! funs = {@plus, @minus, @times, @rdivide, @ldivide, @power, @max, @min, \ -%! @rem, @mod, @atan2, @hypot, @eq, @ne, @lt, @le, @gt, @ge, \ +%! funs = {@plus, @minus, @times, @rdivide, @ldivide, @power, @max, @min, ... +%! @rem, @mod, @atan2, @hypot, @eq, @ne, @lt, @le, @gt, @ge, ... %! @and, @or, @xor }; %! %! float_types = {@single, @double}; -%! int_types = {@int8, @int16, @int32, @int64, \ +%! int_types = {@int8, @int16, @int32, @int64, ... %! @uint8, @uint16, @uint32, @uint64}; %! %! x = rand (3) * 10-5; @@ -792,19 +792,19 @@ %! f_type = float_types{j}; %! i_type = int_types{k}; %! -%! assert (bsxfun (fun, f_type (x), i_type (y)), \ +%! assert (bsxfun (fun, f_type (x), i_type (y)), ... %! fun (f_type(x), i_type (y))); -%! assert (bsxfun (fun, f_type (y), i_type (x)), \ +%! assert (bsxfun (fun, f_type (y), i_type (x)), ... %! fun (f_type(y), i_type (x))); %! -%! assert (bsxfun (fun, i_type (x), i_type (y)), \ +%! assert (bsxfun (fun, i_type (x), i_type (y)), ... %! fun (i_type (x), i_type (y))); -%! assert (bsxfun (fun, i_type (y), i_type (x)), \ +%! assert (bsxfun (fun, i_type (y), i_type (x)), ... %! fun (i_type (y), i_type (x))); %! -%! assert (bsxfun (fun, f_type (x), f_type (y)), \ +%! assert (bsxfun (fun, f_type (x), f_type (y)), ... %! fun (f_type (x), f_type (y))); -%! assert (bsxfun (fun, f_type(y), f_type(x)), \ +%! assert (bsxfun (fun, f_type(y), f_type(x)), ... %! fun (f_type (y), f_type (x))); %! endfor %! endfor diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/cellfun.cc --- a/libinterp/corefcn/cellfun.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/cellfun.cc Sat Oct 05 11:22:09 2013 -0400 @@ -133,6 +133,13 @@ result(count) = f_args.elem (count).is_bool_type (); retval(0) = result; } + else if (name == "isnumeric") + { + boolNDArray result (f_args.dims ()); + for (octave_idx_type count= 0; count < k; count++) + result(count) = f_args.elem (count).is_numeric_type (); + retval(0) = result; + } else if (name == "isreal") { boolNDArray result (f_args.dims ()); @@ -154,7 +161,7 @@ result(count) = static_cast (f_args.elem (count).ndims ()); retval(0) = result; } - else if (name == "prodofsize" || name == "numel") + else if (name == "numel" || name == "prodofsize") { NDArray result (f_args.dims ()); for (octave_idx_type count = 0; count < k; count++) @@ -278,6 +285,9 @@ @item islogical\n\ Return 1 for logical elements.\n\ \n\ +@item isnumeric\n\ +Return 1 for numeric elements.\n\ +\n\ @item isreal\n\ Return 1 for real elements.\n\ \n\ @@ -287,7 +297,7 @@ @item ndims\n\ Return the number of dimensions of each element.\n\ \n\ -@item numel\n\ +@item numel\n\ @itemx prodofsize\n\ Return the number of elements contained within each cell element. The\n\ number is the product of the dimensions of the object at each cell element.\n\ @@ -337,10 +347,10 @@ the input arguments. Input arguments that are singleton (1x1) cells will be\n\ automatically expanded to the size of the other arguments.\n\ \n\ -If the parameter \"UniformOutput\" is set to true (the default), then the\n\ -function must return scalars which will be concatenated into the return\n\ -array(s). If \"UniformOutput\" is false, the outputs are concatenated into a\n\ -cell array (or cell arrays). For example:\n\ +If the parameter @qcode{\"UniformOutput\"} is set to true (the default),\n\ +then the function must return scalars which will be concatenated into the\n\ +return array(s). If @qcode{\"UniformOutput\"} is false, the outputs are\n\ +concatenated into a cell array (or cell arrays). For example:\n\ \n\ @example\n\ @group\n\ @@ -350,8 +360,9 @@ @end group\n\ @end example\n\ \n\ -Given the parameter \"ErrorHandler\", then @var{errfunc} defines a function\n\ -to call in case @var{func} generates an error. The form of the function is\n\ +Given the parameter @qcode{\"ErrorHandler\"}, then @var{errfunc} defines a\n\ +function to call in case @var{func} generates an error. The form of the\n\ +function is\n\ \n\ @example\n\ function [@dots{}] = errfunc (@var{s}, @dots{})\n\ @@ -360,9 +371,9 @@ @noindent\n\ where there is an additional input argument to @var{errfunc} relative to\n\ @var{func}, given by @var{s}. This is a structure with the elements\n\ -'identifier', 'message' and 'index', giving respectively the error\n\ -identifier, the error message, and the index into the input arguments\n\ -of the element that caused the error. For example:\n\ +@qcode{\"identifier\"}, @qcode{\"message\"} and @qcode{\"index\"}, giving\n\ +respectively the error identifier, the error message, and the index into the\n\ +input arguments of the element that caused the error. For example:\n\ \n\ @example\n\ @group\n\ @@ -778,7 +789,7 @@ %! assert (A, [true, false, true, false]); %% First input argument can be the special string "isreal", -%% "isempty", "islogical", "length", "ndims" or "prodofsize" +%% "isempty", "islogical", "isnumeric", "length", "ndims" or "prodofsize" %!test %! A = cellfun ("isreal", {true, 0.1, {}, i*2, [], "abc"}); %! assert (A, [true, true, false, false, true, true]); @@ -789,6 +800,9 @@ %! A = cellfun ("islogical", {true, 0.1, false, i*2, [], "abc"}); %! assert (A, [true, false, true, false, false, false]); %!test +%! A = cellfun ("isnumeric", {true, 0.1, false, i*2, [], "abc"}); +%! assert (A, [false, true, false, true, true, false]); +%!test %! A = cellfun ("length", {true, 0.1, false, i*2, [], "abc"}); %! assert (A, [1, 1, 1, 1, 0, 3]); %!test @@ -803,7 +817,7 @@ %! A = cellfun (@(x,y,z) x + y + z, {1, 1, 1}, {2, 2, 2}, {3, 4, 5}); %! assert (A, [6, 7, 8]); %!test -%! A = cellfun (@(x,y,z) x + y + z, {1, 1, 1}, {2, 2, 2}, {3, 4, 5}, \ +%! A = cellfun (@(x,y,z) x + y + z, {1, 1, 1}, {2, 2, 2}, {3, 4, 5}, ... %! "UniformOutput", false); %! assert (A, {6, 7, 8}); %!test %% Two input arguments of different types @@ -824,20 +838,20 @@ %! A = cellfun (@(x,y) x == y, {false, true}, {true, true}); %! assert (A, [false, true]); %!test -%! A = cellfun (@(x,y) x == y, {false; true}, {true; true}, \ +%! A = cellfun (@(x,y) x == y, {false; true}, {true; true}, ... %! "UniformOutput", true); %! assert (A, [false; true]); %!test %! A = cellfun (@(x) x, {false, true; false, true}, "UniformOutput", false); %! assert (A, {false, true; false, true}); %!test %% Three ouptut arguments of same type -%! [A, B, C] = cellfun (@find, {true, false; false, true}, \ +%! [A, B, C] = cellfun (@find, {true, false; false, true}, ... %! "UniformOutput", false); %! assert (isequal (A, {true, []; [], true})); %! assert (isequal (B, {true, []; [], true})); %! assert (isequal (C, {true, []; [], true})); %!test -%! A = cellfun (@(x,y) cell2str (x,y), {true}, {true}, \ +%! A = cellfun (@(x,y) cell2str (x,y), {true}, {true}, ... %! "ErrorHandler", @__cellfunerror); %! assert (isfield (A, "identifier"), true); %! assert (isfield (A, "message"), true); @@ -845,7 +859,7 @@ %! assert (isempty (A.message), false); %! assert (A.index, 1); %!test %% Overwriting setting of "UniformOutput" true -%! A = cellfun (@(x,y) cell2str (x,y), {true}, {true}, \ +%! A = cellfun (@(x,y) cell2str (x,y), {true}, {true}, ... %! "UniformOutput", true, "ErrorHandler", @__cellfunerror); %! assert (isfield (A, "identifier"), true); %! assert (isfield (A, "message"), true); @@ -858,7 +872,7 @@ %! A = cellfun (@(x,y) x>y, {1.1, 4.2}, {3.1, 2+3*i}); %! assert (A, [false, true]); %!test -%! A = cellfun (@(x,y) x>y, {1.1, 4.2; 2, 4}, {3.1, 2; 2, 4+2*i}, \ +%! A = cellfun (@(x,y) x>y, {1.1, 4.2; 2, 4}, {3.1, 2; 2, 4+2*i}, ... %! "UniformOutput", true); %! assert (A, [false, true; false, false]); %!test @@ -871,7 +885,7 @@ %! assert (isequal (B, {true, true; [], true})); %! assert (isequal (C, {10, 11; [], 12})); %!test -%! A = cellfun (@(x,y) cell2str (x,y), {1.1, 4}, {3.1, 6}, \ +%! A = cellfun (@(x,y) cell2str (x,y), {1.1, 4}, {3.1, 6}, ... %! "ErrorHandler", @__cellfunerror); %! B = isfield (A(1), "message") && isfield (A(1), "index"); %! assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]); @@ -880,7 +894,7 @@ %! assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]); %! assert ([A(1).index, A(2).index], [1, 2]); %!test %% Overwriting setting of "UniformOutput" true -%! A = cellfun (@(x,y) cell2str (x,y), {1.1, 4}, {3.1, 6}, \ +%! A = cellfun (@(x,y) cell2str (x,y), {1.1, 4}, {3.1, 6}, ... %! "UniformOutput", true, "ErrorHandler", @__cellfunerror); %! B = isfield (A(1), "message") && isfield (A(1), "index"); %! assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]); @@ -899,7 +913,7 @@ %! A = cellfun (@(x,y) x:y, {"a", "d"}, {"c", "f"}, "UniformOutput", false); %! assert (A, {"abc", "def"}); %!test -%! A = cellfun (@(x,y) cell2str (x,y), {"a", "d"}, {"c", "f"}, \ +%! A = cellfun (@(x,y) cell2str (x,y), {"a", "d"}, {"c", "f"}, ... %! "ErrorHandler", @__cellfunerror); %! assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]); %! assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]); @@ -907,7 +921,7 @@ %! assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]); %! assert ([A(1).index, A(2).index], [1, 2]); %!test %% Overwriting setting of "UniformOutput" true -%! A = cellfun (@(x,y) cell2str (x,y), {"a", "d"}, {"c", "f"}, \ +%! A = cellfun (@(x,y) cell2str (x,y), {"a", "d"}, {"c", "f"}, ... %! "UniformOutput", true, "ErrorHandler", @__cellfunerror); %! assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]); %! assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]); @@ -925,15 +939,15 @@ %! A = cellfun (@(x,y) x{1} < y{1}, {{1.1}, {4.2}}, {{3.1}, {2}}); %! assert (A, [1, 0], 1e-16); %!test -%! A = cellfun (@(x,y) x{1} < y{1}, {{1.1}; {4.2}}, {{3.1}; {2}}, \ +%! A = cellfun (@(x,y) x{1} < y{1}, {{1.1}; {4.2}}, {{3.1}; {2}}, ... %! "UniformOutput", true); %! assert (A, [1; 0], 1e-16); %!test -%! A = cellfun (@(x,y) x{1} < y{1}, {{1.1}, {4.2}}, {{3.1}, {2}}, \ +%! A = cellfun (@(x,y) x{1} < y{1}, {{1.1}, {4.2}}, {{3.1}, {2}}, ... %! "UniformOutput", false); %! assert (A, {true, false}); %!test -%! A = cellfun (@(x,y) mat2str (x,y), {{1.1}, {4.2}}, {{3.1}, {2}}, \ +%! A = cellfun (@(x,y) mat2str (x,y), {{1.1}, {4.2}}, {{3.1}, {2}}, ... %! "ErrorHandler", @__cellfunerror); %! assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]); %! assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]); @@ -941,7 +955,7 @@ %! assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]); %! assert ([A(1).index, A(2).index], [1, 2]); %!test %% Overwriting setting of "UniformOutput" true -%! A = cellfun (@(x,y) mat2str (x,y), {{1.1}, {4.2}}, {{3.1}, {2}}, \ +%! A = cellfun (@(x,y) mat2str (x,y), {{1.1}, {4.2}}, {{3.1}, {2}}, ... %! "UniformOutput", true, "ErrorHandler", @__cellfunerror); %! assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]); %! assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]); @@ -956,17 +970,17 @@ %! assert (A, true); %!test %! a = struct ("a", 1, "b", 2); b = struct ("a", 1, "b", 3); -%! A = cellfun (@(x,y) (x.a == y.a) && (x.b < y.b) , {a}, {b}, \ +%! A = cellfun (@(x,y) (x.a == y.a) && (x.b < y.b) , {a}, {b}, ... %! "UniformOutput", true); %! assert (A, true); %!test %! a = struct ("a", 1, "b", 2); b = struct ("a", 1, "b", 3); -%! A = cellfun (@(x,y) (x.a == y.a) && (x.b < y.b) , {a}, {b}, \ +%! A = cellfun (@(x,y) (x.a == y.a) && (x.b < y.b) , {a}, {b}, ... %! "UniformOutput", false); %! assert (A, {true}); %!test %! a = struct ("a", 1, "b", 2); b = struct ("a", 1, "b", 3); -%! A = cellfun (@(x,y) cell2str (x.a, y.a), {a}, {b}, \ +%! A = cellfun (@(x,y) cell2str (x.a, y.a), {a}, {b}, ... %! "ErrorHandler", @__cellfunerror); %! assert (isfield (A, "identifier"), true); %! assert (isfield (A, "message"), true); @@ -975,7 +989,7 @@ %! assert (A.index, 1); %!test %% Overwriting setting of "UniformOutput" true %! a = struct ("a", 1, "b", 2); b = struct ("a", 1, "b", 3); -%! A = cellfun (@(x,y) cell2str (x.a, y.a), {a}, {b}, \ +%! A = cellfun (@(x,y) cell2str (x.a, y.a), {a}, {b}, ... %! "UniformOutput", true, "ErrorHandler", @__cellfunerror); %! assert (isfield (A, "identifier"), true); %! assert (isfield (A, "message"), true); @@ -989,6 +1003,7 @@ %!assert (cellfun ("sin", {0,1}), sin ([0,1])) %!assert (cellfun ("isempty", {1,[]}), [false,true]) %!assert (cellfun ("islogical", {false,pi}), [true,false]) +%!assert (cellfun ("isnumeric", {false,pi,struct()}), [false,true,false]) %!assert (cellfun ("isreal", {1i,1}), [false,true]) %!assert (cellfun ("length", {zeros(2,2),1}), [2,1]) %!assert (cellfun ("prodofsize", {zeros(2,2),1}), [4,1]) @@ -1056,7 +1071,7 @@ @end example\n\ \n\ If the parameter @var{val} after a further string input argument\n\ -\"UniformOutput\" is set @code{true} (the default), then the named\n\ +@qcode{\"UniformOutput\"} is set @code{true} (the default), then the named\n\ function @var{func} must return a single element which then will be\n\ concatenated into the return value and is of type matrix. Otherwise,\n\ if that parameter is set to @code{false}, then the outputs are\n\ @@ -1101,7 +1116,7 @@ @end example\n\ \n\ If the parameter @var{errfunc} after a further string input argument\n\ -\"ErrorHandler\" is another string, a function handle, an inline\n\ +@qcode{\"ErrorHandler\"} is another string, a function handle, an inline\n\ function, or an anonymous function, then @var{errfunc} defines a\n\ function to call in the case that @var{func} generates an error.\n\ The definition of the function must be of the form\n\ @@ -1113,11 +1128,11 @@ @noindent\n\ where there is an additional input argument to @var{errfunc}\n\ relative to @var{func}, given by @var{s}. This is a structure with\n\ -the elements \"identifier\", \"message\", and \"index\" giving,\n\ -respectively, the error identifier, the error message, and the index of\n\ -the array elements that caused the error. The size of the output\n\ -argument of @var{errfunc} must have the same size as the output\n\ -argument of @var{func}, otherwise a real error is thrown. For\n\ +the elements @qcode{\"identifier\"}, @qcode{\"message\"}, and\n\ +@qcode{\"index\"} giving, respectively, the error identifier, the error\n\ +message, and the index of the array elements that caused the error. The\n\ +size of the output argument of @var{errfunc} must have the same size as the\n\ +output argument of @var{func}, otherwise a real error is thrown. For\n\ example:\n\ \n\ @example\n\ @@ -1545,7 +1560,7 @@ %! assert (isequal (B, {true, []; [], true})); %! assert (isequal (C, {true, []; [], true})); %!test -%! A = arrayfun (@(x,y) array2str (x,y), true, true, \ +%! A = arrayfun (@(x,y) array2str (x,y), true, true, ... %! "ErrorHandler", @__arrayfunerror); %! assert (isfield (A, "identifier"), true); %! assert (isfield (A, "message"), true); @@ -1553,7 +1568,7 @@ %! assert (isempty (A.message), false); %! assert (A.index, 1); %!test %% Overwriting setting of "UniformOutput" true -%! A = arrayfun (@(x,y) array2str (x,y), true, true, "UniformOutput", true, \ +%! A = arrayfun (@(x,y) array2str (x,y), true, true, "UniformOutput", true, ... %! "ErrorHandler", @__arrayfunerror); %! assert (isfield (A, "identifier"), true); %! assert (isfield (A, "message"), true); @@ -1578,7 +1593,7 @@ %! assert (isequal (B, {true, true; [], true})); %! assert (isequal (C, {10, 11; [], 12})); %!test -%! A = arrayfun (@(x,y) array2str (x,y), {1.1, 4}, {3.1, 6}, \ +%! A = arrayfun (@(x,y) array2str (x,y), {1.1, 4}, {3.1, 6}, ... %! "ErrorHandler", @__arrayfunerror); %! B = isfield (A(1), "message") && isfield (A(1), "index"); %! assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]); @@ -1587,7 +1602,7 @@ %! assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]); %! assert ([A(1).index, A(2).index], [1, 2]); %!test %% Overwriting setting of "UniformOutput" true -%! A = arrayfun (@(x,y) array2str (x,y), {1.1, 4}, {3.1, 6}, \ +%! A = arrayfun (@(x,y) array2str (x,y), {1.1, 4}, {3.1, 6}, ... %! "UniformOutput", true, "ErrorHandler", @__arrayfunerror); %! B = isfield (A(1), "message") && isfield (A(1), "index"); %! assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]); @@ -1607,7 +1622,7 @@ %! A = arrayfun (@(x,y) x:y, ["a", "d"], ["c", "f"], "UniformOutput", false); %! assert (A, {"abc", "def"}); %!test -%! A = arrayfun (@(x,y) cell2str (x,y), ["a", "d"], ["c", "f"], \ +%! A = arrayfun (@(x,y) cell2str (x,y), ["a", "d"], ["c", "f"], ... %! "ErrorHandler", @__arrayfunerror); %! B = isfield (A(1), "identifier") && isfield (A(1), "message") && isfield (A(1), "index"); %! assert (B, true); @@ -1633,7 +1648,7 @@ %! assert (isempty (A.message), false); %! assert (A.index, 1); %!test %% Overwriting setting of "UniformOutput" true -%! A = arrayfun (@(x) mat2str(x), "a", "UniformOutput", true, \ +%! A = arrayfun (@(x) mat2str(x), "a", "UniformOutput", true, ... %! "ErrorHandler", @__arrayfunerror); %! assert (isfield (A, "identifier"), true); %! assert (isfield (A, "message"), true); @@ -1659,7 +1674,7 @@ %! assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]); %! assert ([A(1).index, A(2).index], [1, 2]); %!test -%! A = arrayfun (@(x,y) num2str (x,y), {1.1, 4.2}, {3.1, 2}, \ +%! A = arrayfun (@(x,y) num2str (x,y), {1.1, 4.2}, {3.1, 2}, ... %! "UniformOutput", true, "ErrorHandler", @__arrayfunerror); %! assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]); %! assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]); @@ -2215,7 +2230,7 @@ bool sparse = a.is_sparse_type (); if (sparse && nargin > 3) { - error ("mat2cell: sparse arguments only support 2D indexing"); + error ("mat2cell: sparse arguments only support 2-D indexing"); return retval; } diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/conv2.cc --- a/libinterp/corefcn/conv2.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/conv2.cc Sat Oct 05 11:22:09 2013 -0400 @@ -44,15 +44,15 @@ values\n\ \n\ @table @asis\n\ -@item @var{shape} = \"full\"\n\ +@item @var{shape} = @qcode{\"full\"}\n\ Return the full convolution. (default)\n\ \n\ -@item @var{shape} = \"same\"\n\ +@item @var{shape} = @qcode{\"same\"}\n\ Return the central part of the convolution with the same size as @var{A}.\n\ The central part of the convolution begins at the indices\n\ @code{floor ([size(@var{B})/2] + 1)}.\n\ \n\ -@item @var{shape} = \"valid\"\n\ +@item @var{shape} = @qcode{\"valid\"}\n\ Return only the parts which do not include zero-padded edges.\n\ The size of the result is @code{max (size (A) - size (B) + 1, 0)}.\n\ @end table\n\ @@ -277,7 +277,7 @@ %! y = ones (5); %! A = conv2 (x, y)(5:end-4,5:end-4); %! B = conv2 (x, y, "valid"); -%! assert (B, A); ## Yes, this test is for *exact* equivalence. +%! assert (B, A); # Yes, this test is for *exact* equivalence. %% Test input validation @@ -299,15 +299,15 @@ values\n\ \n\ @table @asis\n\ -@item @var{shape} = \"full\"\n\ +@item @var{shape} = @qcode{\"full\"}\n\ Return the full convolution. (default)\n\ \n\ -@item @var{shape} = \"same\"\n\ +@item @var{shape} = @qcode{\"same\"}\n\ Return central part of the convolution with the same size as @var{A}.\n\ The central part of the convolution begins at the indices\n\ @code{floor ([size(@var{B})/2] + 1)}.\n\ \n\ -@item @var{shape} = \"valid\"\n\ +@item @var{shape} = @qcode{\"valid\"}\n\ Return only the parts which do not include zero-padded edges.\n\ The size of the result is @code{max (size (A) - size (B) + 1, 0)}.\n\ @end table\n\ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/data.cc --- a/libinterp/corefcn/data.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/data.cc Sat Oct 05 11:22:09 2013 -0400 @@ -1095,8 +1095,8 @@ Cumulative sum of elements along dimension @var{dim}. If @var{dim}\n\ is omitted, it defaults to the first non-singleton dimension.\n\ \n\ -See @code{sum} for an explanation of the optional parameters \"native\",\n\ -\"double\", and \"extra\".\n\ +See @code{sum} for an explanation of the optional parameters\n\ +@qcode{\"native\"}, @qcode{\"double\"}, and @qcode{\"extra\"}.\n\ @seealso{sum, cumprod}\n\ @end deftypefn") { @@ -2375,10 +2375,13 @@ DEFUN (length, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} length (@var{a})\n\ -Return the \"length\" of the object @var{a}. For matrix objects, the\n\ -length is the number of rows or columns, whichever is greater (this\n\ -odd definition is used for compatibility with @sc{matlab}).\n\ -@seealso{size}\n\ +Return the length of the object @var{a}.\n\ +\n\ +The length is 0 for empty objects, 1 for scalars, and the number of elements\n\ +for vectors. For matrix objects, the length is the number of rows or\n\ +columns, whichever is greater (this odd definition is used for compatibility\n\ +with @sc{matlab}).\n\ +@seealso{numel, size}\n\ @end deftypefn") { octave_value retval; @@ -2671,9 +2674,9 @@ Sum of elements along dimension @var{dim}. If @var{dim} is\n\ omitted, it defaults to the first non-singleton dimension.\n\ \n\ -If the optional argument \"native\" is given, then the sum is performed\n\ -in the same type as the original argument, rather than in the default\n\ -double type. For example:\n\ +If the optional argument @qcode{\"native\"} is given, then the sum is\n\ +performed in the same type as the original argument, rather than in the\n\ +default double type. For example:\n\ \n\ @example\n\ @group\n\ @@ -2684,13 +2687,13 @@ @end group\n\ @end example\n\ \n\ -On the contrary, if \"double\" is given, the sum is performed in double\n\ -precision even for single precision inputs.\n\ -\n\ -For double precision inputs, \"extra\" indicates that a more accurate\n\ +On the contrary, if @qcode{\"double\"} is given, the sum is performed in\n\ +double precision even for single precision inputs.\n\ +\n\ +For double precision inputs, @qcode{\"extra\"} indicates that a more accurate\n\ algorithm than straightforward summation is to be used. For single precision\n\ -inputs, \"extra\" is the same as \"double\". Otherwise, \"extra\" has no\n\ -effect.\n\ +inputs, @qcode{\"extra\"} is the same as @qcode{\"double\"}. Otherwise,\n\ +@qcode{\"extra\"} has no effect.\n\ @seealso{cumsum, sumsq, prod}\n\ @end deftypefn") { @@ -3970,7 +3973,7 @@ arguments are taken as the number of rows and columns and any further\n\ arguments specify additional matrix dimensions.\n\ The optional argument @var{class} specifies the return type and may be\n\ -either \"double\" or \"single\".\n\ +either @qcode{\"double\"} or @qcode{\"single\"}.\n\ @seealso{isinf, NaN}\n\ @end deftypefn") { @@ -4029,7 +4032,7 @@ arguments are taken as the number of rows and columns and any further\n\ arguments specify additional matrix dimensions.\n\ The optional argument @var{class} specifies the return type and may be\n\ -either \"double\" or \"single\".\n\ +either @qcode{\"double\"} or @qcode{\"single\"}.\n\ @seealso{isnan, Inf}\n\ @end deftypefn") { @@ -4078,7 +4081,7 @@ arguments are taken as the number of rows and columns and any further\n\ arguments specify additional matrix dimensions.\n\ The optional argument @var{class} specifies the return type and may be\n\ -either \"double\" or \"single\".\n\ +either @qcode{\"double\"} or @qcode{\"single\"}.\n\ @seealso{log, exp, pi, I}\n\ @end deftypefn") { @@ -4119,7 +4122,7 @@ the number of rows and columns and any further\n\ arguments specify additional matrix dimensions.\n\ The optional argument @var{class} specifies the return type and may be\n\ -either \"double\" or \"single\".\n\ +either @qcode{\"double\"} or @qcode{\"single\"}.\n\ @seealso{realmax, realmin, intmax, bitmax}\n\ @end deftypefn") { @@ -4243,7 +4246,7 @@ arguments are taken as the number of rows and columns and any further\n\ arguments specify additional matrix dimensions.\n\ The optional argument @var{class} specifies the return type and may be\n\ -either \"double\" or \"single\".\n\ +either @qcode{\"double\"} or @qcode{\"single\"}.\n\ @seealso{e, I}\n\ @end deftypefn") { @@ -4276,13 +4279,13 @@ for single precision.\n\ \n\ When called with no arguments, return a scalar with the value\n\ -@code{realmax (\"double\")}.\n\ +@code{realmax (@qcode{\"double\"})}.\n\ When called with a single argument, return a square matrix with the dimension\n\ specified. When called with more than one scalar argument the first two\n\ arguments are taken as the number of rows and columns and any further\n\ arguments specify additional matrix dimensions.\n\ The optional argument @var{class} specifies the return type and may be\n\ -either \"double\" or \"single\".\n\ +either @qcode{\"double\"} or @qcode{\"single\"}.\n\ @seealso{realmin, intmax, bitmax, eps}\n\ @end deftypefn") { @@ -4310,13 +4313,13 @@ for single precision.\n\ \n\ When called with no arguments, return a scalar with the value\n\ -@code{realmin (\"double\")}.\n\ +@code{realmin (@qcode{\"double\"})}.\n\ When called with a single argument, return a square matrix with the dimension\n\ specified. When called with more than one scalar argument the first two\n\ arguments are taken as the number of rows and columns and any further\n\ arguments specify additional matrix dimensions.\n\ The optional argument @var{class} specifies the return type and may be\n\ -either \"double\" or \"single\".\n\ +either @qcode{\"double\"} or @qcode{\"single\"}.\n\ @seealso{realmax, intmin, eps}\n\ @end deftypefn") { @@ -4354,7 +4357,7 @@ arguments are taken as the number of rows and columns and any further\n\ arguments specify additional matrix dimensions.\n\ The optional argument @var{class} specifies the return type and may be\n\ -either \"double\" or \"single\".\n\ +either @qcode{\"double\"} or @qcode{\"single\"}.\n\ @seealso{e, pi, log, exp}\n\ @end deftypefn") { @@ -4384,7 +4387,7 @@ arguments are taken as the number of rows and columns and any further\n\ arguments specify additional matrix dimensions.\n\ The optional argument @var{class} specifies the return type and may be\n\ -either \"double\" or \"single\".\n\ +either @qcode{\"double\"} or @qcode{\"single\"}.\n\ @seealso{isna}\n\ @end deftypefn") { @@ -4783,9 +4786,9 @@ %! assert (size (x2) == [1, 10] && x2(1) == 1 && x2(10) == 2); %! assert (size (x3) == [1, 10] && x3(1) == 1 && x3(10) == -2); -%assert (linspace ([1, 2; 3, 4], 5, 6), linspace (1, 5, 6)) - -%assert (linspace (0, 1, []), 1) +%! ##assert (linspace ([1, 2; 3, 4], 5, 6), linspace (1, 5, 6)) + +%!assert (linspace (0, 1, []), 1) %!error linspace () %!error linspace (1, 2, 3, 4) @@ -5144,11 +5147,11 @@ @item @var{p} = @code{2}\n\ Largest singular value of @var{A}.\n\ \n\ -@item @var{p} = @code{Inf} or @code{\"inf\"}\n\ +@item @var{p} = @code{Inf} or @qcode{\"inf\"}\n\ @cindex infinity norm\n\ Infinity norm, the largest row sum of the absolute values of @var{A}.\n\ \n\ -@item @var{p} = @code{\"fro\"}\n\ +@item @var{p} = @qcode{\"fro\"}\n\ @cindex Frobenius norm\n\ Frobenius norm of @var{A}, @code{sqrt (sum (diag (@var{A}' * @var{A})))}.\n\ \n\ @@ -5160,13 +5163,13 @@ If @var{A} is a vector or a scalar:\n\ \n\ @table @asis\n\ -@item @var{p} = @code{Inf} or @code{\"inf\"}\n\ +@item @var{p} = @code{Inf} or @qcode{\"inf\"}\n\ @code{max (abs (@var{A}))}.\n\ \n\ @item @var{p} = @code{-Inf}\n\ @code{min (abs (@var{A}))}.\n\ \n\ -@item @var{p} = @code{\"fro\"}\n\ +@item @var{p} = @qcode{\"fro\"}\n\ Frobenius norm of @var{A}, @code{sqrt (sumsq (abs (A)))}.\n\ \n\ @item @var{p} = 0\n\ @@ -5179,10 +5182,10 @@ the p-pseudonorm defined as above.\n\ @end table\n\ \n\ -If @var{opt} is the value @code{\"rows\"}, treat each row as a vector and\n\ +If @var{opt} is the value @qcode{\"rows\"}, treat each row as a vector and\n\ compute its norm. The result is returned as a column vector.\n\ -Similarly, if @var{opt} is @code{\"columns\"} or @code{\"cols\"} then compute\n\ -the norms of each column and return a row vector.\n\ +Similarly, if @var{opt} is @qcode{\"columns\"} or @qcode{\"cols\"} then\n\ +compute the norms of each column and return a row vector.\n\ @seealso{cond, svd}\n\ @end deftypefn") { @@ -5213,29 +5216,53 @@ // we've handled the last parameter, so act as if it was removed nargin --; } - else if (nargin > 1 && ! args(1).is_scalar_type ()) - gripe_wrong_type_arg ("norm", args(1), true); if (! error_state) { octave_value p_arg = (nargin > 1) ? args(1) : octave_value (2); - switch (strflag) + + if (p_arg.is_empty ()) + p_arg = octave_value (2); + else if (p_arg.is_string ()) { - case sfmatrix: - retval(0) = xnorm (x_arg, p_arg); - break; - case sfcols: - retval(0) = xcolnorms (x_arg, p_arg); - break; - case sfrows: - retval(0) = xrownorms (x_arg, p_arg); - break; - case sffrob: - retval(0) = xfrobnorm (x_arg); - break; - case sfinf: - retval(0) = xnorm (x_arg, octave_Inf); - break; + std::string str = p_arg.string_value (); + if ((strflag == sfcols || strflag == sfrows)) + { + if (str == "cols" || str == "columns" || str == "rows") + error ("norm: invalid combination of options"); + else if (str == "fro") + p_arg = octave_value (2); + else if (str == "inf") + p_arg = octave_Inf; + else + error ("norm: unrecognized option: %s", str.c_str ()); + } + else + error ("norm: invalid combination of options"); + } + else if (! p_arg.is_scalar_type ()) + gripe_wrong_type_arg ("norm", p_arg, true); + + if (! error_state) + { + switch (strflag) + { + case sfmatrix: + retval(0) = xnorm (x_arg, p_arg); + break; + case sfcols: + retval(0) = xcolnorms (x_arg, p_arg); + break; + case sfrows: + retval(0) = xrownorms (x_arg, p_arg); + break; + case sffrob: + retval(0) = xfrobnorm (x_arg); + break; + case sfinf: + retval(0) = xnorm (x_arg, octave_Inf); + break; + } } } } @@ -5299,6 +5326,18 @@ %!assert (norm (flo*m2,"fro"), single (sqrt (30)*flo), -eps ("single")) %!assert (norm (fhi*m2,"fro"), single (sqrt (30)*fhi), -eps ("single")) +%!shared q +%! q = rand (1e3, 3); +%!assert (norm (q, 3, "rows"), sum (q.^3, 2).^(1/3), sqrt (eps)); +%!assert (norm (q, "fro", "rows"), sum (q.^2, 2).^(1/2), sqrt (eps)); +%!assert (norm (q, "fro", "rows"), sqrt (sumsq (q, 2)), sqrt (eps)); +%!assert (norm (q, "fro", "cols"), sqrt (sumsq (q, 1)), sqrt (eps)); +%!assert (norm (q, 3, "cols"), sum (q.^3, 1).^(1/3), sqrt (eps)); +%!assert (norm (q, "inf", "rows"), norm (q, Inf, "rows")); +%!assert (norm (q, "inf", "cols"), norm (q, Inf, "cols")); +%!assert (norm (q, [], "rows"), norm (q, 2, "rows")); +%!assert (norm (q, [], "cols"), norm (q, 2, "cols")); + %!test %! ## Test for norm returning NaN on sparse matrix (bug #30631) %! A = sparse (2,2); @@ -5333,7 +5372,7 @@ DEFUN (uplus, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} uplus (@var{x})\n\ -This function and @w{@xcode{+ x}} are equivalent.\n\ +This function and @w{@tcode{+ x}} are equivalent.\n\ @seealso{uminus, plus, minus}\n\ @end deftypefn") { @@ -5343,7 +5382,7 @@ DEFUN (uminus, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} uminus (@var{x})\n\ -This function and @w{@xcode{- x}} are equivalent.\n\ +This function and @w{@tcode{- x}} are equivalent.\n\ @seealso{uplus, minus}\n\ @end deftypefn") { @@ -5354,7 +5393,7 @@ "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} transpose (@var{x})\n\ Return the transpose of @var{x}.\n\ -This function and @xcode{x.'} are equivalent.\n\ +This function and @tcode{x.'} are equivalent.\n\ @seealso{ctranspose}\n\ @end deftypefn") { @@ -5385,7 +5424,7 @@ "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} ctranspose (@var{x})\n\ Return the complex conjugate transpose of @var{x}.\n\ -This function and @xcode{x'} are equivalent.\n\ +This function and @tcode{x'} are equivalent.\n\ @seealso{transpose}\n\ @end deftypefn") { @@ -5459,7 +5498,7 @@ "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} plus (@var{x}, @var{y})\n\ @deftypefnx {Built-in Function} {} plus (@var{x1}, @var{x2}, @dots{})\n\ -This function and @w{@xcode{x + y}} are equivalent.\n\ +This function and @w{@tcode{x + y}} are equivalent.\n\ If more arguments are given, the summation is applied\n\ cumulatively from left to right:\n\ \n\ @@ -5478,7 +5517,7 @@ DEFUN (minus, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} minus (@var{x}, @var{y})\n\ -This function and @w{@xcode{x - y}} are equivalent.\n\ +This function and @w{@tcode{x - y}} are equivalent.\n\ @seealso{plus, uminus}\n\ @end deftypefn") { @@ -5490,7 +5529,7 @@ @deftypefn {Built-in Function} {} mtimes (@var{x}, @var{y})\n\ @deftypefnx {Built-in Function} {} mtimes (@var{x1}, @var{x2}, @dots{})\n\ Return the matrix multiplication product of inputs.\n\ -This function and @w{@xcode{x * y}} are equivalent.\n\ +This function and @w{@tcode{x * y}} are equivalent.\n\ If more arguments are given, the multiplication is applied\n\ cumulatively from left to right:\n\ \n\ @@ -5510,7 +5549,7 @@ "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} mrdivide (@var{x}, @var{y})\n\ Return the matrix right division of @var{x} and @var{y}.\n\ -This function and @w{@xcode{x / y}} are equivalent.\n\ +This function and @w{@tcode{x / y}} are equivalent.\n\ @seealso{mldivide, rdivide, plus, minus}\n\ @end deftypefn") { @@ -5521,7 +5560,7 @@ "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} mpower (@var{x}, @var{y})\n\ Return the matrix power operation of @var{x} raised to the @var{y} power.\n\ -This function and @w{@xcode{x ^ y}} are equivalent.\n\ +This function and @w{@tcode{x ^ y}} are equivalent.\n\ @seealso{power, mtimes, plus, minus}\n\ @end deftypefn") { @@ -5532,7 +5571,7 @@ "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} mldivide (@var{x}, @var{y})\n\ Return the matrix left division of @var{x} and @var{y}.\n\ -This function and @w{@xcode{x @xbackslashchar{} y}} are equivalent.\n\ +This function and @w{@tcode{x @xbackslashchar{} y}} are equivalent.\n\ @seealso{mrdivide, ldivide, rdivide}\n\ @end deftypefn") { @@ -5606,7 +5645,7 @@ @deftypefn {Built-in Function} {} times (@var{x}, @var{y})\n\ @deftypefnx {Built-in Function} {} times (@var{x1}, @var{x2}, @dots{})\n\ Return the element-by-element multiplication product of inputs.\n\ -This function and @w{@xcode{x .* y}} are equivalent.\n\ +This function and @w{@tcode{x .* y}} are equivalent.\n\ If more arguments are given, the multiplication is applied\n\ cumulatively from left to right:\n\ \n\ @@ -5626,7 +5665,7 @@ "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} rdivide (@var{x}, @var{y})\n\ Return the element-by-element right division of @var{x} and @var{y}.\n\ -This function and @w{@xcode{x ./ y}} are equivalent.\n\ +This function and @w{@tcode{x ./ y}} are equivalent.\n\ @seealso{ldivide, mrdivide, times, plus}\n\ @end deftypefn") { @@ -5642,7 +5681,7 @@ @code{realpow}, @code{realsqrt}, @code{cbrt}, or @code{nthroot} if a\n\ real result is preferred.\n\ \n\ -This function and @w{@xcode{x .^ y}} are equivalent.\n\ +This function and @w{@tcode{x .^ y}} are equivalent.\n\ @seealso{mpower, realpow, realsqrt, cbrt, nthroot}\n\ @end deftypefn") { @@ -5653,7 +5692,7 @@ "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} ldivide (@var{x}, @var{y})\n\ Return the element-by-element left division of @var{x} and @var{y}.\n\ -This function and @w{@xcode{x .@xbackslashchar{} y}} are equivalent.\n\ +This function and @w{@tcode{x .@xbackslashchar{} y}} are equivalent.\n\ @seealso{rdivide, mldivide, times, plus}\n\ @end deftypefn") { @@ -5929,7 +5968,7 @@ If the optional argument @var{dim} is given, then the matrix is sorted\n\ along the dimension defined by @var{dim}. The optional argument @code{mode}\n\ defines the order in which the values will be sorted. Valid values of\n\ -@code{mode} are \"ascend\" or \"descend\".\n\ +@code{mode} are @qcode{\"ascend\"} or @qcode{\"descend\"}.\n\ \n\ The @code{sort} function may also be used to produce a matrix\n\ containing the original row indices of the elements in the sorted\n\ @@ -6322,11 +6361,11 @@ @deftypefnx {Built-in Function} {} issorted (@var{a}, @var{mode})\n\ @deftypefnx {Built-in Function} {} issorted (@var{a}, \"rows\", @var{mode})\n\ Return true if the array is sorted according to @var{mode}, which\n\ -may be either \"ascending\", \"descending\", or \"either\". By default,\n\ - @var{mode} is \"ascending\". NaNs are treated in the same manner as\n\ -@code{sort}.\n\ -\n\ -If the optional argument \"rows\" is supplied, check whether\n\ +may be either @qcode{\"ascending\"}, @qcode{\"descending\"}, or\n\ +@qcode{\"either\"}. By default, @var{mode} is @qcode{\"ascending\"}. NaNs\n\ +are treated in the same manner as @code{sort}.\n\ +\n\ +If the optional argument @qcode{\"rows\"} is supplied, check whether\n\ the array is sorted by rows as output by the function @code{sortrows}\n\ (with no options).\n\ \n\ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/debug.cc --- a/libinterp/corefcn/debug.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/debug.cc Sat Oct 05 11:22:09 2013 -0400 @@ -917,8 +917,8 @@ \n\ When called with no arguments in debugging mode, display the script file\n\ currently being debugged. An optional range specification can be used to\n\ -list only a portion of the file. The special keyword \"end\" is a valid\n\ -line number specification for the last line of the file.\n\ +list only a portion of the file. The special keyword @qcode{\"end\"} is a\n\ +valid line number specification for the last line of the file.\n\ \n\ When called with the name of a function, list that script file with line\n\ numbers.\n\ @@ -1041,7 +1041,7 @@ @deftypefn {Command} {} dblist\n\ @deftypefnx {Command} {} dblist @var{n}\n\ In debugging mode, list @var{n} lines of the function being debugged\n\ -centered around the the current line to be executed. If unspecified @var{n}\n\ +centered around the current line to be executed. If unspecified @var{n}\n\ defaults to 10 (+/- 5 lines)\n\ @seealso{dbwhere, dbtype}\n\ @end deftypefn") diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/defaults.cc --- a/libinterp/corefcn/defaults.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/defaults.cc Sat Oct 05 11:22:09 2013 -0400 @@ -474,11 +474,12 @@ use with the @code{edit_history} command. The default value is taken from\n\ the environment variable @w{@env{EDITOR}} when Octave starts. If the\n\ environment variable is not initialized, @w{@env{EDITOR}} will be set to\n\ -@code{\"emacs\"}.\n\ +@qcode{\"emacs\"}.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ +\n\ @seealso{edit_history}\n\ @end deftypefn") { @@ -508,9 +509,11 @@ @w{@env{OCTAVE_EXEC_PATH}}, but that value can be overridden by\n\ the command line argument @option{--exec-path PATH}.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ +\n\ +@seealso{IMAGE_PATH, OCTAVE_HOME}\n\ @end deftypefn") { octave_value retval = SET_NONEMPTY_INTERNAL_STRING_VARIABLE (EXEC_PATH); @@ -541,9 +544,11 @@ Query or set the internal variable that specifies a colon separated\n\ list of directories in which to search for image files.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ +\n\ +@seealso{EXEC_PATH, OCTAVE_HOME}\n\ @end deftypefn") { return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (IMAGE_PATH); @@ -565,6 +570,8 @@ "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} OCTAVE_HOME ()\n\ Return the name of the top-level Octave installation directory.\n\ +\n\ +@seealso{EXEC_PATH, IMAGE_PATH}\n\ @end deftypefn") { octave_value retval; diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/dirfns.cc --- a/libinterp/corefcn/dirfns.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/dirfns.cc Sat Oct 05 11:22:09 2013 -0400 @@ -94,11 +94,16 @@ DEFUN (cd, args, nargout, "-*- texinfo -*-\n\ -@deftypefn {Command} {} cd dir\n\ -@deftypefnx {Command} {} chdir dir\n\ -Change the current working directory to @var{dir}. If @var{dir} is\n\ -omitted, the current directory is changed to the user's home\n\ -directory. For example,\n\ +@deftypefn {Command} {} cd @var{dir}\n\ +@deftypefnx {Command} {} cd\n\ +@deftypefnx {Built-in Function} {@var{old_dir} =} cd @var{dir}\n\ +@deftypefnx {Command} {} chdir @dots{}\n\ +Change the current working directory to @var{dir}.\n\ +\n\ +If @var{dir} is omitted, the current directory is changed to the user's home\n\ +directory (@qcode{\"~\"}).\n\ +\n\ +For example,\n\ \n\ @example\n\ cd ~/octave\n\ @@ -108,7 +113,13 @@ changes the current working directory to @file{~/octave}. If the\n\ directory does not exist, an error message is printed and the working\n\ directory is not changed.\n\ -@seealso{mkdir, rmdir, dir}\n\ +\n\ +@code{chdir} is an alias for @code{cd} and can be used in all of the same\n\ +calling formats.\n\ +\n\ +Compatibility Note: When called with no arguments, @sc{matlab} prints the\n\ +present working directory rather than changing to the user's home directory.\n\ +@seealso{pwd, mkdir, rmdir, dir, ls}\n\ @end deftypefn") { octave_value_list retval; @@ -120,30 +131,22 @@ if (error_state) return retval; + if (nargout > 0) + retval = octave_value (octave_env::get_current_directory ()); + if (argc > 1) { std::string dirname = argv[1]; - if (dirname.length () > 0 - && ! octave_change_to_directory (dirname)) - { - return retval; - } + if (dirname.length () > 0) + octave_change_to_directory (dirname); } else { - // Behave like Unixy shells for "cd" by itself, but be Matlab - // compatible if doing "current_dir = cd". + std::string home_dir = octave_env::get_home_directory (); - if (nargout == 0) - { - std::string home_dir = octave_env::get_home_directory (); - - if (home_dir.empty () || ! octave_change_to_directory (home_dir)) - return retval; - } - else - retval = octave_value (octave_env::get_current_directory ()); + if (! home_dir.empty ()) + octave_change_to_directory (home_dir); } return retval; @@ -153,9 +156,10 @@ DEFUN (pwd, , , "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {} pwd ()\n\ +@deftypefn {Built-in Function} {} pwd ()\n\ +@deftypefnx {Built-in Function} {@var{dir} =} pwd ()\n\ Return the current working directory.\n\ -@seealso{dir, ls}\n\ +@seealso{cd, dir, ls, mkdir, rmdir}\n\ @end deftypefn") { return octave_value (octave_env::get_current_directory ()); @@ -163,14 +167,16 @@ DEFUN (readdir, args, , "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {[@var{files}, @var{err}, @var{msg}] =} readdir (@var{dir})\n\ -Return names of the files in the directory @var{dir} as a cell array of\n\ -strings. If an error occurs, return an empty cell array in @var{files}.\n\ +@deftypefn {Built-in Function} {@var{files} =} readdir (@var{dir})\n\ +@deftypefnx {Built-in Function} {[@var{files}, @var{err}, @var{msg}] =} readdir (@var{dir})\n\ +Return the names of files in the directory @var{dir} as a cell array of\n\ +strings.\n\ \n\ +If an error occurs, return an empty cell array in @var{files}.\n\ If successful, @var{err} is 0 and @var{msg} is an empty string.\n\ Otherwise, @var{err} is nonzero and @var{msg} contains a\n\ system-dependent error message.\n\ -@seealso{ls, dir, glob}\n\ +@seealso{ls, dir, glob, what}\n\ @end deftypefn") { octave_value_list retval; @@ -207,20 +213,24 @@ return retval; } -// FIXME -- should maybe also allow second arg to specify -// mode? OTOH, that might cause trouble with compatibility later... +// FIXME: should maybe also allow second arg to specify mode? +// OTOH, that might cause trouble with compatibility later... DEFUNX ("mkdir", Fmkdir, args, , "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} mkdir (@var{dir})\n\ -@deftypefnx {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} mkdir (@var{parent}, @var{dir})\n\ +@deftypefn {Built-in Function} {} mkdir @var{dir}\n\ +@deftypefnx {Built-in Function} {} mkdir (@var{parent}, @var{dir})\n\ +@deftypefnx {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} mkdir (@dots{})\n\ Create a directory named @var{dir} in the directory @var{parent}.\n\ \n\ -If successful, @var{status} is 1, with @var{msg} and @var{msgid} empty\n\ -character strings. Otherwise, @var{status} is 0, @var{msg} contains a\n\ -system-dependent error message, and @var{msgid} contains a unique\n\ -message identifier.\n\ -@seealso{rmdir}\n\ +If no @var{parent} directory is specified the present working directory is\n\ +used.\n\ +\n\ +If successful, @var{status} is 1, and @var{msg}, @var{msgid} are empty\n\ +character strings (""). Otherwise, @var{status} is 0, @var{msg} contains a\n\ +system-dependent error message, and @var{msgid} contains a unique message\n\ +identifier.\n\ +@seealso{rmdir, pwd, cd}\n\ @end deftypefn") { octave_value_list retval; @@ -295,18 +305,19 @@ DEFUNX ("rmdir", Frmdir, args, , "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} rmdir (@var{dir})\n\ -@deftypefnx {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} rmdir (@var{dir}, \"s\")\n\ +@deftypefn {Built-in Function} {} rmdir @var{dir}\n\ +@deftypefnx {Built-in Function} {} rmdir (@var{dir}, \"s\")\n\ +@deftypefnx {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} rmdir (@dots{})\n\ Remove the directory named @var{dir}.\n\ \n\ -If successful, @var{status} is 1, with @var{msg} and @var{msgid} empty\n\ -character strings. Otherwise, @var{status} is 0, @var{msg} contains a\n\ -system-dependent error message, and @var{msgid} contains a unique\n\ -message identifier.\n\ +If successful, @var{status} is 1, and @var{msg}, @var{msgid} are empty\n\ +character strings (""). Otherwise, @var{status} is 0, @var{msg} contains a\n\ +system-dependent error message, and @var{msgid} contains a unique message\n\ +identifier.\n\ \n\ -If the optional second parameter is supplied with value @code{\"s\"},\n\ +If the optional second parameter is supplied with value @qcode{\"s\"},\n\ recursively remove all subdirectories as well.\n\ -@seealso{mkdir, confirm_recursive_rmdir}\n\ +@seealso{mkdir, confirm_recursive_rmdir, pwd}\n\ @end deftypefn") { octave_value_list retval; @@ -369,13 +380,14 @@ DEFUNX ("link", Flink, args, , "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} link (@var{old}, @var{new})\n\ +@deftypefn {Built-in Function} {} link @var{old} @var{new}\n\ +@deftypefnx {Built-in Function} {[@var{err}, @var{msg}] =} link (@var{old}, @var{new})\n\ Create a new link (also known as a hard link) to an existing file.\n\ \n\ If successful, @var{err} is 0 and @var{msg} is an empty string.\n\ Otherwise, @var{err} is nonzero and @var{msg} contains a\n\ system-dependent error message.\n\ -@seealso{symlink}\n\ +@seealso{symlink, unlink, readlink, lstat}\n\ @end deftypefn") { octave_value_list retval; @@ -401,10 +413,9 @@ int status = octave_link (from, to, msg); - retval(0) = status; - if (status < 0) retval(1) = msg; + retval(0) = status; } } } @@ -416,13 +427,14 @@ DEFUNX ("symlink", Fsymlink, args, , "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} symlink (@var{old}, @var{new})\n\ +@deftypefn {Built-in Function} {} symlink @var{old} @var{new}\n\ +@deftypefnx {Built-in Function} {[@var{err}, @var{msg}] =} symlink (@var{old}, @var{new})\n\ Create a symbolic link @var{new} which contains the string @var{old}.\n\ \n\ If successful, @var{err} is 0 and @var{msg} is an empty string.\n\ Otherwise, @var{err} is nonzero and @var{msg} contains a\n\ system-dependent error message.\n\ -@seealso{link, readlink}\n\ +@seealso{link, unlink, readlink, lstat}\n\ @end deftypefn") { octave_value_list retval; @@ -448,10 +460,9 @@ int status = octave_symlink (from, to, msg); - retval(0) = status; - if (status < 0) retval(1) = msg; + retval(0) = status; } } } @@ -463,14 +474,15 @@ DEFUNX ("readlink", Freadlink, args, , "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {[@var{result}, @var{err}, @var{msg}] =} readlink (@var{symlink})\n\ +@deftypefn {Built-in Function} {} readlink @var{symlink}\n\ +@deftypefnx {Built-in Function} {[@var{result}, @var{err}, @var{msg}] =} readlink (@var{symlink})\n\ Read the value of the symbolic link @var{symlink}.\n\ \n\ If successful, @var{result} contains the contents of the symbolic link\n\ -@var{symlink}, @var{err} is 0 and @var{msg} is an empty string.\n\ -Otherwise, @var{err} is nonzero and @var{msg} contains a\n\ -system-dependent error message.\n\ -@seealso{link, symlink}\n\ +@var{symlink}, @var{err} is 0, and @var{msg} is an empty string.\n\ +Otherwise, @var{err} is nonzero and @var{msg} contains a system-dependent\n\ +error message.\n\ +@seealso{lstat, symlink, link, unlink, delete}\n\ @end deftypefn") { octave_value_list retval; @@ -506,13 +518,14 @@ DEFUNX ("rename", Frename, args, , "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} rename (@var{old}, @var{new})\n\ +@deftypefn {Built-in Function} {} rename @var{old} @var{new}\n\ +@deftypefnx {Built-in Function} {[@var{err}, @var{msg}] =} rename (@var{old}, @var{new})\n\ Change the name of file @var{old} to @var{new}.\n\ \n\ If successful, @var{err} is 0 and @var{msg} is an empty string.\n\ Otherwise, @var{err} is nonzero and @var{msg} contains a\n\ system-dependent error message.\n\ -@seealso{ls, dir}\n\ +@seealso{movefile, copyfile, ls, dir}\n\ @end deftypefn") { octave_value_list retval; @@ -538,10 +551,9 @@ int status = octave_rename (from, to, msg); - retval(0) = status; - if (status < 0) retval(1) = msg; + retval(0) = status; } } } @@ -571,9 +583,8 @@ matches any of the enclosed characters.\n\ @end table\n\ \n\ -Tilde expansion\n\ -is performed on each of the patterns before looking for matching file\n\ -names. For example:\n\ +Tilde expansion is performed on each of the patterns before looking for\n\ +matching file names. For example:\n\ \n\ @example\n\ ls\n\ @@ -597,7 +608,7 @@ [2,1] = file2\n\ @}\n\ @end example\n\ -@seealso{ls, dir, readdir}\n\ +@seealso{ls, dir, readdir, what, fnmatch}\n\ @end deftypefn") { octave_value retval; @@ -628,7 +639,7 @@ %! if (mkdir (tmpdir)) %! cwd = pwd; %! cd (tmpdir); -%! if strcmp (canonicalize_file_name (pwd), canonicalize_file_name (tmpdir)) +%! if (strcmp (canonicalize_file_name (pwd), canonicalize_file_name (tmpdir))) %! a = 0; %! for n = 1:5 %! save (filename{n}, "a"); @@ -656,7 +667,7 @@ DEFUNX ("fnmatch", Ffnmatch, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} fnmatch (@var{pattern}, @var{string})\n\ -Return 1 or zero for each element of @var{string} that matches any of\n\ +Return true or false for each element of @var{string} that matches any of\n\ the elements of the string array @var{pattern}, using the rules of\n\ filename pattern matching. For example:\n\ \n\ @@ -666,6 +677,7 @@ @result{} [ 1; 1; 0 ]\n\ @end group\n\ @end example\n\ +@seealso{glob, regexp}\n\ @end deftypefn") { octave_value retval; @@ -696,8 +708,8 @@ @deftypefnx {Built-in Function} {} filesep (\"all\")\n\ Return the system-dependent character used to separate directory names.\n\ \n\ -If \"all\" is given, the function returns all valid file separators in\n\ -the form of a string. The list of file separators is system-dependent.\n\ +If @qcode{\"all\"} is given, the function returns all valid file separators\n\ +in the form of a string. The list of file separators is system-dependent.\n\ It is @samp{/} (forward slash) under UNIX or @w{Mac OS X}, @samp{/} and\n\ @samp{\\} (forward and backward slashes) under Windows.\n\ @seealso{pathsep}\n\ @@ -780,9 +792,10 @@ Query or set the internal variable that controls whether Octave\n\ will ask for confirmation before recursively removing a directory tree.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ +@seealso{rmdir}\n\ @end deftypefn") { return SET_INTERNAL_VARIABLE (confirm_recursive_rmdir); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/dlmread.cc --- a/libinterp/corefcn/dlmread.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/dlmread.cc Sat Oct 05 11:22:09 2013 -0400 @@ -173,14 +173,15 @@ The @var{range} parameter may be a 4-element vector containing the upper\n\ left and lower right corner @code{[@var{R0},@var{C0},@var{R1},@var{C1}]}\n\ where the lowest index value is zero. Alternatively, a spreadsheet style\n\ -range such as \"A2..Q15\" or \"T1:AA5\" can be used. The lowest alphabetical\n\ -index 'A' refers to the first column. The lowest row index is 1.\n\ +range such as @qcode{\"A2..Q15\"} or @qcode{\"T1:AA5\"} can be used. The\n\ +lowest alphabetical index @qcode{'A'} refers to the first column. The\n\ +lowest row index is 1.\n\ \n\ @var{file} should be a file name or file id given by @code{fopen}. In the\n\ latter case, the file is read until end of file is reached.\n\ \n\ -The \"emptyvalue\" option may be used to specify the value used to fill empty\n\ -fields. The default is zero.\n\ +The @qcode{\"emptyvalue\"} option may be used to specify the value used to\n\ +fill empty fields. The default is zero.\n\ @seealso{csvread, textscan, textread, dlmwrite}\n\ @end deftypefn") { diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/ellipj.cc --- a/libinterp/corefcn/ellipj.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/ellipj.cc Sat Oct 05 11:22:09 2013 -0400 @@ -1,6 +1,6 @@ /* -// Author: Leopoldo Cerbaro +Copyright (C) 2013 Leopoldo Cerbaro This file is part of Octave. @@ -26,7 +26,7 @@ #include "defun.h" #include "error.h" -#include "lo-ieee.h" +#include "lo-specfun.h" static void gripe_ellipj_arg (const char *arg) @@ -34,106 +34,6 @@ error ("ellipj: expecting scalar or matrix as %s argument", arg); } -static void -sncndn (double u, double m, double& sn, double& cn, double& dn, double& err) -{ - static const int Nmax = 16; - double m1, t=0, si_u, co_u, se_u, ta_u, b, c[Nmax], a[Nmax], phi; - int n, Nn, ii; - - if (m < 0 || m > 1) - { - warning ("ellipj: expecting 0 <= m <= 1"); /* -lc- */ - sn = cn = dn = lo_ieee_nan_value (); - return; - } - - double sqrt_eps = sqrt (std::numeric_limits::epsilon ()); - if (m < sqrt_eps) - { - /* # For small m, ( Abramowitz and Stegun, Section 16.13 ) */ - si_u = sin (u); - co_u = cos (u); - t = 0.25*m*(u - si_u*co_u); - sn = si_u - t * co_u; - cn = co_u + t * si_u; - dn = 1 - 0.5*m*si_u*si_u; - } - else if ((1 - m) < sqrt_eps) - { - /* For m1 = (1-m) small ( Abramowitz and Stegun, Section 16.15 ) */ - m1 = 1 - m; - si_u = sinh (u); - co_u = cosh (u); - ta_u = tanh (u); - se_u = 1/co_u; - sn = ta_u + 0.25*m1*(si_u*co_u - u)*se_u*se_u; - cn = se_u - 0.25*m1*(si_u*co_u - u)*ta_u*se_u; - dn = se_u + 0.25*m1*(si_u*co_u + u)*ta_u*se_u; - } - else - { - /* - // Arithmetic-Geometric Mean (AGM) algorithm - // ( Abramowitz and Stegun, Section 16.4 ) - */ - - a[0] = 1; - b = sqrt (1 - m); - c[0] = sqrt (m); - for (n = 1; n < Nmax; ++n) - { - a[n] = (a[n - 1] + b)/2; - c[n] = (a[n - 1] - b)/2; - b = sqrt (a[n - 1]*b); - if (c[n]/a[n] < std::numeric_limits::epsilon ()) break; - } - if (n >= Nmax - 1) - { - err = 1; - return; - } - Nn = n; - for (ii = 1; n > 0; ii = ii*2, --n) ; // ii = pow(2,Nn) - phi = ii*a[Nn]*u; - for (n = Nn; n > 0; --n) - { - t = phi; - phi = (asin ((c[n]/a[n])* sin (phi)) + phi)/2; - } - sn = sin (phi); - cn = cos (phi); - dn = cn/cos (t - phi); - } -} - -static void -sncndn (Complex& u, double m, Complex& sn, Complex& cn, Complex& dn, - double& err) -{ - double m1 = 1 - m, ss1, cc1, dd1; - - sncndn (imag (u), m1, ss1, cc1, dd1, err); - if (real (u) == 0) - { - /* u is pure imag: Jacoby imag. transf. */ - sn = Complex (0, ss1/cc1); - cn = 1/cc1; // cn.imag = 0; - dn = dd1/cc1; // dn.imag = 0; - } - else - { - /* u is generic complex */ - double ss, cc, dd, ddd; - - sncndn (real (u), m, ss, cc, dd, err); - ddd = cc1*cc1 + m*ss*ss*ss1*ss1; - sn = Complex (ss*dd1/ddd, cc*dd*ss1*cc1/ddd); - cn = Complex (cc*cc1/ddd, -ss*dd*ss1*dd1/ddd); - dn = Complex (dd*cc1*dd1/ddd, -m*ss*cc*ss1/ddd); - } -} - DEFUN (ellipj, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {[@var{sn}, @var{cn}, @var{dn}, @var{err}] =} ellipj (@var{u}, @var{m})\n\ @@ -146,13 +46,14 @@ If @var{u} is a column vector and @var{m} is a row vector, the\n\ results are matrices with @code{length (@var{u})} rows and\n\ @code{length (@var{m})} columns. Otherwise, @var{u} and\n\ -@var{m} must conform and the results will be the same size.\n\ +@var{m} must conform in size and the results will be the same size as the\n\ +inputs.\n\ \n\ The value of @var{u} may be complex.\n\ -The value of @var{m} must be 0 @leq{} m @leq{} 1.\n\ +The value of @var{m} must be 0 @leq{} @var{m} @leq{} 1.\n\ \n\ -@var{tol} is currently ignored (@sc{matlab} uses this to allow faster,\n\ -less accurate approximation).\n\ +The optional input @var{tol} is currently ignored (@sc{matlab} uses this to\n\ +allow faster, less accurate approximation).\n\ \n\ If requested, @var{err} contains the following status information\n\ and is the same size as the result.\n\ @@ -165,9 +66,11 @@ Error---no computation, algorithm termination condition not met,\n\ return @code{NaN}.\n\ @end enumerate\n\ - Ref: Abramowitz, Milton and Stegun, Irene A\n\ - Handbook of Mathematical Functions, Dover, 1965\n\ - Chapter 16 (Sections 16.4, 16.13 and 16.15)\n\ +\n\ +Reference: Milton Abramowitz and Irene A Stegun,\n\ +@cite{Handbook of Mathematical Functions}, Chapter 16 (Sections 16.4, 16.13,\n\ +and 16.15), Dover, 1965.\n\ +\n\ @seealso{ellipke}\n\ @end deftypefn") { @@ -197,7 +100,7 @@ if (u_arg.is_scalar_type ()) { if (u_arg.is_real_type ()) - { // u real + { // u real, m scalar double u = args(0).double_value (); if (error_state) @@ -205,65 +108,75 @@ gripe_ellipj_arg ("first"); return retval; } + double sn, cn, dn; double err = 0; - sncndn (u, m, sn, cn, dn, err); - retval (0) = sn; - retval (1) = cn; - retval (2) = dn; - if (nargout > 3) retval(3) = err; + ellipj (u, m, sn, cn, dn, err); + + if (nargout > 3) + retval(3) = err; + retval(2) = dn; + retval(1) = cn; + retval(0) = sn; } else - { // u complex + { // u complex, m scalar Complex u = u_arg.complex_value (); if (error_state) { - gripe_ellipj_arg ("second"); + gripe_ellipj_arg ("first"); return retval; } Complex sn, cn, dn; - double err; + double err = 0; - sncndn (u, m, sn, cn, dn, err); + ellipj (u, m, sn, cn, dn, err); - retval (0) = sn; - retval (1) = cn; - retval (2) = dn; - if (nargout > 3) retval(3) = err; + if (nargout > 3) + retval(3) = err; + retval(2) = dn; + retval(1) = cn; + retval(0) = sn; } } else - { /* u is matrix ( m is scalar ) */ - ComplexMatrix u = u_arg.complex_matrix_value (); - + { // u is matrix, m is scalar + ComplexNDArray u = u_arg.complex_array_value (); + if (error_state) { gripe_ellipj_arg ("first"); return retval; } - octave_idx_type nr = u.rows (); - octave_idx_type nc = u.cols (); + dim_vector sz_u = u.dims (); - ComplexMatrix sn (nr, nc), cn (nr, nc), dn (nr, nc); - Matrix err (nr, nc); + ComplexNDArray sn (sz_u), cn (sz_u), dn (sz_u); + NDArray err (sz_u); - for (octave_idx_type j = 0; j < nc; j++) - for (octave_idx_type i = 0; i < nr; i++) - sncndn (u(i,j), m, sn(i,j), cn(i,j), dn(i,j), err(i,j)); + const Complex *pu = u.data (); + Complex *psn = sn.fortran_vec (); + Complex *pcn = cn.fortran_vec (); + Complex *pdn = dn.fortran_vec (); + double *perr = err.fortran_vec (); + octave_idx_type nel = u.numel (); - retval (0) = sn; - retval (1) = cn; - retval (2) = dn; - if (nargout > 3) retval(3) = err; + for (octave_idx_type i = 0; i < nel; i++) + ellipj (pu[i], m, psn[i], pcn[i], pdn[i], perr[i]); + + if (nargout > 3) + retval(3) = err; + retval(2) = dn; + retval(1) = cn; + retval(0) = sn; } } else { - Matrix m = args(1).matrix_value (); + NDArray m = args(1).array_value (); if (error_state) { @@ -271,17 +184,12 @@ return retval; } - octave_idx_type mr = m.rows (); - octave_idx_type mc = m.cols (); + dim_vector sz_m = m.dims (); if (u_arg.is_scalar_type ()) - { /* u is scalar */ - octave_idx_type nr = m.rows (); - octave_idx_type nc = m.cols (); - Matrix err (nr, nc); - + { // u is scalar, m is array if (u_arg.is_real_type ()) - { + { // u is real scalar, m is array double u = u_arg.double_value (); if (error_state) @@ -290,129 +198,176 @@ return retval; } - Matrix sn (nr, nc), cn (nr, nc), dn (nr, nc); - for (octave_idx_type j = 0; j < nc; j++) - for (octave_idx_type i = 0; i < nr; i++) - sncndn (u, m(i,j), sn(i,j), cn(i,j), dn(i,j), err(i,j)); + NDArray sn (sz_m), cn (sz_m), dn (sz_m); + NDArray err (sz_m); - retval (0) = sn; - retval (1) = cn; - retval (2) = dn; - if (nargout > 3) retval(3) = err; + const double *pm = m.data (); + double *psn = sn.fortran_vec (); + double *pcn = cn.fortran_vec (); + double *pdn = dn.fortran_vec (); + double *perr = err.fortran_vec (); + octave_idx_type nel = m.numel (); + + for (octave_idx_type i = 0; i < nel; i++) + ellipj (u, pm[i], psn[i], pcn[i], pdn[i], perr[i]); + + if (nargout > 3) + retval(3) = err; + retval(2) = dn; + retval(1) = cn; + retval(0) = sn; } else - { + { // u is complex scalar, m is array Complex u = u_arg.complex_value (); + + if (error_state) + { + gripe_ellipj_arg ("first"); + return retval; + } + + ComplexNDArray sn (sz_m), cn (sz_m), dn (sz_m); + NDArray err (sz_m); + + const double *pm = m.data (); + Complex *psn = sn.fortran_vec (); + Complex *pcn = cn.fortran_vec (); + Complex *pdn = dn.fortran_vec (); + double *perr = err.fortran_vec (); + octave_idx_type nel = m.numel (); + + for (octave_idx_type i = 0; i < nel; i++) + ellipj (u, pm[i], psn[i], pcn[i], pdn[i], perr[i]); + + if (nargout > 3) + retval(3) = err; + retval(2) = dn; + retval(1) = cn; + retval(0) = sn; + } + } + else + { // u is array, m is array + if (u_arg.is_real_type ()) + { // u is real array, m is array + NDArray u = u_arg.array_value (); + if (error_state) { gripe_ellipj_arg ("first"); return retval; } - ComplexMatrix sn (nr, nc), cn (nr, nc), dn (nr, nc); - for (octave_idx_type j = 0; j < nc; j++) - for (octave_idx_type i = 0; i < nr; i++) - sncndn (u, m(i,j), sn(i,j), cn(i,j), dn(i,j), err(i,j)); - retval (0) = sn; - retval (1) = cn; - retval (2) = dn; - if (nargout > 3) retval(3) = err; - } - } - else - { // u is matrix (m is matrix) - if (u_arg.is_real_type ()) - { // u real matrix + dim_vector sz_u = u.dims (); - Matrix u = u_arg.matrix_value (); - if (error_state) - { - gripe_ellipj_arg ("first "); - return retval; - } + if (sz_u.length () == 2 && sz_m.length () == 2 + && sz_u(1) == 1 && sz_m(0) == 1) + { // u is real column vector, m is row vector + octave_idx_type ur = sz_u(0); + octave_idx_type mc = sz_m(1); + dim_vector sz_out (ur, mc); - octave_idx_type ur = u.rows (); - octave_idx_type uc = u.cols (); + NDArray sn (sz_out), cn (sz_out), dn (sz_out); + NDArray err (sz_out); - if (mr == 1 && uc == 1) - { // u column, m row - RowVector rm = m.row (0); - ColumnVector cu = u.column (0); - - Matrix sn (ur, mc), cn (ur, mc), dn (ur, mc); - Matrix err (ur,mc); + const double *pu = u.data (); + const double *pm = m.data (); for (octave_idx_type j = 0; j < mc; j++) for (octave_idx_type i = 0; i < ur; i++) - sncndn (cu(i), rm(j), sn(i,j), cn(i,j), dn(i,j), err(i,j)); + ellipj (pu[i], pm[j], sn(i,j), cn(i,j), dn(i,j), err(i,j)); - retval (0) = sn; - retval (1) = cn; - retval (2) = dn; - if (nargout > 3) retval(3) = err; + if (nargout > 3) + retval(3) = err; + retval(2) = dn; + retval(1) = cn; + retval(0) = sn; } - else if (ur == mr && uc == mc) + else if (sz_m == sz_u) { - Matrix sn (ur, mc), cn (ur, mc), dn (ur, mc); - Matrix err (ur,mc); + NDArray sn (sz_m), cn (sz_m), dn (sz_m); + NDArray err (sz_m); - for (octave_idx_type j = 0; j < uc; j++) - for (octave_idx_type i = 0; i < ur; i++) - sncndn (u(i,j), m(i,j), sn(i,j), cn(i,j), dn(i,j), err(i,j)); + const double *pu = u.data (); + const double *pm = m.data (); + double *psn = sn.fortran_vec (); + double *pcn = cn.fortran_vec (); + double *pdn = dn.fortran_vec (); + double *perr = err.fortran_vec (); + octave_idx_type nel = m.numel (); - retval (0) = sn; - retval (1) = cn; - retval (2) = dn; - if (nargout > 3) retval(3) = err; + for (octave_idx_type i = 0; i < nel; i++) + ellipj (pu[i], pm[i], psn[i], pcn[i], pdn[i], perr[i]); + + if (nargout > 3) + retval(3) = err; + retval(2) = dn; + retval(1) = cn; + retval(0) = sn; } else - error ("u m invalid"); + error ("ellipj: Invalid size combination for U and M"); } else - { // u complex matrix - ComplexMatrix u = u_arg.complex_matrix_value (); + { // u is complex array, m is array + ComplexNDArray u = u_arg.complex_array_value (); + if (error_state) { gripe_ellipj_arg ("second"); return retval; } - octave_idx_type ur = u.rows (); - octave_idx_type uc = u.cols (); + dim_vector sz_u = u.dims (); - if (mr == 1 && uc == 1) - { - RowVector rm = m.row (0); - ComplexColumnVector cu = u.column (0); + if (sz_u.length () == 2 && sz_m.length () == 2 + && sz_u(1) == 1 && sz_m(0) == 1) + { // u is complex column vector, m is row vector + octave_idx_type ur = sz_u(0); + octave_idx_type mc = sz_m(1); + dim_vector sz_out (ur, mc); - ComplexMatrix sn (ur, mc), cn (ur, mc), dn (ur, mc); - Matrix err (ur,mc); + ComplexNDArray sn (sz_out), cn (sz_out), dn (sz_out); + NDArray err (sz_out); + + const Complex *pu = u.data (); + const double *pm = m.data (); for (octave_idx_type j = 0; j < mc; j++) for (octave_idx_type i = 0; i < ur; i++) - sncndn (cu(i), rm(j), sn(i,j), cn(i,j), dn(i,j), err(i,j)); + ellipj (pu[i], pm[j], sn(i,j), cn(i,j), dn(i,j), err(i,j)); - retval (0) = sn; - retval (1) = cn; - retval (2) = dn; - if (nargout > 3) retval(3) = err; + if (nargout > 3) + retval(3) = err; + retval(2) = dn; + retval(1) = cn; + retval(0) = sn; } - else if (ur == mr && uc == mc) + else if (sz_m == sz_u) { - ComplexMatrix sn (ur, mc), cn (ur, mc), dn (ur, mc); - Matrix err (ur,mc); + ComplexNDArray sn (sz_m), cn (sz_m), dn (sz_m); + NDArray err (sz_m); - for (octave_idx_type j = 0; j < uc; j++) - for (octave_idx_type i = 0; i < ur; i++) - sncndn (u(i,j), m(i,j), sn(i,j), cn(i,j), dn(i,j), err(i,j)); + const Complex *pu = u.data (); + const double *pm = m.data (); + Complex *psn = sn.fortran_vec (); + Complex *pcn = cn.fortran_vec (); + Complex *pdn = dn.fortran_vec (); + double *perr = err.fortran_vec (); + octave_idx_type nel = m.numel (); - retval (0) = sn; - retval (1) = cn; - retval (2) = dn; - if (nargout > 3) retval(3) = err; + for (octave_idx_type i = 0; i < nel; i++) + ellipj (pu[i], pm[i], psn[i], pcn[i], pdn[i], perr[i]); + + if (nargout > 3) + retval(3) = err; + retval(2) = dn; + retval(1) = cn; + retval(0) = sn; } else - error ("u m invalid"); + error ("ellipj: Invalid size combination for U and M"); } } } // m matrix @@ -425,53 +380,52 @@ %!demo %! N = 150; -%! % m = [1-logspace(0,log(eps),N-1), 1]; ## m near 1 -%! % m = [0, logspace(log(eps),0,N-1)]; ## m near 0 -%! m = linspace(0,1,N); ## m equally spaced -%! u = linspace(-20,20,N); -%! M = ones(length(u),1) * m; -%! U = u' * ones(1, length(m)); -%! [sn, cn, dn] = ellipj(U,M); +%! # m = [1-logspace(0,log(eps),N-1), 1]; # m near 1 +%! # m = [0, logspace(log(eps),0,N-1)]; # m near 0 +%! m = linspace (0,1,N); # m equally spaced +%! u = linspace (-20, 20, N); +%! M = ones (length (u), 1) * m; +%! U = u' * ones (1, length (m)); +%! [sn, cn, dn] = ellipj (U,M); %! -%! %% Plotting -%! c = colormap(hot(64)); +%! ## Plotting %! data = {sn,cn,dn}; %! dname = {"sn","cn","dn"}; %! for i=1:3 -%! subplot(1,3,i); +%! subplot (1,3,i); %! data{i}(data{i} > 1) = 1; %! data{i}(data{i} < -1) = -1; -%! image(m,u,32*data{i}+32); -%! title(dname{i}); -%! end -%! colormap(c); +%! image (m,u,32*data{i}+32); +%! title (dname{i}); +%! endfor +%! colormap (hot (64)); %!demo %! N = 200; -%! % m = [1-logspace(0,log(eps),N-1), 1]; ## m near 1 -%! % m = [0, logspace(log(eps),0,N-1)]; ## m near 0 -%! m = linspace(0,1,N); ## m equally spaced -%! u = linspace(0,20,5); -%! M = ones(length(u),1) * m; -%! U = u' * ones(1, length(m)); -%! [sn, cn, dn] = ellipj(U,M); +%! # m = [1-logspace(0,log(eps),N-1), 1]; # m near 1 +%! # m = [0, logspace(log(eps),0,N-1)]; # m near 0 +%! m = linspace (0,1,N); # m equally spaced +%! u = linspace (0,20,5); +%! M = ones (length (u), 1) * m; +%! U = u' * ones (1, length (m)); +%! [sn, cn, dn] = ellipj (U,M); %! -%! %% Plotting +%! ## Plotting %! data = {sn,cn,dn}; %! dname = {"sn","cn","dn"}; %! for i=1:3 -%! subplot(1,3,i); -%! plot(m, data{i}); -%! title(dname{i}); +%! subplot (1,3,i); +%! plot (m, data{i}); +%! title (dname{i}); %! grid on; -%! end +%! endfor */ /* ## tests taken from inst/test_sncndn.m %!test -%! k = (tan(pi/8.))^2; m = k*k; +%! k = (tan(pi/8.))^2; m = k*k; %! SN = [ %! -1. + I * 0. , -0.8392965923 + 0. * I %! -1. + I * 0.2 , -0.8559363407 + 0.108250955 * I @@ -848,9 +802,9 @@ %! ui = y * 0.2; %! ii = 1 + y + x*11; %! [sn, cn, dn] = ellipj (ur + I * ui, m); -%! assert (SN (ii, 2), sn, tol); -%! assert (CN (ii, 2), cn, tol); -%! assert (DN (ii, 2), dn, tol); +%! assert (sn, SN(ii, 2), tol); +%! assert (cn, CN(ii, 2), tol); +%! assert (dn, DN(ii, 2), tol); %! endfor %! endfor @@ -858,61 +812,69 @@ %!test %! u1 = pi/3; m1 = 0; %! res1 = [sin(pi/3), cos(pi/3), 1]; -%! [sn,cn,dn]=ellipj(u1,m1); -%! assert([sn,cn,dn], res1, 10*eps); +%! [sn,cn,dn] = ellipj (u1,m1); +%! assert ([sn,cn,dn], res1, 10*eps); %!test %! u2 = log(2); m2 = 1; %! res2 = [ 3/5, 4/5, 4/5 ]; -%! [sn,cn,dn]=ellipj(u2,m2); -%! assert([sn,cn,dn], res2, 10*eps); +%! [sn,cn,dn] = ellipj (u2,m2); +%! assert ([sn,cn,dn], res2, 10*eps); %!test %! u3 = log(2)*1i; m3 = 0; %! res3 = [3i/4,5/4,1]; -%! [sn,cn,dn]=ellipj(u3,m3); -%! assert([sn,cn,dn], res3, 10*eps); +%! [sn,cn,dn] = ellipj (u3,m3); +%! assert ([sn,cn,dn], res3, 10*eps); %!test -%! u4 = -1; m4 = tan(pi/8)^4; +%! u4 = -1; m4 = tan (pi/8)^4; %! res4 = [-0.8392965923,0.5436738271,0.9895776106]; -%! [sn,cn,dn]=ellipj(u4, m4); -%! assert([sn,cn,dn], res4, 1e-10); +%! [sn,cn,dn] = ellipj (u4, m4); +%! assert ([sn,cn,dn], res4, 1e-10); %!test %! u5 = -0.2 + 0.4i; m5 = tan(pi/8)^4; %! res5 = [ -0.2152524522 + 0.402598347i, ... %! 1.059453907 + 0.08179712295i, ... %! 1.001705496 + 0.00254669712i ]; -%! [sn,cn,dn]=ellipj(u5,m5); -%! assert([sn,cn,dn], res5, 1e-9); +%! [sn,cn,dn] = ellipj (u5,m5); +%! assert ([sn,cn,dn], res5, 1e-9); %!test %! u6 = 0.2 + 0.6i; m6 = tan(pi/8)^4; %! res6 = [ 0.2369100139 + 0.624633635i, ... %! 1.16200643 - 0.1273503824i, ... -%! 1.004913944 - 0.004334880912i ]; -%! [sn,cn,dn]=ellipj(u6,m6); -%! assert([sn,cn,dn], res6, 1e-8); +%! 1.004913944 - 0.004334880912i ]; +%! [sn,cn,dn] = ellipj (u6,m6); +%! assert ([sn,cn,dn], res6, 1e-8); %!test -%! u7 = 0.8 + 0.8i; m7 = tan(pi/8)^4; +%! u7 = 0.8 + 0.8i; m7 = tan (pi/8)^4; %! res7 = [0.9588386397 + 0.6107824358i, ... %! 0.9245978896 - 0.6334016187i, ... %! 0.9920785856 - 0.01737733806i ]; -%! [sn,cn,dn]=ellipj(u7,m7); -%! assert([sn,cn,dn], res7, 1e-10); +%! [sn,cn,dn] = ellipj (u7,m7); +%! assert ([sn,cn,dn], res7, 1e-10); %!test -%! u=[0,pi/6,pi/4,pi/2]; m=0; +%! u = [0,pi/6,pi/4,pi/2]; m=0; %! res = [0,1/2,1/sqrt(2),1;1,cos(pi/6),1/sqrt(2),0;1,1,1,1]; -%! [sn,cn,dn]=ellipj(u,m); -%! assert([sn;cn;dn],res, 100*eps); -%! [sn,cn,dn]=ellipj(u',0); -%! assert([sn,cn,dn],res', 100*eps); +%! [sn,cn,dn] = ellipj (u,m); +%! assert ([sn;cn;dn], res, 100*eps); +%! [sn,cn,dn] = ellipj (u',0); +%! assert ([sn,cn,dn], res', 100*eps); + +## FIXME: need to check [real,complex]x[scalar,rowvec,colvec,matrix]x[u,m] -## XXX FIXME XXX -## need to check [real,complex]x[scalar,rowvec,colvec,matrix]x[u,m] +## One test for u column vector x m row vector +%!test +%! u = [0,pi/6,pi/4,pi/2]'; m = [0 0 0 0]; +%! res = [0,1/2,1/sqrt(2),1;1,cos(pi/6),1/sqrt(2),0;1,1,1,1]'; +%! [sn,cn,dn] = ellipj (u,m); +%! assert (sn, repmat (res(:,1), [1,4]), 100*eps); +%! assert (cn, repmat (res(:,2), [1,4]), 100*eps); +%! assert (dn, repmat (res(:,3), [1,4]), 100*eps); %!test %! ## Test Jacobi elliptic functions @@ -921,27 +883,46 @@ %! ## 1 February 2001 %! u = [ 0.25; 0.25; 0.20; 0.20; 0.672; 0.5]; %! m = [ 0.0; 1.0; 0.19; 0.81; 0.36; 0.9999999999]; -%! S = [ sin(0.25); tanh(0.25); -%! 0.19842311013970879516; -%! 0.19762082367187648571; -%! 0.6095196917919021945; -%! 0.4621171572617320908 ]; -%! C = [ cos(0.25); sech(0.25); -%! 0.9801164570409401062; -%! 0.9802785369736752032; -%! 0.7927709286533560550; -%! 0.8868188839691764094 ]; -%! D = [ 1.0; sech(0.25); -%! 0.9962526643271134302; -%! 0.9840560289645665155; -%! 0.9307281387786906491; -%! 0.8868188839812167635 ]; -%! [sn,cn,dn] = ellipj(u,m); -%! assert(sn,S,8*eps); -%! assert(cn,C,8*eps); -%! assert(dn,D,8*eps); +%! S = [ sin(0.25); +%! tanh(0.25); +%! 0.19842311013970879516; +%! 0.19762082367187648571; +%! 0.6095196917919021945; +%! 0.4621171572617320908 ]; +%! C = [ cos(0.25); +%! sech(0.25); +%! 0.9801164570409401062; +%! 0.9802785369736752032; +%! 0.7927709286533560550; +%! 0.8868188839691764094 ]; +%! D = [ 1.0; +%! sech(0.25); +%! 0.9962526643271134302; +%! 0.9840560289645665155; +%! 0.9307281387786906491; +%! 0.8868188839812167635 ]; +%! [sn,cn,dn] = ellipj (u,m); +%! assert (sn, S, 8*eps); +%! assert (cn, C, 8*eps); +%! assert (dn, D, 8*eps); %!error ellipj () %!error ellipj (1) %!error ellipj (1,2,3,4) +%!warning ellipj (1,2); +## FIXME: errors commented out untill lasterr() truly returns the last error. +%!#error ellipj (1, "1") +%!#error ellipj ("1", 1) +%!#error ellipj ({1}, 1) +%!#error ellipj ({1, 2}, 1) +%!#error ellipj (1, {1, 2}) +%!#error ellipj ("1", [1, 2]) +%!#error ellipj ({1}, [1, 2]) +%!#error ellipj ({1}, [1, 2]) +%!#error ellipj ("1,2", [1, 2]) +%!#error ellipj ({1, 2}, [1, 2]) +%!error ellipj ([1:4], [1:3]) +%!error ellipj (complex (1:4,1:4), [1:3]) + */ + diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/error.cc --- a/libinterp/corefcn/error.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/error.cc Sat Oct 05 11:22:09 2013 -0400 @@ -830,10 +830,10 @@ "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} rethrow (@var{err})\n\ Reissue a previous error as defined by @var{err}. @var{err} is a structure\n\ -that must contain at least the 'message' and 'identifier' fields. @var{err}\n\ -can also contain a field 'stack' that gives information on the assumed\n\ -location of the error. Typically @var{err} is returned from\n\ -@code{lasterror}.\n\ +that must contain at least the @qcode{\"message\"} and @qcode{\"identifier\"}\n\ +fields. @var{err} can also contain a field @qcode{\"stack\"} that gives\n\ +information on the assumed location of the error. Typically @var{err} is\n\ +returned from @code{lasterror}.\n\ @seealso{lasterror, lasterr, error}\n\ @end deftypefn") { @@ -1091,7 +1091,7 @@ which will only stop execution if an error has been found.\n\ \n\ Implementation Note: For compatibility with @sc{matlab}, escape\n\ -sequences (e.g., \"\\n\" => newline) are processed in @var{template}\n\ +sequences (e.g., @qcode{\"\\n\"} => newline) are processed in @var{template}\n\ regardless of whether @var{template} has been defined within single quotes\n\ as long as there are two or more input arguments.\n\ Use a second backslash to stop interpolation of the escape sequence (e.g.,\n\ @@ -1235,17 +1235,17 @@ \n\ The optional message identifier allows users to enable or disable\n\ warnings tagged by @var{id}. A message identifier is of the form\n\ -\"NAMESPACE:WARNING-NAME\". Octave's own warnings use the \"Octave\"\n\ -namespace (@pxref{docXwarning_ids}). The special identifier @samp{\"all\"}\n\ +\"NAMESPACE:WARNING-NAME\". Octave's own warnings use the @qcode{\"Octave\"}\n\ +namespace (@pxref{XREFwarning_ids}). The special identifier @qcode{\"all\"}\n\ may be used to set the state of all warnings.\n\ \n\ -If the first argument is @samp{\"on\"} or @samp{\"off\"}, set the state\n\ -of a particular warning using the identifier @var{id}. If the first\n\ -argument is @samp{\"query\"}, query the state of this warning instead.\n\ -If the identifier is omitted, a value of @samp{\"all\"} is assumed. If\n\ -you set the state of a warning to @samp{\"error\"}, the warning named by\n\ -@var{id} is handled as if it were an error instead. So, for example, the\n\ -following handles all warnings as errors:\n\ +If the first argument is @qcode{\"on\"} or @qcode{\"off\"},\n\ +set the state of a particular warning using the identifier @var{id}. If the\n\ +first argument is @qcode{\"query\"}, query the state of this warning\n\ +instead. If the identifier is omitted, a value of @qcode{\"all\"} is\n\ +assumed. If you set the state of a warning to @qcode{\"error\"}, the\n\ +warning named by @var{id} is handled as if it were an error instead. So,\n\ +for example, the following handles all warnings as errors:\n\ \n\ @example\n\ @group\n\ @@ -1253,17 +1253,17 @@ @end group\n\ @end example\n\ \n\ -If the state is @samp{\"on\"}, @samp{\"off\"}, or @samp{\"error\"}\n\ -and the third argument is @samp{\"local\"}, then the warning state\n\ +If the state is @qcode{\"on\"}, @qcode{\"off\"}, or @qcode{\"error\"}\n\ +and the third argument is @qcode{\"local\"}, then the warning state\n\ will be set temporarily, until the end of the current function.\n\ Changes to warning states that are set locally affect the current\n\ function and all functions called from the current scope. The\n\ previous warning state is restored on return from the current\n\ -function. The \"local\" option is ignored if used in the top-level\n\ +function. The @qcode{\"local\"} option is ignored if used in the top-level\n\ workspace.\n\ \n\ Implementation Note: For compatibility with @sc{matlab}, escape\n\ -sequences (e.g., \"\\n\" => newline) are processed in @var{template}\n\ +sequences (e.g., @qcode{\"\\n\"} => newline) are processed in @var{template}\n\ regardless of whether @var{template} has been defined within single quotes\n\ as long as there are two or more input arguments.\n\ Use a second backslash to stop interpolation of the escape sequence (e.g.,\n\ @@ -1654,29 +1654,29 @@ arguments, return a structure containing the last error message and other\n\ information related to this error. The elements of the structure are:\n\ \n\ -@table @asis\n\ -@item 'message'\n\ +@table @code\n\ +@item message\n\ The text of the last error message\n\ \n\ -@item 'identifier'\n\ +@item identifier\n\ The message identifier of this error message\n\ \n\ -@item 'stack'\n\ +@item stack\n\ A structure containing information on where the message occurred. This may\n\ be an empty structure if the information cannot\n\ be obtained. The fields of the structure are:\n\ \n\ -@table @asis\n\ -@item 'file'\n\ +@table @code\n\ +@item file\n\ The name of the file where the error occurred\n\ \n\ -@item 'name'\n\ +@item name\n\ The name of function in which the error occurred\n\ \n\ -@item 'line'\n\ +@item line\n\ The line number at which the error occurred\n\ \n\ -@item 'column'\n\ +@item column\n\ An optional field with the column number at which the error occurred\n\ @end table\n\ @end table\n\ @@ -1685,8 +1685,8 @@ as input. Any fields of @var{err} that match those above are set while any\n\ unspecified fields are initialized with default values.\n\ \n\ -If @code{lasterror} is called with the argument \"reset\", all fields are\n\ -set to their default values.\n\ +If @code{lasterror} is called with the argument @qcode{\"reset\"}, all\n\ +fields are set to their default values.\n\ @seealso{lasterr, error, lastwarn}\n\ @end deftypefn") { @@ -1956,9 +1956,9 @@ Query or set the internal variable that controls whether Octave will try\n\ to ring the terminal bell before printing an error message.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @end deftypefn") { return SET_INTERNAL_VARIABLE (beep_on_error); @@ -1974,9 +1974,9 @@ inhibit printing of the normal traceback message (you will only see\n\ the top-level error message).\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{debug_on_warning, debug_on_interrupt}\n\ @end deftypefn") { @@ -1991,9 +1991,9 @@ Query or set the internal variable that controls whether Octave will try\n\ to enter the debugger when a warning is encountered.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{debug_on_error, debug_on_interrupt}\n\ @end deftypefn") { diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/file-io.cc --- a/libinterp/corefcn/file-io.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/file-io.cc Sat Oct 05 11:22:09 2013 -0400 @@ -647,14 +647,14 @@ file.\n\ @end table\n\ \n\ -Append a \"t\" to the mode string to open the file in text mode or a\n\ -\"b\" to open in binary mode. On Windows and Macintosh systems, text\n\ +Append a @qcode{\"t\"} to the mode string to open the file in text mode or a\n\ +@qcode{\"b\"} to open in binary mode. On Windows and Macintosh systems, text\n\ mode reading and writing automatically converts linefeeds to the\n\ appropriate line end character for the system (carriage-return linefeed\n\ on Windows, carriage-return on Macintosh). The default if no mode is\n\ specified is binary mode.\n\ \n\ -Additionally, you may append a \"z\" to the mode string to open a\n\ +Additionally, you may append a @qcode{\"z\"} to the mode string to open a\n\ gzipped file for reading or writing. For this to be successful, you\n\ must also open the file in binary mode.\n\ \n\ @@ -670,15 +670,6 @@ \n\ @item ieee-le\n\ IEEE little endian format.\n\ -\n\ -@item vaxd\n\ -VAX D floating format.\n\ -\n\ -@item vaxg\n\ -VAX G floating format.\n\ -\n\ -@item cray\n\ -Cray floating format.\n\ @end table\n\ \n\ @noindent\n\ @@ -825,8 +816,10 @@ The pointer is positioned @var{offset} characters from the @var{origin},\n\ which may be one of the predefined variables @w{@code{SEEK_CUR}} (current\n\ position), @w{@code{SEEK_SET}} (beginning), or @w{@code{SEEK_END}} (end of\n\ -file) or strings \"cof\", \"bof\" or \"eof\". If @var{origin} is omitted,\n\ -@w{@code{SEEK_SET}} is assumed. @var{offset} may be positive, negative, or zero but not all combinations of @var{origin} and @var{offset} can be realized.\n\ +file) or strings @qcode{\"cof\"}, @qcode{\"bof\"} or @qcode{\"eof\"}. If\n\ +@var{origin} is omitted, @w{@code{SEEK_SET}} is assumed. @var{offset} may\n\ +be positive, negative, or zero but not all combinations of @var{origin} and\n\ +@var{offset} can be realized.\n\ \n\ Return 0 on success and -1 on error.\n\ @seealso{fskipl, frewind, ftell, fopen}\n\ @@ -1440,84 +1433,84 @@ data to read and may be one of\n\ \n\ @table @asis\n\ -@item \"schar\"\n\ -@itemx \"signed char\"\n\ +@item @qcode{\"schar\"}\n\ +@itemx @qcode{\"signed char\"}\n\ Signed character.\n\ \n\ -@item \"uchar\"\n\ -@itemx \"unsigned char\"\n\ +@item @qcode{\"uchar\"}\n\ +@itemx @qcode{\"unsigned char\"}\n\ Unsigned character.\n\ \n\ -@item \"int8\"\n\ -@itemx \"integer*1\"\n\ +@item @qcode{\"int8\"}\n\ +@itemx @qcode{\"integer*1\"}\n\ \n\ 8-bit signed integer.\n\ \n\ -@item \"int16\"\n\ -@itemx \"integer*2\"\n\ +@item @qcode{\"int16\"}\n\ +@itemx @qcode{\"integer*2\"}\n\ 16-bit signed integer.\n\ \n\ -@item \"int32\"\n\ -@itemx \"integer*4\"\n\ +@item @qcode{\"int32\"}\n\ +@itemx @qcode{\"integer*4\"}\n\ 32-bit signed integer.\n\ \n\ -@item \"int64\"\n\ -@itemx \"integer*8\"\n\ +@item @qcode{\"int64\"}\n\ +@itemx @qcode{\"integer*8\"}\n\ 64-bit signed integer.\n\ \n\ -@item \"uint8\"\n\ +@item @qcode{\"uint8\"}\n\ 8-bit unsigned integer.\n\ \n\ -@item \"uint16\"\n\ +@item @qcode{\"uint16\"}\n\ 16-bit unsigned integer.\n\ \n\ -@item \"uint32\"\n\ +@item @qcode{\"uint32\"}\n\ 32-bit unsigned integer.\n\ \n\ -@item \"uint64\"\n\ +@item @qcode{\"uint64\"}\n\ 64-bit unsigned integer.\n\ \n\ -@item \"single\"\n\ -@itemx \"float32\"\n\ -@itemx \"real*4\"\n\ +@item @qcode{\"single\"}\n\ +@itemx @qcode{\"float32\"}\n\ +@itemx @qcode{\"real*4\"}\n\ 32-bit floating point number.\n\ \n\ -@item \"double\"\n\ -@itemx \"float64\"\n\ -@itemx \"real*8\"\n\ +@item @qcode{\"double\"}\n\ +@itemx @qcode{\"float64\"}\n\ +@itemx @qcode{\"real*8\"}\n\ 64-bit floating point number.\n\ \n\ -@item \"char\"\n\ -@itemx \"char*1\"\n\ +@item @qcode{\"char\"}\n\ +@itemx @qcode{\"char*1\"}\n\ Single character.\n\ \n\ -@item \"short\"\n\ +@item @qcode{\"short\"}\n\ Short integer (size is platform dependent).\n\ \n\ -@item \"int\"\n\ +@item @qcode{\"int\"}\n\ Integer (size is platform dependent).\n\ \n\ -@item \"long\"\n\ +@item @qcode{\"long\"}\n\ Long integer (size is platform dependent).\n\ \n\ -@item \"ushort\"\n\ -@itemx \"unsigned short\"\n\ +@item @qcode{\"ushort\"}\n\ +@itemx @qcode{\"unsigned short\"}\n\ Unsigned short integer (size is platform dependent).\n\ \n\ -@item \"uint\"\n\ -@itemx \"unsigned int\"\n\ +@item @qcode{\"uint\"}\n\ +@itemx @qcode{\"unsigned int\"}\n\ Unsigned integer (size is platform dependent).\n\ \n\ -@item \"ulong\"\n\ -@itemx \"unsigned long\"\n\ +@item @qcode{\"ulong\"}\n\ +@itemx @qcode{\"unsigned long\"}\n\ Unsigned long integer (size is platform dependent).\n\ \n\ -@item \"float\"\n\ +@item @qcode{\"float\"}\n\ Single precision floating point number (size is platform dependent).\n\ @end table\n\ \n\ @noindent\n\ -The default precision is @code{\"uchar\"}.\n\ +The default precision is @qcode{\"uchar\"}.\n\ \n\ The @var{precision} argument may also specify an optional repeat\n\ count. For example, @samp{32*single} causes @code{fread} to read\n\ @@ -1553,7 +1546,7 @@ for the file. Valid values are\n\ \n\ @table @code\n\ -@item \"native\"\n\ +@item @qcode{\"native\"}\n\ The format of the current machine.\n\ \n\ @item \"ieee-be\"\n\ @@ -1561,21 +1554,8 @@ \n\ @item \"ieee-le\"\n\ IEEE little endian.\n\ -\n\ -@item \"vaxd\"\n\ -VAX D floating format.\n\ -\n\ -@item \"vaxg\"\n\ -VAX G floating format.\n\ -\n\ -@item \"cray\"\n\ -Cray floating format.\n\ @end table\n\ \n\ -@noindent\n\ -Conversions are currently only supported for @code{\"ieee-be\"} and\n\ -@code{\"ieee-le\"} formats.\n\ -\n\ The data read from the file is returned in @var{val}, and the number of\n\ values read is returned in @code{count}\n\ @seealso{fwrite, fgets, fgetl, fscanf, fopen}\n\ @@ -1827,11 +1807,11 @@ @var{mode} may be\n\ \n\ @table @code\n\ -@item \"r\"\n\ +@item @qcode{\"r\"}\n\ The pipe will be connected to the standard output of the process, and\n\ open for reading.\n\ \n\ -@item \"w\"\n\ +@item @qcode{\"w\"}\n\ The pipe will be connected to the standard input of the process, and\n\ open for writing.\n\ @end table\n\ @@ -1922,7 +1902,7 @@ @deftypefnx {Built-in Function} {} tmpnam (@var{dir}, @var{prefix})\n\ Return a unique temporary file name as a string.\n\ \n\ -If @var{prefix} is omitted, a value of @code{\"oct-\"} is used.\n\ +If @var{prefix} is omitted, a value of @qcode{\"oct-\"} is used.\n\ If @var{dir} is also omitted, the default directory for temporary files\n\ is used. If @var{dir} is provided, it must exist, otherwise the default\n\ directory for temporary files is used. Since the named file is not\n\ @@ -1964,7 +1944,7 @@ "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} tmpfile ()\n\ Return the file ID corresponding to a new temporary file with a unique\n\ -name. The file is opened in binary read/write (@code{\"w+b\"}) mode.\n\ +name. The file is opened in binary read/write (@qcode{\"w+b\"}) mode.\n\ The file will be deleted automatically when it is closed or when Octave\n\ exits.\n\ \n\ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/find.cc --- a/libinterp/corefcn/find.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/find.cc Sat Oct 05 11:22:09 2013 -0400 @@ -377,9 +377,10 @@ If two inputs are given, @var{n} indicates the maximum number of\n\ elements to find from the beginning of the matrix or vector.\n\ \n\ -If three inputs are given, @var{direction} should be one of \"first\" or\n\ -\"last\", requesting only the first or last @var{n} indices, respectively.\n\ -However, the indices are always returned in ascending order.\n\ +If three inputs are given, @var{direction} should be one of\n\ +@qcode{\"first\"} or @qcode{\"last\"}, requesting only the first or last\n\ +@var{n} indices, respectively. However, the indices are always returned in\n\ +ascending order.\n\ \n\ Note that this function is particularly useful for sparse matrices, as\n\ it extracts the non-zero elements as vectors, which can then be used to\n\ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/gammainc.cc --- a/libinterp/corefcn/gammainc.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/gammainc.cc Sat Oct 05 11:22:09 2013 -0400 @@ -66,8 +66,8 @@ @var{a} must agree, and @code{gammainc} is applied element-by-element.\n\ \n\ By default the incomplete gamma function integrated from 0 to @var{x} is\n\ -computed. If \"upper\" is given then the complementary function integrated\n\ -from @var{x} to infinity is calculated. It should be noted that\n\ +computed. If @qcode{\"upper\"} is given then the complementary function\n\ +integrated from @var{x} to infinity is calculated. It should be noted that\n\ \n\ @example\n\ gammainc (@var{x}, @var{a}) @equiv{} 1 - gammainc (@var{x}, @var{a}, \"upper\")\n\ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/gl-render.cc --- a/libinterp/corefcn/gl-render.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/gl-render.cc Sat Oct 05 11:22:09 2013 -0400 @@ -1600,6 +1600,9 @@ i1 = i2 = j1 = j2 = 0; + if ((fc_mode > 0 && fc_mode < 3) || ec_mode > 0) + c = props.get_color_data ().array_value (); + boolMatrix clip (z.dims (), false); for (int i = 0; i < zr; i++) @@ -1613,12 +1616,11 @@ j1 = j; clip(i,j) = is_nan_or_inf (x(i1,j), y(i,j1), z(i,j)); + if (fc_mode == 1 || fc_mode == 2) + clip(i,j) |= (xisnan (c(i,j)) || xisinf (c(i,j))); } } - if ((fc_mode > 0 && fc_mode < 3) || ec_mode > 0) - c = props.get_color_data ().array_value (); - if (fa_mode > 0 || ea_mode > 0) { // FIXME: implement alphadata conversion @@ -3009,7 +3011,7 @@ { #if HAVE_FREETYPE text_renderer.text_to_pixels (txt, pixels, bbox, - halign, valign, rotation); + halign, valign, rotation, "none"); #endif } diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/graphics.cc --- a/libinterp/corefcn/graphics.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/graphics.cc Sat Oct 05 11:22:09 2013 -0400 @@ -1927,22 +1927,6 @@ return m; } -graphics_handle::graphics_handle (const octave_value& a) - : val (octave_NaN) -{ - if (a.is_empty ()) - /* do nothing */; - else - { - double tval = a.double_value (); - - if (! error_state) - val = tval; - else - error ("invalid graphics handle"); - } -} - // Set properties given as a cs-list of name, value pairs. void @@ -1978,11 +1962,14 @@ /* ## test set with name, value pairs %!test -%! set (gcf, "visible", "off"); +%! hf = figure ("visible", "off"); %! h = plot (1:10, 10:-1:1); %! set (h, "linewidth", 10, "marker", "x"); -%! assert (get (h, "linewidth"), 10); -%! assert (get (h, "marker"), "x"); +%! lw = get (h, "linewidth"); +%! mk = get (h, "marker"); +%! close (hf); +%! assert (lw, 10); +%! assert (mk, "x"); */ // Set properties given in two cell arrays containing names and values. @@ -2013,32 +2000,47 @@ /* ## test set with cell array arguments %!test -%! set (gcf, "visible", "off"); +%! hf = figure ("visible", "off"); %! h = plot (1:10, 10:-1:1); %! set (h, {"linewidth", "marker"}, {10, "x"}); -%! assert (get (h, "linewidth"), 10); -%! assert (get (h, "marker"), "x"); +%! lw = get (h, "linewidth"); +%! mk = get (h, "marker"); +%! close (hf); +%! assert (lw, 10); +%! assert (mk, "x"); ## test set with multiple handles and cell array arguments %!test -%! set (gcf, "visible", "off"); -%! h = plot (1:10, 10:-1:1, 1:10, 1:10); -%! set (h, {"linewidth", "marker"}, {10, "x"; 5, "o"}); -%! assert (get (h, "linewidth"), {10; 5}); -%! assert (get (h, "marker"), {"x"; "o"}); -%! set (h, {"linewidth", "marker"}, {10, "x"}); -%! assert (get (h, "linewidth"), {10; 10}); -%! assert (get (h, "marker"), {"x"; "x"}); +%! hf = figure ("visible", "off"); +%! unwind_protect +%! h = plot (1:10, 10:-1:1, 1:10, 1:10); +%! set (h, {"linewidth", "marker"}, {10, "x"; 5, "o"}); +%! assert (get (h, "linewidth"), {10; 5}); +%! assert (get (h, "marker"), {"x"; "o"}); +%! set (h, {"linewidth", "marker"}, {10, "x"}); +%! assert (get (h, "linewidth"), {10; 10}); +%! assert (get (h, "marker"), {"x"; "x"}); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect; %!error -%! set (gcf, "visible", "off"); -%! h = plot (1:10, 10:-1:1, 1:10, 1:10); -%! set (h, {"linewidth", "marker"}, {10, "x"; 5, "o"; 7, "."}); +%! hf = figure ("visible", "off"); +%! unwind_protect +%! h = plot (1:10, 10:-1:1, 1:10, 1:10); +%! set (h, {"linewidth", "marker"}, {10, "x"; 5, "o"; 7, "."}); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect %!error -%! set (gcf, "visible", "off"); -%! h = plot (1:10, 10:-1:1, 1:10, 1:10); -%! set (h, {"linewidth"}, {10, "x"; 5, "o"}); +%! hf = figure ("visible", "off"); +%! unwind_protect +%! h = plot (1:10, 10:-1:1, 1:10, 1:10); +%! set (h, {"linewidth"}, {10, "x"; 5, "o"}); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect */ // Set properties given in a struct array @@ -2061,27 +2063,34 @@ /* ## test set ticklabels for compatibility %!test -%! set (gcf (), "visible", "off"); +%! hf = figure ("visible", "off"); %! set (gca (), "xticklabel", [0, 0.2, 0.4, 0.6, 0.8, 1]); %! xticklabel = get (gca (), "xticklabel"); +%! close (hf); %! assert (class (xticklabel), "char"); %! assert (size (xticklabel), [6, 3]); + %!test -%! set (gcf (), "visible", "off"); +%! hf = figure ("visible", "off"); %! set (gca (), "xticklabel", "0|0.2|0.4|0.6|0.8|1"); %! xticklabel = get (gca (), "xticklabel"); +%! close (hf); %! assert (class (xticklabel), "char"); %! assert (size (xticklabel), [6, 3]); + %!test -%! set (gcf (), "visible", "off"); +%! hf = figure ("visible", "off"); %! set (gca (), "xticklabel", ["0 "; "0.2"; "0.4"; "0.6"; "0.8"; "1 "]); %! xticklabel = get (gca (), "xticklabel"); +%! close (hf); %! assert (class (xticklabel), "char"); %! assert (size (xticklabel), [6, 3]); + %!test -%! set (gcf (), "visible", "off"); +%! hf = figure ("visible", "off"); %! set (gca (), "xticklabel", {"0", "0.2", "0.4", "0.6", "0.8", "1"}); %! xticklabel = get (gca (), "xticklabel"); +%! close (hf); %! assert (class (xticklabel), "cell"); %! assert (size (xticklabel), [6, 1]); */ @@ -2089,40 +2098,47 @@ /* ## test set with struct arguments %!test -%! set (gcf, "visible", "off"); -%! h = plot (1:10, 10:-1:1); -%! set (h, struct ("linewidth", 10, "marker", "x")); -%! assert (get (h, "linewidth"), 10); -%! assert (get (h, "marker"), "x"); -%! h = plot (1:10, 10:-1:1, 1:10, 1:10); -%! set (h, struct ("linewidth", {5, 10})); -%! assert (get (h, "linewidth"), {10; 10}); +%! hf = figure ("visible", "off"); +%! unwind_protect +%! h = plot (1:10, 10:-1:1); +%! set (h, struct ("linewidth", 10, "marker", "x")); +%! assert (get (h, "linewidth"), 10); +%! assert (get (h, "marker"), "x"); +%! h = plot (1:10, 10:-1:1, 1:10, 1:10); +%! set (h, struct ("linewidth", {5, 10})); +%! assert (get (h, "linewidth"), {10; 10}); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + ## test ordering %!test %! markchanged = @(h, foobar, name) set (h, "userdata", [get(h,"userdata"); {name}]); -%! figure (1, "visible", "off") -%! clf (); -%! h = line (); -%! set (h, "userdata", {}); -%! addlistener (h, "color", {markchanged, "color"}); -%! addlistener (h, "linewidth", {markchanged, "linewidth"}); -%! # "linewidth" first -%! props.linewidth = 2; -%! props.color = "r"; -%! set (h, props); -%! assert (get (h, "userdata"), fieldnames (props)); -%! clear props -%! clf (); -%! h = line (); -%! set (h, "userdata", {}); -%! addlistener (h, "color", {markchanged, "color"}); -%! addlistener (h, "linewidth", {markchanged, "linewidth"}); -%! # "color" first -%! props.color = "r"; -%! props.linewidth = 2; -%! set (h, props); -%! assert (get (h, "userdata"), fieldnames (props)); -%! close (1); +%! hf = figure ("visible", "off"); +%! unwind_protect +%! h = line (); +%! set (h, "userdata", {}); +%! addlistener (h, "color", {markchanged, "color"}); +%! addlistener (h, "linewidth", {markchanged, "linewidth"}); +%! ## "linewidth" first +%! props.linewidth = 2; +%! props.color = "r"; +%! set (h, props); +%! assert (get (h, "userdata"), fieldnames (props)); +%! clear props; +%! clf (); +%! h = line (); +%! set (h, "userdata", {}); +%! addlistener (h, "color", {markchanged, "color"}); +%! addlistener (h, "linewidth", {markchanged, "linewidth"}); +%! ## "color" first +%! props.color = "r"; +%! props.linewidth = 2; +%! set (h, props); +%! assert (get (h, "userdata"), fieldnames (props)); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect */ // Set a property to a value or to its (factory) default value. @@ -2173,13 +2189,19 @@ /* ## test setting of default values %!test -%! set (gcf, "visible", "off"); -%! h = plot (1:10, 10:-1:1); -%! set (0, "defaultlinelinewidth", 20); -%! set (h, "linewidth", "default"); -%! assert (get (h, "linewidth"), 20); -%! set (h, "linewidth", "factory"); -%! assert (get (h, "linewidth"), 0.5); +%! old_lw = get (0, "defaultlinelinewidth"); +%! unwind_protect +%! hf = figure ("visible", "off"); +%! h = plot (1:10, 10:-1:1); +%! set (0, "defaultlinelinewidth", 20); +%! set (h, "linewidth", "default"); +%! assert (get (h, "linewidth"), 20); +%! set (h, "linewidth", "factory"); +%! assert (get (h, "linewidth"), 0.5); +%! unwind_protect_cleanup +%! close (hf); +%! set (0, "defaultlinelinewidth", old_lw); +%! end_unwind_protect */ static double @@ -3125,19 +3147,24 @@ /* %!test -%! set (0, "units", "pixels"); -%! sz = get (0, "screensize") - [1, 1, 0, 0]; -%! dpi = get (0, "screenpixelsperinch"); -%! set (0, "units", "inches"); -%! assert (get (0, "screensize"), sz / dpi, 0.5 / dpi); -%! set (0, "units", "centimeters"); -%! assert (get (0, "screensize"), sz / dpi * 2.54, 0.5 / dpi * 2.54); -%! set (0, "units", "points"); -%! assert (get (0, "screensize"), sz / dpi * 72, 0.5 / dpi * 72); -%! set (0, "units", "normalized"); -%! assert (get (0, "screensize"), [0.0, 0.0, 1.0, 1.0]); -%! set (0, "units", "pixels"); -%! assert (get (0, "screensize"), sz + [1, 1, 0, 0]); +%! old_units = get (0, "units"); +%! unwind_protect +%! set (0, "units", "pixels"); +%! sz = get (0, "screensize") - [1, 1, 0, 0]; +%! dpi = get (0, "screenpixelsperinch"); +%! set (0, "units", "inches"); +%! assert (get (0, "screensize"), sz / dpi, 0.5 / dpi); +%! set (0, "units", "centimeters"); +%! assert (get (0, "screensize"), sz / dpi * 2.54, 0.5 / dpi * 2.54); +%! set (0, "units", "points"); +%! assert (get (0, "screensize"), sz / dpi * 72, 0.5 / dpi * 72); +%! set (0, "units", "normalized"); +%! assert (get (0, "screensize"), [0.0, 0.0, 1.0, 1.0]); +%! set (0, "units", "pixels"); +%! assert (get (0, "screensize"), sz + [1, 1, 0, 0]); +%! unwind_protect_cleanup +%! set (0, "units", old_units); +%! end_unwind_protect */ void @@ -3745,27 +3772,34 @@ /* %!test -%! figure (1, "visible", "off"); -%! set (1, "paperunits", "inches"); -%! set (1, "papersize", [5, 4]); -%! set (1, "paperunits", "points"); -%! assert (get (1, "papersize"), [5, 4] * 72, 1); -%! papersize = get (gcf, "papersize"); -%! set (1, "papersize", papersize + 1); -%! set (1, "papersize", papersize); -%! assert (get (1, "papersize"), [5, 4] * 72, 1); -%! close (1); +%! hf = figure ("visible", "off"); +%! unwind_protect +%! set (hf, "paperunits", "inches"); +%! set (hf, "papersize", [5, 4]); +%! set (hf, "paperunits", "points"); +%! assert (get (hf, "papersize"), [5, 4] * 72, 1); +%! papersize = get (hf, "papersize"); +%! set (hf, "papersize", papersize + 1); +%! set (hf, "papersize", papersize); +%! assert (get (hf, "papersize"), [5, 4] * 72, 1); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + %!test -%! figure (1, "visible", "off"); -%! set (1, "paperunits", "inches"); -%! set (1, "papersize", [5, 4]); -%! set (1, "paperunits", "centimeters"); -%! assert (get (1, "papersize"), [5, 4] * 2.54, 2.54/72); -%! papersize = get (gcf, "papersize"); -%! set (1, "papersize", papersize + 1); -%! set (1, "papersize", papersize); -%! assert (get (1, "papersize"), [5, 4] * 2.54, 2.54/72); -%! close (1); +%! hf = figure ("visible", "off"); +%! unwind_protect +%! set (hf, "paperunits", "inches"); +%! set (hf, "papersize", [5, 4]); +%! set (hf, "paperunits", "centimeters"); +%! assert (get (hf, "papersize"), [5, 4] * 2.54, 2.54/72); +%! papersize = get (hf, "papersize"); +%! set (hf, "papersize", papersize + 1); +%! set (hf, "papersize", papersize); +%! assert (get (hf, "papersize"), [5, 4] * 2.54, 2.54/72); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect */ void @@ -3789,25 +3823,29 @@ /* %!test -%! figure (1, "visible", false); -%! tol = 100 * eps (); -%! ## UPPER case and MiXed case is part of test and should not be changed. -%! set (gcf (), "paperorientation", "PORTRAIT"); -%! set (gcf (), "paperunits", "inches"); -%! set (gcf (), "papertype", "USletter"); -%! assert (get (gcf (), "papersize"), [8.5, 11.0], tol); -%! set (gcf (), "paperorientation", "Landscape"); -%! assert (get (gcf (), "papersize"), [11.0, 8.5], tol); -%! set (gcf (), "paperunits", "centimeters"); -%! assert (get (gcf (), "papersize"), [11.0, 8.5] * 2.54, tol); -%! set (gcf (), "papertype", "a4"); -%! assert (get (gcf (), "papersize"), [29.7, 21.0], tol); -%! set (gcf (), "paperunits", "inches", "papersize", [8.5, 11.0]); -%! assert (get (gcf (), "papertype"), "usletter"); -%! assert (get (gcf (), "paperorientation"), "portrait"); -%! set (gcf (), "papersize", [11.0, 8.5]); -%! assert (get (gcf (), "papertype"), "usletter"); -%! assert (get (gcf (), "paperorientation"), "landscape"); +%! hf = figure ("visible", "off"); +%! unwind_protect +%! tol = 100 * eps (); +%! ## UPPER case and MiXed case is part of test and should not be changed. +%! set (hf, "paperorientation", "PORTRAIT"); +%! set (hf, "paperunits", "inches"); +%! set (hf, "papertype", "USletter"); +%! assert (get (hf, "papersize"), [8.5, 11.0], tol); +%! set (hf, "paperorientation", "Landscape"); +%! assert (get (hf, "papersize"), [11.0, 8.5], tol); +%! set (hf, "paperunits", "centimeters"); +%! assert (get (hf, "papersize"), [11.0, 8.5] * 2.54, tol); +%! set (hf, "papertype", "a4"); +%! assert (get (hf, "papersize"), [29.7, 21.0], tol); +%! set (hf, "paperunits", "inches", "papersize", [8.5, 11.0]); +%! assert (get (hf, "papertype"), "usletter"); +%! assert (get (hf, "paperorientation"), "portrait"); +%! set (hf, "papersize", [11.0, 8.5]); +%! assert (get (hf, "papertype"), "usletter"); +%! assert (get (hf, "paperorientation"), "landscape"); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect */ void @@ -3833,13 +3871,20 @@ /* %!test -%! figure (1, "visible", false); -%! set (0, "units", "pixels"); -%! rsz = get (0, "screensize"); -%! set (gcf (), "units", "pixels"); -%! fsz = get (gcf (), "position"); -%! set (gcf (), "units", "normalized"); -%! assert (get (gcf (), "position"), (fsz - [1, 1, 0, 0]) ./ rsz([3, 4, 3, 4])); +%! hf = figure ("visible", "off"); +%! old_units = get (0, "units"); +%! unwind_protect +%! set (0, "units", "pixels"); +%! rsz = get (0, "screensize"); +%! set (gcf (), "units", "pixels"); +%! fsz = get (gcf (), "position"); +%! set (gcf (), "units", "normalized"); +%! pos = get (gcf (), "position"); +%! assert (pos, (fsz - [1, 1, 0, 0]) ./ rsz([3, 4, 3, 4])); +%! unwind_protect_cleanup +%! close (hf); +%! set (0, "units", old_units); +%! end_unwind_protect */ std::string @@ -4006,228 +4051,90 @@ void axes::properties::sync_positions (void) { - Matrix ref_linset = looseinset.get ().matrix_value (); - if (autopos_tag_is ("subplot")) - { - graphics_object parent_obj = gh_manager::get_object (get_parent ()); - if (parent_obj.isa ("figure")) - { - // FIXME: temporarily changed units should be protected - // from interrupts - std::string fig_units = parent_obj.get ("units").string_value (); - parent_obj.set ("units", "pixels"); - - Matrix ref_outbox = outerposition.get ().matrix_value (); - ref_outbox(2) += ref_outbox(0); - ref_outbox(3) += ref_outbox(1); - - // Find those subplots that are left, right, bottom and top aligned - // with the current subplot - Matrix kids = parent_obj.get_properties ().get_children (); - std::vector aligned; - std::vector l_aligned, b_aligned, r_aligned, t_aligned; - for (octave_idx_type i = 0; i < kids.numel (); i++) - { - graphics_object go = gh_manager::get_object (kids(i)); - if (go.isa ("axes")) - { - axes::properties& props = - dynamic_cast (go.get_properties ()); - if (props.autopos_tag_is ("subplot")) - { - Matrix outpos = go.get ("outerposition").matrix_value (); - bool l_align = (std::abs (outpos(0)-ref_outbox(0)) < 1e-15); - bool b_align = (std::abs (outpos(1)-ref_outbox(1)) < 1e-15); - bool r_align = (std::abs (outpos(0)+outpos(2)-ref_outbox(2)) < 1e-15); - bool t_align = (std::abs (outpos(1)+outpos(3)-ref_outbox(3)) < 1e-15); - if (l_align || b_align || r_align || t_align) - { - aligned.push_back (kids(i)); - l_aligned.push_back (l_align); - b_aligned.push_back (b_align); - r_aligned.push_back (r_align); - t_aligned.push_back (t_align); - // FIXME: the temporarily deleted tags should be - // protected from interrupts - props.set_autopos_tag ("none"); - } - } - } - } - // Determine a minimum box which aligns the subplots - Matrix ref_box (1, 4, 0.); - ref_box(2) = 1.; - ref_box(3) = 1.; - for (size_t i = 0; i < aligned.size (); i++) - { - graphics_object go = gh_manager::get_object (aligned[i]); - axes::properties& props = - dynamic_cast (go.get_properties ()); - Matrix linset = props.get_looseinset ().matrix_value (); - if (l_aligned[i]) - linset(0) = std::min (0., linset(0)-0.01); - if (b_aligned[i]) - linset(1) = std::min (0., linset(1)-0.01); - if (r_aligned[i]) - linset(2) = std::min (0., linset(2)-0.01); - if (t_aligned[i]) - linset(3) = std::min (0., linset(3)-0.01); - props.set_looseinset (linset); - Matrix pos = props.get_position ().matrix_value (); - if (l_aligned[i]) - ref_box(0) = std::max (ref_box(0), pos(0)); - if (b_aligned[i]) - ref_box(1) = std::max (ref_box(1), pos(1)); - if (r_aligned[i]) - ref_box(2) = std::min (ref_box(2), pos(0)+pos(2)); - if (t_aligned[i]) - ref_box(3) = std::min (ref_box(3), pos(1)+pos(3)); - } - // Set common looseinset values for all aligned subplots and - // revert their tag values - for (size_t i = 0; i < aligned.size (); i++) - { - graphics_object go = gh_manager::get_object (aligned[i]); - axes::properties& props = - dynamic_cast (go.get_properties ()); - Matrix outpos = props.get_outerposition ().matrix_value (); - Matrix linset = props.get_looseinset ().matrix_value (); - if (l_aligned[i]) - linset(0) = (ref_box(0)-outpos(0))/outpos(2); - if (b_aligned[i]) - linset(1) = (ref_box(1)-outpos(1))/outpos(3); - if (r_aligned[i]) - linset(2) = (outpos(0)+outpos(2)-ref_box(2))/outpos(2); - if (t_aligned[i]) - linset(3) = (outpos(1)+outpos(3)-ref_box(3))/outpos(3); - props.set_looseinset (linset); - props.set_autopos_tag ("subplot"); - } - parent_obj.set ("units", fig_units); - } - } + // First part is equivalent to `update_tightinset ()' + if (activepositionproperty.is ("position")) + update_position (); else - sync_positions (ref_linset); -} - -void -axes::properties::sync_positions (const Matrix& linset) -{ - Matrix pos = position.get ().matrix_value (); - Matrix outpos = outerposition.get ().matrix_value (); - double lratio = linset(0); - double bratio = linset(1); - double wratio = 1-linset(0)-linset(2); - double hratio = 1-linset(1)-linset(3); - if (activepositionproperty.is ("outerposition")) - { - pos = outpos; - pos(0) = outpos(0)+lratio*outpos(2); - pos(1) = outpos(1)+bratio*outpos(3); - pos(2) = wratio*outpos(2); - pos(3) = hratio*outpos(3); - - position = pos; - update_transform (); - Matrix tightpos = calc_tightbox (pos); - - double thrshldx = 0.005*outpos(2); - double thrshldy = 0.005*outpos(3); - double minsizex = 0.2*outpos(2); - double minsizey = 0.2*outpos(3); - bool updatex = true, updatey = true; - for (int i = 0; i < 10; i++) - { - double dt; - bool modified = false; - dt = outpos(0)+outpos(2)-tightpos(0)-tightpos(2); - if (dt < -thrshldx && updatex) - { - pos(2) += dt; - modified = true; - } - dt = outpos(1)+outpos(3)-tightpos(1)-tightpos(3); - if (dt < -thrshldy && updatey) - { - pos(3) += dt; - modified = true; - } - dt = outpos(0)-tightpos(0); - if (dt > thrshldx && updatex) - { - pos(0) += dt; - pos(2) -= dt; - modified = true; - } - dt = outpos(1)-tightpos(1); - if (dt > thrshldy && updatey) - { - pos(1) += dt; - pos(3) -= dt; - modified = true; - } - - // Note: checking limit for minimum axes size - if (pos(2) < minsizex) - { - pos(0) -= 0.5*(minsizex-pos(2)); - pos(2) = minsizex; - updatex = false; - } - if (pos(3) < minsizey) - { - pos(1) -= 0.5*(minsizey-pos(3)); - pos(3) = minsizey; - updatey = false; - } - - if (modified) - { - position = pos; - update_transform (); - tightpos = calc_tightbox (pos); - } - else - break; - } - } - else - { - update_transform (); - - outpos(0) = pos(0)-pos(2)*lratio/wratio; - outpos(1) = pos(1)-pos(3)*bratio/hratio; - outpos(2) = pos(2)/wratio; - outpos(3) = pos(3)/hratio; - - outerposition = calc_tightbox (outpos); - } - - update_insets (); -} - -void -axes::properties::update_insets (void) -{ + update_outerposition (); + caseless_str old_units = get_units (); + set_units ("normalized"); Matrix pos = position.get ().matrix_value (); Matrix outpos = outerposition.get ().matrix_value (); Matrix tightpos = calc_tightbox (pos); - // Determine the tightinset = axes_bbox - position - Matrix inset (1, 4, 1.0); - inset(0) = pos(0)-tightpos(0); - inset(1) = pos(1)-tightpos(1); - inset(2) = tightpos(0)+tightpos(2)-pos(0)-pos(2); - inset(3) = tightpos(1)+tightpos(3)-pos(1)-pos(3); - tightinset = inset; - - // Determine the looseinset = outerposition - position - inset(0) = pos(0)-outpos(0); - inset(1) = pos(1)-outpos(1); - inset(2) = outpos(0)+outpos(2)-pos(0)-pos(2); - inset(3) = outpos(1)+outpos(3)-pos(1)-pos(3); - looseinset = inset; -} - + Matrix tinset (1, 4, 1.0); + tinset(0) = pos(0)-tightpos(0); + tinset(1) = pos(1)-tightpos(1); + tinset(2) = tightpos(0)+tightpos(2)-pos(0)-pos(2); + tinset(3) = tightpos(1)+tightpos(3)-pos(1)-pos(3); + tightinset = tinset; + set_units (old_units); + update_transform (); + if (activepositionproperty.is ("position")) + update_position (); + else + update_outerposition (); +} + +/* +%!testif HAVE_FLTK +%! hf = figure ("visible", "off"); +%! graphics_toolkit (hf, "fltk"); +%! unwind_protect +%! subplot(2,1,1); plot(rand(10,1)); subplot(2,1,2); plot(rand(10,1)); +%! hax = findall (gcf (), "type", "axes"); +%! positions = cell2mat (get (hax, "position")); +%! outerpositions = cell2mat (get (hax, "outerposition")); +%! looseinsets = cell2mat (get (hax, "looseinset")); +%! tightinsets = cell2mat (get (hax, "tightinset")); +%! subplot(2,1,1); plot(rand(10,1)); subplot(2,1,2); plot(rand(10,1)); +%! hax = findall (gcf (), "type", "axes"); +%! assert (cell2mat (get (hax, "position")), positions, 1e-4); +%! assert (cell2mat (get (hax, "outerposition")), outerpositions, 1e-4); +%! assert (cell2mat (get (hax, "looseinset")), looseinsets, 1e-4); +%! assert (cell2mat (get (hax, "tightinset")), tightinsets, 1e-4); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect +%!testif HAVE_FLTK +%! hf = figure ("visible", "off"); +%! graphics_toolkit (hf, "fltk"); +%! fpos = get (hf, "position"); +%! unwind_protect +%! plot (rand (3)) +%! position = get (gca, "position"); +%! outerposition = get (gca, "outerposition"); +%! looseinset = get (gca, "looseinset"); +%! tightinset = get (gca, "tightinset"); +%! set (hf, "position", [fpos(1:2), 2*fpos(3:4)]) +%! set (hf, "position", fpos); +%! assert (get (gca, "outerposition"), outerposition, 0.001) +%! assert (get (gca, "position"), position, 0.001) +%! assert (get (gca, "looseinset"), looseinset, 0.001) +%! assert (get (gca, "tightinset"), tightinset, 0.001) +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect +%!testif HAVE_FLTK +%! hf = figure ("visible", "off"); +%! graphics_toolkit (hf, "fltk"); +%! fpos = get (hf, "position"); +%! set (gca, "activepositionproperty", "position") +%! unwind_protect +%! plot (rand (3)) +%! position = get (gca, "position"); +%! outerposition = get (gca, "outerposition"); +%! looseinset = get (gca, "looseinset"); +%! tightinset = get (gca, "tightinset"); +%! set (hf, "position", [fpos(1:2), 2*fpos(3:4)]) +%! set (hf, "position", fpos); +%! assert (get (gca, "position"), position, 0.001) +%! assert (get (gca, "outerposition"), outerposition, 0.001) +%! assert (get (gca, "looseinset"), looseinset, 0.001) +%! assert (get (gca, "tightinset"), tightinset, 0.001) +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect +*/ void axes::properties::set_text_child (handle_property& hp, @@ -4334,7 +4241,7 @@ { box = "on"; colororder = default_colororder (); - dataaspectratio = Matrix (1, 3, 1.0); + // Note: dataspectratio will be set through update_aspectratios dataaspectratiomode = "auto"; layer = "bottom"; @@ -4348,10 +4255,13 @@ cl(1) = 1; clim = cl; + alim = tlim; + xlimmode = "auto"; ylimmode = "auto"; zlimmode = "auto"; climmode = "auto"; + alimmode = "auto"; xgrid = "off"; ygrid = "off"; @@ -4365,12 +4275,18 @@ xtickmode = "auto"; ytickmode = "auto"; ztickmode = "auto"; + xminortick = "off"; + yminortick = "off"; + zminortick = "off"; xticklabel = ""; yticklabel = ""; zticklabel = ""; xticklabelmode = "auto"; yticklabelmode = "auto"; zticklabelmode = "auto"; + + interpreter = "none"; + color = color_values ("white"); xcolor = color_values ("black"); ycolor = color_values ("black"); @@ -4384,44 +4300,53 @@ yaxislocation = "left"; xaxislocation = "bottom"; - // Note: camera properties will be set through update_transform + Matrix tview (1, 2, 0.0); + tview(1) = 90; + view = tview; + + __hold_all__ = "off"; + nextplot = "replace"; + + ambientlightcolor = Matrix (1, 3, 1.0); + + // Note: camera properties (not mode) will be set in update_transform camerapositionmode = "auto"; cameratargetmode = "auto"; cameraupvectormode = "auto"; cameraviewanglemode = "auto"; - plotboxaspectratio = Matrix (1, 3, 1.0); + drawmode = "normal"; + + fontangle = "normal"; + fontname = OCTAVE_DEFAULT_FONTNAME; + fontsize = 10; + fontunits = "points"; + fontweight = "normal"; + gridlinestyle = ":"; linestyleorder = "-"; linewidth = 0.5; minorgridlinestyle = ":"; - // Note: plotboxaspectratio will be set through update_aspectratiors + + // Note: plotboxaspectratio will be set through update_aspectratios plotboxaspectratiomode = "auto"; projection = "orthographic"; + tickdir = "in"; tickdirmode = "auto"; ticklength = default_axes_ticklength (); + tightinset = Matrix (1, 4, 0.0); sx = "linear"; sy = "linear"; sz = "linear"; - Matrix tview (1, 2, 0.0); - tview(1) = 90; - view = tview; - visible = "on"; - nextplot = "replace"; - + + // Replace preserves Position and Units properties if (mode != "replace") { - fontangle = "normal"; - fontname = OCTAVE_DEFAULT_FONTNAME; - fontsize = 10; - fontunits = "points"; - fontweight = "normal"; - outerposition = default_axes_outerposition (); position = default_axes_position (); activepositionproperty = "outerposition"; @@ -4483,7 +4408,7 @@ adopt (title.handle_value ()); update_transform (); - update_insets (); + sync_positions (); override_defaults (obj); } @@ -4689,7 +4614,7 @@ double yo = ylimits(yd > 0 ? 0 : 1); double zo = zlimits(zd > 0 ? 0 : 1); - Matrix pb = get_plotboxaspectratio ().matrix_value (); + Matrix pb = get_plotboxaspectratio ().matrix_value (); bool autocam = (camerapositionmode_is ("auto") && cameratargetmode_is ("auto") @@ -5491,8 +5416,7 @@ double min_pos = octave_Inf; double max_neg = -octave_Inf; get_children_limits (minval, maxval, min_pos, max_neg, kids, limit_type); - if (!xisinf (minval) && !xisnan (minval) - && !xisinf (maxval) && !xisnan (maxval)) + if (xfinite (minval) && xfinite (maxval)) { limits(0) = minval; limits(1) = maxval; @@ -5842,6 +5766,56 @@ } } +// Almost identical to convert_ticklabel_string but it only accepts +// cellstr or string, not numeric input. +static octave_value +convert_linestyleorder_string (const octave_value& val) +{ + octave_value retval = val; + + if (val.is_cellstr ()) + { + // Always return a column vector for Matlab Compatibility + if (val.columns () > 1) + retval = val.reshape (dim_vector (val.numel (), 1)); + } + else + { + string_vector sv; + if (val.is_string () && val.rows () == 1) + { + std::string valstr = val.string_value (); + std::istringstream iss (valstr); + std::string tmpstr; + + // Split string with delimiter '|' + while (std::getline (iss, tmpstr, '|')) + sv.append (tmpstr); + + // If string ends with '|' Matlab appends a null string + if (*valstr.rbegin () == '|') + sv.append (std::string ("")); + } + else + return retval; + + charMatrix chmat (sv, ' '); + + retval = octave_value (chmat); + } + + return retval; +} + +void +axes::properties::set_linestyleorder (const octave_value& v) +{ + if (!error_state) + { + linestyleorder.set (convert_linestyleorder_string (v), false); + } +} + void axes::properties::set_units (const octave_value& v) { @@ -5973,16 +5947,16 @@ const array_property& data) { double val = data.min_val (); - if (! (xisinf (val) || xisnan (val)) && val < min_val) + if (xfinite (val) && val < min_val) min_val = val; val = data.max_val (); - if (! (xisinf (val) || xisnan (val)) && val > max_val) + if (xfinite (val) && val > max_val) max_val = val; val = data.min_pos (); - if (! (xisinf (val) || xisnan (val)) && val > 0 && val < min_pos) + if (xfinite (val) && val > 0 && val < min_pos) min_pos = val; val = data.max_neg (); - if (! (xisinf (val) || xisnan (val)) && val < 0 && val > max_neg) + if (xfinite (val) && val < 0 && val > max_neg) max_neg = val; } */ @@ -6001,19 +5975,19 @@ double val; val = m(0); - if (! (xisinf (val) || xisnan (val)) && val < min_val) + if (xfinite (val) && val < min_val) min_val = val; val = m(1); - if (! (xisinf (val) || xisnan (val)) && val > max_val) + if (xfinite (val) && val > max_val) max_val = val; val = m(2); - if (! (xisinf (val) || xisnan (val)) && val > 0 && val < min_pos) + if (xfinite (val) && val > 0 && val < min_pos) min_pos = val; val = m(3); - if (! (xisinf (val) || xisnan (val)) && val < 0 && val > max_neg) + if (xfinite (val) && val < 0 && val > max_neg) max_neg = val; } } @@ -6352,7 +6326,7 @@ label.erase (0, label.find_first_not_of (" ")); label = label.substr (0, label.find_last_not_of (" ")+1); #ifdef HAVE_FREETYPE - ext = text_renderer.get_extent (label); + ext = text_renderer.get_extent (label, 0.0, "none"); wmax = std::max (wmax, ext(0)); hmax = std::max (hmax, ext(1)); #else @@ -6478,16 +6452,16 @@ if (limits.numel () == 4) \ { \ val = limits(0); \ - if (! (xisinf (val) || xisnan (val))) \ + if (xfinite (val)) \ min_val = val; \ val = limits(1); \ - if (! (xisinf (val) || xisnan (val))) \ + if (xfinite (val)) \ max_val = val; \ val = limits(2); \ - if (! (xisinf (val) || xisnan (val))) \ + if (xfinite (val)) \ min_pos = val; \ val = limits(3); \ - if (! (xisinf (val) || xisnan (val))) \ + if (xfinite (val)) \ max_neg = val; \ } \ else \ @@ -7077,6 +7051,8 @@ xinitialize (xproperties.get_xlabel ()); xinitialize (xproperties.get_ylabel ()); xinitialize (xproperties.get_zlabel ()); + + xproperties.sync_positions (); } // --------------------------------------------------------------------- @@ -7186,7 +7162,8 @@ string_vector sv = string_prop.all_strings (); renderer.text_to_pixels (sv.join ("\n"), pixels, bbox, - halign, valign, get_rotation ()); + halign, valign, get_rotation (), + get_interpreter ()); /* The bbox is relative to the text's position. We'll leave it that way, because get_position () does not return valid results when the text is first constructed. @@ -7451,16 +7428,16 @@ if (limits.numel () == 4) { val = limits(0); - if (! (xisinf (val) || xisnan (val))) + if (xfinite (val)) min_val = val; val = limits(1); - if (! (xisinf (val) || xisnan (val))) + if (xfinite (val)) max_val = val; val = limits(2); - if (! (xisinf (val) || xisnan (val))) + if (xfinite (val)) min_pos = val; val = limits(3); - if (! (xisinf (val) || xisnan (val))) + if (xfinite (val)) max_neg = val; } else @@ -7631,7 +7608,7 @@ // FIXME: parsed content should be cached for efficiency // FIXME: support multiline text - elt = text_parser_none ().parse (get_string_string ()); + elt = text_parser::parse (get_string_string (), "none"); #ifdef HAVE_FONTCONFIG text_renderer.set_font (get_fontname (), get_fontweight (), @@ -7639,6 +7616,7 @@ get_fontsize ()); #endif box = text_renderer.get_extent (elt, 0); + delete elt; Matrix ext (1, 4, 0.0); @@ -8447,10 +8425,11 @@ "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} ishandle (@var{h})\n\ Return true if @var{h} is a graphics handle and false otherwise.\n\ +\n\ @var{h} may also be a matrix of handles in which case a logical\n\ array is returned that is true where the elements of @var{h} are\n\ graphics handles and false where they are not.\n\ -@seealso{isfigure}\n\ +@seealso{isaxes, isfigure}\n\ @end deftypefn") { gh_manager::auto_lock guard; @@ -8522,9 +8501,10 @@ "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} reset (@var{h}, @var{property})\n\ Remove any defaults set for the handle @var{h}. The default figure\n\ -properties of \"position\", \"units\", \"windowstyle\" and\n\ -\"paperunits\" and the default axes properties of \"position\" and \"units\"\n\ -are not reset.\n\ +properties of @qcode{\"position\"}, @qcode{\"units\"},\n\ +@qcode{\"windowstyle\"} and @qcode{\"paperunits\"} and the default axes\n\ +properties of @qcode{\"position\"} and @qcode{\"units\"} are not reset.\n\ +@seealso{cla, clf}\n\ @end deftypefn") { int nargin = args.length (); @@ -9108,25 +9088,27 @@ if (go.isa ("surface")) nd = 3; - - if ((go.isa ("line") || go.isa ("patch")) && ! go.get("zdata").is_empty ()) + else if ((go.isa ("line") || go.isa ("patch")) + && ! go.get ("zdata").is_empty ()) nd = 3; - - Matrix kids = go.get_properties ().get_children (); - - for (octave_idx_type i = 0; i < kids.length (); i++) - { - graphics_handle hnd = gh_manager::lookup (kids(i)); - - if (hnd.ok ()) - { - const graphics_object& kid = gh_manager::get_object (hnd); - - if (kid.valid_object ()) - nd = calc_dimensions (kid); - - if (nd == 3) - break; + else + { + Matrix kids = go.get_properties ().get_children (); + + for (octave_idx_type i = 0; i < kids.length (); i++) + { + graphics_handle hnd = gh_manager::lookup (kids(i)); + + if (hnd.ok ()) + { + const graphics_object& kid = gh_manager::get_object (hnd); + + if (kid.valid_object ()) + nd = calc_dimensions (kid); + + if (nd == 3) + break; + } } } @@ -9146,17 +9128,15 @@ int nargin = args.length (); - if (nargin == 1) - { - double h = args(0).double_value (); - - if (! error_state) - retval = calc_dimensions (gh_manager::get_object (h)); - else - error ("__calc_dimensions__: expecting graphics handle as only argument"); - } + if (nargin != 1) + print_usage (); + + double h = args(0).double_value (); + + if (! error_state) + retval = calc_dimensions (gh_manager::get_object (h)); else - print_usage (); + error ("__calc_dimensions__: expecting graphics handle as only argument"); return retval; } @@ -9505,6 +9485,16 @@ gtk_manager *gtk_manager::instance = 0; +gtk_manager::gtk_manager (void) + : dtk (), available_toolkits (), loaded_toolkits () +{ +#if defined (HAVE_FLTK) + dtk = "fltk"; +#else + dtk = "gnuplot"; +#endif +} + void gtk_manager::create_instance (void) { @@ -9606,7 +9596,7 @@ @deftypefnx {Built-in Function} {} drawnow (@var{term}, @var{file}, @var{mono}, @var{debug_file})\n\ Update figure windows and their children. The event queue is flushed and\n\ any callbacks generated are executed. With the optional argument\n\ -@code{\"expose\"}, only graphic objects are updated and no other events or\n\ +@qcode{\"expose\"}, only graphic objects are updated and no other events or\n\ callbacks are processed.\n\ The third calling form of @code{drawnow} is for debugging and is\n\ undocumented.\n\ @@ -9791,6 +9781,7 @@ @end group\n\ @end example\n\ \n\ +@seealso{addproperty, hggroup}\n\ @end deftypefn") { gh_manager::auto_lock guard; @@ -9983,6 +9974,7 @@ @end group\n\ @end example\n\ \n\ +@seealso{addlistener, hggroup}\n\ @end deftypefn") { gh_manager::auto_lock guard; @@ -10211,11 +10203,12 @@ @deftypefnx {Built-in Function} {} waitfor (@var{h}, @var{prop}, @var{value})\n\ @deftypefnx {Built-in Function} {} waitfor (@dots{}, \"timeout\", @var{timeout})\n\ Suspend the execution of the current program until a condition is\n\ -satisfied on the graphics handle @var{h}. While the program is suspended\n\ -graphics events are still being processed normally, allowing callbacks to\n\ -modify the state of graphics objects. This function is reentrant and can be\n\ -called from a callback, while another @code{waitfor} call is pending at\n\ -top-level.\n\ +satisfied on the graphics handle @var{h}.\n\ +\n\ +While the program is suspended graphics events are still being processed\n\ +normally, allowing callbacks to modify the state of graphics objects. This\n\ +function is reentrant and can be called from a callback, while another\n\ +@code{waitfor} call is pending at the top-level.\n\ \n\ In the first form, program execution is suspended until the graphics object\n\ @var{h} is destroyed. If the graphics handle is invalid, the function\n\ @@ -10242,7 +10235,7 @@ @code{\\timeout} instead.\n\ \n\ In all cases, typing CTRL-C stops program execution immediately.\n\ -@seealso{isequal}\n\ +@seealso{waitforbuttonpress, isequal}\n\ @end deftypefn") { if (args.length () > 0) @@ -10410,7 +10403,7 @@ // FIXME: There is still a "hole" in the following loop. The code // assumes that an object handle is unique, which is a fair - // assumptions, except for figures. If a figure is destroyed + // assumption, except for figures. If a figure is destroyed // then recreated with the same figure ID, within the same // run of event hooks, then the figure destruction won't be // caught and the loop will not stop. This is an unlikely diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/graphics.in.h --- a/libinterp/corefcn/graphics.in.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/graphics.in.h Sat Oct 05 11:22:09 2013 -0400 @@ -37,123 +37,23 @@ #include #include "caseless-str.h" -#include "lo-ieee.h" #include "gripes.h" +#include "oct-handle.h" #include "oct-map.h" #include "oct-mutex.h" #include "oct-refcount.h" #include "ov.h" #include "txt-eng-ft.h" -// FIXME -- maybe this should be a configure option? +// FIXME: maybe this should be a configure option? // Matlab defaults to "Helvetica", but that causes problems for many // gnuplot users. #if !defined (OCTAVE_DEFAULT_FONTNAME) #define OCTAVE_DEFAULT_FONTNAME "*" #endif -// --------------------------------------------------------------------- - -class graphics_handle -{ -public: - graphics_handle (void) : val (octave_NaN) { } - - graphics_handle (const octave_value& a); - - graphics_handle (int a) : val (a) { } - - graphics_handle (double a) : val (a) { } - - graphics_handle (const graphics_handle& a) : val (a.val) { } - - graphics_handle& operator = (const graphics_handle& a) - { - if (&a != this) - val = a.val; - - return *this; - } - - ~graphics_handle (void) { } - - double value (void) const { return val; } - - octave_value as_octave_value (void) const - { - return ok () ? octave_value (val) : octave_value (Matrix ()); - } - - // Prefix increment/decrement operators. - graphics_handle& operator ++ (void) - { - ++val; - return *this; - } - - graphics_handle& operator -- (void) - { - --val; - return *this; - } - - // Postfix increment/decrement operators. - const graphics_handle operator ++ (int) - { - graphics_handle old_value = *this; - ++(*this); - return old_value; - } - - const graphics_handle operator -- (int) - { - graphics_handle old_value = *this; - --(*this); - return old_value; - } - - bool ok (void) const { return ! xisnan (val); } - -private: - double val; -}; - -inline bool -operator == (const graphics_handle& a, const graphics_handle& b) -{ - return a.value () == b.value (); -} - -inline bool -operator != (const graphics_handle& a, const graphics_handle& b) -{ - return a.value () != b.value (); -} - -inline bool -operator < (const graphics_handle& a, const graphics_handle& b) -{ - return a.value () < b.value (); -} - -inline bool -operator <= (const graphics_handle& a, const graphics_handle& b) -{ - return a.value () <= b.value (); -} - -inline bool -operator >= (const graphics_handle& a, const graphics_handle& b) -{ - return a.value () >= b.value (); -} - -inline bool -operator > (const graphics_handle& a, const graphics_handle& b) -{ - return a.value () > b.value (); -} +typedef octave_handle graphics_handle; // --------------------------------------------------------------------- @@ -1483,7 +1383,7 @@ if (validate (tmp)) { - // FIXME -- should we check for actual data change? + // FIXME: should we check for actual data change? if (! is_equal (tmp)) { data = tmp; @@ -2361,10 +2261,7 @@ private: - // FIXME -- default toolkit should be configurable. - - gtk_manager (void) - : dtk ("gnuplot"), available_toolkits (), loaded_toolkits () { } + gtk_manager (void); ~gtk_manager (void) { } @@ -2628,22 +2525,22 @@ static property_list::pval_map_type factory_defaults (void); - // FIXME -- these functions should be generated automatically by the - // genprops.awk script. + // FIXME: these functions should be generated automatically by the + // genprops.awk script. // // EMIT_BASE_PROPERTIES_GET_FUNCTIONS + virtual octave_value get_alim (void) const { return octave_value (); } + virtual octave_value get_clim (void) const { return octave_value (); } virtual octave_value get_xlim (void) const { return octave_value (); } virtual octave_value get_ylim (void) const { return octave_value (); } virtual octave_value get_zlim (void) const { return octave_value (); } - virtual octave_value get_clim (void) const { return octave_value (); } - virtual octave_value get_alim (void) const { return octave_value (); } - + + virtual bool is_aliminclude (void) const { return false; } + virtual bool is_climinclude (void) const { return false; } virtual bool is_xliminclude (void) const { return false; } virtual bool is_yliminclude (void) const { return false; } virtual bool is_zliminclude (void) const { return false; } - virtual bool is_climinclude (void) const { return false; } - virtual bool is_aliminclude (void) const { return false; } bool is_handle_visible (void) const; @@ -2679,13 +2576,12 @@ bool_property selectionhighlight , "on" string_property tag s , "" string_property type frs , ty + handle_property uicontextmenu , graphics_handle () any_property userdata , Matrix () bool_property visible , "on" - // additional (octave-specific) properties + // additional (Octave-specific) properties bool_property __modified__ s , "on" graphics_handle __myhandle__ fhrs , mh - // FIXME -- should this really be here? - handle_property uicontextmenu , graphics_handle () END_PROPERTIES protected: @@ -3110,11 +3006,17 @@ operator bool (void) const { return rep->valid_object (); } - // FIXME -- these functions should be generated automatically by the - // genprops.awk script. + // FIXME: these functions should be generated automatically by the + // genprops.awk script. // // EMIT_GRAPHICS_OBJECT_GET_FUNCTIONS + octave_value get_alim (void) const + { return get_properties ().get_alim (); } + + octave_value get_clim (void) const + { return get_properties ().get_clim (); } + octave_value get_xlim (void) const { return get_properties ().get_xlim (); } @@ -3124,11 +3026,11 @@ octave_value get_zlim (void) const { return get_properties ().get_zlim (); } - octave_value get_clim (void) const - { return get_properties ().get_clim (); } - - octave_value get_alim (void) const - { return get_properties ().get_alim (); } + bool is_aliminclude (void) const + { return get_properties ().is_aliminclude (); } + + bool is_climinclude (void) const + { return get_properties ().is_climinclude (); } bool is_xliminclude (void) const { return get_properties ().is_xliminclude (); } @@ -3139,12 +3041,6 @@ bool is_zliminclude (void) const { return get_properties ().is_zliminclude (); } - bool is_climinclude (void) const - { return get_properties ().is_climinclude (); } - - bool is_aliminclude (void) const - { return get_properties ().is_aliminclude (); } - bool is_handle_visible (void) const { return get_properties ().is_handle_visible (); } @@ -3187,14 +3083,22 @@ // See the genprops.awk script for an explanation of the // properties declarations. - // FIXME -- it seems strange to me that the diary, diaryfile, - // echo, format, formatspacing, language, and recursionlimit - // properties are here. WTF do they have to do with graphics? + // FIXME: it seems strange to me that the diary, diaryfile, + // echo, errormessage, format, formatspacing, language, and + // recursionlimit properties are here. + // WTF do they have to do with graphics? // Also note that these properties (and the monitorpositions, // pointerlocation, and pointerwindow properties) are not yet used // by Octave, so setting them will have no effect, and changes // made elswhere (say, the diary or format functions) will not // cause these properties to be updated. + // ANSWER: Matlab defines these properties and uses them in + // the same way that Octave uses an internal static variable to + // keep track of state. set (0, "echo", "on") is equivalent + // to Octave's echo ("on"). Maybe someday we can connect callbacks + // that actually call Octave's own functions for this. + + // Programming note: Keep property list sorted if new ones are added. BEGIN_PROPERTIES (root_figure, root) handle_property callbackobject Sr , graphics_handle () @@ -3203,12 +3107,14 @@ bool_property diary , "off" string_property diaryfile , "diary" bool_property echo , "off" - radio_property format , "+|bank|bit|debug|hex|long|longe|longeng|longg|native-bit|native-hex|rational|{short}|shorte|shorteng|shortg" - radio_property formatspacing , "{loose}|compact" + string_property errormessage , "" + string_property fixedwidthfontname , "Courier" + radio_property format , "+|bank|bit|hex|long|longe|longeng|longg|native-bit|native-hex|none|rational|{short}|shorte|shorteng|shortg" + radio_property formatspacing , "compact|{loose}" string_property language , "ascii" array_property monitorpositions , Matrix (1, 4, 0) array_property pointerlocation , Matrix (1, 2, 0) - double_property pointerwindow , 0.0 + double_property pointerwindow r , 0.0 double_property recursionlimit , 256.0 double_property screendepth r , default_screendepth () double_property screenpixelsperinch r , default_screenpixelsperinch () @@ -3393,17 +3299,15 @@ // See the genprops.awk script for an explanation of the // properties declarations. + // Programming note: Keep property list sorted if new ones are added. BEGIN_PROPERTIES (figure) - any_property __plot_stream__ h , Matrix () - bool_property __enhanced__ h , "on" - radio_property nextplot , "new|{add}|replacechildren|replace" + array_property alphamap , Matrix (64, 1, 1) + callback_property buttondownfcn , Matrix () callback_property closerequestfcn , "closereq" + color_property color , color_property (color_values (1, 1, 1), radio_values ("none")) + array_property colormap , jet_colormap () handle_property currentaxes S , graphics_handle () - array_property colormap , jet_colormap () - radio_property paperorientation U , "{portrait}|landscape|rotated" - color_property color , color_property (color_values (1, 1, 1), radio_values ("none")) - array_property alphamap , Matrix (64, 1, 1) string_property currentcharacter r , "" handle_property currentobject r , graphics_handle () array_property currentpoint r , Matrix (2, 1, 0) @@ -3417,13 +3321,15 @@ radio_property menubar , "none|{figure}" double_property mincolormap , 64 string_property name , "" + radio_property nextplot , "new|{add}|replacechildren|replace" bool_property numbertitle , "on" array_property outerposition s , Matrix (1, 4, -1.0) - radio_property paperunits Su , "{inches}|centimeters|normalized|points" + radio_property paperorientation U , "{portrait}|landscape|rotated" array_property paperposition , default_figure_paperposition () radio_property paperpositionmode , "auto|{manual}" array_property papersize U , default_figure_papersize () radio_property papertype SU , "{usletter}|uslegal|a0|a1|a2|a3|a4|a5|b0|b1|b2|b3|b4|b5|arch-a|arch-b|arch-c|arch-d|arch-e|a|b|c|d|e|tabloid|" + radio_property paperunits Su , "{inches}|centimeters|normalized|points" radio_property pointer , "crosshair|fullcrosshair|{arrow}|ibeam|watch|topl|topr|botl|botr|left|top|right|bottom|circle|cross|fleur|custom|hand" array_property pointershapecdata , Matrix (16, 16, 0) array_property pointershapehotspot , Matrix (1, 2, 0) @@ -3438,16 +3344,20 @@ callback_property windowbuttondownfcn , Matrix () callback_property windowbuttonmotionfcn , Matrix () callback_property windowbuttonupfcn , Matrix () - callback_property windowbuttonwheelfcn , Matrix () + callback_property windowkeypressfcn , Matrix () + callback_property windowkeyreleasefcn , Matrix () + callback_property windowscrollwheelfcn , Matrix () radio_property windowstyle , "{normal}|modal|docked" string_property wvisual , "" radio_property wvisualmode , "{auto}|manual" string_property xdisplay , "" string_property xvisual , "" radio_property xvisualmode , "{auto}|manual" - callback_property buttondownfcn , Matrix () - string_property __graphics_toolkit__ s , "gnuplot" + // Octave-specific properties + bool_property __enhanced__ h , "on" + string_property __graphics_toolkit__ s , gtk_manager::default_toolkit () any_property __guidata__ h , Matrix () + any_property __plot_stream__ h , Matrix () END_PROPERTIES protected: @@ -3662,6 +3572,8 @@ update_axes_layout (); } + void sync_positions (void); + void update_autopos (const std::string& elem_type); void update_xlabel_position (void); void update_ylabel_position (void); @@ -3762,80 +3674,29 @@ // See the genprops.awk script for an explanation of the // properties declarations. - - // properties which are not in matlab: interpreter + // Programming note: Keep property list sorted if new ones are added. BEGIN_PROPERTIES (axes) - array_property position u , default_axes_position () + radio_property activepositionproperty , "{outerposition}|position" + row_vector_property alim m , default_lim () + radio_property alimmode , "{auto}|manual" + color_property ambientlightcolor , color_values (1, 1, 1) bool_property box , "on" + array_property cameraposition m , Matrix (1, 3, 0.0) + radio_property camerapositionmode , "{auto}|manual" + array_property cameratarget m , Matrix (1, 3, 0.0) + radio_property cameratargetmode , "{auto}|manual" + array_property cameraupvector m , Matrix () + radio_property cameraupvectormode , "{auto}|manual" + double_property cameraviewangle m , 10.0 + radio_property cameraviewanglemode , "{auto}|manual" + row_vector_property clim m , default_lim () + radio_property climmode al , "{auto}|manual" + color_property color , color_property (color_values (1, 1, 1), radio_values ("none")) array_property colororder , default_colororder () + array_property currentpoint , Matrix (2, 3, 0.0) array_property dataaspectratio mu , Matrix (1, 3, 1.0) radio_property dataaspectratiomode u , "{auto}|manual" - radio_property layer u , "{bottom}|top" - row_vector_property xlim mu , default_lim () - row_vector_property ylim mu , default_lim () - row_vector_property zlim mu , default_lim () - row_vector_property clim m , default_lim () - row_vector_property alim m , default_lim () - radio_property xlimmode al , "{auto}|manual" - radio_property ylimmode al , "{auto}|manual" - radio_property zlimmode al , "{auto}|manual" - radio_property climmode al , "{auto}|manual" - radio_property alimmode , "{auto}|manual" - handle_property xlabel SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false, false, false) - handle_property ylabel SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false, false, false) - handle_property zlabel SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false, false, false) - handle_property title SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false, false, false) - bool_property xgrid , "off" - bool_property ygrid , "off" - bool_property zgrid , "off" - bool_property xminorgrid , "off" - bool_property yminorgrid , "off" - bool_property zminorgrid , "off" - row_vector_property xtick mu , default_axes_tick () - row_vector_property ytick mu , default_axes_tick () - row_vector_property ztick mu , default_axes_tick () - radio_property xtickmode u , "{auto}|manual" - radio_property ytickmode u , "{auto}|manual" - radio_property ztickmode u , "{auto}|manual" - bool_property xminortick , "off" - bool_property yminortick , "off" - bool_property zminortick , "off" - // FIXME -- should be kind of string array. - any_property xticklabel S , "" - any_property yticklabel S , "" - any_property zticklabel S , "" - radio_property xticklabelmode u , "{auto}|manual" - radio_property yticklabelmode u , "{auto}|manual" - radio_property zticklabelmode u , "{auto}|manual" - radio_property interpreter , "tex|{none}|latex" - color_property color , color_property (color_values (1, 1, 1), radio_values ("none")) - color_property xcolor , color_values (0, 0, 0) - color_property ycolor , color_values (0, 0, 0) - color_property zcolor , color_values (0, 0, 0) - radio_property xscale alu , "{linear}|log" - radio_property yscale alu , "{linear}|log" - radio_property zscale alu , "{linear}|log" - radio_property xdir u , "{normal}|reverse" - radio_property ydir u , "{normal}|reverse" - radio_property zdir u , "{normal}|reverse" - radio_property yaxislocation u , "{left}|right|zero" - radio_property xaxislocation u , "{bottom}|top|zero" - array_property view u , Matrix () - bool_property __hold_all__ h , "off" - radio_property nextplot , "new|add|replacechildren|{replace}" - array_property outerposition u , default_axes_outerposition () - radio_property activepositionproperty , "{outerposition}|position" - color_property ambientlightcolor , color_values (1, 1, 1) - array_property cameraposition m , Matrix (1, 3, 0.0) - array_property cameratarget m , Matrix (1, 3, 0.0) - array_property cameraupvector m , Matrix () - double_property cameraviewangle m , 10.0 - radio_property camerapositionmode , "{auto}|manual" - radio_property cameratargetmode , "{auto}|manual" - radio_property cameraupvectormode , "{auto}|manual" - radio_property cameraviewanglemode , "{auto}|manual" - array_property currentpoint , Matrix (2, 3, 0.0) radio_property drawmode , "{normal}|fast" radio_property fontangle u , "{normal}|italic|oblique" string_property fontname u , OCTAVE_DEFAULT_FONTNAME @@ -3843,18 +3704,76 @@ radio_property fontunits SU , "{points}|normalized|inches|centimeters|pixels" radio_property fontweight u , "{normal}|light|demi|bold" radio_property gridlinestyle , "-|--|{:}|-.|none" - string_array_property linestyleorder , "-" + // NOTE: interpreter is not a Matlab axis property, but it makes + // more sense to have it so that axis ticklabels can use it. + radio_property interpreter , "tex|{none}|latex" + radio_property layer u , "{bottom}|top" + // FIXME: should be kind of string array. + any_property linestyleorder S , "-" double_property linewidth , 0.5 radio_property minorgridlinestyle , "-|--|{:}|-.|none" + radio_property nextplot , "add|replacechildren|{replace}" + array_property outerposition u , default_axes_outerposition () array_property plotboxaspectratio mu , Matrix (1, 3, 1.0) radio_property plotboxaspectratiomode u , "{auto}|manual" + array_property position u , default_axes_position () radio_property projection , "{orthographic}|perpective" radio_property tickdir mu , "{in}|out" radio_property tickdirmode u , "{auto}|manual" array_property ticklength u , default_axes_ticklength () array_property tightinset r , Matrix (1, 4, 0.0) - // FIXME -- uicontextmenu should be moved here. + handle_property title SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false, false, false) + // FIXME: uicontextmenu should be moved here. radio_property units SU , "{normalized}|inches|centimeters|points|pixels|characters" + array_property view u , Matrix () + radio_property xaxislocation u , "{bottom}|top|zero" + color_property xcolor , color_values (0, 0, 0) + radio_property xdir u , "{normal}|reverse" + bool_property xgrid , "off" + handle_property xlabel SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false, false, false) + row_vector_property xlim mu , default_lim () + radio_property xlimmode al , "{auto}|manual" + bool_property xminorgrid , "off" + bool_property xminortick , "off" + radio_property xscale alu , "{linear}|log" + row_vector_property xtick mu , default_axes_tick () + // FIXME: should be kind of string array. + any_property xticklabel S , "" + radio_property xticklabelmode u , "{auto}|manual" + radio_property xtickmode u , "{auto}|manual" + radio_property yaxislocation u , "{left}|right|zero" + color_property ycolor , color_values (0, 0, 0) + radio_property ydir u , "{normal}|reverse" + bool_property ygrid , "off" + handle_property ylabel SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false, false, false) + row_vector_property ylim mu , default_lim () + radio_property ylimmode al , "{auto}|manual" + bool_property yminorgrid , "off" + bool_property yminortick , "off" + radio_property yscale alu , "{linear}|log" + row_vector_property ytick mu , default_axes_tick () + any_property yticklabel S , "" + radio_property yticklabelmode u , "{auto}|manual" + radio_property ytickmode u , "{auto}|manual" + color_property zcolor , color_values (0, 0, 0) + radio_property zdir u , "{normal}|reverse" + bool_property zgrid , "off" + handle_property zlabel SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false, false, false) + row_vector_property zlim mu , default_lim () + radio_property zlimmode al , "{auto}|manual" + bool_property zminorgrid , "off" + bool_property zminortick , "off" + radio_property zscale alu , "{linear}|log" + row_vector_property ztick mu , default_axes_tick () + any_property zticklabel S , "" + radio_property zticklabelmode u , "{auto}|manual" + radio_property ztickmode u , "{auto}|manual" + // Octave-specific properties + bool_property __hold_all__ h , "off" + // hidden properties for alignment of subplots + radio_property autopos_tag h , "{none}|subplot" + // hidden properties for inset + array_property looseinset hu , Matrix (1, 4, 0.0) // hidden properties for transformation computation array_property x_viewtransform h , Matrix (4, 4, 0.0) array_property x_projectiontransform h , Matrix (4, 4, 0.0) @@ -3865,10 +3784,6 @@ row_vector_property xmtick h , Matrix () row_vector_property ymtick h , Matrix () row_vector_property zmtick h , Matrix () - // hidden properties for inset - array_property looseinset hu , Matrix (1, 4, 0.0) - // hidden properties for alignment of subplots - radio_property autopos_tag h , "{none}|subplot" END_PROPERTIES protected: @@ -3991,24 +3906,85 @@ void update_fontangle (void) { update_font (); } void update_fontweight (void) { update_font (); } - void sync_positions (const Matrix& linset); - void sync_positions (void); - - void update_insets (void); - void update_outerposition (void) { set_activepositionproperty ("outerposition"); - sync_positions (); + caseless_str old_units = get_units (); + set_units ("normalized"); + Matrix outerbox = outerposition.get ().matrix_value (); + Matrix innerbox = position.get ().matrix_value (); + Matrix linset = looseinset.get ().matrix_value (); + Matrix tinset = tightinset.get ().matrix_value (); + outerbox(2) = outerbox(2) + outerbox(0); + outerbox(3) = outerbox(3) + outerbox(1); + innerbox(0) = outerbox(0) + std::max (linset(0), tinset(0)); + innerbox(1) = outerbox(1) + std::max (linset(1), tinset(1)); + innerbox(2) = outerbox(2) - std::max (linset(2), tinset(2)); + innerbox(3) = outerbox(3) - std::max (linset(3), tinset(3)); + innerbox(2) = innerbox(2) - innerbox(0); + innerbox(3) = innerbox(3) - innerbox(1); + position = innerbox; + set_units (old_units); + update_transform (); } void update_position (void) { set_activepositionproperty ("position"); - sync_positions (); + caseless_str old_units = get_units (); + set_units ("normalized"); + Matrix outerbox = outerposition.get ().matrix_value (); + Matrix innerbox = position.get ().matrix_value (); + Matrix linset = looseinset.get ().matrix_value (); + Matrix tinset = tightinset.get ().matrix_value (); + innerbox(2) = innerbox(2) + innerbox(0); + innerbox(3) = innerbox(3) + innerbox(1); + outerbox(0) = innerbox(0) - std::max (linset(0), tinset(0)); + outerbox(1) = innerbox(1) - std::max (linset(1), tinset(1)); + outerbox(2) = innerbox(2) + std::max (linset(2), tinset(2)); + outerbox(3) = innerbox(3) + std::max (linset(3), tinset(3)); + outerbox(2) = outerbox(2) - outerbox(0); + outerbox(3) = outerbox(3) - outerbox(1); + outerposition = outerbox; + set_units (old_units); + update_transform (); } - void update_looseinset (void) { sync_positions (); } + void update_looseinset (void) + { + caseless_str old_units = get_units (); + set_units ("normalized"); + Matrix innerbox = position.get ().matrix_value (); + innerbox(2) = innerbox(2) + innerbox(0); + innerbox(3) = innerbox(3) + innerbox(1); + Matrix outerbox = outerposition.get ().matrix_value (); + outerbox(2) = outerbox(2) + outerbox(0); + outerbox(3) = outerbox(3) + outerbox(1); + Matrix linset = looseinset.get ().matrix_value (); + Matrix tinset = tightinset.get ().matrix_value (); + if (activepositionproperty.is ("position")) + { + outerbox(0) = innerbox(0) - std::max (linset(0), tinset(0)); + outerbox(1) = innerbox(1) - std::max (linset(1), tinset(1)); + outerbox(2) = innerbox(2) + std::max (linset(2), tinset(2)); + outerbox(3) = innerbox(3) + std::max (linset(3), tinset(3)); + outerbox(2) = outerbox(2) - outerbox(0); + outerbox(3) = outerbox(3) - outerbox(1); + outerposition = outerbox; + } + else + { + innerbox(0) = outerbox(0) + std::max (linset(0), tinset(0)); + innerbox(1) = outerbox(1) + std::max (linset(1), tinset(1)); + innerbox(2) = outerbox(2) - std::max (linset(2), tinset(2)); + innerbox(3) = outerbox(3) - std::max (linset(3), tinset(3)); + innerbox(2) = innerbox(2) - innerbox(0); + innerbox(3) = innerbox(3) - innerbox(1); + position = innerbox; + } + set_units (old_units); + update_transform (); + } double calc_tick_sep (double minval, double maxval); void calc_ticks_and_lims (array_property& lims, array_property& ticks, array_property& mticks, @@ -4145,7 +4121,7 @@ { octave_value retval; - // FIXME -- finish this. + // FIXME: finish this. if (name.compare ("default", 7)) retval = get_default (name.substr (7)); else @@ -4191,26 +4167,28 @@ public: // See the genprops.awk script for an explanation of the // properties declarations. - - // properties which are not in matlab: interpreter + // Programming note: Keep property list sorted if new ones are added. BEGIN_PROPERTIES (line) - row_vector_property xdata u , default_data () - row_vector_property ydata u , default_data () - row_vector_property zdata u , Matrix () - string_property xdatasource , "" - string_property ydatasource , "" - string_property zdatasource , "" color_property color , color_values (0, 0, 0) + string_property displayname , "" + radio_property erasemode , "{normal}|none|xor|background" + // FIXME: interpreter is not a property of Matlab line objects. + // Octave uses this for legend() with the string displayname. + radio_property interpreter , "{tex}|none|latex" radio_property linestyle , "{-}|--|:|-.|none" double_property linewidth , 0.5 - radio_property marker , "{none}|s|o|x|+|.|*|<|>|v|^|d|p|h|@" + radio_property marker , "{none}|+|o|*|.|x|s|square|d|diamond|^|v|>|<|p|pentagram|h|hexagram" color_property markeredgecolor , "{auto}|none" color_property markerfacecolor , "auto|{none}" double_property markersize , 6 - radio_property interpreter , "{tex}|none|latex" - string_property displayname , "" - radio_property erasemode , "{normal}|none|xor|background" + row_vector_property xdata u , default_data () + string_property xdatasource , "" + row_vector_property ydata u , default_data () + string_property ydatasource , "" + row_vector_property zdata u , Matrix () + string_property zdatasource , "" + // hidden properties for limit computation row_vector_property xlim hlr , Matrix () row_vector_property ylim hlr , Matrix () @@ -4293,28 +4271,29 @@ // properties declarations. BEGIN_PROPERTIES (text) - text_label_property string u , "" - radio_property units u , "{data}|pixels|normalized|inches|centimeters|points" - array_property position smu , Matrix (1, 3, 0.0) - double_property rotation mu , 0 - radio_property horizontalalignment mu , "{left}|center|right" + color_property backgroundcolor , "{none}" color_property color u , color_values (0, 0, 0) + string_property displayname , "" + color_property edgecolor , "{none}" + bool_property editing , "off" + radio_property erasemode , "{normal}|none|xor|background" + array_property extent rG , Matrix (1, 4, 0.0) + radio_property fontangle u , "{normal}|italic|oblique" string_property fontname u , OCTAVE_DEFAULT_FONTNAME double_property fontsize u , 10 - radio_property fontangle u , "{normal}|italic|oblique" + radio_property fontunits , "inches|centimeters|normalized|{points}|pixels" radio_property fontweight u , "light|{normal}|demi|bold" + radio_property horizontalalignment mu , "{left}|center|right" radio_property interpreter u , "{tex}|none|latex" - color_property backgroundcolor , "{none}" - string_property displayname , "" - color_property edgecolor , "{none}" - radio_property erasemode , "{normal}|none|xor|background" - bool_property editing , "off" - radio_property fontunits , "inches|centimeters|normalized|{points}|pixels" radio_property linestyle , "{-}|--|:|-.|none" double_property linewidth , 0.5 double_property margin , 1 + array_property position smu , Matrix (1, 3, 0.0) + double_property rotation mu , 0 + text_label_property string u , "" + radio_property units u , "{data}|pixels|normalized|inches|centimeters|points" radio_property verticalalignment mu , "top|cap|{middle}|baseline|bottom" - array_property extent rG , Matrix (1, 4, 0.0) + // hidden properties for limit computation row_vector_property xlim hlr , Matrix () row_vector_property ylim hlr , Matrix () @@ -4426,6 +4405,11 @@ class OCTINTERP_API properties : public base_properties { public: + bool is_aliminclude (void) const + { return (aliminclude.is_on () && alphadatamapping.is ("scaled")); } + std::string get_aliminclude (void) const + { return aliminclude.current_value (); } + bool is_climinclude (void) const { return (climinclude.is_on () && cdatamapping.is ("scaled")); } std::string get_climinclude (void) const @@ -4435,19 +4419,25 @@ // See the genprops.awk script for an explanation of the // properties declarations. + // Programming note: Keep property list sorted if new ones are added. BEGIN_PROPERTIES (image) + array_property alphadata u , Matrix () + radio_property alphadatamapping al , "none|direct|{scaled}" + array_property cdata u , Matrix () + radio_property cdatamapping al , "scaled|{direct}" + radio_property erasemode , "{normal}|none|xor|background" row_vector_property xdata u , Matrix () row_vector_property ydata u , Matrix () - array_property cdata u , Matrix () - radio_property cdatamapping al , "{scaled}|direct" // hidden properties for limit computation + row_vector_property alim hlr , Matrix () + row_vector_property clim hlr , Matrix () row_vector_property xlim hlr , Matrix () row_vector_property ylim hlr , Matrix () - row_vector_property clim hlr , Matrix () + bool_property aliminclude hlg , "on" + bool_property climinclude hlg , "on" bool_property xliminclude hl , "on" bool_property yliminclude hl , "on" - bool_property climinclude hlg , "on" END_PROPERTIES protected: @@ -4467,6 +4457,22 @@ } private: + void update_alphadata (void) + { + if (alphadatamapping_is ("scaled")) + set_alim (alphadata.get_limits ()); + else + alim = alphadata.get_limits (); + } + + void update_cdata (void) + { + if (cdatamapping_is ("scaled")) + set_clim (cdata.get_limits ()); + else + clim = cdata.get_limits (); + } + void update_xdata (void) { Matrix limits = xdata.get_limits (); @@ -4487,14 +4493,6 @@ set_ylim (limits); } - void update_cdata (void) - { - if (cdatamapping_is ("scaled")) - set_clim (cdata.get_limits ()); - else - clim = cdata.get_limits (); - } - float pixel_size (octave_idx_type dim, const Matrix limits) { octave_idx_type l = dim - 1; @@ -4553,64 +4551,69 @@ public: octave_value get_color_data (void) const; - bool is_climinclude (void) const - { return (climinclude.is_on () && cdatamapping.is ("scaled")); } - std::string get_climinclude (void) const - { return climinclude.current_value (); } - bool is_aliminclude (void) const { return (aliminclude.is_on () && alphadatamapping.is ("scaled")); } std::string get_aliminclude (void) const { return aliminclude.current_value (); } + bool is_climinclude (void) const + { return (climinclude.is_on () && cdatamapping.is ("scaled")); } + std::string get_climinclude (void) const + { return climinclude.current_value (); } + // See the genprops.awk script for an explanation of the // properties declarations. + // Programming note: Keep property list sorted if new ones are added. BEGIN_PROPERTIES (patch) - array_property xdata u , Matrix () - array_property ydata u , Matrix () - array_property zdata u , Matrix () + radio_property alphadatamapping l , "none|{scaled}|direct" + double_property ambientstrength , 0.3 + radio_property backfacelighting , "unlit|lit|{reverselit}" array_property cdata u , Matrix () radio_property cdatamapping l , "{scaled}|direct" + double_property diffusestrength , 0.6 + string_property displayname , "" + double_radio_property edgealpha , double_radio_property (1.0, radio_values ("flat|interp")) + color_property edgecolor , color_property (color_values (0, 0, 0), radio_values ("none|flat|interp")) + radio_property edgelighting , "{none}|flat|gouraud|phong" + radio_property erasemode , "{normal}|background|xor|none" + double_radio_property facealpha , double_radio_property (1.0, radio_values ("flat|interp")) + color_property facecolor , color_property (color_values (0, 0, 0), radio_values ("none|flat|interp")) + radio_property facelighting , "{none}|flat|gouraud|phong" array_property faces , Matrix () array_property facevertexalphadata , Matrix () array_property facevertexcdata , Matrix () - array_property vertices , Matrix () - array_property vertexnormals , Matrix () - radio_property normalmode , "{auto}|manual" - color_property facecolor , color_property (color_values (0, 0, 0), radio_values ("flat|none|interp")) - double_radio_property facealpha , double_radio_property (1.0, radio_values ("flat|interp")) - radio_property facelighting , "flat|{none}|gouraud|phong" - color_property edgecolor , color_property (color_values (0, 0, 0), radio_values ("flat|none|interp")) - double_radio_property edgealpha , double_radio_property (1.0, radio_values ("flat|interp")) - radio_property edgelighting , "{none}|flat|gouraud|phong" - radio_property backfacelighting , "{reverselit}|unlit|lit" - double_property ambientstrength , 0.3 - double_property diffusestrength , 0.6 - double_property specularstrength , 0.6 - double_property specularexponent , 10.0 - double_property specularcolorreflectance , 1.0 - radio_property erasemode , "{normal}|background|xor|none" + // FIXME: interpreter is not a property of a Matlab patch. + // Octave uses this for legend() with the string displayname. + radio_property interpreter , "{tex}|none|latex" radio_property linestyle , "{-}|--|:|-.|none" double_property linewidth , 0.5 - radio_property marker , "{none}|s|o|x|+|.|*|<|>|v|^|d|p|h|@" - color_property markeredgecolor , "{auto}|none|flat" - color_property markerfacecolor , "auto|{none}|flat" + radio_property marker , "{none}|+|o|*|.|x|s|square|d|diamond|^|v|>|<|p|pentagram|h|hexagram" + //radio_property marker , "{none}|+|o|*|.|x|s|d|^|v|>|<|p|h" + color_property markeredgecolor , "none|{auto}|flat" + color_property markerfacecolor , "{none}|auto|flat" double_property markersize , 6 - radio_property interpreter , "{tex}|none|latex" - string_property displayname , "" - radio_property alphadatamapping l , "none|{scaled}|direct" + radio_property normalmode , "{auto}|manual" + double_property specularcolorreflectance , 1.0 + double_property specularexponent , 10.0 + double_property specularstrength , 0.6 + array_property vertexnormals , Matrix () + array_property vertices , Matrix () + array_property xdata u , Matrix () + array_property ydata u , Matrix () + array_property zdata u , Matrix () + // hidden properties for limit computation + row_vector_property alim hlr , Matrix () + row_vector_property clim hlr , Matrix () row_vector_property xlim hlr , Matrix () row_vector_property ylim hlr , Matrix () row_vector_property zlim hlr , Matrix () - row_vector_property clim hlr , Matrix () - row_vector_property alim hlr , Matrix () + bool_property aliminclude hlg , "on" + bool_property climinclude hlg , "on" bool_property xliminclude hl , "on" bool_property yliminclude hl , "on" bool_property zliminclude hl , "on" - bool_property climinclude hlg , "on" - bool_property aliminclude hlg , "on" END_PROPERTIES protected: @@ -4671,66 +4674,71 @@ public: octave_value get_color_data (void) const; - bool is_climinclude (void) const - { return (climinclude.is_on () && cdatamapping.is ("scaled")); } - std::string get_climinclude (void) const - { return climinclude.current_value (); } - bool is_aliminclude (void) const { return (aliminclude.is_on () && alphadatamapping.is ("scaled")); } std::string get_aliminclude (void) const { return aliminclude.current_value (); } + bool is_climinclude (void) const + { return (climinclude.is_on () && cdatamapping.is ("scaled")); } + std::string get_climinclude (void) const + { return climinclude.current_value (); } + // See the genprops.awk script for an explanation of the // properties declarations. + // Programming note: Keep property list sorted if new ones are added. BEGIN_PROPERTIES (surface) - array_property xdata u , Matrix () - array_property ydata u , Matrix () - array_property zdata u , Matrix () - array_property cdata u , Matrix () - radio_property cdatamapping al , "{scaled}|direct" - string_property xdatasource , "" - string_property ydatasource , "" - string_property zdatasource , "" - string_property cdatasource , "" - color_property facecolor , "{flat}|none|interp|texturemap" - double_radio_property facealpha , double_radio_property (1.0, radio_values ("flat|interp")) - color_property edgecolor , color_property (color_values (0, 0, 0), radio_values ("flat|none|interp")) - radio_property linestyle , "{-}|--|:|-.|none" - double_property linewidth , 0.5 - radio_property marker , "{none}|s|o|x|+|.|*|<|>|v|^|d|p|h|@" - color_property markeredgecolor , "{auto}|none" - color_property markerfacecolor , "auto|{none}" - double_property markersize , 6 - radio_property interpreter , "{tex}|none|latex" - string_property displayname , "" array_property alphadata u , Matrix () radio_property alphadatamapping l , "none|direct|{scaled}" double_property ambientstrength , 0.3 radio_property backfacelighting , "unlit|lit|{reverselit}" + array_property cdata u , Matrix () + radio_property cdatamapping al , "{scaled}|direct" + string_property cdatasource , "" double_property diffusestrength , 0.6 + string_property displayname , "" double_radio_property edgealpha , double_radio_property (1.0, radio_values ("flat|interp")) + color_property edgecolor , color_property (color_values (0, 0, 0), radio_values ("none|flat|interp")) radio_property edgelighting , "{none}|flat|gouraud|phong" radio_property erasemode , "{normal}|none|xor|background" + double_radio_property facealpha , double_radio_property (1.0, radio_values ("flat|interp|texturemap")) + color_property facecolor , "none|{flat}|interp|texturemap" radio_property facelighting , "{none}|flat|gouraud|phong" + // FIXME: interpreter is not a Matlab surface property + // Octave uses this for legend() with the string displayname. + radio_property interpreter , "{tex}|none|latex" + radio_property linestyle , "{-}|--|:|-.|none" + double_property linewidth , 0.5 + radio_property marker , "{none}|+|o|*|.|x|s|square|d|diamond|^|v|>|<|p|pentagram|h|hexagram" + //radio_property marker , "{none}|+|o|*|.|x|s|d|^|v|>|<|p|h" + color_property markeredgecolor , "none|{auto}|flat" + color_property markerfacecolor , "{none}|auto|flat" + double_property markersize , 6 radio_property meshstyle , "{both}|row|column" radio_property normalmode u , "{auto}|manual" double_property specularcolorreflectance , 1 double_property specularexponent , 10 double_property specularstrength , 0.9 array_property vertexnormals u , Matrix () + array_property xdata u , Matrix () + string_property xdatasource , "" + array_property ydata u , Matrix () + string_property ydatasource , "" + array_property zdata u , Matrix () + string_property zdatasource , "" + // hidden properties for limit computation + row_vector_property alim hlr , Matrix () + row_vector_property clim hlr , Matrix () row_vector_property xlim hlr , Matrix () row_vector_property ylim hlr , Matrix () row_vector_property zlim hlr , Matrix () - row_vector_property clim hlr , Matrix () - row_vector_property alim hlr , Matrix () + bool_property aliminclude hlg , "on" + bool_property climinclude hlg , "on" bool_property xliminclude hl , "on" bool_property yliminclude hl , "on" bool_property zliminclude hl , "on" - bool_property climinclude hlg , "on" - bool_property aliminclude hlg , "on" END_PROPERTIES protected: @@ -4752,7 +4760,21 @@ } private: - void update_normals (void); + void update_alphadata (void) + { + if (alphadatamapping_is ("scaled")) + set_alim (alphadata.get_limits ()); + else + alim = alphadata.get_limits (); + } + + void update_cdata (void) + { + if (cdatamapping_is ("scaled")) + set_clim (cdata.get_limits ()); + else + clim = cdata.get_limits (); + } void update_xdata (void) { @@ -4772,21 +4794,7 @@ set_zlim (zdata.get_limits ()); } - void update_cdata (void) - { - if (cdatamapping_is ("scaled")) - set_clim (cdata.get_limits ()); - else - clim = cdata.get_limits (); - } - - void update_alphadata (void) - { - if (alphadatamapping_is ("scaled")) - set_alim (alphadata.get_limits ()); - else - alim = alphadata.get_limits (); - } + void update_normals (void); void update_normalmode (void) { update_normals (); } @@ -4837,21 +4845,23 @@ // See the genprops.awk script for an explanation of the // properties declarations. + // Programming note: Keep property list sorted if new ones are added. BEGIN_PROPERTIES (hggroup) string_property displayname , "" radio_property erasemode , "{normal}|none|xor|background" + // hidden properties for limit computation + row_vector_property alim hr , Matrix () + row_vector_property clim hr , Matrix () row_vector_property xlim hr , Matrix () row_vector_property ylim hr , Matrix () row_vector_property zlim hr , Matrix () - row_vector_property clim hr , Matrix () - row_vector_property alim hr , Matrix () + bool_property aliminclude h , "on" + bool_property climinclude h , "on" bool_property xliminclude h , "on" bool_property yliminclude h , "on" bool_property zliminclude h , "on" - bool_property climinclude h , "on" - bool_property aliminclude h , "on" END_PROPERTIES private: @@ -4910,6 +4920,7 @@ // See the genprops.awk script for an explanation of the // properties declarations. + // Programming note: Keep property list sorted if new ones are added. BEGIN_PROPERTIES (uimenu) any_property __object__ , Matrix () @@ -4921,6 +4932,7 @@ string_property label , "" double_property position , 9 bool_property separator , "off" + // Octave-specific properties string_property fltk_label h , "" END_PROPERTIES @@ -4959,6 +4971,7 @@ public: // See the genprops.awk script for an explanation of the // properties declarations. + // Programming note: Keep property list sorted if new ones are added. BEGIN_PROPERTIES (uicontextmenu) any_property __object__ , Matrix () @@ -5010,6 +5023,7 @@ // See the genprops.awk script for an explanation of the // properties declarations. + // Programming note: Keep property list sorted if new ones are added. BEGIN_PROPERTIES (uicontrol) any_property __object__ , Matrix () @@ -5025,7 +5039,7 @@ radio_property fontunits S , "inches|centimeters|normalized|{points}|pixels" radio_property fontweight u , "light|{normal}|demi|bold" color_property foregroundcolor , color_values (0, 0, 0) - radio_property horizontalalignment , "{left}|center|right" + radio_property horizontalalignment , "left|{center}|right" callback_property keypressfcn , Matrix () double_property listboxtop , 1 double_property max , 1 @@ -5102,6 +5116,7 @@ // See the genprops.awk script for an explanation of the // properties declarations. + // Programming note: Keep property list sorted if new ones are added. BEGIN_PROPERTIES (uipanel) any_property __object__ , Matrix () @@ -5163,6 +5178,7 @@ public: // See the genprops.awk script for an explanation of the // properties declarations. + // Programming note: Keep property list sorted if new ones are added. BEGIN_PROPERTIES (uitoolbar) any_property __object__ , Matrix () @@ -5251,6 +5267,7 @@ public: // See the genprops.awk script for an explanation of the // properties declarations. + // Programming note: Keep property list sorted if new ones are added. BEGIN_PROPERTIES (uipushtool) any_property __object__ , Matrix () @@ -5301,6 +5318,7 @@ public: // See the genprops.awk script for an explanation of the // properties declarations. + // Programming note: Keep property list sorted if new ones are added. BEGIN_PROPERTIES (uitoggletool) any_property __object__ , Matrix () diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/gripes.cc --- a/libinterp/corefcn/gripes.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/gripes.cc Sat Oct 05 11:22:09 2013 -0400 @@ -236,3 +236,11 @@ warning_with_id ("Octave:matlab-incompatible", "potential Matlab compatibility problem: comparing complex numbers"); } + +void +gripe_disabled_feature (const std::string& func, const std::string& feature, + const std::string& pkg /*="Octave"*/) +{ + error ("%s: support for %s was disabled when %s was built", + func.c_str (), feature.c_str (), pkg.c_str ()); +} diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/gripes.h --- a/libinterp/corefcn/gripes.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/gripes.h Sat Oct 05 11:22:09 2013 -0400 @@ -127,4 +127,7 @@ extern OCTINTERP_API void gripe_warn_complex_cmp (void); +extern OCTINTERP_API void +gripe_disabled_feature (const std::string& func, const std::string& feature, + const std::string& pkg="Octave"); #endif diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/help.cc --- a/libinterp/corefcn/help.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/help.cc Sat Oct 05 11:22:09 2013 -0400 @@ -641,8 +641,8 @@ pair_type ("parfor", "-*- texinfo -*-\n\ -@deftypefn {Keyword} {} for @var{i} = @var{range}\n\ -@deftypefnx {Keyword} {} for (@var{i} = @var{range}, @var{maxproc})\n\ +@deftypefn {Keyword} {} parfor @var{i} = @var{range}\n\ +@deftypefnx {Keyword} {} parfor (@var{i} = @var{range}, @var{maxproc})\n\ Begin a for loop that may execute in parallel.\n\ \n\ @example\n\ @@ -967,7 +967,7 @@ if (file) { // Ignore header; - file.ignore (1000, 0x1f); + file.ignore (1000, 0x1d); if (file.gcount () == 1000) { @@ -988,7 +988,7 @@ while (! file.eof ()) { - file.getline (buf, bufsize, 0x1f); + file.getline (buf, bufsize, 0x1d); std::string tmp (buf); @@ -1066,8 +1066,8 @@ Return the raw help text of function @var{name}.\n\ \n\ The raw help text is returned in @var{text} and the format in @var{format}\n\ -The format is a string which is one of @t{\"texinfo\"}, @t{\"html\"}, or\n\ -@t{\"plain text\"}.\n\ +The format is a string which is one of @qcode{\"texinfo\"},\n\ +@qcode{\"html\"}, or @qcode{\"plain text\"}.\n\ @end deftypefn") { octave_value_list retval; @@ -1135,8 +1135,8 @@ Return the raw help text from the file @var{fname}.\n\ \n\ The raw help text is returned in @var{text} and the format in @var{format}\n\ -The format is a string which is one of @t{\"texinfo\"}, @t{\"html\"}, or\n\ -@t{\"plain text\"}.\n\ +The format is a string which is one of @qcode{\"texinfo\"},\n\ +@qcode{\"html\"}, or @qcode{\"plain text\"}.\n\ @end deftypefn") { octave_value_list retval; @@ -1398,9 +1398,9 @@ @w{@env{OCTAVE_DOC_CACHE_FILE}}, or the command line argument\n\ @samp{--doc-cache-file FNAME}.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{doc_cache_create, lookfor, info_program, doc, help, makeinfo_program}\n\ @end deftypefn") { @@ -1422,9 +1422,9 @@ @w{@env{OCTAVE_TEXI_MACROS_FILE}}, or the command line argument\n\ @samp{--texi-macros-file FNAME}.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{makeinfo_program}\n\ @end deftypefn") { @@ -1444,9 +1444,9 @@ @w{@env{OCTAVE_INFO_FILE}}, or the command line argument\n\ @samp{--info-file FNAME}.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{info_program, doc, help, makeinfo_program}\n\ @end deftypefn") { @@ -1468,9 +1468,9 @@ @w{@env{OCTAVE_INFO_PROGRAM}}, or the command line argument\n\ @samp{--info-program NAME}.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{info_file, doc, help, makeinfo_program}\n\ @end deftypefn") { @@ -1486,9 +1486,9 @@ program that Octave runs to format help text containing\n\ Texinfo markup commands. The default value is @code{makeinfo}.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{texi_macros_file, info_file, info_program, doc, help}\n\ @end deftypefn") { @@ -1504,9 +1504,9 @@ will add additional help information to the end of the output from\n\ the @code{help} command and usage messages for built-in commands.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @end deftypefn") { return SET_INTERNAL_VARIABLE (suppress_verbose_help_message); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/hess.cc --- a/libinterp/corefcn/hess.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/hess.cc Sat Oct 05 11:22:09 2013 -0400 @@ -60,6 +60,7 @@ The Hessenberg decomposition is usually used as the first step in an\n\ eigenvalue computation, but has other applications as well (see Golub,\n\ Nash, and Van Loan, IEEE Transactions on Automatic Control, 1979).\n\ +@seealso{eig, chol, lu, qr, qz, schur, svd}\n\ @end deftypefn") { octave_value_list retval; diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/hex2num.cc --- a/libinterp/corefcn/hex2num.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/hex2num.cc Sat Oct 05 11:22:09 2013 -0400 @@ -34,10 +34,11 @@ DEFUN (hex2num, args, , "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {@var{n} =} hex2num (@var{s})\n\ +@deftypefn {Built-in Function} {@var{n} =} hex2num (@var{s})\n\ +@deftypefnx {Built-in Function} {@var{n} =} hex2num (@var{s}, @var{class})\n\ Typecast the 16 character hexadecimal character string to an IEEE 754\n\ double precision number. If fewer than 16 characters are given the\n\ -strings are right padded with '0' characters.\n\ +strings are right padded with @qcode{'0'} characters.\n\ \n\ Given a string matrix, @code{hex2num} treats each row as a separate\n\ number.\n\ @@ -48,70 +49,142 @@ @result{} [2.7183; 10.000]\n\ @end group\n\ @end example\n\ +\n\ +The optional argument @var{class} can be passed as the string\n\ +@qcode{\"single\"} to specify that the given string should be interpreted as\n\ +a single precision number. In this case, @var{s} should be an 8 character\n\ +hexadecimal string. For example: \n\ +\n\ +@example\n\ +@group\n\ +hex2num ([\"402df854\"; \"41200000\"], \"single\")\n\ + @result{} [2.7183; 10.000]\n\ +@end group\n\ +@end example\n\ @seealso{num2hex, hex2dec, dec2hex}\n\ @end deftypefn") { int nargin = args.length (); octave_value retval; - if (nargin != 1) + if (nargin < 1 || nargin > 2) print_usage (); + else if (nargin == 2 && ! args(1).is_string ()) + error ("hex2num: CLASS must be a string"); else { const charMatrix cmat = args(0).char_matrix_value (); + std::string prec = (nargin == 2) ? args(1).string_value () : "double"; + bool is_single = (prec == "single"); + octave_idx_type nchars = (is_single) ? 8 : 16; - if (cmat.columns () > 16) - error ("hex2num: S must be no more than 16 characters"); + if (cmat.columns () > nchars) + error ("hex2num: S must be no more than %d characters", nchars); + else if (prec != "double" && prec != "single") + error ("hex2num: CLASS must be either \"double\" or \"single\""); else if (! error_state) { octave_idx_type nr = cmat.rows (); octave_idx_type nc = cmat.columns (); - ColumnVector m (nr); - for (octave_idx_type i = 0; i < nr; i++) + if (is_single) { - union - { - uint64_t ival; - double dval; - } num; + FloatColumnVector m (nr); - num.ival = 0; + for (octave_idx_type i = 0; i < nr; i++) + { + union + { + uint32_t ival; + float dval; + } num; + + num.ival = 0; + + for (octave_idx_type j = 0; j < nc; j++) + { + unsigned char ch = cmat.elem (i, j); - for (octave_idx_type j = 0; j < nc; j++) - { - unsigned char ch = cmat.elem (i, j); + if (isxdigit (ch)) + { + num.ival <<= 4; + if (ch >= 'a') + num.ival += static_cast (ch - 'a' + 10); + else if (ch >= 'A') + num.ival += static_cast (ch - 'A' + 10); + else + num.ival += static_cast (ch - '0'); + } + else + { + error ("hex2num: illegal character found in string S"); + break; + } + } - if (isxdigit (ch)) - { - num.ival <<= 4; - if (ch >= 'a') - num.ival += static_cast (ch - 'a' + 10); - else if (ch >= 'A') - num.ival += static_cast (ch - 'A' + 10); - else - num.ival += static_cast (ch - '0'); - } + if (error_state) + break; else { - error ("hex2num: illegal character found in string S"); - break; + if (nc < nchars) + num.ival <<= (nchars - nc) * 4; + + m(i) = num.dval; } } - if (error_state) - break; - else + if (! error_state) + retval = m; + } + else + { + ColumnVector m (nr); + + for (octave_idx_type i = 0; i < nr; i++) { - if (nc < 16) - num.ival <<= (16 - nc) * 4; + union + { + uint64_t ival; + double dval; + } num; + + num.ival = 0; + + for (octave_idx_type j = 0; j < nc; j++) + { + unsigned char ch = cmat.elem (i, j); - m(i) = num.dval; + if (isxdigit (ch)) + { + num.ival <<= 4; + if (ch >= 'a') + num.ival += static_cast (ch - 'a' + 10); + else if (ch >= 'A') + num.ival += static_cast (ch - 'A' + 10); + else + num.ival += static_cast (ch - '0'); + } + else + { + error ("hex2num: illegal character found in string S"); + break; + } + } + + if (error_state) + break; + else + { + if (nc < nchars) + num.ival <<= (nchars - nc) * 4; + + m(i) = num.dval; + } } + + if (! error_state) + retval = m; } - - if (! error_state) - retval = m; } } @@ -120,23 +193,36 @@ /* %!assert (hex2num (["c00";"bff";"000";"3ff";"400"]), [-2:2]') +%!assert (hex2num (["c00";"bf8";"000";"3f8";"400"], "single"), single([-2:2])') */ DEFUN (num2hex, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{s} =} num2hex (@var{n})\n\ -Typecast a double precision number or vector to a 16 character hexadecimal\n\ -string of the IEEE 754 representation of the number. For example:\n\ +Typecast a double or single precision number or vector to a 8 or 16\n\ +character hexadecimal string of the IEEE 754 representation of the number.\n\ +For example:\n\ \n\ @example\n\ @group\n\ -num2hex ([-1, 1, e, Inf, NaN, NA])\n\ +num2hex ([-1, 1, e, Inf])\n\ @result{} \"bff0000000000000\n\ 3ff0000000000000\n\ 4005bf0a8b145769\n\ - 7ff0000000000000\n\ - fff8000000000000\n\ - 7ff00000000007a2\"\n\ + 7ff0000000000000\"\n\ +@end group\n\ +@end example\n\ +\n\ +If the argument @var{n} is a single precision number or vector, the returned\n\ +string has a length of 8. For example:\n\ +\n\ +@example\n\ +@group\n\ +num2hex (single ([-1, 1, e, Inf]))\n\ +@result{} \"bf800000\n\ + 3f800000\n\ + 402df854\n\ + 7f800000\"\n\ @end group\n\ @end example\n\ @seealso{hex2num, hex2dec, dec2hex}\n\ @@ -147,14 +233,52 @@ if (nargin != 1) print_usage (); + else if (args(0).is_single_type ()) + { + const FloatColumnVector v (args(0).float_vector_value ()); + + if (! error_state) + { + octave_idx_type nchars = 8; + octave_idx_type nr = v.length (); + charMatrix m (nr, nchars); + const float *pv = v.fortran_vec (); + + for (octave_idx_type i = 0; i < nr; i++) + { + union + { + uint32_t ival; + float dval; + } num; + + num.dval = *pv++; + + for (octave_idx_type j = 0; j < nchars; j++) + { + unsigned char ch = + static_cast (num.ival >> ((nchars - 1 - j) * 4) & 0xF); + if (ch >= 10) + ch += 'a' - 10; + else + ch += '0'; + + m.elem (i, j) = ch; + } + } + + retval = m; + } + } else { const ColumnVector v (args(0).vector_value ()); if (! error_state) { + octave_idx_type nchars = 16; octave_idx_type nr = v.length (); - charMatrix m (nr, 16); + charMatrix m (nr, nchars); const double *pv = v.fortran_vec (); for (octave_idx_type i = 0; i < nr; i++) @@ -167,10 +291,10 @@ num.dval = *pv++; - for (octave_idx_type j = 0; j < 16; j++) + for (octave_idx_type j = 0; j < nchars; j++) { unsigned char ch = - static_cast (num.ival >> ((15 - j) * 4) & 0xF); + static_cast (num.ival >> ((nchars - 1 - j) * 4) & 0xF); if (ch >= 10) ch += 'a' - 10; else @@ -189,4 +313,5 @@ /* %!assert (num2hex (-2:2), ["c000000000000000";"bff0000000000000";"0000000000000000";"3ff0000000000000";"4000000000000000"]) +%!assert (num2hex (single (-2:2)), ["c0000000";"bf800000";"00000000";"3f800000";"40000000"]) */ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/input.cc --- a/libinterp/corefcn/input.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/input.cc Sat Oct 05 11:22:09 2013 -0400 @@ -147,7 +147,7 @@ void octave_base_reader::do_input_echo (const std::string& input_string) const { - int do_echo = LEXER->reading_script_file ? + int do_echo = (LEXER && LEXER->reading_script_file) ? (Vecho_executing_commands & ECHO_SCRIPTS) : (Vecho_executing_commands & ECHO_CMD_LINE) && ! forced_interactive; @@ -272,9 +272,7 @@ { if (! history_skip_auto_repeated_debugging_command) { - command_history::add (retval); - - if (! command_history::ignoring_entries ()) + if (command_history::add (retval)) octave_link::append_history (retval); } @@ -556,10 +554,10 @@ VPS1 = prompt; if (! (interactive || forced_interactive) - || LEXER->reading_fcn_file - || LEXER->reading_classdef_file - || LEXER->reading_script_file - || LEXER->input_from_eval_string ()) + || (LEXER && (LEXER->reading_fcn_file + || LEXER->reading_classdef_file + || LEXER->reading_script_file + || LEXER->input_from_eval_string ()))) { frame.protect_var (forced_interactive); forced_interactive = true; @@ -741,7 +739,7 @@ of values produced by the evaluation of the expression.\n\ \n\ If you are only interested in getting a literal string value, you can\n\ -call @code{input} with the character string @code{\"s\"} as the second\n\ +call @code{input} with the character string @qcode{\"s\"} as the second\n\ argument. This tells Octave to return the string entered by the user\n\ directly, without evaluating it first.\n\ \n\ @@ -1228,7 +1226,7 @@ Query or set the primary prompt string. When executing interactively,\n\ Octave displays the primary prompt when it is ready to read a command.\n\ \n\ -The default value of the primary prompt string is @code{\"\\s:\\#> \"}.\n\ +The default value of the primary prompt string is @qcode{\"\\s:\\#> \"}.\n\ To change it, use a command like\n\ \n\ @example\n\ @@ -1251,9 +1249,9 @@ @noindent\n\ will give the default Octave prompt a red coloring.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{PS2, PS4}\n\ @end deftypefn") { @@ -1270,11 +1268,11 @@ command. For example, if you are typing a @code{for} loop that spans several\n\ lines, Octave will print the secondary prompt at the beginning of\n\ each line after the first. The default value of the secondary prompt\n\ -string is @code{\"> \"}.\n\ +string is @qcode{\"> \"}.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{PS1, PS4}\n\ @end deftypefn") { @@ -1288,12 +1286,12 @@ @deftypefnx {Built-in Function} {} PS4 (@var{new_val}, \"local\")\n\ Query or set the character string used to prefix output produced\n\ when echoing commands is enabled.\n\ -The default value is @code{\"+ \"}.\n\ +The default value is @qcode{\"+ \"}.\n\ @xref{Diary and Echo Commands}, for a description of echoing commands.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{echo, echo_executing_commands, PS1, PS2}\n\ @end deftypefn") { @@ -1307,11 +1305,11 @@ @deftypefnx {Built-in Function} {} completion_append_char (@var{new_val}, \"local\")\n\ Query or set the internal character variable that is appended to\n\ successful command-line completion attempts. The default\n\ -value is @code{\" \"} (a single space).\n\ +value is @qcode{\" \"} (a single space).\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @end deftypefn") { return SET_INTERNAL_VARIABLE (completion_append_char); @@ -1342,9 +1340,9 @@ The value of @code{echo_executing_commands} may be set by the @kbd{echo}\n\ command or the command line option @option{--echo-commands}.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @end deftypefn") { return SET_INTERNAL_VARIABLE (echo_executing_commands); @@ -1417,9 +1415,9 @@ @noindent\n\ will set a breakpoint at the first line of the subfunction @code{mysubfunc}.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @end deftypefn") { char tmp = Vfilemarker; diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/jit-ir.cc --- a/libinterp/corefcn/jit-ir.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/jit-ir.cc Sat Oct 05 11:22:09 2013 -0400 @@ -34,8 +34,13 @@ #include "jit-ir.h" +#ifdef HAVE_LLVM_IR_FUNCTION_H +#include +#include +#else #include #include +#endif #include "error.h" diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/jit-typeinfo.cc --- a/libinterp/corefcn/jit-typeinfo.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/jit-typeinfo.cc Sat Oct 05 11:22:09 2013 -0400 @@ -35,13 +35,30 @@ #include "jit-typeinfo.h" #include +#include + +#ifdef HAVE_LLVM_IR_FUNCTION_H +#include +#include +#include +#include +#include +#else #include -#include #include #include #include #include +#endif + +#ifdef HAVE_LLVM_SUPPORT_IRBUILDER_H #include +#elif defined(HAVE_LLVM_IR_IRBUILDER_H) +#include +#else +#include +#endif + #include #include "jit-ir.h" @@ -579,10 +596,23 @@ aname, module); if (sret ()) - llvm_function->addAttribute (1, llvm::Attribute::StructRet); + { +#ifdef FUNCTION_ADDATTRIBUTE_ARG_IS_ATTRIBUTES + llvm::AttrBuilder attr_builder; + attr_builder.addAttribute (llvm::Attributes::StructRet); + llvm::Attributes attrs = llvm::Attributes::get(context, attr_builder); + llvm_function->addAttribute (1, attrs); +#else + llvm_function->addAttribute (1, llvm::Attribute::StructRet); +#endif + } if (call_conv == jit_convention::internal) +#ifdef FUNCTION_ADDFNATTR_ARG_IS_ATTRIBUTES + llvm_function->addFnAttr (llvm::Attributes::AlwaysInline); +#else llvm_function->addFnAttr (llvm::Attribute::AlwaysInline); +#endif } jit_function::jit_function (const jit_function& fn, jit_type *aresult, @@ -685,7 +715,14 @@ if (sret ()) { +#ifdef CALLINST_ADDATTRIBUTE_ARG_IS_ATTRIBUTES + llvm::AttrBuilder attr_builder; + attr_builder.addAttribute(llvm::Attributes::StructRet); + llvm::Attributes attrs = llvm::Attributes::get(context, attr_builder); + callinst->addAttribute (1, attrs); +#else callinst->addAttribute (1, llvm::Attribute::StructRet); +#endif ret = builder.CreateLoad (sret_mem); } diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/jit-util.cc --- a/libinterp/corefcn/jit-util.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/jit-util.cc Sat Oct 05 11:22:09 2013 -0400 @@ -32,7 +32,12 @@ #ifdef HAVE_LLVM +#ifdef HAVE_LLVM_IR_FUNCTION_H +#include +#else #include +#endif + #include std::ostream& diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/jit-util.h --- a/libinterp/corefcn/jit-util.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/jit-util.h Sat Oct 05 11:22:09 2013 -0400 @@ -31,6 +31,10 @@ #include +#if defined(HAVE_LLVM_IR_DATALAYOUT_H) || defined(HAVE_LLVM_DATALAYOUT_H) +#define HAVE_LLVM_DATALAYOUT +#endif + // we don't want to include llvm headers here, as they require // __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS be defined in the entire // compilation unit diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/load-path.cc --- a/libinterp/corefcn/load-path.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/load-path.cc Sat Oct 05 11:22:09 2013 -0400 @@ -2319,8 +2319,8 @@ @deftypefn {Built-in Function} {} addpath (@var{dir1}, @dots{})\n\ @deftypefnx {Built-in Function} {} addpath (@var{dir1}, @dots{}, @var{option})\n\ Add named directories to the function search path. If\n\ -@var{option} is \"-begin\" or 0 (the default), prepend the\n\ -directory name to the current path. If @var{option} is \"-end\"\n\ +@var{option} is @qcode{\"-begin\"} or 0 (the default), prepend the\n\ +directory name to the current path. If @var{option} is @qcode{\"-end\"}\n\ or 1, append the directory name to the current path.\n\ Directories added to the path must exist.\n\ \n\ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/load-save.cc --- a/libinterp/corefcn/load-save.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/load-save.cc Sat Oct 05 11:22:09 2013 -0400 @@ -269,6 +269,20 @@ if (! tmp.empty ()) retval = LS_ASCII; + else + { + file.clear (); + file.seekg (0, std::ios::beg); + + // FIXME -- looks_like_mat_ascii_file does not check to see + // whether the file contains numbers. It just skips comments and + // checks for the same number of words on each line. We may need + // a better check here. The best way to do that might be just + // to try to read the file and see if it works. + + if (looks_like_mat_ascii_file (file, filename)) + retval = LS_MAT_ASCII; + } } } } @@ -288,39 +302,36 @@ return LS_HDF5; #endif /* HAVE_HDF5 */ - std::ifstream file (fname.c_str ()); +#ifdef HAVE_ZLIB + use_zlib = check_gzip_magic (fname); +#else use_zlib = false; - - if (file) - { - retval = get_file_format (file, orig_fname); - file.close (); - -#ifdef HAVE_ZLIB - if (retval == LS_UNKNOWN && check_gzip_magic (fname)) - { - gzifstream gzfile (fname.c_str ()); - use_zlib = true; - - if (gzfile) - { - retval = get_file_format (gzfile, orig_fname); - gzfile.close (); - } - } #endif - // FIXME -- looks_like_mat_ascii_file does not check to see - // whether the file contains numbers. It just skips comments and - // checks for the same number of words on each line. We may need - // a better check here. The best way to do that might be just - // to try to read the file and see if it works. - - if (retval == LS_UNKNOWN && looks_like_mat_ascii_file (fname)) - retval = LS_MAT_ASCII; + if (! use_zlib) + { + std::ifstream file (fname.c_str ()); + if (file) + { + retval = get_file_format (file, orig_fname); + file.close (); + } + else if (! quiet) + gripe_file_open ("load", orig_fname); } - else if (! quiet) - gripe_file_open ("load", orig_fname); +#ifdef HAVE_ZLIB + else + { + gzifstream gzfile (fname.c_str ()); + if (gzfile) + { + retval = get_file_format (gzfile, orig_fname); + gzfile.close (); + } + else if (! quiet) + gripe_file_open ("load", orig_fname); + } +#endif return retval; } @@ -617,7 +628,7 @@ Octave can now support multi-dimensional HDF data and automatically\n\ modifies variable names if they are invalid Octave identifiers.\n\ \n\ -@item -mat\n\ +@item -mat\n\ @itemx -mat-binary\n\ @itemx -6\n\ @itemx -v6\n\ @@ -1315,6 +1326,8 @@ { for (int i = argv_idx; i < argc; i++) { + if (argv[i] == "") + continue; // Skip empty vars for Matlab compatibility if (! save_vars (os, argv[i], fmt, save_as_floats)) warning ("save: no such variable '%s'", argv[i].c_str ()); } @@ -1509,20 +1522,20 @@ Only use this format if you know that all the\n\ values to be saved can be represented in single precision.\n\ \n\ -@item -V7\n\ +@item -V7\n\ @itemx -v7\n\ @itemx -7\n\ @itemx -mat7-binary\n\ Save the data in @sc{matlab}'s v7 binary data format.\n\ \n\ -@item -V6\n\ +@item -V6\n\ @itemx -v6\n\ @itemx -6\n\ @itemx -mat\n\ @itemx -mat-binary\n\ Save the data in @sc{matlab}'s v6 binary data format.\n\ \n\ -@item -V4\n\ +@item -V4\n\ @itemx -v4\n\ @itemx -4\n\ @itemx -mat4-binary\n\ @@ -1531,7 +1544,7 @@ @item -text\n\ Save the data in Octave's text data format. (default).\n\ \n\ -@item -zip\n\ +@item -zip\n\ @itemx -z\n\ Use the gzip algorithm to compress the file. This works equally on files\n\ that are compressed with gzip outside of octave, and gzip can equally be\n\ @@ -1761,12 +1774,12 @@ @deftypefnx {Built-in Function} {@var{old_val} =} crash_dumps_octave_core (@var{new_val})\n\ @deftypefnx {Built-in Function} {} crash_dumps_octave_core (@var{new_val}, \"local\")\n\ Query or set the internal variable that controls whether Octave tries\n\ -to save all current variables to the file \"octave-workspace\" if it\n\ +to save all current variables to the file @file{octave-workspace} if it\n\ crashes or receives a hangup, terminate or similar signal.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{octave_core_file_limit, octave_core_file_name, octave_core_file_options}\n\ @end deftypefn") { @@ -1780,12 +1793,12 @@ @deftypefnx {Built-in Function} {} save_default_options (@var{new_val}, \"local\")\n\ Query or set the internal variable that specifies the default options\n\ for the @code{save} command, and defines the default format.\n\ -Typical values include @code{\"-ascii\"}, @code{\"-text -zip\"}.\n\ +Typical values include @qcode{\"-ascii\"}, @qcode{\"-text -zip\"}.\n\ The default value is @option{-text}.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{save}\n\ @end deftypefn") { @@ -1806,9 +1819,9 @@ size of the file. If a text file format is used, then the file could\n\ be much larger than the limit. The default value is -1 (unlimited)\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{crash_dumps_octave_core, octave_core_file_name, octave_core_file_options}\n\ @end deftypefn") { @@ -1822,11 +1835,11 @@ @deftypefnx {Built-in Function} {} octave_core_file_name (@var{new_val}, \"local\")\n\ Query or set the internal variable that specifies the name of the file\n\ used for saving data from the top-level workspace if Octave aborts.\n\ -The default value is @code{\"octave-workspace\"}\n\ +The default value is @qcode{\"octave-workspace\"}\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{crash_dumps_octave_core, octave_core_file_name, octave_core_file_options}\n\ @end deftypefn") { @@ -1844,9 +1857,9 @@ options for the @code{save} function. The default value is Octave's binary\n\ format.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{crash_dumps_octave_core, octave_core_file_name, octave_core_file_limit}\n\ @end deftypefn") { @@ -1872,9 +1885,9 @@ \"# Created by Octave VERSION, %a %b %d %H:%M:%S %Y %Z \"\n\ @end smallexample\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{strftime, save}\n\ @end deftypefn") { diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/ls-mat-ascii.cc --- a/libinterp/corefcn/ls-mat-ascii.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/ls-mat-ascii.cc Sat Oct 05 11:22:09 2013 -0400 @@ -107,7 +107,7 @@ } static void -get_lines_and_columns (std::istream& is, +get_lines_and_columns (std::istream& is, octave_idx_type& nr, octave_idx_type& nc, const std::string& filename = std::string (), bool quiet = false, bool check_numeric = false) @@ -410,21 +410,14 @@ } bool -looks_like_mat_ascii_file (const std::string& filename) +looks_like_mat_ascii_file (std::istream& is, const std::string& filename) { bool retval = false; - - std::ifstream is (filename.c_str ()); + octave_idx_type nr = 0; + octave_idx_type nc = 0; - if (is) - { - octave_idx_type nr = 0; - octave_idx_type nc = 0; - - get_lines_and_columns (is, nr, nc, filename, true, true); - - retval = (nr != 0 && nc != 0); - } + get_lines_and_columns (is, nr, nc, filename, true, true); + retval = (nr != 0 && nc != 0); return retval; } diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/ls-mat-ascii.h --- a/libinterp/corefcn/ls-mat-ascii.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/ls-mat-ascii.h Sat Oct 05 11:22:09 2013 -0400 @@ -31,6 +31,6 @@ save_mat_ascii_data (std::ostream& os, const octave_value& val_arg, int precision, bool tabs = false); -extern bool looks_like_mat_ascii_file (const std::string& filename); +extern bool looks_like_mat_ascii_file (std::istream& is, const std::string& filename); #endif diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/ls-mat4.cc --- a/libinterp/corefcn/ls-mat4.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/ls-mat4.cc Sat Oct 05 11:22:09 2013 -0400 @@ -194,17 +194,8 @@ break; case 2: - flt_fmt = oct_mach_info::flt_fmt_vax_d; - break; - case 3: - flt_fmt = oct_mach_info::flt_fmt_vax_g; - break; - case 4: - flt_fmt = oct_mach_info::flt_fmt_cray; - break; - default: flt_fmt = oct_mach_info::flt_fmt_unknown; break; @@ -228,18 +219,6 @@ retval = 1; break; - case oct_mach_info::flt_fmt_vax_d: - retval = 2; - break; - - case oct_mach_info::flt_fmt_vax_g: - retval = 3; - break; - - case oct_mach_info::flt_fmt_cray: - retval = 4; - break; - default: break; } diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/ls-mat5.cc --- a/libinterp/corefcn/ls-mat5.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/ls-mat5.cc Sat Oct 05 11:22:09 2013 -0400 @@ -1960,7 +1960,7 @@ { double tmp = val[i]; - if (! (xisnan (tmp) || xisinf (tmp)) + if (xfinite (tmp) && fabs (tmp) > std::numeric_limits::max ()) { too_large_for_float = true; diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/ls-oct-ascii.cc --- a/libinterp/corefcn/ls-oct-ascii.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/ls-oct-ascii.cc Sat Oct 05 11:22:09 2013 -0400 @@ -367,7 +367,7 @@ if (tc.is_real_matrix ()) { - os << "# 3D data...\n" + os << "# 3-D data...\n" << "# type: matrix\n" << "# total rows: " << nr << "\n" << "# total columns: " << nc << "\n"; @@ -408,7 +408,7 @@ } else { - ::error ("for now, I can only save real matrices in 3D format"); + ::error ("for now, I can only save real matrices in 3-D format"); fail = true; } @@ -423,9 +423,9 @@ Query or set the internal variable that specifies the number of\n\ digits to keep when saving data in text format.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls.\n\ +The original variable value is restored when exiting the function.\n\ @end deftypefn") { return SET_INTERNAL_VARIABLE_WITH_LIMITS (save_precision, -1, diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/lu.cc --- a/libinterp/corefcn/lu.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/lu.cc Sat Oct 05 11:22:09 2013 -0400 @@ -125,10 +125,10 @@ pivoting strategy and the second for the symmetric strategy. By default,\n\ the values defined by @code{spparms} are used ([0.1, 0.001]).\n\ \n\ -Given the string argument \"vector\", @code{lu} returns the values of @var{P}\n\ -and @var{Q} as vector values, such that for full matrix, @code{@var{A}\n\ -(@var{P},:) = @var{L} * @var{U}}, and @code{@var{R}(@var{P},:) * @var{A}\n\ -(:, @var{Q}) = @var{L} * @var{U}}.\n\ +Given the string argument @qcode{\"vector\"}, @code{lu} returns the values\n\ +of @var{P} and @var{Q} as vector values, such that for full matrix,\n\ +@code{@var{A} (@var{P},:) = @var{L} * @var{U}}, and @code{@var{R}(@var{P},:)\n\ +* @var{A} (:, @var{Q}) = @var{L} * @var{U}}.\n\ \n\ With two output arguments, returns the permuted forms of the upper and\n\ lower triangular matrices, such that @code{@var{A} = @var{L} * @var{U}}.\n\ @@ -137,6 +137,7 @@ is embedded into @var{U} to give a return value similar to the full case.\n\ For both full and sparse matrices, @code{lu} loses the permutation\n\ information.\n\ +@seealso{luupdate, chol, hess, qr, qz, schur, svd}\n\ @end deftypefn") { octave_value_list retval; @@ -614,7 +615,7 @@ @end example\n\ \n\ @noindent\n\ -then a factorization of @xcode{@var{A}+@var{x}*@var{y}.'} can be obtained\n\ +then a factorization of @tcode{@var{A}+@var{x}*@var{y}.'} can be obtained\n\ either as\n\ \n\ @example\n\ @@ -635,7 +636,7 @@ The matrix case is done as a sequence of rank-1 updates;\n\ thus, for large enough k, it will be both faster and more accurate to\n\ recompute the factorization from scratch.\n\ -@seealso{lu, qrupdate, cholupdate}\n\ +@seealso{lu, cholupdate, qrupdate}\n\ @end deftypefn") { octave_idx_type nargin = args.length (); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/luinc.cc --- a/libinterp/corefcn/luinc.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/luinc.cc Sat Oct 05 11:22:09 2013 -0400 @@ -47,7 +47,7 @@ Two types of incomplete factorization are possible, and the type\n\ is determined by the second argument to @code{luinc}.\n\ \n\ -Called with a second argument of '0', the zero-level incomplete\n\ +Called with a second argument of @qcode{'0'}, the zero-level incomplete\n\ LU@tie{}factorization is produced. This creates a factorization of @var{A}\n\ where the position of the non-zero arguments correspond to the same\n\ positions as in the matrix @var{A}.\n\ @@ -91,8 +91,8 @@ All other fields in @var{opts} are ignored. The outputs from @code{luinc}\n\ are the same as for @code{lu}.\n\ \n\ -Given the string argument \"vector\", @code{luinc} returns the values of\n\ -@var{p} @var{q} as vector values.\n\ +Given the string argument @qcode{\"vector\"}, @code{luinc} returns the\n\ +values of @var{p} @var{q} as vector values.\n\ @seealso{sparse, lu}\n\ @end deftypefn") { diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/matrix_type.cc --- a/libinterp/corefcn/matrix_type.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/matrix_type.cc Sat Oct 05 11:22:09 2013 -0400 @@ -50,48 +50,49 @@ matrix and caches it for future use. Called with more than one argument,\n\ @code{matrix_type} allows the type of the matrix to be defined.\n\ \n\ -If the option \"nocompute\" is given, the function will not attempt to guess\n\ -the type if it is still unknown. This is useful for debugging purposes.\n\ +If the option @qcode{\"nocompute\"} is given, the function will not attempt\n\ +to guess the type if it is still unknown. This is useful for debugging\n\ +purposes.\n\ \n\ The possible matrix types depend on whether the matrix is full or sparse, and\n\ can be one of the following\n\ \n\ @table @asis\n\ -@item \"unknown\"\n\ +@item @qcode{\"unknown\"}\n\ Remove any previously cached matrix type, and mark type as unknown.\n\ \n\ -@item \"full\"\n\ +@item @qcode{\"full\"}\n\ Mark the matrix as full.\n\ \n\ -@item \"positive definite\"\n\ +@item @qcode{\"positive definite\"}\n\ Probable full positive definite matrix.\n\ \n\ -@item \"diagonal\"\n\ +@item @qcode{\"diagonal\"}\n\ Diagonal matrix. (Sparse matrices only)\n\ \n\ -@item \"permuted diagonal\"\n\ +@item @qcode{\"permuted diagonal\"}\n\ Permuted Diagonal matrix. The permutation does not need to be specifically\n\ indicated, as the structure of the matrix explicitly gives this. (Sparse\n\ matrices only)\n\ \n\ -@item \"upper\"\n\ +@item @qcode{\"upper\"}\n\ Upper triangular. If the optional third argument @var{perm} is given, the\n\ matrix is assumed to be a permuted upper triangular with the permutations\n\ defined by the vector @var{perm}.\n\ \n\ -@item \"lower\"\n\ +@item @qcode{\"lower\"}\n\ Lower triangular. If the optional third argument @var{perm} is given, the\n\ matrix is assumed to be a permuted lower triangular with the permutations\n\ defined by the vector @var{perm}.\n\ \n\ -@item \"banded\"\n\ -@itemx \"banded positive definite\"\n\ +@item @qcode{\"banded\"}\n\ +@itemx @qcode{\"banded positive definite\"}\n\ Banded matrix with the band size of @var{nl} below the diagonal and @var{nu}\n\ above it. If @var{nl} and @var{nu} are 1, then the matrix is tridiagonal and\n\ treated with specialized code. In addition the matrix can be marked as\n\ probably a positive definite. (Sparse matrices only)\n\ \n\ -@item \"singular\"\n\ +@item @qcode{\"singular\"}\n\ The matrix is assumed to be singular and will be treated with a minimum norm\n\ solution.\n\ \n\ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/max.cc --- a/libinterp/corefcn/max.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/max.cc Sat Oct 05 11:22:09 2013 -0400 @@ -663,8 +663,10 @@ @deftypefn {Built-in Function} {} cummin (@var{x})\n\ @deftypefnx {Built-in Function} {} cummin (@var{x}, @var{dim})\n\ @deftypefnx {Built-in Function} {[@var{w}, @var{iw}] =} cummin (@var{x})\n\ -Return the cumulative minimum values along dimension @var{dim}. If @var{dim}\n\ -is unspecified it defaults to column-wise operation. For example:\n\ +Return the cumulative minimum values along dimension @var{dim}.\n\ +\n\ +If @var{dim} is unspecified it defaults to column-wise operation. For\n\ +example:\n\ \n\ @example\n\ @group\n\ @@ -673,40 +675,52 @@ @end group\n\ @end example\n\ \n\ -\n\ -The call\n\ -\n\ -@example\n\ - [w, iw] = cummin (x)\n\ -@end example\n\ -\n\ -@noindent\n\ -with @code{x} a vector, is equivalent to the following code:\n\ +If called with two output arguments the index of the minimum value is also\n\ +returned.\n\ \n\ @example\n\ @group\n\ -w = iw = zeros (size (x));\n\ -for i = 1:length (x)\n\ - [w(i), iw(i)] = max (x(1:i));\n\ -endfor\n\ +[w, iw] = cummin ([5 4 6 2 3 1])\n\ +@result{}\n\ +w = 5 4 4 2 2 1\n\ +iw = 1 2 2 4 4 6\n\ @end group\n\ @end example\n\ \n\ -@noindent\n\ -but computed in a much faster manner.\n\ @seealso{cummax, min, max}\n\ @end deftypefn") { return do_cumminmax_body (args, nargout, true); } +/* +%!assert (cummin ([1, 4, 2, 3]), [1 1 1 1]) +%!assert (cummin ([1; -10; 5; -2]), [1; -10; -10; -10]) +%!assert (cummin ([4, i; -2, 2]), [4, i; -2, i]) + +%!test +%! x = reshape (1:8, [2,2,2]); +%! assert (cummin (x, 1), reshape ([1 1 3 3 5 5 7 7], [2,2,2])); +%! assert (cummin (x, 2), reshape ([1 2 1 2 5 6 5 6], [2,2,2])); +%! [w, iw] = cummin (x, 3); +%! assert (ndims (w), 3); +%! assert (w, repmat ([1 3; 2 4], [1 1 2])); +%! assert (ndims (iw), 3); +%! assert (iw, ones (2,2,2)); + +%!error cummin () +%!error cummin (1, 2, 3) +*/ + DEFUN (cummax, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} cummax (@var{x})\n\ @deftypefnx {Built-in Function} {} cummax (@var{x}, @var{dim})\n\ -@deftypefnx {Built-in Function} {[@var{w}, @var{iw}] =} cummax (@var{x})\n\ -Return the cumulative maximum values along dimension @var{dim}. If @var{dim}\n\ -is unspecified it defaults to column-wise operation. For example:\n\ +@deftypefnx {Built-in Function} {[@var{w}, @var{iw}] =} cummax (@dots{})\n\ +Return the cumulative maximum values along dimension @var{dim}.\n\ +\n\ +If @var{dim} is unspecified it defaults to column-wise operation. For\n\ +example:\n\ \n\ @example\n\ @group\n\ @@ -715,28 +729,40 @@ @end group\n\ @end example\n\ \n\ -The call\n\ -\n\ -@example\n\ -[w, iw] = cummax (x, dim)\n\ -@end example\n\ -\n\ -@noindent\n\ -with @code{x} a vector, is equivalent to the following code:\n\ +If called with two output arguments the index of the maximum value is also\n\ +returned.\n\ \n\ @example\n\ @group\n\ -w = iw = zeros (size (x));\n\ -for i = 1:length (x)\n\ - [w(i), iw(i)] = max (x(1:i));\n\ -endfor\n\ +[w, iw] = cummax ([1 3 2 6 4 5])\n\ +@result{}\n\ +w = 1 3 3 6 6 6\n\ +iw = 1 2 2 4 4 4\n\ @end group\n\ @end example\n\ \n\ -@noindent\n\ -but computed in a much faster manner.\n\ @seealso{cummin, max, min}\n\ @end deftypefn") { return do_cumminmax_body (args, nargout, false); } + +/* +%!assert (cummax ([1, 4, 2, 3]), [1 4 4 4]) +%!assert (cummax ([1; -10; 5; -2]), [1; 1; 5; 5]) +%!assert (cummax ([4, i 4.9, -2, 2, 3+4i]), [4, 4, 4.9, 4.9, 4.9, 3+4i]) + +%!test +%! x = reshape (8:-1:1, [2,2,2]); +%! assert (cummax (x, 1), reshape ([8 8 6 6 4 4 2 2], [2,2,2])); +%! assert (cummax (x, 2), reshape ([8 7 8 7 4 3 4 3], [2,2,2])); +%! [w, iw] = cummax (x, 3); +%! assert (ndims (w), 3); +%! assert (w, repmat ([8 6; 7 5], [1 1 2])); +%! assert (ndims (iw), 3); +%! assert (iw, ones (2,2,2)); + +%!error cummax () +%!error cummax (1, 2, 3) +*/ + diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/mex.cc --- a/libinterp/corefcn/mex.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/mex.cc Sat Oct 05 11:22:09 2013 -0400 @@ -1164,7 +1164,7 @@ switch (get_class_id ()) { case mxLOGICAL_CLASS: - retval = int_to_ov (dv); + retval = int_to_ov (dv); break; case mxCHAR_CLASS: diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/module.mk --- a/libinterp/corefcn/module.mk Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/module.mk Sat Oct 05 11:22:09 2013 -0400 @@ -4,7 +4,9 @@ corefcn/gl2ps.c \ corefcn/graphics.in.h \ corefcn/mxarray.in.h \ - corefcn/oct-errno.in.cc + corefcn/oct-errno.in.cc \ + corefcn/oct-tex-lexer.in.ll \ + corefcn/oct-tex-symbols.in ## Options functions for Fortran packages like LSODE, DASPK. ## These are generated automagically by configure and Perl. @@ -26,6 +28,8 @@ $(PERL) $(top_srcdir)/build-aux/mk-opts.pl --opt-handler-fcns $< > $@-t mv $@-t $@ +$(OPT_HANDLERS): $(top_srcdir)/build-aux/mk-opts.pl + $(OPT_INC) : %.h : %.in $(MAKE) -C $(top_builddir)/liboctave/numeric $(@F) @@ -35,9 +39,11 @@ corefcn/jit-ir.h \ corefcn/pt-jit.h +TEX_PARSER_INC = \ + corefcn/oct-tex-parser.h + COREFCN_INC = \ corefcn/Cell.h \ - corefcn/action-container.h \ corefcn/c-file-ptr-stream.h \ corefcn/comment-list.h \ corefcn/cutils.h \ @@ -74,6 +80,7 @@ corefcn/mxarray.in.h \ corefcn/oct-errno.h \ corefcn/oct-fstrm.h \ + corefcn/oct-handle.h \ corefcn/oct-hdf5.h \ corefcn/oct-hist.h \ corefcn/oct-iostrm.h \ @@ -100,7 +107,6 @@ corefcn/toplev.h \ corefcn/txt-eng-ft.h \ corefcn/txt-eng.h \ - corefcn/unwind-prot.h \ corefcn/utils.h \ corefcn/variables.h \ corefcn/workspace-element.h \ @@ -108,7 +114,8 @@ corefcn/xnorm.h \ corefcn/xpow.h \ corefcn/zfstream.h \ - $(JIT_INC) + $(JIT_INC) \ + $(TEX_PARSER_INC) JIT_SRC = \ corefcn/jit-util.cc \ @@ -116,6 +123,10 @@ corefcn/jit-ir.cc \ corefcn/pt-jit.cc +TEX_PARSER_SRC = \ + corefcn/oct-tex-lexer.ll \ + corefcn/oct-tex-parser.yy + C_COREFCN_SRC = \ corefcn/cutils.c \ corefcn/matherr.c \ @@ -240,9 +251,10 @@ corefcn/time.cc \ corefcn/toplev.cc \ corefcn/tril.cc \ + corefcn/txt-eng.cc \ corefcn/txt-eng-ft.cc \ corefcn/typecast.cc \ - corefcn/unwind-prot.cc \ + corefcn/urlwrite.cc \ corefcn/utils.cc \ corefcn/variables.cc \ corefcn/xdiv.cc \ @@ -290,8 +302,28 @@ -e "s|%OCTAVE_IDX_TYPE%|${OCTAVE_IDX_TYPE}|" > $@-t mv $@-t $@ -noinst_LTLIBRARIES += corefcn/libcorefcn.la +corefcn/oct-tex-lexer.ll: corefcn/oct-tex-lexer.in.ll corefcn/oct-tex-symbols.in Makefile.am + $(AWK) 'BEGIN { print "/* DO NOT EDIT. AUTOMATICALLY GENERATED FROM oct-tex-lexer.in.ll and oct-tex-symbols.in. */"; } /^@SYMBOL_RULES@$$/ { count = 0; while (getline < "$(srcdir)/corefcn/oct-tex-symbols.in") { if ($$0 !~ /^#.*/ && NF == 3) { printf("\"\\\\%s\" { yylval->sym = %d; return SYM; }\n", $$1, count); count++; } } getline } ! /^@SYMBOL_RULES@$$/ { print }' $< > $@-t + mv $@-t $@ + +corefcn/oct-tex-symbols.cc: corefcn/oct-tex-symbols.in Makefile.am + $(AWK) 'BEGIN { print "// DO NOT EDIT. AUTOMATICALLY GENERATED FROM oct-tex-symbols.in."; print "static uint32_t symbol_codes[][2] = {"; count = 0; } END { print "};"; printf("static int num_symbol_codes = %d;\n", count); } /^#/ { } { if (NF == 3) { printf(" { %s, %s },\n", $$2, $$3); count++; } }' $< > $@-t + mv $@-t $@ + +corefcn/txt-eng.cc: corefcn/oct-tex-symbols.cc +corefcn/oct-tex-lexer.cc: LEX_OUTPUT_ROOT := lex.octave_tex_ +corefcn/oct-tex-parser.h: corefcn/oct-tex-parser.yy + + +noinst_LTLIBRARIES += \ + corefcn/libcorefcn.la \ + corefcn/libtex_parser.la corefcn_libcorefcn_la_SOURCES = $(COREFCN_SRC) corefcn_libcorefcn_la_CPPFLAGS = $(liboctinterp_la_CPPFLAGS) $(FFTW_XCPPFLAGS) +corefcn_libtex_parser_la_SOURCES = $(TEX_PARSER_SRC) +corefcn_libtex_parser_la_CPPFLAGS = $(liboctinterp_la_CPPFLAGS) +corefcn_libtex_parser_la_CXXFLAGS = \ + $(filter-out -Wold-style-cast, $(AM_CXXFLAGS)) + diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/oct-handle.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/corefcn/oct-handle.h Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,147 @@ +/* + +Copyright (C) 2007-2012 John W. Eaton + +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 +. + +*/ + +#if !defined (octave_handle_h) +#define octave_handle_h 1 + +#include "dMatrix.h" +#include "lo-ieee.h" + +#include "ov.h" + +// --------------------------------------------------------------------- + +class octave_handle +{ +public: + octave_handle (void) : val (octave_NaN) { } + + octave_handle (const octave_value& a) + : val (octave_NaN) + { + if (a.is_empty ()) + /* do nothing */; + else + { + double tval = a.double_value (); + + if (! error_state) + val = tval; + else + error ("invalid handle"); + } + } + + octave_handle (int a) : val (a) { } + + octave_handle (double a) : val (a) { } + + octave_handle (const octave_handle& a) : val (a.val) { } + + octave_handle& operator = (const octave_handle& a) + { + if (&a != this) + val = a.val; + + return *this; + } + + ~octave_handle (void) { } + + double value (void) const { return val; } + + octave_value as_octave_value (void) const + { + return ok () ? octave_value (val) : octave_value (Matrix ()); + } + + // Prefix increment/decrement operators. + octave_handle& operator ++ (void) + { + ++val; + return *this; + } + + octave_handle& operator -- (void) + { + --val; + return *this; + } + + // Postfix increment/decrement operators. + const octave_handle operator ++ (int) + { + octave_handle old_value = *this; + ++(*this); + return old_value; + } + + const octave_handle operator -- (int) + { + octave_handle old_value = *this; + --(*this); + return old_value; + } + + bool ok (void) const { return ! xisnan (val); } + +private: + double val; +}; + +inline bool +operator == (const octave_handle& a, const octave_handle& b) +{ + return a.value () == b.value (); +} + +inline bool +operator != (const octave_handle& a, const octave_handle& b) +{ + return a.value () != b.value (); +} + +inline bool +operator < (const octave_handle& a, const octave_handle& b) +{ + return a.value () < b.value (); +} + +inline bool +operator <= (const octave_handle& a, const octave_handle& b) +{ + return a.value () <= b.value (); +} + +inline bool +operator >= (const octave_handle& a, const octave_handle& b) +{ + return a.value () >= b.value (); +} + +inline bool +operator > (const octave_handle& a, const octave_handle& b) +{ + return a.value () > b.value (); +} + +#endif diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/oct-hist.cc --- a/libinterp/corefcn/oct-hist.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/oct-hist.cc Sat Oct 05 11:22:09 2013 -0400 @@ -328,10 +328,8 @@ tmp.resize (len - 1); if (! tmp.empty ()) - { - command_history::add (tmp); + if (command_history::add (tmp)) octave_link::append_history (tmp); - } } } @@ -580,10 +578,8 @@ std::string timestamp = now.strftime (Vhistory_timestamp_format_string); if (! timestamp.empty ()) - { - command_history::add (timestamp); + if (command_history::add (timestamp)) octave_link::append_history (timestamp); - } } DEFUN (edit_history, args, , @@ -759,12 +755,13 @@ @seealso{history_file, history_size, history_timestamp_format_string, history_save}\n\ @end deftypefn") { + octave_value retval; + std::string old_history_control = command_history::histcontrol (); std::string tmp = old_history_control; - octave_value retval = set_internal_variable (tmp, args, nargout, - "history_control"); + retval = set_internal_variable (tmp, args, nargout, "history_control"); if (tmp != old_history_control) command_history::process_histcontrol (tmp); @@ -782,13 +779,15 @@ @seealso{history_file, history_timestamp_format_string, history_save}\n\ @end deftypefn") { + octave_value retval; + int old_history_size = command_history::size (); int tmp = old_history_size; - octave_value retval = set_internal_variable (tmp, args, nargout, - "history_size", -1, - std::numeric_limits::max ()); + retval = set_internal_variable (tmp, args, nargout, + "history_size", -1, + std::numeric_limits::max ()); if (tmp != old_history_size) command_history::set_size (tmp); @@ -807,12 +806,13 @@ @seealso{history_size, history_save, history_timestamp_format_string}\n\ @end deftypefn") { + octave_value retval; + std::string old_history_file = command_history::file (); std::string tmp = old_history_file; - octave_value retval = set_internal_variable (tmp, args, nargout, - "history_file"); + retval = set_internal_variable (tmp, args, nargout, "history_file"); if (tmp != old_history_file) command_history::set_file (tmp); @@ -834,9 +834,9 @@ \"# Octave VERSION, %a %b %d %H:%M:%S %Y %Z \"\n\ @end example\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{strftime, history_file, history_size, history_save}\n\ @end deftypefn") { @@ -851,18 +851,19 @@ Query or set the internal variable that controls whether commands entered\n\ on the command line are saved in the history file.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{history_control, history_file, history_size, history_timestamp_format_string}\n\ @end deftypefn") { + octave_value retval; + bool old_history_save = ! command_history::ignoring_entries (); bool tmp = old_history_save; - octave_value retval = set_internal_variable (tmp, args, nargout, - "history_save"); + retval = set_internal_variable (tmp, args, nargout, "history_save"); if (tmp != old_history_save) command_history::ignore_entries (! tmp); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/oct-map.h --- a/libinterp/corefcn/oct-map.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/oct-map.h Sat Oct 05 11:22:09 2013 -0400 @@ -474,6 +474,7 @@ { return v.map_value (); } // The original Octave_map object which is now deprecated. +// It was fully deprecated in version 3.8 and should be removed in 3.12. // Octave_map and octave_map are convertible to each other. class diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/oct-stream.cc --- a/libinterp/corefcn/oct-stream.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/oct-stream.cc Sat Oct 05 11:22:09 2013 -0400 @@ -1189,29 +1189,6 @@ return is >> valptr; } -template std::istream& -octave_scan (std::istream&, const scanf_format_elt&, int*); - -template std::istream& -octave_scan (std::istream&, const scanf_format_elt&, long int*); - -template std::istream& -octave_scan (std::istream&, const scanf_format_elt&, short int*); - -template std::istream& -octave_scan (std::istream&, const scanf_format_elt&, unsigned int*); - -template std::istream& -octave_scan (std::istream&, const scanf_format_elt&, unsigned long int*); - -template std::istream& -octave_scan (std::istream&, const scanf_format_elt&, unsigned short int*); - -#if 0 -template std::istream& -octave_scan (std::istream&, const scanf_format_elt&, float*); -#endif - template<> std::istream& octave_scan<> (std::istream& is, const scanf_format_elt& fmt, double* valptr) @@ -1278,36 +1255,6 @@ } template void -do_scanf_conv (std::istream&, const scanf_format_elt&, int*, - Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool); - -template void -do_scanf_conv (std::istream&, const scanf_format_elt&, long int*, - Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool); - -template void -do_scanf_conv (std::istream&, const scanf_format_elt&, short int*, - Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool); - -template void -do_scanf_conv (std::istream&, const scanf_format_elt&, unsigned int*, - Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool); - -template void -do_scanf_conv (std::istream&, const scanf_format_elt&, unsigned long int*, - Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool); - -template void -do_scanf_conv (std::istream&, const scanf_format_elt&, unsigned short int*, - Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool); - -#if 0 -template void -do_scanf_conv (std::istream&, const scanf_format_elt&, float*, - Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool); -#endif - -template void do_scanf_conv (std::istream&, const scanf_format_elt&, double*, Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool); @@ -2402,30 +2349,6 @@ return retval; } -template int -do_printf_conv (std::ostream&, const char*, int, int, int, int, - const std::string&); - -template int -do_printf_conv (std::ostream&, const char*, int, int, int, long, - const std::string&); - -template int -do_printf_conv (std::ostream&, const char*, int, int, int, unsigned int, - const std::string&); - -template int -do_printf_conv (std::ostream&, const char*, int, int, int, unsigned long, - const std::string&); - -template int -do_printf_conv (std::ostream&, const char*, int, int, int, double, - const std::string&); - -template int -do_printf_conv (std::ostream&, const char*, int, int, int, const char*, - const std::string&); - #define DO_DOUBLE_CONV(TQUAL) \ do \ { \ @@ -2544,9 +2467,17 @@ nsa--; } - const char *tval = xisinf (val) - ? (val < 0 ? "-Inf" : "Inf") - : (lo_ieee_is_NA (val) ? "NA" : "NaN"); + const char *tval; + if (xisinf (val)) + if (elt->flags.find ('+') != std::string::npos) + tval = (val < 0 ? "-Inf" : "+Inf"); + else + tval = (val < 0 ? "-Inf" : "Inf"); + else + if (elt->flags.find ('+') != std::string::npos) + tval = (lo_ieee_is_NA (val) ? "+NA" : "+NaN"); + else + tval = (lo_ieee_is_NA (val) ? "NA" : "NaN"); retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2, @@ -3027,229 +2958,199 @@ rep->close (); } -template -octave_value -do_read (octave_stream& strm, octave_idx_type nr, octave_idx_type nc, octave_idx_type block_size, - octave_idx_type skip, bool do_float_fmt_conv, bool do_NA_conv, - oct_mach_info::float_format from_flt_fmt, octave_idx_type& count) +template +static octave_value +convert_and_copy (std::list& input_buf_list, + octave_idx_type input_buf_elts, + octave_idx_type elts_read, + octave_idx_type nr, octave_idx_type nc, bool swap, + bool do_float_fmt_conv, bool do_NA_conv, + oct_mach_info::float_format from_flt_fmt) { - octave_value retval; - - RET_T nda; - - count = 0; - - typedef typename RET_T::element_type ELMT; - ELMT elt_zero = ELMT (); - - ELMT *dat = 0; - - octave_idx_type max_size = 0; - - octave_idx_type final_nr = 0; - octave_idx_type final_nc = 1; - - if (nr > 0) + typedef typename DST_T::element_type dst_elt_type; + + DST_T conv (dim_vector (nr, nc)); + + dst_elt_type *conv_data = conv.fortran_vec (); + + octave_idx_type j = 0; + + for (std::list::const_iterator it = input_buf_list.begin (); + it != input_buf_list.end (); it++) { - if (nc > 0) + SRC_T *data = static_cast (*it); + + if (swap || do_float_fmt_conv) { - nda.resize (dim_vector (nr, nc), elt_zero); - dat = nda.fortran_vec (); - max_size = nr * nc; + for (octave_idx_type i = 0; i < input_buf_elts && j < elts_read; + i++, j++) + { + if (swap) + swap_bytes (&data[i]); + else if (do_float_fmt_conv) + do_float_format_conversion (&data[i], sizeof (SRC_T), + 1, from_flt_fmt, + oct_mach_info::float_format ()); + + dst_elt_type tmp (data[i]); + + if (do_NA_conv && __lo_ieee_is_old_NA (tmp)) + tmp = __lo_ieee_replace_old_NA (tmp); + + conv_data[j] = tmp; + } } else { - nda.resize (dim_vector (nr, 32), elt_zero); - dat = nda.fortran_vec (); - max_size = nr * 32; + if (do_NA_conv) + { + for (octave_idx_type i = 0; i < input_buf_elts && j < elts_read; + i++, j++) + { + dst_elt_type tmp (data[i]); + + if (__lo_ieee_is_old_NA (tmp)) + tmp = __lo_ieee_replace_old_NA (tmp); + + conv_data[j] = tmp; + } + } + else + { + for (octave_idx_type i = 0; i < input_buf_elts && j < elts_read; + i++, j++) + conv_data[j] = data[i]; + } } + + delete [] data; } - else + + input_buf_list.clear (); + + for (octave_idx_type i = elts_read; i < nr * nc; i++) + conv_data[i] = dst_elt_type (0); + + return conv; +} + +typedef octave_value (*conv_fptr) + (std::list& input_buf_list, octave_idx_type input_buf_elts, + octave_idx_type elts_read, octave_idx_type nr, octave_idx_type nc, + bool swap, bool do_float_fmt_conv, bool do_NA_conv, + oct_mach_info::float_format from_flt_fmt); + +#define TABLE_ELT(T, U, V, W) \ + conv_fptr_table[oct_data_conv::T][oct_data_conv::U] = convert_and_copy + +#define FILL_TABLE_ROW(T, V) \ + TABLE_ELT (T, dt_int8, V, int8NDArray); \ + TABLE_ELT (T, dt_uint8, V, uint8NDArray); \ + TABLE_ELT (T, dt_int16, V, int16NDArray); \ + TABLE_ELT (T, dt_uint16, V, uint16NDArray); \ + TABLE_ELT (T, dt_int32, V, int32NDArray); \ + TABLE_ELT (T, dt_uint32, V, uint32NDArray); \ + TABLE_ELT (T, dt_int64, V, int64NDArray); \ + TABLE_ELT (T, dt_uint64, V, uint64NDArray); \ + TABLE_ELT (T, dt_single, V, FloatNDArray); \ + TABLE_ELT (T, dt_double, V, NDArray); \ + TABLE_ELT (T, dt_char, V, charNDArray); \ + TABLE_ELT (T, dt_schar, V, charNDArray); \ + TABLE_ELT (T, dt_uchar, V, charNDArray); \ + TABLE_ELT (T, dt_logical, V, boolNDArray); + +octave_value +octave_stream::finalize_read (std::list& input_buf_list, + octave_idx_type input_buf_elts, + octave_idx_type elts_read, + octave_idx_type nr, octave_idx_type nc, + oct_data_conv::data_type input_type, + oct_data_conv::data_type output_type, + oct_mach_info::float_format ffmt) +{ + octave_value retval; + + static bool initialized = false; + + // Table function pointers for return types x read types. + + static conv_fptr conv_fptr_table[oct_data_conv::dt_unknown][14]; + + if (! initialized) { - nda.resize (dim_vector (32, 1), elt_zero); - dat = nda.fortran_vec (); - max_size = 32; + for (int i = 0; i < oct_data_conv::dt_unknown; i++) + for (int j = 0; j < 14; j++) + conv_fptr_table[i][j] = 0; + + FILL_TABLE_ROW (dt_int8, int8_t); + FILL_TABLE_ROW (dt_uint8, uint8_t); + FILL_TABLE_ROW (dt_int16, int16_t); + FILL_TABLE_ROW (dt_uint16, uint16_t); + FILL_TABLE_ROW (dt_int32, int32_t); + FILL_TABLE_ROW (dt_uint32, uint32_t); + FILL_TABLE_ROW (dt_int64, int64_t); + FILL_TABLE_ROW (dt_uint64, uint64_t); + FILL_TABLE_ROW (dt_single, float); + FILL_TABLE_ROW (dt_double, double); + FILL_TABLE_ROW (dt_char, char); + FILL_TABLE_ROW (dt_schar, signed char); + FILL_TABLE_ROW (dt_uchar, unsigned char); + FILL_TABLE_ROW (dt_logical, bool); + + initialized = true; } - // FIXME -- byte order for Cray? - bool swap = false; + if (ffmt == oct_mach_info::flt_fmt_unknown) + ffmt = float_format (); + if (oct_mach_info::words_big_endian ()) - swap = (from_flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian - || from_flt_fmt == oct_mach_info::flt_fmt_vax_g - || from_flt_fmt == oct_mach_info::flt_fmt_vax_g); + swap = (ffmt == oct_mach_info::flt_fmt_ieee_little_endian); else - swap = (from_flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian); - - union - { - char buf[sizeof (typename strip_template_param::type)]; - typename strip_template_param::type val; - } u; - - std::istream *isp = strm.input_stream (); - - if (isp) + swap = (ffmt == oct_mach_info::flt_fmt_ieee_big_endian); + + bool do_float_fmt_conv = ((input_type == oct_data_conv::dt_double + || input_type == oct_data_conv::dt_single) + && ffmt != float_format ()); + + bool do_NA_conv = (output_type == oct_data_conv::dt_double); + + switch (output_type) { - std::istream& is = *isp; - - octave_idx_type elts_read = 0; - - for (;;) - { - // FIXME -- maybe there should be a special case for - // skip == 0. - - if (is) - { - if (nr > 0 && nc > 0 && count == max_size) - { - final_nr = nr; - final_nc = nc; - - break; - } - - is.read (u.buf, sizeof (typename strip_template_param::type)); - - // We only swap bytes for integer types. For float - // types, the format conversion will also handle byte - // swapping. - - if (swap) - swap_bytes::type)> (u.buf); - else if (do_float_fmt_conv) - do_float_format_conversion - (u.buf, - sizeof (typename strip_template_param::type), - 1, from_flt_fmt, oct_mach_info::float_format ()); - - typename RET_T::element_type tmp - = static_cast (u.val); - - if (is) - { - if (count == max_size) - { - max_size *= 2; - - if (nr > 0) - nda.resize (dim_vector (nr, max_size / nr), - elt_zero); - else - nda.resize (dim_vector (max_size, 1), elt_zero); - - dat = nda.fortran_vec (); - } - - if (do_NA_conv && __lo_ieee_is_old_NA (tmp)) - tmp = __lo_ieee_replace_old_NA (tmp); - - dat[count++] = tmp; - - elts_read++; - } - - int seek_status = 0; - - if (skip != 0 && elts_read == block_size) - { - seek_status = strm.seek (skip, SEEK_CUR); - elts_read = 0; - } - - if (is.eof () || seek_status < 0) - { - if (nr > 0) - { - if (count > nr) - { - final_nr = nr; - final_nc = (count - 1) / nr + 1; - } - else - { - final_nr = count; - final_nc = 1; - } - } - else - { - final_nr = count; - final_nc = 1; - } - - break; - } - } - else if (is.eof ()) - break; - } + case oct_data_conv::dt_int8: + case oct_data_conv::dt_uint8: + case oct_data_conv::dt_int16: + case oct_data_conv::dt_uint16: + case oct_data_conv::dt_int32: + case oct_data_conv::dt_uint32: + case oct_data_conv::dt_int64: + case oct_data_conv::dt_uint64: + case oct_data_conv::dt_single: + case oct_data_conv::dt_double: + case oct_data_conv::dt_char: + case oct_data_conv::dt_schar: + case oct_data_conv::dt_uchar: + case oct_data_conv::dt_logical: + { + conv_fptr fptr = conv_fptr_table[input_type][output_type]; + + retval = fptr (input_buf_list, input_buf_elts, elts_read, + nr, nc, swap, do_float_fmt_conv, do_NA_conv, ffmt); + } + break; + + default: + retval = false; + (*current_liboctave_error_handler) + ("read: invalid type specification"); + break; } - - nda.resize (dim_vector (final_nr, final_nc), elt_zero); - - retval = nda; + return retval; } -#define DO_READ_VAL_TEMPLATE(RET_T, READ_T) \ - template octave_value \ - do_read (octave_stream&, octave_idx_type, octave_idx_type, octave_idx_type, octave_idx_type, bool, bool, \ - oct_mach_info::float_format, octave_idx_type&) - -// FIXME -- should we only have float if it is a different -// size from double? - -#define INSTANTIATE_DO_READ(VAL_T) \ - DO_READ_VAL_TEMPLATE (VAL_T, octave_int8); \ - DO_READ_VAL_TEMPLATE (VAL_T, octave_uint8); \ - DO_READ_VAL_TEMPLATE (VAL_T, octave_int16); \ - DO_READ_VAL_TEMPLATE (VAL_T, octave_uint16); \ - DO_READ_VAL_TEMPLATE (VAL_T, octave_int32); \ - DO_READ_VAL_TEMPLATE (VAL_T, octave_uint32); \ - DO_READ_VAL_TEMPLATE (VAL_T, octave_int64); \ - DO_READ_VAL_TEMPLATE (VAL_T, octave_uint64); \ - DO_READ_VAL_TEMPLATE (VAL_T, float); \ - DO_READ_VAL_TEMPLATE (VAL_T, double); \ - DO_READ_VAL_TEMPLATE (VAL_T, char); \ - DO_READ_VAL_TEMPLATE (VAL_T, signed char); \ - DO_READ_VAL_TEMPLATE (VAL_T, unsigned char) - -INSTANTIATE_DO_READ (int8NDArray); -INSTANTIATE_DO_READ (uint8NDArray); -INSTANTIATE_DO_READ (int16NDArray); -INSTANTIATE_DO_READ (uint16NDArray); -INSTANTIATE_DO_READ (int32NDArray); -INSTANTIATE_DO_READ (uint32NDArray); -INSTANTIATE_DO_READ (int64NDArray); -INSTANTIATE_DO_READ (uint64NDArray); -INSTANTIATE_DO_READ (FloatNDArray); -INSTANTIATE_DO_READ (NDArray); -INSTANTIATE_DO_READ (charNDArray); -INSTANTIATE_DO_READ (boolNDArray); - -typedef octave_value (*read_fptr) (octave_stream&, octave_idx_type, octave_idx_type, octave_idx_type, octave_idx_type, bool, bool, - oct_mach_info::float_format ffmt, octave_idx_type&); - -#define FILL_TABLE_ROW(R, VAL_T) \ - read_fptr_table[R][oct_data_conv::dt_int8] = do_read; \ - read_fptr_table[R][oct_data_conv::dt_uint8] = do_read; \ - read_fptr_table[R][oct_data_conv::dt_int16] = do_read; \ - read_fptr_table[R][oct_data_conv::dt_uint16] = do_read; \ - read_fptr_table[R][oct_data_conv::dt_int32] = do_read; \ - read_fptr_table[R][oct_data_conv::dt_uint32] = do_read; \ - read_fptr_table[R][oct_data_conv::dt_int64] = do_read; \ - read_fptr_table[R][oct_data_conv::dt_uint64] = do_read; \ - read_fptr_table[R][oct_data_conv::dt_single] = do_read; \ - read_fptr_table[R][oct_data_conv::dt_double] = do_read; \ - read_fptr_table[R][oct_data_conv::dt_char] = do_read; \ - read_fptr_table[R][oct_data_conv::dt_schar] = do_read; \ - read_fptr_table[R][oct_data_conv::dt_uchar] = do_read; \ - read_fptr_table[R][oct_data_conv::dt_logical] = do_read - octave_value octave_stream::read (const Array& size, octave_idx_type block_size, oct_data_conv::data_type input_type, @@ -3257,38 +3158,13 @@ octave_idx_type skip, oct_mach_info::float_format ffmt, octave_idx_type& char_count) { - static bool initialized = false; - - // Table function pointers for return types x read types. - - static read_fptr read_fptr_table[oct_data_conv::dt_unknown][14]; - - if (! initialized) - { - for (int i = 0; i < oct_data_conv::dt_unknown; i++) - for (int j = 0; j < 14; j++) - read_fptr_table[i][j] = 0; - - FILL_TABLE_ROW (oct_data_conv::dt_int8, int8NDArray); - FILL_TABLE_ROW (oct_data_conv::dt_uint8, uint8NDArray); - FILL_TABLE_ROW (oct_data_conv::dt_int16, int16NDArray); - FILL_TABLE_ROW (oct_data_conv::dt_uint16, uint16NDArray); - FILL_TABLE_ROW (oct_data_conv::dt_int32, int32NDArray); - FILL_TABLE_ROW (oct_data_conv::dt_uint32, uint32NDArray); - FILL_TABLE_ROW (oct_data_conv::dt_int64, int64NDArray); - FILL_TABLE_ROW (oct_data_conv::dt_uint64, uint64NDArray); - FILL_TABLE_ROW (oct_data_conv::dt_single, FloatNDArray); - FILL_TABLE_ROW (oct_data_conv::dt_double, NDArray); - FILL_TABLE_ROW (oct_data_conv::dt_char, charNDArray); - FILL_TABLE_ROW (oct_data_conv::dt_schar, charNDArray); - FILL_TABLE_ROW (oct_data_conv::dt_uchar, charNDArray); - FILL_TABLE_ROW (oct_data_conv::dt_logical, boolNDArray); - - initialized = true; - } - octave_value retval; + octave_idx_type nr = -1; + octave_idx_type nc = -1; + + bool one_elt_size_spec = false; + if (stream_ok ()) { // FIXME -- we may eventually want to make this extensible. @@ -3299,47 +3175,112 @@ char_count = 0; - octave_idx_type nr = -1; - octave_idx_type nc = -1; - - bool ignore; - - get_size (size, nr, nc, ignore, "fread"); + get_size (size, nr, nc, one_elt_size_spec, "fread"); if (! error_state) { - if (nr == 0 || nc == 0) - retval = Matrix (nr, nc); + + octave_idx_type elts_to_read = std::numeric_limits::max (); + + if (one_elt_size_spec) + { + // If NR == 0, Matlab returns [](0x0). + + // If NR > 0, the result will be a column vector with the given + // number of rows. + + // If NR < 0, then we have Inf and the result will be a column + // vector but we have to wait to see how big NR will be. + + if (nr == 0) + nr = nc = 0; + else + nc = 1; + } else { - if (ffmt == oct_mach_info::flt_fmt_unknown) - ffmt = float_format (); - - read_fptr fcn = read_fptr_table[output_type][input_type]; - - bool do_float_fmt_conv = ((input_type == oct_data_conv::dt_double - || input_type == oct_data_conv::dt_single) - && ffmt != float_format ()); - - bool do_NA_conv = (output_type == oct_data_conv::dt_double); - - if (fcn) + // Matlab returns [] even if there are two elements in the size + // specification and one is nonzero. + + // If NC < 0 we have [NR, Inf] and we'll wait to decide how big NC + // should be. + + if (nr == 0 || nc == 0) + nr = nc = 0; + } + + // FIXME -- ensure that this does not overflow. + + elts_to_read = nr * nc; + + bool read_to_eof = elts_to_read < 0; + + octave_idx_type input_buf_elts = -1; + + if (skip == 0) + { + if (read_to_eof) + input_buf_elts = 1024 * 1024; + else + input_buf_elts = elts_to_read; + } + else + input_buf_elts = block_size; + + octave_idx_type input_elt_size = oct_data_conv::data_type_size (input_type); + + octave_idx_type input_buf_size = input_buf_elts * input_elt_size; + + assert (input_buf_size >= 0); + + // Must also work and return correct type object for 0 elements to read. + + std::istream *isp = input_stream (); + + if (isp) + { + std::istream& is = *isp; + + std::list input_buf_list; + + octave_idx_type elts_read = 0; + + while (is && ! is.eof () && (read_to_eof || elts_read < elts_to_read)) { - retval = (*fcn) (*this, nr, nc, block_size, skip, - do_float_fmt_conv, do_NA_conv, - ffmt, char_count); - - // FIXME -- kluge! - - if (! error_state - && (output_type == oct_data_conv::dt_char - || output_type == oct_data_conv::dt_schar - || output_type == oct_data_conv::dt_uchar)) - retval = retval.char_matrix_value (); + char *input_buf = new char [input_buf_size]; + + is.read (input_buf, input_buf_size); + + size_t count = is.gcount (); + + char_count += count; + + elts_read += count / input_elt_size; + + input_buf_list.push_back (input_buf); + + if (is && skip != 0 && elts_read == block_size) + { + int seek_status = seek (skip, SEEK_CUR); + + if (seek_status < 0) + break; + } } - else - error ("fread: unable to read and convert requested types"); + + if (read_to_eof) + { + if (nc < 0) + nc = elts_read / nr + 1; + else + nr = elts_read; + } + + retval = finalize_read (input_buf_list, input_buf_elts, elts_read, + nr, nc, input_type, output_type, ffmt); } + else + error ("fread: invalid input stream"); } else invalid_operation ("fread", "reading"); @@ -3377,103 +3318,106 @@ return retval; } -template -void -write_int (std::ostream& os, bool swap, const T& val) +template +static void +convert_ints (const T *data, void *conv_data, octave_idx_type n_elts, + bool swap) { - typename T::val_type tmp = val.value (); - - if (swap) - swap_bytes (&tmp); - - os.write (reinterpret_cast (&tmp), - sizeof (typename T::val_type)); + typedef typename V::val_type val_type; + + val_type *vt_data = static_cast (conv_data); + + for (octave_idx_type i = 0; i < n_elts; i++) + { + V val (data[i]); + + vt_data[i] = val.value (); + + if (swap) + swap_bytes (&vt_data[i]); + } } -template void write_int (std::ostream&, bool, const octave_int8&); -template void write_int (std::ostream&, bool, const octave_uint8&); -template void write_int (std::ostream&, bool, const octave_int16&); -template void write_int (std::ostream&, bool, const octave_uint16&); -template void write_int (std::ostream&, bool, const octave_int32&); -template void write_int (std::ostream&, bool, const octave_uint32&); -template void write_int (std::ostream&, bool, const octave_int64&); -template void write_int (std::ostream&, bool, const octave_uint64&); - template -static inline bool -do_write (std::ostream& os, const T& val, oct_data_conv::data_type output_type, - oct_mach_info::float_format flt_fmt, bool swap, - bool do_float_conversion) +static bool +convert_data (const T *data, void *conv_data, octave_idx_type n_elts, + oct_data_conv::data_type output_type, + oct_mach_info::float_format flt_fmt) { bool retval = true; - // For compatibility, Octave converts to the output type, then - // writes. This means that truncation happens on the conversion. - // For example, the following program prints 0: - // - // x = int8 (-1) - // f = fopen ("foo.dat", "w"); - // fwrite (f, x, "unsigned char"); - // fclose (f); - // f = fopen ("foo.dat", "r"); - // y = fread (f, 1, "unsigned char"); - // printf ("%d\n", y); + bool swap + = ((oct_mach_info::words_big_endian () + && flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian) + || flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian); + + bool do_float_conversion = flt_fmt != oct_mach_info::float_format (); + + // We use octave_intN classes here instead of converting directly to + // intN_t so that we get integer saturation semantics. switch (output_type) { case oct_data_conv::dt_char: case oct_data_conv::dt_schar: case oct_data_conv::dt_int8: - write_int (os, swap, octave_int8 (val)); + convert_ints (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_uchar: case oct_data_conv::dt_uint8: - write_int (os, swap, octave_uint8 (val)); + convert_ints (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_int16: - write_int (os, swap, octave_int16 (val)); + convert_ints (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_uint16: - write_int (os, swap, octave_uint16 (val)); + convert_ints (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_int32: - write_int (os, swap, octave_int32 (val)); + convert_ints (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_uint32: - write_int (os, swap, octave_uint32 (val)); + convert_ints (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_int64: - write_int (os, swap, octave_int64 (val)); + convert_ints (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_uint64: - write_int (os, swap, octave_uint64 (val)); + convert_ints (data, conv_data, n_elts, swap); break; case oct_data_conv::dt_single: { - float f = static_cast (val); - - if (do_float_conversion) - do_float_format_conversion (&f, 1, flt_fmt); - - os.write (reinterpret_cast (&f), sizeof (float)); + float *vt_data = static_cast (conv_data); + + for (octave_idx_type i = 0; i < n_elts; i++) + { + vt_data[i] = data[i]; + + if (do_float_conversion) + do_float_format_conversion (&vt_data[i], 1, flt_fmt); + } } break; case oct_data_conv::dt_double: { - double d = static_cast (val); - if (do_float_conversion) - do_double_format_conversion (&d, 1, flt_fmt); - - os.write (reinterpret_cast (&d), sizeof (double)); + double *vt_data = static_cast (conv_data); + + for (octave_idx_type i = 0; i < n_elts; i++) + { + vt_data[i] = data[i]; + + if (do_float_conversion) + do_double_format_conversion (&vt_data[i], 1, flt_fmt); + } } break; @@ -3487,198 +3431,174 @@ return retval; } -template bool -do_write (std::ostream&, const octave_int8&, oct_data_conv::data_type, - oct_mach_info::float_format, bool, bool); - -template bool -do_write (std::ostream&, const octave_uint8&, oct_data_conv::data_type, - oct_mach_info::float_format, bool, bool); - -template bool -do_write (std::ostream&, const octave_int16&, oct_data_conv::data_type, - oct_mach_info::float_format, bool, bool); - -template bool -do_write (std::ostream&, const octave_uint16&, oct_data_conv::data_type, - oct_mach_info::float_format, bool, bool); - -template bool -do_write (std::ostream&, const octave_int32&, oct_data_conv::data_type, - oct_mach_info::float_format, bool, bool); - -template bool -do_write (std::ostream&, const octave_uint32&, oct_data_conv::data_type, - oct_mach_info::float_format, bool, bool); - -template bool -do_write (std::ostream&, const octave_int64&, oct_data_conv::data_type, - oct_mach_info::float_format, bool, bool); - -template bool -do_write (std::ostream&, const octave_uint64&, oct_data_conv::data_type, - oct_mach_info::float_format, bool, bool); +bool +octave_stream::write_bytes (const void *data, size_t nbytes) +{ + bool status = false; + + std::ostream *osp = output_stream (); + + if (osp) + { + std::ostream& os = *osp; + + if (os) + { + os.write (static_cast (data), nbytes); + + if (os) + status = true; + } + } + + return status; +} + +bool +octave_stream::skip_bytes (size_t skip) +{ + bool status = false; + + std::ostream *osp = output_stream (); + + if (osp) + { + std::ostream& os = *osp; + + // Seek to skip when inside bounds of existing file. + // Otherwise, write NUL to skip. + + off_t orig_pos = tell (); + + seek (0, SEEK_END); + + off_t eof_pos = tell (); + + // Is it possible for this to fail to return us to the + // original position? + seek (orig_pos, SEEK_SET); + + size_t remaining = eof_pos - orig_pos; + + if (remaining < skip) + { + seek (0, SEEK_END); + + // FIXME -- probably should try to write larger blocks... + + unsigned char zero = 0; + for (size_t j = 0; j < skip - remaining; j++) + os.write (reinterpret_cast (&zero), 1); + } + else + seek (skip, SEEK_CUR); + + if (os) + status = true; + } + + return status; +} template octave_idx_type octave_stream::write (const Array& data, octave_idx_type block_size, oct_data_conv::data_type output_type, - octave_idx_type skip, oct_mach_info::float_format flt_fmt) + octave_idx_type skip, + oct_mach_info::float_format flt_fmt) { - octave_idx_type retval = -1; - - bool status = true; - - octave_idx_type count = 0; - - const T *d = data.data (); - - octave_idx_type n = data.length (); - - oct_mach_info::float_format native_flt_fmt - = oct_mach_info::float_format (); - - bool do_float_conversion = (flt_fmt != native_flt_fmt); - - // FIXME -- byte order for Cray? - - bool swap = false; - - if (oct_mach_info::words_big_endian ()) - swap = (flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian - || flt_fmt == oct_mach_info::flt_fmt_vax_g - || flt_fmt == oct_mach_info::flt_fmt_vax_g); + bool swap + = ((oct_mach_info::words_big_endian () + && flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian) + || flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian); + + bool do_data_conversion + = (swap || ! is_equivalent_type (output_type) + || flt_fmt != oct_mach_info::float_format ()); + + octave_idx_type nel = data.numel (); + + octave_idx_type chunk_size; + + if (skip != 0) + chunk_size = block_size; + else if (do_data_conversion) + chunk_size = 1024 * 1024; else - swap = (flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian); - - for (octave_idx_type i = 0; i < n; i++) + chunk_size = nel; + + octave_idx_type i = 0; + + const T *pdata = data.data (); + + while (i < nel) { - std::ostream *osp = output_stream (); - - if (osp) + if (skip != 0) { - std::ostream& os = *osp; - - if (skip != 0 && (i % block_size) == 0) - { - // Seek to skip when inside bounds of existing file. - // Otherwise, write NUL to skip. - - off_t orig_pos = tell (); - - seek (0, SEEK_END); - - off_t eof_pos = tell (); - - // Is it possible for this to fail to return us to the - // original position? - seek (orig_pos, SEEK_SET); - - off_t remaining = eof_pos - orig_pos; - - if (remaining < skip) - { - seek (0, SEEK_END); - - // FIXME -- probably should try to write larger - // blocks... - - unsigned char zero = 0; - for (octave_idx_type j = 0; j < skip - remaining; j++) - os.write (reinterpret_cast (&zero), 1); - } - else - seek (skip, SEEK_CUR); - } - - if (os) - { - status = do_write (os, d[i], output_type, flt_fmt, swap, - do_float_conversion); - - if (os && status) - count++; - else - break; - } - else - { - status = false; - break; - } + if (! skip_bytes (skip)) + return -1; + } + + octave_idx_type remaining_nel = nel - i; + + if (chunk_size > remaining_nel) + chunk_size = remaining_nel; + + bool status = false; + + if (do_data_conversion) + { + size_t output_size + = chunk_size * oct_data_conv::data_type_size (output_type); + + OCTAVE_LOCAL_BUFFER (unsigned char, conv_data, output_size); + + status = convert_data (&pdata[i], conv_data, chunk_size, + output_type, flt_fmt); + + if (status) + status = write_bytes (conv_data, output_size); } else - { - status = false; - break; - } + status = write_bytes (pdata, sizeof (T) * chunk_size); + + if (! status) + return -1; + + i += chunk_size; } - if (status) - retval = count; - - return retval; + return nel; } -template octave_idx_type -octave_stream::write (const Array&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); - -template octave_idx_type -octave_stream::write (const Array&, octave_idx_type, - oct_data_conv::data_type, - octave_idx_type, oct_mach_info::float_format); +#define INSTANTIATE_WRITE(T) \ + template \ + octave_idx_type \ + octave_stream::write (const Array& data, octave_idx_type block_size, \ + oct_data_conv::data_type output_type, \ + octave_idx_type skip, \ + oct_mach_info::float_format flt_fmt) + +INSTANTIATE_WRITE (octave_int8); +INSTANTIATE_WRITE (octave_uint8); +INSTANTIATE_WRITE (octave_int16); +INSTANTIATE_WRITE (octave_uint16); +INSTANTIATE_WRITE (octave_int32); +INSTANTIATE_WRITE (octave_uint32); +INSTANTIATE_WRITE (octave_int64); +INSTANTIATE_WRITE (octave_uint64); +INSTANTIATE_WRITE (int8_t); +INSTANTIATE_WRITE (uint8_t); +INSTANTIATE_WRITE (int16_t); +INSTANTIATE_WRITE (uint16_t); +INSTANTIATE_WRITE (int32_t); +INSTANTIATE_WRITE (uint32_t); +INSTANTIATE_WRITE (int64_t); +INSTANTIATE_WRITE (uint64_t); +INSTANTIATE_WRITE (bool); +INSTANTIATE_WRITE (char); +INSTANTIATE_WRITE (float); +INSTANTIATE_WRITE (double); octave_value octave_stream::scanf (const std::string& fmt, const Array& size, diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/oct-stream.h --- a/libinterp/corefcn/oct-stream.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/oct-stream.h Sat Oct 05 11:22:09 2013 -0400 @@ -31,12 +31,14 @@ #include #include #include +#include #include #include "Array.h" #include "data-conv.h" #include "lo-utils.h" #include "mach-info.h" +#include "oct-locbuf.h" #include "oct-refcount.h" class @@ -539,13 +541,19 @@ octave_idx_type& count); octave_idx_type write (const octave_value& data, octave_idx_type block_size, - oct_data_conv::data_type output_type, - octave_idx_type skip, oct_mach_info::float_format flt_fmt); + oct_data_conv::data_type output_type, + octave_idx_type skip, + oct_mach_info::float_format flt_fmt); + + bool write_bytes (const void *data, size_t n_elts); + + bool skip_bytes (size_t n_elts); template - octave_idx_type write (const Array&, octave_idx_type block_size, - oct_data_conv::data_type output_type, - octave_idx_type skip, oct_mach_info::float_format flt_fmt); + octave_idx_type write (const Array& data, octave_idx_type block_size, + oct_data_conv::data_type output_type, + octave_idx_type skip, + oct_mach_info::float_format flt_fmt); octave_value scanf (const std::string& fmt, const Array& size, octave_idx_type& count, const std::string& who /* = "scanf" */); @@ -641,6 +649,15 @@ if (rep) rep->invalid_operation (who, rw); } + + octave_value + finalize_read (std::list& input_buf_list, + octave_idx_type input_buf_elts, + octave_idx_type elts_read, + octave_idx_type nr, octave_idx_type nc, + oct_data_conv::data_type input_type, + oct_data_conv::data_type output_type, + oct_mach_info::float_format ffmt); }; class diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/oct-tex-lexer.in.ll --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/corefcn/oct-tex-lexer.in.ll Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,146 @@ +/* + +Copyright (C) 2013 Michael Goffioul + +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 +. + +*/ + +%option prefix = "octave_tex_" +%option noyywrap +%option reentrant +%option bison-bridge + +%top { +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "txt-eng.h" +#include "oct-tex-parser.h" +} + +%x NUM_MODE +%x MAYBE_NUM_MODE + +D [0-9] +NUM (({D}+\.?{D}*)|(\.{D}+)) + +%% + +%{ +// Numeric values +%} + +{NUM} { + int nread; + + nread = sscanf (yytext, "%lf", &(yylval->num)); + if (nread == 1) + return NUM; + } +[ \t]+ { } +"\n"|. { yyless (0); BEGIN (INITIAL); } + +"{" { BEGIN (NUM_MODE); return START; } +"\n"|. { yyless (0); BEGIN (INITIAL); } + +%{ +// Simple commands +%} + +"\\bf" { return BF; } +"\\it" { return IT; } +"\\sl" { return SL; } +"\\rm" { return RM; } + +%{ +// Generic font commands +%} + +"\\fontname" { return FONTNAME; } +"\\fontsize" { BEGIN (MAYBE_NUM_MODE); return FONTSIZE; } +"\\color[rgb]" { BEGIN (MAYBE_NUM_MODE); return COLOR_RGB; } +"\\color" { return COLOR; } + +%{ +// Special characters +%} + +"{" { return START; } +"}" { return END; } +"^" { return SUPER; } +"_" { return SUB; } + +"\\{" | +"\\}" | +"\\^" | +"\\_" | +"\\\\" { yylval->ch = yytext[1]; return CH; } + +%{ +// Symbols +%} + +@SYMBOL_RULES@ + +%{ +// Generic character +%} + +"\n" | +. { yylval->ch = yytext[0]; return CH; } + +%% + +bool +text_parser_tex::init_lexer (const std::string& s) +{ + if (! scanner) + octave_tex_lex_init (&scanner); + + if (scanner) + { + if (buffer_state) + { + octave_tex__delete_buffer (reinterpret_cast (buffer_state), + scanner); + buffer_state = 0; + } + + buffer_state = octave_tex__scan_bytes (s.data (), s.length (), scanner); + } + + return (scanner && buffer_state); +} + +void +text_parser_tex::destroy_lexer (void) +{ + if (buffer_state) + { + octave_tex__delete_buffer (reinterpret_cast (buffer_state), + scanner); + buffer_state = 0; + } + + if (scanner) + { + octave_tex_lex_destroy (scanner); + scanner = 0; + } +} diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/oct-tex-parser.yy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/corefcn/oct-tex-parser.yy Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,210 @@ +/* + +Copyright (C) 2013 Michael Goffioul + +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 +. + +*/ + +%{ +#define YYDEBUG 1 + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "txt-eng.h" +#include "oct-tex-parser.h" + +extern int octave_tex_lex (YYSTYPE *, void *); +static void yyerror (text_parser_tex& parser, const char *s); + +#define scanner parser.get_scanner () +%} + +%name-prefix="octave_tex_" +%define api.pure +%parse-param { text_parser_tex& parser } +%lex-param { void *scanner } + +%code requires {#include } + +%union { + /* Leaf symbols produced by the scanner */ + char ch; + double num; + int sym; + + /* Used for string buffering */ + std::string* str; + + /* Objects produced by the parser */ + text_element* e_base; + text_element_list* e_list; +} + +%token BF IT SL RM +%token FONTNAME FONTSIZE +%token COLOR COLOR_RGB +%token START END SUPER SUB +%token CH +%token NUM +%token SYM + +%type simple_string +%type string_element symbol_element +%type superscript_element subscript_element combined_script_element +%type font_modifier_element fontname_element fontsize_element color_element +%type string_element_list scoped_string_element_list + +/* Make sure there's no memory leak on parse error. */ +%destructor { } +%destructor { delete $$; } <*> + +%nonassoc SCRIPT +%nonassoc SUB SUPER + +%nonassoc STR +%nonassoc CH + +%start string + +%% + +simple_string : CH + { $$ = new std::string (1, $1); } + | simple_string CH + { $1->append (1, $2); $$ = $1; } + ; + +symbol_element : SYM + { $$ = new text_element_symbol ($1); } + ; + +font_modifier_element : BF + { $$ = new text_element_fontstyle (text_element_fontstyle::bold); } + | IT + { $$ = new text_element_fontstyle (text_element_fontstyle::italic); } + | SL + { $$ = new text_element_fontstyle (text_element_fontstyle::oblique); } + | RM + { $$ = new text_element_fontstyle (text_element_fontstyle::normal); } + ; + +fontsize_element : FONTSIZE START NUM END + { $$ = new text_element_fontsize ($3); } + ; + +fontname_element : FONTNAME START simple_string END + { + $$ = new text_element_fontname (*$3); + delete $3; + } + ; + +color_element : COLOR START simple_string END + { + $$ = new text_element_color (*$3); + delete $3; + } + | COLOR_RGB START NUM NUM NUM END + { + $$ = new text_element_color ($3, $4, $5); + } + ; + +string_element : simple_string %prec STR + { + $$ = new text_element_string (*$1); + delete $1; + } + | scoped_string_element_list + /* This is just to avoid a warning in bison. */ + { $$ = $1; } + | symbol_element + | font_modifier_element + | fontsize_element + | fontname_element + | color_element + | superscript_element %prec SCRIPT + | subscript_element %prec SCRIPT + | combined_script_element + ; + +superscript_element : SUPER CH + { $$ = new text_element_superscript ($2); } + | SUPER scoped_string_element_list + { $$ = new text_element_superscript ($2); } + | SUPER symbol_element + { $$ = new text_element_superscript ($2); } + ; + +subscript_element : SUB CH + { $$ = new text_element_subscript ($2); } + | SUB scoped_string_element_list + { $$ = new text_element_subscript ($2); } + | SUB symbol_element + { $$ = new text_element_subscript ($2); } + ; + +combined_script_element : subscript_element superscript_element + { $$ = new text_element_combined ($1, $2); } + | superscript_element subscript_element + { $$ = new text_element_combined ($1, $2); } + ; + +string_element_list : string_element + { $$ = new text_element_list ($1); } + | string_element_list string_element + { $1->push_back ($2); $$ = $1; } + ; + +scoped_string_element_list : START string_element_list END + { $$ = $2; } + | START END + { $$ = new text_element_list (); } + ; + +string : /* empty */ + { parser.set_parse_result (new text_element_string ("")); } + | string_element_list + { parser.set_parse_result ($1); } + ; + +%% + +text_element* +text_parser_tex::parse (const std::string& s) +{ + octave_tex_debug = 0; + + if (init_lexer (s)) + { + result = 0; + + if (octave_tex_parse (*this) == 0) + return result; + } + + return new text_element_string (s); +} + +static void +yyerror (text_parser_tex&, const char *s) +{ + fprintf (stderr, "TeX parse error: %s\n", s); +} diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/oct-tex-symbols.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/corefcn/oct-tex-symbols.in Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,113 @@ +# List of supported symbols for the TeX interpreter +# (http://www.mathworks.com/help/matlab/ref/text_props.html): +# - symbol name +# - Unicode code +# - MS symbol code (http://www.kostis.net/charsets/symbol.htm) +# - Arranged by listings in The TeXbook, Appendix F +# - Lowercase Greek letters: Greek Upper case: Misc Symbols type Ord: "Large" operators: +# - Binary operators: Relations: Negated relations: Arrows: Openings: Closings: Alternate names: +# - Other (not in Appendix F Tables): + +alpha 0x03B1 0xF061 +beta 0x03B2 0xF062 +gamma 0x03B3 0xF067 +delta 0x03B4 0xF064 +epsilon 0x03B5 0xF065 +zeta 0x03B6 0xF07A +eta 0x03B7 0xF068 +theta 0x03B8 0xF071 +vartheta 0x03D1 0xF04A +iota 0x03B9 0xF069 +kappa 0x03BA 0xF06B +lambda 0x03BB 0xF06C +mu 0x03BC 0xF06D +nu 0x03BD 0xF06E +xi 0x03BE 0xF078 +o 0x03BF 0xF0B0 +pi 0x03C0 0xF070 +varpi 0x03D6 0xF076 +rho 0x03C1 0xF072 +sigma 0x03C3 0xF073 +varsigma 0x03C2 0xF056 +tau 0x03C4 0xF074 +upsilon 0x03C5 0xF075 +phi 0x03C6 0xF066 +chi 0x03C7 0xF063 +psi 0x03C8 0xF079 +omega 0x03C9 0xF077 +Gamma 0x0393 0xF047 +Delta 0x0394 0xF044 +Theta 0x0398 0xF051 +Lambda 0x039B 0xF04C +Xi 0x039E 0xF058 +Pi 0x03A0 0xF050 +Sigma 0x03A3 0xF053 +Upsilon 0x03D2 0xF055 +Phi 0x03A6 0xF046 +Psi 0x03A8 0xF059 +Omega 0x03A9 0xF057 +aleph 0x2135 0xF0C0 +wp 0x2118 0xF0C3 +Re 0x211C 0xF0C2 +Im 0x2111 0xF0C1 +partial 0x2202 0xF0B6 +infty 0x221E 0xF0A5 +prime 0x2032 0xF0A2 +nabla 0x2207 0xF0D1 +surd 0x221A 0xF0D6 +angle 0x2220 0xF0D0 +forall 0x2200 0xF022 +exists 0x2203 0xF024 +neg 0x00AC 0xF0D8 +clubsuit 0x2663 0xF0A7 +diamondsuit 0x2666 0xF0A8 +heartsuit 0x2665 0xF0A9 +spadesuit 0x2660 0xF0AA +int 0x222B 0xF0F2 +pm 0x00B1 0xF0B1 +cdot 0x22C5 0xF0D7 +times 0x00D7 0xF0B4 +ast 0x2217 0xF02A +circ 0x2218 0xF0B0 +bullet 0x2219 0xF0B7 +div 0x00F7 0xF0B8 +cap 0x2229 0xF0C7 +cup 0x222A 0xF0C8 +vee 0x2228 0xF0DA +wedge 0x2227 0xF0D9 +oplus 0x2295 0xF0C5 +otimes 0x2297 0xF0C4 +oslash 0x2298 0xF0C6 +leq 0x2264 0xF0A3 +subset 0x2282 0xF0CC +subseteq 0x2286 0xF0CD +in 0x2208 0xF0CE +geq 0x2265 0xF0B3 +supset 0x2283 0xF0C9 +supseteq 0x2287 0xF0CA +ni 0x220B 0xF027 +mid 0x2223 0xF0BD +equiv 0x2261 0xF0BA +sim 0x223C 0xF07E +approx 0x2248 0xF0BB +cong 0x2245 0xF040 +propto 0x221D 0xF0B5 +perp 0x22A5 0xF05E +leftarrow 0x2190 0xF0AC +Leftarrow 0x21D0 0xF0DC +rightarrow 0x2192 0xF0AE +Rightarrow 0x21D2 0xF0DE +leftrightarrow 0x2194 0xF0AB +uparrow 0x2191 0xF0AD +downarrow 0x2193 0xF0AF +lfloor 0x230A 0xF0EB +langle 0x27E8 0xF0E1 +lceil 0x2308 0xF0E9 +rfloor 0x230B 0xF0FB +rangle 0x27E9 0xF0F1 +rceil 0x2309 0xF0F9 +neq 0x2260 0xF0B9 +ldots 0x2026 0xF0BC +0 0x2298 0xF0C6 +copyright 0x00A9 0xF0E3 +deg 0x00B0 0xF0B0 diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/octave-link.cc --- a/libinterp/corefcn/octave-link.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/octave-link.cc Sat Oct 05 11:22:09 2013 -0400 @@ -231,7 +231,7 @@ retval.resize (3); - // If 3, then is filename, directory and selected index. + // If 3, then retval is filename, directory, and selected index. if (nel <= 3) { int idx = 0; @@ -250,12 +250,12 @@ else { // Multiple files. - nel = items_lst.size (); + nel = items_lst.size () - 2; Cell items (dim_vector (1, nel)); std::list::iterator it = items_lst.begin (); - for (unsigned int idx = 0; idx < items_lst.size ()-2; idx++) + for (int idx = 0; idx < nel; idx++) { items.xelem (idx) = *it; it++; @@ -402,3 +402,36 @@ return retval; } + +DEFUN (__octave_link_show_preferences__, , , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} __octave_link_show_preferences__ ()\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; + + retval = octave_link::show_preferences (); + + return retval; +} + +DEFUN (__octave_link_show_doc__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} __octave_link_show_doc__ ( @var{filename} )\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; + std::string file; + + if (args.length () >= 1) + file = args(0).string_value(); + + retval = octave_link::show_doc (file); + + return retval; +} + + + diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/octave-link.h --- a/libinterp/corefcn/octave-link.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/octave-link.h Sat Oct 05 11:22:09 2013 -0400 @@ -307,6 +307,31 @@ return instance_ok () ? instance->link_enabled : false; } + static bool + show_preferences () + { + if (enabled ()) + { + instance->do_show_preferences (); + return true; + } + else + return false; + } + + static bool + show_doc (const std::string & file) + { + if (enabled ()) + { + instance->do_show_doc (file); + return true; + } + else + return false; + + } + private: static octave_link *instance; @@ -425,6 +450,10 @@ virtual void do_set_default_prompts (std::string& ps1, std::string& ps2, std::string& ps4) = 0; + + virtual void do_show_preferences (void) = 0; + + virtual void do_show_doc (const std::string &file) = 0; }; #endif // OCTAVELINK_H diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/pager.cc --- a/libinterp/corefcn/pager.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/pager.cc Sat Oct 05 11:22:09 2013 -0400 @@ -514,23 +514,29 @@ DEFUN (diary, args, , "-*- texinfo -*-\n\ -@deftypefn {Command} {} diary options\n\ +@deftypefn {Command} {} diary\n\ +@deftypefnx {Command} {} diary on\n\ +@deftypefnx {Command} {} diary off\n\ +@deftypefnx {Command} {} diary @var{filename}\n\ Record a list of all commands @emph{and} the output they produce, mixed\n\ -together just as you see them on your terminal. Valid options are:\n\ +together just as they appear on the terminal.\n\ \n\ -@table @code\n\ +Valid options are:\n\ +\n\ +@table @asis\n\ @item on\n\ -Start recording your session in a file called @file{diary} in your\n\ +Start recording a session in a file called @file{diary} in the\n\ current working directory.\n\ \n\ @item off\n\ -Stop recording your session in the diary file.\n\ +Stop recording the session in the diary file.\n\ \n\ -@item @var{file}\n\ -Record your session in the file named @var{file}.\n\ +@item @var{filename}\n\ +Record the session in the file named @var{filename}.\n\ @end table\n\ \n\ With no arguments, @code{diary} toggles the current diary state.\n\ +@seealso{history}\n\ @end deftypefn") { octave_value_list retval; @@ -648,9 +654,9 @@ buffers its output and waits until just before the prompt is printed to\n\ flush it to the pager.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{page_screen_output, more, PAGER, PAGER_FLAGS}\n\ @end deftypefn") { @@ -668,9 +674,9 @@ (such as @code{less}---see @ref{Installation}) are also capable of moving\n\ backward on the output.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{more, page_output_immediately, PAGER, PAGER_FLAGS}\n\ @end deftypefn") { @@ -684,13 +690,13 @@ @deftypefnx {Built-in Function} {} PAGER (@var{new_val}, \"local\")\n\ Query or set the internal variable that specifies the program to use\n\ to display terminal output on your system. The default value is\n\ -normally @code{\"less\"}, @code{\"more\"}, or\n\ -@code{\"pg\"}, depending on what programs are installed on your system.\n\ +normally @qcode{\"less\"}, @qcode{\"more\"}, or\n\ +@qcode{\"pg\"}, depending on what programs are installed on your system.\n\ @xref{Installation}.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{PAGER_FLAGS, page_output_immediately, more, page_screen_output}\n\ @end deftypefn") { @@ -705,9 +711,9 @@ Query or set the internal variable that specifies the options to pass\n\ to the pager.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{PAGER, more, page_screen_output, page_output_immediately}\n\ @end deftypefn") { diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/pinv.cc --- a/libinterp/corefcn/pinv.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/pinv.cc Sat Oct 05 11:22:09 2013 -0400 @@ -172,12 +172,12 @@ /* %!shared a, b, tol, hitol, d, u, x, y -%! a = reshape (rand*[1:16], 4, 4); ## Rank 2 matrix +%! a = reshape (rand*[1:16], 4, 4); # Rank 2 matrix %! b = pinv (a); %! tol = 4e-14; %! hitol = 40*sqrt (eps); %! d = diag ([rand, rand, hitol, hitol]); -%! u = rand (4); ## Could be singular by freak accident +%! u = rand (4); # Could be singular by freak accident %! x = inv (u)*d*u; %! y = pinv (x, sqrt (eps)); %! diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/pr-output.cc --- a/libinterp/corefcn/pr-output.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/pr-output.cc Sat Oct 05 11:22:09 2013 -0400 @@ -493,7 +493,7 @@ for (octave_idx_type i = 0; i < nr; i++) { double val = m(i,j); - if (xisinf (val) || xisnan (val)) + if (! xfinite (val)) continue; all_inf_or_nan = false; @@ -522,7 +522,7 @@ for (octave_idx_type i = 0; i < nr; i++) { double val = m(i,j); - if (xisinf (val) || xisnan (val)) + if (xfinite (val)) continue; all_inf_or_nan = false; @@ -998,11 +998,9 @@ double r_abs = rp < 0.0 ? -rp : rp; double i_abs = ip < 0.0 ? -ip : ip; - int r_x = (xisinf (rp) || xisnan (rp) || r_abs == 0.0) - ? 0 : num_digits (r_abs); - - int i_x = (xisinf (ip) || xisnan (ip) || i_abs == 0.0) - ? 0 : num_digits (i_abs); + int r_x = (! xfinite (rp) || r_abs == 0.0) ? 0 : num_digits (r_abs); + + int i_x = (! xfinite (ip) || i_abs == 0.0) ? 0 : num_digits (i_abs); int x_max, x_min; @@ -1461,9 +1459,6 @@ // Unless explicitly asked for, always print in big-endian // format. - // FIXME -- is it correct to swap bytes for VAX - // formats and not for Cray? - // FIXME -- will bad things happen if we are // interrupted before resetting the format flags and fill // character? @@ -1477,9 +1472,7 @@ = os.flags (std::ios::right | std::ios::hex); if (hex_format > 1 - || flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian - || flt_fmt == oct_mach_info::flt_fmt_cray - || flt_fmt == oct_mach_info::flt_fmt_unknown) + || flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian) { for (size_t i = 0; i < sizeof (double); i++) os << std::setw (2) << static_cast (tmp.i[i]); @@ -1498,15 +1491,10 @@ equiv tmp; tmp.d = d; - // FIXME -- is it correct to swap bytes for VAX - // formats and not for Cray? - oct_mach_info::float_format flt_fmt = oct_mach_info::native_float_format (); - if (flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian - || flt_fmt == oct_mach_info::flt_fmt_cray - || flt_fmt == oct_mach_info::flt_fmt_unknown) + if (flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian) { for (size_t i = 0; i < sizeof (double); i++) PRINT_CHAR_BITS (os, tmp.i[i]); @@ -3805,7 +3793,7 @@ @samp{e} format if it is unable to format a matrix properly using the\n\ current format.\n\ \n\ -@item short e\n\ +@item short e\n\ @itemx long e\n\ Exponential format. The number to be represented is split between a mantissa\n\ and an exponent (power of 10). The mantissa has 5 significant digits in the\n\ @@ -3813,14 +3801,14 @@ For example, with the @samp{short e} format, @code{pi} is displayed as\n\ @code{3.1416e+00}.\n\ \n\ -@item short E\n\ +@item short E\n\ @itemx long E\n\ Identical to @samp{short e} or @samp{long e} but displays an uppercase\n\ @samp{E} to indicate the exponent.\n\ For example, with the @samp{long E} format, @code{pi} is displayed as\n\ @code{3.14159265358979E+00}.\n\ \n\ -@item short g\n\ +@item short g\n\ @itemx long g\n\ Optimally choose between fixed point and exponential format based on\n\ the magnitude of the number.\n\ @@ -3839,19 +3827,19 @@ @end group\n\ @end example\n\ \n\ -@item short eng\n\ +@item short eng\n\ @itemx long eng\n\ Identical to @samp{short e} or @samp{long e} but displays the value\n\ using an engineering format, where the exponent is divisible by 3. For\n\ example, with the @samp{short eng} format, @code{10 * pi} is displayed as\n\ @code{31.4159e+00}.\n\ \n\ -@item long G\n\ +@item long G\n\ @itemx short G\n\ Identical to @samp{short g} or @samp{long g} but displays an uppercase\n\ @samp{E} to indicate the exponent.\n\ \n\ -@item free\n\ +@item free\n\ @itemx none\n\ Print output in free format, without trying to line up columns of\n\ matrices on the decimal point. This also causes complex numbers to be\n\ @@ -3984,9 +3972,9 @@ this reason, you should be careful when setting\n\ @code{fixed_point_format} to a nonzero value.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{format, output_max_field_width, output_precision}\n\ @end deftypefn") { @@ -4013,9 +4001,9 @@ ans = [](3x0)\n\ @end example\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{format}\n\ @end deftypefn") { @@ -4051,9 +4039,9 @@ @end group\n\ @end example\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{format}\n\ @end deftypefn") { @@ -4068,9 +4056,9 @@ Query or set the internal variable that specifies the maximum width\n\ of a numeric output field.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{format, fixed_point_format, output_precision}\n\ @end deftypefn") { @@ -4086,9 +4074,9 @@ Query or set the internal variable that specifies the minimum number of\n\ significant figures to display for numeric output.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{format, fixed_point_format, output_max_field_width}\n\ @end deftypefn") { diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/pt-jit.cc --- a/libinterp/corefcn/pt-jit.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/pt-jit.cc Sat Oct 05 11:22:09 2013 -0400 @@ -44,19 +44,43 @@ static bool Vjit_enable = true; +static int Vjit_startcnt = 1000; + #include #include #include #include -#include #include #include +#include + +#ifdef HAVE_LLVM_IR_FUNCTION_H +#include +#include +#else +#include #include -#include +#endif + +#ifdef HAVE_LLVM_SUPPORT_IRBUILDER_H #include +#elif defined(HAVE_LLVM_IR_IRBUILDER_H) +#include +#else +#include +#endif + #include #include + +#ifdef HAVE_LLVM_IR_DATALAYOUT_H +#include +#elif defined(HAVE_LLVM_DATALAYOUT_H) +#include +#else #include +#endif + #include #include @@ -1868,7 +1892,11 @@ module_pass_manager->add (llvm::createAlwaysInlinerPass ()); pass_manager = new llvm::FunctionPassManager (module); - pass_manager->add (new llvm::TargetData(*engine->getTargetData ())); +#ifdef HAVE_LLVM_DATALAYOUT + pass_manager->add (new llvm::DataLayout (*engine->getDataLayout ())); +#else + pass_manager->add (new llvm::TargetData (*engine->getTargetData ())); +#endif pass_manager->add (llvm::createCFGSimplificationPass ()); pass_manager->add (llvm::createBasicAliasAnalysisPass ()); pass_manager->add (llvm::createPromoteMemoryToRegisterPass ()); @@ -1886,8 +1914,6 @@ bool tree_jit::do_execute (tree_simple_for_command& cmd, const octave_value& bounds) { - const size_t MIN_TRIP_COUNT = 1000; - size_t tc = trip_count (bounds); if (! tc || ! initialize () || ! enabled ()) return false; @@ -1898,7 +1924,7 @@ jit_info *info = cmd.get_info (); if (! info || ! info->match (extra_vars)) { - if (tc < MIN_TRIP_COUNT) + if (tc < static_cast (Vjit_startcnt)) return false; delete info; @@ -2296,10 +2322,10 @@ Query or set the internal variable that determines whether\n\ debugging/tracing is enabled for Octave's JIT compiler.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ -@seealso{jit_enable}\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ +@seealso{jit_enable, jit_startcnt}\n\ @end deftypefn") { #if defined (HAVE_LLVM) @@ -2317,10 +2343,10 @@ @deftypefnx {Built-in Function} {} jit_enable (@var{new_val}, \"local\")\n\ Query or set the internal variable that enables Octave's JIT compiler.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ -@seealso{debug_jit}\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ +@seealso{jit_startcnt, debug_jit}\n\ @end deftypefn") { #if defined (HAVE_LLVM) @@ -2331,369 +2357,27 @@ #endif } -/* -Test some simple cases that compile. - -%!test -%! for i=1:1e6 -%! if i < 5 -%! break -%! else -%! break -%! endif -%! endfor -%! assert (i, 1); - -%!test -%! while 1 -%! if 1 -%! break -%! else -%! break -%! endif -%! endwhile - -%!test -%! for i=1:1e6 -%! if i == 100 -%! break -%! endif -%! endfor -%! assert (i, 100); - -%!test -%! inc = 1e-5; -%! result = 0; -%! for ii = 0:inc:1 -%! result = result + inc * (1/3 * ii * ii); -%! endfor -%! assert (abs (result - 1/9) < 1e-5); - -%!test -%! inc = 1e-5; -%! result = 0; -%! for ii = 0:inc:1 -%! # the ^ operator's result is complex -%! result = result + inc * (1/3 * ii ^ 2); -%! endfor -%! assert (abs (result - 1/9) < 1e-5); - -%!test -%! temp = 1+1i; -%! nan = NaN; -%! while 1 -%! temp = temp - 1i; -%! temp = temp * nan; -%! break; -%! endwhile -%! assert (imag (temp), 0); - -%!test -%! temp = 1+1i; -%! nan = NaN+1i; -%! while 1 -%! nan = nan - 1i; -%! temp = temp - 1i; -%! temp = temp * nan; -%! break; -%! endwhile -%! assert (imag (temp), 0); - -%!test -%! temp = 1+1i; -%! while 1 -%! temp = temp * 5; -%! break; -%! endwhile -%! assert (temp, 5+5i); - -%!test -%! nr = 1001; -%! mat = zeros (1, nr); -%! for i = 1:nr -%! mat(i) = i; -%! endfor -%! assert (mat == 1:nr); - -%!test -%! nr = 1001; -%! mat = 1:nr; -%! mat(end) = 0; # force mat to a matrix -%! total = 0; -%! for i = 1:nr -%! total = mat(i) + total; -%! endfor -%! assert (sum (mat) == total); - -%!test -%! nr = 1001; -%! mat = [3 1 5]; -%! try -%! for i = 1:nr -%! if i > 500 -%! result = mat(100); -%! else -%! result = i; -%! endif -%! endfor -%! catch -%! end -%! assert (result == 500); - -%!function result = gen_test (n) -%! result = double (rand (1, n) > .01); -%!endfunction - -%!function z = vectorized (A, K) -%! temp = ones (1, K); -%! z = conv (A, temp); -%! z = z > K-1; -%! z = conv (z, temp); -%! z = z(K:end-K+1); -%! z = z >= 1; -%!endfunction - -%!function z = loopy (A, K) -%! z = A; -%! n = numel (A); -%! counter = 0; -%! for ii=1:n -%! if z(ii) -%! counter = counter + 1; -%! else -%! if counter > 0 && counter < K -%! z(ii-counter:ii-1) = 0; -%! endif -%! counter = 0; -%! endif -%! endfor -%! -%! if counter > 0 && counter < K -%! z(end-counter+1:end) = 0; -%! endif -%!endfunction - -%!test -%! test_set = gen_test (10000); -%! assert (all (vectorized (test_set, 3) == loopy (test_set, 3))); - -%!test -%! niter = 1001; -%! i = 0; -%! while (i < niter) -%! i = i + 1; -%! endwhile -%! assert (i == niter); - -%!test -%! niter = 1001; -%! result = 0; -%! m = [5 10]; -%! for i=1:niter -%! result = result + m(end); -%! endfor -%! assert (result == m(end) * niter); - -%!test -%! ndim = 100; -%! result = 0; -%! m = zeros (ndim); -%! m(:) = 1:ndim^2; -%! i = 1; -%! while (i <= ndim) -%! for j = 1:ndim -%! result = result + m(i, j); -%! endfor -%! i = i + 1; -%! endwhile -%! assert (result == sum (sum (m))); - -%!test -%! ndim = 100; -%! m = zeros (ndim); -%! i = 1; -%! while (i <= ndim) -%! for j = 1:ndim -%! m(i, j) = (j - 1) * ndim + i; -%! endfor -%! i = i + 1; -%! endwhile -%! m2 = zeros (ndim); -%! m2(:) = 1:(ndim^2); -%! assert (all (m == m2)); - -%!test -%! ndim = 2; -%! m = zeros (ndim, ndim, ndim, ndim); -%! result = 0; -%! i0 = 1; -%! while (i0 <= ndim) -%! for i1 = 1:ndim -%! for i2 = 1:ndim -%! for i3 = 1:ndim -%! m(i0, i1, i2, i3) = 1; -%! m(i0, i1, i2, i3, 1, 1, 1, 1, 1, 1) = 1; -%! result = result + m(i0, i1, i2, i3); -%! endfor -%! endfor -%! endfor -%! i0 = i0 + 1; -%! endwhile -%! expected = ones (ndim, ndim, ndim, ndim); -%! assert (all (m == expected)); -%! assert (result == sum (expected (:))); - -%!function test_divide () -%! state = warning ("query", "Octave:divide-by-zero").state; -%! unwind_protect -%! warning ("error", "Octave:divide-by-zero"); -%! for i=1:1e5 -%! a = 1; -%! a / 0; -%! endfor -%! unwind_protect_cleanup -%! warning (state, "Octave:divide-by-zero"); -%! end_unwind_protect -%!endfunction - -%!error test_divide () - -%!test -%! while 1 -%! a = 0; -%! result = a / 1; -%! break; -%! endwhile -%! assert (result, 0); - -%!test -%! m = zeros (2, 1001); -%! for i=1:1001 -%! m(end, i) = i; -%! m(end - 1, end - i + 1) = i; -%! endfor -%! m2 = zeros (2, 1001); -%! m2(1, :) = fliplr (1:1001); -%! m2(2, :) = 1:1001; -%! assert (m, m2); - -%!test -%! m = [1 2 3]; -%! for i=1:1001 -%! m = sin (m); -%! break; -%! endfor -%! assert (m == sin ([1 2 3])); - -%!test -%! i = 0; -%! while i < 10 -%! i += 1; -%! endwhile -%! assert (i == 10); - -%!test -%! i = 0; -%! while i < 10 -%! a = ++i; -%! endwhile -%! assert (i == 10); -%! assert (a == 10); -%!test -%! i = 0; -%! while i < 10 -%! a = i++; -%! endwhile -%! assert (i == 10); -%! assert (a == 9); - -%!test -%! num = 2; -%! a = zeros (1, num); -%! i = 1; -%! while i <= num -%! a(i) = norm (eye (i)); -%! ++i; -%! endwhile -%! assert (a, ones (1, num)); - -%!function test_compute_idom () -%! while (li <= length (l1) && si <= length (s1)) -%! if (l1 (li) < s1 (si)) -%! if (li == si) -%! break; -%! endif; -%! li++; -%! else -%! si++; -%! endif; -%! endwhile - -%!error test_compute_idom () - -%!function x = test_overload (a) -%! while 1 -%! x = a; -%! break; -%! endwhile -%!endfunction - -%!assert (test_overload (1), 1); -%!assert (test_overload ([1 2]), [1 2]); - -%!function a = bubble (a = [3 2 1]) -%! swapped = 1; -%! n = length (a); -%! while (swapped) -%! swapped = 0; -%! for i = 1:n-1 -%! if a(i) > a(i + 1) -%! swapped = 1; -%! temp = a(i); -%! a(i) = a(i + 1); -%! a(i + 1) = temp; -%! endif -%! endfor -%! endwhile -%!endfunction - -%!assert (bubble (), [1 2 3]); - -%!test -%! a = 0; -%! b = 1; -%! for i=1:1e3 -%! for j=1:2 -%! a = a + b; -%! endfor -%! endfor -%! assert (a, 2000); -%! assert (b, 1); - -%!test -%! a = [1+1i 1+2i]; -%! b = 0; -%! while 1 -%! b = a(1); -%! break; -%! endwhile -%! assert (b, a(1)); - -%!function test_undef () -%! for i=1:1e7 -%! XXX; -%! endfor -%!endfunction - -%!error (test_undef); - -%!shared id -%! id = @(x) x; - -%!assert (id (1), 1); -%!assert (id (1+1i), 1+1i) -%!assert (id (1, 2), 1) -%!error (id ()) - - -*/ +DEFUN (jit_startcnt, args, nargout, + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {@var{val} =} jit_startcnt ()\n\ +@deftypefnx {Built-in Function} {@var{old_val} =} jit_startcnt (@var{new_val})\n\ +@deftypefnx {Built-in Function} {} jit_startcnt (@var{new_val}, \"local\")\n\ +Query or set the internal variable that determines whether JIT compilation\n\ +will take place for a specific loop. Because compilation is a costly\n\ +operation it does not make sense to employ JIT when the loop count is low.\n\ +By default only loops with greater than 1000 iterations will be accelerated.\n\ +\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ +@seealso{jit_enable, debug_jit}\n\ +@end deftypefn") +{ +#if defined (HAVE_LLVM) + return SET_INTERNAL_VARIABLE_WITH_LIMITS (jit_startcnt, 1, + std::numeric_limits::max ()); +#else + warning ("jit_enable: JIT compiling not available in this version of Octave"); + return octave_value (); +#endif +} diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/qz.cc --- a/libinterp/corefcn/qz.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/qz.cc Sat Oct 05 11:22:09 2013 -0400 @@ -346,20 +346,20 @@ of the revised pencil contains all eigenvalues that satisfy:\n\ \n\ @table @asis\n\ -@item \"N\"\n\ +@item @qcode{\"N\"}\n\ = unordered (default)\n\ \n\ -@item \"S\"\n\ +@item @qcode{\"S\"}\n\ = small: leading block has all |lambda| @leq{} 1\n\ \n\ -@item \"B\"\n\ +@item @qcode{\"B\"}\n\ = big: leading block has all |lambda| @geq{} 1\n\ \n\ -@item \"-\"\n\ +@item @qcode{\"-\"}\n\ = negative real part: leading block has all eigenvalues\n\ in the open left half-plane\n\ \n\ -@item \"+\"\n\ +@item @qcode{\"+\"}\n\ = non-negative real part: leading block has all eigenvalues\n\ in the closed right half-plane\n\ @end table\n\ @@ -367,9 +367,9 @@ @end enumerate\n\ \n\ Note: @code{qz} performs permutation balancing, but not scaling\n\ -(@pxref{docXbalance}). The order of output arguments was selected for\n\ +(@pxref{XREFbalance}). The order of output arguments was selected for\n\ compatibility with @sc{matlab}.\n\ -@seealso{balance, eig, schur}\n\ +@seealso{eig, balance, lu, chol, hess, qr, qzhess, schur, svd}\n\ @end deftypefn") { octave_value_list retval; diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/rand.cc --- a/libinterp/corefcn/rand.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/rand.cc Sat Oct 05 11:22:09 2013 -0400 @@ -49,7 +49,7 @@ /* %!shared __random_statistical_tests__ -%! # Flag whether the statistical tests should be run in "make check" or not +%! ## Flag whether the statistical tests should be run in "make check" or not %! __random_statistical_tests__ = 0; */ @@ -424,7 +424,7 @@ random numbers with a significantly longer cycle time. However, in\n\ some circumstances it might be desirable to obtain the same random\n\ sequences as used by the old generators. To do this the keyword\n\ -\"seed\" is used to specify that the old generators should be use,\n\ +@qcode{\"seed\"} is used to specify that the old generators should be use,\n\ as in\n\ \n\ @example\n\ @@ -442,13 +442,15 @@ However, it should be noted that querying the seed will not cause\n\ @code{rand} to use the old generators, only setting the seed will.\n\ To cause @code{rand} to once again use the new generators, the\n\ -keyword \"state\" should be used to reset the state of the @code{rand}.\n\ +keyword @qcode{\"state\"} should be used to reset the state of the\n\ +@code{rand}.\n\ \n\ The state or seed of the generator can be reset to a new random value\n\ -using the \"reset\" keyword.\n\ +using the @qcode{\"reset\"} keyword.\n\ \n\ -The class of the value returned can be controlled by a trailing \"double\"\n\ -or \"single\" argument. These are the only valid classes.\n\ +The class of the value returned can be controlled by a trailing\n\ +@qcode{\"double\"} or @qcode{\"single\"} argument. These are the only valid\n\ +classes.\n\ @seealso{randn, rande, randg, randp}\n\ @end deftypefn") { @@ -500,16 +502,16 @@ /* %!test -%! # Test fixed state +%! ## Test fixed state %! rand ("state", 1); %! assert (rand (1,6), [0.1343642441124013 0.8474337369372327 0.763774618976614 0.2550690257394218 0.495435087091941 0.4494910647887382], 1e-6); %!test -%! # Test fixed seed +%! ## Test fixed seed %! rand ("seed", 1); %! assert (rand (1,6), [0.8668024251237512 0.9126510815694928 0.09366085007786751 0.1664607301354408 0.7408077004365623 0.7615650338120759], 1e-6); %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally. +%! ## statistical tests may fail occasionally. %! rand ("state", 12); %! x = rand (100000, 1); %! assert (max (x) < 1); #*** Please report this!!! *** @@ -521,7 +523,7 @@ %! endif %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally. +%! ## statistical tests may fail occasionally. %! rand ("seed", 12); %! x = rand (100000, 1); %! assert (max (x) < 1); #*** Please report this!!! *** @@ -533,6 +535,19 @@ %! endif */ +/* +%!# Test out-of-range values as rand() seeds. See oct-rand.cc: double2uint32(). +%!function v = __rand_sample__ (initval) +%! rand ("state", initval); +%! v = rand (1, 6); +%!endfunction +%! +%!assert (__rand_sample__ (0), __rand_sample__ (2^32)) +%!assert (__rand_sample__ (-2), __rand_sample__ (2^32-2)) +%!assert (__rand_sample__ (Inf), __rand_sample__ (NaN)) +%!assert (! isequal (__rand_sample__ (-1), __rand_sample__ (-2))) +*/ + static std::string current_distribution = octave_rand::distribution (); DEFUN (randn, args, , @@ -555,8 +570,9 @@ By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique''\n\ to transform from a uniform to a normal distribution.\n\ \n\ -The class of the value returned can be controlled by a trailing \"double\"\n\ -or \"single\" argument. These are the only valid classes.\n\ +The class of the value returned can be controlled by a trailing\n\ +@qcode{\"double\"} or @qcode{\"single\"} argument. These are the only valid\n\ +classes.\n\ \n\ Reference: G. Marsaglia and W.W. Tsang,\n\ @cite{Ziggurat Method for Generating Random Variables},\n\ @@ -577,16 +593,16 @@ /* %!test -%! # Test fixed state +%! ## Test fixed state %! randn ("state", 1); %! assert (randn (1, 6), [-2.666521678978671 -0.7381719971724564 1.507903992673601 0.6019427189162239 -0.450661261143348 -0.7054431351574116], 1e-6); %!test -%! # Test fixed seed +%! ## Test fixed seed %! randn ("seed", 1); %! assert (randn (1, 6), [-1.039402365684509 -1.25938892364502 0.1968704611063004 0.3874166905879974 -0.5976632833480835 -0.6615074276924133], 1e-6); %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally. +%! ## statistical tests may fail occasionally. %! randn ("state", 12); %! x = randn (100000, 1); %! assert (mean (x), 0, 0.01); @@ -596,7 +612,7 @@ %! endif %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally. +%! ## statistical tests may fail occasionally. %! randn ("seed", 12); %! x = randn (100000, 1); %! assert (mean (x), 0, 0.01); @@ -625,8 +641,9 @@ By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique''\n\ to transform from a uniform to an exponential distribution.\n\ \n\ -The class of the value returned can be controlled by a trailing \"double\"\n\ -or \"single\" argument. These are the only valid classes.\n\ +The class of the value returned can be controlled by a trailing\n\ +@qcode{\"double\"} or @qcode{\"single\"} argument. These are the only valid\n\ +classes.\n\ \n\ Reference: G. Marsaglia and W.W. Tsang,\n\ @cite{Ziggurat Method for Generating Random Variables},\n\ @@ -647,16 +664,16 @@ /* %!test -%! # Test fixed state +%! ## Test fixed state %! rande ("state", 1); %! assert (rande (1, 6), [3.602973885835625 0.1386190677555021 0.6743112889616958 0.4512830847258422 0.7255744741233175 0.3415969205292291], 1e-6); %!test -%! # Test fixed seed +%! ## Test fixed seed %! rande ("seed", 1); %! assert (rande (1, 6), [0.06492075175653866 1.717980206012726 0.4816154008731246 0.5231300676241517 0.103910739364359 1.668931916356087], 1e-6); %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally +%! ## statistical tests may fail occasionally %! rande ("state", 1); %! x = rande (100000, 1); %! assert (min (x) > 0); # *** Please report this!!! *** @@ -667,7 +684,7 @@ %! endif %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally +%! ## statistical tests may fail occasionally %! rande ("seed", 1); %! x = rande (100000, 1); %! assert (min (x)>0); # *** Please report this!!! *** @@ -771,8 +788,9 @@ \n\ @end table\n\ \n\ -The class of the value returned can be controlled by a trailing \"double\"\n\ -or \"single\" argument. These are the only valid classes.\n\ +The class of the value returned can be controlled by a trailing\n\ +@qcode{\"double\"} or @qcode{\"single\"} argument. These are the only valid\n\ +classes.\n\ @seealso{rand, randn, rande, randp}\n\ @end deftypefn") { @@ -794,49 +812,49 @@ %! assert (randg ([-inf, -1, 0, inf, nan]), [nan, nan, nan, nan, nan]); # *** Please report %!test -%! # Test fixed state +%! ## Test fixed state %! randg ("state", 1); %! assert (randg (0.1, 1, 6), [0.0103951513331241 8.335671459898252e-05 0.00138691397249762 0.000587308416993855 0.495590518784736 2.3921917414795e-12], 1e-6); %!test -%! # Test fixed state +%! ## Test fixed state %! randg ("state", 1); %! assert (randg (0.95, 1, 6), [3.099382433255327 0.3974529788871218 0.644367450750855 1.143261091802246 1.964111762696822 0.04011915547957939], 1e-6); %!test -%! # Test fixed state +%! ## Test fixed state %! randg ("state", 1); %! assert (randg (1, 1, 6), [0.2273389379645993 1.288822625058359 0.2406335209340746 1.218869553370733 1.024649860162554 0.09631230343599533], 1e-6); %!test -%! # Test fixed state +%! ## Test fixed state %! randg ("state", 1); %! assert (randg (10, 1, 6), [3.520369644331133 15.15369864472106 8.332112081991205 8.406211067432674 11.81193475187611 10.88792728177059], 1e-5); %!test -%! # Test fixed state +%! ## Test fixed state %! randg ("state", 1); %! assert (randg (100, 1, 6), [75.34570255262264 115.4911985594699 95.23493031356388 95.48926019250911 106.2397448229803 103.4813150404118], 1e-4); %!test -%! # Test fixed seed +%! ## Test fixed seed %! randg ("seed", 1); %! assert (randg (0.1, 1, 6), [0.07144210487604141 0.460641473531723 0.4749028384685516 0.06823389977216721 0.000293838675133884 1.802567535340305e-12], 1e-6); %!test -%! # Test fixed seed +%! ## Test fixed seed %! randg ("seed", 1); %! assert (randg (0.95, 1, 6), [1.664905071258545 1.879976987838745 1.905677795410156 0.9948706030845642 0.5606933236122131 0.0766092911362648], 1e-6); %!test -%! # Test fixed seed +%! ## Test fixed seed %! randg ("seed", 1); %! assert (randg (1, 1, 6), [0.03512085229158401 0.6488978862762451 0.8114678859710693 0.1666885763406754 1.60791552066803 1.90356981754303], 1e-6); %!test -%! # Test fixed seed +%! ## Test fixed seed %! randg ("seed", 1); %! assert (randg (10, 1, 6), [6.566435813903809 10.11648464202881 10.73162078857422 7.747178077697754 6.278522491455078 6.240195751190186], 1e-5); %!test -%! # Test fixed seed +%! ## Test fixed seed %! randg ("seed", 1); %! assert (randg (100, 1, 6), [89.40208435058594 101.4734725952148 103.4020004272461 93.62763214111328 88.33104705810547 88.1871337890625], 1e-4); %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally. +%! ## statistical tests may fail occasionally. %! randg ("state", 12); %! a = 0.1; %! x = randg (a, 100000, 1); @@ -847,7 +865,7 @@ %! endif %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally. +%! ## statistical tests may fail occasionally. %! randg ("state", 12); %! a = 0.95; %! x = randg (a, 100000, 1); @@ -858,7 +876,7 @@ %! endif %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally. +%! ## statistical tests may fail occasionally. %! randg ("state", 12); %! a = 1; %! x = randg (a, 100000, 1); @@ -869,7 +887,7 @@ %! endif %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally. +%! ## statistical tests may fail occasionally. %! randg ("state", 12); %! a = 10; %! x = randg (a, 100000, 1); @@ -880,7 +898,7 @@ %! endif %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally. +%! ## statistical tests may fail occasionally. %! randg ("state", 12); %! a = 100; %! x = randg (a, 100000, 1); @@ -894,7 +912,7 @@ %!assert (randg ([-inf, -1, 0, inf, nan]), [nan, nan, nan, nan, nan]) # *** Please report %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally. +%! ## statistical tests may fail occasionally. %! randg ("seed", 12); %! a = 0.1; %! x = randg (a, 100000, 1); @@ -905,7 +923,7 @@ %! endif %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally. +%! ## statistical tests may fail occasionally. %! randg ("seed", 12); %! a = 0.95; %! x = randg (a, 100000, 1); @@ -916,7 +934,7 @@ %! endif %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally. +%! ## statistical tests may fail occasionally. %! randg ("seed", 12); %! a = 1; %! x = randg (a, 100000, 1); @@ -927,7 +945,7 @@ %! endif %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally. +%! ## statistical tests may fail occasionally. %! randg ("seed", 12); %! a = 10; %! x = randg (a, 100000, 1); @@ -938,7 +956,7 @@ %! endif %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally. +%! ## statistical tests may fail occasionally. %! randg ("seed", 12); %! a = 100; %! x = randg (a, 100000, 1); @@ -993,8 +1011,9 @@ D 50 p1284, 1994.\n\ @end table\n\ \n\ -The class of the value returned can be controlled by a trailing \"double\"\n\ -or \"single\" argument. These are the only valid classes.\n\ +The class of the value returned can be controlled by a trailing\n\ +@qcode{\"double\"} or @qcode{\"single\"} argument. These are the only valid\n\ +classes.\n\ @seealso{rand, randn, rande, randg}\n\ @end deftypefn") { @@ -1015,33 +1034,33 @@ %! randp ("state", 12); %! assert (randp ([-inf, -1, 0, inf, nan]), [nan, nan, 0, nan, nan]); # *** Please report %!test -%! # Test fixed state +%! ## Test fixed state %! randp ("state", 1); %! assert (randp (5, 1, 6), [5 5 3 7 7 3]) %!test -%! # Test fixed state +%! ## Test fixed state %! randp ("state", 1); %! assert (randp (15, 1, 6), [13 15 8 18 18 15]) %!test -%! # Test fixed state +%! ## Test fixed state %! randp ("state", 1); %! assert (randp (1e9, 1, 6), [999915677 999976657 1000047684 1000019035 999985749 999977692], -1e-6) %!test -%! # Test fixed state +%! ## Test fixed state %! randp ("seed", 1); %! %%assert (randp (5, 1, 6), [8 2 3 6 6 8]) %! assert (randp (5, 1, 5), [8 2 3 6 6]) %!test -%! # Test fixed state +%! ## Test fixed state %! randp ("seed", 1); %! assert (randp (15, 1, 6), [15 16 12 10 10 12]) %!test -%! # Test fixed state +%! ## Test fixed state %! randp ("seed", 1); %! assert (randp (1e9, 1, 6), [1000006208 1000012224 999981120 999963520 999963072 999981440], -1e-6) %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally. +%! ## statistical tests may fail occasionally. %! randp ("state", 12); %! for a = [5, 15, 1e9; 0.03, 0.03, -5e-3; 0.03, 0.03, 0.03] %! x = randp (a (1), 100000, 1); @@ -1054,7 +1073,7 @@ %! endif %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally. +%! ## statistical tests may fail occasionally. %! randp ("state", 12); %! for a = [5, 15, 1e9; 0.03, 0.03, -5e-3; 0.03, 0.03, 0.03] %! x = randp (a(1)*ones (100000, 1), 100000, 1); @@ -1070,7 +1089,7 @@ %! assert (randp ([-inf, -1, 0, inf, nan]), [nan, nan, 0, nan, nan]); # *** Please report %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally. +%! ## statistical tests may fail occasionally. %! randp ("seed", 12); %! for a = [5, 15, 1e9; 0.03, 0.03, -5e-3; 0.03, 0.03, 0.03] %! x = randp (a(1), 100000, 1); @@ -1083,7 +1102,7 @@ %! endif %!test %! if (__random_statistical_tests__) -%! # statistical tests may fail occasionally. +%! ## statistical tests may fail occasionally. %! randp ("seed", 12); %! for a = [5, 15, 1e9; 0.03, 0.03, -5e-3; 0.03, 0.03, 0.03] %! x = randp (a(1)*ones (100000, 1), 100000, 1); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/regexp.cc --- a/libinterp/corefcn/regexp.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/regexp.cc Sat Oct 05 11:22:09 2013 -0400 @@ -33,7 +33,7 @@ #include "base-list.h" #include "oct-locbuf.h" #include "quit.h" -#include "regexp.h" +#include "lo-regexp.h" #include "str-vec.h" #include "defun.h" @@ -70,6 +70,13 @@ retval[i] = '\b'; break; + // Translate \< and \> to PCRE word boundary + case '<': // begin word boundary + case '>': // end word boundary + retval[i] = '\\'; + retval[++i] = 'b'; + break; + #if 0 // FIXME : To be complete, we need to handle \oN, \o{N}. // The PCRE library already handles \N where N @@ -640,11 +647,18 @@ In addition, the following escaped characters have special meaning.\n\ \n\ @table @code\n\ -@item \\b\n\ -Match a word boundary\n\ +\n\ +@item \\d\n\ +Match any digit\n\ \n\ -@item \\B\n\ -Match within a word\n\ +@item \\D\n\ +Match any non-digit\n\ +\n\ +@item \\s\n\ +Match any whitespace character\n\ +\n\ +@item \\S\n\ +Match any non-whitespace character\n\ \n\ @item \\w\n\ Match any word character\n\ @@ -658,21 +672,12 @@ @item \\>\n\ Match the end of a word\n\ \n\ -@item \\s\n\ -Match any whitespace character\n\ -\n\ -@item \\S\n\ -Match any non-whitespace character\n\ -\n\ -@item \\d\n\ -Match any digit\n\ -\n\ -@item \\D\n\ -Match any non-digit\n\ +@item \\B\n\ +Match within a word\n\ @end table\n\ \n\ Implementation Note: For compatibility with @sc{matlab}, ordinary escape\n\ -sequences (e.g., \"\\n\" => newline) are processed in @var{pat}\n\ +sequences (e.g., @qcode{\"\\n\"} => newline) are processed in @var{pat}\n\ regardless of whether @var{pat} has been defined within single quotes. Use\n\ a second backslash to stop interpolation of the escape sequence (e.g.,\n\ \"\\\\n\") or use the @code{regexptranslate} function.\n\ @@ -712,13 +717,13 @@ are\n\ \n\ @multitable @columnfractions 0.2 0.3 0.3 0.2\n\ -@item @tab 'start' @tab @var{s} @tab\n\ -@item @tab 'end' @tab @var{e} @tab\n\ -@item @tab 'tokenExtents' @tab @var{te} @tab\n\ -@item @tab 'match' @tab @var{m} @tab\n\ -@item @tab 'tokens' @tab @var{t} @tab\n\ -@item @tab 'names' @tab @var{nm} @tab\n\ -@item @tab 'split' @tab @var{sp} @tab\n\ +@item @tab @qcode{'start'} @tab @var{s} @tab\n\ +@item @tab @qcode{'end'} @tab @var{e} @tab\n\ +@item @tab @qcode{'tokenExtents'} @tab @var{te} @tab\n\ +@item @tab @qcode{'match'} @tab @var{m} @tab\n\ +@item @tab @qcode{'tokens'} @tab @var{t} @tab\n\ +@item @tab @qcode{'names'} @tab @var{nm} @tab\n\ +@item @tab @qcode{'split'} @tab @var{sp} @tab\n\ @end multitable\n\ \n\ Additional arguments are summarized below.\n\ @@ -777,8 +782,8 @@ @item emptymatch\n\ Return zero-length matches.\n\ \n\ -@code{regexp ('a', 'b*', 'emptymatch'} returns @code{[1 2]} because there are\n\ -zero or more 'b' characters at positions 1 and end-of-string.\n\ +@code{regexp ('a', 'b*', 'emptymatch')} returns @code{[1 2]} because there\n\ +are zero or more @qcode{'b'} characters at positions 1 and end-of-string.\n\ \n\ @end table\n\ @seealso{regexpi, strfind, regexprep}\n\ @@ -920,7 +925,7 @@ ## Tests for named tokens %!test -%! # Parenthesis in named token (ie (int)) causes a problem +%! ## Parenthesis in named token (ie (int)) causes a problem %! assert (regexp ('qwe int asd', ['(?(int))'], 'names'), struct ('typestr', 'int')); %!test @@ -1067,7 +1072,7 @@ \n\ Case insensitive regular expression string matching. Search for @var{pat} in\n\ @var{str} and return the positions and substrings of any matches, or empty\n\ -values if there are none. @xref{docXregexp,,regexp}, for details on the\n\ +values if there are none. @xref{XREFregexp,,regexp}, for details on the\n\ syntax of the search pattern.\n\ @seealso{regexp}\n\ @end deftypefn") @@ -1279,7 +1284,7 @@ Replace occurrences of pattern @var{pat} in @var{string} with @var{repstr}.\n\ \n\ The pattern is a regular expression as documented for @code{regexp}.\n\ -@xref{docXregexp,,regexp}.\n\ +@xref{XREFregexp,,regexp}.\n\ \n\ The replacement string may contain @code{$i}, which substitutes\n\ for the ith set of parentheses in the match string. For example,\n\ @@ -1304,7 +1309,7 @@ @end table\n\ \n\ Implementation Note: For compatibility with @sc{matlab}, ordinary escape\n\ -sequences (e.g., \"\\n\" => newline) are processed in both @var{pat}\n\ +sequences (e.g., @qcode{\"\\n\"} => newline) are processed in both @var{pat}\n\ and @var{repstr} regardless of whether they were defined within single\n\ quotes. Use a second backslash to stop interpolation of the escape sequence\n\ (e.g., \"\\\\n\") or use the @code{regexptranslate} function.\n\ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/schur.cc --- a/libinterp/corefcn/schur.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/schur.cc Sat Oct 05 11:22:09 2013 -0400 @@ -107,7 +107,8 @@ blocks, when appropriate) are the eigenvalues of @var{A} and @var{S}.\n\ \n\ The default for real matrices is a real Schur@tie{}decomposition.\n\ -A complex decomposition may be forced by passing the flag \"complex\".\n\ +A complex decomposition may be forced by passing the flag\n\ +@qcode{\"complex\"}.\n\ \n\ The eigenvalues are optionally ordered along the diagonal according to\n\ the value of @var{opt}. @code{@var{opt} = \"a\"} indicates that all\n\ @@ -123,7 +124,7 @@ The Schur@tie{}decomposition is used to compute eigenvalues of a\n\ square matrix, and has applications in the solution of algebraic\n\ Riccati equations in control (see @code{are} and @code{dare}).\n\ -@seealso{rsf2csf}\n\ +@seealso{rsf2csf, lu, chol, hess, qr, qz, svd}\n\ @end deftypefn") { octave_value_list retval; @@ -305,7 +306,7 @@ $U^{\\dagger} U$ is the identity matrix I.\n\ @end tex\n\ @ifnottex\n\ -@xcode{@var{UR} * @var{TR} * @var{UR}' = @var{U} * @var{T} * @var{U}'} and\n\ +@tcode{@var{UR} * @var{TR} * @var{UR}' = @var{U} * @var{T} * @var{U}'} and\n\ @code{@var{U}' * @var{U}} is the identity matrix I.\n\ @end ifnottex\n\ \n\ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/sighandlers.cc --- a/libinterp/corefcn/sighandlers.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/sighandlers.cc Sat Oct 05 11:22:09 2013 -0400 @@ -577,6 +577,137 @@ } +static pid_t gui_pid = 0; + +static void +gui_driver_sig_handler (int sig) +{ + if (gui_pid > 0) + octave_syscalls::kill (gui_pid, sig); +} + +void +install_gui_driver_signal_handlers (pid_t pid) +{ + gui_pid = pid; + +#ifdef SIGINT + octave_set_signal_handler (SIGINT, gui_driver_sig_handler); +#endif + +#ifdef SIGBREAK + octave_set_signal_handler (SIGBREAK, gui_driver_sig_handler); +#endif + +#ifdef SIGABRT + octave_set_signal_handler (SIGABRT, gui_driver_sig_handler); +#endif + +#ifdef SIGALRM + octave_set_signal_handler (SIGALRM, gui_driver_sig_handler); +#endif + +#ifdef SIGBUS + octave_set_signal_handler (SIGBUS, gui_driver_sig_handler); +#endif + + // SIGCHLD + // SIGCLD + // SIGCONT + +#ifdef SIGEMT + octave_set_signal_handler (SIGEMT, gui_driver_sig_handler); +#endif + +#ifdef SIGFPE + octave_set_signal_handler (SIGFPE, gui_driver_sig_handler); +#endif + +#ifdef SIGHUP + octave_set_signal_handler (SIGHUP, gui_driver_sig_handler); +#endif + +#ifdef SIGILL + octave_set_signal_handler (SIGILL, gui_driver_sig_handler); +#endif + + // SIGINFO + // SIGINT + +#ifdef SIGIOT + octave_set_signal_handler (SIGIOT, gui_driver_sig_handler); +#endif + +#ifdef SIGLOST + octave_set_signal_handler (SIGLOST, gui_driver_sig_handler); +#endif + +#ifdef SIGPIPE + octave_set_signal_handler (SIGPIPE, gui_driver_sig_handler); +#endif + +#ifdef SIGPOLL + octave_set_signal_handler (SIGPOLL, gui_driver_sig_handler); +#endif + + // SIGPROF + // SIGPWR + +#ifdef SIGQUIT + octave_set_signal_handler (SIGQUIT, gui_driver_sig_handler); +#endif + +#ifdef SIGSEGV + octave_set_signal_handler (SIGSEGV, gui_driver_sig_handler); +#endif + + // SIGSTOP + +#ifdef SIGSYS + octave_set_signal_handler (SIGSYS, gui_driver_sig_handler); +#endif + +#ifdef SIGTERM + octave_set_signal_handler (SIGTERM, gui_driver_sig_handler); +#endif + +#ifdef SIGTRAP + octave_set_signal_handler (SIGTRAP, gui_driver_sig_handler); +#endif + + // SIGTSTP + // SIGTTIN + // SIGTTOU + // SIGURG + +#ifdef SIGUSR1 + octave_set_signal_handler (SIGUSR1, gui_driver_sig_handler); +#endif + +#ifdef SIGUSR2 + octave_set_signal_handler (SIGUSR2, gui_driver_sig_handler); +#endif + +#ifdef SIGVTALRM + octave_set_signal_handler (SIGVTALRM, gui_driver_sig_handler); +#endif + +#ifdef SIGIO + octave_set_signal_handler (SIGIO, gui_driver_sig_handler); +#endif + + // SIGWINCH + +#ifdef SIGXCPU + octave_set_signal_handler (SIGXCPU, gui_driver_sig_handler); +#endif + +#ifdef SIGXFSZ + octave_set_signal_handler (SIGXFSZ, gui_driver_sig_handler); +#endif + +} + static octave_scalar_map make_sig_struct (void) { @@ -908,9 +1039,9 @@ generated with @kbd{C-c}). If a second interrupt signal is received\n\ before reaching the debugging mode, a normal interrupt will occur.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{debug_on_error, debug_on_warning}\n\ @end deftypefn") { @@ -935,12 +1066,12 @@ @deftypefnx {Built-in Function} {@var{old_val} =} sighup_dumps_octave_core (@var{new_val})\n\ @deftypefnx {Built-in Function} {} sighup_dumps_octave_core (@var{new_val}, \"local\")\n\ Query or set the internal variable that controls whether Octave tries\n\ -to save all current variables to the file \"octave-workspace\" if it receives\n\ -a hangup signal.\n\ +to save all current variables to the file @file{octave-workspace} if it\n\ +receives a hangup signal.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @end deftypefn") { return SET_INTERNAL_VARIABLE (sighup_dumps_octave_core); @@ -964,12 +1095,12 @@ @deftypefnx {Built-in Function} {@var{old_val} =} sigterm_dumps_octave_core (@var{new_val})\n\ @deftypefnx {Built-in Function} {} sigterm_dumps_octave_core (@var{new_val}, \"local\")\n\ Query or set the internal variable that controls whether Octave tries\n\ -to save all current variables to the file \"octave-workspace\" if it receives\n\ -a terminate signal.\n\ +to save all current variables to the file @file{octave-workspace} if it\n\ +receives a terminate signal.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @end deftypefn") { return SET_INTERNAL_VARIABLE (sigterm_dumps_octave_core); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/sighandlers.h --- a/libinterp/corefcn/sighandlers.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/sighandlers.h Sat Oct 05 11:22:09 2013 -0400 @@ -71,6 +71,8 @@ extern OCTINTERP_API void install_signal_handlers (void); +extern OCTINTERP_API void install_gui_driver_signal_handlers (pid_t pid); + extern OCTINTERP_API void octave_signal_handler (void); extern OCTINTERP_API octave_interrupt_handler octave_catch_interrupts (void); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/sparse.cc --- a/libinterp/corefcn/sparse.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/sparse.cc Sat Oct 05 11:22:09 2013 -0400 @@ -91,8 +91,9 @@ @end group\n\ @end example\n\ \n\ -Given the option \"unique\". if more than two values are specified for the\n\ -same @var{i}, @var{j} indices, the last specified value will be used.\n\ +Given the option @qcode{\"unique\"}, if more than two values are specified\n\ +for the same @var{i}, @var{j} indices, the last specified value will be\n\ +used.\n\ \n\ @code{sparse (@var{m}, @var{n})} is equivalent to\n\ @code{sparse ([], [], [], @var{m}, @var{n}, 0)}\n\ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/spparms.cc --- a/libinterp/corefcn/spparms.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/spparms.cc Sat Oct 05 11:22:09 2013 -0400 @@ -97,9 +97,9 @@ The value of individual keys can be set with\n\ @code{spparms (@var{key}, @var{val})}.\n\ The default values can be restored with the special keyword\n\ -\"defaults\". The special keyword \"tight\" can be used to set the mmd\n\ -solvers to attempt a sparser solution at the potential cost of longer\n\ -running time.\n\ +@qcode{\"defaults\"}. The special keyword @qcode{\"tight\"} can be used to\n\ +set the mmd solvers to attempt a sparser solution at the potential cost of\n\ +longer running time.\n\ @end deftypefn") { octave_value_list retval; diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/sqrtm.cc --- a/libinterp/corefcn/sqrtm.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/sqrtm.cc Sat Oct 05 11:22:09 2013 -0400 @@ -272,5 +272,5 @@ %! z = eye (4); z(2,2) = z(3,3) = 2^-13; z(1,4) = 0.5; %! [y, err] = sqrtm (x); %! assert (y, z); -%! assert (err, 0); ## Yes, this one has to hold exactly +%! assert (err, 0); # Yes, this one has to hold exactly */ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/str2double.cc --- a/libinterp/corefcn/str2double.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/str2double.cc Sat Oct 05 11:22:09 2013 -0400 @@ -42,9 +42,11 @@ is_imag_unit (int c) { return c == 'i' || c == 'j'; } -static std::istringstream& -single_num (std::istringstream& is, double& num) +static double +single_num (std::istringstream& is) { + double num; + char c = is.peek (); // Skip spaces. @@ -92,7 +94,7 @@ else is >> num; - return is; + return num; } static std::istringstream& @@ -114,10 +116,10 @@ // Accept leading sign. if (c == '+' || c == '-') { + have_sign = true; negative = c == '-'; is.get (); c = is.peek (); - have_sign = true; } // Skip spaces after sign. @@ -138,13 +140,11 @@ { // just 'i' and string is finished. Return immediately. imag = true; - num = 1.0; - if (negative) - num = -num; + num = negative ? -1.0 : 1.0; return is; } else - { + { if (std::tolower (c) != 'n') imag = true; is.unget (); @@ -152,7 +152,7 @@ } else if (c == 'j') imag = true; - + // It's i*num or just i if (imag) { @@ -169,7 +169,7 @@ { // Multiplier follows, we extract it as a number. is.get (); - single_num (is, num); + num = single_num (is); if (is.good ()) c = is.peek (); } @@ -179,7 +179,7 @@ else { // It's num, num*i, or numi. - single_num (is, num); + num = single_num (is); if (is.good ()) { c = is.peek (); @@ -265,10 +265,9 @@ std::string str = str_arg; - // FIXME -- removing all commas does too much... - std::string::iterator se = str.end (); - se = std::remove (str.begin (), se, ','); - str.erase (se, str.end ()); + // FIXME: removing all commas doesn't allow actual parsing. + // Example: "1,23.45" is wrong, but passes Octave. + str.erase (std::remove (str.begin (), str.end(), ','), str.end ()); std::istringstream is (str); double num; @@ -300,7 +299,7 @@ Convert a string to a real or complex number.\n\ \n\ The string must be in one of the following formats where\n\ -a and b are real numbers and the complex unit is 'i' or 'j':\n\ +a and b are real numbers and the complex unit is @qcode{'i'} or @qcode{'j'}:\n\ \n\ @itemize\n\ @item a + bi\n\ @@ -317,17 +316,24 @@ @end itemize\n\ \n\ If present, a and/or b are of the form @nospell{[+-]d[,.]d[[eE][+-]d]} where\n\ -the brackets indicate optional arguments and 'd' indicates zero or more\n\ -digits. The special input values @code{Inf}, @code{NaN}, and @code{NA} are\n\ -also accepted.\n\ +the brackets indicate optional arguments and @qcode{'d'} indicates zero or\n\ +more digits. The special input values @code{Inf}, @code{NaN}, and @code{NA}\n\ +are also accepted.\n\ \n\ -@var{s} may also be a character matrix, in which case the conversion is\n\ -repeated for each row. Or @var{s} may be a cell array of strings, in which\n\ -case each element is converted and an array of the same dimensions is\n\ -returned.\n\ +@var{s} may be a character string, character matrix, or cell array.\n\ +For character arrays the conversion is repeated for every row, and\n\ +a double or complex array is returned. Empty rows in @var{s} are deleted\n\ +and not returned in the numeric array. For cell arrays each character\n\ +string element is processed and a double or complex array of the same\n\ +dimensions as @var{s} is returned.\n\ \n\ -@code{str2double} returns NaN for elements of @var{s} which cannot be\n\ -converted.\n\ +For unconvertible scalar or character string input @code{str2double} returns\n\ +a NaN@. Similarly, for character array input @code{str2double} returns a\n\ +NaN for any row of @var{s} that could not be converted. For a cell array,\n\ +@code{str2double} returns a NaN for any element of @var{s} for which\n\ +conversion fails. Note that numeric elements in a mixed string/numeric\n\ +cell array are not strings and the conversion will fail for these elements\n\ +and return NaN.\n\ \n\ @code{str2double} can replace @code{str2num}, and it avoids the security\n\ risk of using @code{eval} on unknown data.\n\ @@ -340,7 +346,11 @@ print_usage (); else if (args(0).is_string ()) { - if (args(0).rows () == 1 && args(0).ndims () == 2) + if (args(0).rows () == 0 || args(0).columns () == 0) + { + retval = Matrix (1, 1, octave_NaN); + } + else if (args(0).rows () == 1 && args(0).ndims () == 2) { retval = str2double1 (args(0).string_value ()); } @@ -367,7 +377,7 @@ } } else - retval = NDArray (args(0).dims (), octave_NaN); + retval = Matrix (1, 1, octave_NaN); return retval; @@ -377,7 +387,6 @@ %!assert (str2double ("1"), 1) %!assert (str2double ("-.1e-5"), -1e-6) %!assert (str2double (char ("1", "2 3", "4i")), [1; NaN; 4i]) -%!assert (str2double ("-.1e-5"), -1e-6) %!assert (str2double ("1,222.5"), 1222.5) %!assert (str2double ("i"), i) %!assert (str2double ("2j"), 2i) @@ -402,5 +411,8 @@ %!assert (str2double ("-i*NaN - Inf"), complex (-Inf, -NaN)) %!assert (str2double ({"abc", "4i"}), [NaN + 0i, 4i]) %!assert (str2double ({2, "4i"}), [NaN + 0i, 4i]) -%!assert (str2double (zeros (3,1,2)), NaN (3,1,2)) -*/ +%!assert (str2double (zeros (3,1,2)), NaN) +%!assert (str2double (''), NaN) +%!assert (str2double ([]), NaN) +%!assert (str2double (char(zeros(3,0))), NaN) + */ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/strfind.cc --- a/libinterp/corefcn/strfind.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/strfind.cc Sat Oct 05 11:22:09 2013 -0400 @@ -149,20 +149,29 @@ "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{idx} =} strfind (@var{str}, @var{pattern})\n\ @deftypefnx {Built-in Function} {@var{idx} =} strfind (@var{cellstr}, @var{pattern})\n\ +@deftypefnx {Built-in Function} {@var{idx} =} strfind (@dots{}, \"overlaps\", @var{val})\n\ Search for @var{pattern} in the string @var{str} and return the\n\ starting index of every such occurrence in the vector @var{idx}.\n\ +\n\ If there is no such occurrence, or if @var{pattern} is longer\n\ than @var{str}, then @var{idx} is the empty array @code{[]}.\n\ +The optional argument @qcode{\"overlaps\"} determines whether the pattern\n\ +can match at every position in @var{str} (true), or only for unique\n\ +occurrences of the complete pattern (false). The default is true.\n\ \n\ If a cell array of strings @var{cellstr} is specified\n\ -then @var{idx} is a cell array of vectors, as specified\n\ -above. Examples:\n\ +then @var{idx} is a cell array of vectors, as specified above.\n\ +\n\ +Examples:\n\ \n\ @example\n\ @group\n\ strfind (\"abababa\", \"aba\")\n\ @result{} [1, 3, 5]\n\ \n\ +strfind (\"abababa\", \"aba\", \"overlaps\", false)\n\ + @result{} [1, 5]\n\ +\n\ strfind (@{\"abababa\", \"bebebe\", \"ab\"@}, \"aba\")\n\ @result{}\n\ @{\n\ @@ -321,10 +330,20 @@ DEFUN (strrep, args, , "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {} strrep (@var{s}, @var{ptn}, @var{rep})\n\ -@deftypefnx {Built-in Function} {} strrep (@var{s}, @var{ptn}, @var{rep}, \"overlaps\", @var{o})\n\ -Replace all occurrences of the substring @var{ptn} in the string @var{s}\n\ -with the string @var{rep} and return the result. For example:\n\ +@deftypefn {Built-in Function} {@var{newstr} =} strrep (@var{str}, @var{ptn}, @var{rep})\n\ +@deftypefnx {Built-in Function} {@var{newstr} =} strrep (@var{cellstr}, @var{ptn}, @var{rep})\n\ +@deftypefnx {Built-in Function} {@var{newstr} =} strrep (@dots{}, \"overlaps\", @var{val})\n\ +Replace all occurrences of the pattern @var{ptn} in the string @var{str}\n\ +with the string @var{rep} and return the result.\n\ +\n\ +The optional argument @qcode{\"overlaps\"} determines whether the pattern\n\ +can match at every position in @var{str} (true), or only for unique\n\ +occurrences of the complete pattern (false). The default is true.\n\ +\n\ +@var{s} may also be a cell array of strings, in which case the replacement is\n\ +done for each element and a cell array is returned.\n\ +\n\ +Example:\n\ \n\ @example\n\ @group\n\ @@ -333,8 +352,6 @@ @end group\n\ @end example\n\ \n\ -@var{s} may also be a cell array of strings, in which case the replacement is\n\ -done for each element and a cell array is returned.\n\ @seealso{regexprep, strfind, findstr}\n\ @end deftypefn") { diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/svd.cc --- a/libinterp/corefcn/svd.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/svd.cc Sat Oct 05 11:22:09 2013 -0400 @@ -121,7 +121,7 @@ If given a second argument, @code{svd} returns an economy-sized\n\ decomposition, eliminating the unnecessary rows or columns of @var{U} or\n\ @var{V}.\n\ -@seealso{svd_driver, svds, eig}\n\ +@seealso{svd_driver, svds, eig, lu, chol, hess, qr, qz}\n\ @end deftypefn") { octave_value_list retval; @@ -408,12 +408,12 @@ @deftypefnx {Built-in Function} {@var{old_val} =} svd_driver (@var{new_val})\n\ @deftypefnx {Built-in Function} {} svd_driver (@var{new_val}, \"local\")\n\ Query or set the underlying @sc{lapack} driver used by @code{svd}.\n\ -Currently recognized values are \"gesvd\" and \"gesdd\". The default\n\ -is \"gesvd\".\n\ +Currently recognized values are @qcode{\"gesvd\"} and @qcode{\"gesdd\"}. \n\ +The default is @qcode{\"gesvd\"}.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{svd}\n\ @end deftypefn") { diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/symtab.cc --- a/libinterp/corefcn/symtab.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/symtab.cc Sat Oct 05 11:22:09 2013 -0400 @@ -1594,14 +1594,14 @@ @deftypefnx {Built-in Function} {@var{old_val} =} ignore_function_time_stamp (@var{new_val})\n\ Query or set the internal variable that controls whether Octave checks\n\ the time stamp on files each time it looks up functions defined in\n\ -function files. If the internal variable is set to @code{\"system\"},\n\ +function files. If the internal variable is set to @qcode{\"system\"},\n\ Octave will not automatically recompile function files in subdirectories of\n\ @file{@var{octave-home}/lib/@var{version}} if they have changed since\n\ they were last compiled, but will recompile other function files in the\n\ -search path if they change. If set to @code{\"all\"}, Octave will not\n\ +search path if they change. If set to @qcode{\"all\"}, Octave will not\n\ recompile any function files unless their definitions are removed with\n\ -@code{clear}. If set to \"none\", Octave will always check time stamps\n\ -on files to determine whether functions defined in function files\n\ +@code{clear}. If set to @qcode{\"none\"}, Octave will always check time\n\ +stamps on files to determine whether functions defined in function files\n\ need to recompiled.\n\ @end deftypefn") { diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/symtab.h --- a/libinterp/corefcn/symtab.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/symtab.h Sat Oct 05 11:22:09 2013 -0400 @@ -31,7 +31,7 @@ #include #include "glob-match.h" -#include "regexp.h" +#include "lo-regexp.h" class tree_argument_list; class octave_user_function; diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/syscalls.cc --- a/libinterp/corefcn/syscalls.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/syscalls.cc Sat Oct 05 11:22:09 2013 -0400 @@ -38,6 +38,7 @@ #include +#include "cmd-hist.h" #include "file-ops.h" #include "file-stat.h" #include "oct-env.h" @@ -48,6 +49,7 @@ #include "error.h" #include "gripes.h" #include "lo-utils.h" +#include "oct-hist.h" #include "oct-map.h" #include "oct-obj.h" #include "oct-stdstrm.h" @@ -220,6 +222,11 @@ if (! error_state) { + octave_history_write_timestamp (); + + if (! command_history::ignoring_entries ()) + command_history::clean_up_and_save (); + std::string msg; int status = octave_syscalls::execvp (exec_file, exec_args, msg); @@ -276,7 +283,7 @@ @print{} are\n\ @end example\n\ \n\ -Note that @code{popen2}, unlike @code{popen}, will not \"reap\" the\n\ +Note that @code{popen2}, unlike @code{popen}, will not @qcode{\"reap\"} the\n\ child process. If you don't use @code{waitpid} to check the child's\n\ exit status, it will linger until Octave exits.\n\ @end deftypefn") @@ -742,11 +749,13 @@ DEFUNX ("lstat", Flstat, args, , "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {[@var{info}, @var{err}, @var{msg}] =} lstat (@var{symlink})\n\ +@deftypefn {Built-in Function} {@var{info} =} lstat (@var{symlink})\n\ +@deftypefnx {Built-in Function} {[@var{info}, @var{err}, @var{msg}] =} lstat (@var{symlink})\n\ Return a structure @var{info} containing information about the symbolic link\n\ -@var{symlink}. The function outputs are described in the documentation for\n\ -@code{stat}.\n\ -@seealso{stat}\n\ +@var{symlink}.\n\ +\n\ +The function outputs are described in the documentation for @code{stat}.\n\ +@seealso{stat, symlink}\n\ @end deftypefn") { octave_value_list retval; @@ -770,12 +779,14 @@ DEFUNX ("mkfifo", Fmkfifo, args, , "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} mkfifo (@var{name}, @var{mode})\n\ -Create a @var{fifo} special file named @var{name} with file mode @var{mode}\n\ +@deftypefn {Built-in Function} {} mkfifo (@var{name}, @var{mode})\n\ +@deftypefnx {Built-in Function} {[@var{err}, @var{msg}] =} mkfifo (@var{name}, @var{mode})\n\ +Create a FIFO special file named @var{name} with file mode @var{mode}\n\ \n\ If successful, @var{err} is 0 and @var{msg} is an empty string.\n\ Otherwise, @var{err} is nonzero and @var{msg} contains a\n\ system-dependent error message.\n\ +@seealso{pipe}\n\ @end deftypefn") { octave_value_list retval; @@ -830,6 +841,7 @@ If successful, @var{err} is 0 and @var{msg} is an empty string.\n\ Otherwise, @var{err} is nonzero and @var{msg} contains a\n\ system-dependent error message.\n\ +@seealso{mkfifo}\n\ @end deftypefn") { octave_value_list retval; @@ -893,9 +905,9 @@ \n\ @item mode\n\ File mode, as an integer. Use the functions @w{@code{S_ISREG}},\n\ -@w{@code{S_ISDIR}}, @w{@code{S_ISCHR}}, @w{@code{S_ISBLK}}, @w{@code{S_ISFIFO}},\n\ -@w{@code{S_ISLNK}}, or @w{@code{S_ISSOCK}} to extract information from this\n\ -value.\n\ +@w{@code{S_ISDIR}}, @w{@code{S_ISCHR}}, @w{@code{S_ISBLK}},\n\ +@w{@code{S_ISFIFO}}, @w{@code{S_ISLNK}}, or @w{@code{S_ISSOCK}} to extract\n\ +information from this value.\n\ \n\ @item modestr\n\ File mode, as a string of ten letters or dashes as would be returned by\n\ @@ -968,6 +980,7 @@ @result{} err = 0\n\ @result{} msg =\n\ @end example\n\ +@seealso{lstat, ls, dir}\n\ @end deftypefn") { octave_value_list retval; @@ -1006,8 +1019,9 @@ DEFUNX ("S_ISREG", FS_ISREG, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} S_ISREG (@var{mode})\n\ -Return true if @var{mode} corresponds to a regular file. The value\n\ -of @var{mode} is assumed to be returned from a call to @code{stat}.\n\ +Return true if @var{mode} corresponds to a regular file.\n\ +\n\ +The value of @var{mode} is assumed to be returned from a call to @code{stat}.\n\ @seealso{stat, lstat}\n\ @end deftypefn") { @@ -1031,8 +1045,9 @@ DEFUNX ("S_ISDIR", FS_ISDIR, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} S_ISDIR (@var{mode})\n\ -Return true if @var{mode} corresponds to a directory. The value\n\ -of @var{mode} is assumed to be returned from a call to @code{stat}.\n\ +Return true if @var{mode} corresponds to a directory.\n\ +\n\ +The value of @var{mode} is assumed to be returned from a call to @code{stat}.\n\ @seealso{stat, lstat}\n\ @end deftypefn") { @@ -1056,8 +1071,9 @@ DEFUNX ("S_ISCHR", FS_ISCHR, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} S_ISCHR (@var{mode})\n\ -Return true if @var{mode} corresponds to a character device. The value\n\ -of @var{mode} is assumed to be returned from a call to @code{stat}.\n\ +Return true if @var{mode} corresponds to a character device.\n\ +\n\ +The value of @var{mode} is assumed to be returned from a call to @code{stat}.\n\ @seealso{stat, lstat}\n\ @end deftypefn") { @@ -1081,8 +1097,9 @@ DEFUNX ("S_ISBLK", FS_ISBLK, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} S_ISBLK (@var{mode})\n\ -Return true if @var{mode} corresponds to a block device. The value\n\ -of @var{mode} is assumed to be returned from a call to @code{stat}.\n\ +Return true if @var{mode} corresponds to a block device.\n\ +\n\ +The value of @var{mode} is assumed to be returned from a call to @code{stat}.\n\ @seealso{stat, lstat}\n\ @end deftypefn") { @@ -1106,8 +1123,9 @@ DEFUNX ("S_ISFIFO", FS_ISFIFO, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} S_ISFIFO (@var{mode})\n\ -Return true if @var{mode} corresponds to a fifo. The value\n\ -of @var{mode} is assumed to be returned from a call to @code{stat}.\n\ +Return true if @var{mode} corresponds to a fifo.\n\ +\n\ +The value of @var{mode} is assumed to be returned from a call to @code{stat}.\n\ @seealso{stat, lstat}\n\ @end deftypefn") { @@ -1131,8 +1149,9 @@ DEFUNX ("S_ISLNK", FS_ISLNK, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} S_ISLNK (@var{mode})\n\ -Return true if @var{mode} corresponds to a symbolic link. The value\n\ -of @var{mode} is assumed to be returned from a call to @code{stat}.\n\ +Return true if @var{mode} corresponds to a symbolic link.\n\ +\n\ +The value of @var{mode} is assumed to be returned from a call to @code{stat}.\n\ @seealso{stat, lstat}\n\ @end deftypefn") { @@ -1156,8 +1175,9 @@ DEFUNX ("S_ISSOCK", FS_ISSOCK, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} S_ISSOCK (@var{mode})\n\ -Return true if @var{mode} corresponds to a socket. The value\n\ -of @var{mode} is assumed to be returned from a call to @code{stat}.\n\ +Return true if @var{mode} corresponds to a socket.\n\ +\n\ +The value of @var{mode} is assumed to be returned from a call to @code{stat}.\n\ @seealso{stat, lstat}\n\ @end deftypefn") { diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/toplev.cc --- a/libinterp/corefcn/toplev.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/toplev.cc Sat Oct 05 11:22:09 2013 -0400 @@ -634,6 +634,9 @@ } while (retval == 0); + if (retval == EOF) + retval = 0; + return retval; } @@ -751,7 +754,7 @@ else { if (octave_exit) - (*octave_exit) (retval == EOF ? 0 : retval); + (*octave_exit) (retval); } } @@ -807,8 +810,7 @@ { octave_value_list retval; - octave_stdout << "\n" \ - OCTAVE_NAME_VERSION_AND_COPYRIGHT "\n\ + octave_stdout << "\n" << octave_name_version_and_copyright () << "\n\ \n\ GNU Octave free software; you can redistribute it and/or modify\n\ it under the terms of the GNU General Public License as published by\n\ @@ -913,11 +915,11 @@ @deftypefnx {Built-in Function} {} system (\"@var{string}\", @var{return_output}, @var{type})\n\ @deftypefnx {Built-in Function} {[@var{status}, @var{output}] =} system (@dots{})\n\ Execute a shell command specified by @var{string}.\n\ -If the optional argument @var{type} is \"async\", the process\n\ +If the optional argument @var{type} is @qcode{\"async\"}, the process\n\ is started in the background and the process ID of the child process\n\ is returned immediately. Otherwise, the child process is started and\n\ Octave waits until it exits. If the @var{type} argument is omitted, it\n\ -defaults to the value \"sync\".\n\ +defaults to the value @qcode{\"sync\"}.\n\ \n\ If @var{system} is called with one or more output arguments, or if the\n\ optional argument @var{return_output} is true and the subprocess is started\n\ @@ -1139,7 +1141,7 @@ @end example\n\ \n\ @noindent\n\ -will print the message \"Bye bye\" when Octave exits.\n\ +will print the message @qcode{\"Bye bye\"} when Octave exits.\n\ \n\ The additional argument @var{flag} will register or unregister\n\ @var{fcn} from the list of functions to be called when Octave\n\ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/toplev.h --- a/libinterp/corefcn/toplev.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/toplev.h Sat Oct 05 11:22:09 2013 -0400 @@ -40,6 +40,7 @@ #include "input.h" #include "oct-map.h" +#include "symtab.h" typedef void (*octave_exit_func) (int); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/tril.cc --- a/libinterp/corefcn/tril.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/tril.cc Sat Oct 05 11:22:09 2013 -0400 @@ -386,9 +386,9 @@ @end group\n\ @end example\n\ \n\ -If the option \"pack\" is given as third argument, the extracted elements\n\ -are not inserted into a matrix, but rather stacked column-wise one above\n\ -other.\n\ +If the option @qcode{\"pack\"} is given as third argument, the extracted\n\ +elements are not inserted into a matrix, but rather stacked column-wise one\n\ +above other.\n\ @seealso{diag}\n\ @end deftypefn") { diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/txt-eng-ft.cc --- a/libinterp/corefcn/txt-eng-ft.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/txt-eng-ft.cc Sat Oct 05 11:22:09 2013 -0400 @@ -30,7 +30,11 @@ #include #endif +#include +#include #include +#include +#include #include "singleton-cleanup.h" @@ -38,33 +42,36 @@ #include "pr-output.h" #include "txt-eng-ft.h" -// FIXME -- maybe issue at most one warning per glyph/font/size/weight -// combination. +// FIXME: maybe issue at most one warning per glyph/font/size/weight +// combination. static void -gripe_missing_glyph (char c) +gripe_missing_glyph (FT_ULong c) { warning_with_id ("Octave:missing-glyph", - "ft_render: skipping missing glyph for character '%c'", + "ft_render: skipping missing glyph for character '%x'", c); } static void -gripe_glyph_render (char c) +gripe_glyph_render (FT_ULong c) { warning_with_id ("Octave:glyph-render", - "ft_render: unable to render glyph for character '%c'", + "ft_render: unable to render glyph for character '%x'", c); } #ifdef _MSC_VER -// This is just a trick to avoid multiply symbols definition. +// This is just a trick to avoid multiple symbol definitions. // PermMatrix.h contains a dllexport'ed Array -// that will make MSVC not to generate new instantiation and -// use the imported one. +// that will cause MSVC not to generate a new instantiation and +// use the imported one instead. #include "PermMatrix.h" #endif +// Forward declaration +static void ft_face_destroyed (void* object); + class ft_manager { @@ -99,10 +106,24 @@ ? instance->do_get_font (name, weight, angle, size) : 0); } + static void font_destroyed (FT_Face face) + { + if (instance_ok ()) + instance->do_font_destroyed (face); + } + private: static ft_manager *instance; + typedef std::pair ft_key; + typedef std::map ft_cache; + + // Cache the fonts loaded by freetype. This cache only contains + // weak references to the fonts, strong references are only present + // in class ft_render. + ft_cache cache; + private: // No copying! @@ -133,8 +154,7 @@ FT_Done_FreeType (library); #if defined (HAVE_FONTCONFIG) - // FIXME -- Skip the call to FcFini because it can trigger the - // assertion + // FIXME: Skip the call to FcFini because it can trigger the assertion // // octave: fccache.c:507: FcCacheFini: Assertion 'fcCacheChains[i] == ((void *)0)' failed. // @@ -149,6 +169,20 @@ { FT_Face retval = 0; +#if HAVE_FT_REFERENCE_FACE + // Look first into the font cache, then use fontconfig. If the font + // is present in the cache, simply add a reference and return it. + + ft_key key (name + ":" + weight + ":" + angle, size); + ft_cache::const_iterator it = cache.find (key); + + if (it != cache.end ()) + { + FT_Reference_Face (it->second); + return it->second; + } +#endif + std::string file; #if defined (HAVE_FONTCONFIG) @@ -190,7 +224,7 @@ FcDefaultSubstitute (pat); match = FcFontMatch (0, pat, &res); - // FIXME -- originally, this test also required that + // FIXME: originally, this test also required that // res != FcResultNoMatch. Is that really needed? if (match) { @@ -221,12 +255,42 @@ #endif } - if (! file.empty () && FT_New_Face (library, file.c_str (), 0, &retval)) - ::warning ("ft_manager: unable to load font: %s", file.c_str ()); + if (! file.empty ()) + { + if (FT_New_Face (library, file.c_str (), 0, &retval)) + ::warning ("ft_manager: unable to load font: %s", file.c_str ()); +#if HAVE_FT_REFERENCE_FACE + else + { + // Install a finalizer to notify ft_manager that the font is + // being destroyed. The class ft_manager only keeps weak + // references to font objects. + + retval->generic.data = new ft_key (key); + retval->generic.finalizer = ft_face_destroyed; + + // Insert loaded font into the cache. + + cache[key] = retval; + } +#endif + } return retval; } + void do_font_destroyed (FT_Face face) + { + if (face->generic.data) + { + ft_key* pkey = reinterpret_cast (face->generic.data); + + cache.erase (*pkey); + delete pkey; + face->generic.data = 0; + } + } + private: FT_Library library; bool freetype_initialized; @@ -235,39 +299,164 @@ ft_manager* ft_manager::instance = 0; +static void +ft_face_destroyed (void* object) +{ ft_manager::font_destroyed (reinterpret_cast (object)); } + // --------------------------------------------------------------------------- ft_render::ft_render (void) - : text_processor (), face (0), bbox (1, 4, 0.0), - xoffset (0), yoffset (0), multiline_halign (0), - multiline_align_xoffsets (), mode (MODE_BBOX), - red (0), green (0), blue (0) + : text_processor (), font (), bbox (1, 4, 0.0), halign (0), xoffset (0), + line_yoffset (0), yoffset (0), mode (MODE_BBOX), + color (dim_vector (1, 3), 0) { } ft_render::~ft_render (void) { - if (face) - FT_Done_Face (face); } void ft_render::set_font (const std::string& name, const std::string& weight, const std::string& angle, double size) { - if (face) - FT_Done_Face (face); + // FIXME: take "fontunits" into account + + font = ft_font (name, weight, angle, size, 0); +} + +void +ft_render::push_new_line (void) +{ + switch (mode) + { + case MODE_BBOX: + { + // Create a new bbox entry based on the current font. + + FT_Face face = font.get_face (); + + if (face) + { + int asc = face->size->metrics.ascender >> 6; + int desc = face->size->metrics.descender >> 6; + int h = face->size->metrics.height >> 6; + + Matrix bb (1, 5, 0.0); + + bb(1) = desc; + bb(3) = asc - desc; + bb(4) = h; + + line_bbox.push_back (bb); - // FIXME: take "fontunits" into account - face = ft_manager::get_font (name, weight, angle, size); + xoffset = yoffset = 0; + } + } + break; + + case MODE_RENDER: + { + // Move to the next line bbox, adjust xoffset based on alignment + // and yoffset based on the old and new line bbox. + + Matrix old_bbox = line_bbox.front (); + line_bbox.pop_front (); + Matrix new_bbox = line_bbox.front (); + + xoffset = compute_line_xoffset (new_bbox); + line_yoffset += (old_bbox(1) - (new_bbox(1) + new_bbox(3))); + yoffset = 0; + } + break; + } +} + +int +ft_render::compute_line_xoffset (const Matrix& lb) const +{ + if (! bbox.is_empty ()) + { + switch (halign) + { + case 0: + return 0; + case 1: + return (bbox(2) - lb(2)) / 2; + case 2: + return (bbox(2) - lb(2)); + } + } - if (face) + return 0; +} + +void +ft_render::compute_bbox (void) +{ + // Stack the various line bbox together and compute the final + // bounding box for the entire text string. + + bbox = Matrix (); + + switch (line_bbox.size ()) { - if (FT_Set_Char_Size (face, 0, size*64, 0, 0)) - ::warning ("ft_render: unable to set font size to %d", size); + case 0: + break; + case 1: + bbox = line_bbox.front ().extract (0, 0, 0, 3); + break; + default: + for (std::list::const_iterator it = line_bbox.begin (); + it != line_bbox.end (); ++it) + { + if (bbox.is_empty ()) + bbox = it->extract (0, 0, 0, 3); + else + { + bbox(1) -= (*it)(3); + bbox(3) += (*it)(3); + bbox(2) = xmax (bbox(2), (*it)(2)); + } + } + break; } - else - ::warning ("ft_render: unable to load appropriate font"); +} + +void +ft_render::update_line_bbox (void) +{ + // Called after a font change, when in MODE_BBOX mode, to update the + // current line bbox with the new font metrics. This also includes the + // current yoffset, that is the offset of the current glyph's baseline + // the line's baseline. + + if (mode == MODE_BBOX) + { + int asc = font.get_face ()->size->metrics.ascender >> 6; + int desc = font.get_face ()->size->metrics.descender >> 6; + + Matrix& bb = line_bbox.front (); + + if ((yoffset + desc) < bb(1)) + { + // The new font goes below the bottom of the current bbox. + + int delta = bb(1) - (yoffset + desc); + + bb(1) -= delta; + bb(3) += delta; + } + + if ((yoffset + asc) > (bb(1) + bb(3))) + { + // The new font goes above the top of the current bbox. + + int delta = (yoffset + asc) - (bb(1) + bb(3)); + + bb(3) += delta; + } + } } void @@ -278,23 +467,26 @@ switch (mode) { case MODE_BBOX: - xoffset = yoffset = 0; + xoffset = line_yoffset = yoffset = 0; bbox = Matrix (1, 4, 0.0); + line_bbox.clear (); + push_new_line (); break; case MODE_RENDER: if (bbox.numel () != 4) { ::warning ("ft_render: invalid bounding box, cannot render"); - xoffset = yoffset = 0; + xoffset = line_yoffset = yoffset = 0; pixels = uint8NDArray (); } else { pixels = uint8NDArray (dim_vector (4, bbox(2), bbox(3)), static_cast (0)); - xoffset = 0; - yoffset = -bbox(1)-1; + xoffset = compute_line_xoffset (line_bbox.front ()); + line_yoffset = -bbox(1)-1; + yoffset = 0; } break; default: @@ -303,187 +495,335 @@ } } +FT_UInt +ft_render::process_character (FT_ULong code, FT_UInt previous) +{ + FT_Face face = font.get_face (); + FT_UInt glyph_index = 0; + + if (face) + { + glyph_index = FT_Get_Char_Index (face, code); + + if (code != '\n' + && (! glyph_index + || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT))) + { + glyph_index = 0; + gripe_missing_glyph (code); + } + else + { + switch (mode) + { + case MODE_RENDER: + if (code == '\n') + { + glyph_index = FT_Get_Char_Index (face, ' '); + if (!glyph_index || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT)) + { + glyph_index = 0; + gripe_missing_glyph (' '); + } + else + push_new_line (); + } + else if (FT_Render_Glyph (face->glyph, FT_RENDER_MODE_NORMAL)) + { + glyph_index = 0; + gripe_glyph_render (code); + } + else + { + FT_Bitmap& bitmap = face->glyph->bitmap; + int x0, y0; + + if (previous) + { + FT_Vector delta; + + FT_Get_Kerning (face, previous, glyph_index, FT_KERNING_DEFAULT, &delta); + xoffset += (delta.x >> 6); + } + + x0 = xoffset + face->glyph->bitmap_left; + y0 = line_yoffset + yoffset + face->glyph->bitmap_top; + + // 'w' seems to have a negative -1 + // face->glyph->bitmap_left, this is so we don't + // index out of bound, and assumes we we allocated + // the right amount of horizontal space in the bbox. + if (x0 < 0) + x0 = 0; + + for (int r = 0; r < bitmap.rows; r++) + for (int c = 0; c < bitmap.width; c++) + { + unsigned char pix = bitmap.buffer[r*bitmap.width+c]; + if (x0+c < 0 || x0+c >= pixels.dim2 () + || y0-r < 0 || y0-r >= pixels.dim3 ()) + { + //::warning ("ft_render: pixel out of bound (char=%d, (x,y)=(%d,%d), (w,h)=(%d,%d)", + // str[i], x0+c, y0-r, pixels.dim2 (), pixels.dim3 ()); + } + else if (pixels(3, x0+c, y0-r).value () == 0) + { + pixels(0, x0+c, y0-r) = color(0); + pixels(1, x0+c, y0-r) = color(1); + pixels(2, x0+c, y0-r) = color(2); + pixels(3, x0+c, y0-r) = pix; + } + } + + xoffset += (face->glyph->advance.x >> 6); + } + break; + + case MODE_BBOX: + if (code == '\n') + { + glyph_index = FT_Get_Char_Index (face, ' '); + if (! glyph_index + || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT)) + { + glyph_index = 0; + gripe_missing_glyph (' '); + } + else + push_new_line (); + } + else + { + Matrix& bb = line_bbox.back (); + + // If we have a previous glyph, use kerning information. + // This usually means moving a bit backward before adding + // the next glyph. That is, "delta.x" is usually < 0. + if (previous) + { + FT_Vector delta; + + FT_Get_Kerning (face, previous, glyph_index, + FT_KERNING_DEFAULT, &delta); + + xoffset += (delta.x >> 6); + } + + // Extend current X offset box by the width of the current + // glyph. Then extend the line bounding box if necessary. + + xoffset += (face->glyph->advance.x >> 6); + bb(2) = xmax (bb(2), xoffset); + } + break; + } + } + } + + return glyph_index; +} + void ft_render::visit (text_element_string& e) { - if (face) + if (font.is_valid ()) { - int line_index = 0; - FT_UInt box_line_width = 0; - std::string str = e.string_value (); FT_UInt glyph_index, previous = 0; - if (mode == MODE_BBOX) - multiline_align_xoffsets.clear (); - else if (mode == MODE_RENDER) - xoffset += multiline_align_xoffsets[line_index]; + std::string str = e.string_value (); + size_t n = str.length (), curr = 0; + mbstate_t ps; + memset (&ps, 0, sizeof (ps)); // Initialize state to 0. + wchar_t wc; - for (size_t i = 0; i < str.length (); i++) + while (n > 0) { - glyph_index = FT_Get_Char_Index (face, str[i]); + size_t r = gnulib::mbrtowc (&wc, str.data () + curr, n, &ps); - if (str[i] != '\n' - && (! glyph_index - || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT))) - gripe_missing_glyph (str[i]); + if (r > 0 + && r != static_cast (-1) + && r != static_cast (-2)) + { + n -= r; + curr += r; + + glyph_index = process_character (wc, previous); + + if (wc == L'\n') + previous = 0; + else + previous = glyph_index; + } else { - switch (mode) - { - case MODE_RENDER: - if (str[i] == '\n') - { - glyph_index = FT_Get_Char_Index (face, ' '); - if (!glyph_index || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT)) - { - gripe_missing_glyph (' '); - } - else - { - line_index++; - xoffset = multiline_align_xoffsets[line_index]; - yoffset -= (face->size->metrics.height >> 6); - } - } - else if (FT_Render_Glyph (face->glyph, FT_RENDER_MODE_NORMAL)) - { - gripe_glyph_render (str[i]); - } - else - { - FT_Bitmap& bitmap = face->glyph->bitmap; - int x0, y0; - - if (previous) - { - FT_Vector delta; - - FT_Get_Kerning (face, previous, glyph_index, FT_KERNING_DEFAULT, &delta); - xoffset += (delta.x >> 6); - } - - x0 = xoffset+face->glyph->bitmap_left; - y0 = yoffset+face->glyph->bitmap_top; - - // 'w' seems to have a negative -1 - // face->glyph->bitmap_left, this is so we don't - // index out of bound, and assumes we we allocated - // the right amount of horizontal space in the bbox. - if (x0 < 0) - x0 = 0; - - for (int r = 0; r < bitmap.rows; r++) - for (int c = 0; c < bitmap.width; c++) - { - unsigned char pix = bitmap.buffer[r*bitmap.width+c]; - if (x0+c < 0 || x0+c >= pixels.dim2 () - || y0-r < 0 || y0-r >= pixels.dim3 ()) - { - //::error ("out-of-bound indexing!!"); - } - else if (pixels(3, x0+c, y0-r).value () == 0) - { - pixels(0, x0+c, y0-r) = red; - pixels(1, x0+c, y0-r) = green; - pixels(2, x0+c, y0-r) = blue; - pixels(3, x0+c, y0-r) = pix; - } - } - - xoffset += (face->glyph->advance.x >> 6); - } - break; - - case MODE_BBOX: - if (str[i] == '\n') - { - glyph_index = FT_Get_Char_Index (face, ' '); - if (! glyph_index - || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT)) - { - gripe_missing_glyph (' '); - } - else - { - multiline_align_xoffsets.push_back (box_line_width); - // Reset the pixel width for this newline, so we don't - // allocate a bounding box larger than the horizontal - // width of the multi-line - box_line_width = 0; - bbox(1) -= (face->size->metrics.height >> 6); - } - } - else - { - // width - if (previous) - { - FT_Vector delta; - - FT_Get_Kerning (face, previous, glyph_index, - FT_KERNING_DEFAULT, &delta); - - box_line_width += (delta.x >> 6); - } - - box_line_width += (face->glyph->advance.x >> 6); - - int asc, desc; - - if (false /*tight*/) - { - desc = face->glyph->metrics.horiBearingY - face->glyph->metrics.height; - asc = face->glyph->metrics.horiBearingY; - } - else - { - asc = face->size->metrics.ascender; - desc = face->size->metrics.descender; - } - - asc = yoffset + (asc >> 6); - desc = yoffset + (desc >> 6); - - if (desc < bbox(1)) - { - bbox(3) += (bbox(1) - desc); - bbox(1) = desc; - } - if (asc > (bbox(3)+bbox(1))) - bbox(3) = asc-bbox(1); - if (bbox(2) < box_line_width) - bbox(2) = box_line_width; - } - break; - } - if (str[i] == '\n') - previous = 0; - else - previous = glyph_index; - } - } - if (mode == MODE_BBOX) - { - /* Push last the width associated with the last line */ - multiline_align_xoffsets.push_back (box_line_width); - - for (unsigned int i = 0; i < multiline_align_xoffsets.size (); i++) - { - /* Center align */ - if (multiline_halign == 1) - multiline_align_xoffsets[i] = (bbox(2) - multiline_align_xoffsets[i])/2; - /* Right align */ - else if (multiline_halign == 2) - multiline_align_xoffsets[i] = (bbox(2) - multiline_align_xoffsets[i]); - /* Left align */ - else - multiline_align_xoffsets[i] = 0; + if (r != 0) + ::warning ("ft_render: failed to decode string `%s' with " + "locale `%s'", str.c_str (), + std::setlocale (LC_CTYPE, NULL)); + break; } } } } void +ft_render::visit (text_element_list& e) +{ + // Save and restore (after processing the list) the current font and color. + + ft_font saved_font (font); + uint8NDArray saved_color (color); + + text_processor::visit (e); + + font = saved_font; + color = saved_color; +} + +void +ft_render::visit (text_element_subscript& e) +{ + ft_font saved_font (font); + int saved_line_yoffset = line_yoffset; + int saved_yoffset = yoffset; + + set_font (font.get_name (), font.get_weight (), font.get_angle (), + font.get_size () - 2); + + if (font.is_valid ()) + { + int h = font.get_face ()->size->metrics.height >> 6; + + // Shifting the baseline by 2/3 the font height seems to produce + // decent result. + yoffset -= (h * 2) / 3; + + if (mode == MODE_BBOX) + update_line_bbox (); + } + + text_processor::visit (e); + + font = saved_font; + // If line_yoffset changed, this means we moved to a new line; hence yoffset + // cannot be restored, because the saved value is not relevant anymore. + if (line_yoffset == saved_line_yoffset) + yoffset = saved_yoffset; +} + +void +ft_render::visit (text_element_superscript& e) +{ + ft_font saved_font (font); + int saved_line_yoffset = line_yoffset; + int saved_yoffset = yoffset; + + set_font (font.get_name (), font.get_weight (), font.get_angle (), + font.get_size () - 2); + + if (saved_font.is_valid ()) + { + int s_asc = saved_font.get_face ()->size->metrics.ascender >> 6; + + // Shifting the baseline by 2/3 base font ascender seems to produce + // decent result. + yoffset += (s_asc * 2) / 3; + + if (mode == MODE_BBOX) + update_line_bbox (); + } + + text_processor::visit (e); + + font = saved_font; + // If line_yoffset changed, this means we moved to a new line; hence yoffset + // cannot be restored, because the saved value is not relevant anymore. + if (line_yoffset == saved_line_yoffset) + yoffset = saved_yoffset; +} + +void +ft_render::visit (text_element_color& e) +{ + if (mode == MODE_RENDER) + set_color (e.get_color ()); +} + +void +ft_render::visit (text_element_fontsize& e) +{ + double sz = e.get_fontsize (); + + // FIXME: Matlab documentation says that the font size is expressed + // in the text object FontUnit. + + set_font (font.get_name (), font.get_weight (), font.get_angle (), sz); + + if (mode == MODE_BBOX) + update_line_bbox (); +} + +void +ft_render::visit (text_element_fontname& e) +{ + set_font (e.get_fontname (), font.get_weight (), font.get_angle (), + font.get_size ()); + + if (mode == MODE_BBOX) + update_line_bbox (); +} + +void +ft_render::visit (text_element_fontstyle& e) +{ + switch (e.get_fontstyle ()) + { + case text_element_fontstyle::normal: + set_font (font.get_name (), "normal", "normal", font.get_size ()); + break; + case text_element_fontstyle::bold: + set_font (font.get_name (), "bold", "normal", font.get_size ()); + break; + case text_element_fontstyle::italic: + set_font (font.get_name (), "normal", "italic", font.get_size ()); + break; + case text_element_fontstyle::oblique: + set_font (font.get_name (), "normal", "oblique", font.get_size ()); + break; + } + + if (mode == MODE_BBOX) + update_line_bbox (); +} + +void +ft_render::visit (text_element_symbol& e) +{ + uint32_t code = e.get_symbol_code (); + + if (code != text_element_symbol::invalid_code && font.is_valid ()) + process_character (code); + else if (font.is_valid ()) + ::warning ("ignoring unknown symbol: %d", e.get_symbol ()); +} + +void +ft_render::visit (text_element_combined& e) +{ + int saved_xoffset = xoffset; + int max_xoffset = xoffset; + + for (text_element_combined::iterator it = e.begin (); it != e.end (); ++it) + { + xoffset = saved_xoffset; + (*it)->accept (*this); + max_xoffset = xmax (xoffset, max_xoffset); + } + + xoffset = max_xoffset; +} + +void ft_render::reset (void) { set_mode (MODE_BBOX); @@ -495,9 +835,9 @@ { if (c.numel () == 3) { - red = static_cast (c(0)*255); - green = static_cast (c(1)*255); - blue = static_cast (c(2)*255); + color(0) = static_cast (c(0)*255); + color(1) = static_cast (c(1)*255); + color(2) = static_cast (c(2)*255); } else ::warning ("ft_render::set_color: invalid color"); @@ -508,6 +848,7 @@ { set_mode (MODE_BBOX); elt->accept (*this); + compute_bbox (); box = bbox; set_mode (MODE_RENDER); @@ -574,6 +915,7 @@ { set_mode (MODE_BBOX); elt->accept (*this); + compute_bbox (); Matrix extent (1, 2, 0.0); @@ -594,9 +936,10 @@ } Matrix -ft_render::get_extent (const std::string& txt, double rotation) +ft_render::get_extent (const std::string& txt, double rotation, + const caseless_str& interpreter) { - text_element *elt = text_parser_none ().parse (txt); + text_element *elt = text_parser::parse (txt, interpreter); Matrix extent = get_extent (elt, rotation); delete elt; @@ -606,6 +949,12 @@ int ft_render::rotation_to_mode (double rotation) const { + // Clip rotation to range [0, 360] + while (rotation < 0) + rotation += 360.0; + while (rotation > 360.0) + rotation -= 360.0; + if (rotation == 0.0) return ROTATION_0; else if (rotation == 90.0) @@ -621,14 +970,14 @@ void ft_render::text_to_pixels (const std::string& txt, uint8NDArray& pixels_, Matrix& box, - int halign, int valign, double rotation) + int _halign, int valign, double rotation, + const caseless_str& interpreter) { - // FIXME: clip "rotation" between 0 and 360 int rot_mode = rotation_to_mode (rotation); - multiline_halign = halign; + halign = _halign; - text_element *elt = text_parser_none ().parse (txt); + text_element *elt = text_parser::parse (txt, interpreter); pixels_ = render (elt, box, rot_mode); delete elt; @@ -672,4 +1021,61 @@ } } +ft_render::ft_font::ft_font (const ft_font& ft) + : name (ft.name), weight (ft.weight), angle (ft.angle), size (ft.size), + face (0) +{ +#if HAVE_FT_REFERENCE_FACE + FT_Face ft_face = ft.get_face (); + + if (ft_face && FT_Reference_Face (ft_face) == 0) + face = ft_face; +#endif +} + +ft_render::ft_font& +ft_render::ft_font::operator = (const ft_font& ft) +{ + if (&ft != this) + { + name = ft.name; + weight = ft.weight; + angle = ft.angle; + size = ft.size; + if (face) + { + FT_Done_Face (face); + face = 0; + } + +#if HAVE_FT_REFERENCE_FACE + FT_Face ft_face = ft.get_face (); + + if (ft_face && FT_Reference_Face (ft_face) == 0) + face = ft_face; +#endif + } + + return *this; +} + +FT_Face +ft_render::ft_font::get_face (void) const +{ + if (! face && ! name.empty ()) + { + face = ft_manager::get_font (name, weight, angle, size); + + if (face) + { + if (FT_Set_Char_Size (face, 0, size*64, 0, 0)) + ::warning ("ft_render: unable to set font size to %g", size); + } + else + ::warning ("ft_render: unable to load appropriate font"); + } + + return face; +} + #endif // HAVE_FREETYPE diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/txt-eng-ft.h --- a/libinterp/corefcn/txt-eng-ft.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/txt-eng-ft.h Sat Oct 05 11:22:09 2013 -0400 @@ -25,6 +25,7 @@ #if HAVE_FREETYPE +#include #include #include @@ -58,6 +59,24 @@ void visit (text_element_string& e); + void visit (text_element_list& e); + + void visit (text_element_subscript& e); + + void visit (text_element_superscript& e); + + void visit (text_element_color& e); + + void visit (text_element_fontsize& e); + + void visit (text_element_fontname& e); + + void visit (text_element_fontstyle& e); + + void visit (text_element_symbol& e); + + void visit (text_element_combined& e); + void reset (void); uint8NDArray get_pixels (void) const { return pixels; } @@ -68,7 +87,8 @@ int rotation = ROTATION_0); Matrix get_extent (text_element *elt, double rotation = 0.0); - Matrix get_extent (const std::string& txt, double rotation = 0.0); + Matrix get_extent (const std::string& txt, double rotation = 0.0, + const caseless_str& interpreter = "tex"); void set_font (const std::string& name, const std::string& weight, const std::string& angle, double size); @@ -79,7 +99,8 @@ void text_to_pixels (const std::string& txt, uint8NDArray& pixels_, Matrix& bbox, - int halign, int valign, double rotation); + int halign, int valign, double rotation, + const caseless_str& interpreter = "tex"); private: int rotation_to_mode (double rotation) const; @@ -90,16 +111,96 @@ ft_render& operator = (const ft_render&); + // Class to hold information about fonts and a strong + // reference to the font objects loaded by freetype. + class ft_font + { + public: + ft_font (void) + : name (), weight (), angle (), size (0), face (0) { } + + ft_font (const std::string& nm, const std::string& wt, + const std::string& ang, double sz, FT_Face f = 0) + : name (nm), weight (wt), angle (ang), size (sz), face (f) { } + + ft_font (const ft_font& ft); + + ~ft_font (void) + { + if (face) + FT_Done_Face (face); + } + + ft_font& operator = (const ft_font& ft); + + bool is_valid (void) const { return get_face (); } + + std::string get_name (void) const { return name; } + + std::string get_weight (void) const { return weight; } + + std::string get_angle (void) const { return angle; } + + double get_size (void) const { return size; } + + FT_Face get_face (void) const; + + private: + std::string name; + std::string weight; + std::string angle; + double size; + mutable FT_Face face; + }; + + void push_new_line (void); + + void update_line_bbox (void); + + void compute_bbox (void); + + int compute_line_xoffset (const Matrix& lb) const; + + FT_UInt process_character (FT_ULong code, FT_UInt previous = 0); + private: - FT_Face face; + // The current font used by the renderer. + ft_font font; + + // Used to stored the bounding box corresponding to the rendered text. + // The bounding box has the form [x, y, w, h] where x and y represent the + // coordinates of the bottom left corner relative to the anchor point of + // the text (== start of text on the baseline). Due to font descent or + // multiple lines, the value y is usually negative. Matrix bbox; + + // Used to stored the rendered text. It's a 3D matrix with size MxNx4 + // where M and N are the width and height of the bounding box. uint8NDArray pixels; + + // Used to store the bounding box of each line. This is used to layout + // multiline text properly. + std::list line_bbox; + + // The current horizontal alignment. This is used to align multi-line text. + int halign; + + // The X offset for the next glyph. int xoffset; + + // The Y offset of the baseline for the current line. + int line_yoffset; + + // The Y offset of the baseline for the next glyph. The offset is relative + // to line_yoffset. The total Y offset is computed with: + // line_yoffset + yoffset. int yoffset; - int multiline_halign; - std::vector multiline_align_xoffsets; + + // The current mode of the rendering process (box computing or rendering). int mode; - uint8_t red, green, blue; + + // The base color of the rendered text. + uint8NDArray color; }; #endif // HAVE_FREETYPE diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/txt-eng.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/corefcn/txt-eng.cc Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,39 @@ +/* + +Copyright (C) 2013 Michael Goffioul + +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 +. + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "txt-eng.h" +#include "oct-tex-symbols.cc" + +uint32_t +text_element_symbol::get_symbol_code (void) const +{ + uint32_t code = invalid_code; + + if (0 <= symbol && symbol < num_symbol_codes) + code = symbol_codes[symbol][0]; + + return code; +} diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/txt-eng.h --- a/libinterp/corefcn/txt-eng.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/txt-eng.h Sat Oct 05 11:22:09 2013 -0400 @@ -23,13 +23,24 @@ #if ! defined (txt_eng_h) #define txt_eng_h 1 +#include +#include + #include "base-list.h" +#include "caseless-str.h" +#include "dMatrix.h" class text_element; class text_element_string; +class text_element_symbol; class text_element_list; -class text_subscript_element; -class text_superscript_element; +class text_element_subscript; +class text_element_superscript; +class text_element_combined; +class text_element_fontname; +class text_element_fontsize; +class text_element_fontstyle; +class text_element_color; class text_processor; @@ -54,7 +65,7 @@ { public: text_element_string (const std::string& s = "") - : text_element (), str (s) { } + : text_element (), str (s) { } ~text_element_string (void) { } @@ -71,13 +82,40 @@ class OCTINTERP_API +text_element_symbol : public text_element +{ +public: + enum { invalid_code = 0xFFFFFFFFU }; + +public: + text_element_symbol (int sym) + : text_element (), symbol (sym) { } + + ~text_element_symbol (void) { } + + int get_symbol (void) const { return symbol; } + + uint32_t get_symbol_code (void) const; + + void accept (text_processor& p); + +private: + int symbol; +}; + +class +OCTINTERP_API text_element_list : public text_element, public octave_base_list { public: text_element_list (void) - : text_element (), octave_base_list () { } + : text_element (), octave_base_list () { } + + text_element_list (text_element* e) + : text_element (), octave_base_list () + { push_back (e); } ~text_element_list (void) { @@ -94,28 +132,181 @@ class OCTINTERP_API -text_subscript_element : public text_element_list +text_element_subscript : public text_element +{ +public: + text_element_subscript (text_element* e) + : text_element (), elem (e) { } + + text_element_subscript (char c) + : text_element () + { elem = new text_element_string (std::string (1, c)); } + + ~text_element_subscript (void) + { delete elem; } + + void accept (text_processor& p); + + text_element* get_element (void) { return elem; } + +private: + text_element* elem; + +private: + text_element_subscript (void); +}; + +class +OCTINTERP_API +text_element_superscript : public text_element { public: - text_subscript_element (void) - : text_element_list () { } + text_element_superscript (text_element* e) + : text_element (), elem (e) { } + + text_element_superscript (char c) + : text_element () + { elem = new text_element_string (std::string (1, c)); } + + ~text_element_superscript (void) + { delete elem; } + + void accept (text_processor& p); + + text_element* get_element (void) { return elem; } - ~text_subscript_element (void) { } +private: + text_element* elem; + +private: + text_element_superscript (void); +}; + +class +OCTINTERP_API +text_element_combined : public text_element_list +{ +public: + text_element_combined (text_element* e) + : text_element_list (e) { } + + text_element_combined (text_element* e1, text_element* e2) + : text_element_list(e1) + { push_back (e2); } void accept (text_processor& p); }; class OCTINTERP_API -text_superscript_element : public text_element_list +text_element_fontstyle : public text_element +{ +public: + enum fontstyle + { + normal, + bold, + italic, + oblique + }; + + text_element_fontstyle (fontstyle st) + : text_element (), style (st) { } + + ~text_element_fontstyle (void) { } + + fontstyle get_fontstyle (void) const { return style; } + + void accept (text_processor& p); + +private: + fontstyle style; + +private: + text_element_fontstyle (void); +}; + +class +OCTINTERP_API +text_element_fontname : public text_element +{ +public: + text_element_fontname (const std::string& fname) + : text_element (), name (fname) { } + + ~text_element_fontname (void) { } + + const std::string& get_fontname (void) const { return name; } + + void accept (text_processor& p); + +private: + std::string name; + +private: + text_element_fontname (void); +}; + +class +OCTINTERP_API +text_element_fontsize : public text_element { public: - text_superscript_element (void) - : text_element_list () { } + text_element_fontsize (double fsize) + : text_element (), size (fsize) { } - ~text_superscript_element (void) { } + ~text_element_fontsize (void) { } + + double get_fontsize (void) const { return size; } void accept (text_processor& p); + +private: + double size; + +private: + text_element_fontsize (void); +}; + +class +OCTINTERP_API +text_element_color : public text_element +{ +public: + text_element_color (double r, double g, double b) + : text_element (), rgb (1, 3, 0.0) + { + rgb(0) = r; + rgb(1) = g; + rgb(2) = b; + } + + text_element_color (const std::string& cname) + : text_element (), rgb (1, 3, 0.0) + { +#define ASSIGN_COLOR(r,g,b) { rgb(0) = r; rgb(1) = g; rgb(2) = b; } + if (cname == "red") ASSIGN_COLOR(1, 0, 0) + else if (cname == "green") ASSIGN_COLOR(0, 1, 0) + else if (cname == "yellow") ASSIGN_COLOR(1, 1, 0) + else if (cname == "magenta") ASSIGN_COLOR(1, 0, 1) + else if (cname == "blue") ASSIGN_COLOR(0, 0, 1) + else if (cname == "black") ASSIGN_COLOR(0, 0, 0) + else if (cname == "white") ASSIGN_COLOR(1, 1, 1) + else if (cname == "gray") ASSIGN_COLOR(.5, .5, .5) + else if (cname == "darkGreen") ASSIGN_COLOR(0, .5, 0) + else if (cname == "orange") ASSIGN_COLOR(1, .65, 0) + else if (cname == "lightBlue") ASSIGN_COLOR(0.68, .85, .9) +#undef ASSIGN_COLOR + } + + ~text_element_color (void) { } + + Matrix get_color (void) { return rgb; } + + void accept (text_processor& p); + +private: + Matrix rgb; }; class @@ -125,6 +316,8 @@ public: virtual void visit (text_element_string& e) = 0; + virtual void visit (text_element_symbol&) { } + virtual void visit (text_element_list& e) { for (text_element_list::iterator it = e.begin (); @@ -134,11 +327,21 @@ } } - virtual void visit (text_subscript_element& e) - { visit (dynamic_cast (e)); } + virtual void visit (text_element_subscript& e) + { e.get_element ()->accept (*this); } + + virtual void visit (text_element_superscript& e) + { e.get_element ()->accept (*this); } + + virtual void visit (text_element_combined&) { } - virtual void visit (text_superscript_element& e) - { visit (dynamic_cast (e)); } + virtual void visit (text_element_fontstyle&) { } + + virtual void visit (text_element_fontname&) { } + + virtual void visit (text_element_fontsize&) { } + + virtual void visit (text_element_color&) { } virtual void reset (void) { } @@ -154,9 +357,15 @@ { p.visit (*this); } TEXT_ELEMENT_ACCEPT(text_element_string) +TEXT_ELEMENT_ACCEPT(text_element_symbol) TEXT_ELEMENT_ACCEPT(text_element_list) -TEXT_ELEMENT_ACCEPT(text_subscript_element) -TEXT_ELEMENT_ACCEPT(text_superscript_element) +TEXT_ELEMENT_ACCEPT(text_element_subscript) +TEXT_ELEMENT_ACCEPT(text_element_superscript) +TEXT_ELEMENT_ACCEPT(text_element_combined) +TEXT_ELEMENT_ACCEPT(text_element_fontstyle) +TEXT_ELEMENT_ACCEPT(text_element_fontname) +TEXT_ELEMENT_ACCEPT(text_element_fontsize) +TEXT_ELEMENT_ACCEPT(text_element_color) class OCTINTERP_API @@ -168,6 +377,10 @@ virtual ~text_parser (void) { } virtual text_element* parse (const std::string& s) = 0; + +public: + static text_element* parse (const std::string& s, + const caseless_str& interpreter); }; class @@ -190,4 +403,50 @@ } }; +class +OCTINTERP_API +text_parser_tex : public text_parser +{ +public: + text_parser_tex (void) + : text_parser (), scanner (0), buffer_state (0), result (0) + { } + + ~text_parser_tex (void) + { destroy_lexer (); } + + text_element* parse (const std::string& s); + + void* get_scanner (void) { return scanner; } + + void set_parse_result (text_element* e) { result = e; } + + text_element* get_parse_result (void) { return result; } + +private: + bool init_lexer (const std::string& s); + + void destroy_lexer (void); + +private: + void* scanner; + + void* buffer_state; + + text_element* result; +}; + +inline text_element* +text_parser::parse (const std::string& s, const caseless_str& interpreter) +{ + std::auto_ptr parser; + + if (interpreter.compare ("tex")) + parser.reset (new text_parser_tex ()); + else + parser.reset (new text_parser_none ()); + + return parser->parse (s); +} + #endif diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/typecast.cc --- a/libinterp/corefcn/typecast.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/typecast.cc Sat Oct 05 11:22:09 2013 -0400 @@ -25,7 +25,7 @@ #include #endif -#include +#include #include "mx-base.h" @@ -121,10 +121,10 @@ their bit counts. Both logical and char are typically one byte wide;\n\ however, this is not guaranteed by C++. If your system is IEEE conformant,\n\ single and double should be 4 bytes and 8 bytes wide, respectively.\n\ -\"logical\" is not allowed for @var{class}. If the input is a row vector,\n\ -the return value is a row vector, otherwise it is a column vector. If the\n\ -bit length of @var{x} is not divisible by that of @var{class}, an error\n\ -occurs.\n\ +@qcode{\"logical\"} is not allowed for @var{class}. If the input is a row\n\ +vector, the return value is a row vector, otherwise it is a column vector. \n\ +If the bit length of @var{x} is not divisible by that of @var{class}, an\n\ +error occurs.\n\ \n\ An example of the use of typecast on a little-endian machine is\n\ \n\ @@ -242,9 +242,9 @@ do_bitpack (const boolNDArray& bitp) { typedef typename ArrayType::element_type T; - octave_idx_type n = bitp.numel () / (sizeof (T) * CHAR_BIT); + octave_idx_type n = bitp.numel () / (sizeof (T) * std::numeric_limits::digits); - if (n * static_cast (sizeof (T)) * CHAR_BIT == bitp.numel ()) + if (n * static_cast (sizeof (T)) * std::numeric_limits::digits == bitp.numel ()) { ArrayType retval (get_vec_dims (bitp.dims (), n)); @@ -257,11 +257,11 @@ for (octave_idx_type i = 0; i < m; i++) { char c = bits[0]; - for (int j = 1; j < CHAR_BIT; j++) + for (int j = 1; j < std::numeric_limits::digits; j++) c |= bits[j] << j; packed[i] = c; - bits += CHAR_BIT; + bits += std::numeric_limits::digits; } return retval; @@ -361,22 +361,22 @@ do_bitunpack (const ArrayType& array) { typedef typename ArrayType::element_type T; - octave_idx_type n = array.numel () * sizeof (T) * CHAR_BIT; + octave_idx_type n = array.numel () * sizeof (T) * std::numeric_limits::digits; boolNDArray retval (get_vec_dims (array.dims (), n)); const char *packed = reinterpret_cast (array.fortran_vec ()); bool *bits = retval.fortran_vec (); - octave_idx_type m = n / CHAR_BIT; + octave_idx_type m = n / std::numeric_limits::digits; for (octave_idx_type i = 0; i < m; i++) { char c = packed[i]; bits[0] = c & 1; - for (int j = 1; j < CHAR_BIT; j++) + for (int j = 1; j < std::numeric_limits::digits; j++) bits[j] = (c >>= 1) & 1; - bits += CHAR_BIT; + bits += std::numeric_limits::digits; } return retval; diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/unwind-prot.cc --- a/libinterp/corefcn/unwind-prot.cc Thu Sep 12 21:08:07 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* - -Copyright (C) 1993-2012 John W. Eaton -Copyright (C) 2009 VZLU Prague - -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 -. - -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "error.h" -#include "unwind-prot.h" - -void unwind_protect_safe::gripe_exception (void) -{ - // FIXME: can this throw an exception? - error ("internal: unhandled exception in unwind_protect handler"); -} diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/unwind-prot.h --- a/libinterp/corefcn/unwind-prot.h Thu Sep 12 21:08:07 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,143 +0,0 @@ -/* - -Copyright (C) 1993-2012 John W. Eaton -Copyright (C) 2009-2010 VZLU Prague - -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 -. - -*/ - -#if !defined (octave_unwind_prot_h) -#define octave_unwind_prot_h 1 - -#include -#include - -#include "action-container.h" - -class -OCTINTERP_API -unwind_protect : public action_container -{ -public: - - unwind_protect (void) : lifo () { } - - // Destructor should not raise an exception, so all actions - // registered should be exception-safe (but setting error_state is - // allowed). If you're not sure, see unwind_protect_safe. - - ~unwind_protect (void) { run (); } - - virtual void add (elem *new_elem) - { - lifo.push (new_elem); - } - - void add (void (*fcn) (void *), void *ptr = 0) GCC_ATTR_DEPRECATED - { - add (new fcn_arg_elem (fcn, ptr)); - } - - operator bool (void) const { return ! empty (); } - - void run_top (void) GCC_ATTR_DEPRECATED { run_first (); } - - void run_first (void) - { - if (! empty ()) - { - // No leak on exception! - std::auto_ptr ptr (lifo.top ()); - lifo.pop (); - ptr->run (); - } - } - - void run_top (int num) GCC_ATTR_DEPRECATED { run (num); } - - void discard_top (void) GCC_ATTR_DEPRECATED { discard_first (); } - - void discard_first (void) - { - if (! empty ()) - { - elem *ptr = lifo.top (); - lifo.pop (); - delete ptr; - } - } - - void discard_top (int num) GCC_ATTR_DEPRECATED { discard (num); } - - size_t size (void) const { return lifo.size (); } - -protected: - - std::stack lifo; - -private: - - // No copying! - - unwind_protect (const unwind_protect&); - - unwind_protect& operator = (const unwind_protect&); -}; - -// Like unwind_protect, but this one will guard against the -// possibility of seeing an exception (or interrupt) in the cleanup -// actions. Not that we can do much about it, but at least we won't -// crash. - -class -OCTINTERP_API -unwind_protect_safe : public unwind_protect -{ -private: - - static void gripe_exception (void); - -public: - - unwind_protect_safe (void) : unwind_protect () { } - - ~unwind_protect_safe (void) - { - while (! empty ()) - { - try - { - run_first (); - } - catch (...) // Yes, the black hole. Remember we're in a dtor. - { - gripe_exception (); - } - } - } - -private: - - // No copying! - - unwind_protect_safe (const unwind_protect_safe&); - - unwind_protect_safe& operator = (const unwind_protect_safe&); -}; - -#endif diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/urlwrite.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/corefcn/urlwrite.cc Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,1180 @@ +// urlwrite and urlread, a curl front-end for octave +/* + +Copyright (C) 2006-2012 Alexander Barth +Copyright (C) 2009 David Bateman + +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 +. + +*/ + +// Author: Alexander Barth +// Adapted-By: jwe + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include "dir-ops.h" +#include "file-ops.h" +#include "file-stat.h" +#include "oct-env.h" +#include "oct-handle.h" +#include "glob-match.h" +#include "singleton-cleanup.h" +#include "url-transfer.h" + +#include "defun.h" +#include "error.h" +#include "oct-obj.h" +#include "ov-cell.h" +#include "pager.h" +#include "oct-map.h" +#include "oct-refcount.h" +#include "unwind-prot.h" + +static void +delete_file (const std::string& file) +{ + octave_unlink (file); +} + +typedef octave_handle curl_handle; + +class OCTINTERP_API ch_manager +{ +protected: + + ch_manager (void) + : handle_map (), handle_free_list (), + next_handle (-1.0 - (rand () + 1.0) / (RAND_MAX + 2.0)) { } + +public: + + static void create_instance (void); + + static bool instance_ok (void) + { + bool retval = true; + + if (! instance) + create_instance (); + + if (! instance) + { + ::error ("unable to create ch_manager!"); + + retval = false; + } + + return retval; + } + + static void cleanup_instance (void) { delete instance; instance = 0; } + + static curl_handle get_handle (void) + { + return instance_ok () + ? instance->do_get_handle () : curl_handle (); + } + + static void free (const curl_handle& h) + { + if (instance_ok ()) + instance->do_free (h); + } + + static curl_handle lookup (double val) + { + return instance_ok () ? instance->do_lookup (val) : curl_handle (); + } + + static curl_handle lookup (const octave_value& val) + { + return val.is_real_scalar () + ? lookup (val.double_value ()) : curl_handle (); + } + + static url_transfer get_object (double val) + { + return get_object (lookup (val)); + } + + static url_transfer get_object (const octave_value& val) + { + return get_object (lookup (val)); + } + + static url_transfer get_object (const curl_handle& h) + { + return instance_ok () ? instance->do_get_object (h) : url_transfer (); + } + + static curl_handle make_curl_handle (const std::string& host, + const std::string& user, + const std::string& passwd, + std::ostream& os) + { + return instance_ok () + ? instance->do_make_curl_handle (host, user, passwd, os) : curl_handle (); + } + + static Matrix handle_list (void) + { + return instance_ok () ? instance->do_handle_list () : Matrix (); + } + +private: + + static ch_manager *instance; + + typedef std::map::iterator iterator; + typedef std::map::const_iterator const_iterator; + + typedef std::set::iterator free_list_iterator; + typedef std::set::const_iterator const_free_list_iterator; + + // A map of handles to curl objects. + std::map handle_map; + + // The available curl handles. + std::set handle_free_list; + + // The next handle available if handle_free_list is empty. + double next_handle; + + curl_handle do_get_handle (void); + + void do_free (const curl_handle& h); + + curl_handle do_lookup (double val) + { + iterator p = (xisnan (val) ? handle_map.end () : handle_map.find (val)); + + return (p != handle_map.end ()) ? p->first : curl_handle (); + } + + url_transfer do_get_object (const curl_handle& h) + { + iterator p = (h.ok () ? handle_map.find (h) : handle_map.end ()); + + return (p != handle_map.end ()) ? p->second : url_transfer (); + } + + curl_handle do_make_curl_handle (const std::string& host, + const std::string& user, + const std::string& passwd, + std::ostream& os) + { + curl_handle h = get_handle (); + + url_transfer obj (host, user, passwd, os); + + if (! error_state) + handle_map[h] = obj; + else + h = curl_handle (); + + return h; + } + + Matrix do_handle_list (void) + { + Matrix retval (1, handle_map.size ()); + + octave_idx_type i = 0; + for (const_iterator p = handle_map.begin (); p != handle_map.end (); p++) + { + curl_handle h = p->first; + + retval(i++) = h.value (); + } + + return retval; + } +}; + +void +ch_manager::create_instance (void) +{ + instance = new ch_manager (); + + if (instance) + singleton_cleanup_list::add (cleanup_instance); +} + +static double +make_handle_fraction (void) +{ + static double maxrand = RAND_MAX + 2.0; + + return (rand () + 1.0) / maxrand; +} + +curl_handle +ch_manager::do_get_handle (void) +{ + curl_handle retval; + + // Curl handles are negative integers plus some random fractional + // part. To avoid running out of integers, we recycle the integer + // part but tack on a new random part each time. + + free_list_iterator p = handle_free_list.begin (); + + if (p != handle_free_list.end ()) + { + retval = *p; + handle_free_list.erase (p); + } + else + { + retval = curl_handle (next_handle); + + next_handle = std::ceil (next_handle) - 1.0 - make_handle_fraction (); + } + + return retval; +} + +void +ch_manager::do_free (const curl_handle& h) +{ + if (h.ok ()) + { + iterator p = handle_map.find (h); + + if (p != handle_map.end ()) + { + // Curl handles are negative integers plus some random + // fractional part. To avoid running out of integers, we + // recycle the integer part but tack on a new random part + // each time. + + handle_map.erase (p); + + if (h.value () < 0) + handle_free_list.insert (std::ceil (h.value ()) - make_handle_fraction ()); + } + else + error ("ch_manager::free: invalid object %g", h.value ()); + } +} + +ch_manager *ch_manager::instance = 0; + +DEFUN (urlwrite, args, nargout, + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} urlwrite (@var{url}, @var{localfile})\n\ +@deftypefnx {Loadable Function} {@var{f} =} urlwrite (@var{url}, @var{localfile})\n\ +@deftypefnx {Loadable Function} {[@var{f}, @var{success}] =} urlwrite (@var{url}, @var{localfile})\n\ +@deftypefnx {Loadable Function} {[@var{f}, @var{success}, @var{message}] =} urlwrite (@var{url}, @var{localfile})\n\ +Download a remote file specified by its @var{url} and save it as\n\ +@var{localfile}. For example:\n\ +\n\ +@example\n\ +@group\n\ +urlwrite (\"ftp://ftp.octave.org/pub/octave/README\",\n\ + \"README.txt\");\n\ +@end group\n\ +@end example\n\ +\n\ +The full path of the downloaded file is returned in @var{f}. The\n\ +variable @var{success} is 1 if the download was successful,\n\ +otherwise it is 0 in which case @var{message} contains an error\n\ +message. If no output argument is specified and an error occurs,\n\ +then the error is signaled through Octave's error handling mechanism.\n\ +\n\ +This function uses libcurl. Curl supports, among others, the HTTP,\n\ +FTP and FILE protocols. Username and password may be specified in\n\ +the URL, for example:\n\ +\n\ +@example\n\ +@group\n\ +urlwrite (\"http://username:password@@example.com/file.txt\",\n\ + \"file.txt\");\n\ +@end group\n\ +@end example\n\ +\n\ +GET and POST requests can be specified by @var{method} and @var{param}.\n\ +The parameter @var{method} is either @samp{get} or @samp{post}\n\ +and @var{param} is a cell array of parameter and value pairs.\n\ +For example:\n\ +\n\ +@example\n\ +@group\n\ +urlwrite (\"http://www.google.com/search\", \"search.html\",\n\ + \"get\", @{\"query\", \"octave\"@});\n\ +@end group\n\ +@end example\n\ +@seealso{urlread}\n\ +@end deftypefn") +{ + octave_value_list retval; + + int nargin = args.length (); + + // verify arguments + if (nargin != 2 && nargin != 4) + { + print_usage (); + return retval; + } + + std::string url = args(0).string_value (); + + if (error_state) + { + error ("urlwrite: URL must be a character string"); + return retval; + } + + // name to store the file if download is succesful + std::string filename = args(1).string_value (); + + if (error_state) + { + error ("urlwrite: LOCALFILE must be a character string"); + return retval; + } + + std::string method; + Array param; + + if (nargin == 4) + { + method = args(2).string_value (); + + if (error_state) + { + error ("urlwrite: METHOD must be \"get\" or \"post\""); + return retval; + } + + if (method != "get" && method != "post") + { + error ("urlwrite: METHOD must be \"get\" or \"post\""); + return retval; + } + + param = args(3).cellstr_value (); + + if (error_state) + { + error ("urlwrite: parameters (PARAM) for get and post requests must be given as a cell array of character strings"); + return retval; + } + + + if (param.numel () % 2 == 1 ) + { + error ("urlwrite: number of elements in PARAM must be even"); + return retval; + } + } + + // The file should only be deleted if it doesn't initially exist, we + // create it, and the download fails. We use unwind_protect to do + // it so that the deletion happens no matter how we exit the function. + + file_stat fs (filename); + + std::ofstream ofile (filename.c_str (), std::ios::out | std::ios::binary); + + if (! ofile.is_open ()) + { + error ("urlwrite: unable to open file"); + return retval; + } + + unwind_protect_safe frame; + + frame.add_fcn (delete_file, filename); + + url_transfer curl = url_transfer (url, method, param, ofile); + + ofile.close (); + + if (curl.good ()) + frame.discard (); + + if (nargout > 0) + { + if (curl.good ()) + { + retval(2) = std::string (); + retval(1) = true; + retval(0) = octave_env::make_absolute (filename); + } + else + { + retval(2) = curl.lasterror (); + retval(1) = false; + retval(0) = std::string (); + } + } + + if (nargout < 2 && ! curl.good ()) + error ("urlwrite: %s", curl.lasterror ().c_str ()); + + return retval; +} + +DEFUN (urlread, args, nargout, + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{s} =} urlread (@var{url})\n\ +@deftypefnx {Loadable Function} {[@var{s}, @var{success}] =} urlread (@var{url})\n\ +@deftypefnx {Loadable Function} {[@var{s}, @var{success}, @var{message}] =} urlread (@var{url})\n\ +@deftypefnx {Loadable Function} {[@dots{}] =} urlread (@var{url}, @var{method}, @var{param})\n\ +Download a remote file specified by its @var{url} and return its content\n\ +in string @var{s}. For example:\n\ +\n\ +@example\n\ +s = urlread (\"ftp://ftp.octave.org/pub/octave/README\");\n\ +@end example\n\ +\n\ +The variable @var{success} is 1 if the download was successful,\n\ +otherwise it is 0 in which case @var{message} contains an error\n\ +message. If no output argument is specified and an error occurs,\n\ +then the error is signaled through Octave's error handling mechanism.\n\ +\n\ +This function uses libcurl. Curl supports, among others, the HTTP,\n\ +FTP and FILE protocols. Username and password may be specified in the\n\ +URL@. For example:\n\ +\n\ +@example\n\ +s = urlread (\"http://user:password@@example.com/file.txt\");\n\ +@end example\n\ +\n\ +GET and POST requests can be specified by @var{method} and @var{param}.\n\ +The parameter @var{method} is either @samp{get} or @samp{post}\n\ +and @var{param} is a cell array of parameter and value pairs.\n\ +For example:\n\ +\n\ +@example\n\ +@group\n\ +s = urlread (\"http://www.google.com/search\", \"get\",\n\ + @{\"query\", \"octave\"@});\n\ +@end group\n\ +@end example\n\ +@seealso{urlwrite}\n\ +@end deftypefn") +{ + // Octave's return value + octave_value_list retval; + + int nargin = args.length (); + + // verify arguments + if (nargin != 1 && nargin != 3) + { + print_usage (); + return retval; + } + + std::string url = args(0).string_value (); + + if (error_state) + { + error ("urlread: URL must be a character string"); + return retval; + } + + std::string method; + Array param; + + if (nargin == 3) + { + method = args(1).string_value (); + + if (error_state) + { + error ("urlread: METHOD must be \"get\" or \"post\""); + return retval; + } + + if (method != "get" && method != "post") + { + error ("urlread: METHOD must be \"get\" or \"post\""); + return retval; + } + + param = args(2).cellstr_value (); + + if (error_state) + { + error ("urlread: parameters (PARAM) for get and post requests must be given as a cell array of character strings"); + return retval; + } + + if (param.numel () % 2 == 1 ) + { + error ("urlread: number of elements in PARAM must be even"); + return retval; + } + } + + std::ostringstream buf; + + url_transfer curl = url_transfer (url, method, param, buf); + + if (curl.good ()) + { + if (nargout > 0) + { + // Return empty string if no error occured. + retval(2) = curl.good () ? "" : curl.lasterror (); + retval(1) = curl.good (); + retval(0) = buf.str (); + } + } + + if (nargout < 2 && ! curl.good ()) + error ("urlread: %s", curl.lasterror().c_str()); + + return retval; +} + +DEFUN (__ftp__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{handle} =} __ftp__ (@var{host})\n\ +@deftypefnx {Loadable Function} {@var{handle} =} __ftp__ (@var{host}, @var{username}, @var{password})\n\ +Undocumented internal function\n\ +@end deftypefn") +{ + octave_value retval; + + int nargin = args.length (); + std::string host; + std::string user = "anonymous"; + std::string passwd = ""; + + if (nargin < 1 || nargin > 3) + { + print_usage (); + return retval; + } + else + { + host = args(0).string_value (); + + if (nargin > 1) + user = args(1).string_value (); + + if (nargin > 2) + passwd = args(2).string_value (); + + if (! error_state) + { + curl_handle ch + = ch_manager::make_curl_handle (host, user, passwd, octave_stdout); + + if (! error_state) + retval = ch.value (); + } + } + + return retval; +} + +DEFUN (__ftp_pwd__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __ftp_pwd__ (@var{handle})\n\ +Undocumented internal function\n\ +@end deftypefn") +{ + octave_value retval; + + int nargin = args.length (); + + if (nargin != 1) + error ("__ftp_pwd__: incorrect number of arguments"); + else + { + url_transfer curl = ch_manager::get_object (args(0)); + + if (error_state) + return retval; + + if (curl.is_valid ()) + retval = curl.pwd (); + else + error ("__ftp_pwd__: invalid ftp handle"); + } + + return retval; +} + +DEFUN (__ftp_cwd__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __ftp_cwd__ (@var{handle}, @var{path})\n\ +Undocumented internal function\n\ +@end deftypefn") +{ + octave_value retval; + + int nargin = args.length (); + + if (nargin != 1 && nargin != 2) + error ("__ftp_cwd__: incorrect number of arguments"); + else + { + url_transfer curl = ch_manager::get_object (args(0)); + + if (error_state) + return retval; + + if (curl.is_valid ()) + { + std::string path = ""; + + if (nargin > 1) + path = args(1).string_value (); + + if (! error_state) + curl.cwd (path); + else + error ("__ftp_cwd__: expecting path as second argument"); + } + else + error ("__ftp_cwd__: invalid ftp handle"); + } + + return retval; +} + +DEFUN (__ftp_dir__, args, nargout, + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __ftp_dir__ (@var{handle})\n\ +Undocumented internal function\n\ +@end deftypefn") +{ + octave_value retval; + + int nargin = args.length (); + + if (nargin != 1) + error ("__ftp_dir__: incorrect number of arguments"); + else + { + url_transfer curl = ch_manager::get_object (args(0)); + + if (error_state) + return retval; + + if (curl.is_valid ()) + { + if (nargout == 0) + curl.dir (); + else + { + string_vector sv = curl.list (); + octave_idx_type n = sv.length (); + + if (n == 0) + { + string_vector flds (5); + + flds(0) = "name"; + flds(1) = "date"; + flds(2) = "bytes"; + flds(3) = "isdir"; + flds(4) = "datenum"; + + retval = octave_map (flds); + } + else + { + octave_map st; + + Cell filectime (dim_vector (n, 1)); + Cell filesize (dim_vector (n, 1)); + Cell fileisdir (dim_vector (n, 1)); + Cell filedatenum (dim_vector (n, 1)); + + st.assign ("name", Cell (sv)); + + for (octave_idx_type i = 0; i < n; i++) + { + time_t ftime; + bool fisdir; + double fsize; + + curl.get_fileinfo (sv(i), fsize, ftime, fisdir); + + fileisdir (i) = fisdir; + filectime (i) = ctime (&ftime); + filesize (i) = fsize; + filedatenum (i) = double (ftime); + } + + st.assign ("date", filectime); + st.assign ("bytes", filesize); + st.assign ("isdir", fileisdir); + st.assign ("datenum", filedatenum); + + retval = st; + } + } + } + else + error ("__ftp_dir__: invalid ftp handle"); + } + + return retval; +} + +DEFUN (__ftp_ascii__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __ftp_ascii__ (@var{handle})\n\ +Undocumented internal function\n\ +@end deftypefn") +{ + octave_value retval; + + int nargin = args.length (); + + if (nargin != 1) + error ("__ftp_ascii__: incorrect number of arguments"); + else + { + url_transfer curl = ch_manager::get_object (args(0)); + + if (error_state) + return retval; + + if (curl.is_valid ()) + curl.ascii (); + else + error ("__ftp_ascii__: invalid ftp handle"); + } + + return retval; +} + +DEFUN (__ftp_binary__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __ftp_binary__ (@var{handle})\n\ +Undocumented internal function\n\ +@end deftypefn") +{ + octave_value retval; + + int nargin = args.length (); + + if (nargin != 1) + error ("__ftp_binary__: incorrect number of arguments"); + else + { + url_transfer curl = ch_manager::get_object (args(0)); + + if (error_state) + return retval; + + if (curl.is_valid ()) + curl.binary (); + else + error ("__ftp_binary__: invalid ftp handle"); + } + + return retval; +} + +DEFUN (__ftp_close__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __ftp_close__ (@var{handle})\n\ +Undocumented internal function\n\ +@end deftypefn") +{ + octave_value retval; + + int nargin = args.length (); + + if (nargin != 1) + error ("__ftp_close__: incorrect number of arguments"); + else + { + curl_handle h = ch_manager::lookup (args(0)); + + if (error_state) + return retval; + + if (h.ok ()) + ch_manager::free (h); + else + error ("__ftp_close__: invalid ftp handle"); + } + + return retval; +} + +DEFUN (__ftp_mode__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __ftp_mode__ (@var{handle})\n\ +Undocumented internal function\n\ +@end deftypefn") +{ + octave_value retval; + + int nargin = args.length (); + + if (nargin != 1) + error ("__ftp_mode__: incorrect number of arguments"); + else + { + url_transfer curl = ch_manager::get_object (args(0)); + + if (error_state) + return retval; + + if (curl.is_valid ()) + retval = (curl.is_ascii () ? "ascii" : "binary"); + else + error ("__ftp_binary__: invalid ftp handle"); + } + + return retval; +} + +DEFUN (__ftp_delete__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __ftp_delete__ (@var{handle}, @var{path})\n\ +Undocumented internal function\n\ +@end deftypefn") +{ + octave_value retval; + + int nargin = args.length (); + + if (nargin != 2) + error ("__ftp_delete__: incorrect number of arguments"); + else + { + url_transfer curl = ch_manager::get_object (args(0)); + + if (error_state) + return retval; + + if (curl.is_valid ()) + { + std::string file = args(1).string_value (); + + if (! error_state) + curl.del (file); + else + error ("__ftp_delete__: expecting file name as second argument"); + } + else + error ("__ftp_delete__: invalid ftp handle"); + } + + return retval; +} + +DEFUN (__ftp_rmdir__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __ftp_rmdir__ (@var{handle}, @var{path})\n\ +Undocumented internal function\n\ +@end deftypefn") +{ + octave_value retval; + + int nargin = args.length (); + + if (nargin != 2) + error ("__ftp_rmdir__: incorrect number of arguments"); + else + { + url_transfer curl = ch_manager::get_object (args(0)); + + if (error_state) + return retval; + + if (curl.is_valid ()) + { + std::string dir = args(1).string_value (); + + if (! error_state) + curl.rmdir (dir); + else + error ("__ftp_rmdir__: expecting directory name as second argument"); + } + else + error ("__ftp_rmdir__: invalid ftp handle"); + } + + return retval; +} + +DEFUN (__ftp_mkdir__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __ftp_mkdir__ (@var{handle}, @var{path})\n\ +Undocumented internal function\n\ +@end deftypefn") +{ + octave_value retval; + + int nargin = args.length (); + + if (nargin != 2) + error ("__ftp_mkdir__: incorrect number of arguments"); + else + { + url_transfer curl = ch_manager::get_object (args(0)); + + if (error_state) + return retval; + + if (curl.is_valid ()) + { + std::string dir = args(1).string_value (); + + if (! error_state) + curl.mkdir (dir); + else + error ("__ftp_mkdir__: expecting directory name as second argument"); + } + else + error ("__ftp_mkdir__: invalid ftp handle"); + } + + return retval; +} + +DEFUN (__ftp_rename__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __ftp_rename__ (@var{handle}, @var{path})\n\ +Undocumented internal function\n\ +@end deftypefn") +{ + octave_value retval; + + int nargin = args.length (); + + if (nargin != 3) + error ("__ftp_rename__: incorrect number of arguments"); + else + { + url_transfer curl = ch_manager::get_object (args(0)); + + if (error_state) + return retval; + + if (curl.is_valid ()) + { + std::string oldname = args(1).string_value (); + std::string newname = args(2).string_value (); + + if (! error_state) + curl.rename (oldname, newname); + else + error ("__ftp_rename__: expecting file names for second and third arguments"); + } + else + error ("__ftp_rename__: invalid ftp handle"); + } + + return retval; +} + +DEFUN (__ftp_mput__, args, nargout, + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __ftp_mput__ (@var{handle}, @var{files})\n\ +Undocumented internal function\n\ +@end deftypefn") +{ + octave_value retval; + + int nargin = args.length (); + + if (nargin != 2) + error ("__ftp_mput__: incorrect number of arguments"); + else + { + url_transfer curl = ch_manager::get_object (args(0)); + + if (error_state) + return retval; + + if (curl.is_valid ()) + { + std::string pat = args(1).string_value (); + + if (! error_state) + { + string_vector file_list; + + glob_match pattern (file_ops::tilde_expand (pat)); + string_vector files = pattern.glob (); + + for (octave_idx_type i = 0; i < files.length (); i++) + { + std::string file = files (i); + + file_stat fs (file); + + if (! fs.exists ()) + { + error ("__ftp__mput: file does not exist"); + break; + } + + if (fs.is_dir ()) + { + file_list.append (curl.mput_directory ("", file)); + + if (! curl.good ()) + { + error ("__ftp_mput__: %s", curl.lasterror().c_str()); + break; + } + } + else + { + // FIXME Does ascii mode need to be flagged here? + std::ifstream ifile (file.c_str (), std::ios::in | + std::ios::binary); + + if (! ifile.is_open ()) + { + error ("__ftp_mput__: unable to open file"); + break; + } + + curl.put (file, ifile); + + ifile.close (); + + if (! curl.good ()) + { + error ("__ftp_mput__: %s", curl.lasterror().c_str()); + break; + } + + file_list.append (file); + } + } + + if (nargout > 0) + retval = file_list; + } + else + error ("__ftp_mput__: expecting file name patter as second argument"); + } + else + error ("__ftp_mput__: invalid ftp handle"); + } + + return retval; +} + +DEFUN (__ftp_mget__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __ftp_mget__ (@var{handle}, @var{files})\n\ +Undocumented internal function\n\ +@end deftypefn") +{ + octave_value retval; + + int nargin = args.length (); + + if (nargin != 2 && nargin != 3) + error ("__ftp_mget__: incorrect number of arguments"); + else + { + url_transfer curl = ch_manager::get_object (args(0)); + + if (error_state) + return retval; + + if (curl.is_valid ()) + { + std::string file = args(1).string_value (); + std::string target; + + if (nargin == 3) + target = args(2).string_value () + file_ops::dir_sep_str (); + + if (! error_state) + { + string_vector sv = curl.list (); + octave_idx_type n = 0; + glob_match pattern (file); + + + for (octave_idx_type i = 0; i < sv.length (); i++) + { + if (pattern.match (sv(i))) + { + n++; + + time_t ftime; + bool fisdir; + double fsize; + + curl.get_fileinfo (sv(i), fsize, ftime, fisdir); + + if (fisdir) + curl.mget_directory (sv(i), target); + else + { + std::ofstream ofile ((target + sv(i)).c_str (), + std::ios::out | + std::ios::binary); + + if (! ofile.is_open ()) + { + error ("__ftp_mget__: unable to open file"); + break; + } + + unwind_protect_safe frame; + + frame.add_fcn (delete_file, target + sv(i)); + + curl.get (sv(i), ofile); + + ofile.close (); + + if (curl.good ()) + frame.discard (); + } + + if (! curl.good ()) + { + error ("__ftp_mget__: %s", curl.lasterror().c_str()); + break; + } + } + } + if (n == 0) + error ("__ftp_mget__: file not found"); + } + else + error ("__ftp_mget__: expecting file name and target as second and third arguments"); + } + else + error ("__ftp_mget__: invalid ftp handle"); + } + + return retval; +} diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/utils.cc --- a/libinterp/corefcn/utils.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/utils.cc Sat Oct 05 11:22:09 2013 -0400 @@ -299,7 +299,7 @@ directory of the loadpath for element of the cell array and return\n\ the first that matches.\n\ \n\ -If the second optional argument @code{\"all\"} is supplied, return\n\ +If the second optional argument @qcode{\"all\"} is supplied, return\n\ a cell array containing the list of all files that have the same\n\ name in the path. If no files are found, return an empty cell array.\n\ @seealso{file_in_path, path}\n\ @@ -375,7 +375,7 @@ directory of the path for element of the cell array and return\n\ the first that matches.\n\ \n\ -If the third optional argument @code{\"all\"} is supplied, return\n\ +If the third optional argument @qcode{\"all\"} is supplied, return\n\ a cell array containing the list of all files that have the same\n\ name in the path. If no files are found, return an empty cell array.\n\ @seealso{file_in_loadpath}\n\ @@ -896,9 +896,10 @@ @deftypefnx {Built-in Function} {} find_dir_in_path (@var{dir}, \"all\")\n\ Return the full name of the path element matching @var{dir}. The\n\ match is performed at the end of each path element. For example, if\n\ -@var{dir} is @code{\"foo/bar\"}, it matches the path element\n\ -@code{\"/some/dir/foo/bar\"}, but not @code{\"/some/dir/foo/bar/baz\"}\n\ -or @code{\"/some/dir/allfoo/bar\"}.\n\ +@var{dir} is @qcode{\"foo/bar\"}, it matches the path element\n\ +@nospell{@qcode{\"/some/dir/foo/bar\"}}, but not\n\ +@nospell{@qcode{\"/some/dir/foo/bar/baz\"}}\n\ +@nospell{@qcode{\"/some/dir/allfoo/bar\"}}.\n\ \n\ The second argument is optional. If it is supplied, return a cell array\n\ containing all name matches rather than just the first.\n\ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/corefcn/variables.cc --- a/libinterp/corefcn/variables.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/corefcn/variables.cc Sat Oct 05 11:22:09 2013 -0400 @@ -36,7 +36,7 @@ #include "oct-env.h" #include "file-ops.h" #include "glob-match.h" -#include "regexp.h" +#include "lo-regexp.h" #include "str-vec.h" #include @@ -401,6 +401,8 @@ struct_elts = name.substr (pos+1); symbol_name = name.substr (0, pos); } + else if (is_keyword (symbol_name)) + return retval; // We shouldn't need to look in the global symbol table, since any // name that is visible in the current scope will be in the local @@ -537,16 +539,16 @@ symbols of the specified type. Valid types are\n\ \n\ @table @asis\n\ -@item \"var\"\n\ +@item @qcode{\"var\"}\n\ Check only for variables.\n\ \n\ -@item \"builtin\"\n\ +@item @qcode{\"builtin\"}\n\ Check only for built-in functions.\n\ \n\ -@item \"file\"\n\ +@item @qcode{\"file\"}\n\ Check only for files and directories.\n\ \n\ -@item \"dir\"\n\ +@item @qcode{\"dir\"}\n\ Check only for directories.\n\ @end table\n\ \n\ @@ -2530,11 +2532,11 @@ left of the specified balance column.\n\ \n\ The default format is\n\ -@code{\" %a:4; %ln:6; %cs:16:6:1; %rb:12; %lc:-1;\\n\"}.\n\ +@qcode{\" %a:4; %ln:6; %cs:16:6:1; %rb:12; %lc:-1;\\n\"}.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{whos}\n\ @end deftypefn") { @@ -2551,9 +2553,9 @@ Query or set the internal variable that specifies the function to call when\n\ an unknown identifier is requested.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @end deftypefn") { return SET_INTERNAL_VARIABLE (missing_function_hook); @@ -2604,3 +2606,33 @@ return retval; } + +static std::string Vmissing_component_hook; + +DEFUN (missing_component_hook, args, nargout, + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {@var{val} =} missing_component_hook ()\n\ +@deftypefnx {Built-in Function} {@var{old_val} =} missing_component_hook (@var{new_val})\n\ +@deftypefnx {Built-in Function} {} missing_component_hook (@var{new_val}, \"local\")\n\ +Query or set the internal variable that specifies the function to call when\n\ +a component of Octave is missing. This can be useful for packagers that\n\ +may split the Octave installation into multiple sub-packages, for example,\n\ +to provide a hint to users for how to install the missing components.\n\ +\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ +\n\ +The hook function is expected to be of the form\n\ +\n\ +@example\n\ +@var{fcn} (@var{component})\n\ +@end example\n\ +\n\ +Octave will call @var{fcn} with the name of the function that requires the\n\ +component and a string describing the missing component. The hook function\n\ +should return an error message to be displayed.\n\ +@end deftypefn") +{ + return SET_INTERNAL_VARIABLE (missing_component_hook); +} diff -r 20d1b911b4e7 -r c702371ff6df libinterp/dldfcn/__eigs__.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/dldfcn/__eigs__.cc Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,618 @@ +/* + +Copyright (C) 2005-2012 David Bateman + +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 +. + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "ov.h" +#include "defun-dld.h" +#include "error.h" +#include "gripes.h" +#include "quit.h" +#include "variables.h" +#include "ov-re-sparse.h" +#include "ov-cx-sparse.h" +#include "oct-map.h" +#include "pager.h" +#include "unwind-prot.h" + +#include "eigs-base.cc" + +// Global pointer for user defined function. +static octave_function *eigs_fcn = 0; + +// Have we warned about imaginary values returned from user function? +static bool warned_imaginary = false; + +// Is this a recursive call? +static int call_depth = 0; + +ColumnVector +eigs_func (const ColumnVector &x, int &eigs_error) +{ + ColumnVector retval; + octave_value_list args; + args(0) = x; + + if (eigs_fcn) + { + octave_value_list tmp = eigs_fcn->do_multi_index_op (1, args); + + if (error_state) + { + eigs_error = 1; + gripe_user_supplied_eval ("eigs"); + return retval; + } + + if (tmp.length () && tmp(0).is_defined ()) + { + if (! warned_imaginary && tmp(0).is_complex_type ()) + { + warning ("eigs: ignoring imaginary part returned from user-supplied function"); + warned_imaginary = true; + } + + retval = ColumnVector (tmp(0).vector_value ()); + + if (error_state) + { + eigs_error = 1; + gripe_user_supplied_eval ("eigs"); + } + } + else + { + eigs_error = 1; + gripe_user_supplied_eval ("eigs"); + } + } + + return retval; +} + +ComplexColumnVector +eigs_complex_func (const ComplexColumnVector &x, int &eigs_error) +{ + ComplexColumnVector retval; + octave_value_list args; + args(0) = x; + + if (eigs_fcn) + { + octave_value_list tmp = eigs_fcn->do_multi_index_op (1, args); + + if (error_state) + { + eigs_error = 1; + gripe_user_supplied_eval ("eigs"); + return retval; + } + + if (tmp.length () && tmp(0).is_defined ()) + { + retval = ComplexColumnVector (tmp(0).complex_vector_value ()); + + if (error_state) + { + eigs_error = 1; + gripe_user_supplied_eval ("eigs"); + } + } + else + { + eigs_error = 1; + gripe_user_supplied_eval ("eigs"); + } + } + + return retval; +} + +DEFUN_DLD (__eigs__, args, nargout, + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{d} =} __eigs__ (@var{A})\n\ +@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{A}, @var{k})\n\ +@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{A}, @var{k}, @var{sigma})\n\ +@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{A}, @var{k}, @var{sigma}, @var{opts})\n\ +@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{A}, @var{B})\n\ +@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{A}, @var{B}, @var{k})\n\ +@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{A}, @var{B}, @var{k}, @var{sigma})\n\ +@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{A}, @var{B}, @var{k}, @var{sigma}, @var{opts})\n\ +@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{af}, @var{n})\n\ +@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{af}, @var{n}, @var{B})\n\ +@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{af}, @var{n}, @var{k})\n\ +@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{af}, @var{n}, @var{B}, @var{k})\n\ +@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{af}, @var{n}, @var{k}, @var{sigma})\n\ +@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{af}, @var{n}, @var{B}, @var{k}, @var{sigma})\n\ +@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{af}, @var{n}, @var{k}, @var{sigma}, @var{opts})\n\ +@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{af}, @var{n}, @var{B}, @var{k}, @var{sigma}, @var{opts})\n\ +@deftypefnx {Loadable Function} {[@var{V}, @var{d}] =} __eigs__ (@var{A}, @dots{})\n\ +@deftypefnx {Loadable Function} {[@var{V}, @var{d}] =} __eigs__ (@var{af}, @var{n}, @dots{})\n\ +@deftypefnx {Loadable Function} {[@var{V}, @var{d}, @var{flag}] =} __eigs__ (@var{A}, @dots{})\n\ +@deftypefnx {Loadable Function} {[@var{V}, @var{d}, @var{flag}] =} __eigs__ (@var{af}, @var{n}, @dots{})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value_list retval; +#ifdef HAVE_ARPACK + int nargin = args.length (); + std::string fcn_name; + octave_idx_type n = 0; + octave_idx_type k = 6; + Complex sigma = 0.; + double sigmar, sigmai; + bool have_sigma = false; + std::string typ = "LM"; + Matrix amm, bmm, bmt; + ComplexMatrix acm, bcm, bct; + SparseMatrix asmm, bsmm, bsmt; + SparseComplexMatrix ascm, bscm, bsct; + int b_arg = 0; + bool have_b = false; + bool have_a_fun = false; + bool a_is_complex = false; + bool b_is_complex = false; + bool symmetric = false; + bool sym_tested = false; + bool cholB = false; + bool a_is_sparse = false; + ColumnVector permB; + int arg_offset = 0; + double tol = std::numeric_limits::epsilon (); + int maxit = 300; + int disp = 0; + octave_idx_type p = -1; + ColumnVector resid; + ComplexColumnVector cresid; + octave_idx_type info = 1; + + warned_imaginary = false; + + unwind_protect frame; + + frame.protect_var (call_depth); + call_depth++; + + if (call_depth > 1) + { + error ("eigs: invalid recursive call"); + if (fcn_name.length ()) + clear_function (fcn_name); + return retval; + } + + if (nargin == 0) + print_usage (); + else if (args(0).is_function_handle () || args(0).is_inline_function () + || args(0).is_string ()) + { + if (args(0).is_string ()) + { + std::string name = args(0).string_value (); + std::string fname = "function y = "; + fcn_name = unique_symbol_name ("__eigs_fcn_"); + fname.append (fcn_name); + fname.append ("(x) y = "); + eigs_fcn = extract_function (args(0), "eigs", fcn_name, fname, + "; endfunction"); + } + else + eigs_fcn = args(0).function_value (); + + if (!eigs_fcn) + { + error ("eigs: unknown function"); + return retval; + } + + if (nargin < 2) + { + error ("eigs: incorrect number of arguments"); + return retval; + } + else + { + n = args(1).nint_value (); + arg_offset = 1; + have_a_fun = true; + } + } + else + { + if (args(0).is_complex_type ()) + { + if (args(0).is_sparse_type ()) + { + ascm = (args(0).sparse_complex_matrix_value ()); + a_is_sparse = true; + } + else + acm = (args(0).complex_matrix_value ()); + a_is_complex = true; + symmetric = false; // ARPACK doesn't special case complex symmetric + sym_tested = true; + } + else + { + if (args(0).is_sparse_type ()) + { + asmm = (args(0).sparse_matrix_value ()); + a_is_sparse = true; + } + else + { + amm = (args(0).matrix_value ()); + } + } + + } + + // Note hold off reading B till later to avoid issues of double + // copies of the matrix if B is full/real while A is complex. + if (!error_state && nargin > 1 + arg_offset && + !(args(1 + arg_offset).is_real_scalar ())) + { + if (args(1+arg_offset).is_complex_type ()) + { + b_arg = 1+arg_offset; + have_b = true; + b_is_complex = true; + arg_offset++; + } + else + { + b_arg = 1+arg_offset; + have_b = true; + arg_offset++; + } + } + + if (!error_state && nargin > (1+arg_offset)) + k = args(1+arg_offset).nint_value (); + + if (!error_state && nargin > (2+arg_offset)) + { + if (args(2+arg_offset).is_string ()) + { + typ = args(2+arg_offset).string_value (); + + // Use STL function to convert to upper case + transform (typ.begin (), typ.end (), typ.begin (), toupper); + + sigma = 0.; + } + else + { + sigma = args(2+arg_offset).complex_value (); + + if (! error_state) + have_sigma = true; + else + { + error ("eigs: SIGMA must be a scalar or a string"); + return retval; + } + } + } + + sigmar = std::real (sigma); + sigmai = std::imag (sigma); + + if (!error_state && nargin > (3+arg_offset)) + { + if (args(3+arg_offset).is_map ()) + { + octave_scalar_map map = args(3+arg_offset).scalar_map_value (); + + if (! error_state) + { + octave_value tmp; + + // issym is ignored for complex matrix inputs + tmp = map.getfield ("issym"); + if (tmp.is_defined () && !sym_tested) + { + symmetric = tmp.double_value () != 0.; + sym_tested = true; + } + + // isreal is ignored if A is not a function + tmp = map.getfield ("isreal"); + if (tmp.is_defined () && have_a_fun) + a_is_complex = ! (tmp.double_value () != 0.); + + tmp = map.getfield ("tol"); + if (tmp.is_defined ()) + tol = tmp.double_value (); + + tmp = map.getfield ("maxit"); + if (tmp.is_defined ()) + maxit = tmp.nint_value (); + + tmp = map.getfield ("p"); + if (tmp.is_defined ()) + p = tmp.nint_value (); + + tmp = map.getfield ("v0"); + if (tmp.is_defined ()) + { + if (a_is_complex || b_is_complex) + cresid = ComplexColumnVector (tmp.complex_vector_value ()); + else + resid = ColumnVector (tmp.vector_value ()); + } + + tmp = map.getfield ("disp"); + if (tmp.is_defined ()) + disp = tmp.nint_value (); + + tmp = map.getfield ("cholB"); + if (tmp.is_defined ()) + cholB = tmp.double_value () != 0.; + + tmp = map.getfield ("permB"); + if (tmp.is_defined ()) + permB = ColumnVector (tmp.vector_value ()) - 1.0; + } + else + { + error ("eigs: OPTS argument must be a scalar structure"); + return retval; + } + } + else + { + error ("eigs: OPTS argument must be a structure"); + return retval; + } + } + + if (nargin > (4+arg_offset)) + { + error ("eigs: incorrect number of arguments"); + return retval; + } + + // Test undeclared (no issym) matrix inputs for symmetry + if (!sym_tested && !have_a_fun) + { + if (a_is_sparse) + symmetric = asmm.is_symmetric (); + else + symmetric = amm.is_symmetric (); + } + + if (have_b) + { + if (a_is_complex || b_is_complex) + { + if (a_is_sparse) + bscm = args(b_arg).sparse_complex_matrix_value (); + else + bcm = args(b_arg).complex_matrix_value (); + } + else + { + if (a_is_sparse) + bsmm = args(b_arg).sparse_matrix_value (); + else + bmm = args(b_arg).matrix_value (); + } + } + + // Mode 1 for SM mode seems unstable for some reason. + // Use Mode 3 instead, with sigma = 0. + if (!error_state && !have_sigma && typ == "SM") + have_sigma = true; + + if (!error_state) + { + octave_idx_type nconv; + if (a_is_complex || b_is_complex) + { + ComplexMatrix eig_vec; + ComplexColumnVector eig_val; + + + if (have_a_fun) + nconv = EigsComplexNonSymmetricFunc + (eigs_complex_func, n, typ, sigma, k, p, info, eig_vec, eig_val, + cresid, octave_stdout, tol, (nargout > 1), cholB, disp, maxit); + else if (have_sigma) + { + if (a_is_sparse) + nconv = EigsComplexNonSymmetricMatrixShift + (ascm, sigma, k, p, info, eig_vec, eig_val, bscm, permB, + cresid, octave_stdout, tol, (nargout > 1), cholB, disp, + maxit); + else + nconv = EigsComplexNonSymmetricMatrixShift + (acm, sigma, k, p, info, eig_vec, eig_val, bcm, permB, cresid, + octave_stdout, tol, (nargout > 1), cholB, disp, maxit); + } + else + { + if (a_is_sparse) + nconv = EigsComplexNonSymmetricMatrix + (ascm, typ, k, p, info, eig_vec, eig_val, bscm, permB, cresid, + octave_stdout, tol, (nargout > 1), cholB, disp, maxit); + else + nconv = EigsComplexNonSymmetricMatrix + (acm, typ, k, p, info, eig_vec, eig_val, bcm, permB, cresid, + octave_stdout, tol, (nargout > 1), cholB, disp, maxit); + } + + if (nargout < 2) + retval(0) = eig_val; + else + { + retval(2) = double (info); + retval(1) = ComplexDiagMatrix (eig_val); + retval(0) = eig_vec; + } + } + else if (sigmai != 0.) + { + // Promote real problem to a complex one. + ComplexMatrix eig_vec; + ComplexColumnVector eig_val; + + if (have_a_fun) + nconv = EigsComplexNonSymmetricFunc + (eigs_complex_func, n, typ, sigma, k, p, info, eig_vec, eig_val, + cresid, octave_stdout, tol, (nargout > 1), cholB, disp, maxit); + else + { + if (a_is_sparse) + nconv = EigsComplexNonSymmetricMatrixShift + (SparseComplexMatrix (asmm), sigma, k, p, info, eig_vec, + eig_val, SparseComplexMatrix (bsmm), permB, cresid, + octave_stdout, tol, (nargout > 1), cholB, disp, maxit); + else + nconv = EigsComplexNonSymmetricMatrixShift + (ComplexMatrix (amm), sigma, k, p, info, eig_vec, + eig_val, ComplexMatrix (bmm), permB, cresid, + octave_stdout, tol, (nargout > 1), cholB, disp, maxit); + } + + if (nargout < 2) + retval(0) = eig_val; + else + { + retval(2) = double (info); + retval(1) = ComplexDiagMatrix (eig_val); + retval(0) = eig_vec; + } + } + else + { + if (symmetric) + { + Matrix eig_vec; + ColumnVector eig_val; + + if (have_a_fun) + nconv = EigsRealSymmetricFunc + (eigs_func, n, typ, sigmar, k, p, info, eig_vec, eig_val, + resid, octave_stdout, tol, (nargout > 1), cholB, disp, + maxit); + else if (have_sigma) + { + if (a_is_sparse) + nconv = EigsRealSymmetricMatrixShift + (asmm, sigmar, k, p, info, eig_vec, eig_val, bsmm, permB, + resid, octave_stdout, tol, (nargout > 1), cholB, disp, + maxit); + else + nconv = EigsRealSymmetricMatrixShift + (amm, sigmar, k, p, info, eig_vec, eig_val, bmm, permB, + resid, octave_stdout, tol, (nargout > 1), cholB, disp, + maxit); + } + else + { + if (a_is_sparse) + nconv = EigsRealSymmetricMatrix + (asmm, typ, k, p, info, eig_vec, eig_val, bsmm, permB, + resid, octave_stdout, tol, (nargout > 1), cholB, disp, + maxit); + else + nconv = EigsRealSymmetricMatrix + (amm, typ, k, p, info, eig_vec, eig_val, bmm, permB, + resid, octave_stdout, tol, (nargout > 1), cholB, disp, + maxit); + } + + if (nargout < 2) + retval(0) = eig_val; + else + { + retval(2) = double (info); + retval(1) = DiagMatrix (eig_val); + retval(0) = eig_vec; + } + } + else + { + ComplexMatrix eig_vec; + ComplexColumnVector eig_val; + + if (have_a_fun) + nconv = EigsRealNonSymmetricFunc + (eigs_func, n, typ, sigmar, k, p, info, eig_vec, eig_val, + resid, octave_stdout, tol, (nargout > 1), cholB, disp, + maxit); + else if (have_sigma) + { + if (a_is_sparse) + nconv = EigsRealNonSymmetricMatrixShift + (asmm, sigmar, k, p, info, eig_vec, eig_val, bsmm, permB, + resid, octave_stdout, tol, (nargout > 1), cholB, disp, + maxit); + else + nconv = EigsRealNonSymmetricMatrixShift + (amm, sigmar, k, p, info, eig_vec, eig_val, bmm, permB, + resid, octave_stdout, tol, (nargout > 1), cholB, disp, + maxit); + } + else + { + if (a_is_sparse) + nconv = EigsRealNonSymmetricMatrix + (asmm, typ, k, p, info, eig_vec, eig_val, bsmm, permB, + resid, octave_stdout, tol, (nargout > 1), cholB, disp, + maxit); + else + nconv = EigsRealNonSymmetricMatrix + (amm, typ, k, p, info, eig_vec, eig_val, bmm, permB, + resid, octave_stdout, tol, (nargout > 1), cholB, disp, + maxit); + } + + if (nargout < 2) + retval(0) = eig_val; + else + { + retval(2) = double (info); + retval(1) = ComplexDiagMatrix (eig_val); + retval(0) = eig_vec; + } + } + } + + if (nconv <= 0) + warning ("eigs: None of the %d requested eigenvalues converged", k); + else if (nconv < k) + warning ("eigs: Only %d of the %d requested eigenvalues converged", + nconv, k); + } + + if (! fcn_name.empty ()) + clear_function (fcn_name); +#else + error ("eigs: not available in this version of Octave"); +#endif + + return retval; +} diff -r 20d1b911b4e7 -r c702371ff6df libinterp/dldfcn/__glpk__.cc --- a/libinterp/dldfcn/__glpk__.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/dldfcn/__glpk__.cc Sat Oct 05 11:22:09 2013 -0400 @@ -1,6 +1,7 @@ /* Copyright (C) 2005-2012 Nicolo' Giorgetti +Copyright (C) 2013 Sébastien Villemot This file is part of Octave. @@ -46,191 +47,86 @@ #else #include #endif - -#if 0 -#ifdef GLPK_PRE_4_14 - -#ifndef _GLPLIB_H -#include -#endif -#ifndef lib_set_fault_hook -#define lib_set_fault_hook lib_fault_hook -#endif -#ifndef lib_set_print_hook -#define lib_set_print_hook lib_print_hook -#endif - -#else - -void _glp_lib_print_hook (int (*func)(void *info, char *buf), void *info); -void _glp_lib_fault_hook (int (*func)(void *info, char *buf), void *info); - -#endif -#endif } -#define NIntP 17 -#define NRealP 10 - -int lpxIntParam[NIntP] = { - 0, - 1, - 0, - 1, - 0, - -1, - 0, - 200, - 1, - 2, - 0, - 1, - 0, - 0, - 2, - 2, - 1 -}; - -int IParam[NIntP] = { - LPX_K_MSGLEV, - LPX_K_SCALE, - LPX_K_DUAL, - LPX_K_PRICE, - LPX_K_ROUND, - LPX_K_ITLIM, - LPX_K_ITCNT, - LPX_K_OUTFRQ, - LPX_K_MPSINFO, - LPX_K_MPSOBJ, - LPX_K_MPSORIG, - LPX_K_MPSWIDE, - LPX_K_MPSFREE, - LPX_K_MPSSKIP, - LPX_K_BRANCH, - LPX_K_BTRACK, - LPX_K_PRESOL -}; - - -double lpxRealParam[NRealP] = { - 0.07, - 1e-7, - 1e-7, - 1e-9, - -std::numeric_limits::max (), - std::numeric_limits::max (), - -1.0, - 0.0, - 1e-6, - 1e-7 -}; - -int RParam[NRealP] = { - LPX_K_RELAX, - LPX_K_TOLBND, - LPX_K_TOLDJ, - LPX_K_TOLPIV, - LPX_K_OBJLL, - LPX_K_OBJUL, - LPX_K_TMLIM, - LPX_K_OUTDLY, - LPX_K_TOLINT, - LPX_K_TOLOBJ +struct control_params +{ + int msglev; + int dual; + int price; + int itlim; + int outfrq; + int branch; + int btrack; + int presol; + int rtest; + int tmlim; + int outdly; + double tolbnd; + double toldj; + double tolpiv; + double objll; + double objul; + double tolint; + double tolobj; }; static jmp_buf mark; //-- Address for long jump to jump to -#if 0 -int -glpk_fault_hook (void * /* info */, char *msg) -{ - error ("CRITICAL ERROR in GLPK: %s", msg); - longjmp (mark, -1); -} - -int -glpk_print_hook (void * /* info */, char *msg) -{ - message (0, "%s", msg); - return 1; -} -#endif - int glpk (int sense, int n, int m, double *c, int nz, int *rn, int *cn, double *a, double *b, char *ctype, int *freeLB, double *lb, int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver, - int save_pb, double *xmin, double *fmin, double *status, - double *lambda, double *redcosts, double *time, double *mem) + int save_pb, int scale, const control_params *par, + double *xmin, double *fmin, int *status, + double *lambda, double *redcosts, double *time) { - int errnum; int typx = 0; - int method; + int errnum = 0; clock_t t_start = clock (); -#if 0 -#ifdef GLPK_PRE_4_14 - lib_set_fault_hook (0, glpk_fault_hook); -#else - _glp_lib_fault_hook (glpk_fault_hook, 0); -#endif - - if (lpxIntParam[0] > 1) -#ifdef GLPK_PRE_4_14 - lib_set_print_hook (0, glpk_print_hook); -#else - _glp_lib_print_hook (glpk_print_hook, 0); -#endif -#endif - - LPX *lp = lpx_create_prob (); - + glp_prob *lp = glp_create_prob (); //-- Set the sense of optimization if (sense == 1) - lpx_set_obj_dir (lp, LPX_MIN); + glp_set_obj_dir (lp, GLP_MIN); else - lpx_set_obj_dir (lp, LPX_MAX); + glp_set_obj_dir (lp, GLP_MAX); - //-- If the problem has integer structural variables switch to MIP - if (isMIP) - lpx_set_class (lp, LPX_MIP); - - lpx_add_cols (lp, n); + glp_add_cols (lp, n); for (int i = 0; i < n; i++) { //-- Define type of the structural variables if (! freeLB[i] && ! freeUB[i]) { if (lb[i] != ub[i]) - lpx_set_col_bnds (lp, i+1, LPX_DB, lb[i], ub[i]); + glp_set_col_bnds (lp, i+1, GLP_DB, lb[i], ub[i]); else - lpx_set_col_bnds (lp, i+1, LPX_FX, lb[i], ub[i]); + glp_set_col_bnds (lp, i+1, GLP_FX, lb[i], ub[i]); } else { if (! freeLB[i] && freeUB[i]) - lpx_set_col_bnds (lp, i+1, LPX_LO, lb[i], ub[i]); + glp_set_col_bnds (lp, i+1, GLP_LO, lb[i], ub[i]); else { if (freeLB[i] && ! freeUB[i]) - lpx_set_col_bnds (lp, i+1, LPX_UP, lb[i], ub[i]); + glp_set_col_bnds (lp, i+1, GLP_UP, lb[i], ub[i]); else - lpx_set_col_bnds (lp, i+1, LPX_FR, lb[i], ub[i]); + glp_set_col_bnds (lp, i+1, GLP_FR, lb[i], ub[i]); } } // -- Set the objective coefficient of the corresponding // -- structural variable. No constant term is assumed. - lpx_set_obj_coef(lp,i+1,c[i]); + glp_set_obj_coef(lp,i+1,c[i]); if (isMIP) - lpx_set_col_kind (lp, i+1, vartype[i]); + glp_set_col_kind (lp, i+1, vartype[i]); } - lpx_add_rows (lp, m); + glp_add_rows (lp, m); for (int i = 0; i < m; i++) { @@ -245,124 +141,123 @@ switch (ctype[i]) { case 'F': - typx = LPX_FR; + typx = GLP_FR; break; case 'U': - typx = LPX_UP; + typx = GLP_UP; break; case 'L': - typx = LPX_LO; + typx = GLP_LO; break; case 'S': - typx = LPX_FX; + typx = GLP_FX; break; case 'D': - typx = LPX_DB; + typx = GLP_DB; break; } - lpx_set_row_bnds (lp, i+1, typx, b[i], b[i]); + glp_set_row_bnds (lp, i+1, typx, b[i], b[i]); } - lpx_load_matrix (lp, nz, rn, cn, a); + glp_load_matrix (lp, nz, rn, cn, a); if (save_pb) { static char tmp[] = "outpb.lp"; - if (lpx_write_cpxlp (lp, tmp) != 0) + if (glp_write_lp (lp, NULL, tmp) != 0) { error ("__glpk__: unable to write problem"); longjmp (mark, -1); } } - //-- scale the problem data (if required) - //-- if (scale && (!presol || method == 1)) lpx_scale_prob (lp); - //-- LPX_K_SCALE=IParam[1] LPX_K_PRESOL=IParam[16] - if (lpxIntParam[1] && (! lpxIntParam[16] || lpsolver != 1)) - lpx_scale_prob (lp); + //-- scale the problem data + if (!par->presol || lpsolver != 1) + glp_scale_prob (lp, scale); //-- build advanced initial basis (if required) - if (lpsolver == 1 && ! lpxIntParam[16]) - lpx_adv_basis (lp); - - for (int i = 0; i < NIntP; i++) - lpx_set_int_parm (lp, IParam[i], lpxIntParam[i]); + if (lpsolver == 1 && !par->presol) + glp_adv_basis (lp, 0); - for (int i = 0; i < NRealP; i++) - lpx_set_real_parm (lp, RParam[i], lpxRealParam[i]); - - if (lpsolver == 1) - method = 'S'; - else - method = 'T'; - - switch (method) + /* For MIP problems without a presolver, a first pass with glp_simplex + is required */ + if ((!isMIP && lpsolver == 1) + || (isMIP && !par->presol)) { - case 'S': - { - if (isMIP) - { - method = 'I'; - errnum = lpx_simplex (lp); - errnum = lpx_integer (lp); - } - else - errnum = lpx_simplex (lp); - } - break; - - case 'T': - errnum = lpx_interior (lp); - break; - - default: - break; -#if 0 -#ifdef GLPK_PRE_4_14 - insist (method != method); -#else - static char tmp[] = "method != method"; - glpk_fault_hook (0, tmp); -#endif -#endif + glp_smcp smcp; + glp_init_smcp (&smcp); + smcp.msg_lev = par->msglev; + smcp.meth = par->dual; + smcp.pricing = par->price; + smcp.r_test = par->rtest; + smcp.tol_bnd = par->tolbnd; + smcp.tol_dj = par->toldj; + smcp.tol_piv = par->tolpiv; + smcp.obj_ll = par->objll; + smcp.obj_ul = par->objul; + smcp.it_lim = par->itlim; + smcp.tm_lim = par->tmlim; + smcp.out_frq = par->outfrq; + smcp.out_dly = par->outdly; + smcp.presolve = par->presol; + errnum = glp_simplex (lp, &smcp); } - /* errnum assumes the following results: - errnum = 0 <=> No errors - errnum = 1 <=> Iteration limit exceeded. - errnum = 2 <=> Numerical problems with basis matrix. - */ - if (errnum == LPX_E_OK) + if (isMIP) + { + glp_iocp iocp; + glp_init_iocp (&iocp); + iocp.msg_lev = par->msglev; + iocp.br_tech = par->branch; + iocp.bt_tech = par->btrack; + iocp.tol_int = par->tolint; + iocp.tol_obj = par->tolobj; + iocp.tm_lim = par->tmlim; + iocp.out_frq = par->outfrq; + iocp.out_dly = par->outdly; + iocp.presolve = par->presol; + errnum = glp_intopt (lp, &iocp); + } + + if (!isMIP && lpsolver == 2) + { + glp_iptcp iptcp; + glp_init_iptcp (&iptcp); + iptcp.msg_lev = par->msglev; + errnum = glp_interior (lp, &iptcp); + } + + if (errnum == 0) { if (isMIP) { - *status = lpx_mip_status (lp); - *fmin = lpx_mip_obj_val (lp); + *status = glp_mip_status (lp); + *fmin = glp_mip_obj_val (lp); } else { if (lpsolver == 1) { - *status = lpx_get_status (lp); - *fmin = lpx_get_obj_val (lp); + *status = glp_get_status (lp); + *fmin = glp_get_obj_val (lp); } else { - *status = lpx_ipt_status (lp); - *fmin = lpx_ipt_obj_val (lp); + *status = glp_ipt_status (lp); + *fmin = glp_ipt_obj_val (lp); } } if (isMIP) { for (int i = 0; i < n; i++) - xmin[i] = lpx_mip_col_val (lp, i+1); + xmin[i] = glp_mip_col_val (lp, i+1); } else { @@ -370,52 +265,41 @@ for (int i = 0; i < n; i++) { if (lpsolver == 1) - xmin[i] = lpx_get_col_prim (lp, i+1); + xmin[i] = glp_get_col_prim (lp, i+1); else - xmin[i] = lpx_ipt_col_prim (lp, i+1); + xmin[i] = glp_ipt_col_prim (lp, i+1); } /* Dual values */ for (int i = 0; i < m; i++) { if (lpsolver == 1) - lambda[i] = lpx_get_row_dual (lp, i+1); + lambda[i] = glp_get_row_dual (lp, i+1); else - lambda[i] = lpx_ipt_row_dual (lp, i+1); + lambda[i] = glp_ipt_row_dual (lp, i+1); } /* Reduced costs */ - for (int i = 0; i < lpx_get_num_cols (lp); i++) + for (int i = 0; i < glp_get_num_cols (lp); i++) { if (lpsolver == 1) - redcosts[i] = lpx_get_col_dual (lp, i+1); + redcosts[i] = glp_get_col_dual (lp, i+1); else - redcosts[i] = lpx_ipt_col_dual (lp, i+1); + redcosts[i] = glp_ipt_col_dual (lp, i+1); } } *time = (clock () - t_start) / CLOCKS_PER_SEC; - -#ifdef GLPK_PRE_4_14 - *mem = (lib_env_ptr () -> mem_tpeak); -#else - *mem = 0; -#endif - - lpx_delete_prob (lp); - return 0; } - lpx_delete_prob (lp); - - *status = errnum; + glp_delete_prob (lp); return errnum; } #endif -#define OCTAVE_GLPK_GET_REAL_PARAM(NAME, IDX) \ +#define OCTAVE_GLPK_GET_REAL_PARAM(NAME, VAL) \ do \ { \ octave_value tmp = PARAM.getfield (NAME); \ @@ -424,7 +308,7 @@ { \ if (! tmp.is_empty ()) \ { \ - lpxRealParam[IDX] = tmp.scalar_value (); \ + VAL = tmp.scalar_value (); \ \ if (error_state) \ { \ @@ -659,10 +543,10 @@ if (VTYPE(i,0) == 'I') { isMIP = 1; - vartype(i) = LPX_IV; + vartype(i) = GLP_IV; } else - vartype(i) = LPX_CV; + vartype(i) = GLP_CV; } //-- 8th Input. Sense of optimization. @@ -689,78 +573,78 @@ return retval; } + control_params par; + //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //-- Integer parameters //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //-- Level of messages output by the solver - OCTAVE_GLPK_GET_INT_PARAM ("msglev", lpxIntParam[0]); - if (lpxIntParam[0] < 0 || lpxIntParam[0] > 3) + par.msglev = 1; + OCTAVE_GLPK_GET_INT_PARAM ("msglev", par.msglev); + if (par.msglev < 0 || par.msglev > 3) { - error ("__glpk__: PARAM.msglev must be 0 (no output [default]) or 1 (error messages only) or 2 (normal output) or 3 (full output)"); + error ("__glpk__: PARAM.msglev must be 0 (no output) or 1 (error and warning messages only [default]) or 2 (normal output) or 3 (full output)"); return retval; } //-- scaling option - OCTAVE_GLPK_GET_INT_PARAM ("scale", lpxIntParam[1]); - if (lpxIntParam[1] < 0 || lpxIntParam[1] > 2) + volatile int scale = 16; + OCTAVE_GLPK_GET_INT_PARAM ("scale", scale); + if (scale < 0 || scale > 128) { - error ("__glpk__: PARAM.scale must be 0 (no scaling) or 1 (equilibration scaling [default]) or 2 (geometric mean scaling)"); + error ("__glpk__: PARAM.scale must either be 128 (automatic selection of scaling options), or a bitwise or of: 1 (geometric mean scaling), 16 (equilibration scaling), 32 (round scale factors to power of two), 64 (skip if problem is well scaled"); return retval; } - //-- Dual dimplex option - OCTAVE_GLPK_GET_INT_PARAM ("dual", lpxIntParam[2]); - if (lpxIntParam[2] < 0 || lpxIntParam[2] > 1) + //-- Dual simplex option + par.dual = 1; + OCTAVE_GLPK_GET_INT_PARAM ("dual", par.dual); + if (par.dual < 1 || par.dual > 3) { - error ("__glpk__: PARAM.dual must be 0 (do NOT use dual simplex [default]) or 1 (use dual simplex)"); + error ("__glpk__: PARAM.dual must be 1 (use two-phase primal simplex [default]) or 2 (use two-phase dual simplex) or 3 (use two-phase dual simplex, and if it fails, switch to the primal simplex)"); return retval; } //-- Pricing option - OCTAVE_GLPK_GET_INT_PARAM ("price", lpxIntParam[3]); - if (lpxIntParam[3] < 0 || lpxIntParam[3] > 1) + par.price = 34; + OCTAVE_GLPK_GET_INT_PARAM ("price", par.price); + if (par.price != 17 && par.price != 34) { - error ("__glpk__: PARAM.price must be 0 (textbook pricing) or 1 (steepest edge pricing [default])"); - return retval; - } - - //-- Solution rounding option - OCTAVE_GLPK_GET_INT_PARAM ("round", lpxIntParam[4]); - if (lpxIntParam[4] < 0 || lpxIntParam[4] > 1) - { - error ("__glpk__: PARAM.round must be 0 (report all primal and dual values [default]) or 1 (replace tiny primal and dual values by exact zero)"); + error ("__glpk__: PARAM.price must be 17 (textbook pricing) or 34 (steepest edge pricing [default])"); return retval; } //-- Simplex iterations limit - OCTAVE_GLPK_GET_INT_PARAM ("itlim", lpxIntParam[5]); - - //-- Simplex iterations count - OCTAVE_GLPK_GET_INT_PARAM ("itcnt", lpxIntParam[6]); + par.itlim = std::numeric_limits::max (); + OCTAVE_GLPK_GET_INT_PARAM ("itlim", par.itlim); //-- Output frequency, in iterations - OCTAVE_GLPK_GET_INT_PARAM ("outfrq", lpxIntParam[7]); + par.outfrq = 200; + OCTAVE_GLPK_GET_INT_PARAM ("outfrq", par.outfrq); //-- Branching heuristic option - OCTAVE_GLPK_GET_INT_PARAM ("branch", lpxIntParam[14]); - if (lpxIntParam[14] < 0 || lpxIntParam[14] > 2) + par.branch = 4; + OCTAVE_GLPK_GET_INT_PARAM ("branch", par.branch); + if (par.branch < 1 || par.branch > 5) { - error ("__glpk__: PARAM.branch must be (MIP only) 0 (branch on first variable) or 1 (branch on last variable) or 2 (branch using a heuristic by Driebeck and Tomlin [default]"); + error ("__glpk__: PARAM.branch must be 1 (first fractional variable) or 2 (last fractional variable) or 3 (most fractional variable) or 4 (heuristic by Driebeck and Tomlin [default]) or 5 (hybrid pseudocost heuristic)"); return retval; } //-- Backtracking heuristic option - OCTAVE_GLPK_GET_INT_PARAM ("btrack", lpxIntParam[15]); - if (lpxIntParam[15] < 0 || lpxIntParam[15] > 2) + par.btrack = 4; + OCTAVE_GLPK_GET_INT_PARAM ("btrack", par.btrack); + if (par.btrack < 1 || par.btrack > 4) { - error ("__glpk__: PARAM.btrack must be (MIP only) 0 (depth first search) or 1 (breadth first search) or 2 (backtrack using the best projection heuristic [default]"); + error ("__glpk__: PARAM.btrack must be 1 (depth first search) or 2 (breadth first search) or 3 (best local bound) or 4 (best projection heuristic [default]"); return retval; } //-- Presolver option - OCTAVE_GLPK_GET_INT_PARAM ("presol", lpxIntParam[16]); - if (lpxIntParam[16] < 0 || lpxIntParam[16] > 1) + par.presol = 1; + OCTAVE_GLPK_GET_INT_PARAM ("presol", par.presol); + if (par.presol < 0 || par.presol > 1) { error ("__glpk__: PARAM.presol must be 0 (do NOT use LP presolver) or 1 (use LP presolver [default])"); return retval; @@ -775,6 +659,21 @@ return retval; } + //-- Ratio test option + par.rtest = 34; + OCTAVE_GLPK_GET_INT_PARAM ("rtest", par.rtest); + if (par.rtest != 17 && par.rtest != 34) + { + error ("__glpk__: PARAM.rtest must be 17 (standard ratio test) or 34 (Harris' two-pass ratio test [default])"); + return retval; + } + + par.tmlim = std::numeric_limits::max (); + OCTAVE_GLPK_GET_INT_PARAM ("tmlim", par.tmlim); + + par.outdly = 0; + OCTAVE_GLPK_GET_INT_PARAM ("outdly", par.outdly); + //-- Save option volatile int save_pb = 0; OCTAVE_GLPK_GET_INT_PARAM ("save", save_pb); @@ -784,51 +683,50 @@ //-- Real parameters //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - //-- Ratio test option - OCTAVE_GLPK_GET_REAL_PARAM ("relax", 0); - //-- Relative tolerance used to check if the current basic solution //-- is primal feasible - OCTAVE_GLPK_GET_REAL_PARAM ("tolbnd", 1); + par.tolbnd = 1e-7; + OCTAVE_GLPK_GET_REAL_PARAM ("tolbnd", par.tolbnd); //-- Absolute tolerance used to check if the current basic solution //-- is dual feasible - OCTAVE_GLPK_GET_REAL_PARAM ("toldj", 2); + par.toldj = 1e-7; + OCTAVE_GLPK_GET_REAL_PARAM ("toldj", par.toldj); //-- Relative tolerance used to choose eligible pivotal elements of //-- the simplex table in the ratio test - OCTAVE_GLPK_GET_REAL_PARAM ("tolpiv", 3); + par.tolpiv = 1e-10; + OCTAVE_GLPK_GET_REAL_PARAM ("tolpiv", par.tolpiv); - OCTAVE_GLPK_GET_REAL_PARAM ("objll", 4); - - OCTAVE_GLPK_GET_REAL_PARAM ("objul", 5); + par.objll = -std::numeric_limits::max (); + OCTAVE_GLPK_GET_REAL_PARAM ("objll", par.objll); - OCTAVE_GLPK_GET_REAL_PARAM ("tmlim", 6); - - OCTAVE_GLPK_GET_REAL_PARAM ("outdly", 7); + par.objul = std::numeric_limits::max (); + OCTAVE_GLPK_GET_REAL_PARAM ("objul", par.objul); - OCTAVE_GLPK_GET_REAL_PARAM ("tolint", 8); + par.tolint = 1e-5; + OCTAVE_GLPK_GET_REAL_PARAM ("tolint", par.tolint); - OCTAVE_GLPK_GET_REAL_PARAM ("tolobj", 9); + par.tolobj = 1e-7; + OCTAVE_GLPK_GET_REAL_PARAM ("tolobj", par.tolobj); //-- Assign pointers to the output parameters ColumnVector xmin (mrowsc, octave_NA); double fmin = octave_NA; - double status; ColumnVector lambda (mrowsA, octave_NA); ColumnVector redcosts (mrowsc, octave_NA); double time; - double mem; + int status, errnum = 0; int jmpret = setjmp (mark); if (jmpret == 0) - glpk (sense, mrowsc, mrowsA, c, nz, rn.fortran_vec (), - cn.fortran_vec (), a.fortran_vec (), b, ctype, - freeLB.fortran_vec (), lb, freeUB.fortran_vec (), ub, - vartype.fortran_vec (), isMIP, lpsolver, save_pb, - xmin.fortran_vec (), &fmin, &status, lambda.fortran_vec (), - redcosts.fortran_vec (), &time, &mem); + errnum = glpk (sense, mrowsc, mrowsA, c, nz, rn.fortran_vec (), + cn.fortran_vec (), a.fortran_vec (), b, ctype, + freeLB.fortran_vec (), lb, freeUB.fortran_vec (), ub, + vartype.fortran_vec (), isMIP, lpsolver, save_pb, scale, &par, + xmin.fortran_vec (), &fmin, &status, lambda.fortran_vec (), + redcosts.fortran_vec (), &time); octave_scalar_map extra; @@ -839,10 +737,10 @@ } extra.assign ("time", time); - extra.assign ("mem", mem); + extra.assign ("status", status); retval(3) = extra; - retval(2) = status; + retval(2) = errnum; retval(1) = fmin; retval(0) = xmin; diff -r 20d1b911b4e7 -r c702371ff6df libinterp/dldfcn/__init_fltk__.cc --- a/libinterp/dldfcn/__init_fltk__.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/dldfcn/__init_fltk__.cc Sat Oct 05 11:22:09 2013 -0400 @@ -255,7 +255,7 @@ }; // Parameter controlling how fast we zoom when using the scrool wheel. -static double wheel_zoom_speed = 0.05; +static double Vwheel_zoom_speed = 0.05; // Parameter controlling the GUI mode. static enum { pan_zoom, rotate_zoom, none } gui_mode; @@ -662,10 +662,10 @@ friend class fltk_uimenu; public: plot_window (int xx, int yy, int ww, int hh, figure::properties& xfp) - : Fl_Window (xx, yy, ww, hh, "octave"), window_label (), shift (0), - ndim (2), fp (xfp), canvas (0), autoscale (0), togglegrid (0), - panzoom (0), rotate (0), help (0), status (0), - ax_obj (), pos_x (0), pos_y (0) + : Fl_Window (xx, yy - menu_h, ww, hh + menu_h + status_h, "octave"), + window_label (), shift (0), ndim (2), fp (xfp), canvas (0), + autoscale (0), togglegrid (0), panzoom (0), rotate (0), help (0), + status (0), ax_obj (), pos_x (0), pos_y (0) { callback (window_close, static_cast (this)); size_range (4*status_h, 2*status_h); @@ -680,32 +680,38 @@ begin (); { + // bbox of plot canvas = [xx, yy, ww, hh]; + // (xx, yy) = UL coordinate relative to UL window. - canvas = new OpenGL_fltk (0, 0, ww, hh - status_h, number ()); + canvas = new OpenGL_fltk (0, menu_h, ww, hh, number ()); uimenu = new fltk_uimenu (0, 0, ww, menu_h); uimenu->hide (); - bottom = new Fl_Box (0, hh - status_h, ww, status_h); + // Toolbar is a composite of "bottom", "autoscale", "togglegrid", + // "panzoom", "rotate", "help", and "status". + + yy = hh + menu_h; + bottom = new Fl_Box (0, yy, ww, status_h); bottom->box (FL_FLAT_BOX); ndim = calc_dimensions (gh_manager::get_object (fp.get___myhandle__ ())); - autoscale = new Fl_Button (0, hh - status_h, status_h, status_h, "A"); + autoscale = new Fl_Button (0, yy, status_h, status_h, "A"); autoscale->callback (button_callback, static_cast (this)); autoscale->tooltip ("Autoscale"); - togglegrid = new Fl_Button (status_h, hh - status_h, status_h, + togglegrid = new Fl_Button (status_h, yy, status_h, status_h, "G"); togglegrid->callback (button_callback, static_cast (this)); togglegrid->tooltip ("Toggle Grid"); - panzoom = new Fl_Button (2 * status_h, hh - status_h, status_h, + panzoom = new Fl_Button (2 * status_h, yy, status_h, status_h, "P"); panzoom->callback (button_callback, static_cast (this)); panzoom->tooltip ("Mouse Pan/Zoom"); - rotate = new Fl_Button (3 * status_h, hh - status_h, status_h, + rotate = new Fl_Button (3 * status_h, yy, status_h, status_h, "R"); rotate->callback (button_callback, static_cast (this)); rotate->tooltip ("Mouse Rotate"); @@ -713,12 +719,12 @@ if (ndim == 2) rotate->deactivate (); - help = new Fl_Button (4 * status_h, hh - status_h, status_h, + help = new Fl_Button (4 * status_h, yy, status_h, status_h, "?"); help->callback (button_callback, static_cast (this)); help->tooltip ("Help"); - status = new Fl_Output (5 * status_h, hh - status_h, + status = new Fl_Output (5 * status_h, yy, ww > 2*status_h ? ww - status_h : 0, status_h, ""); @@ -799,10 +805,7 @@ { if (!uimenu->is_visible ()) { - canvas->resize (canvas->x (), - canvas->y () + menu_h, - canvas->w (), - canvas->h () - menu_h); + // FIXME - Toolbar and menubar do not update uimenu->show (); mark_modified (); } @@ -812,10 +815,7 @@ { if (uimenu->is_visible ()) { - canvas->resize (canvas->x (), - canvas->y () - menu_h, - canvas->w (), - canvas->h () + menu_h); + // FIXME - Toolbar and menubar do not update uimenu->hide (); mark_modified (); } @@ -1108,8 +1108,12 @@ { Matrix pos (1,2,0); pos(0) = px; - pos(1) = h () - status_h - menu_h - py; + pos(1) = h () - (py + status_h + menu_dy ()); fp.set_currentpoint (pos); + graphics_object robj = gh_manager::get_object (fp.get_parent ()); + root_figure::properties& rp = + dynamic_cast (robj.get_properties ()); + rp.set_currentfigure (fp.get___myhandle__ ().value ()); } } @@ -1130,9 +1134,18 @@ pos(1,1) = yy; ap.set_currentpoint (pos); + fp.set_currentaxes (ap.get___myhandle__ ().value ()); } } + int menu_dy () + { + if (uimenu->is_visible ()) + return menu_h; + else + return 0; + } + int key2shift (int key) { if (key == FL_Shift_L || key == FL_Shift_R) @@ -1181,17 +1194,35 @@ Matrix pos (1,4,0); pos(0) = xx; - pos(1) = yy; + pos(1) = yy + menu_dy (); pos(2) = ww; - pos(3) = hh - status_h - menu_h; + pos(3) = hh - menu_dy () - status_h; fp.set_boundingbox (pos, true); } void draw (void) { + // FIXME - Toolbar and menubar do not update properly Matrix pos = fp.get_boundingbox (true); - Fl_Window::resize (pos(0), pos(1), pos(2), pos(3) + status_h + menu_h); + int canvas_h = pos(3); + int canvas_w = pos(2); + int canvas_y = menu_dy (); + int toolbar_y = menu_dy () + canvas_h; + pos(1) = pos(1) - menu_dy (); + pos(3) = pos(3) + menu_dy () + status_h; + + Fl_Window::resize (pos(0), pos(1), pos(2), pos(3)); + + bottom->resize (0, toolbar_y, status_h, status_h); + autoscale->resize (0, toolbar_y, status_h, status_h); + togglegrid->resize (status_h, toolbar_y, status_h, status_h); + panzoom->resize (2 * status_h, toolbar_y, status_h, status_h); + rotate->resize (3 * status_h, toolbar_y, status_h, status_h); + help->resize (4 * status_h, toolbar_y, status_h, status_h); + status->resize (5 * status_h, toolbar_y, pos(2) - 4 * status_h, status_h); + if (canvas->valid ()) + canvas->resize (0, canvas_y, canvas_w, canvas_h); return Fl_Window::draw (); } @@ -1268,15 +1299,15 @@ break; case FL_MOVE: - pixel2status (pixel2axes_or_ca (Fl::event_x (), Fl::event_y ()), - Fl::event_x (), Fl::event_y ()); + pixel2status (pixel2axes_or_ca (Fl::event_x (), Fl::event_y () - menu_dy ()), + Fl::event_x (), Fl::event_y () - menu_dy ()); break; case FL_PUSH: pos_x = Fl::event_x (); - pos_y = Fl::event_y (); + pos_y = Fl::event_y () - menu_dy (); - set_currentpoint (Fl::event_x (), Fl::event_y ()); + set_currentpoint (Fl::event_x (), Fl::event_y () - menu_dy ()); gh = pixel2axes_or_ca (pos_x, pos_y); @@ -1296,7 +1327,7 @@ case FL_DRAG: if (fp.get_windowbuttonmotionfcn ().is_defined ()) { - set_currentpoint (Fl::event_x (), Fl::event_y ()); + set_currentpoint (Fl::event_x (), Fl::event_y () - menu_dy ()); fp.execute_windowbuttonmotionfcn (); } @@ -1306,7 +1337,7 @@ { if (gui_mode == pan_zoom) pixel2status (ax_obj, pos_x, pos_y, - Fl::event_x (), Fl::event_y ()); + Fl::event_x (), Fl::event_y () - menu_dy ()); else view2status (ax_obj); axes::properties& ap = @@ -1315,7 +1346,7 @@ double x0, y0, x1, y1; Matrix pos = fp.get_boundingbox (true); pixel2pos (ax_obj, pos_x, pos_y, x0, y0); - pixel2pos (ax_obj, Fl::event_x (), Fl::event_y (), x1, y1); + pixel2pos (ax_obj, Fl::event_x (), Fl::event_y () - menu_dy (), x1, y1); if (gui_mode == pan_zoom) ap.translate_view (x0, x1, y0, y1); @@ -1323,12 +1354,12 @@ { double daz, del; daz = (Fl::event_x () - pos_x) / pos(2) * 360; - del = (Fl::event_y () - pos_y) / pos(3) * 360; + del = (Fl::event_y () - menu_dy () - pos_y) / pos(3) * 360; ap.rotate_view (del, daz); } pos_x = Fl::event_x (); - pos_y = Fl::event_y (); + pos_y = Fl::event_y () - menu_dy (); mark_modified (); } return 1; @@ -1336,12 +1367,12 @@ else if (Fl::event_button () == 3) { pixel2status (ax_obj, pos_x, pos_y, - Fl::event_x (), Fl::event_y ()); + Fl::event_x (), Fl::event_y () - menu_dy ()); Matrix zoom_box (1,4,0); zoom_box (0) = pos_x; zoom_box (1) = pos_y; zoom_box (2) = Fl::event_x (); - zoom_box (3) = Fl::event_y (); + zoom_box (3) = Fl::event_y () - menu_dy (); canvas->set_zoom_box (zoom_box); canvas->zoom (true); canvas->redraw (); @@ -1353,7 +1384,7 @@ { graphics_object ax = gh_manager::get_object (pixel2axes_or_ca (Fl::event_x (), - Fl::event_y ())); + Fl::event_y () - menu_dy ())); if (ax && ax.isa ("axes")) { axes::properties& ap = @@ -1361,11 +1392,12 @@ // Determine if we're zooming in or out. const double factor = - (Fl::event_dy () > 0) ? 1.0 + wheel_zoom_speed : 1.0 - wheel_zoom_speed; + (Fl::event_dy () > 0) ? 1 / (1.0 - Vwheel_zoom_speed) + : 1.0 - Vwheel_zoom_speed; // Get the point we're zooming about. double x1, y1; - pixel2pos (ax, Fl::event_x (), Fl::event_y (), x1, y1); + pixel2pos (ax, Fl::event_x (), Fl::event_y () - menu_dy (), x1, y1); ap.zoom_about_point (x1, y1, factor, false); mark_modified (); @@ -1376,7 +1408,7 @@ case FL_RELEASE: if (fp.get_windowbuttonupfcn ().is_defined ()) { - set_currentpoint (Fl::event_x (), Fl::event_y ()); + set_currentpoint (Fl::event_x (), Fl::event_y () - menu_dy ()); fp.execute_windowbuttonupfcn (); } @@ -1408,7 +1440,7 @@ dynamic_cast (ax_obj.get_properties ()); pixel2pos (ax_obj, pos_x, pos_y, x0, y0); int pos_x1 = Fl::event_x (); - int pos_y1 = Fl::event_y (); + int pos_y1 = Fl::event_y () - menu_dy (); pixel2pos (ax_obj, pos_x1, pos_y1, x1, y1); Matrix xl (1,2,0); Matrix yl (1,2,0); @@ -1845,7 +1877,18 @@ bool is_valid (void) const { return true; } bool initialize (const graphics_object& go) - { return go.isa ("figure"); } + { + if (go.isa ("figure") + || go.isa ("uimenu")) + { + if (go.isa ("uimenu")) + update (go, uimenu::properties::ID_LABEL); + + return true; + } + + return false; + } void finalize (const graphics_object& go) { @@ -2086,35 +2129,35 @@ return retval; } -// FIXME -- This function should be abstracted and made potentially +// FIXME: This function should be abstracted and made potentially // available to all graphics toolkits. This suggests putting it in // graphics.cc as is done for drawnow() and having the master // mouse_wheel_zoom function call fltk_mouse_wheel_zoom. The same // should be done for gui_mode and fltk_gui_mode. For now (2011.01.30), // just changing function names and docstrings. -DEFUN_DLD (mouse_wheel_zoom, args, , +DEFUN_DLD (mouse_wheel_zoom, args, nargout, "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {@var{speed} =} mouse_wheel_zoom ()\n\ -@deftypefnx {Built-in Function} {} mouse_wheel_zoom (@var{speed})\n\ +@deftypefn {Loadable Function} {@var{val} =} mouse_wheel_zoom ()\n\ +@deftypefnx {Loadable Function} {@var{old_val} =} mouse_wheel_zoom (@var{new_val})\n\ +@deftypefnx {Loadable Function} {} mouse_wheel_zoom (@var{new_val}, \"local\")\n\ Query or set the mouse wheel zoom factor.\n\ \n\ +The zoom factor is a number in the range (0,1) which is the percentage of the\n\ +current axis limits that will be used when zooming. For example, if the\n\ +current x-axis limits are [0, 50] and @code{mouse_wheel_zoom} is 0.4 (40%),\n\ +then a zoom operation will change the limits by 20.\n\ +\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ +\n\ This function is currently implemented only for the FLTK graphics toolkit.\n\ @seealso{gui_mode}\n\ @end deftypefn") { #ifdef HAVE_FLTK - octave_value retval = wheel_zoom_speed; - - if (args.length () == 1) - { - if (args(0).is_real_scalar ()) - wheel_zoom_speed = args(0).double_value (); - else - error ("mouse_wheel_zoom: SPEED must be a real scalar"); - } - - return retval; + return SET_INTERNAL_VARIABLE_WITH_LIMITS(wheel_zoom_speed, 0.0001, 0.9999); #else error ("mouse_wheel_zoom: not available without OpenGL and FLTK libraries"); return octave_value (); @@ -2129,13 +2172,13 @@ The @var{mode} argument can be one of the following strings:\n\ \n\ @table @asis\n\ -@item '2d'\n\ +@item @qcode{\"2d\"}\n\ Allows panning and zooming of current axes.\n\ \n\ -@item '3d'\n\ +@item @qcode{\"3d\"}\n\ Allows rotating and zooming of current axes.\n\ \n\ -@item 'none'\n\ +@item @qcode{\"none\"}\n\ Mouse inputs have no effect.\n\ @end table\n\ \n\ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/dldfcn/__magick_read__.cc --- a/libinterp/dldfcn/__magick_read__.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/dldfcn/__magick_read__.cc Sat Oct 05 11:22:09 2013 -0400 @@ -1,5 +1,6 @@ /* +Copyright (C) 2013 Carnë Draug Copyright (C) 2002-2012 Andy Adler Copyright (C) 2008 Thomas L. Scofield Copyright (C) 2010 David Grundberg @@ -26,8 +27,6 @@ #include #endif -#include - #include "file-stat.h" #include "oct-env.h" #include "oct-time.h" @@ -36,357 +35,647 @@ #include "error.h" #include "ov-struct.h" +#include "gripes.h" + #ifdef HAVE_MAGICK #include #include -octave_value_list -read_indexed_images (std::vector& imvec, - const Array& frameidx, bool wantalpha) +// In theory, it should be enough to check the class: +// Magick::ClassType +// PseudoClass: +// Image is composed of pixels which specify an index in a color palette. +// DirectClass: +// Image is composed of pixels which represent literal color values. +// +// GraphicsMagick does not really distinguishes between indexed and +// normal images. After reading a file, it decides itself the optimal +// way to store the image in memory, independently of the how the +// image was stored in the file. That's what ClassType returns. While +// it seems to match the original file most of the times, this is +// not necessarily true all the times. See +// https://sourceforge.net/mailarchive/message.php?msg_id=31180507 +// In addition to the ClassType, there is also ImageType which has a +// type for indexed images (PaletteType and PaletteMatteType). However, +// they also don't represent the original image. Not only does DirectClass +// can have a PaletteType, but also does a PseudoClass have non Palette +// types. +// +// We can't do better without having format specific code which is +// what we are trying to avoid by using a library such as GM. We at +// least create workarounds for the most common problems. +// +// 1) A grayscale jpeg image can report being indexed even though the +// JPEG format has no support for indexed images. We can at least +// fix this one. +// 2) A PNG file is only an indexed image if color type orig is 3 (value comes +// from libpng) +static bool +is_indexed (const Magick::Image& img) { - octave_value_list output; - - int rows = imvec[0].baseRows (); - int columns = imvec[0].baseColumns (); - int nframes = frameidx.length (); - - dim_vector idim = dim_vector (); - idim.resize (4); - idim(0) = rows; - idim(1) = columns; - idim(2) = 1; - idim(3) = nframes; - - Array idx (dim_vector (4, 1)); - - Magick::ImageType type = imvec[0].type (); - - unsigned int mapsize = imvec[0].colorMapSize (); - unsigned int i = mapsize; - unsigned int depth = 0; - while (i >>= 1) - depth++; - i = 0; - depth--; - while (depth >>= 1) - i++; - depth = 1 << i; + bool retval = false; + const std::string format = img.magick (); + if (img.classType () == Magick::PseudoClass + && format != "JPEG" + && (format != "PNG" + || const_cast (img).attribute ("PNG:IHDR.color-type-orig") == "3")) + retval = true; - switch (depth) - { - case 1: - case 2: - case 4: - case 8: - { - uint8NDArray im = uint8NDArray (idim); - - idx(2) = 0; - for (int frame = 0; frame < nframes; frame++) - { - imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows); - - const Magick::IndexPacket *pix - = imvec[frameidx(frame)].getConstIndexes (); - - i = 0; - idx(3) = frame; - - for (int y = 0; y < rows; y++) - { - idx(0) = y; - for (int x = 0; x < columns; x++) - { - idx(1) = x; - im(idx) = static_cast (pix[i++]); - } - } - } - - output(0) = octave_value (im); - } - break; - - case 16: - { - uint16NDArray im = uint16NDArray (idim); + return retval; +} - idx(2) = 0; - for (int frame = 0; frame < nframes; frame++) - { - imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows); - - const Magick::IndexPacket *pix - = imvec[frameidx(frame)].getConstIndexes (); - - i = 0; - idx(3) = frame; +// The depth from depth() is not always correct for us but seems to be the +// best value we can get. For example, a grayscale png image with 1 bit +// per channel should return a depth of 1 but instead we get 8. +// We could check channelDepth() but then, which channel has the data +// is not straightforward. So we'd have to check all +// the channels and select the highest value. But then, I also +// have a 16bit TIFF whose depth returns 16 (correct), but all of the +// channels gives 8 (wrong). No idea why, maybe a bug in GM? +// Anyway, using depth() seems that only causes problems for binary +// images, and the problem with channelDepth() is not making set them +// all to 1. So we will guess that if all channels have depth of 1, +// then we must have a binary image. +// Note that we can't use AllChannels it doesn't work for this. +// Instead of checking all of the individual channels, we check one +// from RGB, CMYK, grayscale, and transparency. +static octave_idx_type +get_depth (Magick::Image& img) +{ + octave_idx_type depth = img.depth (); + if (depth == 8 + && img.channelDepth (Magick::RedChannel) == 1 + && img.channelDepth (Magick::CyanChannel) == 1 + && img.channelDepth (Magick::OpacityChannel) == 1 + && img.channelDepth (Magick::GrayChannel) == 1) + depth = 1; - for (int y = 0; y < rows; y++) - { - idx(0) = y; - for (int x = 0; x < columns; x++) - { - idx(1) = x; - im(idx) = static_cast (pix[i++]); - } - } - } + return depth; +} - output(0) = octave_value (im); - } - break; - - default: - error ("__magic_read__: index depths greater than 16-bit are not supported"); - return octave_value_list (); - } - - Matrix map = Matrix (mapsize, 3); - Matrix alpha; - - switch (type) +// We need this in case one of the sides of the image being read has +// width 1. In those cases, the type will come as scalar instead of range +// since that's the behaviour of the colon operator (1:1:1 will be a scalar, +// not a range). +static Range +get_region_range (const octave_value& region) +{ + Range output; + if (region.is_range ()) + output = region.range_value (); + else if (region.is_scalar_type ()) { - case Magick::PaletteMatteType: -#if 0 - warning ("palettematte"); - Matrix map (mapsize, 3); - Matrix alpha (mapsize, 1); - for (i = 0; i < mapsize; i++) - { - warning ("%d", i); - Magick::ColorRGB c = imvec[0].colorMap (i); - map(i,0) = c.red (); - map(i,1) = c.green (); - map(i,2) = c.blue (); - alpha(i,1) = c.alpha (); - } - break; -#endif - - case Magick::PaletteType: - alpha = Matrix (0, 0); - for (i = 0; i < mapsize; i++) - { - Magick::ColorRGB c = imvec[0].colorMap (i); - map(i,0) = c.red (); - map(i,1) = c.green (); - map(i,2) = c.blue (); - } - break; - - default: - error ("__magick_read__: unsupported indexed image type"); - return octave_value_list (); + double value = region.scalar_value (); + output = Range (value, value); } - - if (wantalpha) - output(2) = alpha; - - output(1) = map; + else + error ("__magick_read__: unknow datatype for Region option"); return output; } +static std::map +calculate_region (const octave_scalar_map& options) +{ + std::map region; + const Cell pixel_region = options.getfield ("region").cell_value (); + + // Subtract 1 to account for 0 indexing. + const Range rows = get_region_range (pixel_region (0)); + const Range cols = get_region_range (pixel_region (1)); + region["row_start"] = rows.base () -1; + region["col_start"] = cols.base () -1; + region["row_end"] = rows.max () -1; + region["col_end"] = cols.max () -1; + + // Length of the area to load into the Image Pixel Cache. We use max and + // min to account for cases where last element of range is the range limit. + region["row_cache"] = region["row_end"] - region["row_start"] +1; + region["col_cache"] = region["col_end"] - region["col_start"] +1; + + // How much we have to shift in the memory when doing the loops. + region["row_shift"] = region["col_cache"] * rows.inc (); + region["col_shift"] = region["col_cache"] * + (region["row_cache"] + rows.inc () -1) - cols.inc (); + + // The actual height and width of the output image + region["row_out"] = rows.nelem (); + region["col_out"] = cols.nelem (); + + return region; +} + +static octave_value_list +read_maps (Magick::Image& img) +{ + // can't call colorMapSize on const Magick::Image + const octave_idx_type mapsize = img.colorMapSize (); + Matrix cmap = Matrix (mapsize, 3); // colormap + ColumnVector amap = ColumnVector (mapsize); // alpha map + for (octave_idx_type i = 0; i < mapsize; i++) + { + const Magick::ColorRGB c = img.colorMap (i); + cmap(i,0) = c.red (); + cmap(i,1) = c.green (); + cmap(i,2) = c.blue (); + amap(i) = c.alpha (); + } + octave_value_list maps; + maps(0) = cmap; + maps(1) = amap; + return maps; +} + +template +static octave_value_list +read_indexed_images (const std::vector& imvec, + const Array& frameidx, + const octave_idx_type& nargout, + const octave_scalar_map& options) +{ + typedef typename T::element_type P; + + octave_value_list retval (3, Matrix ()); + + std::map region = calculate_region (options); + const octave_idx_type nFrames = frameidx.length (); + const octave_idx_type nRows = region["row_out"]; + const octave_idx_type nCols = region["col_out"]; + + // imvec has all of the pages of a file, even the ones we are not + // interested in. We will use the first image that we will be actually + // reading to get information about the image. + const octave_idx_type def_elem = frameidx(0); + + T img = T (dim_vector (nRows, nCols, 1, nFrames)); + P* img_fvec = img.fortran_vec (); + + const octave_idx_type row_start = region["row_start"]; + const octave_idx_type col_start = region["col_start"]; + const octave_idx_type row_shift = region["row_shift"]; + const octave_idx_type col_shift = region["col_shift"]; + const octave_idx_type row_cache = region["row_cache"]; + const octave_idx_type col_cache = region["col_cache"]; + + // When reading PixelPackets from the Image Pixel Cache, they come in + // row major order. So we keep moving back and forth there so we can + // write the image in column major order. + octave_idx_type idx = 0; + for (octave_idx_type frame = 0; frame < nFrames; frame++) + { + imvec[frameidx(frame)].getConstPixels (col_start, row_start, + col_cache, row_cache); + + const Magick::IndexPacket *pix + = imvec[frameidx(frame)].getConstIndexes (); + + for (octave_idx_type col = 0; col < nCols; col++) + { + for (octave_idx_type row = 0; row < nRows; row++) + { + img_fvec[idx++] = static_cast

(*pix); + pix += row_shift; + } + pix -= col_shift; + } + } + retval(0) = octave_value (img); + +// Only bother reading the colormap if it was requested as output. + if (nargout > 1) + { + // In theory, it should be possible for each frame of an image to + // have different colormaps but for Matlab compatibility, we only + // return the colormap of the first frame. To obtain the colormaps + // of different frames, one needs can either use imfinfo or a for + // loop around imread. + const octave_value_list maps = + read_maps (const_cast (imvec[frameidx(def_elem)])); + + retval(1) = maps(0); + + // only interpret alpha channel if it exists and was requested as output + if (imvec[def_elem].matte () && nargout >= 3) + { + const Matrix amap = maps(1).matrix_value (); + const double* amap_fvec = amap.fortran_vec (); + + NDArray alpha (dim_vector (nRows, nCols, 1, nFrames)); + double* alpha_fvec = alpha.fortran_vec (); + + // GraphicsMagick stores the alpha values inverted, i.e., + // 1 for transparent and 0 for opaque so we fix that here. + const octave_idx_type nPixels = alpha.numel (); + for (octave_idx_type pix = 0; pix < nPixels; pix++) + alpha_fvec[pix] = 1 - amap_fvec[static_cast (img_fvec[3])]; + + retval(2) = alpha; + } + } + + return retval; +} + +// This function is highly repetitive, a bunch of for loops that are +// very similar to account for different image types. They are different +// enough that trying to reduce the copy and paste would decrease its +// readability too much. template octave_value_list -read_images (const std::vector& imvec, - const Array& frameidx, unsigned int depth) +read_images (std::vector& imvec, + const Array& frameidx, + const octave_idx_type& nargout, + const octave_scalar_map& options) { typedef typename T::element_type P; octave_value_list retval (3, Matrix ()); - T im; + std::map region = calculate_region (options); + const octave_idx_type nFrames = frameidx.length (); + const octave_idx_type nRows = region["row_out"]; + const octave_idx_type nCols = region["col_out"]; + T img; + + // imvec has all of the pages of a file, even the ones we are not + // interested in. We will use the first image that we will be actually + // reading to get information about the image. + const octave_idx_type def_elem = frameidx(0); + + const octave_idx_type row_start = region["row_start"]; + const octave_idx_type col_start = region["col_start"]; + const octave_idx_type row_shift = region["row_shift"]; + const octave_idx_type col_shift = region["col_shift"]; + const octave_idx_type row_cache = region["row_cache"]; + const octave_idx_type col_cache = region["col_cache"]; - int rows = imvec[0].baseRows (); - int columns = imvec[0].baseColumns (); - int nframes = frameidx.length (); + // GraphicsMagick (GM) keeps the image values in memory using whatever + // QuantumDepth it was built with independently of the original image + // bitdepth. Basically this means that if GM was built with quantum 16 + // all values are scaled in the uint16 range. If the original image + // had an 8 bit depth, we need to rescale it for that range. + // However, if the image had a bitdepth of 32, then we will be returning + // a floating point image. In this case, the values need to be rescaled + // for the range [0 1] (this is what Matlab has documented on the page + // about image types but in some cases seems to be doing something else. + // See bug #39249). + // Finally, we must do the division ourselves (set a divisor) instead of + // using quantumOperator for the cases where we will be returning floating + // point and want things in the range [0 1]. This is the same reason why + // the divisor is of type double. + // uint64_t is used in expression because default 32-bit value overflows + // when depth() is 32. + // TODO in the next release of GraphicsMagick, MaxRGB should be replaced + // with QuantumRange since MaxRGB is already deprecated in ImageMagick. + double divisor; + if (imvec[def_elem].depth () == 32) + divisor = std::numeric_limits::max (); + else + divisor = MaxRGB / ((uint64_t (1) << imvec[def_elem].depth ()) - 1); + + // FIXME: this workaround should probably be fixed in GM by creating a + // new ImageType BilevelMatteType + // Despite what GM documentation claims, opacity is not only on the types + // with Matte on the name. It is possible that an image is completely + // black (1 color), and have a second channel set for transparency (2nd + // color). Its type will be bilevel since there is no BilevelMatte. The + // only way to check for this seems to be by checking matte (). + Magick::ImageType type = imvec[def_elem].type (); + if (type == Magick::BilevelType && imvec[def_elem].matte ()) + type = Magick::GrayscaleMatteType; - dim_vector idim = dim_vector (); - idim.resize (4); - idim(0) = rows; - idim(1) = columns; - idim(2) = 1; - idim(3) = nframes; + // FIXME: ImageType is the type being used to represent the image in memory + // by GM. The real type may be different (see among others bug #36820). For + // example, a png file where all channels are equal may report being + // grayscale or even bilevel. But we must always return the real image in + // file. In some cases, the original image attributes are stored in the + // attributes but this is undocumented. This should be fixed in GM so that + // a method such as original_type returns an actual Magick::ImageType + if (imvec[0].magick () == "PNG") + { + // These values come from libpng, not GM: + // Grayscale = 0 + // Palette = 2 + 1 + // RGB = 2 + // RGB + Alpha = 2 + 4 + // Grayscale + Alpha = 4 + // We won't bother with case 3 (palette) since those should be + // read by the function to read indexed images + const std::string type_str = imvec[0].attribute ("PNG:IHDR.color-type-orig"); + if (type_str == "0") + type = Magick::GrayscaleType; + else if (type_str == "2") + type = Magick::TrueColorType; + else if (type_str == "6") + type = Magick::TrueColorMatteType; + else if (type_str == "4") + type = Magick::GrayscaleMatteType; + // Color types 0, 2, and 3 can also have alpha channel, conveyed + // via the "tRNS" chunk. For 0 and 2, it's limited to GIF-style + // binary transparency, while 3 can have any level of alpha per + // palette entry. We thus must check matte() to see if the image + // really doesn't have an alpha channel. + if (imvec[0].matte ()) + { + if (type == Magick::GrayscaleType) + type = Magick::GrayscaleMatteType; + else if (type == Magick::TrueColorType) + type = Magick::TrueColorMatteType; + } + } - Magick::ImageType type = imvec[0].type (); - const int divisor = ((uint64_t (1) << QuantumDepth) - 1) / - ((uint64_t (1) << depth) - 1); + // If the alpha channel was not requested, treat images as if + // it doesn't exist. + if (nargout < 3) + { + switch (type) + { + case Magick::GrayscaleMatteType: + type = Magick::GrayscaleType; + break; + + case Magick::PaletteMatteType: + type = Magick::PaletteType; + break; + + case Magick::TrueColorMatteType: + type = Magick::TrueColorType; + break; + + case Magick::ColorSeparationMatteType: + type = Magick::ColorSeparationType; + break; + + default: + // Do nothing other than silencing warnings about enumeration + // values not being handled in switch. + ; + } + } switch (type) { - case Magick::BilevelType: - case Magick::GrayscaleType: + case Magick::BilevelType: // Monochrome bi-level image + case Magick::GrayscaleType: // Grayscale image { - im = T (idim); - P *vec = im.fortran_vec (); + img = T (dim_vector (nRows, nCols, 1, nFrames)); + P *img_fvec = img.fortran_vec (); + + octave_idx_type idx = 0; + for (octave_idx_type frame = 0; frame < nFrames; frame++) + { + const Magick::PixelPacket *pix + = imvec[frameidx(frame)].getConstPixels (col_start, row_start, + col_cache, row_cache); - for (int frame = 0; frame < nframes; frame++) + for (octave_idx_type col = 0; col < nCols; col++) + { + for (octave_idx_type row = 0; row < nRows; row++) + { + img_fvec[idx++] = pix->red / divisor; + pix += row_shift; + } + pix -= col_shift; + } + } + break; + } + + case Magick::GrayscaleMatteType: // Grayscale image with opacity + { + img = T (dim_vector (nRows, nCols, 1, nFrames)); + T alpha (dim_vector (nRows, nCols, 1, nFrames)); + P *img_fvec = img.fortran_vec (); + P *a_fvec = alpha.fortran_vec (); + + octave_idx_type idx = 0; + for (octave_idx_type frame = 0; frame < nFrames; frame++) { const Magick::PixelPacket *pix - = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows); - - P *rbuf = vec; - for (int y = 0; y < rows; y++) - { - for (int x = 0; x < columns; x++) - { - *rbuf = pix->red / divisor; - pix++; - rbuf += rows; - } - rbuf -= rows * columns - 1; - } + = imvec[frameidx(frame)].getConstPixels (col_start, row_start, + col_cache, row_cache); - // Next frame. - vec += rows * columns * idim(2); + for (octave_idx_type col = 0; col < nCols; col++) + { + for (octave_idx_type row = 0; row < nRows; row++) + { + img_fvec[idx] = pix->red / divisor; + a_fvec[idx] = (MaxRGB - pix->opacity) / divisor; + pix += row_shift; + idx++; + } + pix -= col_shift; + } } - } - break; + retval(2) = alpha; + break; + } - case Magick::GrayscaleMatteType: + case Magick::PaletteType: // Indexed color (palette) image + case Magick::TrueColorType: // Truecolor image { - idim(2) = 2; - im = T (idim); - P *vec = im.fortran_vec (); + img = T (dim_vector (nRows, nCols, 3, nFrames)); + P *img_fvec = img.fortran_vec (); - for (int frame = 0; frame < nframes; frame++) + for (octave_idx_type frame = 0; frame < nFrames; frame++) { const Magick::PixelPacket *pix - = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows); + = imvec[frameidx(frame)].getConstPixels (col_start, row_start, + col_cache, row_cache); - P *rbuf = vec; - P *obuf = vec + rows * columns; - for (int y = 0; y < rows; y++) + octave_idx_type idx = 0; + img_fvec += nRows * nCols * frame; + P *rbuf = img_fvec; + P *gbuf = img_fvec + nRows * nCols; + P *bbuf = img_fvec + nRows * nCols * 2; + + for (octave_idx_type col = 0; col < nCols; col++) { - for (int x = 0; x < columns; x++) + for (octave_idx_type row = 0; row < nRows; row++) { - *rbuf = pix->red / divisor; - *obuf = pix->opacity / divisor; - pix++; - rbuf += rows; - obuf += rows; + rbuf[idx] = pix->red / divisor; + gbuf[idx] = pix->green / divisor; + bbuf[idx] = pix->blue / divisor; + pix += row_shift; + idx++; } - rbuf -= rows * columns - 1; - obuf -= rows * columns - 1; + pix -= col_shift; } - - // Next frame. - vec += rows * columns * idim(2); } - } - break; + break; + } - case Magick::PaletteType: - case Magick::TrueColorType: + case Magick::PaletteMatteType: // Indexed color (palette) image with opacity + case Magick::TrueColorMatteType: // Truecolor image with opacity { - idim(2) = 3; - im = T (idim); - P *vec = im.fortran_vec (); + img = T (dim_vector (nRows, nCols, 3, nFrames)); + T alpha (dim_vector (nRows, nCols, 1, nFrames)); + P *img_fvec = img.fortran_vec (); + P *a_fvec = alpha.fortran_vec (); - for (int frame = 0; frame < nframes; frame++) + // Unlike the index for the other channels, this one won't need + // to be reset on each frame since it's a separate matrix. + octave_idx_type a_idx = 0; + for (octave_idx_type frame = 0; frame < nFrames; frame++) { const Magick::PixelPacket *pix - = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows); + = imvec[frameidx(frame)].getConstPixels (col_start, row_start, + col_cache, row_cache); - P *rbuf = vec; - P *gbuf = vec + rows * columns; - P *bbuf = vec + rows * columns * 2; - for (int y = 0; y < rows; y++) + octave_idx_type idx = 0; + img_fvec += nRows * nCols * frame; + P *rbuf = img_fvec; + P *gbuf = img_fvec + nRows * nCols; + P *bbuf = img_fvec + nRows * nCols * 2; + + for (octave_idx_type col = 0; col < nCols; col++) { - for (int x = 0; x < columns; x++) + for (octave_idx_type row = 0; row < nRows; row++) { - *rbuf = pix->red / divisor; - *gbuf = pix->green / divisor; - *bbuf = pix->blue / divisor; - pix++; - rbuf += rows; - gbuf += rows; - bbuf += rows; + rbuf[idx] = pix->red / divisor; + gbuf[idx] = pix->green / divisor; + bbuf[idx] = pix->blue / divisor; + a_fvec[a_idx++] = (MaxRGB - pix->opacity) / divisor; + pix += row_shift; + idx++; } - rbuf -= rows * columns - 1; - gbuf -= rows * columns - 1; - bbuf -= rows * columns - 1; + pix -= col_shift; } - - // Next frame. - vec += rows * columns * idim(2); } - } - break; + retval(2) = alpha; + break; + } - case Magick::PaletteMatteType: - case Magick::TrueColorMatteType: - case Magick::ColorSeparationType: + case Magick::ColorSeparationType: // Cyan/Yellow/Magenta/Black (CYMK) image { - idim(2) = 4; - im = T (idim); - P *vec = im.fortran_vec (); + img = T (dim_vector (nRows, nCols, 4, nFrames)); + P *img_fvec = img.fortran_vec (); - for (int frame = 0; frame < nframes; frame++) + for (octave_idx_type frame = 0; frame < nFrames; frame++) { const Magick::PixelPacket *pix - = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows); + = imvec[frameidx(frame)].getConstPixels (col_start, row_start, + col_cache, row_cache); - P *rbuf = vec; - P *gbuf = vec + rows * columns; - P *bbuf = vec + rows * columns * 2; - P *obuf = vec + rows * columns * 3; - for (int y = 0; y < rows; y++) + octave_idx_type idx = 0; + img_fvec += nRows * nCols * frame; + P *cbuf = img_fvec; + P *mbuf = img_fvec + nRows * nCols; + P *ybuf = img_fvec + nRows * nCols * 2; + P *kbuf = img_fvec + nRows * nCols * 3; + + for (octave_idx_type col = 0; col < nCols; col++) { - for (int x = 0; x < columns; x++) + for (octave_idx_type row = 0; row < nRows; row++) { - *rbuf = pix->red / divisor; - *gbuf = pix->green / divisor; - *bbuf = pix->blue / divisor; - *obuf = pix->opacity / divisor; - pix++; - rbuf += rows; - gbuf += rows; - bbuf += rows; - obuf += rows; + cbuf[idx] = pix->red / divisor; + mbuf[idx] = pix->green / divisor; + ybuf[idx] = pix->blue / divisor; + kbuf[idx] = pix->opacity / divisor; + pix += row_shift; + idx++; } - rbuf -= rows * columns - 1; - gbuf -= rows * columns - 1; - bbuf -= rows * columns - 1; - obuf -= rows * columns - 1; + pix -= col_shift; } + } + break; + } + + // Cyan, magenta, yellow, and black with alpha (opacity) channel + case Magick::ColorSeparationMatteType: + { + img = T (dim_vector (nRows, nCols, 4, nFrames)); + T alpha (dim_vector (nRows, nCols, 1, nFrames)); + P *img_fvec = img.fortran_vec (); + P *a_fvec = alpha.fortran_vec (); - // Next frame. - vec += rows * columns * idim(2); + // Unlike the index for the other channels, this one won't need + // to be reset on each frame since it's a separate matrix. + octave_idx_type a_idx = 0; + for (octave_idx_type frame = 0; frame < nFrames; frame++) + { + const Magick::PixelPacket *pix + = imvec[frameidx(frame)].getConstPixels (col_start, row_start, + col_cache, row_cache); + // Note that for CMYKColorspace + matte (CMYKA), the opacity is + // stored in the assocated IndexPacket. + const Magick::IndexPacket *apix + = imvec[frameidx(frame)].getConstIndexes (); + + octave_idx_type idx = 0; + img_fvec += nRows * nCols * frame; + P *cbuf = img_fvec; + P *mbuf = img_fvec + nRows * nCols; + P *ybuf = img_fvec + nRows * nCols * 2; + P *kbuf = img_fvec + nRows * nCols * 3; + + for (octave_idx_type col = 0; col < nCols; col++) + { + for (octave_idx_type row = 0; row < nRows; row++) + { + cbuf[idx] = pix->red / divisor; + mbuf[idx] = pix->green / divisor; + ybuf[idx] = pix->blue / divisor; + kbuf[idx] = pix->opacity / divisor; + a_fvec[a_idx++] = (MaxRGB - *apix) / divisor; + pix += row_shift; + idx++; + } + pix -= col_shift; + } } - } - break; + retval(2) = alpha; + break; + } default: - error ("__magick_read__: undefined ImageMagick image type"); + error ("__magick_read__: unknown Magick++ image type"); return retval; } - retval(0) = im; - + retval(0) = img; return retval; } -#endif +// Read a file into vector of image objects. +void static +read_file (const std::string& filename, std::vector& imvec) +{ + try + { + Magick::readImages (&imvec, filename); + } + catch (Magick::Warning& w) + { + warning ("Magick++ warning: %s", w.what ()); + } + catch (Magick::ErrorCoder& e) + { + // FIXME: there's a WarningCoder and ErrorCoder. Shouldn't this + // exception cause an error? + warning ("Magick++ coder error: %s", e.what ()); + } + catch (Magick::Exception& e) + { + error ("Magick++ exception: %s", e.what ()); + error_state = 1; + } +} static void maybe_initialize_magick (void) { -#ifdef HAVE_MAGICK - static bool initialized = false; if (! initialized) { - // Save locale as GraphicsMagick might change this (depending on version) + // Save locale as GraphicsMagick might change this (fixed in + // GraphicsMagick since version 1.3.13 released on December 24, 2011) const char *static_locale = setlocale (LC_ALL, NULL); const std::string locale (static_locale); - std::string program_name = octave_env::get_program_invocation_name (); - + const std::string program_name = octave_env::get_program_invocation_name (); Magick::InitializeMagick (program_name.c_str ()); // Restore locale from before GraphicsMagick initialisation @@ -398,57 +687,576 @@ initialized = true; } +} #endif -} DEFUN_DLD (__magick_read__, args, nargout, "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{m} =} __magick_read__ (@var{fname}, @var{index})\n\ -@deftypefnx {Loadable Function} {[@var{m}, @var{colormap}] =} __magick_read__ (@var{fname}, @var{index})\n\ -@deftypefnx {Loadable Function} {[@var{m}, @var{colormap}, @var{alpha}] =} __magick_read__ (@var{fname}, @var{index})\n\ -Read images with ImageMagick++. In general you should not be using this\n\ -function. Instead use @code{imread}.\n\ -@seealso{imread}\n\ +@deftypefn {Loadable Function} {[@var{img}, @var{map}, @var{alpha}] =} __magick_read__ (@var{fname}, @var{options})\n\ +Read image with GraphicsMagick or ImageMagick.\n\ +\n\ +This is a private internal function not intended for direct use. Instead\n\ +use @code{imread}.\n\ +\n\ +@seealso{imfinfo, imformats, imread, imwrite}\n\ @end deftypefn") { octave_value_list output; -#ifdef HAVE_MAGICK +#ifndef HAVE_MAGICK + gripe_disabled_feature ("imread", "Image IO"); +#else maybe_initialize_magick (); - if (args.length () > 3 || args.length () < 1 || ! args(0).is_string () - || nargout > 3) + if (args.length () != 2 || ! args(0).is_string ()) { print_usage (); return output; } - Array frameidx; - bool all_frames = false; + const octave_scalar_map options = args(1).scalar_map_value (); + if (error_state) + { + error ("__magick_read__: OPTIONS must be a struct"); + return output; + } - if (args.length () == 2 && args(1).is_real_type ()) - frameidx = args(1).int_vector_value (); - else if (args.length () == 3 && args(1).is_string () - && args(1).string_value () == "frames") + std::vector imvec; + read_file (args(0).string_value (), imvec); + if (error_state) + return output; + + // Prepare an Array with the indexes for the requested frames. + const octave_idx_type nFrames = imvec.size (); + Array frameidx; + const octave_value indexes = options.getfield ("index"); + if (indexes.is_string () && indexes.string_value () == "all") { - if (args(2).is_string () && args(2).string_value () == "all") - all_frames = true; - else if (args(2).is_real_type ()) - frameidx = args(2).int_vector_value (); + frameidx.resize (dim_vector (1, nFrames)); + for (octave_idx_type i = 0; i < nFrames; i++) + frameidx(i) = i; } else { - frameidx = Array (dim_vector (1, 1)); - frameidx(0) = 1; + frameidx = indexes.int_vector_value (); + if (error_state) + { + error ("__magick_read__: invalid value for Index/Frame"); + return output; + } + // Fix indexes from base 1 to base 0, and at the same time, make + // sure none of the indexes is outside the range of image number. + const octave_idx_type n = frameidx.nelem (); + for (octave_idx_type i = 0; i < n; i++) + { + frameidx(i)--; + if (frameidx(i) < 0 || frameidx(i) > nFrames - 1) + { + error ("imread: index/frames specified are outside the number of images"); + return output; + } + } + } + + const octave_idx_type depth = get_depth (imvec[frameidx(0)]); + if (is_indexed (imvec[frameidx(0)])) + { + if (depth <= 1) + output = read_indexed_images (imvec, frameidx, + nargout, options); + else if (depth <= 8) + output = read_indexed_images (imvec, frameidx, + nargout, options); + else if (depth <= 16) + output = read_indexed_images (imvec, frameidx, + nargout, options); + else + { + error ("imread: indexed images with depths greater than 16-bit are not supported"); + return output; + } + } + + else + { + if (depth <= 1) + output = read_images (imvec, frameidx, nargout, options); + else if (depth <= 8) + output = read_images (imvec, frameidx, nargout, options); + else if (depth <= 16) + output = read_images (imvec, frameidx, nargout, options); + else if (depth <= 32) + output = read_images (imvec, frameidx, nargout, options); + else + { + error ("imread: reading of images with %i-bit depth is not supported", + depth); + } + } + +#endif + return output; +} + +/* +## No test needed for internal helper function. +%!assert (1) +*/ + +#ifdef HAVE_MAGICK + +template +static uint32NDArray +img_float2uint (const T& img) +{ + typedef typename T::element_type P; + uint32NDArray out (img.dims ()); + + octave_uint32* out_fvec = out.fortran_vec (); + const P* img_fvec = img.fortran_vec (); + + const octave_uint32 max = octave_uint32::max (); + const octave_idx_type numel = img.numel (); + for (octave_idx_type idx = 0; idx < numel; idx++) + out_fvec[idx] = img_fvec[idx] * max; + + return out; +} + +// Gets the bitdepth to be used for an Octave class, i.e, returns 8 for +// uint8, 16 for uint16, and 32 for uint32 +template +static octave_idx_type +bitdepth_from_class () +{ + typedef typename T::element_type P; + const octave_idx_type bitdepth = + sizeof (P) * std::numeric_limits::digits; + return bitdepth; +} + +static Magick::Image +init_enconde_image (const octave_idx_type& nCols, const octave_idx_type& nRows, + const octave_idx_type& bitdepth, + const Magick::ImageType& type, + const Magick::ClassType& klass) +{ + Magick::Image img (Magick::Geometry (nCols, nRows), "black"); + // Ensure that there are no other references to this image. + img.modifyImage (); + + img.classType (klass); + img.type (type); + // FIXME: for some reason, setting bitdepth doesn't seem to work for + // indexed images. + img.depth (bitdepth); + switch (type) + { + case Magick::GrayscaleMatteType: + case Magick::TrueColorMatteType: + case Magick::ColorSeparationMatteType: + case Magick::PaletteMatteType: + img.matte (true); + break; + + default: + img.matte (false); } - std::vector imvec; + return img; +} + +template +static void +encode_indexed_images (std::vector& imvec, + const T& img, + const Matrix& cmap) +{ + typedef typename T::element_type P; + const octave_idx_type nFrames = img.ndims () < 4 ? 1 : img.dims ()(3); + const octave_idx_type nRows = img.rows (); + const octave_idx_type nCols = img.columns (); + const octave_idx_type cmap_size = cmap.rows (); + const octave_idx_type bitdepth = bitdepth_from_class (); + + // There is no colormap object, we need to build a new one for each frame, + // even if it's always the same. We can least get a vector for the Colors. + std::vector colormap; + { + const double* cmap_fvec = cmap.fortran_vec (); + const octave_idx_type G_offset = cmap_size; + const octave_idx_type B_offset = cmap_size * 2; + for (octave_idx_type map_idx = 0; map_idx < cmap_size; map_idx++) + colormap.push_back (Magick::ColorRGB (cmap_fvec[map_idx], + cmap_fvec[map_idx + G_offset], + cmap_fvec[map_idx + B_offset])); + } + + for (octave_idx_type frame = 0; frame < nFrames; frame++) + { + Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth, + Magick::PaletteType, + Magick::PseudoClass); + + // Insert colormap. + m_img.colorMapSize (cmap_size); + for (octave_idx_type map_idx = 0; map_idx < cmap_size; map_idx++) + m_img.colorMap (map_idx, colormap[map_idx]); + + // Why are we also setting the pixel values instead of only the + // index values? We don't know if a file format supports indexed + // images. If we only set the indexes and then try to save the + // image as JPEG for example, the indexed values get discarded, + // there is no conversion from the indexes, it's the initial values + // that get used. An alternative would be to only set the pixel + // values (no indexes), then set the image as PseudoClass and GM + // would create a colormap for us. However, we wouldn't have control + // over the order of that colormap. And that's why we set both. + Magick::PixelPacket* pix = m_img.getPixels (0, 0, nCols, nRows); + Magick::IndexPacket* ind = m_img.getIndexes (); + const P* img_fvec = img.fortran_vec (); + + octave_idx_type GM_idx = 0; + for (octave_idx_type column = 0; column < nCols; column++) + { + for (octave_idx_type row = 0; row < nRows; row++) + { + ind[GM_idx] = double (*img_fvec); + pix[GM_idx] = m_img.colorMap (double (*img_fvec)); + img_fvec++; + GM_idx += nCols; + } + GM_idx -= nCols * nRows - 1; + } + + // Save changes to underlying image. + m_img.syncPixels (); + imvec.push_back (m_img); + } +} + +static void +encode_bool_image (std::vector& imvec, const boolNDArray& img) +{ + const octave_idx_type nFrames = img.ndims () < 4 ? 1 : img.dims ()(3); + const octave_idx_type nRows = img.rows (); + const octave_idx_type nCols = img.columns (); + + // The initialized image will be black, this is for the other pixels + const Magick::Color white ("white"); + + const bool *img_fvec = img.fortran_vec (); + octave_idx_type img_idx = 0; + for (octave_idx_type frame = 0; frame < nFrames; frame++) + { + // For some reason, we can't set the type to Magick::BilevelType or + // the output image will be black, changing to white has no effect. + // However, this will still work fine and a binary image will be + // saved because we are setting the bitdepth to 1. + Magick::Image m_img = init_enconde_image (nCols, nRows, 1, + Magick::GrayscaleType, + Magick::DirectClass); + + Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows); + octave_idx_type GM_idx = 0; + for (octave_idx_type col = 0; col < nCols; col++) + { + for (octave_idx_type row = 0; row < nRows; row++) + { + if (img_fvec[img_idx]) + pix[GM_idx] = white; + + img_idx++; + GM_idx += nCols; + } + GM_idx -= nCols * nRows - 1; + } + // Save changes to underlying image. + m_img.syncPixels (); + // While we could not set it to Bilevel at the start, we can do it + // here otherwise some coders won't save it as binary. + m_img.type (Magick::BilevelType); + imvec.push_back (m_img); + } +} + +template +static void +encode_uint_image (std::vector& imvec, + const T& img, const T& alpha) +{ + typedef typename T::element_type P; + const octave_idx_type channels = img.ndims () < 3 ? 1 : img.dims ()(2); + const octave_idx_type nFrames = img.ndims () < 4 ? 1 : img.dims ()(3); + const octave_idx_type nRows = img.rows (); + const octave_idx_type nCols = img.columns (); + const octave_idx_type bitdepth = bitdepth_from_class (); + + Magick::ImageType type; + const bool has_alpha = ! alpha.is_empty (); + switch (channels) + { + case 1: + if (has_alpha) + type = Magick::GrayscaleMatteType; + else + type = Magick::GrayscaleType; + break; + + case 3: + if (has_alpha) + type = Magick::TrueColorMatteType; + else + type = Magick::TrueColorType; + break; + + case 4: + if (has_alpha) + type = Magick::ColorSeparationMatteType; + else + type = Magick::ColorSeparationType; + break; + + default: + { + // __imwrite should have already filtered this cases + error ("__magick_write__: wrong size on 3rd dimension"); + return; + } + } + + // We will be passing the values as integers with depth as specified + // by QuantumDepth (maximum value specified by MaxRGB). This is independent + // of the actual depth of the image. GM will then convert the values but + // while in memory, it always keeps the values as specified by QuantumDepth. + // From GM documentation: + // Color arguments are must be scaled to fit the Quantum size according to + // the range of MaxRGB + const double divisor = static_cast((uint64_t (1) << bitdepth) - 1) / MaxRGB; + + const P *img_fvec = img.fortran_vec (); + const P *a_fvec = alpha.fortran_vec (); + switch (type) + { + case Magick::GrayscaleType: + { + octave_idx_type GM_idx = 0; + for (octave_idx_type frame = 0; frame < nFrames; frame++) + { + Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth, + type, + Magick::DirectClass); + Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows); + for (octave_idx_type col = 0; col < nCols; col++) + { + for (octave_idx_type row = 0; row < nRows; row++) + { + Magick::Color c; + c.redQuantum (double (*img_fvec) / divisor); + pix[GM_idx] = c; + img_fvec++; + GM_idx += nCols; + } + GM_idx -= nCols * nRows - 1; + } + // Save changes to underlying image. + m_img.syncPixels (); + imvec.push_back (m_img); + } + break; + } + + case Magick::GrayscaleMatteType: + { + octave_idx_type GM_idx = 0; + for (octave_idx_type frame = 0; frame < nFrames; frame++) + { + Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth, + type, + Magick::DirectClass); + + Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows); + for (octave_idx_type col = 0; col < nCols; col++) + { + for (octave_idx_type row = 0; row < nRows; row++) + { + Magick::Color c; + c.redQuantum (double (*img_fvec) / divisor); + c.alphaQuantum (MaxRGB - (double (*a_fvec) / divisor)); + pix[GM_idx] = c; + img_fvec++; + a_fvec++; + GM_idx += nCols; + } + GM_idx -= nCols * nRows - 1; + } + // Save changes to underlying image. + m_img.syncPixels (); + imvec.push_back (m_img); + } + break; + } + + case Magick::TrueColorType: + { + // The fortran_vec offset for the green and blue channels + const octave_idx_type G_offset = nCols * nRows; + const octave_idx_type B_offset = nCols * nRows * 2; + octave_idx_type GM_idx = 0; + for (octave_idx_type frame = 0; frame < nFrames; frame++) + { + Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth, + type, + Magick::DirectClass); + + Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows); + for (octave_idx_type col = 0; col < nCols; col++) + { + for (octave_idx_type row = 0; row < nRows; row++) + { + Magick::Color c (double (*img_fvec) / divisor, + double (img_fvec[G_offset]) / divisor, + double (img_fvec[B_offset]) / divisor); + pix[GM_idx] = c; + img_fvec++; + GM_idx += nCols; + } + GM_idx -= nCols * nRows - 1; + } + // Save changes to underlying image. + m_img.syncPixels (); + imvec.push_back (m_img); + } + break; + } + + case Magick::TrueColorMatteType: + { + // The fortran_vec offset for the green and blue channels + const octave_idx_type G_offset = nCols * nRows; + const octave_idx_type B_offset = nCols * nRows * 2; + octave_idx_type GM_idx = 0; + for (octave_idx_type frame = 0; frame < nFrames; frame++) + { + Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth, + type, + Magick::DirectClass); + + Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows); + for (octave_idx_type col = 0; col < nCols; col++) + { + for (octave_idx_type row = 0; row < nRows; row++) + { + Magick::Color c (double (*img_fvec) / divisor, + double (img_fvec[G_offset]) / divisor, + double (img_fvec[B_offset]) / divisor, + MaxRGB - (double (*a_fvec) / divisor)); + pix[GM_idx] = c; + img_fvec++; + a_fvec++; + GM_idx += nCols; + } + GM_idx -= nCols * nRows - 1; + } + // Save changes to underlying image. + m_img.syncPixels (); + imvec.push_back (m_img); + } + break; + } + + case Magick::ColorSeparationType: + { + // The fortran_vec offset for the Magenta, Yellow, and blacK channels + const octave_idx_type M_offset = nCols * nRows; + const octave_idx_type Y_offset = nCols * nRows * 2; + const octave_idx_type K_offset = nCols * nRows * 3; + octave_idx_type GM_idx = 0; + for (octave_idx_type frame = 0; frame < nFrames; frame++) + { + Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth, + type, + Magick::DirectClass); + + Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows); + for (octave_idx_type col = 0; col < nCols; col++) + { + for (octave_idx_type row = 0; row < nRows; row++) + { + Magick::Color c (double (*img_fvec) / divisor, + double (img_fvec[M_offset]) / divisor, + double (img_fvec[Y_offset]) / divisor, + double (img_fvec[K_offset]) / divisor); + pix[GM_idx] = c; + img_fvec++; + GM_idx += nCols; + } + GM_idx -= nCols * nRows - 1; + } + // Save changes to underlying image. + m_img.syncPixels (); + imvec.push_back (m_img); + } + break; + } + + case Magick::ColorSeparationMatteType: + { + // The fortran_vec offset for the Magenta, Yellow, and blacK channels + const octave_idx_type M_offset = nCols * nRows; + const octave_idx_type Y_offset = nCols * nRows * 2; + const octave_idx_type K_offset = nCols * nRows * 3; + octave_idx_type GM_idx = 0; + for (octave_idx_type frame = 0; frame < nFrames; frame++) + { + Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth, + type, + Magick::DirectClass); + + Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows); + Magick::IndexPacket *ind = m_img.getIndexes (); + for (octave_idx_type col = 0; col < nCols; col++) + { + for (octave_idx_type row = 0; row < nRows; row++) + { + Magick::Color c (double (*img_fvec) / divisor, + double (img_fvec[M_offset]) / divisor, + double (img_fvec[Y_offset]) / divisor, + double (img_fvec[K_offset]) / divisor); + pix[GM_idx] = c; + ind[GM_idx] = MaxRGB - (double (*a_fvec) / divisor); + img_fvec++; + a_fvec++; + GM_idx += nCols; + } + GM_idx -= nCols * nRows - 1; + } + // Save changes to underlying image. + m_img.syncPixels (); + imvec.push_back (m_img); + } + break; + } + + default: + { + error ("__magick_write__: unrecognized Magick::ImageType"); + return; + } + } + return; +} + +void static +write_file (const std::string& filename, + const std::string& ext, + std::vector& imvec) +{ try { - // Read a file into vector of image objects - Magick::readImages (&imvec, args(0).string_value ()); + Magick::writeImages (imvec.begin (), imvec.end (), ext + ":" + filename); } catch (Magick::Warning& w) { @@ -461,409 +1269,7 @@ catch (Magick::Exception& e) { error ("Magick++ exception: %s", e.what ()); - return output; - } - - int nframes = imvec.size (); - if (all_frames) - { - frameidx = Array (dim_vector (1, nframes)); - for (int i = 0; i < frameidx.length (); i++) - frameidx(i) = i; - } - else - { - for (int i = 0; i < frameidx.length (); i++) - { - frameidx(i) = frameidx(i) - 1; - - if (frameidx(i) >= nframes || frameidx(i) < 0) - { - error ("__magick_read__: invalid INDEX vector"); - return output; - } - } - } - - Magick::ClassType klass = imvec[0].classType (); - - if (klass == Magick::PseudoClass && nargout > 1) - output = read_indexed_images (imvec, frameidx, (nargout == 3)); - else - { - unsigned int depth = imvec[0].modulusDepth (); - if (depth > 1) - { - --depth; - int i = 1; - while (depth >>= 1) - i++; - depth = 1 << i; - } - - switch (depth) - { - case 1: - output = read_images (imvec, frameidx, depth); - break; - - case 2: - case 4: - case 8: - output = read_images (imvec, frameidx, depth) ; - break; - - case 16: - output = read_images (imvec, frameidx, depth); - break; - - case 32: - case 64: - default: - error ("__magick_read__: image depths greater than 16-bit are not supported"); - } - } -#else - - error ("imread: image reading capabilities were disabled when Octave was compiled"); - -#endif - - return output; -} - -/* -## No test needed for internal helper function. -%!assert (1) -*/ - -#ifdef HAVE_MAGICK - -static void -jpg_settings (std::vector& imvec, - const octave_map& options, - bool) -{ - bool something_set = false; - - // Quality setting - octave_value result; - octave_map::const_iterator p; - bool found_it = false; - - for (p = options.begin (); p != options.end (); p++) - { - if (options.key (p) == "Quality") - { - found_it = true; - result = options.contents (p).elem (0); - break; - } - } - - if (found_it && (! result.is_empty ())) - { - something_set = true; - - if (result.is_real_type ()) - { - int qlev = result.int_value (); - - if (qlev < 0 || qlev > 100) - warning ("warning: Quality setting invalid--use default of 75"); - else - { - for (size_t fnum = 0; fnum < imvec.size (); fnum++) - imvec[fnum].quality (static_cast(qlev)); - } - } - else - warning ("warning: Quality setting invalid--use default of 75"); - } - - // Other settings go here - - if (! something_set) - warning ("__magick_write__ warning: all write parameters ignored"); -} - -static void -encode_bool_image (std::vector& imvec, const octave_value& img) -{ - unsigned int nframes = 1; - boolNDArray m = img.bool_array_value (); - - dim_vector dsizes = m.dims (); - if (dsizes.length () == 4) - nframes = dsizes(3); - - Array idx (dim_vector (dsizes.length (), 1)); - - octave_idx_type rows = m.rows (); - octave_idx_type columns = m.columns (); - - for (unsigned int ii = 0; ii < nframes; ii++) - { - Magick::Image im (Magick::Geometry (columns, rows), "black"); - im.classType (Magick::DirectClass); - im.depth (1); - - for (int y = 0; y < columns; y++) - { - idx(1) = y; - - for (int x = 0; x < rows; x++) - { - if (nframes > 1) - { - idx(2) = 0; - idx(3) = ii; - } - - idx(0) = x; - - if (m(idx)) - im.pixelColor (y, x, "white"); - } - } - - im.quantizeColorSpace (Magick::GRAYColorspace); - im.quantizeColors (2); - im.quantize (); - - imvec.push_back (im); - } -} - -template -static void -encode_uint_image (std::vector& imvec, - const octave_value& img, - bool has_map) -{ - unsigned int bitdepth = 0; - T m; - - if (img.is_uint8_type ()) - { - bitdepth = 8; - m = img.uint8_array_value (); - } - else if (img.is_uint16_type ()) - { - bitdepth = 16; - m = img.uint16_array_value (); - } - else - error ("__magick_write__: invalid image class"); - - dim_vector dsizes = m.dims (); - unsigned int nframes = 1; - if (dsizes.length () == 4) - nframes = dsizes(3); - - bool is_color = ((dsizes.length () > 2) && (dsizes(2) > 2)); - bool has_alpha = (dsizes.length () > 2 && (dsizes(2) == 2 || dsizes(2) == 4)); - - Array idx (dim_vector (dsizes.length (), 1)); - octave_idx_type rows = m.rows (); - octave_idx_type columns = m.columns (); - - unsigned int div_factor = (1 << bitdepth) - 1; - - for (unsigned int ii = 0; ii < nframes; ii++) - { - Magick::Image im (Magick::Geometry (columns, rows), "black"); - - im.depth (bitdepth); - - if (has_map) - im.classType (Magick::PseudoClass); - else - im.classType (Magick::DirectClass); - - if (is_color) - { - if (has_alpha) - im.type (Magick::TrueColorMatteType); - else - im.type (Magick::TrueColorType); - - Magick::ColorRGB c; - - for (int y = 0; y < columns; y++) - { - idx(1) = y; - - for (int x = 0; x < rows; x++) - { - idx(0) = x; - - if (nframes > 1) - idx(3) = ii; - - idx(2) = 0; - c.red (static_cast(m(idx)) / div_factor); - - idx(2) = 1; - c.green (static_cast(m(idx)) / div_factor); - - idx(2) = 2; - c.blue (static_cast(m(idx)) / div_factor); - - if (has_alpha) - { - idx(2) = 3; - c.alpha (static_cast(m(idx)) / div_factor); - } - - im.pixelColor (y, x, c); - } - } - } - else - { - if (has_alpha) - im.type (Magick::GrayscaleMatteType); - else - im.type (Magick::GrayscaleType); - - Magick::ColorGray c; - - for (int y = 0; y < columns; y++) - { - idx(1) = y; - - for (int x=0; x < rows; x++) - { - idx(0) = x; - - if (nframes > 1) - { - idx(2) = 0; - idx(3) = ii; - } - - if (has_alpha) - { - idx(2) = 1; - c.alpha (static_cast(m(idx)) / div_factor); - idx(2) = 0; - } - - c.shade (static_cast(m(idx)) / div_factor); - - im.pixelColor (y, x, c); - } - } - - im.quantizeColorSpace (Magick::GRAYColorspace); - im.quantizeColors (1 << bitdepth); - im.quantize (); - } - - imvec.push_back (im); - } -} - -static void -encode_map (std::vector& imvec, const NDArray& cmap) -{ - unsigned int mapsize = cmap.dim1 (); - - for (size_t fnum = 0; fnum < imvec.size (); fnum++) - { - imvec[fnum].colorMapSize (mapsize); - imvec[fnum].type (Magick::PaletteType); - } - - for (unsigned int ii = 0; ii < mapsize; ii++) - { - Magick::ColorRGB c (cmap(ii,0), cmap(ii,1), cmap(ii,2)); - - // FIXME -- is this case needed? - if (cmap.dim2 () == 4) - c.alpha (cmap(ii,3)); - - try - { - for_each (imvec.begin (), imvec.end (), - Magick::colorMapImage (ii, c)); - } - catch (Magick::Warning& w) - { - warning ("Magick++ warning: %s", w.what ()); - } - catch (Magick::ErrorCoder& e) - { - warning ("Magick++ coder error: %s", e.what ()); - } - catch (Magick::Exception& e) - { - error ("Magick++ exception: %s", e.what ()); - } - } -} - -static void -write_image (const std::string& filename, const std::string& fmt, - const octave_value& img, - const octave_value& map = octave_value (), - const octave_value& params = octave_value ()) -{ - std::vector imvec; - - bool has_map = map.is_defined (); - - if (has_map) - { - error ("__magick_write__: direct saving of indexed images not currently supported; use ind2rgb and save converted image"); - return; - } - - if (img.is_bool_type ()) - encode_bool_image (imvec, img); - else if (img.is_uint8_type ()) - encode_uint_image (imvec, img, has_map); - else if (img.is_uint16_type ()) - encode_uint_image (imvec, img, has_map); - else - error ("__magick_write__: image type not supported"); - - if (! error_state && has_map) - { - NDArray cmap = map.array_value (); - - if (! error_state) - encode_map (imvec, cmap); - } - - if (! error_state && params.is_defined ()) - { - octave_map options = params.map_value (); - - // Insert calls here to handle parameters for various image formats - if (fmt == "jpg" || fmt == "jpeg") - jpg_settings (imvec, options, has_map); - else - warning ("warning: your parameter(s) currently not supported"); - } - - try - { - Magick::writeImages (imvec.begin (), imvec.end (), fmt + ":" + filename); - } - catch (Magick::Warning& w) - { - warning ("Magick++ warning: %s", w.what ()); - } - catch (Magick::ErrorCoder& e) - { - warning ("Magick++ coder error: %s", e.what ()); - } - catch (Magick::Exception& e) - { - error ("Magick++ exception: %s", e.what ()); + error_state = 1; } } @@ -871,277 +1277,135 @@ DEFUN_DLD (__magick_write__, args, , "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __magick_write__ (@var{fname}, @var{fmt}, @var{img})\n\ -@deftypefnx {Loadable Function} {} __magick_write__ (@var{fname}, @var{fmt}, @var{img}, @var{map})\n\ -Write images with ImageMagick++. In general you should not be using this\n\ -function. Instead use @code{imwrite}.\n\ -@seealso{imread}\n\ +@deftypefn {Loadable Function} {} __magick_write__ (@var{fname}, @var{fmt}, @var{img}, @var{map}, @var{options})\n\ +Write image with GraphicsMagick or ImageMagick.\n\ +\n\ +This is a private internal function not intended for direct use. Instead\n\ +use @code{imwrite}.\n\ +\n\ +@seealso{imfinfo, imformats, imread, imwrite}\n\ @end deftypefn") { octave_value_list retval; -#ifdef HAVE_MAGICK - maybe_initialize_magick (); - - int nargin = args.length (); - - if (nargin > 2) - { - std::string filename = args(0).string_value (); - - if (! error_state) - { - std::string fmt = args(1).string_value (); - - if (! error_state) - { - if (nargin > 4) - write_image (filename, fmt, args(2), args(3), args(4)); - else if (nargin > 3) - if (args(3).is_real_type ()) - write_image (filename, fmt, args(2), args(3)); - else - write_image (filename, fmt, args(2), octave_value (), args(3)); - else - write_image (filename, fmt, args(2)); - } - else - error ("__magick_write__: FMT must be string"); - } - else - error ("__magick_write__: FNAME must be a string"); - } - else - print_usage (); +#ifndef HAVE_MAGICK + gripe_disabled_feature ("imwrite", "Image IO"); #else - error ("__magick_write__: not available in this version of Octave"); - -#endif - -return retval; -} - -/* -## No test needed for internal helper function. -%!assert (1) -*/ - -#ifdef HAVE_MAGICK - -template -static octave_value -magick_to_octave_value (const T magick) -{ - return octave_value (magick); -} - -static octave_value -magick_to_octave_value (const Magick::EndianType magick) -{ - switch (magick) - { - case Magick::LSBEndian: - return octave_value ("little-endian"); - - case Magick::MSBEndian: - return octave_value ("big-endian"); - - default: - return octave_value ("undefined"); - } -} - -static octave_value -magick_to_octave_value (const Magick::ResolutionType magick) -{ - switch (magick) - { - case Magick::PixelsPerInchResolution: - return octave_value ("pixels per inch"); - - case Magick::PixelsPerCentimeterResolution: - return octave_value ("pixels per centimeter"); - - default: - return octave_value ("undefined"); - } -} - -static octave_value -magick_to_octave_value (const Magick::ImageType magick) -{ - switch (magick) - { - case Magick::BilevelType: - case Magick::GrayscaleType: - case Magick::GrayscaleMatteType: - return octave_value ("grayscale"); - - case Magick::PaletteType: - case Magick::PaletteMatteType: - return octave_value ("indexed"); - - case Magick::TrueColorType: - case Magick::TrueColorMatteType: - case Magick::ColorSeparationType: - return octave_value ("truecolor"); - - default: - return octave_value ("undefined"); - } -} - -// We put this in a try-block because GraphicsMagick will throw -// exceptions if a parameter isn't present in the current image. -#define GET_PARAM(NAME, OUTNAME) \ - try \ - { \ - info.contents (OUTNAME)(frame,0) = magick_to_octave_value (im.NAME ()); \ - } \ - catch (Magick::Warning& w) \ - { \ - } - -#endif - -DEFUN_DLD (__magick_finfo__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __magick_finfo__ (@var{fname})\n\ -Read image information with GraphicsMagick++. In general you should\n\ -not be using this function. Instead use @code{imfinfo}.\n\ -@seealso{imfinfo, imread}\n\ -@end deftypefn") -{ - octave_value retval; - -#ifdef HAVE_MAGICK - maybe_initialize_magick (); - if (args.length () < 1 || ! args (0).is_string ()) + if (args.length () != 5 || ! args(0).is_string () || ! args(1).is_string ()) { print_usage (); return retval; } + const std::string filename = args(0).string_value (); + const std::string ext = args(1).string_value (); - const std::string filename = args (0).string_value (); + const octave_scalar_map options = args(4).scalar_map_value (); + if (error_state) + { + error ("__magick_write__: OPTIONS must be a struct"); + return retval; + } - try + const octave_value img = args(2); + const Matrix cmap = args(3).matrix_value (); + if (error_state) { - // Read the file. - std::vector imvec; - Magick::readImages (&imvec, args(0).string_value ()); - int nframes = imvec.size (); + error ("__magick_write__: invalid IMG or MAP"); + return retval; + } + + std::vector imvec; - // Create the right size for the output. - - static const char *fields[] = + if (cmap.is_empty ()) + { + const octave_value alpha = options.getfield ("alpha"); + if (img.is_bool_type ()) + encode_bool_image (imvec, img.bool_array_value ()); + else if (img.is_uint8_type ()) + encode_uint_image (imvec, img.uint8_array_value (), + alpha.uint8_array_value ()); + else if (img.is_uint16_type ()) + encode_uint_image (imvec, img.uint16_array_value (), + alpha.uint16_array_value ()); + else if (img.is_uint32_type ()) + encode_uint_image (imvec, img.uint32_array_value (), + alpha.uint32_array_value ()); + else if (img.is_float_type ()) { - "Filename", - "FileModDate", - "FileSize", - "Height", - "Width", - "BitDepth", - "Format", - "LongFormat", - "XResolution", - "YResolution", - "TotalColors", - "TileName", - "AnimationDelay", - "AnimationIterations", - "ByteOrder", - "Gamma", - "Matte", - "ModulusDepth", - "Quality", - "QuantizeColors", - "ResolutionUnits", - "ColorType", - "View", - 0 - }; - - octave_map info (dim_vector (nframes, 1), string_vector (fields)); - - file_stat fs (filename); - - std::string filetime; - - if (fs) - { - octave_localtime mtime = fs.mtime (); - - filetime = mtime.strftime ("%e-%b-%Y %H:%M:%S"); + // For image formats that support floating point values, we write + // the actual values. For those who don't, we only use the values + // on the range [0 1] and save integer values. + // But here, even for formats that would support floating point + // values, GM seems unable to do that so we at least make them uint32. + uint32NDArray clip_img; + uint32NDArray clip_alpha; + if (img.is_single_type ()) + { + clip_img = img_float2uint (img.float_array_value ()); + clip_alpha = img_float2uint (alpha.float_array_value ()); + } + else + { + clip_img = img_float2uint (img.array_value ()); + clip_alpha = img_float2uint (alpha.array_value ()); + } + encode_uint_image (imvec, clip_img, clip_alpha); } else { - std::string msg = fs.error (); - - error ("imfinfo: error reading '%s': %s", - filename.c_str (), msg.c_str ()); - + error ("__magick_write__: image type not supported"); + return retval; + } + } + else + { + // We should not get floating point indexed images here because we + // converted them in __imwrite__.m. We should probably do it here + // but it would look much messier. + if (img.is_uint8_type ()) + encode_indexed_images (imvec, img.uint8_array_value (), + cmap); + else if (img.is_uint16_type ()) + encode_indexed_images (imvec, img.uint16_array_value (), + cmap); + else + { + error ("__magick_write__: indexed image must be uint8, uint16 or float."); return retval; } - - // For each frame in the image (some images contain multiple - // layers, each to be treated like a separate image). - for (int frame = 0; frame < nframes; frame++) - { - Magick::Image im = imvec[frame]; - - // Add file name and timestamp. - info.contents ("Filename")(frame,0) = filename; - info.contents ("FileModDate")(frame,0) = filetime; - - // Annoying CamelCase naming is for Matlab compatibility. - GET_PARAM (fileSize, "FileSize") - GET_PARAM (rows, "Height") - GET_PARAM (columns, "Width") - GET_PARAM (depth, "BitDepth") - GET_PARAM (magick, "Format") - GET_PARAM (format, "LongFormat") - GET_PARAM (xResolution, "XResolution") - GET_PARAM (yResolution, "YResolution") - GET_PARAM (totalColors, "TotalColors") - GET_PARAM (tileName, "TileName") - GET_PARAM (animationDelay, "AnimationDelay") - GET_PARAM (animationIterations, "AnimationIterations") - GET_PARAM (endian, "ByteOrder") - GET_PARAM (gamma, "Gamma") - GET_PARAM (matte, "Matte") - GET_PARAM (modulusDepth, "ModulusDepth") - GET_PARAM (quality, "Quality") - GET_PARAM (quantizeColors, "QuantizeColors") - GET_PARAM (resolutionUnits, "ResolutionUnits") - GET_PARAM (type, "ColorType") - GET_PARAM (view, "View") - } - - retval = octave_value (info); - } - catch (Magick::Warning& w) - { - warning ("Magick++ warning: %s", w.what ()); - } - catch (Magick::ErrorCoder& e) - { - warning ("Magick++ coder error: %s", e.what ()); - } - catch (Magick::Exception& e) - { - error ("Magick++ exception: %s", e.what ()); - return retval; } -#else + const octave_idx_type nFrames = imvec.size (); + + // FIXME What happens when we try to set with formats that do not support it? + const octave_idx_type quality = options.getfield ("quality").int_value (); + for (octave_idx_type i = 0; i < nFrames; i++) + imvec[i].quality (quality); - error ("imfinfo: not available in this version of Octave"); + // If writemode is set to append, read the image and append to it. Even + // if set to append, make sure that something was read at all. + const std::string writemode = options.getfield ("writemode").string_value (); + if (writemode == "append" && file_stat (filename).exists ()) + { + std::vector ini_imvec; + read_file (filename, ini_imvec); + if (error_state) + return retval; + if (ini_imvec.size () > 0) + { + ini_imvec.insert (ini_imvec.end (), imvec.begin (), imvec.end ()); + ini_imvec.swap (imvec); + } + } + + write_file (filename, ext, imvec); + if (error_state) + return retval; #endif - return retval; } @@ -1150,63 +1414,686 @@ %!assert (1) */ -#undef GET_PARAM +// Gets the minimum information from images such as its size and format. Much +// faster than using imfinfo, which slows down a lot since. Note than without +// this, we need to read the image once for imfinfo to set defaults (which is +// done in Octave language), and then again for the actual reading. +DEFUN_DLD (__magick_ping__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __magick_ping__ (@var{fname}, @var{idx})\n\ +Ping image information with GraphicsMagick or ImageMagick.\n\ +\n\ +This is a private internal function not intended for direct use.\n\ +\n\ +@seealso{imfinfo}\n\ +@end deftypefn") +{ + octave_value retval; +#ifndef HAVE_MAGICK + gripe_disabled_feature ("imfinfo", "Image IO"); +#else + maybe_initialize_magick (); + + if (args.length () < 1 || ! args(0).is_string ()) + { + print_usage (); + return retval; + } + const std::string filename = args(0).string_value (); + int idx; + if (args.length () > 1) + idx = args(1).int_value () -1; + else + idx = 0; + + Magick::Image img; + img.subImage (idx); + img.subRange (1); + img.ping (filename); + static const char *fields[] = {"rows", "columns", "format", 0}; + octave_scalar_map ping = octave_scalar_map (string_vector (fields)); + ping.setfield ("rows", octave_value (img.rows ())); + ping.setfield ("columns", octave_value (img.columns ())); + ping.setfield ("format", octave_value (img.magick ())); + retval = octave_value (ping); +#endif + return retval; +} + +#ifdef HAVE_MAGICK +static octave_value +magick_to_octave_value (const Magick::CompressionType& magick) +{ + switch (magick) + { + case Magick::NoCompression: + return octave_value ("none"); + case Magick::BZipCompression: + return octave_value ("bzip"); + case Magick::FaxCompression: + return octave_value ("fax3"); + case Magick::Group4Compression: + return octave_value ("fax4"); + case Magick::JPEGCompression: + return octave_value ("jpeg"); + case Magick::LZWCompression: + return octave_value ("lzw"); + case Magick::RLECompression: + // This is named "rle" for the HDF, but the same thing is named + // "ccitt" and "PackBits" for binary and non-binary images in TIFF. + return octave_value ("rle"); + case Magick::ZipCompression: + return octave_value ("deflate"); + + // The following are present only in recent versions of GraphicsMagick. + // At the moment the only use of this would be to have imfinfo report + // the compression method. In the future, someone could implement + // the Compression option for imwrite in which case a macro in + // configure.ac will have to check for their presence of this. + // See bug #39913 +// case Magick::LZMACompression: +// return octave_value ("lzma"); +// case Magick::JPEG2000Compression: +// return octave_value ("jpeg2000"); +// case Magick::JBIG1Compression: +// return octave_value ("jbig1"); +// case Magick::JBIG2Compression: +// return octave_value ("jbig2"); + default: + return octave_value ("undefined"); + } +} + +static octave_value +magick_to_octave_value (const Magick::EndianType& magick) +{ + switch (magick) + { + case Magick::LSBEndian: + return octave_value ("little-endian"); + case Magick::MSBEndian: + return octave_value ("big-endian"); + default: + return octave_value ("undefined"); + } +} -// Determine the file formats supported by GraphicsMagick. This is -// called once at the beginning of imread or imwrite to determine -// exactly which file formats are supported, so error messages can be -// displayed properly. +static octave_value +magick_to_octave_value (const Magick::OrientationType& magick) +{ + switch (magick) + { + // Values come from the TIFF6 spec + case Magick::TopLeftOrientation: + return octave_value (1); + case Magick::TopRightOrientation: + return octave_value (2); + case Magick::BottomRightOrientation: + return octave_value (3); + case Magick::BottomLeftOrientation: + return octave_value (4); + case Magick::LeftTopOrientation: + return octave_value (5); + case Magick::RightTopOrientation: + return octave_value (6); + case Magick::RightBottomOrientation: + return octave_value (7); + case Magick::LeftBottomOrientation: + return octave_value (8); + default: + return octave_value (1); + } +} + +static octave_value +magick_to_octave_value (const Magick::ResolutionType& magick) +{ + switch (magick) + { + case Magick::PixelsPerInchResolution: + return octave_value ("Inch"); + case Magick::PixelsPerCentimeterResolution: + return octave_value ("Centimeter"); + default: + return octave_value ("undefined"); + } +} + +// Meant to be shared with both imfinfo and imwrite. +static std::map +init_disposal_methods () +{ + // GIF Specifications: + // + // Disposal Method - Indicates the way in which the graphic is to + // be treated after being displayed. + // + // 0 - No disposal specified. The decoder is + // not required to take any action. + // 1 - Do not dispose. The graphic is to be left + // in place. + // 2 - Restore to background color. The area used by the + // graphic must be restored to the background color. + // 3 - Restore to previous. The decoder is required to + // restore the area overwritten by the graphic with + // what was there prior to rendering the graphic. + // 4-7 - To be defined. + static std::map methods; + if (methods.empty ()) + { + methods[0] = "doNotSpecify"; + methods[1] = "leaveInPlace"; + methods[2] = "restoreBG"; + methods[3] = "restorePrevious"; + } + return methods; +} -DEFUN_DLD (__magick_format_list__, args, , +static bool +is_valid_exif (const std::string& val) +{ + // Sometimes GM will return the string "unknown" instead of empty + // for an empty value. + return (! val.empty () && val != "unknown"); +} + +static void +fill_exif (octave_scalar_map& map, Magick::Image& img, + const std::string& key) +{ + const std::string attr = img.attribute ("EXIF:" + key); + if (is_valid_exif (attr)) + map.setfield (key, octave_value (attr)); + return; +} + +static void +fill_exif_ints (octave_scalar_map& map, Magick::Image& img, + const std::string& key) +{ + const std::string attr = img.attribute ("EXIF:" + key); + if (is_valid_exif (attr)) + { + // string of the type "float,float,float....." + float number; + ColumnVector values (std::count (attr.begin (), attr.end (), ',') +1); + std::string sub; + std::istringstream sstream (attr); + octave_idx_type n = 0; + while (std::getline (sstream, sub, char (','))) + { + sscanf (sub.c_str (), "%f", &number); + values(n++) = number; + } + map.setfield (key, octave_value (values)); + } + return; +} + +static void +fill_exif_floats (octave_scalar_map& map, Magick::Image& img, + const std::string& key) +{ + const std::string attr = img.attribute ("EXIF:" + key); + if (is_valid_exif (attr)) + { + // string of the type "int/int,int/int,int/int....." + int numerator; + int denominator; + ColumnVector values (std::count (attr.begin (), attr.end (), ',') +1); + std::string sub; + std::istringstream sstream (attr); + octave_idx_type n = 0; + while (std::getline (sstream, sub, ',')) + { + sscanf (sub.c_str (), "%i/%i", &numerator, &denominator); + values(n++) = double (numerator) / double (denominator); + } + map.setfield (key, octave_value (values)); + } + return; +} + +#endif + +DEFUN_DLD (__magick_finfo__, args, , "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __magick_format_list__ (@var{formats})\n\ -Undocumented internal function.\n\ +@deftypefn {Loadable Function} {} __magick_finfo__ (@var{fname})\n\ +Read image information with GraphicsMagick or ImageMagick.\n\ +\n\ +This is a private internal function not intended for direct use. Instead\n\ +use @code{imfinfo}.\n\ +\n\ +@seealso{imfinfo, imformats, imread, imwrite}\n\ @end deftypefn") { octave_value retval; -#ifdef HAVE_MAGICK +#ifndef HAVE_MAGICK + gripe_disabled_feature ("imfinfo", "Image IO"); +#else maybe_initialize_magick (); - std::list accepted_formats; + if (args.length () < 1 || ! args(0).is_string ()) + { + print_usage (); + return retval; + } + const std::string filename = args(0).string_value (); - if (args.length () == 1) - { - Cell c = args (0).cell_value (); + std::vector imvec; + read_file (filename, imvec); + if (error_state) + return retval; + const octave_idx_type nFrames = imvec.size (); + const std::string format = imvec[0].magick (); - if (! error_state) - { - for (octave_idx_type i = 0; i < c.nelem (); i++) - { - try - { - std::string fmt = c.elem (i).string_value (); + // Here's how this function works. We need to return a struct array, one + // struct for each image in the file (remember, there are image + // that allow for multiple images in the same file). Now, Matlab seems + // to have format specific code so the fields on the struct are different + // for each format. It only has a small subset that is common to all + // of them, the others are undocumented. Because we try to abstract from + // the formats we always return the same list of fields (note that with + // GM we support more than 88 formats. That's way more than Matlab, and + // I don't want to write specific code for each of them). + // + // So what we do is we create an octave_scalar_map, fill it with the + // information for that image, and then insert it into an octave_map. + // Because in the same file, different images may have values for + // different fields, we can't create a field only if there's a value. + // Bad things happen if we merge octave_scalar_maps with different + // fields from the others (suppose for example a TIFF file with 4 images, + // where only the third image has a colormap. + + static const char *fields[] = + { + // These are fields that must always appear for Matlab. + "Filename", + "FileModDate", + "FileSize", + "Format", + "FormatVersion", + "Width", + "Height", + "BitDepth", + "ColorType", - Magick::CoderInfo info(fmt); + // These are format specific or not existent in Matlab. The most + // annoying thing is that Matlab may have different names for the + // same thing in different formats. + "DelayTime", + "DisposalMethod", + "LoopCount", + "ByteOrder", + "Gamma", + "Chromaticities", + "Comment", + "Quality", + "Compression", // same as CompressionType + "Colormap", // same as ColorTable (in PNG) + "Orientation", + "ResolutionUnit", + "XResolution", + "YResolution", + "Software", // sometimes is an Exif tag + "Make", // actually an Exif tag + "Model", // actually an Exif tag + "DateTime", // actually an Exif tag + "ImageDescription", // actually an Exif tag + "Artist", // actually an Exif tag + "Copyright", // actually an Exif tag + "DigitalCamera", + "GPSInfo", + // Notes for the future: GM allows to get many attributes, and even has + // attribute() to obtain arbitrary ones, that may exist in only some + // cases. The following is a list of some methods and into what possible + // Matlab compatible values they may be converted. + // + // colorSpace() -> PhotometricInterpretation + // backgroundColor() -> BackgroundColor + // interlaceType() -> Interlaced, InterlaceType, and PlanarConfiguration + // label() -> Title + 0 + }; - if (info.isReadable () && info.isWritable ()) - accepted_formats.push_back (fmt); - } - catch (Magick::Exception& e) - { - // Do nothing: exception here are simply missing formats. - } - } - } - else - error ("__magick_format_list__: expecting a cell array of image format names"); + // The one we will return at the end + octave_map info (dim_vector (nFrames, 1), string_vector (fields)); + + // Some of the fields in the struct are about file information and will be + // the same for all images in the file. So we create a template, fill in + // those values, and make a copy of the template for each image. + octave_scalar_map template_info = (string_vector (fields)); + + template_info.setfield ("Format", octave_value (format)); + // We can't actually get FormatVersion but even Matlab sometimes can't. + template_info.setfield ("FormatVersion", octave_value ("")); + + const file_stat fs (filename); + if (fs) + { + const octave_localtime mtime (fs.mtime ()); + const std::string filetime = mtime.strftime ("%e-%b-%Y %H:%M:%S"); + template_info.setfield ("Filename", octave_value (filename)); + template_info.setfield ("FileModDate", octave_value (filetime)); + template_info.setfield ("FileSize", octave_value (fs.size ())); } else - print_usage (); + { + error ("imfinfo: error reading '%s': %s", + filename.c_str (), fs.error ().c_str ()); + return retval; + } + + for (octave_idx_type frame = 0; frame < nFrames; frame++) + { + octave_scalar_map info_frame (template_info); + const Magick::Image img = imvec[frame]; + + info_frame.setfield ("Width", octave_value (img.columns ())); + info_frame.setfield ("Height", octave_value (img.rows ())); + info_frame.setfield ("BitDepth", + octave_value (get_depth (const_cast (img)))); + + // Stuff related to colormap, image class and type + // Because GM is too smart for us... Read the comments in is_indexed() + { + std::string color_type; + Matrix cmap; + if (is_indexed (img)) + { + color_type = "indexed"; + cmap = read_maps (const_cast (img))(0).matrix_value (); + } + else + { + switch (img.type ()) + { + case Magick::BilevelType: + case Magick::GrayscaleType: + case Magick::GrayscaleMatteType: + color_type = "grayscale"; + break; + + case Magick::TrueColorType: + case Magick::TrueColorMatteType: + color_type = "truecolor"; + break; + + case Magick::PaletteType: + case Magick::PaletteMatteType: + // we should never get here or is_indexed needs to be fixed + color_type = "indexed"; + break; + + case Magick::ColorSeparationType: + case Magick::ColorSeparationMatteType: + color_type = "CMYK"; + break; + + default: + color_type = "undefined"; + } + } + info_frame.setfield ("ColorType", octave_value (color_type)); + info_frame.setfield ("Colormap", octave_value (cmap)); + } + + { + // Not all images have chroma values. In such cases, they'll + // be all zeros. So rather than send a matrix of zeros, we will + // check for that, and send an empty vector instead. + RowVector chromaticities (8); + double* chroma_fvec = chromaticities.fortran_vec (); + img.chromaWhitePoint (&chroma_fvec[0], &chroma_fvec[1]); + img.chromaRedPrimary (&chroma_fvec[2], &chroma_fvec[3]); + img.chromaGreenPrimary (&chroma_fvec[4], &chroma_fvec[5]); + img.chromaBluePrimary (&chroma_fvec[6], &chroma_fvec[7]); + if (chromaticities.nnz () == 0) + chromaticities = RowVector (0); + info_frame.setfield ("Chromaticities", octave_value (chromaticities)); + } - retval = Cell (accepted_formats); + info_frame.setfield ("Gamma", octave_value (img.gamma ())); + info_frame.setfield ("XResolution", octave_value (img.xResolution ())); + info_frame.setfield ("YResolution", octave_value (img.yResolution ())); + info_frame.setfield ("DelayTime", octave_value (img.animationDelay ())); + info_frame.setfield ("LoopCount", octave_value (img.animationIterations ())); + info_frame.setfield ("Quality", octave_value (img.quality ())); + info_frame.setfield ("Comment", octave_value (img.comment ())); + + info_frame.setfield ("Compression", + magick_to_octave_value (img.compressType ())); + info_frame.setfield ("Orientation", + magick_to_octave_value (img.orientation ())); + info_frame.setfield ("ResolutionUnit", + magick_to_octave_value (img.resolutionUnits ())); + info_frame.setfield ("ByteOrder", + magick_to_octave_value (img.endian ())); + + // It is not possible to know if there's an Exif field so we just + // check for the Exif Version value. If it does exists, then we + // bother about looking for specific fields. + { + Magick::Image& cimg = const_cast (img); + + // These will be in Exif tags but must appear as fields in the + // base struct array, not as another struct in one of its fields. + // This is likely because they belong to the Baseline TIFF specs + // and may appear out of the Exif tag. So first we check if it + // exists outside the Exif tag. + // See Section 4.6.4, table 4, page 28 of Exif specs version 2.3 + // (CIPA DC- 008-Translation- 2010) + static const char *base_exif_str_fields[] = { + "DateTime", + "ImageDescription", + "Make", + "Model", + "Software", + "Artist", + "Copyright", + 0, + }; + static const string_vector base_exif_str (base_exif_str_fields); + static const octave_idx_type n_base_exif_str = base_exif_str.numel (); + for (octave_idx_type field = 0; field < n_base_exif_str; field++) + { + info_frame.setfield (base_exif_str[field], + octave_value (cimg.attribute (base_exif_str[field]))); + fill_exif (info_frame, cimg, base_exif_str[field]); + } + + octave_scalar_map camera; + octave_scalar_map gps; + if (! cimg.attribute ("EXIF:ExifVersion").empty ()) + { + // See Section 4.6.5, table 7 and 8, over pages page 42 to 43 + // of Exif specs version 2.3 (CIPA DC- 008-Translation- 2010) + + // Listed on the Exif specs as being of type ASCII. + static const char *exif_str_fields[] = { + "RelatedSoundFile", + "DateTimeOriginal", + "DateTimeDigitized", + "SubSecTime", + "DateTimeOriginal", + "SubSecTimeOriginal", + "SubSecTimeDigitized", + "ImageUniqueID", + "CameraOwnerName", + "BodySerialNumber", + "LensMake", + "LensModel", + "LensSerialNumber", + "SpectralSensitivity", + // These last two are of type undefined but most likely will + // be strings. Even if they're not GM returns a string anyway. + "UserComment", + "MakerComment", + 0 + }; + static const string_vector exif_str (exif_str_fields); + static const octave_idx_type n_exif_str = exif_str.numel (); + for (octave_idx_type field = 0; field < n_exif_str; field++) + fill_exif (camera, cimg, exif_str[field]); -#else + // Listed on the Exif specs as being of type SHORT or LONG. + static const char *exif_int_fields[] = { + "ColorSpace", + "ExifImageWidth", // PixelXDimension (CPixelXDimension in Matlab) + "ExifImageHeight", // PixelYDimension (CPixelYDimension in Matlab) + "PhotographicSensitivity", + "StandardOutputSensitivity", + "RecommendedExposureIndex", + "ISOSpeed", + "ISOSpeedLatitudeyyy", + "ISOSpeedLatitudezzz", + "FocalPlaneResolutionUnit", + "FocalLengthIn35mmFilm", + // Listed as SHORT or LONG but with more than 1 count. + "SubjectArea", + "SubjectLocation", + // While the following are an integer, their value have a meaning + // that must be represented as a string for Matlab compatibility. + // For example, a 3 on ExposureProgram, would return + // "Aperture priority" as defined on the Exif specs. + "ExposureProgram", + "SensitivityType", + "MeteringMode", + "LightSource", + "Flash", + "SensingMethod", + "FileSource", + "CustomRendered", + "ExposureMode", + "WhiteBalance", + "SceneCaptureType", + "GainControl", + "Contrast", + "Saturation", + "Sharpness", + "SubjectDistanceRange", + 0 + }; + static const string_vector exif_int (exif_int_fields); + static const octave_idx_type n_exif_int = exif_int.numel (); + for (octave_idx_type field = 0; field < n_exif_int; field++) + fill_exif_ints (camera, cimg, exif_int[field]); + + // Listed as RATIONAL or SRATIONAL + static const char *exif_float_fields[] = { + "Gamma", + "CompressedBitsPerPixel", + "ExposureTime", + "FNumber", + "ShutterSpeedValue", // SRATIONAL + "ApertureValue", + "BrightnessValue", // SRATIONAL + "ExposureBiasValue", // SRATIONAL + "MaxApertureValue", + "SubjectDistance", + "FocalLength", + "FlashEnergy", + "FocalPlaneXResolution", + "FocalPlaneYResolution", + "ExposureIndex", + "DigitalZoomRatio", + // Listed as RATIONAL or SRATIONAL with more than 1 count. + "LensSpecification", + 0 + }; + static const string_vector exif_float (exif_float_fields); + static const octave_idx_type n_exif_float = exif_float.numel (); + for (octave_idx_type field = 0; field < n_exif_float; field++) + fill_exif_floats (camera, cimg, exif_float[field]); + + // Inside a Exif field, it is possible that there is also a + // GPS field. This is not the same as ExifVersion but seems + // to be how we have to check for it. + if (cimg.attribute ("EXIF:GPSInfo") != "unknown") + { + // The story here is the same as with Exif. + // See Section 4.6.6, table 15 on page 68 of Exif specs + // version 2.3 (CIPA DC- 008-Translation- 2010) - error ("__magick_format_list__: not available in this version of Octave"); + static const char *gps_str_fields[] = { + "GPSLatitudeRef", + "GPSLongitudeRef", + "GPSAltitudeRef", + "GPSSatellites", + "GPSStatus", + "GPSMeasureMode", + "GPSSpeedRef", + "GPSTrackRef", + "GPSImgDirectionRef", + "GPSMapDatum", + "GPSDestLatitudeRef", + "GPSDestLongitudeRef", + "GPSDestBearingRef", + "GPSDestDistanceRef", + "GPSDateStamp", + 0 + }; + static const string_vector gps_str (gps_str_fields); + static const octave_idx_type n_gps_str = gps_str.numel (); + for (octave_idx_type field = 0; field < n_gps_str; field++) + fill_exif (gps, cimg, gps_str[field]); + + static const char *gps_int_fields[] = { + "GPSDifferential", + 0 + }; + static const string_vector gps_int (gps_int_fields); + static const octave_idx_type n_gps_int = gps_int.numel (); + for (octave_idx_type field = 0; field < n_gps_int; field++) + fill_exif_ints (gps, cimg, gps_int[field]); + static const char *gps_float_fields[] = { + "GPSAltitude", + "GPSDOP", + "GPSSpeed", + "GPSTrack", + "GPSImgDirection", + "GPSDestBearing", + "GPSDestDistance", + "GPSHPositioningError", + // Listed as RATIONAL or SRATIONAL with more than 1 count. + "GPSLatitude", + "GPSLongitude", + "GPSTimeStamp", + "GPSDestLatitude", + "GPSDestLongitude", + 0 + }; + static const string_vector gps_float (gps_float_fields); + static const octave_idx_type n_gps_float = gps_float.numel (); + for (octave_idx_type field = 0; field < n_gps_float; field++) + fill_exif_floats (gps, cimg, gps_float[field]); + + } + } + info_frame.setfield ("DigitalCamera", octave_value (camera)); + info_frame.setfield ("GPSInfo", octave_value (gps)); + } + + info.fast_elem_insert (frame, info_frame); + } + + if (format == "GIF") + { + static std::map disposal_methods + = init_disposal_methods (); + string_vector methods (nFrames); + for (octave_idx_type frame = 0; frame < nFrames; frame++) + methods[frame] = disposal_methods[imvec[frame].gifDisposeMethod ()]; + info.setfield ("DisposalMethod", Cell (methods)); + } + else + info.setfield ("DisposalMethod", + Cell (dim_vector (nFrames, 1), octave_value (""))); + + retval = octave_value (info); #endif - return retval; } @@ -1214,3 +2101,58 @@ ## No test needed for internal helper function. %!assert (1) */ + +DEFUN_DLD (__magick_formats__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __magick_imformats__ (@var{formats})\n\ +Fill formats info with GraphicsMagick CoderInfo.\n\ +\n\ +@seealso{imfinfo, imformats, imread, imwrite}\n\ +@end deftypefn") +{ + octave_value retval; +#ifndef HAVE_MAGICK + gripe_disabled_feature ("imformats", "Image IO"); +#else + if (args.length () != 1 || ! args(0).is_map ()) + { + print_usage (); + return retval; + } + octave_map formats = args(0).map_value (); + + maybe_initialize_magick (); + for (octave_idx_type idx = 0; idx < formats.numel (); idx++) + { + try + { + octave_scalar_map fmt = formats.checkelem (idx); + Magick::CoderInfo coder (fmt.getfield ("coder").string_value ()); + + fmt.setfield ("description", octave_value (coder.description ())); + fmt.setfield ("multipage", coder.isMultiFrame () ? true : false); + // default for read and write is a function handle. If we can't + // read or write them, them set it to an empty value + if (! coder.isReadable ()) + fmt.setfield ("read", Matrix ()); + if (! coder.isWritable ()) + fmt.setfield ("write", Matrix ()); + formats.fast_elem_insert (idx, fmt); + } + catch (Magick::Exception& e) + { + // Exception here are missing formats. So we remove the format + // from the structure and reduce idx. + formats.delete_elements (idx); + idx--; + } + } + retval = formats; +#endif + return retval; +} + +/* +## No test needed for internal helper function. +%!assert (1) +*/ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/dldfcn/chol.cc --- a/libinterp/dldfcn/chol.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/dldfcn/chol.cc Sat Oct 05 11:22:09 2013 -0400 @@ -103,8 +103,8 @@ @end ifnottex\n\ \n\ The sparsity preserving permutation is generally returned as a matrix.\n\ -However, given the flag \"vector\", @var{Q} will be returned as a vector\n\ -such that\n\ +However, given the flag @qcode{\"vector\"}, @var{Q} will be returned as a\n\ +vector such that\n\ @tex\n\ $ R^T R = A (Q, Q)$.\n\ @end tex\n\ @@ -116,8 +116,8 @@ \n\ @end ifnottex\n\ \n\ -Called with either a sparse or full matrix and using the \"lower\" flag,\n\ -@code{chol} returns the lower triangular factorization such that\n\ +Called with either a sparse or full matrix and using the @qcode{\"lower\"}\n\ +flag, @code{chol} returns the lower triangular factorization such that\n\ @tex\n\ $ L L^T = A $.\n\ @end tex\n\ @@ -129,13 +129,13 @@ \n\ @end ifnottex\n\ \n\ -For full matrices, if the \"lower\" flag is set only the lower triangular\n\ -part of the matrix is used for the factorization, otherwise the upper\n\ -triangular part is used.\n\ +For full matrices, if the @qcode{\"lower\"} flag is set only the lower\n\ +triangular part of the matrix is used for the factorization, otherwise the\n\ +upper triangular part is used.\n\ \n\ In general the lower triangular factorization is significantly faster for\n\ sparse matrices.\n\ -@seealso{cholinv, chol2inv}\n\ +@seealso{hess, lu, qr, qz, schur, svd, cholinv, chol2inv, cholupdate, cholinsert, choldelete, cholshift}\n\ @end deftypefn") { octave_value_list retval; @@ -631,14 +631,14 @@ @itemize @bullet\n\ @item\n\ @var{R1}'*@var{R1} = @var{R}'*@var{R} + @var{u}*@var{u}'\n\ -if @var{op} is \"+\"\n\ +if @var{op} is @qcode{\"+\"}\n\ \n\ @item\n\ @var{R1}'*@var{R1} = @var{R}'*@var{R} - @var{u}*@var{u}'\n\ -if @var{op} is \"-\"\n\ +if @var{op} is @qcode{\"-\"}\n\ @end itemize\n\ \n\ -If @var{op} is \"-\", @var{info} is set to\n\ +If @var{op} is @qcode{\"-\"}, @var{info} is set to\n\ \n\ @itemize\n\ @item 0 if the downdate was successful,\n\ @@ -649,7 +649,7 @@ @end itemize\n\ \n\ If @var{info} is not present, an error message is printed in cases 1 and 2.\n\ -@seealso{chol, qrupdate}\n\ +@seealso{chol, cholinsert, choldelete, cholshift}\n\ @end deftypefn") { octave_idx_type nargin = args.length (); @@ -849,7 +849,7 @@ @end itemize\n\ \n\ If @var{info} is not present, an error message is printed in cases 1 and 2.\n\ -@seealso{chol, cholupdate, choldelete}\n\ +@seealso{chol, cholupdate, choldelete, cholshift}\n\ @end deftypefn") { octave_idx_type nargin = args.length (); @@ -1097,7 +1097,7 @@ positive definite matrix @w{@var{A} = @var{R}'*@var{R}}, @var{R}@tie{}upper\n\ triangular, return the Cholesky@tie{}factorization of @w{A(p,p)}, where\n\ @w{p = [1:j-1,j+1:n+1]}.\n\ -@seealso{chol, cholupdate, cholinsert}\n\ +@seealso{chol, cholupdate, cholinsert, cholshift}\n\ @end deftypefn") { octave_idx_type nargin = args.length (); @@ -1234,7 +1234,7 @@ or @*\n\ @code{p = [1:j-1, shift(j:i,-1), i+1:n]} if @w{@var{j} < @var{i}}. @*\n\ \n\ -@seealso{chol, cholinsert, choldelete}\n\ +@seealso{chol, cholupdate, cholinsert, choldelete}\n\ @end deftypefn") { octave_idx_type nargin = args.length (); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/dldfcn/colamd.cc --- a/libinterp/dldfcn/colamd.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/dldfcn/colamd.cc Sat Oct 05 11:22:09 2013 -0400 @@ -651,7 +651,8 @@ is assumed to be symmetric and the symmetric elimination tree is\n\ returned. The argument @var{typ} controls whether a symmetric or\n\ column elimination tree is returned. Valid values of @var{typ} are\n\ -\"sym\" or \"col\", for symmetric or column elimination tree respectively\n\ +@qcode{\"sym\"} or @qcode{\"col\"}, for symmetric or column elimination tree\n\ +respectively.\n\ \n\ Called with a second argument, @code{etree} also returns the postorder\n\ permutations on the tree.\n\ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/dldfcn/eigs.cc --- a/libinterp/dldfcn/eigs.cc Thu Sep 12 21:08:07 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1521 +0,0 @@ -/* - -Copyright (C) 2005-2012 David Bateman - -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 -. - -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "ov.h" -#include "defun-dld.h" -#include "error.h" -#include "gripes.h" -#include "quit.h" -#include "variables.h" -#include "ov-re-sparse.h" -#include "ov-cx-sparse.h" -#include "oct-map.h" -#include "pager.h" -#include "unwind-prot.h" - -#include "eigs-base.cc" - -// Global pointer for user defined function. -static octave_function *eigs_fcn = 0; - -// Have we warned about imaginary values returned from user function? -static bool warned_imaginary = false; - -// Is this a recursive call? -static int call_depth = 0; - -ColumnVector -eigs_func (const ColumnVector &x, int &eigs_error) -{ - ColumnVector retval; - octave_value_list args; - args(0) = x; - - if (eigs_fcn) - { - octave_value_list tmp = eigs_fcn->do_multi_index_op (1, args); - - if (error_state) - { - eigs_error = 1; - gripe_user_supplied_eval ("eigs"); - return retval; - } - - if (tmp.length () && tmp(0).is_defined ()) - { - if (! warned_imaginary && tmp(0).is_complex_type ()) - { - warning ("eigs: ignoring imaginary part returned from user-supplied function"); - warned_imaginary = true; - } - - retval = ColumnVector (tmp(0).vector_value ()); - - if (error_state) - { - eigs_error = 1; - gripe_user_supplied_eval ("eigs"); - } - } - else - { - eigs_error = 1; - gripe_user_supplied_eval ("eigs"); - } - } - - return retval; -} - -ComplexColumnVector -eigs_complex_func (const ComplexColumnVector &x, int &eigs_error) -{ - ComplexColumnVector retval; - octave_value_list args; - args(0) = x; - - if (eigs_fcn) - { - octave_value_list tmp = eigs_fcn->do_multi_index_op (1, args); - - if (error_state) - { - eigs_error = 1; - gripe_user_supplied_eval ("eigs"); - return retval; - } - - if (tmp.length () && tmp(0).is_defined ()) - { - retval = ComplexColumnVector (tmp(0).complex_vector_value ()); - - if (error_state) - { - eigs_error = 1; - gripe_user_supplied_eval ("eigs"); - } - } - else - { - eigs_error = 1; - gripe_user_supplied_eval ("eigs"); - } - } - - return retval; -} - -DEFUN_DLD (eigs, args, nargout, - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{d} =} eigs (@var{A})\n\ -@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{k})\n\ -@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{k}, @var{sigma})\n\ -@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{k}, @var{sigma}, @var{opts})\n\ -@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B})\n\ -@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B}, @var{k})\n\ -@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B}, @var{k}, @var{sigma})\n\ -@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B}, @var{k}, @var{sigma}, @var{opts})\n\ -@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n})\n\ -@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B})\n\ -@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{k})\n\ -@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B}, @var{k})\n\ -@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{k}, @var{sigma})\n\ -@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B}, @var{k}, @var{sigma})\n\ -@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{k}, @var{sigma}, @var{opts})\n\ -@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B}, @var{k}, @var{sigma}, @var{opts})\n\ -@deftypefnx {Loadable Function} {[@var{V}, @var{d}] =} eigs (@var{A}, @dots{})\n\ -@deftypefnx {Loadable Function} {[@var{V}, @var{d}] =} eigs (@var{af}, @var{n}, @dots{})\n\ -@deftypefnx {Loadable Function} {[@var{V}, @var{d}, @var{flag}] =} eigs (@var{A}, @dots{})\n\ -@deftypefnx {Loadable Function} {[@var{V}, @var{d}, @var{flag}] =} eigs (@var{af}, @var{n}, @dots{})\n\ -Calculate a limited number of eigenvalues and eigenvectors of @var{A},\n\ -based on a selection criteria. The number of eigenvalues and eigenvectors to\n\ -calculate is given by @var{k} and defaults to 6.\n\ -\n\ -By default, @code{eigs} solve the equation\n\ -@tex\n\ -$A \\nu = \\lambda \\nu$,\n\ -@end tex\n\ -@ifinfo\n\ -@code{A * v = lambda * v},\n\ -@end ifinfo\n\ -where\n\ -@tex\n\ -$\\lambda$ is a scalar representing one of the eigenvalues, and $\\nu$\n\ -@end tex\n\ -@ifinfo\n\ -@code{lambda} is a scalar representing one of the eigenvalues, and @code{v}\n\ -@end ifinfo\n\ -is the corresponding eigenvector. If given the positive definite matrix\n\ -@var{B} then @code{eigs} solves the general eigenvalue equation\n\ -@tex\n\ -$A \\nu = \\lambda B \\nu$.\n\ -@end tex\n\ -@ifinfo\n\ -@code{A * v = lambda * B * v}.\n\ -@end ifinfo\n\ -\n\ -The argument @var{sigma} determines which eigenvalues are returned.\n\ -@var{sigma} can be either a scalar or a string. When @var{sigma} is a\n\ -scalar, the @var{k} eigenvalues closest to @var{sigma} are returned. If\n\ -@var{sigma} is a string, it must have one of the following values.\n\ -\n\ -@table @asis\n\ -@item \"lm\"\n\ -Largest Magnitude (default).\n\ -\n\ -@item \"sm\"\n\ -Smallest Magnitude.\n\ -\n\ -@item \"la\"\n\ -Largest Algebraic (valid only for real symmetric problems).\n\ -\n\ -@item \"sa\"\n\ -Smallest Algebraic (valid only for real symmetric problems).\n\ -\n\ -@item \"be\"\n\ -Both Ends, with one more from the high-end if @var{k} is odd (valid only for\n\ -real symmetric problems).\n\ -\n\ -@item \"lr\"\n\ -Largest Real part (valid only for complex or unsymmetric problems).\n\ -\n\ -@item \"sr\"\n\ -Smallest Real part (valid only for complex or unsymmetric problems).\n\ -\n\ -@item \"li\"\n\ -Largest Imaginary part (valid only for complex or unsymmetric problems).\n\ -\n\ -@item \"si\"\n\ -Smallest Imaginary part (valid only for complex or unsymmetric problems).\n\ -@end table\n\ -\n\ -If @var{opts} is given, it is a structure defining possible options that\n\ -@code{eigs} should use. The fields of the @var{opts} structure are:\n\ -\n\ -@table @code\n\ -@item issym\n\ -If @var{af} is given, then flags whether the function @var{af} defines a\n\ -symmetric problem. It is ignored if @var{A} is given. The default is false.\n\ -\n\ -@item isreal\n\ -If @var{af} is given, then flags whether the function @var{af} defines a\n\ -real problem. It is ignored if @var{A} is given. The default is true.\n\ -\n\ -@item tol\n\ -Defines the required convergence tolerance, calculated as\n\ -@code{tol * norm (A)}. The default is @code{eps}.\n\ -\n\ -@item maxit\n\ -The maximum number of iterations. The default is 300.\n\ -\n\ -@item p\n\ -The number of Lanzcos basis vectors to use. More vectors will result in\n\ -faster convergence, but a greater use of memory. The optimal value of\n\ -@code{p} is problem dependent and should be in the range @var{k} to @var{n}.\n\ -The default value is @code{2 * @var{k}}.\n\ -\n\ -@item v0\n\ -The starting vector for the algorithm. An initial vector close to the\n\ -final vector will speed up convergence. The default is for @sc{arpack}\n\ -to randomly generate a starting vector. If specified, @code{v0} must be\n\ -an @var{n}-by-1 vector where @code{@var{n} = rows (@var{A})}\n\ -\n\ -@item disp\n\ -The level of diagnostic printout (0|1|2). If @code{disp} is 0 then\n\ -diagnostics are disabled. The default value is 0.\n\ -\n\ -@item cholB\n\ -Flag if @code{chol (@var{B})} is passed rather than @var{B}. The default is\n\ -false.\n\ -\n\ -@item permB\n\ -The permutation vector of the Cholesky@tie{}factorization of @var{B} if\n\ -@code{cholB} is true. That is @code{chol (@var{B}(permB, permB))}. The\n\ -default is @code{1:@var{n}}.\n\ -\n\ -@end table\n\ -\n\ -It is also possible to represent @var{A} by a function denoted @var{af}.\n\ -@var{af} must be followed by a scalar argument @var{n} defining the length\n\ -of the vector argument accepted by @var{af}. @var{af} can be\n\ -a function handle, an inline function, or a string. When @var{af} is a\n\ -string it holds the name of the function to use.\n\ -\n\ -@var{af} is a function of the form @code{y = af (x)}\n\ -where the required return value of @var{af} is determined by\n\ -the value of @var{sigma}. The four possible forms are\n\ -\n\ -@table @code\n\ -@item A * x\n\ -if @var{sigma} is not given or is a string other than \"sm\".\n\ -\n\ -@item A \\ x\n\ -if @var{sigma} is 0 or \"sm\".\n\ -\n\ -@item (A - sigma * I) \\ x\n\ -for the standard eigenvalue problem, where @code{I} is the identity matrix of\n\ -the same size as @var{A}.\n\ -\n\ -@item (A - sigma * B) \\ x\n\ -for the general eigenvalue problem.\n\ -@end table\n\ -\n\ -The return arguments of @code{eigs} depend on the number of return arguments\n\ -requested. With a single return argument, a vector @var{d} of length @var{k}\n\ -is returned containing the @var{k} eigenvalues that have been found. With\n\ -two return arguments, @var{V} is a @var{n}-by-@var{k} matrix whose columns\n\ -are the @var{k} eigenvectors corresponding to the returned eigenvalues. The\n\ -eigenvalues themselves are returned in @var{d} in the form of a\n\ -@var{n}-by-@var{k} matrix, where the elements on the diagonal are the\n\ -eigenvalues.\n\ -\n\ -Given a third return argument @var{flag}, @code{eigs} returns the status\n\ -of the convergence. If @var{flag} is 0 then all eigenvalues have converged.\n\ -Any other value indicates a failure to converge.\n\ -\n\ -This function is based on the @sc{arpack} package, written by R. Lehoucq,\n\ -K. Maschhoff, D. Sorensen, and C. Yang. For more information see\n\ -@url{http://www.caam.rice.edu/software/ARPACK/}.\n\ -\n\ -@seealso{eig, svds}\n\ -@end deftypefn") -{ - octave_value_list retval; -#ifdef HAVE_ARPACK - int nargin = args.length (); - std::string fcn_name; - octave_idx_type n = 0; - octave_idx_type k = 6; - Complex sigma = 0.; - double sigmar, sigmai; - bool have_sigma = false; - std::string typ = "LM"; - Matrix amm, bmm, bmt; - ComplexMatrix acm, bcm, bct; - SparseMatrix asmm, bsmm, bsmt; - SparseComplexMatrix ascm, bscm, bsct; - int b_arg = 0; - bool have_b = false; - bool have_a_fun = false; - bool a_is_complex = false; - bool b_is_complex = false; - bool symmetric = false; - bool sym_tested = false; - bool cholB = false; - bool a_is_sparse = false; - ColumnVector permB; - int arg_offset = 0; - double tol = std::numeric_limits::epsilon (); - int maxit = 300; - int disp = 0; - octave_idx_type p = -1; - ColumnVector resid; - ComplexColumnVector cresid; - octave_idx_type info = 1; - - warned_imaginary = false; - - unwind_protect frame; - - frame.protect_var (call_depth); - call_depth++; - - if (call_depth > 1) - { - error ("eigs: invalid recursive call"); - if (fcn_name.length ()) - clear_function (fcn_name); - return retval; - } - - if (nargin == 0) - print_usage (); - else if (args(0).is_function_handle () || args(0).is_inline_function () - || args(0).is_string ()) - { - if (args(0).is_string ()) - { - std::string name = args(0).string_value (); - std::string fname = "function y = "; - fcn_name = unique_symbol_name ("__eigs_fcn_"); - fname.append (fcn_name); - fname.append ("(x) y = "); - eigs_fcn = extract_function (args(0), "eigs", fcn_name, fname, - "; endfunction"); - } - else - eigs_fcn = args(0).function_value (); - - if (!eigs_fcn) - { - error ("eigs: unknown function"); - return retval; - } - - if (nargin < 2) - { - error ("eigs: incorrect number of arguments"); - return retval; - } - else - { - n = args(1).nint_value (); - arg_offset = 1; - have_a_fun = true; - } - } - else - { - if (args(0).is_complex_type ()) - { - if (args(0).is_sparse_type ()) - { - ascm = (args(0).sparse_complex_matrix_value ()); - a_is_sparse = true; - } - else - acm = (args(0).complex_matrix_value ()); - a_is_complex = true; - symmetric = false; // ARPACK doesn't special case complex symmetric - sym_tested = true; - } - else - { - if (args(0).is_sparse_type ()) - { - asmm = (args(0).sparse_matrix_value ()); - a_is_sparse = true; - } - else - { - amm = (args(0).matrix_value ()); - } - } - - } - - // Note hold off reading B till later to avoid issues of double - // copies of the matrix if B is full/real while A is complex. - if (!error_state && nargin > 1 + arg_offset && - !(args(1 + arg_offset).is_real_scalar ())) - { - if (args(1+arg_offset).is_complex_type ()) - { - b_arg = 1+arg_offset; - have_b = true; - b_is_complex = true; - arg_offset++; - } - else - { - b_arg = 1+arg_offset; - have_b = true; - arg_offset++; - } - } - - if (!error_state && nargin > (1+arg_offset)) - k = args(1+arg_offset).nint_value (); - - if (!error_state && nargin > (2+arg_offset)) - { - if (args(2+arg_offset).is_string ()) - { - typ = args(2+arg_offset).string_value (); - - // Use STL function to convert to upper case - transform (typ.begin (), typ.end (), typ.begin (), toupper); - - sigma = 0.; - } - else - { - sigma = args(2+arg_offset).complex_value (); - - if (! error_state) - have_sigma = true; - else - { - error ("eigs: SIGMA must be a scalar or a string"); - return retval; - } - } - } - - sigmar = std::real (sigma); - sigmai = std::imag (sigma); - - if (!error_state && nargin > (3+arg_offset)) - { - if (args(3+arg_offset).is_map ()) - { - octave_scalar_map map = args(3+arg_offset).scalar_map_value (); - - if (! error_state) - { - octave_value tmp; - - // issym is ignored for complex matrix inputs - tmp = map.getfield ("issym"); - if (tmp.is_defined () && !sym_tested) - { - symmetric = tmp.double_value () != 0.; - sym_tested = true; - } - - // isreal is ignored if A is not a function - tmp = map.getfield ("isreal"); - if (tmp.is_defined () && have_a_fun) - a_is_complex = ! (tmp.double_value () != 0.); - - tmp = map.getfield ("tol"); - if (tmp.is_defined ()) - tol = tmp.double_value (); - - tmp = map.getfield ("maxit"); - if (tmp.is_defined ()) - maxit = tmp.nint_value (); - - tmp = map.getfield ("p"); - if (tmp.is_defined ()) - p = tmp.nint_value (); - - tmp = map.getfield ("v0"); - if (tmp.is_defined ()) - { - if (a_is_complex || b_is_complex) - cresid = ComplexColumnVector (tmp.complex_vector_value ()); - else - resid = ColumnVector (tmp.vector_value ()); - } - - tmp = map.getfield ("disp"); - if (tmp.is_defined ()) - disp = tmp.nint_value (); - - tmp = map.getfield ("cholB"); - if (tmp.is_defined ()) - cholB = tmp.double_value () != 0.; - - tmp = map.getfield ("permB"); - if (tmp.is_defined ()) - permB = ColumnVector (tmp.vector_value ()) - 1.0; - } - else - { - error ("eigs: OPTS argument must be a scalar structure"); - return retval; - } - } - else - { - error ("eigs: OPTS argument must be a structure"); - return retval; - } - } - - if (nargin > (4+arg_offset)) - { - error ("eigs: incorrect number of arguments"); - return retval; - } - - // Test undeclared (no issym) matrix inputs for symmetry - if (!sym_tested && !have_a_fun) - { - if (a_is_sparse) - symmetric = asmm.is_symmetric (); - else - symmetric = amm.is_symmetric (); - } - - if (have_b) - { - if (a_is_complex || b_is_complex) - { - if (a_is_sparse) - bscm = args(b_arg).sparse_complex_matrix_value (); - else - bcm = args(b_arg).complex_matrix_value (); - } - else - { - if (a_is_sparse) - bsmm = args(b_arg).sparse_matrix_value (); - else - bmm = args(b_arg).matrix_value (); - } - } - - // Mode 1 for SM mode seems unstable for some reason. - // Use Mode 3 instead, with sigma = 0. - if (!error_state && !have_sigma && typ == "SM") - have_sigma = true; - - if (!error_state) - { - octave_idx_type nconv; - if (a_is_complex || b_is_complex) - { - ComplexMatrix eig_vec; - ComplexColumnVector eig_val; - - - if (have_a_fun) - nconv = EigsComplexNonSymmetricFunc - (eigs_complex_func, n, typ, sigma, k, p, info, eig_vec, eig_val, - cresid, octave_stdout, tol, (nargout > 1), cholB, disp, maxit); - else if (have_sigma) - { - if (a_is_sparse) - nconv = EigsComplexNonSymmetricMatrixShift - (ascm, sigma, k, p, info, eig_vec, eig_val, bscm, permB, - cresid, octave_stdout, tol, (nargout > 1), cholB, disp, - maxit); - else - nconv = EigsComplexNonSymmetricMatrixShift - (acm, sigma, k, p, info, eig_vec, eig_val, bcm, permB, cresid, - octave_stdout, tol, (nargout > 1), cholB, disp, maxit); - } - else - { - if (a_is_sparse) - nconv = EigsComplexNonSymmetricMatrix - (ascm, typ, k, p, info, eig_vec, eig_val, bscm, permB, cresid, - octave_stdout, tol, (nargout > 1), cholB, disp, maxit); - else - nconv = EigsComplexNonSymmetricMatrix - (acm, typ, k, p, info, eig_vec, eig_val, bcm, permB, cresid, - octave_stdout, tol, (nargout > 1), cholB, disp, maxit); - } - - if (nargout < 2) - retval(0) = eig_val; - else - { - retval(2) = double (info); - retval(1) = ComplexDiagMatrix (eig_val); - retval(0) = eig_vec; - } - } - else if (sigmai != 0.) - { - // Promote real problem to a complex one. - ComplexMatrix eig_vec; - ComplexColumnVector eig_val; - - if (have_a_fun) - nconv = EigsComplexNonSymmetricFunc - (eigs_complex_func, n, typ, sigma, k, p, info, eig_vec, eig_val, - cresid, octave_stdout, tol, (nargout > 1), cholB, disp, maxit); - else - { - if (a_is_sparse) - nconv = EigsComplexNonSymmetricMatrixShift - (SparseComplexMatrix (asmm), sigma, k, p, info, eig_vec, - eig_val, SparseComplexMatrix (bsmm), permB, cresid, - octave_stdout, tol, (nargout > 1), cholB, disp, maxit); - else - nconv = EigsComplexNonSymmetricMatrixShift - (ComplexMatrix (amm), sigma, k, p, info, eig_vec, - eig_val, ComplexMatrix (bmm), permB, cresid, - octave_stdout, tol, (nargout > 1), cholB, disp, maxit); - } - - if (nargout < 2) - retval(0) = eig_val; - else - { - retval(2) = double (info); - retval(1) = ComplexDiagMatrix (eig_val); - retval(0) = eig_vec; - } - } - else - { - if (symmetric) - { - Matrix eig_vec; - ColumnVector eig_val; - - if (have_a_fun) - nconv = EigsRealSymmetricFunc - (eigs_func, n, typ, sigmar, k, p, info, eig_vec, eig_val, - resid, octave_stdout, tol, (nargout > 1), cholB, disp, - maxit); - else if (have_sigma) - { - if (a_is_sparse) - nconv = EigsRealSymmetricMatrixShift - (asmm, sigmar, k, p, info, eig_vec, eig_val, bsmm, permB, - resid, octave_stdout, tol, (nargout > 1), cholB, disp, - maxit); - else - nconv = EigsRealSymmetricMatrixShift - (amm, sigmar, k, p, info, eig_vec, eig_val, bmm, permB, - resid, octave_stdout, tol, (nargout > 1), cholB, disp, - maxit); - } - else - { - if (a_is_sparse) - nconv = EigsRealSymmetricMatrix - (asmm, typ, k, p, info, eig_vec, eig_val, bsmm, permB, - resid, octave_stdout, tol, (nargout > 1), cholB, disp, - maxit); - else - nconv = EigsRealSymmetricMatrix - (amm, typ, k, p, info, eig_vec, eig_val, bmm, permB, - resid, octave_stdout, tol, (nargout > 1), cholB, disp, - maxit); - } - - if (nargout < 2) - retval(0) = eig_val; - else - { - retval(2) = double (info); - retval(1) = DiagMatrix (eig_val); - retval(0) = eig_vec; - } - } - else - { - ComplexMatrix eig_vec; - ComplexColumnVector eig_val; - - if (have_a_fun) - nconv = EigsRealNonSymmetricFunc - (eigs_func, n, typ, sigmar, k, p, info, eig_vec, eig_val, - resid, octave_stdout, tol, (nargout > 1), cholB, disp, - maxit); - else if (have_sigma) - { - if (a_is_sparse) - nconv = EigsRealNonSymmetricMatrixShift - (asmm, sigmar, k, p, info, eig_vec, eig_val, bsmm, permB, - resid, octave_stdout, tol, (nargout > 1), cholB, disp, - maxit); - else - nconv = EigsRealNonSymmetricMatrixShift - (amm, sigmar, k, p, info, eig_vec, eig_val, bmm, permB, - resid, octave_stdout, tol, (nargout > 1), cholB, disp, - maxit); - } - else - { - if (a_is_sparse) - nconv = EigsRealNonSymmetricMatrix - (asmm, typ, k, p, info, eig_vec, eig_val, bsmm, permB, - resid, octave_stdout, tol, (nargout > 1), cholB, disp, - maxit); - else - nconv = EigsRealNonSymmetricMatrix - (amm, typ, k, p, info, eig_vec, eig_val, bmm, permB, - resid, octave_stdout, tol, (nargout > 1), cholB, disp, - maxit); - } - - if (nargout < 2) - retval(0) = eig_val; - else - { - retval(2) = double (info); - retval(1) = ComplexDiagMatrix (eig_val); - retval(0) = eig_vec; - } - } - } - - if (nconv <= 0) - warning ("eigs: None of the %d requested eigenvalues converged", k); - else if (nconv < k) - warning ("eigs: Only %d of the %d requested eigenvalues converged", - nconv, k); - } - - if (! fcn_name.empty ()) - clear_function (fcn_name); -#else - error ("eigs: not available in this version of Octave"); -#endif - - return retval; -} - -/* #### SPARSE MATRIX VERSIONS #### */ - -/* -## Real positive definite tests, n must be even -%!shared n, k, A, d0, d2 -%! n = 20; -%! k = 4; -%! A = sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),4*ones(1,n),ones(1,n-2)]); -%! d0 = eig (A); -%! d2 = sort (d0); -%! [~, idx] = sort (abs (d0)); -%! d0 = d0(idx); -%! rand ("state", 42); # initialize generator to make eigs behavior reproducible -%!testif HAVE_ARPACK -%! d1 = eigs (A, k); -%! assert (d1, d0(end:-1:(end-k+1)), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k+1); -%! assert (d1, d0(end:-1:(end-k)), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "lm"); -%! assert (d1, d0(end:-1:(end-k+1)), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! d1 = eigs (A, k, "sm"); -%! assert (d1, d0(k:-1:1), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "la"); -%! assert (d1, d2(end:-1:(end-k+1)), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "sa"); -%! assert (d1, d2(1:k), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "be"); -%! assert (d1, d2([1:floor(k/2), (end - ceil(k/2) + 1):end]), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k+1, "be"); -%! assert (d1, d2([1:floor((k+1)/2), (end - ceil((k+1)/2) + 1):end]), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! d1 = eigs (A, k, 4.1); -%! [~, idx0] = sort (abs (d0 - 4.1)); -%! [~, idx1] = sort (abs (d1 - 4.1)); -%! assert (d1(idx1), d0(idx0(1:k)), 1e-11); -%!testif HAVE_ARPACK, HAVE_CHOLMOD -%! d1 = eigs (A, speye (n), k, "lm"); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! assert (eigs (A, k, 4.1), eigs (A, speye (n), k, 4.1), 1e-11); -%!testif HAVE_ARPACK -%! opts.cholB = true; -%! d1 = eigs (A, speye (n), k, "lm", opts); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! opts.cholB = true; -%! q = [2:n,1]; -%! opts.permB = q; -%! d1 = eigs (A, speye (n)(q,q), k, "lm", opts); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! opts.cholB = true; -%! d1 = eigs (A, speye (n), k, 4.1, opts); -%! assert (abs (d1), eigs (A, k, 4.1), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! opts.cholB = true; -%! q = [2:n,1]; -%! opts.permB = q; -%! d1 = eigs (A, speye (n)(q,q), k, 4.1, opts); -%! assert (abs (d1), eigs (A, k, 4.1), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! assert (eigs (A, k, 4.1), eigs (A, speye (n), k, 4.1), 1e-11); -%!testif HAVE_ARPACK -%! fn = @(x) A * x; -%! opts.issym = 1; opts.isreal = 1; -%! d1 = eigs (fn, n, k, "lm", opts); -%! assert (d1, d0(end:-1:(end-k+1)), 1e-11); -%!testif HAVE_ARPACK -%! fn = @(x) A \ x; -%! opts.issym = 1; opts.isreal = 1; -%! d1 = eigs (fn, n, k, "sm", opts); -%! assert (d1, d0(k:-1:1), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! fn = @(x) (A - 4.1 * eye (n)) \ x; -%! opts.issym = 1; opts.isreal = 1; -%! d1 = eigs (fn, n, k, 4.1, opts); -%! assert (d1, eigs (A, k, 4.1), 1e-11); -%!testif HAVE_ARPACK -%! AA = speye (10); -%! fn = @(x) AA * x; -%! opts.issym = 1; opts.isreal = 1; -%! assert (eigs (fn, 10, AA, 3, "lm", opts), [1; 1; 1], 10*eps); -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "lm"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! [v1,d1] = eigs (A, k, "sm"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "la"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "sa"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "be"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11); -%! endfor -*/ - -/* -## Real unsymmetric tests -%!shared n, k, A, d0 -%! n = 20; -%! k = 4; -%! A = sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),1:n,-ones(1,n-2)]); -%! d0 = eig (A); -%! [~, idx] = sort (abs (d0)); -%! d0 = d0(idx); -%! rand ("state", 42); % initialize generator to make eigs behavior reproducible -%!testif HAVE_ARPACK -%! d1 = eigs (A, k); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k+1); -%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "lm"); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! d1 = eigs (A, k, "sm"); -%! assert (abs (d1), abs (d0(1:k)), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "lr"); -%! [~, idx] = sort (real (d0)); -%! d2 = d0(idx); -%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "sr"); -%! [~, idx] = sort (real (abs (d0))); -%! d2 = d0(idx); -%! assert (real (d1), real (d2(1:k)), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "li"); -%! [~, idx] = sort (imag (abs (d0))); -%! d2 = d0(idx); -%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "si"); -%! [~, idx] = sort (imag (abs (d0))); -%! d2 = d0(idx); -%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! d1 = eigs (A, k, 4.1); -%! [~, idx0] = sort (abs (d0 - 4.1)); -%! [~, idx1] = sort (abs (d1 - 4.1)); -%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11); -%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11); -%!testif HAVE_ARPACK, HAVE_CHOLMOD -%! d1 = eigs (A, speye (n), k, "lm"); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! opts.cholB = true; -%! d1 = eigs (A, speye (n), k, "lm", opts); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! opts.cholB = true; -%! q = [2:n,1]; -%! opts.permB = q; -%! d1 = eigs (A, speye (n)(q,q), k, "lm", opts); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! opts.cholB = true; -%! d1 = eigs (A, speye (n), k, 4.1, opts); -%! assert (abs (d1), eigs (A, k, 4.1), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! opts.cholB = true; -%! q = [2:n,1]; -%! opts.permB = q; -%! d1 = eigs (A, speye (n)(q,q), k, 4.1, opts); -%! assert (abs (d1), eigs (A, k, 4.1), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, speye (n), k, 4.1)), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, speye (n), k, 4.1))), 1e-11); -%!testif HAVE_ARPACK -%! fn = @(x) A * x; -%! opts.issym = 0; opts.isreal = 1; -%! d1 = eigs (fn, n, k, "lm", opts); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! fn = @(x) A \ x; -%! opts.issym = 0; opts.isreal = 1; -%! d1 = eigs (fn, n, k, "sm", opts); -%! assert (abs (d1), d0(1:k), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! fn = @(x) (A - 4.1 * eye (n)) \ x; -%! opts.issym = 0; opts.isreal = 1; -%! d1 = eigs (fn, n, k, 4.1, opts); -%! assert (abs (d1), eigs (A, k, 4.1), 1e-11); -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "lm"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! [v1,d1] = eigs (A, k, "sm"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "lr"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "sr"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "li"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "si"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11); -%! endfor -*/ - -/* -## Complex hermitian tests -%!shared n, k, A, d0 -%! n = 20; -%! k = 4; -%! A = sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[1i*ones(1,n-2),4*ones(1,n),-1i*ones(1,n-2)]); -%! d0 = eig (A); -%! [~, idx] = sort (abs (d0)); -%! d0 = d0(idx); -%! rand ("state", 42); % initialize generator to make eigs behavior reproducible -%!testif HAVE_ARPACK -%! d1 = eigs (A, k); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k+1); -%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "lm"); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! d1 = eigs (A, k, "sm"); -%! assert (abs (d1), abs (d0(1:k)), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "lr"); -%! [~, idx] = sort (real (abs (d0))); -%! d2 = d0(idx); -%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "sr"); -%! [~, idx] = sort (real (abs (d0))); -%! d2 = d0(idx); -%! assert (real (d1), real (d2(1:k)), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "li"); -%! [~, idx] = sort (imag (abs (d0))); -%! d2 = d0(idx); -%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "si"); -%! [~, idx] = sort (imag (abs (d0))); -%! d2 = d0(idx); -%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! d1 = eigs (A, k, 4.1); -%! [~, idx0] = sort (abs (d0 - 4.1)); -%! [~, idx1] = sort (abs (d1 - 4.1)); -%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11); -%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11); -%!testif HAVE_ARPACK, HAVE_CHOLMOD -%! d1 = eigs (A, speye (n), k, "lm"); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! opts.cholB = true; -%! d1 = eigs (A, speye (n), k, "lm", opts); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! opts.cholB = true; -%! q = [2:n,1]; -%! opts.permB = q; -%! d1 = eigs (A, speye (n)(q,q), k, "lm", opts); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! opts.cholB = true; -%! d1 = eigs (A, speye (n), k, 4.1, opts); -%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11); -%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! opts.cholB = true; -%! q = [2:n,1]; -%! opts.permB = q; -%! d1 = eigs (A, speye (n)(q,q), k, 4.1, opts); -%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11); -%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, speye (n), k, 4.1)), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, speye (n), k, 4.1))), 1e-11); -%!testif HAVE_ARPACK -%! fn = @(x) A * x; -%! opts.issym = 0; opts.isreal = 0; -%! d1 = eigs (fn, n, k, "lm", opts); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! fn = @(x) A \ x; -%! opts.issym = 0; opts.isreal = 0; -%! d1 = eigs (fn, n, k, "sm", opts); -%! assert (abs (d1), d0(1:k), 1e-11); -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! fn = @(x) (A - 4.1 * eye (n)) \ x; -%! opts.issym = 0; opts.isreal = 0; -%! d1 = eigs (fn, n, k, 4.1, opts); -%! assert (abs (d1), eigs (A, k, 4.1), 1e-11); -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "lm"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK, HAVE_UMFPACK -%! [v1,d1] = eigs (A, k, "sm"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "lr"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "sr"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "li"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "si"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11); -%! endfor -*/ - -/* #### FULL MATRIX VERSIONS #### */ - -/* -## Real positive definite tests, n must be even -%!shared n, k, A, d0, d2 -%! n = 20; -%! k = 4; -%! A = full (sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),4*ones(1,n),ones(1,n-2)])); -%! d0 = eig (A); -%! d2 = sort (d0); -%! [~, idx] = sort (abs (d0)); -%! d0 = d0(idx); -%! rand ("state", 42); % initialize generator to make eigs behavior reproducible -%!testif HAVE_ARPACK -%! d1 = eigs (A, k); -%! assert (d1, d0(end:-1:(end-k+1)), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k+1); -%! assert (d1, d0(end:-1:(end-k)),1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "lm"); -%! assert (d1, d0(end:-1:(end-k+1)), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "sm"); -%! assert (d1, d0(k:-1:1), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "la"); -%! assert (d1, d2(end:-1:(end-k+1)), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "sa"); -%! assert (d1, d2(1:k), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "be"); -%! assert (d1, d2([1:floor(k/2), (end - ceil(k/2) + 1):end]), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k+1, "be"); -%! assert (d1, d2([1:floor((k+1)/2), (end - ceil((k+1)/2) + 1):end]), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, 4.1); -%! [~, idx0] = sort (abs (d0 - 4.1)); -%! [~, idx1] = sort (abs (d1 - 4.1)); -%! assert (d1(idx1), d0(idx0(1:k)), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, eye (n), k, "lm"); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! assert (eigs (A, k, 4.1), eigs (A, eye (n), k, 4.1), 1e-11); -%!testif HAVE_ARPACK -%! opts.cholB = true; -%! d1 = eigs (A, eye (n), k, "lm", opts); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! opts.cholB = true; -%! q = [2:n,1]; -%! opts.permB = q; -%! d1 = eigs (A, eye (n)(q,q), k, "lm", opts); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! opts.cholB = true; -%! d1 = eigs (A, eye (n), k, 4.1, opts); -%! assert (abs (d1), eigs (A, k, 4.1), 1e-11); -%!testif HAVE_ARPACK -%! opts.cholB = true; -%! q = [2:n,1]; -%! opts.permB = q; -%! d1 = eigs (A, eye (n)(q,q), k, 4.1, opts); -%! assert (abs (d1), eigs (A, k, 4.1), 1e-11); -%!testif HAVE_ARPACK -%! assert (eigs (A, k, 4.1), eigs (A, eye (n), k, 4.1), 1e-11); -%!testif HAVE_ARPACK -%! fn = @(x) A * x; -%! opts.issym = 1; opts.isreal = 1; -%! d1 = eigs (fn, n, k, "lm", opts); -%! assert (d1, d0(end:-1:(end-k+1)), 1e-11); -%!testif HAVE_ARPACK -%! fn = @(x) A \ x; -%! opts.issym = 1; opts.isreal = 1; -%! d1 = eigs (fn, n, k, "sm", opts); -%! assert (d1, d0(k:-1:1), 1e-11); -%!testif HAVE_ARPACK -%! fn = @(x) (A - 4.1 * eye (n)) \ x; -%! opts.issym = 1; opts.isreal = 1; -%! d1 = eigs (fn, n, k, 4.1, opts); -%! assert (d1, eigs (A, k, 4.1), 1e-11); -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "lm"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "sm"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "la"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "sa"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "be"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11); -%! endfor -*/ - -/* -## Real unsymmetric tests -%!shared n, k, A, d0 -%! n = 20; -%! k = 4; -%! A = full (sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),1:n,-ones(1,n-2)])); -%! d0 = eig (A); -%! [~, idx] = sort (abs (d0)); -%! d0 = d0(idx); -%! rand ("state", 42); % initialize generator to make eigs behavior reproducible -%!testif HAVE_ARPACK -%! d1 = eigs (A, k); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k+1); -%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "lm"); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "sm"); -%! assert (abs (d1), abs (d0(1:k)), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "lr"); -%! [~, idx] = sort (real (d0)); -%! d2 = d0(idx); -%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "sr"); -%! [~, idx] = sort (real (abs (d0))); -%! d2 = d0(idx); -%! assert (real (d1), real (d2(1:k)), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "li"); -%! [~, idx] = sort (imag (abs (d0))); -%! d2 = d0(idx); -%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "si"); -%! [~, idx] = sort (imag (abs (d0))); -%! d2 = d0(idx); -%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, 4.1); -%! [~, idx0] = sort (abs (d0 - 4.1)); -%! [~, idx1] = sort (abs (d1 - 4.1)); -%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11); -%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, eye (n), k, "lm"); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! opts.cholB = true; -%! d1 = eigs (A, eye (n), k, "lm", opts); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! opts.cholB = true; -%! q = [2:n,1]; -%! opts.permB = q; -%! d1 = eigs (A, eye (n)(q,q), k, "lm", opts); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! opts.cholB = true; -%! d1 = eigs (A, eye (n), k, 4.1, opts); -%! assert (abs (d1), eigs (A, k, 4.1), 1e-11); -%!testif HAVE_ARPACK -%! opts.cholB = true; -%! q = [2:n,1]; -%! opts.permB = q; -%! d1 = eigs (A, eye (n)(q,q), k, 4.1, opts); -%! assert (abs (d1), eigs (A, k, 4.1), 1e-11); -%!testif HAVE_ARPACK -%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, eye (n), k, 4.1)), 1e-11); -%!testif HAVE_ARPACK -%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, eye (n), k, 4.1))), 1e-11); -%!testif HAVE_ARPACK -%! fn = @(x) A * x; -%! opts.issym = 0; opts.isreal = 1; -%! d1 = eigs (fn, n, k, "lm", opts); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! fn = @(x) A \ x; -%! opts.issym = 0; opts.isreal = 1; -%! d1 = eigs (fn, n, k, "sm", opts); -%! assert (abs (d1), d0(1:k), 1e-11); -%!testif HAVE_ARPACK -%! fn = @(x) (A - 4.1 * eye (n)) \ x; -%! opts.issym = 0; opts.isreal = 1; -%! d1 = eigs (fn, n, k, 4.1, opts); -%! assert (abs (d1), eigs (A, k, 4.1), 1e-11); -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "lm"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "sm"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "lr"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "sr"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "li"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "si"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11); -%! endfor -*/ - -/* -## Complex hermitian tests -%!shared n, k, A, d0 -%! n = 20; -%! k = 4; -%! A = full (sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[1i*ones(1,n-2),4*ones(1,n),-1i*ones(1,n-2)])); -%! d0 = eig (A); -%! [~, idx] = sort (abs (d0)); -%! d0 = d0(idx); -%! rand ("state", 42); % initialize generator to make eigs behavior reproducible -%!testif HAVE_ARPACK -%! d1 = eigs (A, k); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k+1); -%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "lm"); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "sm"); -%! assert (abs (d1), abs (d0(1:k)), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "lr"); -%! [~, idx] = sort (real (abs (d0))); -%! d2 = d0(idx); -%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "sr"); -%! [~, idx] = sort (real (abs (d0))); -%! d2 = d0(idx); -%! assert (real (d1), real (d2(1:k)), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "li"); -%! [~, idx] = sort (imag (abs (d0))); -%! d2 = d0(idx); -%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, "si"); -%! [~, idx] = sort (imag (abs (d0))); -%! d2 = d0(idx); -%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, k, 4.1); -%! [~, idx0] = sort (abs (d0 - 4.1)); -%! [~, idx1] = sort (abs (d1 - 4.1)); -%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11); -%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11); -%!testif HAVE_ARPACK -%! d1 = eigs (A, eye (n), k, "lm"); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! opts.cholB = true; -%! d1 = eigs (A, eye (n), k, "lm", opts); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! opts.cholB = true; -%! q = [2:n,1]; -%! opts.permB = q; -%! d1 = eigs (A, eye (n)(q,q), k, "lm", opts); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! opts.cholB = true; -%! d1 = eigs (A, eye (n), k, 4.1, opts); -%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11); -%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11); -%!testif HAVE_ARPACK -%! opts.cholB = true; -%! q = [2:n,1]; -%! opts.permB = q; -%! d1 = eigs (A, eye (n)(q,q), k, 4.1, opts); -%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11); -%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11); -%!testif HAVE_ARPACK -%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, eye (n), k, 4.1)), 1e-11); -%!testif HAVE_ARPACK -%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, eye (n), k, 4.1))), 1e-11); -%!testif HAVE_ARPACK -%! fn = @(x) A * x; -%! opts.issym = 0; opts.isreal = 0; -%! d1 = eigs (fn, n, k, "lm", opts); -%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11); -%!testif HAVE_ARPACK -%! fn = @(x) A \ x; -%! opts.issym = 0; opts.isreal = 0; -%! d1 = eigs (fn, n, k, "sm", opts); -%! assert (abs (d1), d0(1:k), 1e-11); -%!testif HAVE_ARPACK -%! fn = @(x) (A - 4.1 * eye (n)) \ x; -%! opts.issym = 0; opts.isreal = 0; -%! d1 = eigs (fn, n, k, 4.1, opts); -%! assert (abs (d1), eigs (A, k, 4.1), 1e-11); -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "lm"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "sm"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "lr"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "sr"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "li"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11); -%! endfor -%!testif HAVE_ARPACK -%! [v1,d1] = eigs (A, k, "si"); -%! d1 = diag (d1); -%! for i=1:k -%! assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11); -%! endfor -*/ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/dldfcn/fftw.cc --- a/libinterp/dldfcn/fftw.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/dldfcn/fftw.cc Sat Oct 05 11:22:09 2013 -0400 @@ -70,31 +70,32 @@ wisdom can be treated:\n\ \n\ @table @asis\n\ -@item \"estimate\"\n\ +@item @qcode{\"estimate\"}\n\ Specifies that no run-time measurement of the optimal means of\n\ calculating a particular is performed, and a simple heuristic is used\n\ to pick a (probably sub-optimal) plan. The advantage of this method is\n\ that there is little or no overhead in the generation of the plan, which\n\ is appropriate for a Fourier transform that will be calculated once.\n\ \n\ -@item \"measure\"\n\ +@item @qcode{\"measure\"}\n\ In this case a range of algorithms to perform the transform is considered\n\ and the best is selected based on their execution time.\n\ \n\ -@item \"patient\"\n\ -Similar to \"measure\", but a wider range of algorithms is considered.\n\ +@item @qcode{\"patient\"}\n\ +Similar to @qcode{\"measure\"}, but a wider range of algorithms is\n\ +considered.\n\ \n\ -@item \"exhaustive\"\n\ -Like \"measure\", but all possible algorithms that may be used to\n\ +@item @qcode{\"exhaustive\"}\n\ +Like @qcode{\"measure\"}, but all possible algorithms that may be used to\n\ treat the transform are considered.\n\ \n\ -@item \"hybrid\"\n\ +@item @qcode{\"hybrid\"}\n\ As run-time measurement of the algorithm can be expensive, this is a\n\ -compromise where \"measure\" is used for transforms up to the size of 8192\n\ -and beyond that the \"estimate\" method is used.\n\ +compromise where @qcode{\"measure\"} is used for transforms up to the size\n\ +of 8192 and beyond that the @qcode{\"estimate\"} method is used.\n\ @end table\n\ \n\ -The default method is \"estimate\". The current method can\n\ +The default method is @qcode{\"estimate\"}. The current method can\n\ be queried with\n\ \n\ @example\n\ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/dldfcn/module-files --- a/libinterp/dldfcn/module-files Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/dldfcn/module-files Sat Oct 05 11:22:09 2013 -0400 @@ -1,9 +1,10 @@ # FILE|CPPFLAGS|LDFLAGS|LIBRARIES __delaunayn__.cc|$(QHULL_CPPFLAGS)|$(QHULL_LDFLAGS)|$(QHULL_LIBS) __dsearchn__.cc +__eigs__.cc|$(ARPACK_CPPFLAGS) $(SPARSE_XCPPFLAGS)|$(ARPACK_LDFLAGS) $(SPARSE_XLDFLAGS)|$(ARPACK_LIBS) $(SPARSE_XLIBS) $(LAPACK_LIBS) $(BLAS_LIBS) __fltk_uigetfile__.cc|$(GRAPHICS_CFLAGS) $(FT2_CPPFLAGS)|$(GRAPHICS_LDFLAGS) $(FT2_LDFLAGS)|$(GRAPHICS_LIBS) $(FT2_LIBS) __glpk__.cc|$(GLPK_CPPFLAGS)|$(GLPK_LDFLAGS)|$(GLPK_LIBS) -__init_fltk__.cc|$(GRAPHICS_CFLAGS) $(FT2_CPPFLAGS)|$(GRAPHICS_LDFLAGS) $(FT2_LDFLAGS)|$(GRAPHICS_LIBS) $(FT2_LIBS) +__init_fltk__.cc|$(GRAPHICS_CFLAGS) $(FT2_CPPFLAGS)|$(GRAPHICS_LDFLAGS) $(FT2_LDFLAGS)|$(GRAPHICS_LIBS) $(FT2_LIBS) $(OPENGL_LIBS) __init_gnuplot__.cc __magick_read__.cc|$(MAGICK_CPPFLAGS)|$(MAGICK_LDFLAGS)|$(MAGICK_LIBS) __voronoi__.cc|$(QHULL_CPPFLAGS)|$(QHULL_LDFLAGS)|$(QHULL_LIBS) @@ -13,10 +14,8 @@ colamd.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS) convhulln.cc|$(QHULL_CPPFLAGS)|$(QHULL_LDFLAGS)|$(QHULL_LIBS) dmperm.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS) -eigs.cc|$(ARPACK_CPPFLAGS) $(SPARSE_XCPPFLAGS)|$(ARPACK_LDFLAGS) $(SPARSE_XLDFLAGS)|$(ARPACK_LIBS) $(SPARSE_XLIBS) $(LAPACK_LIBS) $(BLAS_LIBS) fftw.cc|$(FFTW_XCPPFLAGS)|$(FFTW_XLDFLAGS)|$(FFTW_XLIBS) qr.cc|$(QRUPDATE_CPPFLAGS) $(SPARSE_XCPPFLAGS)|$(QRUPDATE_LDFLAGS) $(SPARSE_XLDFLAGS)|$(QRUPDATE_LIBS) $(SPARSE_XLIBS) symbfact.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS) symrcm.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS) tsearch.cc -urlwrite.cc|$(CURL_CPPFLAGS)|$(CURL_LDFLAGS)|$(CURL_LIBS) diff -r 20d1b911b4e7 -r c702371ff6df libinterp/dldfcn/qr.cc --- a/libinterp/dldfcn/qr.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/dldfcn/qr.cc Sat Oct 05 11:22:09 2013 -0400 @@ -133,7 +133,7 @@ @var{R} is upper triangular.\n\ @end ifnottex\n\ \n\ -If given a second argument of '0', @code{qr} returns an economy-sized\n\ +If given a second argument of @qcode{'0'}, @code{qr} returns an economy-sized\n\ QR@tie{}factorization, omitting zero rows of @var{R} and the corresponding\n\ columns of @var{Q}.\n\ \n\ @@ -194,6 +194,7 @@ x = @var{R} \\ @var{C}\n\ @end group\n\ @end example\n\ +@seealso{chol, hess, lu, qz, schur, svd, qrupdate, qrinsert, qrdelete, qrshift}\n\ @end deftypefn") { octave_value_list retval; @@ -769,7 +770,7 @@ The QR@tie{}factorization supplied may be either full\n\ (Q is square) or economized (R is square).\n\ \n\ -@seealso{qr, qrinsert, qrdelete}\n\ +@seealso{qr, qrinsert, qrdelete, qrshift}\n\ @end deftypefn") { octave_idx_type nargin = args.length (); @@ -941,13 +942,13 @@ @w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and\n\ @var{R}@tie{}upper trapezoidal, return the QR@tie{}factorization of\n\ @w{[A(:,1:j-1) x A(:,j:n)]}, where @var{u} is a column vector to be\n\ -inserted into @var{A} (if @var{orient} is @code{\"col\"}), or the\n\ +inserted into @var{A} (if @var{orient} is @qcode{\"col\"}), or the\n\ QR@tie{}factorization of @w{[A(1:j-1,:);x;A(:,j:n)]}, where @var{x}\n\ is a row vector to be inserted into @var{A} (if @var{orient} is\n\ -@code{\"row\"}).\n\ +@qcode{\"row\"}).\n\ \n\ -The default value of @var{orient} is @code{\"col\"}.\n\ -If @var{orient} is @code{\"col\"},\n\ +The default value of @var{orient} is @qcode{\"col\"}.\n\ +If @var{orient} is @qcode{\"col\"},\n\ @var{u} may be a matrix and @var{j} an index vector\n\ resulting in the QR@tie{}factorization of a matrix @var{B} such that\n\ @w{B(:,@var{j})} gives @var{u} and @w{B(:,@var{j}) = []} gives @var{A}.\n\ @@ -955,12 +956,12 @@ thus, for k large enough, it will be both faster and more accurate to\n\ recompute the factorization from scratch.\n\ \n\ -If @var{orient} is @code{\"col\"},\n\ +If @var{orient} is @qcode{\"col\"},\n\ the QR@tie{}factorization supplied may be either full\n\ (Q is square) or economized (R is square).\n\ \n\ -If @var{orient} is @code{\"row\"}, full factorization is needed.\n\ -@seealso{qr, qrupdate, qrdelete}\n\ +If @var{orient} is @qcode{\"row\"}, full factorization is needed.\n\ +@seealso{qr, qrupdate, qrdelete, qrshift}\n\ @end deftypefn") { octave_idx_type nargin = args.length (); @@ -1160,13 +1161,13 @@ @w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and\n\ @var{R}@tie{}upper trapezoidal, return the QR@tie{}factorization of\n\ @w{[A(:,1:j-1) A(:,j+1:n)]}, i.e., @var{A} with one column deleted\n\ -(if @var{orient} is \"col\"), or the QR@tie{}factorization of\n\ +(if @var{orient} is @qcode{\"col\"}), or the QR@tie{}factorization of\n\ @w{[A(1:j-1,:);A(j+1:n,:)]}, i.e., @var{A} with one row deleted (if\n\ -@var{orient} is \"row\").\n\ +@var{orient} is @qcode{\"row\"}).\n\ \n\ -The default value of @var{orient} is \"col\".\n\ +The default value of @var{orient} is @qcode{\"col\"}.\n\ \n\ -If @var{orient} is @code{\"col\"},\n\ +If @var{orient} is @qcode{\"col\"},\n\ @var{j} may be an index vector\n\ resulting in the QR@tie{}factorization of a matrix @var{B} such that\n\ @w{A(:,@var{j}) = []} gives @var{B}.\n\ @@ -1174,12 +1175,12 @@ thus, for k large enough, it will be both faster and more accurate to\n\ recompute the factorization from scratch.\n\ \n\ -If @var{orient} is @code{\"col\"},\n\ +If @var{orient} is @qcode{\"col\"},\n\ the QR@tie{}factorization supplied may be either full\n\ (Q is square) or economized (R is square).\n\ \n\ -If @var{orient} is @code{\"row\"}, full factorization is needed.\n\ -@seealso{qr, qrinsert, qrupdate}\n\ +If @var{orient} is @qcode{\"row\"}, full factorization is needed.\n\ +@seealso{qr, qrupdate, qrinsert, qrshift}\n\ @end deftypefn") { octave_idx_type nargin = args.length (); @@ -1391,7 +1392,7 @@ %! assert (norm (vec (triu (R) - R), Inf) == 0); %! assert (norm (vec (Q*R - [AA(1:2,:);AA(4:5,:)]), Inf) < norm (AA)*1e1*eps ("single")); %!testif HAVE_QRUPDATE -%! # Same test as above but with more precicision +%! ## Same test as above but with more precicision %! AA = single ([0.091364 0.613038 0.027504 0.999083; %! 0.594638 0.425302 0.562834 0.603537; %! 0.383594 0.291238 0.742073 0.085574; @@ -1429,7 +1430,7 @@ or @*\n\ @code{p = [1:j-1, shift(j:i,-1), i+1:n]} if @w{@var{j} < @var{i}}. @*\n\ \n\ -@seealso{qr, qrinsert, qrdelete}\n\ +@seealso{qr, qrupdate, qrinsert, qrdelete}\n\ @end deftypefn") { octave_idx_type nargin = args.length (); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/dldfcn/symbfact.cc --- a/libinterp/dldfcn/symbfact.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/dldfcn/symbfact.cc Sat Oct 05 11:22:09 2013 -0400 @@ -63,18 +63,18 @@ Factorize @code{@var{S}' * @var{S}}.\n\ \n\ @item row\n\ -Factorize @xcode{@var{S} * @var{S}'}.\n\ +Factorize @tcode{@var{S} * @var{S}'}.\n\ \n\ @item lo\n\ -Factorize @xcode{@var{S}'}\n\ +Factorize @tcode{@var{S}'}\n\ @end table\n\ \n\ @item mode\n\ The default is to return the Cholesky@tie{}factorization for @var{r}, and if\n\ -@var{mode} is 'L', the conjugate transpose of the Cholesky@tie{}factorization\n\ -is returned. The conjugate transpose version is faster and uses less\n\ -memory, but returns the same values for @var{count}, @var{h}, @var{parent}\n\ -and @var{post} outputs.\n\ +@var{mode} is @qcode{'L'}, the conjugate transpose of the\n\ +Cholesky@tie{}factorization is returned. The conjugate transpose version is\n\ +faster and uses less memory, but returns the same values for @var{count},\n\ +@var{h}, @var{parent} and @var{post} outputs.\n\ @end table\n\ \n\ The output variables are\n\ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/dldfcn/urlwrite.cc --- a/libinterp/dldfcn/urlwrite.cc Thu Sep 12 21:08:07 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1742 +0,0 @@ -// urlwrite and urlread, a curl front-end for octave -/* - -Copyright (C) 2006-2012 Alexander Barth -Copyright (C) 2009 David Bateman - -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 -. - -*/ - -// Author: Alexander Barth -// Adapted-By: jwe - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#include "dir-ops.h" -#include "file-ops.h" -#include "file-stat.h" -#include "oct-env.h" -#include "glob-match.h" - -#include "defun-dld.h" -#include "error.h" -#include "oct-obj.h" -#include "ov-cell.h" -#include "pager.h" -#include "oct-map.h" -#include "oct-refcount.h" -#include "unwind-prot.h" - -#ifdef HAVE_CURL - -#include -#include -#include - -static int -write_data (void *buffer, size_t size, size_t nmemb, void *streamp) -{ - std::ostream& stream = *(static_cast (streamp)); - stream.write (static_cast (buffer), size*nmemb); - return (stream.fail () ? 0 : size * nmemb); -} - -static int -read_data (void *buffer, size_t size, size_t nmemb, void *streamp) -{ - std::istream& stream = *(static_cast (streamp)); - stream.read (static_cast (buffer), size*nmemb); - if (stream.eof ()) - return stream.gcount (); - else - return (stream.fail () ? 0 : size * nmemb); -} - -static size_t -throw_away (void *, size_t size, size_t nmemb, void *) -{ - return static_cast(size * nmemb); -} - -class -curl_handle -{ -private: - class - curl_handle_rep - { - public: - curl_handle_rep (void) : count (1), valid (true), ascii (false) - { - curl = curl_easy_init (); - if (!curl) - error ("can not create curl handle"); - } - - ~curl_handle_rep (void) - { - if (curl) - curl_easy_cleanup (curl); - } - - bool is_valid (void) const - { - return valid; - } - - bool perform (bool curlerror) const - { - bool retval = false; - if (!error_state) - { - BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - - errnum = curl_easy_perform (curl); - if (errnum != CURLE_OK) - { - if (curlerror) - error ("%s", curl_easy_strerror (errnum)); - } - else - retval = true; - - END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - } - return retval; - } - - CURL* handle (void) const - { - return curl; - } - - bool is_ascii (void) const - { - return ascii; - } - - bool is_binary (void) const - { - return !ascii; - } - - octave_refcount count; - std::string host; - std::string url; - std::string userpwd; - bool valid; - bool ascii; - mutable CURLcode errnum; - - private: - CURL *curl; - - // No copying! - - curl_handle_rep (const curl_handle_rep& ov); - - curl_handle_rep& operator = (const curl_handle_rep&); - }; - -public: - -// I'd love to rewrite this as a private method of the curl_handle -// class, but you can't pass the va_list from the wrapper setopt to -// the curl_easy_setopt function. -#define setopt(option, parameter) \ - { \ - CURLcode res = curl_easy_setopt (rep->handle (), option, parameter); \ - if (res != CURLE_OK) \ - error ("%s", curl_easy_strerror (res)); \ - } - - curl_handle (void) : rep (new curl_handle_rep ()) - { - rep->valid = false; - } - - curl_handle (const std::string& _host, const std::string& user, - const std::string& passwd) : - rep (new curl_handle_rep ()) - { - rep->host = _host; - init (user, passwd, std::cin, octave_stdout); - - rep->url = "ftp://" + _host; - setopt (CURLOPT_URL, rep->url.c_str ()); - - // Setup the link, with no transfer - if (!error_state) - perform (); - } - - curl_handle (const std::string& url, const std::string& method, - const Cell& param, std::ostream& os, bool& retval) : - rep (new curl_handle_rep ()) - { - retval = false; - - init ("", "", std::cin, os); - - setopt (CURLOPT_NOBODY, 0); - - // Restore the default HTTP request method to GET after setting - // NOBODY to true and back to false. This is needed for backward - // compatibility with versions of libcurl < 7.18.2. - setopt (CURLOPT_HTTPGET, 1); - - // Don't need to store the parameters here as we can't change - // the URL after the handle is created - std::string query_string = form_query_string (param); - - if (method == "get") - { - query_string = url + "?" + query_string; - setopt (CURLOPT_URL, query_string.c_str ()); - } - else if (method == "post") - { - setopt (CURLOPT_URL, url.c_str ()); - setopt (CURLOPT_POSTFIELDS, query_string.c_str ()); - } - else - setopt (CURLOPT_URL, url.c_str ()); - - if (!error_state) - retval = perform (false); - } - - curl_handle (const curl_handle& h) : rep (h.rep) - { - rep->count++; - } - - ~curl_handle (void) - { - if (--rep->count == 0) - delete rep; - } - - curl_handle& operator = (const curl_handle& h) - { - if (this != &h) - { - if (--rep->count == 0) - delete rep; - - rep = h.rep; - rep->count++; - } - return *this; - } - - bool is_valid (void) const - { - return rep->is_valid (); - } - - std::string lasterror (void) const - { - return std::string (curl_easy_strerror (rep->errnum)); - } - - void set_ostream (std::ostream& os) const - { - setopt (CURLOPT_WRITEDATA, static_cast (&os)); - } - - void set_istream (std::istream& is) const - { - setopt (CURLOPT_READDATA, static_cast (&is)); - } - - void ascii (void) const - { - setopt (CURLOPT_TRANSFERTEXT, 1); - rep->ascii = true; - } - - void binary (void) const - { - setopt (CURLOPT_TRANSFERTEXT, 0); - rep->ascii = false; - } - - bool is_ascii (void) const - { - return rep->is_ascii (); - } - - bool is_binary (void) const - { - return rep->is_binary (); - } - - void cwd (const std::string& path) const - { - struct curl_slist *slist = 0; - std::string cmd = "cwd " + path; - slist = curl_slist_append (slist, cmd.c_str ()); - setopt (CURLOPT_POSTQUOTE, slist); - if (! error_state) - perform (); - setopt (CURLOPT_POSTQUOTE, 0); - curl_slist_free_all (slist); - } - - void del (const std::string& file) const - { - struct curl_slist *slist = 0; - std::string cmd = "dele " + file; - slist = curl_slist_append (slist, cmd.c_str ()); - setopt (CURLOPT_POSTQUOTE, slist); - if (! error_state) - perform (); - setopt (CURLOPT_POSTQUOTE, 0); - curl_slist_free_all (slist); - } - - void rmdir (const std::string& path) const - { - struct curl_slist *slist = 0; - std::string cmd = "rmd " + path; - slist = curl_slist_append (slist, cmd.c_str ()); - setopt (CURLOPT_POSTQUOTE, slist); - if (! error_state) - perform (); - setopt (CURLOPT_POSTQUOTE, 0); - curl_slist_free_all (slist); - } - - bool mkdir (const std::string& path, bool curlerror = true) const - { - bool retval = false; - struct curl_slist *slist = 0; - std::string cmd = "mkd " + path; - slist = curl_slist_append (slist, cmd.c_str ()); - setopt (CURLOPT_POSTQUOTE, slist); - if (! error_state) - retval = perform (curlerror); - setopt (CURLOPT_POSTQUOTE, 0); - curl_slist_free_all (slist); - return retval; - } - - void rename (const std::string& oldname, const std::string& newname) const - { - struct curl_slist *slist = 0; - std::string cmd = "rnfr " + oldname; - slist = curl_slist_append (slist, cmd.c_str ()); - cmd = "rnto " + newname; - slist = curl_slist_append (slist, cmd.c_str ()); - setopt (CURLOPT_POSTQUOTE, slist); - if (! error_state) - perform (); - setopt (CURLOPT_POSTQUOTE, 0); - curl_slist_free_all (slist); - } - - void put (const std::string& file, std::istream& is) const - { - rep->url = "ftp://" + rep->host + "/" + file; - setopt (CURLOPT_URL, rep->url.c_str ()); - setopt (CURLOPT_UPLOAD, 1); - setopt (CURLOPT_NOBODY, 0); - set_istream (is); - if (! error_state) - perform (); - set_istream (std::cin); - setopt (CURLOPT_NOBODY, 1); - setopt (CURLOPT_UPLOAD, 0); - rep->url = "ftp://" + rep->host; - setopt (CURLOPT_URL, rep->url.c_str ()); - } - - void get (const std::string& file, std::ostream& os) const - { - rep->url = "ftp://" + rep->host + "/" + file; - setopt (CURLOPT_URL, rep->url.c_str ()); - setopt (CURLOPT_NOBODY, 0); - set_ostream (os); - if (! error_state) - perform (); - set_ostream (octave_stdout); - setopt (CURLOPT_NOBODY, 1); - rep->url = "ftp://" + rep->host; - setopt (CURLOPT_URL, rep->url.c_str ()); - } - - void dir (void) const - { - rep->url = "ftp://" + rep->host + "/"; - setopt (CURLOPT_URL, rep->url.c_str ()); - setopt (CURLOPT_NOBODY, 0); - if (! error_state) - perform (); - setopt (CURLOPT_NOBODY, 1); - rep->url = "ftp://" + rep->host; - setopt (CURLOPT_URL, rep->url.c_str ()); - } - - string_vector list (void) const - { - std::ostringstream buf; - rep->url = "ftp://" + rep->host + "/"; - setopt (CURLOPT_WRITEDATA, static_cast (&buf)); - setopt (CURLOPT_URL, rep->url.c_str ()); - setopt (CURLOPT_DIRLISTONLY, 1); - setopt (CURLOPT_NOBODY, 0); - if (! error_state) - perform (); - setopt (CURLOPT_NOBODY, 1); - rep->url = "ftp://" + rep->host; - setopt (CURLOPT_WRITEDATA, static_cast (&octave_stdout)); - setopt (CURLOPT_DIRLISTONLY, 0); - setopt (CURLOPT_URL, rep->url.c_str ()); - - // Count number of directory entries - std::string str = buf.str (); - octave_idx_type n = 0; - size_t pos = 0; - while (true) - { - pos = str.find_first_of ('\n', pos); - if (pos == std::string::npos) - break; - pos++; - n++; - } - string_vector retval (n); - pos = 0; - for (octave_idx_type i = 0; i < n; i++) - { - size_t newpos = str.find_first_of ('\n', pos); - if (newpos == std::string::npos) - break; - - retval(i) = str.substr(pos, newpos - pos); - pos = newpos + 1; - } - return retval; - } - - void get_fileinfo (const std::string& filename, double& filesize, - time_t& filetime, bool& fileisdir) const - { - std::string path = pwd (); - - rep->url = "ftp://" + rep->host + "/" + path + "/" + filename; - setopt (CURLOPT_URL, rep->url.c_str ()); - setopt (CURLOPT_FILETIME, 1); - setopt (CURLOPT_HEADERFUNCTION, throw_away); - setopt (CURLOPT_WRITEFUNCTION, throw_away); - - // FIXME - // The MDTM command fails for a directory on the servers I tested - // so this is a means of testing for directories. It also means - // I can't get the date of directories! - if (! error_state) - { - if (! perform (false)) - { - fileisdir = true; - filetime = -1; - filesize = 0; - } - else - { - fileisdir = false; - time_t ft; - curl_easy_getinfo (rep->handle (), CURLINFO_FILETIME, &ft); - filetime = ft; - double fs; - curl_easy_getinfo (rep->handle (), - CURLINFO_CONTENT_LENGTH_DOWNLOAD, &fs); - filesize = fs; - } - } - - setopt (CURLOPT_WRITEFUNCTION, write_data); - setopt (CURLOPT_HEADERFUNCTION, 0); - setopt (CURLOPT_FILETIME, 0); - rep->url = "ftp://" + rep->host; - setopt (CURLOPT_URL, rep->url.c_str ()); - - // The MDTM command seems to reset the path to the root with the - // servers I tested with, so cd again into the correct path. Make - // the path absolute so that this will work even with servers that - // don't end up in the root after an MDTM command. - cwd ("/" + path); - } - - std::string pwd (void) const - { - struct curl_slist *slist = 0; - std::string retval; - std::ostringstream buf; - - slist = curl_slist_append (slist, "pwd"); - setopt (CURLOPT_POSTQUOTE, slist); - setopt (CURLOPT_HEADERFUNCTION, write_data); - setopt (CURLOPT_WRITEHEADER, static_cast(&buf)); - - if (! error_state) - { - perform (); - retval = buf.str (); - - // Can I assume that the path is alway in "" on the last line - size_t pos2 = retval.rfind ('"'); - size_t pos1 = retval.rfind ('"', pos2 - 1); - retval = retval.substr (pos1 + 1, pos2 - pos1 - 1); - } - setopt (CURLOPT_HEADERFUNCTION, 0); - setopt (CURLOPT_WRITEHEADER, 0); - setopt (CURLOPT_POSTQUOTE, 0); - curl_slist_free_all (slist); - - return retval; - } - - bool perform (bool curlerror = true) const - { - return rep->perform (curlerror); - } - -private: - curl_handle_rep *rep; - - std::string form_query_string (const Cell& param) - { - std::ostringstream query; - - for (int i = 0; i < param.numel (); i += 2) - { - std::string name = param(i).string_value (); - std::string text = param(i+1).string_value (); - - // Encode strings. - char *enc_name = curl_easy_escape (rep->handle (), name.c_str (), - name.length ()); - char *enc_text = curl_easy_escape (rep->handle (), text.c_str (), - text.length ()); - - query << enc_name << "=" << enc_text; - - curl_free (enc_name); - curl_free (enc_text); - - if (i < param.numel ()-1) - query << "&"; - } - - query.flush (); - - return query.str (); - } - - void init (const std::string& user, const std::string& passwd, - std::istream& is, std::ostream& os) - { - // No data transfer by default - setopt (CURLOPT_NOBODY, 1); - - // Set the username and password - rep->userpwd = user; - if (! passwd.empty ()) - rep->userpwd += ":" + passwd; - if (! rep->userpwd.empty ()) - setopt (CURLOPT_USERPWD, rep->userpwd.c_str ()); - - // Define our callback to get called when there's data to be written. - setopt (CURLOPT_WRITEFUNCTION, write_data); - - // Set a pointer to our struct to pass to the callback. - setopt (CURLOPT_WRITEDATA, static_cast (&os)); - - // Define our callback to get called when there's data to be read - setopt (CURLOPT_READFUNCTION, read_data); - - // Set a pointer to our struct to pass to the callback. - setopt (CURLOPT_READDATA, static_cast (&is)); - - // Follow redirects. - setopt (CURLOPT_FOLLOWLOCATION, true); - - // Don't use EPSV since connecting to sites that don't support it - // will hang for some time (3 minutes?) before moving on to try PASV - // instead. - setopt (CURLOPT_FTP_USE_EPSV, false); - - setopt (CURLOPT_NOPROGRESS, true); - setopt (CURLOPT_FAILONERROR, true); - - setopt (CURLOPT_POSTQUOTE, 0); - setopt (CURLOPT_QUOTE, 0); - } - -#undef setopt -}; - -class -curl_handles -{ -public: - - typedef std::map::iterator iterator; - typedef std::map::const_iterator const_iterator; - - curl_handles (void) : map () - { - curl_global_init (CURL_GLOBAL_DEFAULT); - } - - ~curl_handles (void) - { - // Remove the elements of the map explicitly as they should - // be deleted before the call to curl_global_cleanup - map.erase (begin (), end ()); - - curl_global_cleanup (); - } - - iterator begin (void) { return iterator (map.begin ()); } - const_iterator begin (void) const { return const_iterator (map.begin ()); } - - iterator end (void) { return iterator (map.end ()); } - const_iterator end (void) const { return const_iterator (map.end ()); } - - iterator seek (const std::string& k) { return map.find (k); } - const_iterator seek (const std::string& k) const { return map.find (k); } - - std::string key (const_iterator p) const { return p->first; } - - curl_handle& contents (const std::string& k) - { - return map[k]; - } - - curl_handle contents (const std::string& k) const - { - const_iterator p = seek (k); - return p != end () ? p->second : curl_handle (); - } - - curl_handle& contents (iterator p) - { return p->second; } - - curl_handle contents (const_iterator p) const - { return p->second; } - - void del (const std::string& k) - { - iterator p = map.find (k); - - if (p != map.end ()) - map.erase (p); - } - -private: - std::map map; -}; - -static curl_handles handles; - -static void -cleanup_urlwrite (std::string filename) -{ - octave_unlink (filename); -} - -static void -reset_path (const curl_handle curl) -{ - curl.cwd (".."); -} - -static void -delete_file (std::string file) -{ - octave_unlink (file); -} -#endif - -DEFUN_DLD (urlwrite, args, nargout, - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} urlwrite (@var{url}, @var{localfile})\n\ -@deftypefnx {Loadable Function} {@var{f} =} urlwrite (@var{url}, @var{localfile})\n\ -@deftypefnx {Loadable Function} {[@var{f}, @var{success}] =} urlwrite (@var{url}, @var{localfile})\n\ -@deftypefnx {Loadable Function} {[@var{f}, @var{success}, @var{message}] =} urlwrite (@var{url}, @var{localfile})\n\ -Download a remote file specified by its @var{url} and save it as\n\ -@var{localfile}. For example:\n\ -\n\ -@example\n\ -@group\n\ -urlwrite (\"ftp://ftp.octave.org/pub/octave/README\",\n\ - \"README.txt\");\n\ -@end group\n\ -@end example\n\ -\n\ -The full path of the downloaded file is returned in @var{f}. The\n\ -variable @var{success} is 1 if the download was successful,\n\ -otherwise it is 0 in which case @var{message} contains an error\n\ -message. If no output argument is specified and an error occurs,\n\ -then the error is signaled through Octave's error handling mechanism.\n\ -\n\ -This function uses libcurl. Curl supports, among others, the HTTP,\n\ -FTP and FILE protocols. Username and password may be specified in\n\ -the URL, for example:\n\ -\n\ -@example\n\ -@group\n\ -urlwrite (\"http://username:password@@example.com/file.txt\",\n\ - \"file.txt\");\n\ -@end group\n\ -@end example\n\ -\n\ -GET and POST requests can be specified by @var{method} and @var{param}.\n\ -The parameter @var{method} is either @samp{get} or @samp{post}\n\ -and @var{param} is a cell array of parameter and value pairs.\n\ -For example:\n\ -\n\ -@example\n\ -@group\n\ -urlwrite (\"http://www.google.com/search\", \"search.html\",\n\ - \"get\", @{\"query\", \"octave\"@});\n\ -@end group\n\ -@end example\n\ -@seealso{urlread}\n\ -@end deftypefn") -{ - octave_value_list retval; - -#ifdef HAVE_CURL - - int nargin = args.length (); - - // verify arguments - if (nargin != 2 && nargin != 4) - { - print_usage (); - return retval; - } - - std::string url = args(0).string_value (); - - if (error_state) - { - error ("urlwrite: URL must be a character string"); - return retval; - } - - // name to store the file if download is succesful - std::string filename = args(1).string_value (); - - if (error_state) - { - error ("urlwrite: LOCALFILE must be a character string"); - return retval; - } - - std::string method; - Cell param; // empty cell array - - if (nargin == 4) - { - method = args(2).string_value (); - - if (error_state) - { - error ("urlwrite: METHOD must be \"get\" or \"post\""); - return retval; - } - - if (method != "get" && method != "post") - { - error ("urlwrite: METHOD must be \"get\" or \"post\""); - return retval; - } - - param = args(3).cell_value (); - - if (error_state) - { - error ("urlwrite: parameters (PARAM) for get and post requests must be given as a cell"); - return retval; - } - - - if (param.numel () % 2 == 1 ) - { - error ("urlwrite: number of elements in PARAM must be even"); - return retval; - } - } - - // The file should only be deleted if it doesn't initially exist, we - // create it, and the download fails. We use unwind_protect to do - // it so that the deletion happens no matter how we exit the function. - - file_stat fs (filename); - - std::ofstream ofile (filename.c_str (), std::ios::out | std::ios::binary); - - if (! ofile.is_open ()) - { - error ("urlwrite: unable to open file"); - return retval; - } - - unwind_protect_safe frame; - - frame.add_fcn (cleanup_urlwrite, filename); - - bool ok; - curl_handle curl = curl_handle (url, method, param, ofile, ok); - - ofile.close (); - - if (!error_state) - frame.discard (); - else - frame.run (); - - if (nargout > 0) - { - if (ok) - { - retval(2) = std::string (); - retval(1) = true; - retval(0) = octave_env::make_absolute (filename); - } - else - { - retval(2) = curl.lasterror (); - retval(1) = false; - retval(0) = std::string (); - } - } - - if (nargout < 2 && ! ok) - error ("urlwrite: curl: %s", curl.lasterror ().c_str ()); - -#else - error ("urlwrite: not available in this version of Octave"); -#endif - - return retval; -} - -DEFUN_DLD (urlread, args, nargout, - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {@var{s} =} urlread (@var{url})\n\ -@deftypefnx {Loadable Function} {[@var{s}, @var{success}] =} urlread (@var{url})\n\ -@deftypefnx {Loadable Function} {[@var{s}, @var{success}, @var{message}] =} urlread (@var{url})\n\ -@deftypefnx {Loadable Function} {[@dots{}] =} urlread (@var{url}, @var{method}, @var{param})\n\ -Download a remote file specified by its @var{url} and return its content\n\ -in string @var{s}. For example:\n\ -\n\ -@example\n\ -s = urlread (\"ftp://ftp.octave.org/pub/octave/README\");\n\ -@end example\n\ -\n\ -The variable @var{success} is 1 if the download was successful,\n\ -otherwise it is 0 in which case @var{message} contains an error\n\ -message. If no output argument is specified and an error occurs,\n\ -then the error is signaled through Octave's error handling mechanism.\n\ -\n\ -This function uses libcurl. Curl supports, among others, the HTTP,\n\ -FTP and FILE protocols. Username and password may be specified in the\n\ -URL@. For example:\n\ -\n\ -@example\n\ -s = urlread (\"http://user:password@@example.com/file.txt\");\n\ -@end example\n\ -\n\ -GET and POST requests can be specified by @var{method} and @var{param}.\n\ -The parameter @var{method} is either @samp{get} or @samp{post}\n\ -and @var{param} is a cell array of parameter and value pairs.\n\ -For example:\n\ -\n\ -@example\n\ -@group\n\ -s = urlread (\"http://www.google.com/search\", \"get\",\n\ - @{\"query\", \"octave\"@});\n\ -@end group\n\ -@end example\n\ -@seealso{urlwrite}\n\ -@end deftypefn") -{ - // Octave's return value - octave_value_list retval; - -#ifdef HAVE_CURL - - int nargin = args.length (); - - // verify arguments - if (nargin != 1 && nargin != 3) - { - print_usage (); - return retval; - } - - std::string url = args(0).string_value (); - - if (error_state) - { - error ("urlread: URL must be a character string"); - return retval; - } - - std::string method; - Cell param; // empty cell array - - if (nargin == 3) - { - method = args(1).string_value (); - - if (error_state) - { - error ("urlread: METHOD must be \"get\" or \"post\""); - return retval; - } - - if (method != "get" && method != "post") - { - error ("urlread: METHOD must be \"get\" or \"post\""); - return retval; - } - - param = args(2).cell_value (); - - if (error_state) - { - error ("urlread: parameters (PARAM) for get and post requests must be given as a cell"); - return retval; - } - - if (param.numel () % 2 == 1 ) - { - error ("urlread: number of elements in PARAM must be even"); - return retval; - } - } - - std::ostringstream buf; - - bool ok; - curl_handle curl = curl_handle (url, method, param, buf, ok); - - if (nargout > 0) - { - // Return empty string if no error occured. - retval(2) = ok ? "" : curl.lasterror (); - retval(1) = ok; - retval(0) = buf.str (); - } - - if (nargout < 2 && ! ok) - error ("urlread: curl: %s", curl.lasterror().c_str()); - -#else - error ("urlread: not available in this version of Octave"); -#endif - - return retval; -} - -DEFUN_DLD (__ftp__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __ftp__ (@var{handle}, @var{host})\n\ -@deftypefnx {Loadable Function} {} __ftp__ (@var{handle}, @var{host}, @var{username}, @var{password})\n\ -Undocumented internal function\n\ -@end deftypefn") -{ -#ifdef HAVE_CURL - int nargin = args.length (); - std::string handle; - std::string host; - std::string user = "anonymous"; - std::string passwd = ""; - - if (nargin < 2 || nargin > 4) - error ("incorrect number of arguments"); - else - { - handle = args(0).string_value (); - host = args(1).string_value (); - - if (nargin > 1) - user = args(2).string_value (); - - if (nargin > 2) - passwd = args(3).string_value (); - - if (!error_state) - { - handles.contents (handle) = curl_handle (host, user, passwd); - - if (error_state) - handles.del (handle); - } - } -#else - error ("__ftp__: not available in this version of Octave"); -#endif - - return octave_value (); -} - -DEFUN_DLD (__ftp_pwd__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __ftp_pwd__ (@var{handle})\n\ -Undocumented internal function\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_CURL - int nargin = args.length (); - - if (nargin != 1) - error ("__ftp_pwd__: incorrect number of arguments"); - else - { - std::string handle = args(0).string_value (); - - if (!error_state) - { - const curl_handle curl = handles.contents (handle); - - if (curl.is_valid ()) - retval = curl.pwd (); - else - error ("__ftp_pwd__: invalid ftp handle"); - } - } -#else - error ("__ftp_pwd__: not available in this version of Octave"); -#endif - - return retval; -} - -DEFUN_DLD (__ftp_cwd__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __ftp_cwd__ (@var{handle}, @var{path})\n\ -Undocumented internal function\n\ -@end deftypefn") -{ -#ifdef HAVE_CURL - int nargin = args.length (); - - if (nargin != 1 && nargin != 2) - error ("__ftp_cwd__: incorrect number of arguments"); - else - { - std::string handle = args(0).string_value (); - std::string path = ""; - - if (nargin > 1) - path = args(1).string_value (); - - if (!error_state) - { - const curl_handle curl = handles.contents (handle); - - if (curl.is_valid ()) - curl.cwd (path); - else - error ("__ftp_cwd__: invalid ftp handle"); - } - } -#else - error ("__ftp_cwd__: not available in this version of Octave"); -#endif - - return octave_value (); -} - -DEFUN_DLD (__ftp_dir__, args, nargout, - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __ftp_dir__ (@var{handle})\n\ -Undocumented internal function\n\ -@end deftypefn") -{ - octave_value retval; -#ifdef HAVE_CURL - int nargin = args.length (); - - if (nargin != 1) - error ("__ftp_dir__: incorrect number of arguments"); - else - { - std::string handle = args(0).string_value (); - - if (!error_state) - { - const curl_handle curl = handles.contents (handle); - - if (curl.is_valid ()) - { - if (nargout == 0) - curl.dir (); - else - { - string_vector sv = curl.list (); - octave_idx_type n = sv.length (); - if (n == 0) - { - string_vector flds (5); - flds(0) = "name"; - flds(1) = "date"; - flds(2) = "bytes"; - flds(3) = "isdir"; - flds(4) = "datenum"; - retval = octave_map (flds); - } - else - { - octave_map st; - Cell filectime (dim_vector (n, 1)); - Cell filesize (dim_vector (n, 1)); - Cell fileisdir (dim_vector (n, 1)); - Cell filedatenum (dim_vector (n, 1)); - - st.assign ("name", Cell (sv)); - - for (octave_idx_type i = 0; i < n; i++) - { - time_t ftime; - bool fisdir; - double fsize; - - curl.get_fileinfo (sv(i), fsize, ftime, fisdir); - - fileisdir (i) = fisdir; - filectime (i) = ctime (&ftime); - filesize (i) = fsize; - filedatenum (i) = double (ftime); - } - st.assign ("date", filectime); - st.assign ("bytes", filesize); - st.assign ("isdir", fileisdir); - st.assign ("datenum", filedatenum); - retval = st; - } - } - } - else - error ("__ftp_dir__: invalid ftp handle"); - } - } -#else - error ("__ftp_dir__: not available in this version of Octave"); -#endif - - return retval; -} - -DEFUN_DLD (__ftp_ascii__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __ftp_ascii__ (@var{handle})\n\ -Undocumented internal function\n\ -@end deftypefn") -{ -#ifdef HAVE_CURL - int nargin = args.length (); - - if (nargin != 1) - error ("__ftp_ascii__: incorrect number of arguments"); - else - { - std::string handle = args(0).string_value (); - - if (!error_state) - { - const curl_handle curl = handles.contents (handle); - - if (curl.is_valid ()) - curl.ascii (); - else - error ("__ftp_ascii__: invalid ftp handle"); - } - } -#else - error ("__ftp_ascii__: not available in this version of Octave"); -#endif - - return octave_value (); -} - -DEFUN_DLD (__ftp_binary__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __ftp_binary__ (@var{handle})\n\ -Undocumented internal function\n\ -@end deftypefn") -{ -#ifdef HAVE_CURL - int nargin = args.length (); - - if (nargin != 1) - error ("__ftp_binary__: incorrect number of arguments"); - else - { - std::string handle = args(0).string_value (); - - if (!error_state) - { - const curl_handle curl = handles.contents (handle); - - if (curl.is_valid ()) - curl.binary (); - else - error ("__ftp_binary__: invalid ftp handle"); - } - } -#else - error ("__ftp_binary__: not available in this version of Octave"); -#endif - - return octave_value (); -} - -DEFUN_DLD (__ftp_close__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __ftp_close__ (@var{handle})\n\ - Undocumented internal function\n\ - @end deftypefn") - { - #ifdef HAVE_CURL - int nargin = args.length (); - - if (nargin != 1) - error ("__ftp_close__: incorrect number of arguments"); - else - { - std::string handle = args(0).string_value (); - - if (!error_state) - handles.del (handle); - } - #else - error ("__ftp_close__: not available in this version of Octave"); - #endif - - return octave_value (); - } - -DEFUN_DLD (__ftp_mode__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __ftp_mode__ (@var{handle})\n\ - Undocumented internal function\n\ - @end deftypefn") - { - octave_value retval; - #ifdef HAVE_CURL - int nargin = args.length (); - - if (nargin != 1) - error ("__ftp_mode__: incorrect number of arguments"); - else - { - std::string handle = args(0).string_value (); - - - if (!error_state) - { - const curl_handle curl = handles.contents (handle); - - if (curl.is_valid ()) - retval = (curl.is_ascii () ? "ascii" : "binary"); - else - error ("__ftp_binary__: invalid ftp handle"); - } - } - #else - error ("__ftp_mode__: not available in this version of Octave"); - #endif - - return retval; - } - -DEFUN_DLD (__ftp_delete__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __ftp_delete__ (@var{handle}, @var{path})\n\ -Undocumented internal function\n\ -@end deftypefn") -{ -#ifdef HAVE_CURL - int nargin = args.length (); - - if (nargin != 2) - error ("__ftp_delete__: incorrect number of arguments"); - else - { - std::string handle = args(0).string_value (); - std::string file = args(1).string_value (); - - if (!error_state) - { - const curl_handle curl = handles.contents (handle); - - if (curl.is_valid ()) - curl.del (file); - else - error ("__ftp_delete__: invalid ftp handle"); - } - } -#else - error ("__ftp_delete__: not available in this version of Octave"); -#endif - - return octave_value (); -} - -DEFUN_DLD (__ftp_rmdir__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __ftp_rmdir__ (@var{handle}, @var{path})\n\ -Undocumented internal function\n\ -@end deftypefn") -{ -#ifdef HAVE_CURL - int nargin = args.length (); - - if (nargin != 2) - error ("__ftp_rmdir__: incorrect number of arguments"); - else - { - std::string handle = args(0).string_value (); - std::string dir = args(1).string_value (); - - if (!error_state) - { - const curl_handle curl = handles.contents (handle); - - if (curl.is_valid ()) - curl.rmdir (dir); - else - error ("__ftp_rmdir__: invalid ftp handle"); - } - } -#else - error ("__ftp_rmdir__: not available in this version of Octave"); -#endif - - return octave_value (); -} - -DEFUN_DLD (__ftp_mkdir__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __ftp_mkdir__ (@var{handle}, @var{path})\n\ -Undocumented internal function\n\ -@end deftypefn") -{ -#ifdef HAVE_CURL - int nargin = args.length (); - - if (nargin != 2) - error ("__ftp_mkdir__: incorrect number of arguments"); - else - { - std::string handle = args(0).string_value (); - std::string dir = args(1).string_value (); - - if (!error_state) - { - const curl_handle curl = handles.contents (handle); - - if (curl.is_valid ()) - curl.mkdir (dir); - else - error ("__ftp_mkdir__: invalid ftp handle"); - } - } -#else - error ("__ftp_mkdir__: not available in this version of Octave"); -#endif - - return octave_value (); -} - -DEFUN_DLD (__ftp_rename__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __ftp_rename__ (@var{handle}, @var{path})\n\ -Undocumented internal function\n\ -@end deftypefn") -{ -#ifdef HAVE_CURL - int nargin = args.length (); - - if (nargin != 3) - error ("__ftp_rename__: incorrect number of arguments"); - else - { - std::string handle = args(0).string_value (); - std::string oldname = args(1).string_value (); - std::string newname = args(2).string_value (); - - if (!error_state) - { - const curl_handle curl = handles.contents (handle); - - if (curl.is_valid ()) - curl.rename (oldname, newname); - else - error ("__ftp_rename__: invalid ftp handle"); - } - } -#else - error ("__ftp_rename__: not available in this version of Octave"); -#endif - - return octave_value (); -} - -#ifdef HAVE_CURL -static string_vector -mput_directory (const curl_handle& curl, const std::string& base, - const std::string& dir) -{ - string_vector retval; - - if (! curl.mkdir (dir, false)) - warning ("__ftp_mput__: can not create the remote directory ""%s""", - (base.length () == 0 ? dir : base + - file_ops::dir_sep_str () + dir).c_str ()); - - curl.cwd (dir); - - if (! error_state) - { - unwind_protect_safe frame; - - frame.add_fcn (reset_path, curl); - - std::string realdir = base.length () == 0 ? dir : base + - file_ops::dir_sep_str () + dir; - - dir_entry dirlist (realdir); - - if (dirlist) - { - string_vector files = dirlist.read (); - - for (octave_idx_type i = 0; i < files.length (); i++) - { - std::string file = files (i); - - if (file == "." || file == "..") - continue; - - std::string realfile = realdir + file_ops::dir_sep_str () + file; - file_stat fs (realfile); - - if (! fs.exists ()) - { - error ("__ftp__mput: file ""%s"" does not exist", - realfile.c_str ()); - break; - } - - if (fs.is_dir ()) - { - retval.append (mput_directory (curl, realdir, file)); - - if (error_state) - break; - } - else - { - // FIXME Does ascii mode need to be flagged here? - std::ifstream ifile (realfile.c_str (), std::ios::in | - std::ios::binary); - - if (! ifile.is_open ()) - { - error ("__ftp_mput__: unable to open file ""%s""", - realfile.c_str ()); - break; - } - - curl.put (file, ifile); - - ifile.close (); - - if (error_state) - break; - - retval.append (realfile); - } - } - } - else - error ("__ftp_mput__: can not read the directory ""%s""", - realdir.c_str ()); - } - - return retval; -} -#endif - -DEFUN_DLD (__ftp_mput__, args, nargout, - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __ftp_mput__ (@var{handle}, @var{files})\n\ -Undocumented internal function\n\ -@end deftypefn") -{ - string_vector retval; - -#ifdef HAVE_CURL - int nargin = args.length (); - - if (nargin != 2) - error ("__ftp_mput__: incorrect number of arguments"); - else - { - std::string handle = args(0).string_value (); - std::string pat = args(1).string_value (); - - if (!error_state) - { - const curl_handle curl = handles.contents (handle); - - if (curl.is_valid ()) - { - glob_match pattern (file_ops::tilde_expand (pat)); - string_vector files = pattern.glob (); - - for (octave_idx_type i = 0; i < files.length (); i++) - { - std::string file = files (i); - - file_stat fs (file); - - if (! fs.exists ()) - { - error ("__ftp__mput: file does not exist"); - break; - } - - if (fs.is_dir ()) - { - retval.append (mput_directory (curl, "", file)); - if (error_state) - break; - } - else - { - // FIXME Does ascii mode need to be flagged here? - std::ifstream ifile (file.c_str (), std::ios::in | - std::ios::binary); - - if (! ifile.is_open ()) - { - error ("__ftp_mput__: unable to open file"); - break; - } - - curl.put (file, ifile); - - ifile.close (); - - if (error_state) - break; - - retval.append (file); - } - } - } - else - error ("__ftp_mput__: invalid ftp handle"); - } - } -#else - error ("__ftp_mput__: not available in this version of Octave"); -#endif - - return (nargout > 0 ? octave_value (retval) : octave_value ()); -} - -#ifdef HAVE_CURL -static void -getallfiles (const curl_handle& curl, const std::string& dir, - const std::string& target) -{ - std::string sep = file_ops::dir_sep_str (); - file_stat fs (dir); - - if (!fs || !fs.is_dir ()) - { - std::string msg; - int status = octave_mkdir (dir, 0777, msg); - - if (status < 0) - error ("__ftp_mget__: can't create directory %s%s%s. %s", - target.c_str (), sep.c_str (), dir.c_str (), msg.c_str ()); - } - - if (! error_state) - { - curl.cwd (dir); - - if (! error_state) - { - unwind_protect_safe frame; - - frame.add_fcn (reset_path, curl); - - string_vector sv = curl.list (); - - for (octave_idx_type i = 0; i < sv.length (); i++) - { - time_t ftime; - bool fisdir; - double fsize; - - curl.get_fileinfo (sv(i), fsize, ftime, fisdir); - - if (fisdir) - getallfiles (curl, sv(i), target + dir + sep); - else - { - std::string realfile = target + dir + sep + sv(i); - std::ofstream ofile (realfile.c_str (), - std::ios::out | - std::ios::binary); - - if (! ofile.is_open ()) - { - error ("__ftp_mget__: unable to open file"); - break; - } - - unwind_protect_safe frame2; - - frame2.add_fcn (delete_file, realfile); - - curl.get (sv(i), ofile); - - ofile.close (); - - if (!error_state) - frame2.discard (); - else - frame2.run (); - } - - if (error_state) - break; - } - } - } -} -#endif - -DEFUN_DLD (__ftp_mget__, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} __ftp_mget__ (@var{handle}, @var{files})\n\ -Undocumented internal function\n\ -@end deftypefn") -{ -#ifdef HAVE_CURL - int nargin = args.length (); - - if (nargin != 2 && nargin != 3) - error ("__ftp_mget__: incorrect number of arguments"); - else - { - std::string handle = args(0).string_value (); - std::string file = args(1).string_value (); - std::string target; - - if (nargin == 3) - target = args(2).string_value () + file_ops::dir_sep_str (); - - if (! error_state) - { - const curl_handle curl = handles.contents (handle); - - if (curl.is_valid ()) - { - string_vector sv = curl.list (); - octave_idx_type n = 0; - glob_match pattern (file); - - for (octave_idx_type i = 0; i < sv.length (); i++) - { - if (pattern.match (sv(i))) - { - n++; - - time_t ftime; - bool fisdir; - double fsize; - - curl.get_fileinfo (sv(i), fsize, ftime, fisdir); - - if (fisdir) - getallfiles (curl, sv(i), target); - else - { - std::ofstream ofile ((target + sv(i)).c_str (), - std::ios::out | - std::ios::binary); - - if (! ofile.is_open ()) - { - error ("__ftp_mget__: unable to open file"); - break; - } - - unwind_protect_safe frame; - - frame.add_fcn (delete_file, target + sv(i)); - - curl.get (sv(i), ofile); - - ofile.close (); - - if (!error_state) - frame.discard (); - else - frame.run (); - } - - if (error_state) - break; - } - } - if (n == 0) - error ("__ftp_mget__: file not found"); - } - } - } -#else - error ("__ftp_mget__: not available in this version of Octave"); -#endif - - return octave_value (); -} diff -r 20d1b911b4e7 -r c702371ff6df libinterp/gendoc.pl --- a/libinterp/gendoc.pl Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/gendoc.pl Sat Oct 05 11:22:09 2013 -0400 @@ -64,7 +64,7 @@ foreach $i (0 .. $#func_list) { $func = $func_list[$i]; - print "$func\n"; + print "\x{1d}$func\n"; print "\@c $func $src_fname\n"; print $docstr[$i],"\n"; } diff -r 20d1b911b4e7 -r c702371ff6df libinterp/octave-value/ov-base.cc --- a/libinterp/octave-value/ov-base.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/octave-value/ov-base.cc Sat Oct 05 11:22:09 2013 -0400 @@ -1565,9 +1565,9 @@ @end group\n\ @end example\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @end deftypefn") { return SET_INTERNAL_VARIABLE (sparse_auto_mutate); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/octave-value/ov-bool-sparse.cc --- a/libinterp/octave-value/ov-bool-sparse.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/octave-value/ov-bool-sparse.cc Sat Oct 05 11:22:09 2013 -0400 @@ -273,7 +273,7 @@ swap_bytes<4> (&tmp); if (tmp != -2) { - error ("load: only 2D sparse matrices are supported"); + error ("load: only 2-D sparse matrices are supported"); return false; } diff -r 20d1b911b4e7 -r c702371ff6df libinterp/octave-value/ov-class.cc --- a/libinterp/octave-value/ov-class.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/octave-value/ov-class.cc Sat Oct 05 11:22:09 2013 -0400 @@ -1239,13 +1239,19 @@ if (have_ctor) { + unwind_protect frame; + + // Simulate try/catch. + + interpreter_try (frame); + octave_value_list result = ctor.do_multi_index_op (1, octave_value_list ()); - if (result.length () == 1) + if (! error_state && result.length () == 1) retval = true; - else - warning ("call to constructor for class %s failed", c_name.c_str ()); + + error_state = false; } else warning ("no constructor for class %s", c_name.c_str ()); @@ -1401,19 +1407,17 @@ if (! reconstruct_parents ()) warning ("load: unable to reconstruct object inheritance"); - else + + if (load_path::find_method (classname, "loadobj") + != std::string ()) { - if (load_path::find_method (classname, "loadobj") - != std::string ()) - { - octave_value in = new octave_class (*this); - octave_value_list tmp = feval ("loadobj", in, 1); + octave_value in = new octave_class (*this); + octave_value_list tmp = feval ("loadobj", in, 1); - if (! error_state) - map = tmp(0).map_value (); - else - success = false; - } + if (! error_state) + map = tmp(0).map_value (); + else + success = false; } } else @@ -1548,18 +1552,16 @@ if (! reconstruct_parents ()) warning ("load: unable to reconstruct object inheritance"); - else + + if (load_path::find_method (c_name, "loadobj") != std::string ()) { - if (load_path::find_method (c_name, "loadobj") != std::string ()) - { - octave_value in = new octave_class (*this); - octave_value_list tmp = feval ("loadobj", in, 1); + octave_value in = new octave_class (*this); + octave_value_list tmp = feval ("loadobj", in, 1); - if (! error_state) - map = tmp(0).map_value (); - else - success = false; - } + if (! error_state) + map = tmp(0).map_value (); + else + success = false; } } else @@ -1788,23 +1790,19 @@ if (!reconstruct_parents ()) warning ("load: unable to reconstruct object inheritance"); - else - { - if (load_path::find_method (c_name, "loadobj") != std::string ()) - { - octave_value in = new octave_class (*this); - octave_value_list tmp = feval ("loadobj", in, 1); - if (! error_state) - { - map = tmp(0).map_value (); - retval = true; - } - else - retval = false; + if (load_path::find_method (c_name, "loadobj") != std::string ()) + { + octave_value in = new octave_class (*this); + octave_value_list tmp = feval ("loadobj", in, 1); + + if (! error_state) + { + map = tmp(0).map_value (); + retval = true; } else - retval = true; + retval = false; } } diff -r 20d1b911b4e7 -r c702371ff6df libinterp/octave-value/ov-cx-sparse.cc --- a/libinterp/octave-value/ov-cx-sparse.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/octave-value/ov-cx-sparse.cc Sat Oct 05 11:22:09 2013 -0400 @@ -305,7 +305,7 @@ swap_bytes<4> (&tmp); if (tmp != -2) { - error ("load: only 2D sparse matrices are supported"); + error ("load: only 2-D sparse matrices are supported"); return false; } diff -r 20d1b911b4e7 -r c702371ff6df libinterp/octave-value/ov-fcn-handle.cc --- a/libinterp/octave-value/ov-fcn-handle.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/octave-value/ov-fcn-handle.cc Sat Oct 05 11:22:09 2013 -0400 @@ -1329,14 +1329,14 @@ /* %!function fcn_handle_save_recurse (n, mode, nm, f2, g2, hm2, hdld2, hbi2) -%! if n == 0 +%! if (n == 0) %! save (mode, nm, "f2", "g2", "hm2", "hdld2", "hbi2"); %! else %! fcn_handle_save_recurse (n - 1, mode, nm, f2, g2, hm2, hdld2, hbi2); %! endif %!endfunction %!function [f2, g2, hm2, hdld2, hbi2] = fcn_handle_load_recurse (n, nm) -%! if n == 0 +%! if (n == 0) %! load (nm) %! else %! [f2, g2, hm2, hdld2, hbi2] = fcn_handle_load_recurse (n - 1, nm); @@ -1792,8 +1792,8 @@ @deftypefn {Built-in Function} {} str2func (@var{fcn_name})\n\ @deftypefnx {Built-in Function} {} str2func (@var{fcn_name}, \"global\")\n\ Return a function handle constructed from the string @var{fcn_name}.\n\ -If the optional \"global\" argument is passed, locally visible functions\n\ -are ignored in the lookup.\n\ +If the optional @qcode{\"global\"} argument is passed, locally visible\n\ +functions are ignored in the lookup.\n\ @end deftypefn") { octave_value retval; diff -r 20d1b911b4e7 -r c702371ff6df libinterp/octave-value/ov-fcn-inline.cc --- a/libinterp/octave-value/ov-fcn-inline.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/octave-value/ov-fcn-inline.cc Sat Oct 05 11:22:09 2013 -0400 @@ -652,7 +652,7 @@ they are the names of the arguments of the function.\n\ \n\ If the second argument is an integer @var{n}, the arguments are\n\ -@code{\"x\"}, @code{\"P1\"}, @dots{}, @code{\"P@var{N}\"}.\n\ +@qcode{\"x\"}, @qcode{\"P1\"}, @dots{}, @qcode{\"P@var{N}\"}.\n\ @seealso{argnames, formula, vectorize}\n\ @end deftypefn") { diff -r 20d1b911b4e7 -r c702371ff6df libinterp/octave-value/ov-java.cc --- a/libinterp/octave-value/ov-java.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/octave-value/ov-java.cc Sat Oct 05 11:22:09 2013 -0400 @@ -2304,9 +2304,9 @@ Query or set the internal variable that controls whether Java arrays are\n\ automatically converted to Octave matrices. The default value is false.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{java_unsigned_autoconversion, debug_java}\n\ @end deftypefn") { @@ -2328,9 +2328,9 @@ Java arrays of class Byte or Integer are converted to matrices of class\n\ uint8 or uint32 respectively. The default value is true.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{java_matrix_autoconversion, debug_java}\n\ @end deftypefn") { @@ -2351,9 +2351,9 @@ information regarding the initialization of the JVM and any Java exceptions\n\ is printed.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @seealso{java_matrix_autoconversion, java_unsigned_autoconversion}\n\ @end deftypefn") { diff -r 20d1b911b4e7 -r c702371ff6df libinterp/octave-value/ov-range.cc --- a/libinterp/octave-value/ov-range.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/octave-value/ov-range.cc Sat Oct 05 11:22:09 2013 -0400 @@ -688,9 +688,9 @@ compatibility; however, it is still not entirely compatible because\n\ @sc{matlab} treats the range expression differently in different contexts.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @end deftypefn") { return SET_INTERNAL_VARIABLE (allow_noninteger_range_as_index); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/octave-value/ov-re-sparse.cc --- a/libinterp/octave-value/ov-re-sparse.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/octave-value/ov-re-sparse.cc Sat Oct 05 11:22:09 2013 -0400 @@ -338,7 +338,7 @@ swap_bytes<4> (&tmp); if (tmp != -2) { - error ("load: only 2D sparse matrices are supported"); + error ("load: only 2-D sparse matrices are supported"); return false; } diff -r 20d1b911b4e7 -r c702371ff6df libinterp/octave-value/ov-struct.cc --- a/libinterp/octave-value/ov-struct.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/octave-value/ov-struct.cc Sat Oct 05 11:22:09 2013 -0400 @@ -2285,9 +2285,9 @@ Query or set the internal variable that specifies the number of\n\ structure levels to display.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @end deftypefn") { return SET_INTERNAL_VARIABLE_WITH_LIMITS (struct_levels_to_print, -1, @@ -2305,9 +2305,9 @@ are always printed. In both cases, however, printing will be limited to\n\ the number of levels specified by @var{struct_levels_to_print}.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @end deftypefn") { return SET_INTERNAL_VARIABLE (print_struct_array_contents); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/octave-value/ov-usr-fcn.cc --- a/libinterp/octave-value/ov-usr-fcn.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/octave-value/ov-usr-fcn.cc Sat Oct 05 11:22:09 2013 -0400 @@ -1014,9 +1014,9 @@ If true, Octave will attempt to eliminate the redundant copying when calling\n\ subsasgn method of a user-defined class.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @end deftypefn") { return SET_INTERNAL_VARIABLE (optimize_subsasgn_calls); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/octave.cc --- a/libinterp/octave.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/octave.cc Sat Oct 05 11:22:09 2013 -0400 @@ -33,6 +33,7 @@ #include +#include #include #include #include @@ -126,6 +127,10 @@ // (--force-gui) static bool force_gui_option = false; +// If TRUE don't fork when starting the GUI. +// (--no-fork) +static bool no_fork_option = false; + // If TRUE don't start the GUI. // (--no-gui) static bool no_gui_option = false; @@ -160,7 +165,7 @@ [--echo-commands] [--eval CODE] [--exec-path path]\n\ [--force-gui] [--help] [--image-path path]\n\ [--info-file file] [--info-program prog] [--interactive]\n\ - [--line-editing] [--no-gui] [--no-history]\n\ + [--line-editing] [--no-fork] [--no-gui] [--no-history]\n\ [--no-init-file] [--no-init-path] [--no-jit-compiler]\n\ [--no-line-editing] [--no-site-file] [--no-window-system]\n\ [--norc] [-p path] [--path path] [--persist] [--silent]\n\ @@ -195,15 +200,16 @@ #define INFO_PROG_OPTION 8 #define DEBUG_JIT_OPTION 9 #define LINE_EDITING_OPTION 10 -#define NO_GUI_OPTION 11 -#define NO_INIT_FILE_OPTION 12 -#define NO_INIT_PATH_OPTION 13 -#define NO_JIT_COMPILER_OPTION 14 -#define NO_LINE_EDITING_OPTION 15 -#define NO_SITE_FILE_OPTION 16 -#define PERSIST_OPTION 17 -#define TEXI_MACROS_FILE_OPTION 18 -#define TRADITIONAL_OPTION 19 +#define NO_FORK_OPTION 11 +#define NO_GUI_OPTION 12 +#define NO_INIT_FILE_OPTION 13 +#define NO_INIT_PATH_OPTION 14 +#define NO_JIT_COMPILER_OPTION 15 +#define NO_LINE_EDITING_OPTION 16 +#define NO_SITE_FILE_OPTION 17 +#define PERSIST_OPTION 18 +#define TEXI_MACROS_FILE_OPTION 19 +#define TRADITIONAL_OPTION 20 struct option long_opts[] = { { "braindead", no_argument, 0, TRADITIONAL_OPTION }, { "built-in-docstrings-file", required_argument, 0, BUILT_IN_DOCSTRINGS_FILE_OPTION }, @@ -220,6 +226,7 @@ { "info-program", required_argument, 0, INFO_PROG_OPTION }, { "interactive", no_argument, 0, 'i' }, { "line-editing", no_argument, 0, LINE_EDITING_OPTION }, + { "no-fork", no_argument, 0, NO_FORK_OPTION }, { "no-gui", no_argument, 0, NO_GUI_OPTION }, { "no-history", no_argument, 0, 'H' }, { "no-init-file", no_argument, 0, NO_INIT_FILE_OPTION }, @@ -517,7 +524,8 @@ static void verbose_usage (void) { - std::cout << OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_AND_WARRANTY "\n\ + std::cout << octave_name_version_copyright_copying_and_warranty () + << "\n\ \n\ Usage: octave [options] [FILE]\n\ \n\ @@ -537,6 +545,7 @@ --info-program PROGRAM Use PROGRAM for reading info files.\n\ --interactive, -i Force interactive behavior.\n\ --line-editing Force readline use for command-line editing.\n\ + --no-fork Don't fork when starting the graphical user interface.\n\ --no-gui Disable the graphical user interface.\n\ --no-history, -H Don't save commands to the history list\n\ --no-init-file Don't read the ~/.octaverc or .octaverc files.\n\ @@ -557,11 +566,12 @@ FILE Execute commands from FILE. Exit when done\n\ unless --persist is also specified.\n\ \n" -OCTAVE_WWW_STATEMENT "\n\ -\n" -OCTAVE_CONTRIB_STATEMENT "\n\ -\n" -OCTAVE_BUGS_STATEMENT "\n"; + << octave_www_statement () + << "\n\n" + << octave_contrib_statement () + << "\n\n" + << octave_bugs_statement () + << "\n"; exit (0); } @@ -578,7 +588,8 @@ static void print_version_and_exit (void) { - std::cout << OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_WARRANTY_AND_BUGS "\n"; + std::cout << octave_name_version_copyright_copying_warranty_and_bugs () + << "\n"; exit (0); } @@ -785,6 +796,10 @@ forced_line_editing = true; break; + case NO_FORK_OPTION: + no_fork_option = true; + break; + case NO_GUI_OPTION: no_gui_option = true; break; @@ -944,7 +959,7 @@ octave_execute_interpreter (void) { if (! inhibit_startup_message) - std::cout << OCTAVE_STARTUP_MESSAGE "\n" << std::endl; + std::cout << octave_startup_message () << "\n" << std::endl; execute_startup_files (); @@ -1071,6 +1086,26 @@ return start_gui; } +int +octave_fork_gui (void) +{ + bool have_ctty = false; + +#if ! (defined (__WIN32__) || defined (__APPLE__)) || defined (__CYGWIN__) + +#if defined (HAVE_CTERMID) + const char *ctty = ctermid (0); +#else + const char *ctty = "/dev/tty"; +#endif + + have_ctty = gnulib::open (ctty, O_RDWR, 0) > 0; + +#endif + + return (have_ctty && ! no_fork_option); +} + DEFUN (isguirunning, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} isguirunning ()\n\ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/octave.h --- a/libinterp/octave.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/octave.h Sat Oct 05 11:22:09 2013 -0400 @@ -41,6 +41,7 @@ extern OCTINTERP_API int octave_embedded; extern OCTINTERP_API int octave_starting_gui (void); +extern OCTINTERP_API int octave_fork_gui (void); #ifdef __cplusplus } diff -r 20d1b911b4e7 -r c702371ff6df libinterp/parse-tree/lex.h --- a/libinterp/parse-tree/lex.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/parse-tree/lex.h Sat Oct 05 11:22:09 2013 -0400 @@ -282,6 +282,7 @@ looping (0), defining_func (0), looking_at_function_handle (0), block_comment_nesting_level (0), token_count (0), current_input_line (), comment_text (), help_text (), + string_text (), string_line (0), string_column (0), fcn_file_name (), fcn_file_full_name (), looking_at_object_index (), parsed_function_name (), pending_local_variables (), symtab_context (), nesting_level (), tokens () @@ -419,6 +420,13 @@ // The current help text. std::string help_text; + // The current character string text. + std::string string_text; + + // The position of the beginning of the current character string. + int string_line; + int string_column; + // Simple name of function file we are reading. std::string fcn_file_name; @@ -509,6 +517,8 @@ void prep_for_file (void); + void begin_string (int state); + virtual int fill_flex_buffer (char *buf, unsigned int max_size) = 0; bool at_end_of_buffer (void) const { return input_buf.empty (); } @@ -543,12 +553,6 @@ void finish_comment (octave_comment_elt::comment_type typ); - bool have_continuation (bool trailing_comments_ok = true); - - bool have_ellipsis_continuation (bool trailing_comments_ok = true); - - int handle_string (char delim); - int handle_close_bracket (int bracket_type); bool looks_like_command_arg (void); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/parse-tree/lex.ll --- a/libinterp/parse-tree/lex.ll Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/parse-tree/lex.ll Sat Oct 05 11:22:09 2013 -0400 @@ -51,6 +51,9 @@ %x BLOCK_COMMENT_START %x LINE_COMMENT_START +%x DQ_STRING_START +%x SQ_STRING_START + %{ #include @@ -205,6 +208,31 @@ } \ while (0) +// We can't rely on the trick used elsewhere of sticking ASCII 1 in +// the input buffer and recognizing it as a special case because ASCII +// 1 is a valid character for a character string. If we are at the +// end of the buffer, ask for more input. If we are at the end of the +// file, deal with it. Otherwise, just keep going with the text from +// the current buffer. +#define HANDLE_STRING_CONTINUATION \ + do \ + { \ + curr_lexer->decrement_promptflag (); \ + curr_lexer->input_line_number++; \ + curr_lexer->current_input_column = 1; \ + \ + if (curr_lexer->is_push_lexer ()) \ + { \ + if (curr_lexer->at_end_of_buffer ()) \ + return -1; \ + \ + if (curr_lexer->at_end_of_file ()) \ + return curr_lexer->handle_end_of_input (); \ + } \ + } \ + while (0) + + static bool Vdisplay_tokens = false; static unsigned int Vtoken_count = 0; @@ -222,7 +250,6 @@ D [0-9] S [ \t] NL ((\n)|(\r)|(\r\n)) -CONT ((\.\.\.)|(\\)) Im [iIjJ] CCHAR [#%] IDENT ([_$a-zA-Z][_$a-zA-Z0-9]*) @@ -290,9 +317,9 @@ curr_lexer->at_beginning_of_statement = false; curr_lexer->current_input_column++; - int tok = curr_lexer->handle_string (yytext[0]); - - return curr_lexer->count_token_internal (tok); + + curr_lexer->begin_string (yytext[0] == '"' + ? DQ_STRING_START : SQ_STRING_START); } [^#% \t\r\n\;\,\"\'][^ \t\r\n\;\,]*{S}* { @@ -449,7 +476,7 @@ %} ^{S}*{CCHAR}\{{S}*{NL} { - curr_lexer->lexer_debug ("^{S}*{CCHAR}\{{S}*{NL}"); + curr_lexer->lexer_debug ("^{S}*{CCHAR}\\{{S}*{NL}"); yyless (0); @@ -468,7 +495,7 @@ } ^{S}*{CCHAR}\{{S}*{NL} { - curr_lexer->lexer_debug ("^{S}*{CCHAR}\{{S}*{NL}"); + curr_lexer->lexer_debug ("^{S}*{CCHAR}\\{{S}*{NL}"); curr_lexer->input_line_number++; curr_lexer->current_input_column = 1; @@ -622,6 +649,238 @@ } %{ +// Double-quoted character strings. +%} + +\"\" { + curr_lexer->lexer_debug ("\\\"\\\""); + + curr_lexer->current_input_column += yyleng; + curr_lexer->string_text += '"'; + } + +\" { + curr_lexer->lexer_debug ("\\\""); + + curr_lexer->current_input_column++; + + curr_lexer->pop_start_state (); + + curr_lexer->looking_for_object_index = true; + curr_lexer->at_beginning_of_statement = false; + + curr_lexer->push_token (new token (DQ_STRING, + curr_lexer->string_text, + curr_lexer->string_line, + curr_lexer->string_column)); + + curr_lexer->string_text = ""; + + return curr_lexer->count_token_internal (DQ_STRING); + } + +\\[0-7]{1,3} { + curr_lexer->lexer_debug ("\\\\[0-7]{1,3}"); + + curr_lexer->current_input_column += yyleng; + + int result; + sscanf (yytext+1, "%o", &result); + + if (result > 0xff) + error ("invalid octal escape sequence in character string"); + else + curr_lexer->string_text += static_cast (result); + } + +\\x[0-9a-fA-F]+ { + curr_lexer->lexer_debug ("\\\\x[0-9a-fA-F]+"); + + curr_lexer->current_input_column += yyleng; + + int result; + sscanf (yytext+2, "%x", &result); + + // Truncate the value silently instead of checking the range like + // we do for octal above. This is to match C/C++ where any number + // of digits is allowed but the value is implementation-defined if + // it exceeds the range of the character type. + curr_lexer->string_text += static_cast (result); + } + +"\\a" { + curr_lexer->lexer_debug ("\"\\\\a\""); + + curr_lexer->current_input_column += yyleng; + curr_lexer->string_text += '\a'; + } + +"\\b" { + curr_lexer->lexer_debug ("\"\\\\b\""); + + curr_lexer->current_input_column += yyleng; + curr_lexer->string_text += '\b'; + } + +"\\f" { + curr_lexer->lexer_debug ("\"\\\\f\""); + + curr_lexer->current_input_column += yyleng; + curr_lexer->string_text += '\f'; + } + +"\\n" { + curr_lexer->lexer_debug ("\"\\\\n\""); + + curr_lexer->current_input_column += yyleng; + curr_lexer->string_text += '\n'; + } + +"\\r" { + curr_lexer->lexer_debug ("\"\\\\r\""); + + curr_lexer->current_input_column += yyleng; + curr_lexer->string_text += '\r'; + } + +"\\t" { + curr_lexer->lexer_debug ("\"\\\\t\""); + + curr_lexer->current_input_column += yyleng; + curr_lexer->string_text += '\t'; + } + +"\\v" { + curr_lexer->lexer_debug ("\"\\\\v\""); + + curr_lexer->current_input_column += yyleng; + curr_lexer->string_text += '\v'; + } + +(\.\.\.){S}*{NL} | +(\.\.\.){S}*{CCHAR}.*{NL} { + curr_lexer->lexer_debug ("(\\.\\.\\.){S}*{NL}|(\\.\\.\\.){S}*{CCHAR}.*{NL}"); + + static const char *msg = "'...' continuations in double-quoted character strings are obsolete and will not be allowed in a future version of Octave; please use '\\' instead"; + + std::string nm = curr_lexer->fcn_file_full_name; + + if (nm.empty ()) + warning_with_id ("Octave:deprecated-syntax", "%s", msg); + else + warning_with_id ("Octave:deprecated-syntax", + "%s; near line %d of file '%s'", msg, + curr_lexer->input_line_number, nm.c_str ()); + + HANDLE_STRING_CONTINUATION; + } + +\\{S}+{NL} | +\\{S}*{CCHAR}.*{NL} { + curr_lexer->lexer_debug ("\\\\{S}+{NL}|\\\\{S}*{CCHAR}.*{NL}"); + + static const char *msg = "white space and comments after continuation markers in double-quoted character strings are obsolete and will not be allowed in a future version of Octave"; + + std::string nm = curr_lexer->fcn_file_full_name; + + if (nm.empty ()) + warning_with_id ("Octave:deprecated-syntax", "%s", msg); + else + warning_with_id ("Octave:deprecated-syntax", + "%s; near line %d of file '%s'", msg, + curr_lexer->input_line_number, nm.c_str ()); + + HANDLE_STRING_CONTINUATION; + } + +\\{NL} { + curr_lexer->lexer_debug ("\\\\{NL}"); + + HANDLE_STRING_CONTINUATION; + } + +\\. { + curr_lexer->lexer_debug ("\\\\."); + + curr_lexer->current_input_column += yyleng; + curr_lexer->string_text += yytext[1]; + } + +\. { + curr_lexer->lexer_debug ("\\."); + + curr_lexer->current_input_column++; + curr_lexer->string_text += yytext[0]; + } + +[^\.\\\r\n\"]+ { + curr_lexer->lexer_debug ("[^\\.\\\\\\r\\n\\\"]+"); + + curr_lexer->current_input_column += yyleng; + curr_lexer->string_text += yytext; + } + +{NL} { + curr_lexer->lexer_debug ("{NL}"); + + curr_lexer->input_line_number++; + curr_lexer->current_input_column = 1; + + error ("unterminated character string constant"); + + return LEXICAL_ERROR; + } + +%{ +// Single-quoted character strings. +%} + +\'\' { + curr_lexer->lexer_debug ("\\'\\'"); + + curr_lexer->current_input_column += yyleng; + curr_lexer->string_text += '\''; + } + +\' { + curr_lexer->lexer_debug ("\\'"); + + curr_lexer->current_input_column++; + + curr_lexer->pop_start_state (); + + curr_lexer->looking_for_object_index = true; + curr_lexer->at_beginning_of_statement = false; + + curr_lexer->push_token (new token (SQ_STRING, + curr_lexer->string_text, + curr_lexer->string_line, + curr_lexer->string_column)); + + curr_lexer->string_text = ""; + + return curr_lexer->count_token_internal (SQ_STRING); + } + +[^\'\n\r]+ { + curr_lexer->lexer_debug ("[^\\'\\n\\r]+"); + + curr_lexer->current_input_column += yyleng; + curr_lexer->string_text += yytext; + } + +{NL} { + curr_lexer->lexer_debug ("{NL}"); + + curr_lexer->input_line_number++; + curr_lexer->current_input_column = 1; + + error ("unterminated character string constant"); + + return LEXICAL_ERROR; + } + +%{ // Imaginary numbers. %} @@ -661,7 +920,7 @@ {D}+/\.[\*/\\^\'] | {NUMBER} { - curr_lexer->lexer_debug ("{D}+/\\.[\\*/\\^\\']|{NUMBER}"); + curr_lexer->lexer_debug ("{D}+/\\.[\\*/\\\\^\\']|{NUMBER}"); if (curr_lexer->previous_token_may_be_command () && curr_lexer->space_follows_previous_token ()) @@ -701,12 +960,33 @@ } %{ -// Continuation lines. Allow comments after continuations. +// Continuation lines. Allow arbitrary text after continuations. +%} + +\.\.\..*{NL} { + curr_lexer->lexer_debug ("\\.\\.\\..*{NL}"); + + curr_lexer->handle_continuation (); + } + +%{ +// Deprecated C preprocessor style continuation markers. %} -{CONT}{S}*{NL} | -{CONT}{S}*{CCHAR}.*{NL} { - curr_lexer->lexer_debug ("{CONT}{S}*{NL}|{CONT}{S}*{CCHAR}.*{NL}"); +\\{S}*{NL} | +\\{S}*{CCHAR}.*{NL} { + curr_lexer->lexer_debug ("\\\\{S}*{NL}|\\\\{S}*{CCHAR}.*{NL}"); + + static const char *msg = "using continuation marker \\ outside of double quoted strings is deprecated and will be removed in a future version of Octave"; + + std::string nm = curr_lexer->fcn_file_full_name; + + if (nm.empty ()) + warning_with_id ("Octave:deprecated-syntax", "%s", msg); + else + warning_with_id ("Octave:deprecated-syntax", + "%s; near line %d of file '%s'", msg, + curr_lexer->input_line_number, nm.c_str ()); curr_lexer->handle_continuation (); } @@ -867,14 +1147,14 @@ if (curr_lexer->previous_token_may_be_command () && curr_lexer->space_follows_previous_token ()) { - yyless (0); + curr_lexer->current_input_column++; curr_lexer->push_start_state (COMMAND_START); + curr_lexer->begin_string (SQ_STRING_START); } else if (curr_lexer->at_beginning_of_statement) { curr_lexer->current_input_column++; - int retval = curr_lexer->handle_string ('\''); - return curr_lexer->count_token_internal (retval); + curr_lexer->begin_string (SQ_STRING_START); } else { @@ -888,8 +1168,7 @@ || curr_lexer->previous_token_is_binop ()) { curr_lexer->current_input_column++; - int retval = curr_lexer->handle_string ('\''); - return curr_lexer->count_token_internal (retval); + curr_lexer->begin_string (SQ_STRING_START); } else { @@ -906,8 +1185,7 @@ || curr_lexer->previous_token_is_keyword ()) { curr_lexer->current_input_column++; - int retval = curr_lexer->handle_string ('\''); - return curr_lexer->count_token_internal (retval); + curr_lexer->begin_string (SQ_STRING_START); } else return curr_lexer->count_token (HERMITIAN); @@ -920,8 +1198,7 @@ || curr_lexer->previous_token_is_keyword ()) { curr_lexer->current_input_column++; - int retval = curr_lexer->handle_string ('\''); - return curr_lexer->count_token_internal (retval); + curr_lexer->begin_string (SQ_STRING_START); } else return curr_lexer->count_token (HERMITIAN); @@ -934,13 +1211,14 @@ %} \" { - curr_lexer->lexer_debug ("\""); + curr_lexer->lexer_debug ("\\\""); if (curr_lexer->previous_token_may_be_command () && curr_lexer->space_follows_previous_token ()) { - yyless (0); + curr_lexer->current_input_column++; curr_lexer->push_start_state (COMMAND_START); + curr_lexer->begin_string (DQ_STRING_START); } else { @@ -954,8 +1232,7 @@ || curr_lexer->previous_token_is_binop ()) { curr_lexer->current_input_column++; - int retval = curr_lexer->handle_string ('"'); - return curr_lexer->count_token_internal (retval); + curr_lexer->begin_string (DQ_STRING_START); } else { @@ -968,15 +1245,13 @@ else { curr_lexer->current_input_column++; - int retval = curr_lexer->handle_string ('"'); - return curr_lexer->count_token_internal (retval); + curr_lexer->begin_string (DQ_STRING_START); } } else { curr_lexer->current_input_column++; - int retval = curr_lexer->handle_string ('"'); - return curr_lexer->count_token_internal (retval); + curr_lexer->begin_string (DQ_STRING_START); } } } @@ -1557,6 +1832,9 @@ current_input_line = ""; comment_text = ""; help_text = ""; + string_text = ""; + string_line = 0; + string_column = 0; fcn_file_name = ""; fcn_file_full_name = ""; looking_at_object_index.clear (); @@ -1771,6 +2049,15 @@ push_start_state (INPUT_FILE_START); } +void +octave_base_lexer::begin_string (int state) +{ + string_line = input_line_number; + string_column = current_input_column; + + push_start_state (state); +} + int octave_base_lexer::handle_end_of_input (void) { @@ -2259,218 +2546,6 @@ at_beginning_of_statement = true; } -// We have seen a backslash and need to find out if it should be -// treated as a continuation character. If so, this eats it, up to -// and including the new line character. -// -// Match whitespace only, followed by a comment character or newline. -// Once a comment character is found, discard all input until newline. -// If non-whitespace characters are found before comment -// characters, return 0. Otherwise, return 1. - -// FIXME -- we need to handle block comments here. - -bool -octave_base_lexer::have_continuation (bool trailing_comments_ok) -{ - std::ostringstream buf; - - std::string comment_buf; - - bool in_comment = false; - bool beginning_of_comment = false; - - int c = 0; - - while ((c = text_yyinput ()) != EOF) - { - buf << static_cast (c); - - switch (c) - { - case ' ': - case '\t': - if (in_comment) - { - comment_buf += static_cast (c); - beginning_of_comment = false; - } - break; - - case '%': - case '#': - if (trailing_comments_ok) - { - if (in_comment) - { - if (! beginning_of_comment) - comment_buf += static_cast (c); - } - else - { - maybe_gripe_matlab_incompatible_comment (c); - in_comment = true; - beginning_of_comment = true; - } - } - else - goto cleanup; - break; - - case '\n': - if (in_comment) - { - comment_buf += static_cast (c); - octave_comment_buffer::append (comment_buf); - } - current_input_column = 0; - decrement_promptflag (); - gripe_matlab_incompatible_continuation (); - return true; - - default: - if (in_comment) - { - comment_buf += static_cast (c); - beginning_of_comment = false; - } - else - goto cleanup; - break; - } - } - - xunput (c); - return false; - -cleanup: - - std::string s = buf.str (); - - int len = s.length (); - while (len--) - xunput (s[len]); - - return false; -} - -// We have seen a '.' and need to see if it is the start of a -// continuation. If so, this eats it, up to and including the new -// line character. - -bool -octave_base_lexer::have_ellipsis_continuation (bool trailing_comments_ok) -{ - char c1 = text_yyinput (); - if (c1 == '.') - { - char c2 = text_yyinput (); - if (c2 == '.' && have_continuation (trailing_comments_ok)) - return true; - else - { - xunput (c2); - xunput (c1); - } - } - else - xunput (c1); - - return false; -} - -int -octave_base_lexer::handle_string (char delim) -{ - std::ostringstream buf; - - int bos_line = input_line_number; - int bos_col = current_input_column; - - int c; - int escape_pending = 0; - - while ((c = text_yyinput ()) != EOF) - { - current_input_column++; - - if (c == '\\') - { - if (delim == '\'' || escape_pending) - { - buf << static_cast (c); - escape_pending = 0; - } - else - { - if (have_continuation (false)) - escape_pending = 0; - else - { - buf << static_cast (c); - escape_pending = 1; - } - } - continue; - } - else if (c == '.') - { - if (delim == '\'' || ! have_ellipsis_continuation (false)) - buf << static_cast (c); - } - else if (c == '\n') - { - error ("unterminated string constant"); - break; - } - else if (c == delim) - { - if (escape_pending) - buf << static_cast (c); - else - { - c = text_yyinput (); - if (c == delim) - { - buf << static_cast (c); - } - else - { - std::string s; - xunput (c); - - if (delim == '\'') - s = buf.str (); - else - s = do_string_escapes (buf.str ()); - - if (delim == '"') - gripe_matlab_incompatible ("\" used as string delimiter"); - else if (delim == '\'') - gripe_single_quote_string (); - - looking_for_object_index = true; - at_beginning_of_statement = false; - - int tok = delim == '"' ? DQ_STRING : SQ_STRING; - - push_token (new token (tok, s, bos_line, bos_col)); - - return tok; - } - } - } - else - { - buf << static_cast (c); - } - - escape_pending = 0; - } - - return LEXICAL_ERROR; -} - int octave_base_lexer::handle_close_bracket (int bracket_type) { @@ -2638,11 +2713,7 @@ return kw_token; } - // Find the token in the symbol table. Beware the magic - // transformation of the end keyword... - - if (tok == "end") - tok = "__end__"; + // Find the token in the symbol table. symbol_table::scope_id sid = symtab_context.curr_scope (); @@ -2669,7 +2740,9 @@ current_input_column += flex_yyleng (); - if (tok != "__end__") + // The magic end index can't be indexed. + + if (tok != "end") looking_for_object_index = true; at_beginning_of_statement = false; @@ -2980,6 +3053,14 @@ std::cerr << "LINE_COMMENT_START" << std::endl; break; + case DQ_STRING_START: + std::cerr << "DQ_STRING_START" << std::endl; + break; + + case SQ_STRING_START: + std::cerr << "SQ_STRING_START" << std::endl; + break; + default: std::cerr << "UNKNOWN START STATE!" << std::endl; break; diff -r 20d1b911b4e7 -r c702371ff6df libinterp/parse-tree/module.mk --- a/libinterp/parse-tree/module.mk Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/parse-tree/module.mk Sat Oct 05 11:22:09 2013 -0400 @@ -1,5 +1,6 @@ EXTRA_DIST += \ parse-tree/module.mk \ + parse-tree/oct-parse.in.yy \ parse-tree/octave.gperf PARSER_INC = \ diff -r 20d1b911b4e7 -r c702371ff6df libinterp/parse-tree/oct-parse.in.yy --- a/libinterp/parse-tree/oct-parse.in.yy Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/parse-tree/oct-parse.in.yy Sat Oct 05 11:22:09 2013 -0400 @@ -257,8 +257,8 @@ %type string constant magic_colon %type anon_fcn_handle %type fcn_handle -%type matrix_rows matrix_rows1 -%type cell_rows cell_rows1 +%type matrix_rows +%type cell_rows %type matrix cell %type primary_expr oper_expr %type simple_expr colon_expr assign_expr expression @@ -282,13 +282,12 @@ %type switch_command %type switch_case default_case %type case_list1 case_list -%type decl2 +%type decl2 param_list_elt %type decl1 %type declaration %type statement function_end %type simple_list simple_list1 list list1 -%type opt_list input1 - +%type opt_list %type attr %type attr_list opt_attr_list %type superclass @@ -331,33 +330,24 @@ // Statements and statement lists // ============================== -input : input1 +input : simple_list '\n' { parser.stmt_list = $1; YYACCEPT; } - | simple_list parse_error - { ABORT_PARSE; } + | simple_list END_OF_INPUT + { + lexer.end_of_input = true; + parser.stmt_list = $1; + YYACCEPT; + } | parse_error { ABORT_PARSE; } ; -input1 : '\n' +simple_list : opt_sep_no_nl { $$ = 0; } - | END_OF_INPUT - { - lexer.end_of_input = true; - $$ = 0; - } - | simple_list - { $$ = $1; } - | simple_list '\n' - { $$ = $1; } - | simple_list END_OF_INPUT - { $$ = $1; } - ; - -simple_list : simple_list1 opt_sep_no_nl + | simple_list1 opt_sep_no_nl { $$ = parser.set_stmt_print_flag ($1, $2, false); } ; @@ -465,59 +455,62 @@ { $$ = $1; } ; -matrix : '[' ']' - { $$ = new tree_constant (octave_null_matrix::instance); } - | '[' ';' ']' - { $$ = new tree_constant (octave_null_matrix::instance); } - | '[' ',' ']' - { $$ = new tree_constant (octave_null_matrix::instance); } - | '[' matrix_rows ']' +matrix : '[' matrix_rows ']' { $$ = parser.finish_matrix ($2); } ; -matrix_rows : matrix_rows1 - { $$ = $1; } - | matrix_rows1 ';' // Ignore trailing semicolon. - { $$ = $1; } - ; - -matrix_rows1 : cell_or_matrix_row - { $$ = new tree_matrix ($1); } - | matrix_rows1 ';' cell_or_matrix_row +matrix_rows : cell_or_matrix_row + { $$ = $1 ? new tree_matrix ($1) : 0; } + | matrix_rows ';' cell_or_matrix_row { - $1->append ($3); - $$ = $1; + if ($1) + { + if ($3) + $1->append ($3); + + $$ = $1; + } + else + $$ = $3 ? new tree_matrix ($3) : 0; } ; -cell : '{' '}' - { $$ = new tree_constant (octave_value (Cell ())); } - | '{' ';' '}' - { $$ = new tree_constant (octave_value (Cell ())); } - | '{' cell_rows '}' +cell : '{' cell_rows '}' { $$ = parser.finish_cell ($2); } ; -cell_rows : cell_rows1 - { $$ = $1; } - | cell_rows1 ';' // Ignore trailing semicolon. - { $$ = $1; } - ; - -cell_rows1 : cell_or_matrix_row - { $$ = new tree_cell ($1); } - | cell_rows1 ';' cell_or_matrix_row +cell_rows : cell_or_matrix_row + { $$ = $1 ? new tree_cell ($1) : 0; } + | cell_rows ';' cell_or_matrix_row { - $1->append ($3); - $$ = $1; + if ($1) + { + if ($3) + $1->append ($3); + + $$ = $1; + } + else + $$ = $3 ? new tree_cell ($3) : 0; } ; +// tree_argument_list objects can't be empty or have leading or trailing +// commas, but those are all allowed in matrix and cell array rows. + cell_or_matrix_row - : arg_list + : // empty + { $$ = 0; } + | ',' + { $$ = 0; } + | arg_list { $$ = $1; } - | arg_list ',' // Ignore trailing comma. + | arg_list ',' { $$ = $1; } + | ',' arg_list + { $$ = $2; } + | ',' arg_list ',' + { $$ = $2; } ; fcn_handle : '@' FCN_HANDLE @@ -832,10 +825,6 @@ lexer.looking_at_initializer_expression = false; $$ = new tree_decl_elt ($1, $4); } - | magic_tilde - { - $$ = new tree_decl_elt ($1); - } ; // ==================== @@ -1009,15 +998,15 @@ if (! ($$ = parser.make_unwind_command ($1, $4, $8, $9, $2, $6))) ABORT_PARSE; } - | TRY stash_comment opt_sep opt_list CATCH - stash_comment opt_sep opt_list END + | TRY stash_comment opt_sep opt_list CATCH stash_comment + opt_sep opt_list END { - if (! ($$ = parser.make_try_command ($1, $4, $8, $9, $2, $6))) + if (! ($$ = parser.make_try_command ($1, $4, $7, $8, $9, $2, $6))) ABORT_PARSE; } | TRY stash_comment opt_sep opt_list END { - if (! ($$ = parser.make_try_command ($1, $4, 0, $5, $2, 0))) + if (! ($$ = parser.make_try_command ($1, $4, 0, 0, $5, $2, 0))) ABORT_PARSE; } ; @@ -1104,15 +1093,21 @@ } ; -param_list2 : decl2 +param_list2 : param_list_elt { $$ = new tree_parameter_list ($1); } - | param_list2 ',' decl2 + | param_list2 ',' param_list_elt { $1->append ($3); $$ = $1; } ; +param_list_elt : decl2 + { $$ = $1; } + | magic_tilde + { $$ = new tree_decl_elt ($1); } + ; + // =================================== // List of function return value names // =================================== @@ -1120,19 +1115,31 @@ return_list : '[' ']' { lexer.looking_at_return_list = false; + $$ = new tree_parameter_list (); } - | return_list1 + | identifier { lexer.looking_at_return_list = false; - if ($1->validate (tree_parameter_list::out)) - $$ = $1; + + tree_parameter_list *tmp = new tree_parameter_list ($1); + + // Even though this parameter list can contain only + // a single identifier, we still need to validate it + // to check for varargin or varargout. + + if (tmp->validate (tree_parameter_list::out)) + $$ = tmp; else ABORT_PARSE; } | '[' return_list1 ']' { lexer.looking_at_return_list = false; + + // Check for duplicate parameter names, varargin, + // or varargout. + if ($2->validate (tree_parameter_list::out)) $$ = $2; else @@ -2283,6 +2290,7 @@ tree_command * octave_base_parser::make_try_command (token *try_tok, tree_statement_list *body, + char catch_sep, tree_statement_list *cleanup_stmts, token *end_tok, octave_comment_list *lc, @@ -2297,7 +2305,26 @@ int l = try_tok->line (); int c = try_tok->column (); - retval = new tree_try_catch_command (body, cleanup_stmts, + tree_identifier *id = 0; + + if (! catch_sep && cleanup_stmts && ! cleanup_stmts->empty ()) + { + tree_statement *stmt = cleanup_stmts->front (); + + if (stmt) + { + tree_expression *expr = stmt->expression (); + + if (expr && expr->is_identifier ()) + { + id = dynamic_cast (expr); + + cleanup_stmts->pop_front (); + } + } + } + + retval = new tree_try_catch_command (body, cleanup_stmts, id, lc, mc, tc, l, c); } @@ -3340,7 +3367,9 @@ tree_expression * octave_base_parser::finish_matrix (tree_matrix *m) { - return finish_array_list (m); + return (m + ? finish_array_list (m) + : new tree_constant (octave_null_matrix::instance)); } // Finish building a cell list. @@ -3348,7 +3377,9 @@ tree_expression * octave_base_parser::finish_cell (tree_cell *c) { - return finish_array_list (c); + return (c + ? finish_array_list (c) + : new tree_constant (octave_value (Cell ()))); } void @@ -3804,7 +3835,7 @@ DEFUN (autoload, args, , "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {} autoload (@var{function}, @var{file})\n\ +@deftypefn {Built-in Function} {} autoload (@var{function}, @var{file})\n\ @deftypefnx {Built-in Function} {} autoload (@dots{}, @asis{\"remove\"})\n\ Define @var{function} to autoload from @var{file}.\n\ \n\ @@ -4034,9 +4065,9 @@ @deftypefnx {Built-in Function} {} mfilename (\"fullpath\")\n\ @deftypefnx {Built-in Function} {} mfilename (\"fullpathext\")\n\ Return the name of the currently executing file. At the top-level,\n\ -return the empty string. Given the argument @code{\"fullpath\"},\n\ +return the empty string. Given the argument @qcode{\"fullpath\"},\n\ include the directory part of the file name, but not the extension.\n\ -Given the argument @code{\"fullpathext\"}, include the directory part\n\ +Given the argument @qcode{\"fullpathext\"}, include the directory part\n\ of the file name and the extension.\n\ @end deftypefn") { @@ -4555,7 +4586,7 @@ "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} assignin (@var{context}, @var{varname}, @var{value})\n\ Assign @var{value} to @var{varname} in context @var{context}, which\n\ -may be either @code{\"base\"} or @code{\"caller\"}.\n\ +may be either @qcode{\"base\"} or @qcode{\"caller\"}.\n\ @seealso{evalin}\n\ @end deftypefn") { @@ -4609,8 +4640,8 @@ @deftypefn {Built-in Function} {} evalin (@var{context}, @var{try})\n\ @deftypefnx {Built-in Function} {} evalin (@var{context}, @var{try}, @var{catch})\n\ Like @code{eval}, except that the expressions are evaluated in the\n\ -context @var{context}, which may be either @code{\"caller\"} or\n\ -@code{\"base\"}.\n\ +context @var{context}, which may be either @qcode{\"caller\"} or\n\ +@qcode{\"base\"}.\n\ @seealso{eval, assignin}\n\ @end deftypefn") { @@ -4693,3 +4724,54 @@ return retval; } + +DEFUN (__parse_file__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} __parse_file__ (@var{file}, @var{verbose})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; + + int nargin = args.length (); + + if (nargin == 1 || nargin == 2) + { + std::string file = args(0).string_value (); + + std::string full_file = octave_env::make_absolute (file); + + size_t file_len = file.length (); + + if ((file_len > 4 && file.substr (file_len-4) == ".oct") + || (file_len > 4 && file.substr (file_len-4) == ".mex") + || (file_len > 2 && file.substr (file_len-2) == ".m")) + { + file = octave_env::base_pathname (file); + file = file.substr (0, file.find_last_of ('.')); + + size_t pos = file.find_last_of (file_ops::dir_sep_str ()); + if (pos != std::string::npos) + file = file.substr (pos+1); + } + + if (! error_state) + { + if (nargin == 2) + octave_stdout << "parsing " << full_file << std::endl; + + octave_function *fcn = parse_fcn_file (full_file, file, "", "", + true, false, false, + false, "__parse_file__"); + + if (fcn) + delete fcn; + } + else + error ("__parse_file__: expecting file name as argument"); + } + else + print_usage (); + + return retval; +} diff -r 20d1b911b4e7 -r c702371ff6df libinterp/parse-tree/parse.h --- a/libinterp/parse-tree/parse.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/parse-tree/parse.h Sat Oct 05 11:22:09 2013 -0400 @@ -215,8 +215,9 @@ // Build a try-catch command. tree_command * make_try_command (token *try_tok, tree_statement_list *body, - tree_statement_list *cleanup, token *end_tok, - octave_comment_list *lc, octave_comment_list *mc); + char catch_sep, tree_statement_list *cleanup, + token *end_tok, octave_comment_list *lc, + octave_comment_list *mc); // Build a while command. tree_command * diff -r 20d1b911b4e7 -r c702371ff6df libinterp/parse-tree/pt-arg-list.cc --- a/libinterp/parse-tree/pt-arg-list.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/parse-tree/pt-arg-list.cc Sat Oct 05 11:22:09 2013 -0400 @@ -126,7 +126,7 @@ static int index_position = 0; static int num_indices = 0; -DEFCONSTFUN (__end__, , , +DEFCONSTFUN (end, , , "internal function") { octave_value retval; diff -r 20d1b911b4e7 -r c702371ff6df libinterp/parse-tree/pt-binop.cc --- a/libinterp/parse-tree/pt-binop.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/parse-tree/pt-binop.cc Sat Oct 05 11:22:09 2013 -0400 @@ -293,9 +293,9 @@ To obtain short-circuit behavior for logical expressions in new programs,\n\ you should always use the @samp{&&} and @samp{||} operators.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @end deftypefn") { return SET_INTERNAL_VARIABLE (do_braindead_shortcircuit_evaluation); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/parse-tree/pt-check.cc --- a/libinterp/parse-tree/pt-check.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/parse-tree/pt-check.cc Sat Oct 05 11:22:09 2013 -0400 @@ -504,6 +504,15 @@ { tree_statement_list *try_code = cmd.body (); + tree_identifier *expr_id = cmd.identifier (); + + if (expr_id) + { + if (! expr_id->lvalue_ok ()) + gripe ("invalid lvalue used for identifier in try-catch command", + cmd.line ()); + } + if (try_code) try_code->accept (*this); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/parse-tree/pt-eval.cc --- a/libinterp/parse-tree/pt-eval.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/parse-tree/pt-eval.cc Sat Oct 05 11:22:09 2013 -0400 @@ -816,18 +816,18 @@ break; else { - // Clear preivous values before next statement is + // Clear previous values before next statement is // evaluated so that we aren't holding an extra // reference to a value that may be used next. For // example, in code like this: // - // X = rand (N); ## refcount for X should be 1 - // ## after this statement + // X = rand (N); # refcount for X should be 1 + // # after this statement // - // X(idx) = val; ## no extra copy of X should be - // ## needed, but we will be faked - // ## out if retval is not cleared - // ## between statements here + // X(idx) = val; # no extra copy of X should be + // # needed, but we will be faked + // # out if retval is not cleared + // # between statements here // result_values = empty_list; } @@ -927,6 +927,27 @@ buffer_error_messages--; + tree_identifier *expr_id = cmd.identifier (); + octave_lvalue ult; + + if (expr_id) + { + + octave_scalar_map err; + + ult = expr_id->lvalue (); + + if (error_state) + return; + + err.assign ("message", last_error_message ()); + err.assign ("identifier", last_error_id ()); + + if (! error_state) + ult.assign (octave_value::op_asn_eq, err); + + } + if (catch_code) catch_code->accept (*this); } @@ -1244,9 +1265,9 @@ be called recursively. If the limit is exceeded, an error message is\n\ printed and control returns to the top level.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls.\n\ +The original variable value is restored when exiting the function.\n\ @end deftypefn") { return SET_INTERNAL_VARIABLE (max_recursion_depth); @@ -1274,9 +1295,9 @@ Octave will display the results produced by evaluating expressions\n\ within a function body that are not terminated with a semicolon.\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls.\n\ +The original variable value is restored when exiting the function.\n\ @end deftypefn") { return SET_INTERNAL_VARIABLE (silent_functions); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/parse-tree/pt-except.cc --- a/libinterp/parse-tree/pt-except.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/parse-tree/pt-except.cc Sat Oct 05 11:22:09 2013 -0400 @@ -33,6 +33,7 @@ #include "pt-cmd.h" #include "pt-except.h" #include "pt-exp.h" +#include "pt-id.h" #include "pt-jump.h" #include "pt-stmt.h" #include "pt-walk.h" @@ -43,6 +44,7 @@ tree_try_catch_command::~tree_try_catch_command (void) { + delete expr_id; delete try_code; delete catch_code; delete lead_comm; @@ -57,6 +59,7 @@ return new tree_try_catch_command (try_code ? try_code->dup (scope, context) : 0, catch_code ? catch_code->dup (scope, context) : 0, + expr_id ? expr_id->dup (scope, context) : 0, lead_comm ? lead_comm->dup () : 0, mid_comm ? mid_comm->dup () : 0, trail_comm ? trail_comm->dup () : 0, diff -r 20d1b911b4e7 -r c702371ff6df libinterp/parse-tree/pt-except.h --- a/libinterp/parse-tree/pt-except.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/parse-tree/pt-except.h Sat Oct 05 11:22:09 2013 -0400 @@ -29,6 +29,7 @@ #include "comment-list.h" #include "pt-cmd.h" +#include "pt-id.h" #include "symtab.h" // Simple exception handling. @@ -39,19 +40,22 @@ public: tree_try_catch_command (int l = -1, int c = -1) - : tree_command (l, c), try_code (0), catch_code (0), lead_comm (0), + : tree_command (l, c), try_code (0), catch_code (0), expr_id (0), lead_comm (0), mid_comm (0), trail_comm (0) { } tree_try_catch_command (tree_statement_list *tc, tree_statement_list *cc, + tree_identifier *id, octave_comment_list *cl = 0, octave_comment_list *cm = 0, octave_comment_list *ct = 0, int l = -1, int c = -1) - : tree_command (l, c), try_code (tc), catch_code (cc), + : tree_command (l, c), try_code (tc), catch_code (cc), expr_id (id), lead_comm (cl), mid_comm (cm), trail_comm (ct) { } ~tree_try_catch_command (void); + tree_identifier *identifier (void) { return expr_id; } + tree_statement_list *body (void) { return try_code; } tree_statement_list *cleanup (void) { return catch_code; } @@ -75,6 +79,9 @@ // The code to execute if an error occurs in the first block. tree_statement_list *catch_code; + // Identifier to modify. + tree_identifier *expr_id; + // Comment preceding TRY token. octave_comment_list *lead_comm; diff -r 20d1b911b4e7 -r c702371ff6df libinterp/parse-tree/pt-id.h --- a/libinterp/parse-tree/pt-id.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/parse-tree/pt-id.h Sat Oct 05 11:22:09 2013 -0400 @@ -56,7 +56,7 @@ ~tree_identifier (void) { } - bool has_magic_end (void) const { return (name () == "__end__"); } + bool has_magic_end (void) const { return (name () == "end"); } bool is_identifier (void) const { return true; } diff -r 20d1b911b4e7 -r c702371ff6df libinterp/parse-tree/pt-idx.cc --- a/libinterp/parse-tree/pt-idx.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/parse-tree/pt-idx.cc Sat Oct 05 11:22:09 2013 -0400 @@ -360,7 +360,7 @@ // contains the second (or third, etc.) "end" token, // so we must evaluate everything up to the point of // that argument list so we can pass the appropriate - // value to the built-in __end__ function. + // value to the built-in end function. const octave_value_list tmp_list = tmp.subsref (type.substr (tmpi, i - tmpi), idx, nargout); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/parse-tree/pt-mat.cc --- a/libinterp/parse-tree/pt-mat.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/parse-tree/pt-mat.cc Sat Oct 05 11:22:09 2013 -0400 @@ -1336,6 +1336,34 @@ %!assert (class ([cell(1), struct("foo", "bar")]), "cell") %!error [struct("foo", "bar"), cell(1)] + +%!assert ([,1], 1) +%!assert ([1,], 1) +%!assert ([,1,], 1) +%!assert ([,1,;;], 1) +%!assert ([,1,;,;], 1) + +%!assert ([1,1], ones (1, 2)) +%!assert ([,1,1], ones (1, 2)) +%!assert ([1,1,], ones (1, 2)) +%!assert ([,1,1,], ones (1, 2)) +%!assert ([,1,1,;;], ones (1, 2)) +%!assert ([,1,1,;,;], ones (1, 2)) +%!assert ([,;,1,1], ones (1, 2)) + +%!assert ([1;1], ones (2, 1)) +%!assert ([1,;1], ones (2, 1)) +%!assert ([1,;,;1], ones (2, 1)) + +%!error eval ("[,,]") +%!error eval ("[,,;,]") +%!error eval ("[,;,,;,]") + +%!assert (isnull ([,])) +%!assert (isnull ([;])) +%!assert (isnull ([;;])) +%!assert (isnull ([;,;])) +%!assert (isnull ([,;,;,])) */ DEFUN (string_fill_char, args, nargout, @@ -1345,7 +1373,7 @@ @deftypefnx {Built-in Function} {} string_fill_char (@var{new_val}, \"local\")\n\ Query or set the internal variable used to pad all rows of a character\n\ matrix to the same length. It must be a single character. The default\n\ -value is @code{\" \"} (a single space). For example:\n\ +value is @qcode{\" \"} (a single space). For example:\n\ \n\ @example\n\ @group\n\ @@ -1357,9 +1385,9 @@ @end group\n\ @end example\n\ \n\ -When called from inside a function with the \"local\" option, the variable is\n\ -changed locally for the function and any subroutines it calls. The original\n\ -variable value is restored when exiting the function.\n\ +When called from inside a function with the @qcode{\"local\"} option, the\n\ +variable is changed locally for the function and any subroutines it calls. \n\ +The original variable value is restored when exiting the function.\n\ @end deftypefn") { return SET_INTERNAL_VARIABLE (string_fill_char); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/parse-tree/pt-misc.h --- a/libinterp/parse-tree/pt-misc.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/parse-tree/pt-misc.h Sat Oct 05 11:22:09 2013 -0400 @@ -59,6 +59,9 @@ tree_parameter_list (tree_decl_elt *t) : marked_for_varargs (0) { append (t); } + tree_parameter_list (tree_identifier *id) + : marked_for_varargs (0) { append (new tree_decl_elt (id)); } + ~tree_parameter_list (void); void mark_as_formal_parameters (void); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/parse-tree/pt-pr-code.cc --- a/libinterp/parse-tree/pt-pr-code.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/parse-tree/pt-pr-code.cc Sat Oct 05 11:22:09 2013 -0400 @@ -1005,6 +1005,7 @@ newline (); tree_statement_list *try_code = cmd.body (); + tree_identifier *expr_id = cmd.identifier (); if (try_code) { @@ -1021,6 +1022,12 @@ os << "catch"; + if (expr_id) + { + os << " "; + expr_id->accept (*this); + } + newline (); tree_statement_list *catch_code = cmd.cleanup (); diff -r 20d1b911b4e7 -r c702371ff6df libinterp/version.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/version.cc Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,131 @@ +/* + +Copyright (C) 2013 John W. Eaton + +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 +. + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "defaults.h" +#include "version.h" + +static std::string +octave_warranty_statement (const std::string& extra_info = std::string ()) +{ + return "There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or\n\ +FITNESS FOR A PARTICULAR PURPOSE." + + extra_info; +} + +static std::string +format_url (bool html, const std::string& url) +{ + return html ? "" + url + "" : url; +} + +std::string +octave_www_statement (bool html) +{ + return "Additional information about Octave is available at " + + format_url (html, "http://www.octave.org."); +} + +std::string +octave_contrib_statement (bool html) +{ + return "Please contribute if you find this software useful.\n\ +For more information, visit " + + format_url (html, "http://www.octave.org/get-involved.html"); +} + +std::string +octave_bugs_statement (bool html) +{ + return "Read " + format_url (html, "http://www.octave.org/bugs.html") + + " to learn how to submit bug reports."; +} + +std::string +octave_name_version_and_copyright (void) +{ + // The GNU coding standards say that on the first line printed by + // --version, the version number should follow the last space on the + // line. + + return "GNU Octave, version " OCTAVE_VERSION "\n" OCTAVE_COPYRIGHT; +} + +std::string +octave_name_version_copyright_copying_and_warranty + (bool html, const std::string& extra_info) +{ + std::string br = html ? "
\n" : "\n"; + std::string sep = html ? "\n

\n

\n" : "\n\n"; + + return octave_name_version_and_copyright () + + br + + "This is free software; see the source code for copying conditions." + + br + + octave_warranty_statement (extra_info) + + sep + + "Octave was configured for \"" OCTAVE_CANONICAL_HOST_TYPE "\"."; +} + +std::string +octave_name_version_copyright_copying_warranty_and_bugs + (bool html, const std::string& extra_info) +{ + std::string sep = html ? "\n

\n

\n" : "\n\n"; + + std::string msg; + + if (html) + msg = "

\n"; + + msg += octave_name_version_copyright_copying_and_warranty (html, extra_info) + + sep + + octave_www_statement (html) + + sep + + octave_contrib_statement (html) + + sep + + octave_bugs_statement (html) + + (html ? "\n

" : ""); + + return msg; +} + +std::string +octave_startup_message (bool html) +{ + std::string msg + = octave_name_version_copyright_copying_warranty_and_bugs + (html, " For details, type 'warranty'."); + + msg += (html ? "

\n" : "\n"); + + msg += "For information about changes from previous versions, type 'news'."; + + msg += (html ? "\n

" : ""); + + return msg; +} diff -r 20d1b911b4e7 -r c702371ff6df libinterp/version.in.h --- a/libinterp/version.in.h Thu Sep 12 21:08:07 2013 -0400 +++ b/libinterp/version.in.h Sat Oct 05 11:22:09 2013 -0400 @@ -26,67 +26,28 @@ #define OCTAVE_VERSION %OCTAVE_VERSION% -#define OCTAVE_API_VERSION_NUMBER %OCTAVE_API_VERSION_NUMBER% - #define OCTAVE_API_VERSION %OCTAVE_API_VERSION% #define OCTAVE_RELEASE_DATE %OCTAVE_RELEASE_DATE% #define OCTAVE_COPYRIGHT %OCTAVE_COPYRIGHT% -// This is the first line printed by --version. The GNU coding -// standards say that the version number should follow the last space -// on the line. - -#define OCTAVE_NAME_AND_VERSION "GNU Octave, version " OCTAVE_VERSION +extern std::string octave_www_statement (bool html = false); -#define OCTAVE_CONFIG_STATEMENT \ - "Octave was configured for \"" OCTAVE_CANONICAL_HOST_TYPE "\"." - -#define OCTAVE_COPYING_STATEMENT \ - "This is free software; see the source code for copying conditions." +extern std::string octave_contrib_statement (bool html = false); -#define X_OCTAVE_WARRANTY_STATEMENT(ARG) \ - "There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or\n\ -FITNESS FOR A PARTICULAR PURPOSE." ARG - -#define OCTAVE_WARRANTY_STATEMENT \ - X_OCTAVE_WARRANTY_STATEMENT ("") +extern std::string octave_bugs_statement (bool html = false); -#define OCTAVE_WWW_STATEMENT \ - "Additional information about Octave is available at http://www.octave.org." - -#define OCTAVE_CONTRIB_STATEMENT \ - "Please contribute if you find this software useful.\n\ -For more information, visit http://www.octave.org/get-involved.html" +extern std::string octave_name_version_and_copyright (void); -#define OCTAVE_BUGS_STATEMENT \ - "Read http://www.octave.org/bugs.html to learn how to submit bug reports." - -#define OCTAVE_NAME_VERSION_AND_COPYRIGHT \ - OCTAVE_NAME_AND_VERSION "\n" \ - OCTAVE_COPYRIGHT - -#define OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_AND_WARRANTY \ - X_OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_AND_WARRANTY("") \ +extern std::string +octave_name_version_copyright_copying_and_warranty + (bool html = false, const std::string& extra_info = std::string ()); -#define X_OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_AND_WARRANTY(ARG) \ - OCTAVE_NAME_VERSION_AND_COPYRIGHT "\n" \ - OCTAVE_COPYING_STATEMENT "\n" \ - X_OCTAVE_WARRANTY_STATEMENT (ARG) "\n\n" \ - OCTAVE_CONFIG_STATEMENT +extern std::string +octave_name_version_copyright_copying_warranty_and_bugs + (bool html = false, const std::string& extra_info = std::string ()); -#define X_OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_WARRANTY_AND_BUGS(ARG) \ - X_OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_AND_WARRANTY(ARG) "\n\n" \ - OCTAVE_WWW_STATEMENT "\n\n" \ - OCTAVE_CONTRIB_STATEMENT "\n\n" \ - OCTAVE_BUGS_STATEMENT +extern std::string octave_startup_message (bool html = false); -#define OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_WARRANTY_AND_BUGS \ - X_OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_WARRANTY_AND_BUGS ("") - -#define OCTAVE_STARTUP_MESSAGE \ - X_OCTAVE_NAME_VERSION_COPYRIGHT_COPYING_WARRANTY_AND_BUGS \ - (" For details, type 'warranty'.") "\n\n" \ - "For information about changes from previous versions, type 'news'." #endif diff -r 20d1b911b4e7 -r c702371ff6df liboctave/Makefile.am --- a/liboctave/Makefile.am Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/Makefile.am Sat Oct 05 11:22:09 2013 -0400 @@ -20,8 +20,6 @@ include $(top_srcdir)/build-aux/common.mk -AUTOMAKE_OPTIONS = subdir-objects - ## Run cruft dir with stand-alone Makefile. ## Eventually this will use module.mk syntax. SUBDIRS = cruft @@ -125,7 +123,8 @@ $(array_libarray_la_SOURCES) \ $(numeric_libnumeric_la_SOURCES) \ $(system_libsystem_la_SOURCES) \ - $(util_libutil_la_SOURCES) + $(util_libutil_la_SOURCES) \ + $(TEMPLATE_SRC) TST_FILES_SRC := $(shell $(top_srcdir)/build-aux/find-files-with-tests.sh "$(srcdir)" $(LIBOCTAVE_TST_SRC)) diff -r 20d1b911b4e7 -r c702371ff6df liboctave/array/Sparse.cc --- a/liboctave/array/Sparse.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/array/Sparse.cc Sat Oct 05 11:22:09 2013 -0400 @@ -2623,7 +2623,7 @@ * %!function x = set_slice (x, dim, slice, arg) -%! switch dim +%! switch (dim) %! case 11 %! x(slice) = 2; %! case 21 @@ -2636,7 +2636,7 @@ %!endfunction %!function x = set_slice2 (x, dim, slice) -%! switch dim +%! switch (dim) %! case 11 %! x(slice) = 2 * ones (size (slice)); %! case 21 @@ -2793,6 +2793,23 @@ %! s(1,:) = []; %! assert (s, sparse ([], [], [], 0, 1)); +## Test (bug #37321) +%!test a=sparse (0,0); assert (all (a) == sparse ([1])); +%!test a=sparse (0,1); assert (all (a) == sparse ([1])); +%!test a=sparse (1,0); assert (all (a) == sparse ([1])); +%!test a=sparse (1,0); assert (all (a,2) == sparse ([1])); +%!test a=sparse (1,0); assert (size (all (a,1)), [1 0]); +%!test a=sparse (1,1); +%! assert (all (a) == sparse ([0])); +%! assert (size (all (a)), [1 1]); +%!test a=sparse (2,1); +%! assert (all (a) == sparse ([0])); +%! assert (size (all (a)), [1 1]); +%!test a=sparse (1,2); +%! assert (all (a) == sparse ([0])); +%! assert (size (all (a)), [1 1]); +%!test a=sparse (2,2); assert (isequal (all (a), sparse ([0 0]))); + */ template diff -r 20d1b911b4e7 -r c702371ff6df liboctave/cruft/Makefile.am --- a/liboctave/cruft/Makefile.am Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/cruft/Makefile.am Sat Oct 05 11:22:09 2013 -0400 @@ -20,8 +20,6 @@ include $(top_srcdir)/build-aux/common.mk -AUTOMAKE_OPTIONS = subdir-objects - ## Search local directories before those specified by the user. AM_CPPFLAGS = \ -I$(top_builddir)/libgnu -I$(top_srcdir)/libgnu diff -r 20d1b911b4e7 -r c702371ff6df liboctave/link-deps.mk --- a/liboctave/link-deps.mk Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/link-deps.mk Sat Oct 05 11:22:09 2013 -0400 @@ -15,6 +15,7 @@ LIBOCTAVE_LINK_DEPS = \ $(GNULIB_LINK_DEPS) \ + $(CURL_LIBS) \ $(SPARSE_XLIBS) \ $(ARPACK_LIBS) \ $(QRUPDATE_LIBS) \ @@ -31,6 +32,7 @@ $(LIBS) LIBOCTAVE_LINK_OPTS = \ + $(CURL_LDFLAGS) \ $(SPARSE_XLDFLAGS) \ $(ARPACK_LDFLAGS) \ $(QRUPDATE_LDFLAGS) \ diff -r 20d1b911b4e7 -r c702371ff6df liboctave/numeric/DASPK-opts.in --- a/liboctave/numeric/DASPK-opts.in Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/numeric/DASPK-opts.in Sat Oct 05 11:22:09 2013 -0400 @@ -103,7 +103,7 @@ initial conditions that are consistent). If this option is set to a nonzero value, you must also set the -@code{\"algebraic variables\"} option to declare which variables in the +@qcode{\"algebraic variables\"} option to declare which variables in the problem are algebraic. END_DOC_ITEM @@ -139,11 +139,11 @@ @item MXNH Maximum number of values of the artificial stepsize parameter to be -tried if the @code{\"compute consistent initial condition\"} option has +tried if the @qcode{\"compute consistent initial condition\"} option has been set to 1 (default is 5). Note that the maximum total number of Newton iterations allowed is -@code{MXNIT*MXNJ*MXNH} if the @code{\"compute consistent initial +@code{MXNIT*MXNJ*MXNH} if the @qcode{\"compute consistent initial condition\"} option has been set to 1 and @code{MXNIT*MXNJ} if it is set to 2. @@ -194,7 +194,7 @@ NAME = "exclude algebraic variables from error test" DOC_ITEM Set to a nonzero value to exclude algebraic variables from the error -test. You must also set the @code{\"algebraic variables\"} option to +test. You must also set the @qcode{\"algebraic variables\"} option to declare which variables in the problem are algebraic (default is 0). END_DOC_ITEM @@ -212,8 +212,8 @@ in the equation set. This option is required by the -@code{compute consistent initial condition\"} and -@code{\"exclude algebraic variables from error test\"} options. +@qcode{compute consistent initial condition\"} and +@qcode{\"exclude algebraic variables from error test\"} options. END_DOC_ITEM TYPE = "Array" @@ -239,7 +239,7 @@ NAME = "enforce inequality constraints" DOC_ITEM Set to one of the following values to enforce the inequality -constraints specified by the @code{\"inequality constraint types\"} +constraints specified by the @qcode{\"inequality constraint types\"} option (default is 0). @enumerate @@ -282,7 +282,7 @@ @end table This option only has an effect if the -@code{\"enforce inequality constraints\"} option is nonzero. +@qcode{\"enforce inequality constraints\"} option is nonzero. END_DOC_ITEM TYPE = "Array" diff -r 20d1b911b4e7 -r c702371ff6df liboctave/numeric/LSODE-opts.in --- a/liboctave/numeric/LSODE-opts.in Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/numeric/LSODE-opts.in Sat Oct 05 11:22:09 2013 -0400 @@ -74,12 +74,12 @@ system. Valid values are @table @asis -@item \"adams\" -@itemx \"non-stiff\" +@item @qcode{\"adams\"} +@itemx @qcode{\"non-stiff\"} No Jacobian used (even if it is available). -@item \"bdf\" -@itemx \"stiff\" +@item @qcode{\"bdf\"} +@itemx @qcode{\"stiff\"} Use stiff backward differentiation formula (BDF) method. If a function to compute the Jacobian is not supplied, @code{lsode} will compute a finite difference approximation of the Jacobian matrix. diff -r 20d1b911b4e7 -r c702371ff6df liboctave/numeric/lo-mappers.h --- a/liboctave/numeric/lo-mappers.h Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/numeric/lo-mappers.h Sat Oct 05 11:22:09 2013 -0400 @@ -234,7 +234,7 @@ T X_NINT (T x) { - return (xisinf (x) || xisnan (x)) ? x : xfloor (x + 0.5); + return (xfinite (x) ? xfloor (x + 0.5) : x); } inline OCTAVE_API double D_NINT (double x) { return X_NINT (x); } diff -r 20d1b911b4e7 -r c702371ff6df liboctave/numeric/lo-specfun.cc --- a/liboctave/numeric/lo-specfun.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/numeric/lo-specfun.cc Sat Oct 05 11:22:09 2013 -0400 @@ -3568,3 +3568,100 @@ return retval; } + +void +ellipj (double u, double m, double& sn, double& cn, double& dn, double& err) +{ + static const int Nmax = 16; + double m1, t=0, si_u, co_u, se_u, ta_u, b, c[Nmax], a[Nmax], phi; + int n, Nn, ii; + + if (m < 0 || m > 1) + { + (*current_liboctave_warning_handler) + ("ellipj: expecting 0 <= M <= 1"); + sn = cn = dn = lo_ieee_nan_value (); + return; + } + + double sqrt_eps = sqrt (std::numeric_limits::epsilon ()); + if (m < sqrt_eps) + { + // For small m, ( Abramowitz and Stegun, Section 16.13 ) + si_u = sin (u); + co_u = cos (u); + t = 0.25*m*(u - si_u*co_u); + sn = si_u - t * co_u; + cn = co_u + t * si_u; + dn = 1 - 0.5*m*si_u*si_u; + } + else if ((1 - m) < sqrt_eps) + { + // For m1 = (1-m) small ( Abramowitz and Stegun, Section 16.15 ) + m1 = 1 - m; + si_u = sinh (u); + co_u = cosh (u); + ta_u = tanh (u); + se_u = 1/co_u; + sn = ta_u + 0.25*m1*(si_u*co_u - u)*se_u*se_u; + cn = se_u - 0.25*m1*(si_u*co_u - u)*ta_u*se_u; + dn = se_u + 0.25*m1*(si_u*co_u + u)*ta_u*se_u; + } + else + { + // Arithmetic-Geometric Mean (AGM) algorithm + // ( Abramowitz and Stegun, Section 16.4 ) + a[0] = 1; + b = sqrt (1 - m); + c[0] = sqrt (m); + for (n = 1; n < Nmax; ++n) + { + a[n] = (a[n - 1] + b)/2; + c[n] = (a[n - 1] - b)/2; + b = sqrt (a[n - 1]*b); + if (c[n]/a[n] < std::numeric_limits::epsilon ()) break; + } + if (n >= Nmax - 1) + { + err = 1; + return; + } + Nn = n; + for (ii = 1; n > 0; ii = ii*2, --n) ; // ii = pow(2,Nn) + phi = ii*a[Nn]*u; + for (n = Nn; n > 0; --n) + { + t = phi; + phi = (asin ((c[n]/a[n])* sin (phi)) + phi)/2; + } + sn = sin (phi); + cn = cos (phi); + dn = cn/cos (t - phi); + } +} + +void +ellipj (const Complex& u, double m, Complex& sn, Complex& cn, Complex& dn, double& err) +{ + double m1 = 1 - m, ss1, cc1, dd1; + + ellipj (imag (u), m1, ss1, cc1, dd1, err); + if (real (u) == 0) + { + // u is pure imag: Jacoby imag. transf. + sn = Complex (0, ss1/cc1); + cn = 1/cc1; // cn.imag = 0; + dn = dd1/cc1; // dn.imag = 0; + } + else + { + // u is generic complex + double ss, cc, dd, ddd; + + ellipj (real (u), m, ss, cc, dd, err); + ddd = cc1*cc1 + m*ss*ss*ss1*ss1; + sn = Complex (ss*dd1/ddd, cc*dd*ss1*cc1/ddd); + cn = Complex (cc*cc1/ddd, -ss*dd*ss1*dd1/ddd); + dn = Complex (dd*cc1*dd1/ddd, -m*ss*cc*ss1/ddd); + } +} diff -r 20d1b911b4e7 -r c702371ff6df liboctave/numeric/lo-specfun.h --- a/liboctave/numeric/lo-specfun.h Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/numeric/lo-specfun.h Sat Oct 05 11:22:09 2013 -0400 @@ -607,4 +607,7 @@ extern OCTAVE_API Array betaincinv (const Array& x, const Array& a, double b); extern OCTAVE_API Array betaincinv (const Array& x, const Array& a, const Array& b); +extern OCTAVE_API void ellipj (double u, double m, double& sn, double& cn, double& dn, double& err); +extern OCTAVE_API void ellipj (const Complex& u, double m, Complex& sn, Complex& cn, Complex& dn, double& err); + #endif diff -r 20d1b911b4e7 -r c702371ff6df liboctave/numeric/module.mk --- a/liboctave/numeric/module.mk Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/numeric/module.mk Sat Oct 05 11:22:09 2013 -0400 @@ -168,11 +168,13 @@ numeric/sparse-dmsolve.cc ## Special rules for sources which must be built before rest of compilation. -$(OPT_INC) : %.h : %.in $(top_srcdir)/build-aux/mk-opts.pl +$(OPT_INC) : %.h : %.in @echo making $@ from $< @$(PERL) $(top_srcdir)/build-aux/mk-opts.pl --opt-class-header $< > $@-t mv $@-t $@ +$(OPT_INC) : $(top_srcdir)/build-aux/mk-opts.pl + noinst_LTLIBRARIES += numeric/libnumeric.la numeric_libnumeric_la_SOURCES = $(NUMERIC_SRC) diff -r 20d1b911b4e7 -r c702371ff6df liboctave/numeric/oct-rand.cc --- a/liboctave/numeric/oct-rand.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/numeric/oct-rand.cc Sat Oct 05 11:22:09 2013 -0400 @@ -360,7 +360,7 @@ break; case poisson_dist: - if (a < 0.0 || xisnan (a) || xisinf (a)) + if (a < 0.0 || ! xfinite (a)) retval = octave_NaN; else { @@ -371,7 +371,7 @@ break; case gamma_dist: - if (a <= 0.0 || xisnan (a) || xisinf (a)) + if (a <= 0.0 || ! xfinite (a)) retval = octave_NaN; else F77_FUNC (dgengam, DGENGAM) (1.0, a, retval); @@ -443,7 +443,7 @@ break; case poisson_dist: - if (da < 0.0 || xisnan (da) || xisinf (da)) + if (da < 0.0 || ! xfinite (a)) dretval = octave_NaN; else { @@ -454,7 +454,7 @@ break; case gamma_dist: - if (da <= 0.0 || xisnan (da) || xisinf (da)) + if (da <= 0.0 || ! xfinite (a)) retval = octave_NaN; else F77_FUNC (dgengam, DGENGAM) (1.0, da, dretval); @@ -663,6 +663,30 @@ return retval; } +// Guarantee reproducible conversion of negative initialization values to +// random number algorithm. Note that Matlab employs slightly different rules. +// 1) Seed saturates at 2^32-1 for any value larger than that. +// 2) NaN, Inf are translated to 2^32-1. +// 3) -Inf is translated to 0. +static uint32_t +double2uint32 (double d) +{ + uint32_t u; + static const double TWOUP32 = std::numeric_limits::max() + 1.0; + + if (! xfinite (d)) + u = 0; + else + { + d = fmod (d, TWOUP32); + if (d < 0) + d += TWOUP32; + u = static_cast (d); + } + + return u; +} + void octave_rand::set_internal_state (const ColumnVector& s) { @@ -672,7 +696,7 @@ OCTAVE_LOCAL_BUFFER (uint32_t, tmp, MT_N + 1); for (octave_idx_type i = 0; i < n; i++) - tmp[i] = static_cast (s.elem (i)); + tmp[i] = double2uint32 (s.elem (i)); if (len == MT_N + 1 && tmp[MT_N] <= MT_N && tmp[MT_N] > 0) oct_set_state (tmp); @@ -748,7 +772,7 @@ case poisson_dist: if (use_old_generators) { - if (a < 0.0 || xisnan (a) || xisinf (a)) + if (a < 0.0 || ! xfinite (a)) #define RAND_FUNC(x) x = octave_NaN; MAKE_RAND (len); #undef RAND_FUNC @@ -769,7 +793,7 @@ case gamma_dist: if (use_old_generators) { - if (a <= 0.0 || xisnan (a) || xisinf (a)) + if (a <= 0.0 || ! xfinite (a)) #define RAND_FUNC(x) x = octave_NaN; MAKE_RAND (len); #undef RAND_FUNC @@ -838,7 +862,7 @@ if (use_old_generators) { double da = a; - if (da < 0.0 || xisnan (da) || xisinf (da)) + if (da < 0.0 || ! xfinite (a)) #define RAND_FUNC(x) x = octave_NaN; MAKE_RAND (len); #undef RAND_FUNC @@ -860,7 +884,7 @@ if (use_old_generators) { double da = a; - if (da <= 0.0 || xisnan (da) || xisinf (da)) + if (da <= 0.0 || ! xfinite (a)) #define RAND_FUNC(x) x = octave_NaN; MAKE_RAND (len); #undef RAND_FUNC diff -r 20d1b911b4e7 -r c702371ff6df liboctave/numeric/randmtzig.c --- a/liboctave/numeric/randmtzig.c Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/numeric/randmtzig.c Sat Oct 05 11:22:09 2013 -0400 @@ -268,7 +268,7 @@ unsigned char word[4]; if (fread (word, 4, 1, urandom) != 1) break; - entropy[n++] = word[0]+(word[1]<<8)+(word[2]<<16)+(word[3]<<24); + entropy[n++] = word[0]+(word[1]<<8)+(word[2]<<16)+((uint32_t)word[3]<<24); } fclose (urandom); } diff -r 20d1b911b4e7 -r c702371ff6df liboctave/operators/Sparse-op-defs.h --- a/liboctave/operators/Sparse-op-defs.h Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/operators/Sparse-op-defs.h Sat Oct 05 11:22:09 2013 -0400 @@ -1766,7 +1766,7 @@ for (octave_idx_type i = 0; i < nc ; i++) \ { \ retval.ridx (i) = 0; \ - retval.cidx (i+1) = i; \ + retval.cidx (i+1) = i+1; \ retval.data (i) = MT_RESULT; \ } \ } \ diff -r 20d1b911b4e7 -r c702371ff6df liboctave/system/mach-info.cc --- a/liboctave/system/mach-info.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/system/mach-info.cc Sat Oct 05 11:22:09 2013 -0400 @@ -75,14 +75,6 @@ { oct_mach_info::float_format retval = oct_mach_info::flt_fmt_unknown; -#if defined (CRAY) - - // FIXME -- this should be determined automatically. - - native_float_fmt = oct_mach_info::flt_fmt_cray; - -#else - float_params fp[5]; INIT_FLT_PAR (fp[0], oct_mach_info::flt_fmt_ieee_big_endian, @@ -97,18 +89,6 @@ 0, 1017118720, 0, 1018167296); - INIT_FLT_PAR (fp[2], oct_mach_info::flt_fmt_vax_d, - 128, 0, - -32769, -1, - 9344, 0, - 9344, 0); - - INIT_FLT_PAR (fp[3], oct_mach_info::flt_fmt_vax_g, - 16, 0, - -32769, -1, - 15552, 0, - 15552, 0); - INIT_FLT_PAR (fp[4], oct_mach_info::flt_fmt_unknown, 0, 0, 0, 0, @@ -133,8 +113,6 @@ } while (fp[++i].fp_fmt != oct_mach_info::flt_fmt_unknown); -#endif - return retval; } @@ -214,12 +192,6 @@ retval = oct_mach_info::flt_fmt_ieee_big_endian; else if (s == "ieee-le" || s == "l") retval = oct_mach_info::flt_fmt_ieee_little_endian; - else if (s == "vaxd" || s == "d") - retval = oct_mach_info::flt_fmt_vax_d; - else if (s == "vaxg" || s == "g") - retval = oct_mach_info::flt_fmt_vax_g; - else if (s == "cray" || s == "c") - retval = oct_mach_info::flt_fmt_cray; else if (s == "unknown") retval = oct_mach_info::flt_fmt_unknown; else @@ -244,18 +216,6 @@ retval = "ieee-le"; break; - case flt_fmt_vax_d: - retval = "vaxd"; - break; - - case flt_fmt_vax_g: - retval = "vaxg"; - break; - - case flt_fmt_cray: - retval = "cray"; - break; - default: break; } diff -r 20d1b911b4e7 -r c702371ff6df liboctave/system/mach-info.h --- a/liboctave/system/mach-info.h Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/system/mach-info.h Sat Oct 05 11:22:09 2013 -0400 @@ -40,9 +40,6 @@ flt_fmt_unknown, flt_fmt_ieee_little_endian, flt_fmt_ieee_big_endian, - flt_fmt_vax_d, - flt_fmt_vax_g, - flt_fmt_cray }; static bool instance_ok (void); diff -r 20d1b911b4e7 -r c702371ff6df liboctave/util/action-container.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/liboctave/util/action-container.h Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,341 @@ +/* + +Copyright (C) 1993-2012 John W. Eaton +Copyright (C) 2009-2010 VZLU Prague + +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 +. + +*/ + +#if !defined (octave_action_container_h) +#define octave_action_container_h 1 + +// This class allows registering actions in a list for later +// execution, either explicitly or when the container goes out of +// scope. + +// FIXME -- is there a better name for this class? + +class +action_container +{ +public: + + // A generic unwind_protect element. Knows how to run itself and + // discard itself. Also, contains a pointer to the next element. + class elem + { + public: + elem (void) { } + + virtual void run (void) { } + + virtual ~elem (void) { } + + friend class action_container; + + private: + + // No copying! + + elem (const elem&); + + elem& operator = (const elem&); + }; + + // An element that merely runs a void (*)(void) function. + + class fcn_elem : public elem + { + public: + fcn_elem (void (*fptr) (void)) + : e_fptr (fptr) { } + + void run (void) { e_fptr (); } + + private: + void (*e_fptr) (void); + }; + + // An element that stores a variable of type T along with a void (*) (T) + // function pointer, and calls the function with the parameter. + + template + class fcn_arg_elem : public elem + { + public: + fcn_arg_elem (void (*fcn) (T), T arg) + : e_fcn (fcn), e_arg (arg) { } + + void run (void) { e_fcn (e_arg); } + + private: + + // No copying! + + fcn_arg_elem (const fcn_arg_elem&); + + fcn_arg_elem& operator = (const fcn_arg_elem&); + + void (*e_fcn) (T); + T e_arg; + }; + + // An element that stores a variable of type T along with a + // void (*) (const T&) function pointer, and calls the function with + // the parameter. + + template + class fcn_crefarg_elem : public elem + { + public: + fcn_crefarg_elem (void (*fcn) (const T&), const T& arg) + : e_fcn (fcn), e_arg (arg) { } + + void run (void) { e_fcn (e_arg); } + + private: + void (*e_fcn) (const T&); + T e_arg; + }; + + // An element for calling a member function. + + template + class method_elem : public elem + { + public: + method_elem (T *obj, void (T::*method) (void)) + : e_obj (obj), e_method (method) { } + + void run (void) { (e_obj->*e_method) (); } + + private: + + T *e_obj; + void (T::*e_method) (void); + + // No copying! + + method_elem (const method_elem&); + + method_elem operator = (const method_elem&); + }; + + // An element for calling a member function with a single argument + + template + class method_arg_elem : public elem + { + public: + method_arg_elem (T *obj, void (T::*method) (A), A arg) + : e_obj (obj), e_method (method), e_arg (arg) { } + + void run (void) { (e_obj->*e_method) (e_arg); } + + private: + + T *e_obj; + void (T::*e_method) (A); + A e_arg; + + // No copying! + + method_arg_elem (const method_arg_elem&); + + method_arg_elem operator = (const method_arg_elem&); + }; + + // An element for calling a member function with a single argument + + template + class method_crefarg_elem : public elem + { + public: + method_crefarg_elem (T *obj, void (T::*method) (const A&), const A& arg) + : e_obj (obj), e_method (method), e_arg (arg) { } + + void run (void) { (e_obj->*e_method) (e_arg); } + + private: + + T *e_obj; + void (T::*e_method) (const A&); + A e_arg; + + // No copying! + + method_crefarg_elem (const method_crefarg_elem&); + + method_crefarg_elem operator = (const method_crefarg_elem&); + }; + + // An element that stores arbitrary variable, and restores it. + + template + class restore_var_elem : public elem + { + public: + restore_var_elem (T& ref, const T& val) + : e_ptr (&ref), e_val (val) { } + + void run (void) { *e_ptr = e_val; } + + private: + + // No copying! + + restore_var_elem (const restore_var_elem&); + + restore_var_elem& operator = (const restore_var_elem&); + + T *e_ptr, e_val; + }; + + // Deletes a class allocated using new. + + template + class delete_ptr_elem : public elem + { + public: + delete_ptr_elem (T *ptr) + : e_ptr (ptr) { } + + void run (void) { delete e_ptr; } + + private: + + T *e_ptr; + + // No copying! + + delete_ptr_elem (const delete_ptr_elem&); + + delete_ptr_elem operator = (const delete_ptr_elem&); + }; + + action_container (void) { } + + virtual ~action_container (void) { } + + virtual void add (elem *new_elem) = 0; + + // Call to void func (void). + void add_fcn (void (*fcn) (void)) + { + add (new fcn_elem (fcn)); + } + + // Call to void func (T). + template + void add_fcn (void (*action) (T), T val) + { + add (new fcn_arg_elem (action, val)); + } + + // Call to void func (const T&). + template + void add_fcn (void (*action) (const T&), const T& val) + { + add (new fcn_crefarg_elem (action, val)); + } + + // Call to T::method (void). + template + void add_method (T *obj, void (T::*method) (void)) + { + add (new method_elem (obj, method)); + } + + // Call to T::method (A). + template + void add_method (T *obj, void (T::*method) (A), A arg) + { + add (new method_arg_elem (obj, method, arg)); + } + + // Call to T::method (const A&). + template + void add_method (T *obj, void (T::*method) (const A&), const A& arg) + { + add (new method_crefarg_elem (obj, method, arg)); + } + + // Call to delete (T*). + + template + void add_delete (T *obj) + { + add (new delete_ptr_elem (obj)); + } + + // Protect any variable. + template + void protect_var (T& var) + { + add (new restore_var_elem (var, var)); + } + + // Protect any variable, value given. + template + void protect_var (T& var, const T& val) + { + add (new restore_var_elem (var, val)); + } + + operator bool (void) const { return ! empty (); } + + virtual void run_first (void) = 0; + + void run (size_t num) + { + if (num > size ()) + num = size (); + + for (size_t i = 0; i < num; i++) + run_first (); + } + + void run (void) { run (size ()); } + + virtual void discard_first (void) = 0; + + void discard (size_t num) + { + if (num > size ()) + num = size (); + + for (size_t i = 0; i < num; i++) + discard_first (); + } + + void discard (void) { discard (size ()); } + + virtual size_t size (void) const = 0; + + bool empty (void) const { return size () == 0; } + +private: + + // No copying! + + action_container (const action_container&); + + action_container& operator = (const action_container&); +}; + +#endif diff -r 20d1b911b4e7 -r c702371ff6df liboctave/util/base-list.h --- a/liboctave/util/base-list.h Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/util/base-list.h Sat Oct 05 11:22:09 2013 -0400 @@ -49,24 +49,28 @@ template void remove_if (P pred) { + lst.remove_if (pred); + + // FIXME: kluge removed 8/7/13. Eventually this commented + // code should be deleted. + // + // FIXME: this kluge should be removed at some point. // We would like to simply call // // lst.remove_if (pred); // // but the Sun Studio compiler chokes on that. // - // FIXME -- this kluge should be removed at some point. - - iterator b = lst.begin (); - iterator e = lst.end (); - while (b != e) - { - iterator n = b; - n++; - if (pred (*b)) - lst.erase (b); - b = n; - } + // iterator b = lst.begin (); + // iterator e = lst.end (); + // while (b != e) + // { + // iterator n = b; + // n++; + // if (pred (*b)) + // lst.erase (b); + // b = n; + // } } void clear (void) { lst.clear (); } diff -r 20d1b911b4e7 -r c702371ff6df liboctave/util/byte-swap.h --- a/liboctave/util/byte-swap.h Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/util/byte-swap.h Sat Oct 05 11:22:09 2013 -0400 @@ -23,13 +23,10 @@ #if !defined (octave_byte_swap_h) #define octave_byte_swap_h 1 -// FIXME -- not sure these volatile qualifiers are really -// needed or appropriate here. - static inline void -swap_bytes (volatile void *ptr, unsigned int i, unsigned int j) +swap_bytes (void *ptr, unsigned int i, unsigned int j) { - volatile char *t = static_cast (ptr); + char *t = static_cast (ptr); char tmp = t[i]; t[i] = t[j]; @@ -38,7 +35,7 @@ template void -swap_bytes (volatile void *ptr) +swap_bytes (void *ptr) { for (int i = 0; i < n/2; i++) swap_bytes (ptr, i, n-1-i); @@ -46,20 +43,20 @@ template <> inline void -swap_bytes <1> (volatile void *) +swap_bytes<1> (void *) { } template <> inline void -swap_bytes <2> (volatile void *ptr) +swap_bytes<2> (void *ptr) { swap_bytes (ptr, 0, 1); } template <> inline void -swap_bytes <4> (volatile void *ptr) +swap_bytes<4> (void *ptr) { swap_bytes (ptr, 0, 3); swap_bytes (ptr, 1, 2); @@ -67,7 +64,7 @@ template <> inline void -swap_bytes <8> (volatile void *ptr) +swap_bytes<8> (void *ptr) { swap_bytes (ptr, 0, 7); swap_bytes (ptr, 1, 6); @@ -77,9 +74,9 @@ template void -swap_bytes (volatile void *ptr, int len) +swap_bytes (void *ptr, int len) { - volatile char *t = static_cast (ptr); + char *t = static_cast (ptr); for (int i = 0; i < len; i++) { @@ -90,7 +87,7 @@ template <> inline void -swap_bytes<1> (volatile void *, int) +swap_bytes<1> (void *, int) { } diff -r 20d1b911b4e7 -r c702371ff6df liboctave/util/cmd-hist.cc --- a/liboctave/util/cmd-hist.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/util/cmd-hist.cc Sat Oct 05 11:22:09 2013 -0400 @@ -65,7 +65,7 @@ std::string do_histcontrol (void) const; - void do_add (const std::string&); + bool do_add (const std::string&); void do_remove (int); @@ -184,14 +184,14 @@ return retval; } -void +bool gnu_history::do_add (const std::string& s) { if (! do_ignoring_entries ()) { if (s.empty () || (s.length () == 1 && (s[0] == '\r' || s[0] == '\n'))) - return; + return false; // Strip newline before adding to list std::string stmp = s; @@ -199,8 +199,11 @@ if (stmp[stmp_len - 1] == '\n') stmp.resize (stmp_len - 1); - lines_this_session += ::octave_add_history (stmp.c_str (), history_control); + int added = ::octave_add_history (stmp.c_str (), history_control); + lines_this_session += added; + return (added > 0) ? true : false; } + return false; } void @@ -587,11 +590,12 @@ ? instance->do_ignoring_entries () : false; } -void +bool command_history::add (const std::string& s) { if (instance_ok ()) - instance->do_add (s); + return instance->do_add (s); + return false; } void @@ -818,9 +822,10 @@ return ignoring_additions; } -void +bool command_history::do_add (const std::string&) { + return false; } void diff -r 20d1b911b4e7 -r c702371ff6df liboctave/util/cmd-hist.h --- a/liboctave/util/cmd-hist.h Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/util/cmd-hist.h Sat Oct 05 11:22:09 2013 -0400 @@ -61,7 +61,7 @@ static bool ignoring_entries (void); - static void add (const std::string&); + static bool add (const std::string&); static void remove (int); @@ -156,7 +156,7 @@ virtual bool do_ignoring_entries (void) const; - virtual void do_add (const std::string&); + virtual bool do_add (const std::string&); virtual void do_remove (int); diff -r 20d1b911b4e7 -r c702371ff6df liboctave/util/data-conv.cc --- a/liboctave/util/data-conv.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/util/data-conv.cc Sat Oct 05 11:22:09 2013 -0400 @@ -25,10 +25,10 @@ #endif #include -#include #include #include +#include #include #include "byte-swap.h" @@ -37,15 +37,11 @@ #include "lo-ieee.h" #include "oct-locbuf.h" -template void swap_bytes<2> (volatile void *, int); -template void swap_bytes<4> (volatile void *, int); -template void swap_bytes<8> (volatile void *, int); - #if defined HAVE_LONG_LONG_INT #define FIND_SIZED_INT_TYPE(VAL, BITS, TQ, Q) \ do \ { \ - int sz = BITS / CHAR_BIT; \ + int sz = BITS / std::numeric_limits::digits; \ if (sizeof (TQ char) == sz) \ VAL = oct_data_conv::dt_ ## Q ## char; \ else if (sizeof (TQ short) == sz) \ @@ -64,7 +60,7 @@ #define FIND_SIZED_INT_TYPE(VAL, BITS, TQ, Q) \ do \ { \ - int sz = BITS / CHAR_BIT; \ + int sz = BITS / std::numeric_limits::digits; \ if (sizeof (TQ char) == sz) \ VAL = oct_data_conv::dt_ ## Q ## char; \ else if (sizeof (TQ short) == sz) \ @@ -82,7 +78,7 @@ #define FIND_SIZED_FLOAT_TYPE(VAL, BITS) \ do \ { \ - int sz = BITS / CHAR_BIT; \ + int sz = BITS / std::numeric_limits::digits; \ if (sizeof (float) == sz) \ VAL = oct_data_conv::dt_float; \ else if (sizeof (double) == sz) \ @@ -94,8 +90,9 @@ // I'm not sure it is worth the trouble, but let's use a lookup table // for the types that are supposed to be a specific number of bits -// wide. Given the macros above, this should work as long as CHAR_BIT -// is a multiple of 8 and there are types with the right sizes. +// wide. Given the macros above, this should work as long as +// std::numeric_limits::digits is a multiple of 8 and +// there are types with the right sizes. // // The sized data type lookup table has the following format: // @@ -177,6 +174,111 @@ } \ while (0) +size_t +oct_data_conv::data_type_size (data_type dt) +{ + size_t retval = -1; + + switch (dt) + { + case oct_data_conv::dt_int8: + retval = sizeof (int8_t); + break; + + case oct_data_conv::dt_uint8: + retval = sizeof (uint8_t); + break; + + case oct_data_conv::dt_int16: + retval = sizeof (int16_t); + break; + + case oct_data_conv::dt_uint16: + retval = sizeof (uint16_t); + break; + + case oct_data_conv::dt_int32: + retval = sizeof (int32_t); + break; + + case oct_data_conv::dt_uint32: + retval = sizeof (uint32_t); + break; + + case oct_data_conv::dt_int64: + retval = sizeof (int64_t); + break; + + case oct_data_conv::dt_uint64: + retval = sizeof (uint64_t); + break; + + case oct_data_conv::dt_float: + case oct_data_conv::dt_single: + retval = sizeof (float); + break; + + case oct_data_conv::dt_double: + retval = sizeof (double); + break; + + case oct_data_conv::dt_char: + retval = sizeof (char); + break; + + case oct_data_conv::dt_schar: + retval = sizeof (signed char); + break; + + case oct_data_conv::dt_uchar: + retval = sizeof (unsigned char); + break; + + case oct_data_conv::dt_short: + retval = sizeof (short); + break; + + case oct_data_conv::dt_ushort: + retval = sizeof (unsigned short); + break; + + case oct_data_conv::dt_int: + retval = sizeof (int); + break; + + case oct_data_conv::dt_uint: + retval = sizeof (unsigned int); + break; + + case oct_data_conv::dt_long: + retval = sizeof (long); + break; + + case oct_data_conv::dt_ulong: + retval = sizeof (unsigned long); + break; + + case oct_data_conv::dt_longlong: + retval = sizeof (long long); + break; + + case oct_data_conv::dt_ulonglong: + retval = sizeof (unsigned long long); + break; + + case oct_data_conv::dt_logical: + retval = sizeof (bool); + break; + + case oct_data_conv::dt_unknown: + default: + abort (); + break; + } + + return retval; +} + oct_data_conv::data_type oct_data_conv::string_to_data_type (const std::string& str) { @@ -429,7 +531,7 @@ break; case oct_data_conv::dt_uchar: - retval = "usigned char"; + retval = "unsigned char"; break; case oct_data_conv::dt_short: @@ -445,7 +547,7 @@ break; case oct_data_conv::dt_uint: - retval = "usigned int"; + retval = "unsigned int"; break; case oct_data_conv::dt_long: @@ -453,7 +555,7 @@ break; case oct_data_conv::dt_ulong: - retval = "usigned long"; + retval = "unsigned long"; break; case oct_data_conv::dt_longlong: @@ -548,191 +650,23 @@ } static void -VAX_D_double_to_IEEE_little_double (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("VAX D float", "IEEE little endian format"); -} - -static void -VAX_G_double_to_IEEE_little_double (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("VAX G float", "IEEE little endian format"); -} - -static void -Cray_to_IEEE_little_double (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("Cray", "IEEE little endian format"); -} - -static void IEEE_big_float_to_IEEE_little_float (void *d, octave_idx_type len) { swap_bytes<4> (d, len); } static void -VAX_D_float_to_IEEE_little_float (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("VAX D float", "IEEE little endian format"); -} - -static void -VAX_G_float_to_IEEE_little_float (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("VAX G float", "IEEE little endian format"); -} - -static void -Cray_to_IEEE_little_float (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("Cray", "IEEE little endian format"); -} - -static void IEEE_little_double_to_IEEE_big_double (void *d, octave_idx_type len) { swap_bytes<8> (d, len); } static void -VAX_D_double_to_IEEE_big_double (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("VAX D float", "IEEE big endian format"); -} - -static void -VAX_G_double_to_IEEE_big_double (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("VAX G float", "IEEE big endian format"); -} - -static void -Cray_to_IEEE_big_double (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("Cray", "IEEE big endian format"); -} - -static void IEEE_little_float_to_IEEE_big_float (void *d, octave_idx_type len) { swap_bytes<4> (d, len); } -static void -VAX_D_float_to_IEEE_big_float (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("VAX D float", "IEEE big endian format"); -} - -static void -VAX_G_float_to_IEEE_big_float (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("VAX G float", "IEEE big endian format"); -} - -static void -Cray_to_IEEE_big_float (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("Cray", "IEEE big endian format"); -} - -static void -IEEE_little_double_to_VAX_D_double (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("IEEE little endian", "VAX D"); -} - -static void -IEEE_big_double_to_VAX_D_double (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("IEEE big endian", "VAX D"); -} - -static void -VAX_G_double_to_VAX_D_double (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("VAX G float", "VAX D"); -} - -static void -Cray_to_VAX_D_double (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("Cray", "VAX D"); -} - -static void -IEEE_little_float_to_VAX_D_float (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("IEEE little endian", "VAX D"); -} - -static void -IEEE_big_float_to_VAX_D_float (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("IEEE big endian", "VAX D"); -} - -static void -VAX_G_float_to_VAX_D_float (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("VAX G float", "VAX D"); -} - -static void -Cray_to_VAX_D_float (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("Cray", "VAX D"); -} - -static void -IEEE_little_double_to_VAX_G_double (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("IEEE little endian", "VAX G"); -} - -static void -IEEE_big_double_to_VAX_G_double (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("IEEE big endian", "VAX G"); -} - -static void -VAX_D_double_to_VAX_G_double (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("VAX D float", "VAX G"); -} - -static void -Cray_to_VAX_G_double (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("VAX G float", "VAX G"); -} - -static void -IEEE_little_float_to_VAX_G_float (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("IEEE little endian", "VAX G"); -} - -static void -IEEE_big_float_to_VAX_G_float (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("IEEE big endian", "VAX G"); -} - -static void -VAX_D_float_to_VAX_G_float (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("VAX D float", "VAX G"); -} - -static void -Cray_to_VAX_G_float (void * /* d */, octave_idx_type /* len */) -{ - gripe_data_conversion ("VAX G float", "VAX G"); -} - void do_double_format_conversion (void *data, octave_idx_type len, oct_mach_info::float_format from_fmt, @@ -750,18 +684,6 @@ IEEE_big_double_to_IEEE_little_double (data, len); break; - case oct_mach_info::flt_fmt_vax_d: - VAX_D_double_to_IEEE_little_double (data, len); - break; - - case oct_mach_info::flt_fmt_vax_g: - VAX_G_double_to_IEEE_little_double (data, len); - break; - - case oct_mach_info::flt_fmt_cray: - Cray_to_IEEE_little_double (data, len); - break; - default: gripe_unrecognized_float_fmt (); break; @@ -778,74 +700,6 @@ case oct_mach_info::flt_fmt_ieee_big_endian: break; - case oct_mach_info::flt_fmt_vax_d: - VAX_D_double_to_IEEE_big_double (data, len); - break; - - case oct_mach_info::flt_fmt_vax_g: - VAX_G_double_to_IEEE_big_double (data, len); - break; - - case oct_mach_info::flt_fmt_cray: - Cray_to_IEEE_big_double (data, len); - break; - - default: - gripe_unrecognized_float_fmt (); - break; - } - break; - - case oct_mach_info::flt_fmt_vax_d: - switch (from_fmt) - { - case oct_mach_info::flt_fmt_ieee_little_endian: - IEEE_little_double_to_VAX_D_double (data, len); - break; - - case oct_mach_info::flt_fmt_ieee_big_endian: - IEEE_big_double_to_VAX_D_double (data, len); - break; - - case oct_mach_info::flt_fmt_vax_d: - break; - - case oct_mach_info::flt_fmt_vax_g: - VAX_G_double_to_VAX_D_double (data, len); - break; - - case oct_mach_info::flt_fmt_cray: - Cray_to_VAX_D_double (data, len); - break; - - default: - gripe_unrecognized_float_fmt (); - break; - } - break; - - case oct_mach_info::flt_fmt_vax_g: - switch (from_fmt) - { - case oct_mach_info::flt_fmt_ieee_little_endian: - IEEE_little_double_to_VAX_G_double (data, len); - break; - - case oct_mach_info::flt_fmt_ieee_big_endian: - IEEE_big_double_to_VAX_G_double (data, len); - break; - - case oct_mach_info::flt_fmt_vax_d: - VAX_D_double_to_VAX_G_double (data, len); - break; - - case oct_mach_info::flt_fmt_vax_g: - break; - - case oct_mach_info::flt_fmt_cray: - Cray_to_VAX_G_double (data, len); - break; - default: gripe_unrecognized_float_fmt (); break; @@ -877,18 +731,6 @@ IEEE_big_float_to_IEEE_little_float (data, len); break; - case oct_mach_info::flt_fmt_vax_d: - VAX_D_float_to_IEEE_little_float (data, len); - break; - - case oct_mach_info::flt_fmt_vax_g: - VAX_G_float_to_IEEE_little_float (data, len); - break; - - case oct_mach_info::flt_fmt_cray: - Cray_to_IEEE_little_float (data, len); - break; - default: gripe_unrecognized_float_fmt (); break; @@ -905,74 +747,6 @@ case oct_mach_info::flt_fmt_ieee_big_endian: break; - case oct_mach_info::flt_fmt_vax_d: - VAX_D_float_to_IEEE_big_float (data, len); - break; - - case oct_mach_info::flt_fmt_vax_g: - VAX_G_float_to_IEEE_big_float (data, len); - break; - - case oct_mach_info::flt_fmt_cray: - Cray_to_IEEE_big_float (data, len); - break; - - default: - gripe_unrecognized_float_fmt (); - break; - } - break; - - case oct_mach_info::flt_fmt_vax_d: - switch (from_fmt) - { - case oct_mach_info::flt_fmt_ieee_little_endian: - IEEE_little_float_to_VAX_D_float (data, len); - break; - - case oct_mach_info::flt_fmt_ieee_big_endian: - IEEE_big_float_to_VAX_D_float (data, len); - break; - - case oct_mach_info::flt_fmt_vax_d: - break; - - case oct_mach_info::flt_fmt_vax_g: - VAX_G_float_to_VAX_D_float (data, len); - break; - - case oct_mach_info::flt_fmt_cray: - Cray_to_VAX_D_float (data, len); - break; - - default: - gripe_unrecognized_float_fmt (); - break; - } - break; - - case oct_mach_info::flt_fmt_vax_g: - switch (from_fmt) - { - case oct_mach_info::flt_fmt_ieee_little_endian: - IEEE_little_float_to_VAX_G_float (data, len); - break; - - case oct_mach_info::flt_fmt_ieee_big_endian: - IEEE_big_float_to_VAX_G_float (data, len); - break; - - case oct_mach_info::flt_fmt_vax_d: - VAX_D_float_to_VAX_G_float (data, len); - break; - - case oct_mach_info::flt_fmt_vax_g: - break; - - case oct_mach_info::flt_fmt_cray: - Cray_to_VAX_G_float (data, len); - break; - default: gripe_unrecognized_float_fmt (); break; diff -r 20d1b911b4e7 -r c702371ff6df liboctave/util/data-conv.h --- a/liboctave/util/data-conv.h Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/util/data-conv.h Sat Oct 05 11:22:09 2013 -0400 @@ -26,6 +26,7 @@ #include #include "mach-info.h" +#include "oct-inttypes.h" class OCTAVE_API @@ -61,6 +62,8 @@ dt_unknown = 23 // Must be last, have largest value! }; + static size_t data_type_size (data_type dt); + static data_type string_to_data_type (const std::string& s); static void string_to_data_type (const std::string& s, int& block_size, @@ -125,4 +128,137 @@ write_floats (std::ostream& os, const float *data, save_type type, octave_idx_type len); +template +inline bool +is_equivalent_type (oct_data_conv::data_type) +{ + return false; +} + +template <> +inline bool +is_equivalent_type (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_int8; +} + +template <> +inline bool +is_equivalent_type (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_int16; +} + +template <> +inline bool +is_equivalent_type (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_int32; +} + +template <> +inline bool +is_equivalent_type (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_int64; +} + +template <> +inline bool +is_equivalent_type (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_uint8; +} + +template <> +inline bool +is_equivalent_type (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_uint16; +} + +template <> +inline bool +is_equivalent_type (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_uint32; +} + +template <> +inline bool +is_equivalent_type (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_uint64; +} + +template <> +inline bool +is_equivalent_type (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_int8; +} + +template <> +inline bool +is_equivalent_type (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_int16; +} + +template <> +inline bool +is_equivalent_type (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_int32; +} + +template <> +inline bool +is_equivalent_type (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_int64; +} + +template <> +inline bool +is_equivalent_type (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_uint8; +} + +template <> +inline bool +is_equivalent_type (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_uint16; +} + +template <> +inline bool +is_equivalent_type (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_uint32; +} + +template <> +inline bool +is_equivalent_type (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_uint64; +} + +template <> +inline bool +is_equivalent_type (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_double; +} + +template <> +inline bool +is_equivalent_type (oct_data_conv::data_type t) +{ + return t == oct_data_conv::dt_single || t == oct_data_conv::dt_float; +} + #endif diff -r 20d1b911b4e7 -r c702371ff6df liboctave/util/lo-ieee.cc --- a/liboctave/util/lo-ieee.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/util/lo-ieee.cc Sat Oct 05 11:22:09 2013 -0400 @@ -73,9 +73,6 @@ } break; - case oct_mach_info::flt_fmt_cray: - case oct_mach_info::flt_fmt_vax_d: - case oct_mach_info::flt_fmt_vax_g: default: // If the format is unknown, then you will probably not have a // useful system, so we will abort here. Anyone wishing to diff -r 20d1b911b4e7 -r c702371ff6df liboctave/util/lo-regexp.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/liboctave/util/lo-regexp.cc Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,620 @@ +/* + +Copyright (C) 2012 John W. Eaton +Copyright (C) 2005-2012 David Bateman +Copyright (C) 2002-2005 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 +. + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#if defined (HAVE_PCRE_H) +#include +#elif defined (HAVE_PCRE_PCRE_H) +#include +#endif + +#include "Matrix.h" +#include "base-list.h" +#include "lo-error.h" +#include "oct-locbuf.h" +#include "quit.h" +#include "lo-regexp.h" +#include "str-vec.h" + +// Define the maximum number of retries for a pattern that possibly +// results in an infinite recursion. +#define PCRE_MATCHLIMIT_MAX 10 + +// FIXME -- should this be configurable? +#define MAXLOOKBEHIND 10 + +static bool lookbehind_warned = false; + +// FIXME -- don't bother collecting and composing return values the user +// doesn't want. + +void +regexp::free (void) +{ + if (data) + pcre_free (static_cast (data)); +} + +void +regexp::compile_internal (void) +{ + // If we had a previously compiled pattern, release it. + free (); + + size_t max_length = MAXLOOKBEHIND; + + size_t pos = 0; + size_t new_pos; + int inames = 0; + std::ostringstream buf; + + while ((new_pos = pattern.find ("(?", pos)) != std::string::npos) + { + if (pattern.at (new_pos + 2) == '<' + && !(pattern.at (new_pos + 3) == '=' + || pattern.at (new_pos + 3) == '!')) + { + // The syntax of named tokens in pcre is "(?P...)" while + // we need a syntax "(?...)", so fix that here. Also an + // expression like + // "(?\w+)\s+(?\w+)|(?\w+),\s+(?\w+)" + // should be perfectly legal, while pcre does not allow the same + // named token name on both sides of the alternative. Also fix + // that here by replacing name tokens by dummy names, and dealing + // with the dummy names later. + + size_t tmp_pos = pattern.find_first_of ('>', new_pos); + + if (tmp_pos == std::string::npos) + { + (*current_liboctave_error_handler) + ("regexp: syntax error in pattern"); + return; + } + + std::string tmp_name = + pattern.substr (new_pos+3, tmp_pos-new_pos-3); + + bool found = false; + + for (int i = 0; i < nnames; i++) + { + if (named_pats(i) == tmp_name) + { + named_idx.resize (dim_vector (inames+1, 1)); + named_idx(inames) = i; + found = true; + break; + } + } + + if (! found) + { + named_idx.resize (dim_vector (inames+1, 1)); + named_idx(inames) = nnames; + named_pats.append (tmp_name); + nnames++; + } + + if (new_pos - pos > 0) + buf << pattern.substr (pos, new_pos-pos); + if (inames < 10) + buf << "(?P 0) + { + char ch = pattern.at (tmp_pos1); + + if (ch == '(') + brackets++; + else if (ch == ')') + { + if (brackets > 1) + tmp_pos2 = tmp_pos1; + + brackets--; + } + + tmp_pos1++; + } + + if (brackets != 0) + { + buf << pattern.substr (pos, new_pos - pos) << "(?"; + pos = new_pos + 2; + } + else + { + size_t tmp_pos3 = pattern.find_first_of ("*+", tmp_pos2); + + if (tmp_pos3 != std::string::npos && tmp_pos3 < tmp_pos1) + { + if (!lookbehind_warned) + { + lookbehind_warned = true; + (*current_liboctave_warning_handler) + ("%s: arbitrary length lookbehind patterns are only supported up to length %d", + who.c_str (), MAXLOOKBEHIND); + } + + buf << pattern.substr (pos, new_pos - pos) << "("; + + size_t i; + + if (pattern.at (tmp_pos3) == '*') + i = 0; + else + i = 1; + + for (; i < max_length + 1; i++) + { + buf << pattern.substr (new_pos, tmp_pos3 - new_pos) + << "{" << i << "}"; + buf << pattern.substr (tmp_pos3 + 1, + tmp_pos1 - tmp_pos3 - 1); + if (i != max_length) + buf << "|"; + } + buf << ")"; + } + else + buf << pattern.substr (pos, tmp_pos1 - pos); + + pos = tmp_pos1; + } + } + else + { + buf << pattern.substr (pos, new_pos - pos) << "(?"; + pos = new_pos + 2; + } + + } + + buf << pattern.substr (pos); + + const char *err; + int erroffset; + std::string buf_str = buf.str (); + + int pcre_options + = ((options.case_insensitive () ? PCRE_CASELESS : 0) + | (options.dotexceptnewline () ? 0 : PCRE_DOTALL) + | (options.lineanchors () ? PCRE_MULTILINE : 0) + | (options.freespacing () ? PCRE_EXTENDED : 0)); + + data = pcre_compile (buf_str.c_str (), pcre_options, &err, &erroffset, 0); + + if (! data) + (*current_liboctave_error_handler) + ("%s: %s at position %d of expression", who.c_str (), + err, erroffset); +} + +regexp::match_data +regexp::match (const std::string& buffer) +{ + regexp::match_data retval; + + std::list lst; + + int subpatterns; + int namecount; + int nameentrysize; + char *nametable; + size_t idx = 0; + + pcre *re = static_cast (data); + + pcre_fullinfo (re, 0, PCRE_INFO_CAPTURECOUNT, &subpatterns); + pcre_fullinfo (re, 0, PCRE_INFO_NAMECOUNT, &namecount); + pcre_fullinfo (re, 0, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize); + pcre_fullinfo (re, 0, PCRE_INFO_NAMETABLE, &nametable); + + OCTAVE_LOCAL_BUFFER (int, ovector, (subpatterns+1)*3); + OCTAVE_LOCAL_BUFFER (int, nidx, namecount); + + for (int i = 0; i < namecount; i++) + { + // Index of subpattern in first two bytes MSB first of name. + // Extract index. + nidx[i] = (static_cast (nametable[i*nameentrysize])) << 8 + | static_cast (nametable[i*nameentrysize+1]); + } + + while (true) + { + OCTAVE_QUIT; + + int matches = pcre_exec (re, 0, buffer.c_str (), + buffer.length (), idx, + (idx ? PCRE_NOTBOL : 0), + ovector, (subpatterns+1)*3); + + if (matches == PCRE_ERROR_MATCHLIMIT) + { + // Try harder; start with default value for MATCH_LIMIT + // and increase it. + (*current_liboctave_warning_handler) + ("your pattern caused PCRE to hit its MATCH_LIMIT; trying harder now, but this will be slow"); + + pcre_extra pe; + + pcre_config (PCRE_CONFIG_MATCH_LIMIT, + static_cast (&pe.match_limit)); + + pe.flags = PCRE_EXTRA_MATCH_LIMIT; + + int i = 0; + while (matches == PCRE_ERROR_MATCHLIMIT + && i++ < PCRE_MATCHLIMIT_MAX) + { + OCTAVE_QUIT; + + pe.match_limit *= 10; + matches = pcre_exec (re, &pe, buffer.c_str (), + buffer.length (), idx, + (idx ? PCRE_NOTBOL : 0), + ovector, (subpatterns+1)*3); + } + } + + if (matches < 0 && matches != PCRE_ERROR_NOMATCH) + { + (*current_liboctave_error_handler) + ("%s: internal error calling pcre_exec; error code from pcre_exec is %i", + who.c_str (), matches); + return retval; + } + else if (matches == PCRE_ERROR_NOMATCH) + break; + else if (ovector[1] <= ovector[0] && ! options.emptymatch ()) + { + // Zero length match. Skip to next char. + idx = ovector[0] + 1; + if (idx < buffer.length ()) + continue; + else + break; + } + else + { + int pos_match = 0; + Matrix token_extents (matches-1, 2); + + for (int i = 1; i < matches; i++) + { + if (ovector[2*i] >= 0 && ovector[2*i+1] > 0 + && (i == 1 || ovector[2*i] != ovector[2*i-2] + || ovector[2*i-1] != ovector[2*i+1])) + { + token_extents(pos_match,0) = double (ovector[2*i]+1); + token_extents(pos_match++,1) = double (ovector[2*i+1]); + } + } + + token_extents.resize (pos_match, 2); + + double start = double (ovector[0]+1); + double end = double (ovector[1]); + + const char **listptr; + int status = pcre_get_substring_list (buffer.c_str (), ovector, + matches, &listptr); + + if (status == PCRE_ERROR_NOMEMORY) + { + (*current_liboctave_error_handler) + ("%s: cannot allocate memory in pcre_get_substring_list", + who.c_str ()); + return retval; + } + + string_vector tokens (pos_match); + string_vector named_tokens (nnames); + int pos_offset = 0; + pos_match = 0; + + for (int i = 1; i < matches; i++) + { + if (ovector[2*i] >= 0 && ovector[2*i+1] > 0) + { + if (i == 1 || ovector[2*i] != ovector[2*i-2] + || ovector[2*i-1] != ovector[2*i+1]) + { + if (namecount > 0) + { + // FIXME: Should probably do this with a map() + // rather than a linear search. However, + // the number of captured, named expressions + // is usually pretty small (< 4) + for (int j = 0; j < namecount; j++) + { + if (nidx[j] == i) + { + named_tokens(named_idx(j)) = + std::string (*(listptr+i-pos_offset)); + break; + } + } + } + + tokens(pos_match++) = std::string (*(listptr+i)); + } + else + pos_offset++; + } + } + + std::string match_string = std::string (*listptr); + + pcre_free_substring_list (listptr); + + regexp::match_element new_elem (named_tokens, tokens, match_string, + token_extents, start, end); + lst.push_back (new_elem); + + if (ovector[1] <= ovector[0]) + { + // Zero length match. Skip to next char. + idx = ovector[0] + 1; + if (idx <= buffer.length ()) + continue; + } + else + idx = ovector[1]; + + if (options.once () || idx >= buffer.length ()) + break; + } + } + + retval = regexp::match_data (lst, named_pats); + + return retval; +} + +bool +regexp::is_match (const std::string& buffer) +{ + regexp::match_data rx_lst = match (buffer); + + return rx_lst.size () > 0; +} + +Array +regexp::is_match (const string_vector& buffer) +{ + octave_idx_type len = buffer.length (); + + Array retval (dim_vector (len, 1)); + + for (octave_idx_type i = 0; i < buffer.length (); i++) + retval(i) = is_match (buffer(i)); + + return retval; +} + +// Declare rep_token_t used in processing replacement string +typedef struct + { + size_t pos; + int num; + } rep_token_t; + + +std::string +regexp::replace (const std::string& buffer, const std::string& replacement) +{ + std::string retval; + + regexp::match_data rx_lst = match (buffer); + + size_t num_matches = rx_lst.size (); + + if (num_matches == 0) + { + retval = buffer; + return retval; + } + + // Identify replacement tokens; build a vector of group numbers in + // the replacement string so that we can quickly calculate the size + // of the replacement. + + // FIXME: All code assumes that only 10 tokens ($0-$9) exist. + // $11 represents $1 followed by the character '1' rather than + // the eleventh capture buffer. + + std::string repstr = replacement; + std::vector tokens; + tokens.reserve (5); // Reserve memory for 5 pattern replacements + + for (size_t i=0; i < repstr.size (); i++) + { + if (repstr[i] == '\\') + { + if (i < repstr.size () - 1 && repstr[i+1] == '$') + { + repstr.erase (i,1); // erase backslash + i++; // skip over '$' + continue; + } + if (i < repstr.size () - 1 && repstr[i+1] == '\\') + { + repstr.erase (i,1); // erase 1st backslash + continue; + } + } + else if (repstr[i] == '$') + { + if (i < repstr.size () - 1 && isdigit (repstr[i+1])) + { + rep_token_t tmp_token; + + tmp_token.pos = i; + tmp_token.num = repstr[i+1]-'0'; + tokens.push_back (tmp_token); + } + } + } + + std::string rep; + int num_tokens = tokens.size (); + + if (num_tokens > 0) + { + // Determine replacement length + const size_t replen = repstr.size () - 2*num_tokens; + int delta = 0; + regexp::match_data::const_iterator p = rx_lst.begin (); + for (size_t i = 0; i < num_matches; i++) + { + OCTAVE_QUIT; + + double start = p->start (); + double end = p->end (); + + const Matrix pairs (p->token_extents ()); + size_t pairlen = 0; + for (int j = 0; j < num_tokens; j++) + { + if (tokens[j].num == 0) + pairlen += static_cast (end - start) + 1; + else if (tokens[j].num <= pairs.rows ()) + pairlen += static_cast (pairs(tokens[j].num-1,1) + - pairs(tokens[j].num-1,0)) + 1; + } + delta += (static_cast (replen + pairlen) + - static_cast (end - start + 1)); + p++; + } + + // Build replacement string + rep.reserve (buffer.size () + delta); + size_t from = 0; + p = rx_lst.begin (); + for (size_t i = 0; i < num_matches; i++) + { + OCTAVE_QUIT; + + double start = p->start (); + double end = p->end (); + + const Matrix pairs (p->token_extents ()); + rep.append (&buffer[from], static_cast (start - 1) - from); + from = static_cast (end); + + size_t cur_pos = 0; + + for (int j = 0; j < num_tokens; j++) + { + rep.append (&repstr[cur_pos], (tokens[j].pos) - cur_pos); + cur_pos = tokens[j].pos+2; + + int k = tokens[j].num; + if (k == 0) + { + // replace with entire match + rep.append (&buffer[static_cast (end - 1)], + static_cast (end - start) + 1); + } + else if (k <= pairs.rows ()) + { + // replace with group capture + rep.append (&buffer[static_cast (pairs(k-1,0)-1)], + static_cast (pairs(k-1,1) + - pairs(k-1,0)) + 1); + } + else + { + // replace with nothing + } + } + if (cur_pos < repstr.size ()) + rep.append (&repstr[cur_pos], repstr.size () - cur_pos); + + p++; + } + rep.append (&buffer[from], buffer.size () - from); + } + else + { + // Determine repstr length + const size_t replen = repstr.size (); + int delta = 0; + regexp::match_data::const_iterator p = rx_lst.begin (); + for (size_t i = 0; i < num_matches; i++) + { + OCTAVE_QUIT; + delta += static_cast (replen) + - static_cast (p->end () - p->start () + 1); + p++; + } + + // Build replacement string + rep.reserve (buffer.size () + delta); + size_t from = 0; + p = rx_lst.begin (); + for (size_t i = 0; i < num_matches; i++) + { + OCTAVE_QUIT; + rep.append (&buffer[from], + static_cast (p->start () - 1) - from); + from = static_cast (p->end ()); + rep.append (repstr); + p++; + } + rep.append (&buffer[from], buffer.size () - from); + } + + retval = rep; + return retval; +} diff -r 20d1b911b4e7 -r c702371ff6df liboctave/util/lo-regexp.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/liboctave/util/lo-regexp.h Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,289 @@ +/* + +Copyright (C) 2012 John W. Eaton +Copyright (C) 2005-2012 David Bateman + +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 +. + +*/ + +#if !defined (octave_liboctave_regexp_match_h) +#define octave_liboctave_regexp_match_h 1 + +#include +#include +#include + +#include "Array.h" +#include "Matrix.h" +#include "base-list.h" +#include "str-vec.h" + +class +OCTAVE_API +regexp +{ +public: + + class opts; + class match_data; + + regexp (const std::string& pat = "", + const regexp::opts& opt = regexp::opts (), + const std::string& w = "regexp") + : pattern (pat), options (opt), data (0), named_pats (), + nnames (0), named_idx (), who (w) + { + compile_internal (); + } + + regexp (const regexp& rx) + : pattern (rx.pattern), data (rx.data), named_pats (rx.named_pats), + nnames (rx.nnames), named_idx (rx.named_idx) + { } + + regexp& operator = (const regexp& rx) + { + if (this != &rx) + { + pattern = rx.pattern; + data = rx.data; + named_pats = rx.named_pats; + nnames = rx.nnames; + named_idx = rx.named_idx; + } + + return *this; + } + + ~regexp (void) { free (); } + + void compile (const std::string& pat, + const regexp::opts& opt = regexp::opts ()) + { + pattern = pat; + options = opt; + compile_internal (); + } + + match_data match (const std::string& buffer); + + bool is_match (const std::string& buffer); + + Array is_match (const string_vector& buffer); + + std::string replace (const std::string& buffer, + const std::string& replacement); + + class opts + { + public: + + opts (void) + : x_case_insensitive (false), x_dotexceptnewline (false), + x_emptymatch (false), x_freespacing (false), x_lineanchors (false), + x_once (false) { } + + opts (const opts& o) + : x_case_insensitive (o.x_case_insensitive), + x_dotexceptnewline (o.x_dotexceptnewline), + x_emptymatch (o.x_emptymatch), + x_freespacing (o.x_freespacing), + x_lineanchors (o.x_lineanchors), + x_once (o.x_once) + { } + + opts& operator = (const opts& o) + { + if (this != &o) + { + x_case_insensitive = o.x_case_insensitive; + x_dotexceptnewline = o.x_dotexceptnewline; + x_emptymatch = o.x_emptymatch; + x_freespacing = o.x_freespacing; + x_lineanchors = o.x_lineanchors; + x_once = o.x_once; + } + + return *this; + } + + ~opts (void) { } + + void case_insensitive (bool val) { x_case_insensitive = val; } + void dotexceptnewline (bool val) { x_dotexceptnewline = val; } + void emptymatch (bool val) { x_emptymatch = val; } + void freespacing (bool val) { x_freespacing = val; } + void lineanchors (bool val) { x_lineanchors = val; } + void once (bool val) { x_once = val; } + + bool case_insensitive (void) const { return x_case_insensitive; } + bool dotexceptnewline (void) const { return x_dotexceptnewline; } + bool emptymatch (void) const { return x_emptymatch; } + bool freespacing (void) const { return x_freespacing; } + bool lineanchors (void) const { return x_lineanchors; } + bool once (void) const { return x_once; } + + private: + + bool x_case_insensitive; + bool x_dotexceptnewline; + bool x_emptymatch; + bool x_freespacing; + bool x_lineanchors; + bool x_once; + }; + + class match_element + { + public: + + match_element (const string_vector& nt, const string_vector& t, + const std::string& ms, const Matrix& te, + double s, double e) + : x_match_string (ms), x_named_tokens (nt), x_tokens (t), + x_token_extents (te), x_start (s), x_end (e) + { } + + match_element (const match_element &a) + : x_match_string (a.x_match_string), + x_named_tokens (a.x_named_tokens), x_tokens (a.x_tokens), + x_token_extents (a.x_token_extents), + x_start (a.x_start), x_end (a.x_end) + { } + + std::string match_string (void) const { return x_match_string; } + string_vector named_tokens (void) const { return x_named_tokens; } + string_vector tokens (void) const { return x_tokens; } + Matrix token_extents (void) const { return x_token_extents; } + double start (void) const { return x_start; } + double end (void) const { return x_end; } + + private: + + std::string x_match_string; + string_vector x_named_tokens; + string_vector x_tokens; + Matrix x_token_extents; + double x_start; + double x_end; + }; + + class match_data : public octave_base_list + { + public: + + match_data (void) + : octave_base_list (), named_pats () + { } + + match_data (const std::list& l, const string_vector& np) + : octave_base_list (l), named_pats (np) + { } + + match_data (const match_data& rx_lst) + : octave_base_list (rx_lst), + named_pats (rx_lst.named_pats) + { } + + match_data& operator = (const match_data& rx_lst) + { + if (this != &rx_lst) + { + octave_base_list::operator = (rx_lst); + named_pats = rx_lst.named_pats; + } + + return *this; + } + + ~match_data (void) { } + + string_vector named_patterns (void) { return named_pats; } + + private: + + string_vector named_pats; + }; + +private: + + // The pattern we've been asked to match. + std::string pattern; + + opts options; + + // Internal data describing the regular expression. + void *data; + + std::string m; + string_vector named_pats; + int nnames; + Array named_idx; + std::string who; + + void free (void); + + void compile_internal (void); +}; + +inline regexp::match_data +regexp_match (const std::string& pat, + const std::string& buffer, + const regexp::opts& opt = regexp::opts (), + const std::string& who = "regexp") +{ + regexp rx (pat, opt, who); + + return rx.match (buffer); +} + +inline bool +is_regexp_match (const std::string& pat, + const std::string& buffer, + const regexp::opts& opt = regexp::opts (), + const std::string& who = "regexp") +{ + regexp rx (pat, opt, who); + + return rx.is_match (buffer); +} + +inline Array +is_regexp_match (const std::string& pat, + const string_vector& buffer, + const regexp::opts& opt = regexp::opts (), + const std::string& who = "regexp") +{ + regexp rx (pat, opt, who); + + return rx.is_match (buffer); +} + +inline std::string +regexp_replace (const std::string& pat, + const std::string& buffer, + const std::string& replacement, + const regexp::opts& opt = regexp::opts (), + const std::string& who = "regexp") +{ + regexp rx (pat, opt, who); + + return rx.replace (buffer, replacement); +} + +#endif diff -r 20d1b911b4e7 -r c702371ff6df liboctave/util/lo-utils.cc --- a/liboctave/util/lo-utils.cc Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/util/lo-utils.cc Sat Oct 05 11:22:09 2013 -0400 @@ -55,8 +55,7 @@ bool xtoo_large_for_float (double x) { - return (! (xisnan (x) || xisinf (x)) - && fabs (x) > std::numeric_limits::max ()); + return (xfinite (x) && fabs (x) > std::numeric_limits::max ()); } bool xtoo_large_for_float (const Complex& x) diff -r 20d1b911b4e7 -r c702371ff6df liboctave/util/module.mk --- a/liboctave/util/module.mk Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/util/module.mk Sat Oct 05 11:22:09 2013 -0400 @@ -2,6 +2,7 @@ util/module.mk UTIL_INC = \ + util/action-container.h \ util/base-list.h \ util/byte-swap.h \ util/caseless-str.h \ @@ -34,13 +35,15 @@ util/oct-sort.h \ util/oct-sparse.h \ util/pathsearch.h \ - util/regexp.h \ + util/lo-regexp.h \ util/singleton-cleanup.h \ util/sparse-sort.h \ util/sparse-util.h \ util/statdefs.h \ util/str-vec.h \ - util/sun-utils.h + util/sun-utils.h \ + util/unwind-prot.h \ + util/url-transfer.h UTIL_C_SRC = \ util/f2c-main.c \ @@ -66,11 +69,13 @@ util/oct-mutex.cc \ util/oct-shlib.cc \ util/pathsearch.cc \ - util/regexp.cc \ + util/lo-regexp.cc \ util/singleton-cleanup.cc \ util/sparse-sort.cc \ util/sparse-util.cc \ util/str-vec.cc \ + util/unwind-prot.cc \ + util/url-transfer.cc \ $(UTIL_C_SRC) TEMPLATE_SRC += \ diff -r 20d1b911b4e7 -r c702371ff6df liboctave/util/oct-rl-hist.c --- a/liboctave/util/oct-rl-hist.c Thu Sep 12 21:08:07 2013 -0400 +++ b/liboctave/util/oct-rl-hist.c Sat Oct 05 11:22:09 2013 -0400 @@ -289,12 +289,10 @@ char *tmp = malloc (len + 64); if (number_lines) - sprintf (tmp, "%5d%c%s", i + history_base, - hlist[i]->data ? '*' : ' ', + sprintf (tmp, "%5d %s", i + history_base, line ? line : ""); else - sprintf (tmp, "%c%s", hlist[i]->data ? '*' : ' ', - line ? line : ""); + strcpy (tmp, line ? line : ""); retval[k++] = tmp; } diff -r 20d1b911b4e7 -r c702371ff6df liboctave/util/regexp.cc --- a/liboctave/util/regexp.cc Thu Sep 12 21:08:07 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,620 +0,0 @@ -/* - -Copyright (C) 2012 John W. Eaton -Copyright (C) 2005-2012 David Bateman -Copyright (C) 2002-2005 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 -. - -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#if defined (HAVE_PCRE_H) -#include -#elif defined (HAVE_PCRE_PCRE_H) -#include -#endif - -#include "Matrix.h" -#include "base-list.h" -#include "lo-error.h" -#include "oct-locbuf.h" -#include "quit.h" -#include "regexp.h" -#include "str-vec.h" - -// Define the maximum number of retries for a pattern that possibly -// results in an infinite recursion. -#define PCRE_MATCHLIMIT_MAX 10 - -// FIXME -- should this be configurable? -#define MAXLOOKBEHIND 10 - -static bool lookbehind_warned = false; - -// FIXME -- don't bother collecting and composing return values the user -// doesn't want. - -void -regexp::free (void) -{ - if (data) - pcre_free (static_cast (data)); -} - -void -regexp::compile_internal (void) -{ - // If we had a previously compiled pattern, release it. - free (); - - size_t max_length = MAXLOOKBEHIND; - - size_t pos = 0; - size_t new_pos; - int inames = 0; - std::ostringstream buf; - - while ((new_pos = pattern.find ("(?", pos)) != std::string::npos) - { - if (pattern.at (new_pos + 2) == '<' - && !(pattern.at (new_pos + 3) == '=' - || pattern.at (new_pos + 3) == '!')) - { - // The syntax of named tokens in pcre is "(?P...)" while - // we need a syntax "(?...)", so fix that here. Also an - // expression like - // "(?\w+)\s+(?\w+)|(?\w+),\s+(?\w+)" - // should be perfectly legal, while pcre does not allow the same - // named token name on both sides of the alternative. Also fix - // that here by replacing name tokens by dummy names, and dealing - // with the dummy names later. - - size_t tmp_pos = pattern.find_first_of ('>', new_pos); - - if (tmp_pos == std::string::npos) - { - (*current_liboctave_error_handler) - ("regexp: syntax error in pattern"); - return; - } - - std::string tmp_name = - pattern.substr (new_pos+3, tmp_pos-new_pos-3); - - bool found = false; - - for (int i = 0; i < nnames; i++) - { - if (named_pats(i) == tmp_name) - { - named_idx.resize (dim_vector (inames+1, 1)); - named_idx(inames) = i; - found = true; - break; - } - } - - if (! found) - { - named_idx.resize (dim_vector (inames+1, 1)); - named_idx(inames) = nnames; - named_pats.append (tmp_name); - nnames++; - } - - if (new_pos - pos > 0) - buf << pattern.substr (pos, new_pos-pos); - if (inames < 10) - buf << "(?P 0) - { - char ch = pattern.at (tmp_pos1); - - if (ch == '(') - brackets++; - else if (ch == ')') - { - if (brackets > 1) - tmp_pos2 = tmp_pos1; - - brackets--; - } - - tmp_pos1++; - } - - if (brackets != 0) - { - buf << pattern.substr (pos, new_pos - pos) << "(?"; - pos = new_pos + 2; - } - else - { - size_t tmp_pos3 = pattern.find_first_of ("*+", tmp_pos2); - - if (tmp_pos3 != std::string::npos && tmp_pos3 < tmp_pos1) - { - if (!lookbehind_warned) - { - lookbehind_warned = true; - (*current_liboctave_warning_handler) - ("%s: arbitrary length lookbehind patterns are only supported up to length %d", - who.c_str (), MAXLOOKBEHIND); - } - - buf << pattern.substr (pos, new_pos - pos) << "("; - - size_t i; - - if (pattern.at (tmp_pos3) == '*') - i = 0; - else - i = 1; - - for (; i < max_length + 1; i++) - { - buf << pattern.substr (new_pos, tmp_pos3 - new_pos) - << "{" << i << "}"; - buf << pattern.substr (tmp_pos3 + 1, - tmp_pos1 - tmp_pos3 - 1); - if (i != max_length) - buf << "|"; - } - buf << ")"; - } - else - buf << pattern.substr (pos, tmp_pos1 - pos); - - pos = tmp_pos1; - } - } - else - { - buf << pattern.substr (pos, new_pos - pos) << "(?"; - pos = new_pos + 2; - } - - } - - buf << pattern.substr (pos); - - const char *err; - int erroffset; - std::string buf_str = buf.str (); - - int pcre_options - = ((options.case_insensitive () ? PCRE_CASELESS : 0) - | (options.dotexceptnewline () ? 0 : PCRE_DOTALL) - | (options.lineanchors () ? PCRE_MULTILINE : 0) - | (options.freespacing () ? PCRE_EXTENDED : 0)); - - data = pcre_compile (buf_str.c_str (), pcre_options, &err, &erroffset, 0); - - if (! data) - (*current_liboctave_error_handler) - ("%s: %s at position %d of expression", who.c_str (), - err, erroffset); -} - -regexp::match_data -regexp::match (const std::string& buffer) -{ - regexp::match_data retval; - - std::list lst; - - int subpatterns; - int namecount; - int nameentrysize; - char *nametable; - size_t idx = 0; - - pcre *re = static_cast (data); - - pcre_fullinfo (re, 0, PCRE_INFO_CAPTURECOUNT, &subpatterns); - pcre_fullinfo (re, 0, PCRE_INFO_NAMECOUNT, &namecount); - pcre_fullinfo (re, 0, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize); - pcre_fullinfo (re, 0, PCRE_INFO_NAMETABLE, &nametable); - - OCTAVE_LOCAL_BUFFER (int, ovector, (subpatterns+1)*3); - OCTAVE_LOCAL_BUFFER (int, nidx, namecount); - - for (int i = 0; i < namecount; i++) - { - // Index of subpattern in first two bytes MSB first of name. - // Extract index. - nidx[i] = (static_cast (nametable[i*nameentrysize])) << 8 - | static_cast (nametable[i*nameentrysize+1]); - } - - while (true) - { - OCTAVE_QUIT; - - int matches = pcre_exec (re, 0, buffer.c_str (), - buffer.length (), idx, - (idx ? PCRE_NOTBOL : 0), - ovector, (subpatterns+1)*3); - - if (matches == PCRE_ERROR_MATCHLIMIT) - { - // Try harder; start with default value for MATCH_LIMIT - // and increase it. - (*current_liboctave_warning_handler) - ("your pattern caused PCRE to hit its MATCH_LIMIT; trying harder now, but this will be slow"); - - pcre_extra pe; - - pcre_config (PCRE_CONFIG_MATCH_LIMIT, - static_cast (&pe.match_limit)); - - pe.flags = PCRE_EXTRA_MATCH_LIMIT; - - int i = 0; - while (matches == PCRE_ERROR_MATCHLIMIT - && i++ < PCRE_MATCHLIMIT_MAX) - { - OCTAVE_QUIT; - - pe.match_limit *= 10; - matches = pcre_exec (re, &pe, buffer.c_str (), - buffer.length (), idx, - (idx ? PCRE_NOTBOL : 0), - ovector, (subpatterns+1)*3); - } - } - - if (matches < 0 && matches != PCRE_ERROR_NOMATCH) - { - (*current_liboctave_error_handler) - ("%s: internal error calling pcre_exec; error code from pcre_exec is %i", - who.c_str (), matches); - return retval; - } - else if (matches == PCRE_ERROR_NOMATCH) - break; - else if (ovector[1] <= ovector[0] && ! options.emptymatch ()) - { - // Zero length match. Skip to next char. - idx = ovector[0] + 1; - if (idx < buffer.length ()) - continue; - else - break; - } - else - { - int pos_match = 0; - Matrix token_extents (matches-1, 2); - - for (int i = 1; i < matches; i++) - { - if (ovector[2*i] >= 0 && ovector[2*i+1] > 0 - && (i == 1 || ovector[2*i] != ovector[2*i-2] - || ovector[2*i-1] != ovector[2*i+1])) - { - token_extents(pos_match,0) = double (ovector[2*i]+1); - token_extents(pos_match++,1) = double (ovector[2*i+1]); - } - } - - token_extents.resize (pos_match, 2); - - double start = double (ovector[0]+1); - double end = double (ovector[1]); - - const char **listptr; - int status = pcre_get_substring_list (buffer.c_str (), ovector, - matches, &listptr); - - if (status == PCRE_ERROR_NOMEMORY) - { - (*current_liboctave_error_handler) - ("%s: cannot allocate memory in pcre_get_substring_list", - who.c_str ()); - return retval; - } - - string_vector tokens (pos_match); - string_vector named_tokens (nnames); - int pos_offset = 0; - pos_match = 0; - - for (int i = 1; i < matches; i++) - { - if (ovector[2*i] >= 0 && ovector[2*i+1] > 0) - { - if (i == 1 || ovector[2*i] != ovector[2*i-2] - || ovector[2*i-1] != ovector[2*i+1]) - { - if (namecount > 0) - { - // FIXME: Should probably do this with a map() - // rather than a linear search. However, - // the number of captured, named expressions - // is usually pretty small (< 4) - for (int j = 0; j < namecount; j++) - { - if (nidx[j] == i) - { - named_tokens(named_idx(j)) = - std::string (*(listptr+i-pos_offset)); - break; - } - } - } - - tokens(pos_match++) = std::string (*(listptr+i)); - } - else - pos_offset++; - } - } - - std::string match_string = std::string (*listptr); - - pcre_free_substring_list (listptr); - - regexp::match_element new_elem (named_tokens, tokens, match_string, - token_extents, start, end); - lst.push_back (new_elem); - - if (ovector[1] <= ovector[0]) - { - // Zero length match. Skip to next char. - idx = ovector[0] + 1; - if (idx <= buffer.length ()) - continue; - } - else - idx = ovector[1]; - - if (options.once () || idx >= buffer.length ()) - break; - } - } - - retval = regexp::match_data (lst, named_pats); - - return retval; -} - -bool -regexp::is_match (const std::string& buffer) -{ - regexp::match_data rx_lst = match (buffer); - - return rx_lst.size () > 0; -} - -Array -regexp::is_match (const string_vector& buffer) -{ - octave_idx_type len = buffer.length (); - - Array retval (dim_vector (len, 1)); - - for (octave_idx_type i = 0; i < buffer.length (); i++) - retval(i) = is_match (buffer(i)); - - return retval; -} - -// Declare rep_token_t used in processing replacement string -typedef struct - { - size_t pos; - int num; - } rep_token_t; - - -std::string -regexp::replace (const std::string& buffer, const std::string& replacement) -{ - std::string retval; - - regexp::match_data rx_lst = match (buffer); - - size_t num_matches = rx_lst.size (); - - if (num_matches == 0) - { - retval = buffer; - return retval; - } - - // Identify replacement tokens; build a vector of group numbers in - // the replacement string so that we can quickly calculate the size - // of the replacement. - - // FIXME: All code assumes that only 10 tokens ($0-$9) exist. - // $11 represents $1 followed by the character '1' rather than - // the eleventh capture buffer. - - std::string repstr = replacement; - std::vector tokens; - tokens.reserve (5); // Reserve memory for 5 pattern replacements - - for (size_t i=0; i < repstr.size (); i++) - { - if (repstr[i] == '\\') - { - if (i < repstr.size () - 1 && repstr[i+1] == '$') - { - repstr.erase (i,1); // erase backslash - i++; // skip over '$' - continue; - } - if (i < repstr.size () - 1 && repstr[i+1] == '\\') - { - repstr.erase (i,1); // erase 1st backslash - continue; - } - } - else if (repstr[i] == '$') - { - if (i < repstr.size () - 1 && isdigit (repstr[i+1])) - { - rep_token_t tmp_token; - - tmp_token.pos = i; - tmp_token.num = repstr[i+1]-'0'; - tokens.push_back (tmp_token); - } - } - } - - std::string rep; - int num_tokens = tokens.size (); - - if (num_tokens > 0) - { - // Determine replacement length - const size_t replen = repstr.size () - 2*num_tokens; - int delta = 0; - regexp::match_data::const_iterator p = rx_lst.begin (); - for (size_t i = 0; i < num_matches; i++) - { - OCTAVE_QUIT; - - double start = p->start (); - double end = p->end (); - - const Matrix pairs (p->token_extents ()); - size_t pairlen = 0; - for (int j = 0; j < num_tokens; j++) - { - if (tokens[j].num == 0) - pairlen += static_cast (end - start) + 1; - else if (tokens[j].num <= pairs.rows ()) - pairlen += static_cast (pairs(tokens[j].num-1,1) - - pairs(tokens[j].num-1,0)) + 1; - } - delta += (static_cast (replen + pairlen) - - static_cast (end - start + 1)); - p++; - } - - // Build replacement string - rep.reserve (buffer.size () + delta); - size_t from = 0; - p = rx_lst.begin (); - for (size_t i = 0; i < num_matches; i++) - { - OCTAVE_QUIT; - - double start = p->start (); - double end = p->end (); - - const Matrix pairs (p->token_extents ()); - rep.append (&buffer[from], static_cast (start - 1) - from); - from = static_cast (end - 1) + 1; - - size_t cur_pos = 0; - - for (int j = 0; j < num_tokens; j++) - { - rep.append (&repstr[cur_pos], (tokens[j].pos) - cur_pos); - cur_pos = tokens[j].pos+2; - - int k = tokens[j].num; - if (k == 0) - { - // replace with entire match - rep.append (&buffer[static_cast (end - 1)], - static_cast (end - start) + 1); - } - else if (k <= pairs.rows ()) - { - // replace with group capture - rep.append (&buffer[static_cast (pairs(k-1,0)-1)], - static_cast (pairs(k-1,1) - - pairs(k-1,0)) + 1); - } - else - { - // replace with nothing - } - } - if (cur_pos < repstr.size ()) - rep.append (&repstr[cur_pos], repstr.size () - cur_pos); - - p++; - } - rep.append (&buffer[from], buffer.size () - from); - } - else - { - // Determine repstr length - const size_t replen = repstr.size (); - int delta = 0; - regexp::match_data::const_iterator p = rx_lst.begin (); - for (size_t i = 0; i < num_matches; i++) - { - OCTAVE_QUIT; - delta += static_cast (replen) - - static_cast (p->end () - p->start () + 1); - p++; - } - - // Build replacement string - rep.reserve (buffer.size () + delta); - size_t from = 0; - p = rx_lst.begin (); - for (size_t i = 0; i < num_matches; i++) - { - OCTAVE_QUIT; - rep.append (&buffer[from], - static_cast (p->start () - 1) - from); - from = static_cast (p->end () - 1) + 1; - rep.append (repstr); - p++; - } - rep.append (&buffer[from], buffer.size () - from); - } - - retval = rep; - return retval; -} diff -r 20d1b911b4e7 -r c702371ff6df liboctave/util/regexp.h --- a/liboctave/util/regexp.h Thu Sep 12 21:08:07 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,289 +0,0 @@ -/* - -Copyright (C) 2012 John W. Eaton -Copyright (C) 2005-2012 David Bateman - -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 -. - -*/ - -#if !defined (octave_regexp_match_h) -#define octave_regexp_match_h 1 - -#include -#include -#include - -#include "Array.h" -#include "Matrix.h" -#include "base-list.h" -#include "str-vec.h" - -class -OCTAVE_API -regexp -{ -public: - - class opts; - class match_data; - - regexp (const std::string& pat = "", - const regexp::opts& opt = regexp::opts (), - const std::string& w = "regexp") - : pattern (pat), options (opt), data (0), named_pats (), - nnames (0), named_idx (), who (w) - { - compile_internal (); - } - - regexp (const regexp& rx) - : pattern (rx.pattern), data (rx.data), named_pats (rx.named_pats), - nnames (rx.nnames), named_idx (rx.named_idx) - { } - - regexp& operator = (const regexp& rx) - { - if (this != &rx) - { - pattern = rx.pattern; - data = rx.data; - named_pats = rx.named_pats; - nnames = rx.nnames; - named_idx = rx.named_idx; - } - - return *this; - } - - ~regexp (void) { free (); } - - void compile (const std::string& pat, - const regexp::opts& opt = regexp::opts ()) - { - pattern = pat; - options = opt; - compile_internal (); - } - - match_data match (const std::string& buffer); - - bool is_match (const std::string& buffer); - - Array is_match (const string_vector& buffer); - - std::string replace (const std::string& buffer, - const std::string& replacement); - - class opts - { - public: - - opts (void) - : x_case_insensitive (false), x_dotexceptnewline (false), - x_emptymatch (false), x_freespacing (false), x_lineanchors (false), - x_once (false) { } - - opts (const opts& o) - : x_case_insensitive (o.x_case_insensitive), - x_dotexceptnewline (o.x_dotexceptnewline), - x_emptymatch (o.x_emptymatch), - x_freespacing (o.x_freespacing), - x_lineanchors (o.x_lineanchors), - x_once (o.x_once) - { } - - opts& operator = (const opts& o) - { - if (this != &o) - { - x_case_insensitive = o.x_case_insensitive; - x_dotexceptnewline = o.x_dotexceptnewline; - x_emptymatch = o.x_emptymatch; - x_freespacing = o.x_freespacing; - x_lineanchors = o.x_lineanchors; - x_once = o.x_once; - } - - return *this; - } - - ~opts (void) { } - - void case_insensitive (bool val) { x_case_insensitive = val; } - void dotexceptnewline (bool val) { x_dotexceptnewline = val; } - void emptymatch (bool val) { x_emptymatch = val; } - void freespacing (bool val) { x_freespacing = val; } - void lineanchors (bool val) { x_lineanchors = val; } - void once (bool val) { x_once = val; } - - bool case_insensitive (void) const { return x_case_insensitive; } - bool dotexceptnewline (void) const { return x_dotexceptnewline; } - bool emptymatch (void) const { return x_emptymatch; } - bool freespacing (void) const { return x_freespacing; } - bool lineanchors (void) const { return x_lineanchors; } - bool once (void) const { return x_once; } - - private: - - bool x_case_insensitive; - bool x_dotexceptnewline; - bool x_emptymatch; - bool x_freespacing; - bool x_lineanchors; - bool x_once; - }; - - class match_element - { - public: - - match_element (const string_vector& nt, const string_vector& t, - const std::string& ms, const Matrix& te, - double s, double e) - : x_match_string (ms), x_named_tokens (nt), x_tokens (t), - x_token_extents (te), x_start (s), x_end (e) - { } - - match_element (const match_element &a) - : x_match_string (a.x_match_string), - x_named_tokens (a.x_named_tokens), x_tokens (a.x_tokens), - x_token_extents (a.x_token_extents), - x_start (a.x_start), x_end (a.x_end) - { } - - std::string match_string (void) const { return x_match_string; } - string_vector named_tokens (void) const { return x_named_tokens; } - string_vector tokens (void) const { return x_tokens; } - Matrix token_extents (void) const { return x_token_extents; } - double start (void) const { return x_start; } - double end (void) const { return x_end; } - - private: - - std::string x_match_string; - string_vector x_named_tokens; - string_vector x_tokens; - Matrix x_token_extents; - double x_start; - double x_end; - }; - - class match_data : public octave_base_list - { - public: - - match_data (void) - : octave_base_list (), named_pats () - { } - - match_data (const std::list& l, const string_vector& np) - : octave_base_list (l), named_pats (np) - { } - - match_data (const match_data& rx_lst) - : octave_base_list (rx_lst), - named_pats (rx_lst.named_pats) - { } - - match_data& operator = (const match_data& rx_lst) - { - if (this != &rx_lst) - { - octave_base_list::operator = (rx_lst); - named_pats = rx_lst.named_pats; - } - - return *this; - } - - ~match_data (void) { } - - string_vector named_patterns (void) { return named_pats; } - - private: - - string_vector named_pats; - }; - -private: - - // The pattern we've been asked to match. - std::string pattern; - - opts options; - - // Internal data describing the regular expression. - void *data; - - std::string m; - string_vector named_pats; - int nnames; - Array named_idx; - std::string who; - - void free (void); - - void compile_internal (void); -}; - -inline regexp::match_data -regexp_match (const std::string& pat, - const std::string& buffer, - const regexp::opts& opt = regexp::opts (), - const std::string& who = "regexp") -{ - regexp rx (pat, opt, who); - - return rx.match (buffer); -} - -inline bool -is_regexp_match (const std::string& pat, - const std::string& buffer, - const regexp::opts& opt = regexp::opts (), - const std::string& who = "regexp") -{ - regexp rx (pat, opt, who); - - return rx.is_match (buffer); -} - -inline Array -is_regexp_match (const std::string& pat, - const string_vector& buffer, - const regexp::opts& opt = regexp::opts (), - const std::string& who = "regexp") -{ - regexp rx (pat, opt, who); - - return rx.is_match (buffer); -} - -inline std::string -regexp_replace (const std::string& pat, - const std::string& buffer, - const std::string& replacement, - const regexp::opts& opt = regexp::opts (), - const std::string& who = "regexp") -{ - regexp rx (pat, opt, who); - - return rx.replace (buffer, replacement); -} - -#endif diff -r 20d1b911b4e7 -r c702371ff6df liboctave/util/unwind-prot.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/liboctave/util/unwind-prot.cc Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,38 @@ +/* + +Copyright (C) 1993-2012 John W. Eaton +Copyright (C) 2009 VZLU Prague + +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 +. + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "lo-error.h" +#include "unwind-prot.h" + +void +unwind_protect_safe::gripe_exception (void) +{ + // FIXME: can this throw an exception? + + (*current_liboctave_error_handler) + ("internal: unhandled exception in unwind_protect handler"); +} diff -r 20d1b911b4e7 -r c702371ff6df liboctave/util/unwind-prot.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/liboctave/util/unwind-prot.h Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,145 @@ +/* + +Copyright (C) 1993-2012 John W. Eaton +Copyright (C) 2009-2010 VZLU Prague + +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 +. + +*/ + +#if !defined (octave_unwind_prot_h) +#define octave_unwind_prot_h 1 + +#include + +#include +#include + +#include "action-container.h" + +class +OCTINTERP_API +unwind_protect : public action_container +{ +public: + + unwind_protect (void) : lifo () { } + + // Destructor should not raise an exception, so all actions + // registered should be exception-safe (but setting error_state is + // allowed). If you're not sure, see unwind_protect_safe. + + ~unwind_protect (void) { run (); } + + virtual void add (elem *new_elem) + { + lifo.push (new_elem); + } + + void add (void (*fcn) (void *), void *ptr = 0) GCC_ATTR_DEPRECATED + { + add (new fcn_arg_elem (fcn, ptr)); + } + + operator bool (void) const { return ! empty (); } + + void run_top (void) GCC_ATTR_DEPRECATED { run_first (); } + + void run_first (void) + { + if (! empty ()) + { + // No leak on exception! + std::auto_ptr ptr (lifo.top ()); + lifo.pop (); + ptr->run (); + } + } + + void run_top (int num) GCC_ATTR_DEPRECATED { run (num); } + + void discard_top (void) GCC_ATTR_DEPRECATED { discard_first (); } + + void discard_first (void) + { + if (! empty ()) + { + elem *ptr = lifo.top (); + lifo.pop (); + delete ptr; + } + } + + void discard_top (int num) GCC_ATTR_DEPRECATED { discard (num); } + + size_t size (void) const { return lifo.size (); } + +protected: + + std::stack lifo; + +private: + + // No copying! + + unwind_protect (const unwind_protect&); + + unwind_protect& operator = (const unwind_protect&); +}; + +// Like unwind_protect, but this one will guard against the +// possibility of seeing an exception (or interrupt) in the cleanup +// actions. Not that we can do much about it, but at least we won't +// crash. + +class +OCTINTERP_API +unwind_protect_safe : public unwind_protect +{ +private: + + static void gripe_exception (void); + +public: + + unwind_protect_safe (void) : unwind_protect () { } + + ~unwind_protect_safe (void) + { + while (! empty ()) + { + try + { + run_first (); + } + catch (...) // Yes, the black hole. Remember we're in a dtor. + { + gripe_exception (); + } + } + } + +private: + + // No copying! + + unwind_protect_safe (const unwind_protect_safe&); + + unwind_protect_safe& operator = (const unwind_protect_safe&); +}; + +#endif diff -r 20d1b911b4e7 -r c702371ff6df liboctave/util/url-transfer.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/liboctave/util/url-transfer.cc Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,799 @@ +/* + +Copyright (C) 2013 John W. Eaton +Copyright (C) 2006-2012 Alexander Barth +Copyright (C) 2009 David Bateman + +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 +. + +*/ + +// Author: Alexander Barth +// Author: jwe + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include "dir-ops.h" +#include "file-ops.h" +#include "file-stat.h" +#include "unwind-prot.h" +#include "url-transfer.h" + +#ifdef HAVE_CURL +#include +#include +#include +#endif + +void base_url_transfer::delete_file (const std::string& file) +{ + octave_unlink (file); +} + +void +base_url_transfer::mget_directory (const std::string& directory, + const std::string& target) +{ + std::string sep = file_ops::dir_sep_str (); + file_stat fs (directory); + + if (!fs || !fs.is_dir ()) + { + std::string msg; + int status = octave_mkdir (directory, 0777, msg); + + if (status < 0) + { + ok = false; + errmsg = "__ftp_mget__: can not create directory '" + + target + sep + directory + "': " + msg; + return; + } + } + + cwd (directory); + + if (good ()) + { + unwind_protect_safe frame; + + frame.add_fcn (reset_path, this); + + string_vector sv = list (); + + for (octave_idx_type i = 0; i < sv.length (); i++) + { + time_t ftime; + bool fisdir; + double fsize; + + get_fileinfo (sv(i), fsize, ftime, fisdir); + + if (fisdir) + mget_directory (sv(i), target + directory + sep); + else + { + std::string realfile = target + directory + sep + sv(i); + + std::ofstream ofile (realfile.c_str (), + std::ios::out | std::ios::binary); + + if (! ofile.is_open ()) + { + ok = false; + errmsg = "__ftp_mget__: unable to open file"; + break; + } + + unwind_protect_safe frame2; + + frame2.add_fcn (delete_file, realfile); + + get (sv(i), ofile); + + ofile.close (); + + if (good ()) + frame2.discard (); + } + + if (! good ()) + break; + } + } +} + +string_vector +base_url_transfer::mput_directory (const std::string& base, + const std::string& directory) +{ + string_vector file_list; + + std::string realdir + = (base.length () == 0 + ? directory : base + file_ops::dir_sep_str () + directory); + + mkdir (directory); + + if (! good ()) + return file_list; + + cwd (directory); + + if (good ()) + { + unwind_protect_safe frame; + + frame.add_fcn (reset_path, this); + + dir_entry dirlist (realdir); + + if (dirlist) + { + string_vector files = dirlist.read (); + + for (octave_idx_type i = 0; i < files.length (); i++) + { + std::string file = files (i); + + if (file == "." || file == "..") + continue; + + std::string realfile = realdir + file_ops::dir_sep_str () + file; + file_stat fs (realfile); + + if (! fs.exists ()) + { + ok = false; + errmsg = "__ftp__mput: file '" + realfile + + "' does not exist"; + break; + } + + if (fs.is_dir ()) + { + file_list.append (mput_directory (realdir, file)); + + if (! good ()) + break; + } + else + { + // FIXME Does ascii mode need to be flagged here? + std::ifstream ifile (realfile.c_str (), std::ios::in | + std::ios::binary); + + if (! ifile.is_open ()) + { + ok = false; + errmsg = "__ftp_mput__: unable to open file '" + + realfile + "'"; + break; + } + + put (file, ifile); + + ifile.close (); + + if (! good ()) + break; + + file_list.append (realfile); + } + } + } + else + { + ok = false; + errmsg = "__ftp_mput__: can not read the directory '" + + realdir + "'"; + } + } +} + +#if defined (HAVE_CURL) + +static int +write_data (void *buffer, size_t size, size_t nmemb, void *streamp) +{ + std::ostream& stream = *(static_cast (streamp)); + stream.write (static_cast (buffer), size*nmemb); + return (stream.fail () ? 0 : size * nmemb); +} + +static int +read_data (void *buffer, size_t size, size_t nmemb, void *streamp) +{ + std::istream& stream = *(static_cast (streamp)); + stream.read (static_cast (buffer), size*nmemb); + if (stream.eof ()) + return stream.gcount (); + else + return (stream.fail () ? 0 : size * nmemb); +} + +static size_t +throw_away (void *, size_t size, size_t nmemb, void *) +{ + return static_cast(size * nmemb); +} + +// I'd love to rewrite this as a private method of the url_transfer +// class, but you can't pass the va_list from the wrapper SETOPT to +// the curl_easy_setopt function. +#define SETOPT(option, parameter) \ + do \ + { \ + CURLcode res = curl_easy_setopt (curl, option, parameter); \ + if (res != CURLE_OK) \ + { \ + ok = false; \ + errmsg = curl_easy_strerror (res); \ + return; \ + } \ + } \ + while (0) + +// Same as above but with a return value. +#define SETOPTR(option, parameter) \ + do \ + { \ + CURLcode res = curl_easy_setopt (curl, option, parameter); \ + if (res != CURLE_OK) \ + { \ + ok = false; \ + errmsg = curl_easy_strerror (res); \ + return retval; \ + } \ + } \ + while (0) + +class curl_transfer : public base_url_transfer +{ +public: + + curl_transfer (void) + : base_url_transfer (), curl (curl_easy_init ()), errnum () + { + if (curl) + valid = true; + else + errmsg = "can not create curl object"; + } + + curl_transfer (const std::string& host_arg, const std::string& user_arg, + const std::string& passwd, std::ostream& os) + : base_url_transfer (host_arg, user_arg, passwd, os), + curl (curl_easy_init ()), errnum () + { + if (curl) + valid = true; + else + { + errmsg = "can not create curl object"; + return; + } + + init (user_arg, passwd, std::cin, os); + + std::string url ("ftp://" + host_arg); + SETOPT (CURLOPT_URL, url.c_str ()); + + // Setup the link, with no transfer. + perform (); + } + + curl_transfer (const std::string& url, const std::string& method, + const Array& param, std::ostream& os) + : base_url_transfer (url, method, param, os), + curl (curl_easy_init ()), errnum () + { + if (curl) + valid = true; + else + { + errmsg = "can not create curl object"; + return; + } + + init ("", "", std::cin, os); + + SETOPT (CURLOPT_NOBODY, 0); + + // Restore the default HTTP request method to GET after setting + // NOBODY to true and back to false. This is needed for backward + // compatibility with versions of libcurl < 7.18.2. + SETOPT (CURLOPT_HTTPGET, 1); + + // Don't need to store the parameters here as we can't change + // the URL after the object is created + std::string query_string = form_query_string (param); + + if (method == "get") + { + query_string = url + "?" + query_string; + SETOPT (CURLOPT_URL, query_string.c_str ()); + } + else if (method == "post") + { + SETOPT (CURLOPT_URL, url.c_str ()); + SETOPT (CURLOPT_POSTFIELDS, query_string.c_str ()); + } + else + SETOPT (CURLOPT_URL, url.c_str ()); + + perform (); + } + + ~curl_transfer (void) + { + if (curl) + curl_easy_cleanup (curl); + } + + void perform (void) + { + BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; + + errnum = curl_easy_perform (curl); + + if (errnum != CURLE_OK) + { + ok = false; + errmsg = curl_easy_strerror (errnum); + } + + END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; + } + + std::string lasterror (void) const + { + return std::string (curl_easy_strerror (errnum)); + } + + std::ostream& set_ostream (std::ostream& os) + { + std::ostream& retval = *curr_ostream; + curr_ostream = &os; + SETOPTR (CURLOPT_WRITEDATA, static_cast (curr_ostream)); + return retval; + } + + std::istream& set_istream (std::istream& is) + { + std::istream& retval = *curr_istream; + curr_istream = &is; + SETOPTR (CURLOPT_READDATA, static_cast (curr_istream)); + return retval; + } + + void ascii (void) + { + ascii_mode = true; + SETOPT (CURLOPT_TRANSFERTEXT, 1); + } + + void binary (void) + { + ascii_mode = false; + SETOPT (CURLOPT_TRANSFERTEXT, 0); + } + + void cwd (const std::string& path) + { + struct curl_slist *slist = 0; + + unwind_protect frame; + frame.add_fcn (curl_slist_free_all, slist); + + std::string cmd = "cwd " + path; + slist = curl_slist_append (slist, cmd.c_str ()); + SETOPT (CURLOPT_POSTQUOTE, slist); + + perform (); + if (! good ()) + return; + + SETOPT (CURLOPT_POSTQUOTE, 0); + } + + void del (const std::string& file) + { + struct curl_slist *slist = 0; + + unwind_protect frame; + frame.add_fcn (curl_slist_free_all, slist); + + std::string cmd = "dele " + file; + slist = curl_slist_append (slist, cmd.c_str ()); + SETOPT (CURLOPT_POSTQUOTE, slist); + + perform (); + if (! good ()) + return; + + SETOPT (CURLOPT_POSTQUOTE, 0); + } + + void rmdir (const std::string& path) + { + struct curl_slist *slist = 0; + + unwind_protect frame; + frame.add_fcn (curl_slist_free_all, slist); + + std::string cmd = "rmd " + path; + slist = curl_slist_append (slist, cmd.c_str ()); + SETOPT (CURLOPT_POSTQUOTE, slist); + + perform (); + if (! good ()) + return; + + SETOPT (CURLOPT_POSTQUOTE, 0); + } + + void mkdir (const std::string& path) + { + struct curl_slist *slist = 0; + + unwind_protect frame; + frame.add_fcn (curl_slist_free_all, slist); + + std::string cmd = "mkd " + path; + slist = curl_slist_append (slist, cmd.c_str ()); + SETOPT (CURLOPT_POSTQUOTE, slist); + + perform (); + if (! good ()) + return; + + SETOPT (CURLOPT_POSTQUOTE, 0); + } + + void rename (const std::string& oldname, const std::string& newname) + { + struct curl_slist *slist = 0; + + unwind_protect frame; + frame.add_fcn (curl_slist_free_all, slist); + + std::string cmd = "rnfr " + oldname; + slist = curl_slist_append (slist, cmd.c_str ()); + cmd = "rnto " + newname; + slist = curl_slist_append (slist, cmd.c_str ()); + SETOPT (CURLOPT_POSTQUOTE, slist); + + perform (); + if (! good ()) + return; + + SETOPT (CURLOPT_POSTQUOTE, 0); + } + + void put (const std::string& file, std::istream& is) + { + std::string url = "ftp://" + host + "/" + file; + SETOPT (CURLOPT_URL, url.c_str ()); + SETOPT (CURLOPT_UPLOAD, 1); + SETOPT (CURLOPT_NOBODY, 0); + std::istream& old_is = set_istream (is); + + perform (); + if (! good ()) + return; + + set_istream (old_is); + SETOPT (CURLOPT_NOBODY, 1); + SETOPT (CURLOPT_UPLOAD, 0); + url = "ftp://" + host; + SETOPT (CURLOPT_URL, url.c_str ()); + } + + void get (const std::string& file, std::ostream& os) + { + std::string url = "ftp://" + host + "/" + file; + SETOPT (CURLOPT_URL, url.c_str ()); + SETOPT (CURLOPT_NOBODY, 0); + std::ostream& old_os = set_ostream (os); + + perform (); + if (! good ()) + return; + + set_ostream (old_os); + SETOPT (CURLOPT_NOBODY, 1); + url = "ftp://" + host; + SETOPT (CURLOPT_URL, url.c_str ()); + } + + void dir (void) + { + std::string url = "ftp://" + host + "/"; + SETOPT (CURLOPT_URL, url.c_str ()); + SETOPT (CURLOPT_NOBODY, 0); + + perform (); + if (! good ()) + return; + + SETOPT (CURLOPT_NOBODY, 1); + url = "ftp://" + host; + SETOPT (CURLOPT_URL, url.c_str ()); + } + + string_vector list (void) + { + string_vector retval; + + std::ostringstream buf; + std::string url = "ftp://" + host + "/"; + SETOPTR (CURLOPT_WRITEDATA, static_cast (&buf)); + SETOPTR (CURLOPT_URL, url.c_str ()); + SETOPTR (CURLOPT_DIRLISTONLY, 1); + SETOPTR (CURLOPT_NOBODY, 0); + + perform (); + if (! good ()) + return retval; + + SETOPTR (CURLOPT_NOBODY, 1); + url = "ftp://" + host; + SETOPTR (CURLOPT_WRITEDATA, static_cast (curr_ostream)); + SETOPTR (CURLOPT_DIRLISTONLY, 0); + SETOPTR (CURLOPT_URL, url.c_str ()); + + // Count number of directory entries + std::string str = buf.str (); + octave_idx_type n = 0; + size_t pos = 0; + while (true) + { + pos = str.find_first_of ('\n', pos); + if (pos == std::string::npos) + break; + pos++; + n++; + } + retval.resize (n); + pos = 0; + for (octave_idx_type i = 0; i < n; i++) + { + size_t newpos = str.find_first_of ('\n', pos); + if (newpos == std::string::npos) + break; + + retval(i) = str.substr(pos, newpos - pos); + pos = newpos + 1; + } + + return retval; + } + + void get_fileinfo (const std::string& filename, double& filesize, + time_t& filetime, bool& fileisdir) + { + std::string path = pwd (); + + std::string url = "ftp://" + host + "/" + path + "/" + filename; + SETOPT (CURLOPT_URL, url.c_str ()); + SETOPT (CURLOPT_FILETIME, 1); + SETOPT (CURLOPT_HEADERFUNCTION, throw_away); + SETOPT (CURLOPT_WRITEFUNCTION, throw_away); + + // FIXME + // The MDTM command fails for a directory on the servers I tested + // so this is a means of testing for directories. It also means + // I can't get the date of directories! + + perform (); + if (! good ()) + { + fileisdir = true; + filetime = -1; + filesize = 0; + + return; + } + + fileisdir = false; + time_t ft; + curl_easy_getinfo (curl, CURLINFO_FILETIME, &ft); + filetime = ft; + double fs; + curl_easy_getinfo (curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &fs); + filesize = fs; + + SETOPT (CURLOPT_WRITEFUNCTION, write_data); + SETOPT (CURLOPT_HEADERFUNCTION, 0); + SETOPT (CURLOPT_FILETIME, 0); + url = "ftp://" + host; + SETOPT (CURLOPT_URL, url.c_str ()); + + // The MDTM command seems to reset the path to the root with the + // servers I tested with, so cd again into the correct path. Make + // the path absolute so that this will work even with servers that + // don't end up in the root after an MDTM command. + cwd ("/" + path); + } + + std::string pwd (void) + { + std::string retval; + + struct curl_slist *slist = 0; + + unwind_protect frame; + frame.add_fcn (curl_slist_free_all, slist); + + slist = curl_slist_append (slist, "pwd"); + SETOPTR (CURLOPT_POSTQUOTE, slist); + SETOPTR (CURLOPT_HEADERFUNCTION, write_data); + + std::ostringstream buf; + SETOPTR (CURLOPT_WRITEHEADER, static_cast(&buf)); + + perform (); + if (! good ()) + return retval; + + retval = buf.str (); + + // Can I assume that the path is alway in "" on the last line + size_t pos2 = retval.rfind ('"'); + size_t pos1 = retval.rfind ('"', pos2 - 1); + retval = retval.substr (pos1 + 1, pos2 - pos1 - 1); + + SETOPTR (CURLOPT_HEADERFUNCTION, 0); + SETOPTR (CURLOPT_WRITEHEADER, 0); + SETOPTR (CURLOPT_POSTQUOTE, 0); + + return retval; + } + +private: + + CURL *curl; + CURLcode errnum; + + // No copying! + + curl_transfer (const curl_transfer&); + + curl_transfer& operator = (const curl_transfer&); + + void init (const std::string& user, const std::string& passwd, + std::istream& is, std::ostream& os) + { + // No data transfer by default + SETOPT (CURLOPT_NOBODY, 1); + + // Set the username and password + userpwd = user; + if (! passwd.empty ()) + userpwd += ":" + passwd; + if (! userpwd.empty ()) + SETOPT (CURLOPT_USERPWD, userpwd.c_str ()); + + // Define our callback to get called when there's data to be written. + SETOPT (CURLOPT_WRITEFUNCTION, write_data); + + // Set a pointer to our struct to pass to the callback. + SETOPT (CURLOPT_WRITEDATA, static_cast (&os)); + + // Define our callback to get called when there's data to be read + SETOPT (CURLOPT_READFUNCTION, read_data); + + // Set a pointer to our struct to pass to the callback. + SETOPT (CURLOPT_READDATA, static_cast (&is)); + + // Follow redirects. + SETOPT (CURLOPT_FOLLOWLOCATION, true); + + // Don't use EPSV since connecting to sites that don't support it + // will hang for some time (3 minutes?) before moving on to try PASV + // instead. + SETOPT (CURLOPT_FTP_USE_EPSV, false); + + SETOPT (CURLOPT_NOPROGRESS, true); + SETOPT (CURLOPT_FAILONERROR, true); + + SETOPT (CURLOPT_POSTQUOTE, 0); + SETOPT (CURLOPT_QUOTE, 0); + } + + std::string form_query_string (const Array& param) + { + std::ostringstream query; + + for (int i = 0; i < param.numel (); i += 2) + { + std::string name = param(i); + std::string text = param(i+1); + + // Encode strings. + char *enc_name = curl_easy_escape (curl, name.c_str (), + name.length ()); + char *enc_text = curl_easy_escape (curl, text.c_str (), + text.length ()); + + query << enc_name << "=" << enc_text; + + curl_free (enc_name); + curl_free (enc_text); + + if (i < param.numel ()-1) + query << "&"; + } + + query.flush (); + + return query.str (); + } +}; + +#undef SETOPT + +#else + +static void +disabled_error (void) +{ + (*current_liboctave_error_handler) + ("support for url transfers was disabled when Octave was built"); +} + +#endif + +#if defined (HAVE_CURL) +# define REP_CLASS curl_transfer +#else +# define REP_CLASS base_url_transfer +#endif + +url_transfer::url_transfer (void) : rep (new REP_CLASS ()) +{ +#if !defined (HAVE_CURL) + disabled_error (); +#endif +} + +url_transfer::url_transfer (const std::string& host, const std::string& user, + const std::string& passwd, std::ostream& os) + : rep (new REP_CLASS (host, user, passwd, os)) +{ +#if !defined (HAVE_CURL) + disabled_error (); +#endif +} + +url_transfer::url_transfer (const std::string& url, const std::string& method, + const Array& param, std::ostream& os) + : rep (new REP_CLASS (url, method, param, os)) +{ +#if !defined (HAVE_CURL) + disabled_error (); +#endif +} + +#undef REP_CLASS diff -r 20d1b911b4e7 -r c702371ff6df liboctave/util/url-transfer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/liboctave/util/url-transfer.h Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,265 @@ +/* + +Copyright (C) 2013 John W. Eaton +Copyright (C) 2006-2012 Alexander Barth +Copyright (C) 2009 David Bateman + +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 +. + +*/ + +// Author: Alexander Barth +// Author: jwe + +#if !defined (octave_url_transfer_h) +#define octave_url_transfer_h 1 + +#include +#include + +class base_url_transfer +{ +private: + + static void delete_file (const std::string& file); + + static void reset_path (base_url_transfer *curl_xfer) + { + curl_xfer->cwd (".."); + } + +public: + + friend class url_transfer; + + base_url_transfer (void) + : count (1), host (), userpwd (), valid (false), ascii_mode (false), + ok (true), errmsg (), curr_istream (&std::cin), curr_ostream (&std::cout) + { } + + base_url_transfer (const std::string& host_arg, + const std::string& /* user_arg */, + const std::string& /* passwd */, + std::ostream& os) + : count (1), host (host_arg), userpwd (), valid (false), + ascii_mode (false), ok (true), errmsg (), curr_istream (&std::cin), + curr_ostream (&os) { } + + base_url_transfer (const std::string& /* url */, + const std::string& /* method */, + const Array& /* param */, + std::ostream& os) + : count (1), host (), userpwd (), valid (false), ascii_mode (false), + ok (true), errmsg (), curr_istream (&std::cin), curr_ostream (&os) { } + + virtual ~base_url_transfer (void) { } + + bool is_valid (void) const { return valid; } + + bool good (void) const { return valid && ok; } + + virtual void perform (void) { } + + virtual std::string lasterror (void) const { return errmsg; } + + virtual std::ostream& set_ostream (std::ostream& /* os */) + { + return *curr_ostream; + } + + virtual std::istream& set_istream (std::istream& /* is */) + { + return *curr_istream; + } + + virtual void ascii (void) { } + + virtual void binary (void) { } + + bool is_ascii (void) const { return ascii_mode; } + + bool is_binary (void) const { return !ascii_mode; } + + virtual void cwd (const std::string& /* path */) { } + + virtual void del (const std::string& /* file */) { } + + virtual void rmdir (const std::string& /* path */) { } + + virtual void mkdir (const std::string& /* path */) { } + + virtual void rename (const std::string& /* oldname */, + const std::string& /* newname */) { } + + virtual void put (const std::string& /* file */, + std::istream& /* is */) { } + + virtual void get (const std::string& /* file */, + std::ostream& /* os */) { } + + void mget_directory (const std::string& directory, + const std::string& target); + + string_vector mput_directory (const std::string& base, + const std::string& directory); + + virtual void dir (void) { } + + virtual string_vector list (void) { return string_vector (); } + + virtual void get_fileinfo (const std::string& /* filename */, + double& /* filesize */, + time_t& /* filetime */, + bool& /* fileisdir */) { } + + virtual std::string pwd (void) { return std::string (); } + +protected: + + octave_refcount count; + std::string host; + std::string userpwd; + bool valid; + bool ascii_mode; + bool ok; + std::string errmsg; + std::istream *curr_istream; + std::ostream *curr_ostream; + +private: + + // No copying! + + base_url_transfer (const base_url_transfer&); + + base_url_transfer& operator = (const base_url_transfer&); +}; + +class url_transfer +{ +public: + + url_transfer (void); + + url_transfer (const std::string& host, const std::string& user, + const std::string& passwd, std::ostream& os); + + url_transfer (const std::string& url, const std::string& method, + const Array& param, std::ostream& os); + + url_transfer (const url_transfer& h) : rep (h.rep) + { + rep->count++; + } + + ~url_transfer (void) + { + if (--rep->count == 0) + delete rep; + } + + url_transfer& operator = (const url_transfer& h) + { + if (this != &h) + { + if (--rep->count == 0) + delete rep; + + rep = h.rep; + rep->count++; + } + + return *this; + } + + bool is_valid (void) const { return rep->is_valid (); } + + bool good (void) const { return rep->good (); } + + std::string lasterror (void) const { return rep->lasterror (); } + + std::ostream& set_ostream (std::ostream& os) + { + return rep->set_ostream (os); + } + + std::istream& set_istream (std::istream& is) + { + return rep->set_istream (is); + } + + void ascii (void) { rep->ascii (); } + + void binary (void) { rep->binary (); } + + bool is_ascii (void) const { return rep->is_ascii (); } + + bool is_binary (void) const { return rep->is_binary (); } + + void cwd (const std::string& path) { rep->cwd (path); } + + void del (const std::string& file) { rep->del (file); } + + void rmdir (const std::string& path) { rep->rmdir (path); } + + void mkdir (const std::string& path) { rep->mkdir (path); } + + void rename (const std::string& oldname, const std::string& newname) + { + rep->rename (oldname, newname); + } + + void put (const std::string& file, std::istream& is) + { + rep->put (file, is); + } + + void get (const std::string& file, std::ostream& os) + { + rep->get (file, os); + } + + void mget_directory (const std::string& directory, + const std::string& target) + { + rep->mget_directory (directory, target); + } + + string_vector mput_directory (const std::string& base, + const std::string& directory) + { + return rep->mput_directory (base, directory); + } + + void dir (void) { rep->dir (); } + + string_vector list (void) { return rep->list (); } + + void get_fileinfo (const std::string& filename, double& filesize, + time_t& filetime, bool& fileisdir) + { + rep->get_fileinfo (filename, filesize, filetime, fileisdir); + } + + std::string pwd (void) { return rep->pwd (); } + +private: + + base_url_transfer *rep; +}; + +#endif diff -r 20d1b911b4e7 -r c702371ff6df m4/acinclude.m4 --- a/m4/acinclude.m4 Thu Sep 12 21:08:07 2013 -0400 +++ b/m4/acinclude.m4 Sat Oct 05 11:22:09 2013 -0400 @@ -1,19 +1,19 @@ dnl aclocal.m4 -- extra macros for configuring Octave dnl dnl Copyright (C) 1995-2012 John W. Eaton -dnl +dnl dnl This file is part of Octave. -dnl +dnl dnl Octave is free software; you can redistribute it and/or modify it dnl under the terms of the GNU General Public License as published by the dnl Free Software Foundation; either version 3 of the License, or (at dnl your option) any later version. -dnl +dnl dnl Octave is distributed in the hope that it will be useful, but WITHOUT dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License dnl for more details. -dnl +dnl dnl You should have received a copy of the GNU General Public License dnl along with Octave; see the file COPYING. If not, see dnl . @@ -84,7 +84,7 @@ ]) if eval "test \"`echo '$octave_cv_cc_flag_'$ac_safe`\" = yes"; then AC_MSG_RESULT([yes]) - ifelse([$2], , + ifelse([$2], , [CFLAGS="$CFLAGS $1" AC_MSG_RESULT([adding $1 to CFLAGS])], [$2]) else @@ -147,7 +147,7 @@ dnl Check whether a math mapper function is available in . dnl Will define HAVE_CMATH_FUNC if there is a double variant and dnl HAVE_CMATH_FUNCF if there is a float variant. -dnl Currently capable of checking for functions with single +dnl Currently capable of checking for functions with single dnl argument and returning bool/int/real. dnl AC_DEFUN([OCTAVE_CHECK_FUNC_CMATH], [ @@ -242,7 +242,7 @@ end program ]], octave_cv_func_fortran_isnan=yes, octave_cv_func_fortran_isnan=no) - AC_LANG_POP(Fortran 77) + AC_LANG_POP(Fortran 77) ]) ]) dnl @@ -267,7 +267,7 @@ AC_LANG_POP(C++) ]) if test $octave_cv_func_glutesscallback_threedots = yes; then - AC_DEFINE(HAVE_GLUTESSCALLBACK_THREEDOTS, 1, + AC_DEFINE(HAVE_GLUTESSCALLBACK_THREEDOTS, 1, [Define to 1 if gluTessCallback is called with (...).]) fi ]) @@ -295,11 +295,54 @@ AC_LANG_POP(C++) ]) if test $octave_cv_func_setplaceholdertext = yes; then - AC_DEFINE(HAVE_SETPLACEHOLDERTEXT, 1, + AC_DEFINE(HAVE_SETPLACEHOLDERTEXT, 1, [Define to 1 if you have the Qt SetPlaceholderText function.]) fi ]) dnl +dnl Check whether the Qt QAbstractItemModel::beginResetModel() function exists. +dnl Also checks for QAbstractItemModel::endResetModel(). These are two of the +dnl newest Qt functions that the Octave GUI depends on, added in Qt 4.6. +dnl +AC_DEFUN([OCTAVE_CHECK_FUNC_QABSTRACTITEMMODEL_BEGINRESETMODEL], [ + AC_CACHE_CHECK([whether Qt has the QAbstractItemModel::beginResetModel() function], + [octave_cv_func_qabstractitemmodel_beginresetmodel], + [AC_LANG_PUSH(C++) + ac_octave_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$QT_CPPFLAGS $CPPFLAGS" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + class item_model : public QAbstractItemModel + { + public: + item_model (QObject *parent = 0) : QAbstractItemModel (parent) {} + ~item_model () {} + QModelIndex index (int, int, const QModelIndex& m) const { return m; } + QModelIndex parent (const QModelIndex& m) const { return m; } + int columnCount (const QModelIndex&) const { return 0; } + int rowCount (const QModelIndex&) const { return 0; } + QVariant data (const QModelIndex&, int) const { return QVariant(); } + void update_model () + { + this->beginResetModel (); + this->endResetModel (); + } + }; + ]], [[ + item_model model; + model.update_model (); + ]])], + octave_cv_func_qabstractitemmodel_beginresetmodel=yes, + octave_cv_func_qabstractitemmodel_beginresetmodel=no) + CPPFLAGS="$ac_octave_save_CPPFLAGS" + AC_LANG_POP(C++) + ]) + if test $octave_cv_func_qabstractitemmodel_beginresetmodel = yes; then + AC_DEFINE(HAVE_QABSTRACTITEMMODEL_BEGINRESETMODEL, 1, + [Define to 1 if Qt has the QAbstractItemModel::beginResetModel() function.]) + fi +]) +dnl dnl Check whether HDF5 library has version 1.6 API functions. dnl AC_DEFUN([OCTAVE_CHECK_HDF5_HAS_VER_16_API], [ @@ -470,7 +513,7 @@ ip[8] = 0; ip[9] = 0; ip[10] = 0; - + int *ipntr = new int [14]; int k = 1; @@ -486,7 +529,7 @@ double tol = DBL_EPSILON; - do + do { F77_FUNC (dnaupd, DNAUPD) (ido, "I", n, "LM", k, tol, resid, p, v, n, ip, ipntr, workd, workl, lwork, @@ -509,7 +552,7 @@ break; } - } + } while (1); int *sel = new int [p]; @@ -555,6 +598,42 @@ fi ]) dnl +dnl Check whether GLPK provides the latest API functions required +dnl for the glpk function. The glp_iptcp structure was introduced +dnl in GLPK version 4.38. +dnl +AC_DEFUN([OCTAVE_CHECK_LIB_GLPK_OK], [ + AC_CACHE_CHECK([whether the glpk library has glp_interior(glp_prob*, glp_iptcp*)], + [octave_cv_lib_glpk_ok], + [AC_LANG_PUSH(C++) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + extern "C" + { + #if defined (HAVE_GLPK_GLPK_H) + #include + #else + #include + #endif + } + ]], [[ + glp_prob *lp = glp_create_prob (); + glp_iptcp iptcp; + glp_init_iptcp (&iptcp); + int retval = glp_interior (lp, &iptcp); + ]])], + octave_cv_lib_glpk_ok=yes, + octave_cv_lib_glpk_ok=no) + AC_LANG_POP(C++) + ]) + if test $octave_cv_lib_glpk_ok = yes; then + $1 + : + else + $2 + : + fi +]) +dnl dnl Check whether using HDF5 DLL under Windows. This is done by dnl testing for a data symbol in the HDF5 library, which would dnl require the definition of _HDF5USEDL_ under MSVC compiler. @@ -637,7 +716,7 @@ #endif ]) - if test "$have_opengl_incs" = yes; then + if test $have_opengl_incs = yes; then case $canonical_host_type in *-*-mingw32* | *-*-msdosmsvc) save_LIBS="$LIBS" @@ -652,7 +731,7 @@ #elif defined (HAVE_OPENGL_GL_H) # include #endif - ]], [[ + ]], [[ glEnable(GL_SMOOTH); ]])], [OPENGL_LIBS="-lopengl32 -lglu32"]) @@ -715,7 +794,7 @@ int n = 4; coordT points[8] = { -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5 }; boolT ismalloc = 0; - return qh_new_qhull (dim, n, points, ismalloc, "qhull ", 0, stderr); + return qh_new_qhull (dim, n, points, ismalloc, "qhull ", 0, stderr); ]])], octave_cv_lib_qhull_ok=yes, octave_cv_lib_qhull_ok=no, @@ -740,7 +819,7 @@ [], []) LIBS="$ac_octave_save_LIBS" case "$ac_cv_search_tputs" in - -l*) + -l*) TERM_LIBS="$ac_cv_search_tputs" ;; no) @@ -776,7 +855,7 @@ ]], [[ int main(int argc, char* argv[]) { - _Pragma("omp parallel") + _Pragma("omp parallel") printf("Hello, world.\n"); return 0; } @@ -828,7 +907,7 @@ #endif ]], [[ const char *tmp = qh_version; - ]])], + ]])], octave_cv_lib_qhull_version=yes, octave_cv_lib_qhull_version=no) ]) if test $octave_cv_lib_qhull_version = no; then @@ -998,7 +1077,7 @@ AC_LANG_POP(C++) ]) if test $octave_cv_cxx_complex_setters = yes; then - AC_DEFINE(HAVE_CXX_COMPLEX_SETTERS, 1, + AC_DEFINE(HAVE_CXX_COMPLEX_SETTERS, 1, [Define to 1 if C++ complex class has void real (T) and void imag (T) methods.]) fi ]) @@ -1015,7 +1094,7 @@ char x[length()]; test(x); ]])], - octave_cv_cxx_dynamic_auto_arrays=yes, + octave_cv_cxx_dynamic_auto_arrays=yes, octave_cv_cxx_dynamic_auto_arrays=no) AC_LANG_POP(C++) ]) @@ -1087,13 +1166,13 @@ ]) AC_MSG_RESULT([$octave_cv_cxx_iso_compliant_library]) if test $octave_cv_cxx_iso_compliant_library = yes; then - AC_DEFINE(CXX_ISO_COMPLIANT_LIBRARY, 1, + AC_DEFINE(CXX_ISO_COMPLIANT_LIBRARY, 1, [Define to 1 if your C++ runtime library is ISO compliant.]) fi ]) dnl dnl Check if C++ compiler needs the new friend template declaration -dnl syntax. +dnl syntax. dnl AC_DEFUN([OCTAVE_CXX_NEW_FRIEND_TEMPLATE_DECL], [ AC_REQUIRE([AC_PROG_CXX]) @@ -1141,7 +1220,7 @@ ]], [[ operator delete((void *)0, (void *)0); ]])], - octave_cv_cxx_placement_delete=yes, + octave_cv_cxx_placement_delete=yes, octave_cv_cxx_placement_delete=no) AC_LANG_POP(C++) ]) @@ -1230,16 +1309,16 @@ AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include template - static bool + static bool do_test (UT, ST) { volatile ST s = std::numeric_limits::min () / 3; volatile UT u = static_cast (s); if (*(reinterpret_cast (&u)) != s) return true; - + u = 0; u = ~u; if (*(reinterpret_cast (&u)) != -1) return true; - + ST sx, sy; sx = std::numeric_limits::max () / 2 + 1; sy = std::numeric_limits::max () / 2 + 2; @@ -1247,7 +1326,7 @@ != std::numeric_limits::min () + 1) return true; if (static_cast (static_cast (sx) - static_cast (sy)) != -1) return true; - + if ((sx & sy) != (static_cast (sx) & static_cast (sy))) return true; if ((sx | sy) != (static_cast (sx) | static_cast (sy))) @@ -1257,7 +1336,7 @@ if ((-1 >> 1) != -1) return true; return false; } - + #define DO_TEST(T) \ if (do_test (static_cast (0), static_cast (0)))\ return sizeof (T); @@ -1305,7 +1384,7 @@ if test "$octave_cv_framework_$1" = yes; then AC_MSG_RESULT([yes]) AC_ARG_WITH(framework-m4_tolower($1), - [AS_HELP_STRING([--without-framework-m4_tolower($1)], + [AS_HELP_STRING([--without-framework-m4_tolower($1)], [don't use framework $1])], with_have_framework=$withval, with_have_framework=yes) if test "$with_have_framework" = yes; then @@ -1349,10 +1428,10 @@ AC_CACHE_VAL([octave_cv_ieee754_data_format], [AC_RUN_IFELSE([AC_LANG_SOURCE([[ int - main (void) + main (void) { typedef union { unsigned char c[8]; double d; } ieeebytes; - + ieeebytes l = {0x1c, 0xbc, 0x6e, 0xf2, 0x54, 0x8b, 0x11, 0x43}; ieeebytes b = {0x43, 0x11, 0x8b, 0x54, 0xf2, 0x6e, 0xbc, 0x1c}; @@ -1381,6 +1460,101 @@ fi ]) dnl +dnl Check for CallInst::addAttribute API +dnl +AC_DEFUN([OCTAVE_LLVM_CALLINST_ADDATTRIBUTE_API], [ + AC_CACHE_CHECK([check LLVM::CallInst::addAttribute arg type is llvm::Attributes], + [octave_cv_callinst_addattribute_arg_is_attributes], + [AC_LANG_PUSH(C++) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([ +#ifdef HAVE_LLVM_IR_FUNCTION_H + #include + #include +#else + #include + #include +#endif + ], [[ + llvm::CallInst *callinst; + llvm::AttrBuilder attr_builder; + attr_builder.addAttribute(llvm::Attributes::StructRet); + llvm::Attributes attrs = llvm::Attributes::get(llvm::getGlobalContext(), attr_builder); + callinst->addAttribute (1, attrs); + ]])], + octave_cv_callinst_addattribute_arg_is_attributes=yes, + octave_cv_callinst_addattribute_arg_is_attributes=no) + AC_LANG_POP(C++) + ]) + if test $octave_cv_callinst_addattribute_arg_is_attributes = yes; then + AC_DEFINE(CALLINST_ADDATTRIBUTE_ARG_IS_ATTRIBUTES, 1, + [Define to 1 if llvm::CallInst:addAttribute arg type is llvm::Attributes.]) + fi +]) +dnl +dnl Check for Function::addAttribute API +dnl +AC_DEFUN([OCTAVE_LLVM_FUNCTION_ADDATTRIBUTE_API], [ + AC_CACHE_CHECK([check llvm::Function::addAttribute arg type is llvm::Attributes], + [octave_cv_function_addattribute_arg_is_attributes], + [AC_LANG_PUSH(C++) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ +#ifdef HAVE_LLVM_IR_FUNCTION_H + #include + #include + #include +#else + #include + #include + #include +#endif + ]], [[ + llvm::Function *llvm_function; + llvm::AttrBuilder attr_builder; + attr_builder.addAttribute(llvm::Attributes::StructRet); + llvm::Attributes attrs = llvm::Attributes::get(llvm::getGlobalContext(), attr_builder); + llvm_function->addAttribute (1, attrs); + ]])], + octave_cv_function_addattribute_arg_is_attributes=yes, + octave_cv_function_addattribute_arg_is_attributes=no) + AC_LANG_POP(C++) + ]) + if test $octave_cv_function_addattribute_arg_is_attributes = yes; then + AC_DEFINE(FUNCTION_ADDATTRIBUTE_ARG_IS_ATTRIBUTES, 1, + [Define to 1 if llvm::Function:addAttribute arg type is llvm::Attributes.]) + fi +]) +dnl +dnl Check for Function::addFnAttr API +dnl +AC_DEFUN([OCTAVE_LLVM_FUNCTION_ADDFNATTR_API], [ + AC_CACHE_CHECK([check LLVM::Function::addFnAttr arg type is llvm::Attributes], + [octave_cv_function_addfnattr_arg_is_attributes], + [AC_LANG_PUSH(C++) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ +#ifdef LLVM_HAVE_IR_FUNCTION_H + #include + #include +#else + #include + #include +#endif + ]], [[ + llvm::Function *llvm_function; + llvm_function->addFnAttr (llvm::Attributes::AlwaysInline); + ]])], + octave_cv_function_addfnattr_arg_is_attributes=yes, + octave_cv_function_addfnattr_arg_is_attributes=no) + AC_LANG_POP(C++) + ]) + if test $octave_cv_function_addfnattr_arg_is_attributes = yes; then + AC_DEFINE(FUNCTION_ADDFNATTR_ARG_IS_ATTRIBUTES, 1, + [Define to 1 if llvm::Function:addFnAttr arg type is llvm::Attributes.]) + fi +]) +dnl dnl Check for ar. dnl AC_DEFUN([OCTAVE_PROG_AR], [ @@ -1401,11 +1575,11 @@ AC_PROG_YACC case "`$YACC --version`" in - *bison*) tmp_have_bison="yes" ;; + *bison*) tmp_have_bison=yes ;; *) tmp_have_bison=no ;; esac - if test "$tmp_have_bison" = yes; then + if test $tmp_have_bison = yes; then AC_CACHE_CHECK([syntax of bison push/pull declaration], [octave_cv_bison_push_pull_decl_style], [ style="dash underscore" @@ -1459,7 +1633,7 @@ OCTAVE_CONFIGURE_WARNING([warn_bison_push_pull_decl_style]) fi - if test "$tmp_have_bison" = no; then + if test $tmp_have_bison = no; then YACC='$(top_srcdir)/build-aux/missing bison' warn_bison=" @@ -1574,7 +1748,7 @@ warn_gperf=" I didn't find gperf, but it's only a problem if you need to -reconstruct oct-gperf.h +reconstruct oct-gperf.h " OCTAVE_CONFIGURE_WARNING([warn_gperf]) GPERF='$(top_srcdir)/build-aux/missing gperf' @@ -1761,7 +1935,7 @@ dnl Macro assumes that the check for umfpack has already been performed. dnl AC_DEFUN([OCTAVE_UMFPACK_NEED_SUITESPARSE_TIME], [ - AC_CACHE_CHECK([whether UMFPACK needs SuiteSparse_time function], + AC_CACHE_CHECK([whether UMFPACK needs SuiteSparse_time function], [octave_cv_umfpack_need_suitesparse_time], [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[ @@ -1814,7 +1988,7 @@ idx_type n = 5; idx_type Ap[] = {0, 2, 5, 9, 10, 12}; idx_type Ai[] = {0, 1, 0, 2, 4, 1, 2, 3, 4, 2, 1, 4}; - double Ax[] = {2., 0., 3., 0., 3., 0., -1., 0., 4., 0., 4., 0., + double Ax[] = {2., 0., 3., 0., 3., 0., -1., 0., 4., 0., 4., 0., -3., 0., 1., 0., 2., 0., 2., 0., 6., 0., 1., 0.}; double br[] = {8., 45., -3., 3., 19.}; double bi[] = {0., 0., 0., 0., 0.}; @@ -1827,10 +2001,10 @@ (void) UMFPACK_NAME (symbolic) (n, n, Ap, Ai, Ax, null, &Symbolic, null, null) ; (void) UMFPACK_NAME (numeric) (Ap, Ai, Ax, null, Symbolic, &Numeric, null, null) ; UMFPACK_NAME (free_symbolic) (&Symbolic) ; - (void) UMFPACK_NAME (solve) (0, Ap, Ai, Ax, null, x, null, br, bi, + (void) UMFPACK_NAME (solve) (0, Ap, Ai, Ax, null, x, null, br, bi, Numeric, null, null) ; UMFPACK_NAME (free_numeric) (&Numeric) ; - for (i = 0; i < n; i++, x+=2) + for (i = 0; i < n; i++, x+=2) if (fabs (*x - i - 1.) > 1.e-13) return (1); return (0) ; @@ -1846,7 +2020,7 @@ AC_MSG_RESULT([$octave_cv_umfpack_separate_split]) fi if test $octave_cv_umfpack_separate_split = yes; then - AC_DEFINE(UMFPACK_SEPARATE_SPLIT, 1, + AC_DEFINE(UMFPACK_SEPARATE_SPLIT, 1, [Define to 1 if the UMFPACK Complex solver allows matrix and RHS to be split independently.]) fi ]) @@ -1857,7 +2031,7 @@ AC_DEFUN([OCTAVE_UNORDERED_MAP_HEADERS], [ AC_CHECK_HEADERS([unordered_map], [], [AC_CHECK_HEADERS([tr1/unordered_map])]) - AC_CACHE_CHECK([whether unordered_map requires tr1 namespace], + AC_CACHE_CHECK([whether unordered_map requires tr1 namespace], [octave_cv_header_require_tr1_namespace], [AC_LANG_PUSH(C++) octave_cv_header_require_tr1_namespace=no @@ -1870,7 +2044,7 @@ ]], [[ std::unordered_map m; ]])], - octave_cv_header_require_tr1_namespace=no, + octave_cv_header_require_tr1_namespace=no, octave_cv_header_require_tr1_namespace=yes) elif test $ac_cv_header_tr1_unordered_map = yes; then octave_cv_header_require_tr1_namespace=yes @@ -1878,7 +2052,7 @@ AC_LANG_POP(C++) ]) if test $octave_cv_header_require_tr1_namespace = yes; then - AC_DEFINE(USE_UNORDERED_MAP_WITH_TR1, 1, + AC_DEFINE(USE_UNORDERED_MAP_WITH_TR1, 1, [Define to 1 if unordered_map requires the use of tr1 namespace.]) fi ]) diff -r 20d1b911b4e7 -r c702371ff6df scripts/@ftp/ascii.m --- a/scripts/@ftp/ascii.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/@ftp/ascii.m Sat Oct 05 11:22:09 2013 -0400 @@ -29,3 +29,4 @@ function ascii (f) __ftp_ascii__ (f.curlhandle); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/@ftp/binary.m --- a/scripts/@ftp/binary.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/@ftp/binary.m Sat Oct 05 11:22:09 2013 -0400 @@ -28,3 +28,4 @@ function binary (f) __ftp_binary__ (f.curlhandle); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/@ftp/cd.m --- a/scripts/@ftp/cd.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/@ftp/cd.m Sat Oct 05 11:22:09 2013 -0400 @@ -41,3 +41,4 @@ endif path = __ftp_pwd__ (f.curlhandle); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/@ftp/close.m --- a/scripts/@ftp/close.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/@ftp/close.m Sat Oct 05 11:22:09 2013 -0400 @@ -23,6 +23,7 @@ ## @var{f} is an FTP object returned by the @code{ftp} function. ## @end deftypefn -function dir (f) +function close (f) __ftp_close__ (f.curlhandle); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/@ftp/delete.m --- a/scripts/@ftp/delete.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/@ftp/delete.m Sat Oct 05 11:22:09 2013 -0400 @@ -26,3 +26,4 @@ function delete (f, file) __ftp_delete__ (f.curlhandle, file); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/@ftp/dir.m --- a/scripts/@ftp/dir.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/@ftp/dir.m Sat Oct 05 11:22:09 2013 -0400 @@ -31,3 +31,4 @@ lst = __ftp_dir__ (f.curlhandle); endif endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/@ftp/display.m --- a/scripts/@ftp/display.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/@ftp/display.m Sat Oct 05 11:22:09 2013 -0400 @@ -22,4 +22,5 @@ printf (" user: %s\n", obj.username); printf (" dir: %s\n", __ftp_pwd__ (obj.curlhandle)); printf (" mode: %s\n", __ftp_mode__ (obj.curlhandle)); -endfunction \ No newline at end of file +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/@ftp/ftp.m --- a/scripts/@ftp/ftp.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/@ftp/ftp.m Sat Oct 05 11:22:09 2013 -0400 @@ -20,9 +20,9 @@ ## @deftypefn {Function File} {@var{f} =} ftp (@var{host}) ## @deftypefnx {Function File} {@var{f} =} ftp (@var{host}, @var{username}, @var{password}) ## Connect to the FTP server @var{host} with @var{username} and @var{password}. -## If @var{username} and @var{password} are not specified, user "anonymous" -## with no password is used. The returned FTP object @var{f} represents the -## established FTP connection. +## If @var{username} and @var{password} are not specified, user +## @qcode{"anonymous"} with no password is used. The returned FTP object +## @var{f} represents the established FTP connection. ## ## The list of actions for an FTP object are shown below. All functions ## require an FTP object as the first argument. @@ -53,8 +53,9 @@ p.password = password; p.curlhandle = tmpnam ("ftp-"); if (nargin > 0) - __ftp__ (p.curlhandle, host, username, password); + p.curlhandle = __ftp__ (host, username, password); endif obj = class (p, "ftp"); endif endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/@ftp/loadobj.m --- a/scripts/@ftp/loadobj.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/@ftp/loadobj.m Sat Oct 05 11:22:09 2013 -0400 @@ -21,8 +21,7 @@ if (isfield (b, "jobject")) b = rmfield (b, "jobject"); endif - b.curlhandle = tmpnam ("ftp-"); - __ftp__ (b.curlhandle, b.host, b.username, b.password); + b.curlhandle = __ftp__ (b.host, b.username, b.password); if (isfield (b, "dir")) if (! isempty (b.dir)) __ftp_cwd__ (b.curlhandle, b.dir); @@ -34,3 +33,4 @@ b = rmfield (b, "remotePwd"); endif endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/@ftp/mget.m --- a/scripts/@ftp/mget.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/@ftp/mget.m Sat Oct 05 11:22:09 2013 -0400 @@ -35,3 +35,4 @@ function mget (f, file) __ftp_mget__ (f.curlhandle, file); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/@ftp/mkdir.m --- a/scripts/@ftp/mkdir.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/@ftp/mkdir.m Sat Oct 05 11:22:09 2013 -0400 @@ -26,3 +26,4 @@ function mkdir (f, path) __ftp_mkdir__ (f.curlhandle, path); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/@ftp/mput.m --- a/scripts/@ftp/mput.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/@ftp/mput.m Sat Oct 05 11:22:09 2013 -0400 @@ -33,3 +33,4 @@ retval = __ftp_mput__ (f.curlhandle, file); endif endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/@ftp/rename.m --- a/scripts/@ftp/rename.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/@ftp/rename.m Sat Oct 05 11:22:09 2013 -0400 @@ -27,3 +27,4 @@ function rename (f, oldname, newname) __ftp_rename__ (f.curlhandle, oldname, newname); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/@ftp/rmdir.m --- a/scripts/@ftp/rmdir.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/@ftp/rmdir.m Sat Oct 05 11:22:09 2013 -0400 @@ -26,3 +26,4 @@ function rmdir (f, path) __ftp_rmdir__ (f.curlhandle, path); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/@ftp/saveobj.m --- a/scripts/@ftp/saveobj.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/@ftp/saveobj.m Sat Oct 05 11:22:09 2013 -0400 @@ -19,5 +19,6 @@ function b = saveobj (a) b = a; b = rmfield (b, "curlhandle"); - b.dir = __ftp_pwd (a.curlhandle); + b.dir = __ftp_pwd__ (a.curlhandle); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/Makefile.am --- a/scripts/Makefile.am Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/Makefile.am Sat Oct 05 11:22:09 2013 -0400 @@ -20,8 +20,6 @@ include $(top_srcdir)/build-aux/common.mk -AUTOMAKE_OPTIONS = subdir-objects - EXTRA_DIST = CLEANFILES = @@ -49,6 +47,7 @@ include elfun/module.mk include general/module.mk include geometry/module.mk +include gui/module.mk include help/module.mk include image/module.mk include io/module.mk @@ -58,7 +57,9 @@ include optimization/module.mk include path/module.mk include pkg/module.mk -include plot/module.mk +include plot/appearance/module.mk +include plot/draw/module.mk +include plot/util/module.mk include polynomial/module.mk include prefs/module.mk include set/module.mk @@ -114,6 +115,10 @@ $(srcdir)/mk-pkg-add $(srcdir) $(geometry_FCN_FILES) -- $(geometry_GEN_FCN_FILES) > $@-t mv $@-t $@ +gui/PKG_ADD: $(gui_FCN_FILES) $(gui_GEN_FCN_FILES) gui/$(octave_dirstamp) mk-pkg-add + $(srcdir)/mk-pkg-add $(srcdir) $(gui_FCN_FILES) -- $(gui_GEN_FCN_FILES) > $@-t + mv $@-t $@ + help/PKG_ADD: $(help_FCN_FILES) $(help_GEN_FCN_FILES) help/$(octave_dirstamp) mk-pkg-add $(srcdir)/mk-pkg-add $(srcdir) $(help_FCN_FILES) -- $(help_GEN_FCN_FILES) > $@-t mv $@-t $@ @@ -150,8 +155,16 @@ $(srcdir)/mk-pkg-add $(srcdir) $(pkg_FCN_FILES) -- $(pkg_GEN_FCN_FILES) > $@-t mv $@-t $@ -plot/PKG_ADD: $(plot_FCN_FILES) $(plot_GEN_FCN_FILES) plot/$(octave_dirstamp) mk-pkg-add - $(srcdir)/mk-pkg-add $(srcdir) $(plot_FCN_FILES) -- $(plot_GEN_FCN_FILES) > $@-t +plot/appearance/PKG_ADD: $(plot_appearance_FCN_FILES) $(plot_appearance_GEN_FCN_FILES) plot/appearance/$(octave_dirstamp) mk-pkg-add + $(srcdir)/mk-pkg-add $(srcdir) $(plot_appearance_FCN_FILES) -- $(plot_appearance_GEN_FCN_FILES) > $@-t + mv $@-t $@ + +plot/draw/PKG_ADD: $(plot_draw_FCN_FILES) $(plot_draw_GEN_FCN_FILES) plot/draw/$(octave_dirstamp) mk-pkg-add + $(srcdir)/mk-pkg-add $(srcdir) $(plot_draw_FCN_FILES) -- $(plot_draw_GEN_FCN_FILES) > $@-t + mv $@-t $@ + +plot/util/PKG_ADD: $(plot_util_FCN_FILES) $(plot_util_GEN_FCN_FILES) plot/util/$(octave_dirstamp) mk-pkg-add + $(srcdir)/mk-pkg-add $(srcdir) $(plot_util_FCN_FILES) -- $(plot_util_GEN_FCN_FILES) > $@-t mv $@-t $@ polynomial/PKG_ADD: $(polynomial_FCN_FILES) $(polynomial_GEN_FCN_FILES) polynomial/$(octave_dirstamp) mk-pkg-add @@ -224,6 +237,7 @@ $(elfun_GEN_FCN_FILES): elfun/$(octave_dirstamp) $(general_GEN_FCN_FILES): general/$(octave_dirstamp) $(geometry_GEN_FCN_FILES): geometry/$(octave_dirstamp) +$(gui_GEN_FCN_FILES): gui/$(octave_dirstamp) $(help_GEN_FCN_FILES): help/$(octave_dirstamp) $(image_GEN_FCN_FILES): image/$(octave_dirstamp) $(io_GEN_FCN_FILES): io/$(octave_dirstamp) @@ -233,7 +247,9 @@ $(optimization_GEN_FCN_FILES): optimization/$(octave_dirstamp) $(path_GEN_FCN_FILES): path/$(octave_dirstamp) $(pkg_GEN_FCN_FILES): pkg/$(octave_dirstamp) -$(plot_GEN_FCN_FILES): plot/$(octave_dirstamp) +$(plot_appearance_GEN_FCN_FILES): plot/appearance/$(octave_dirstamp) +$(plot_draw_GEN_FCN_FILES): plot/draw/$(octave_dirstamp) +$(plot_util_GEN_FCN_FILES): plot/util/$(octave_dirstamp) $(polynomial_GEN_FCN_FILES): polynomial/$(octave_dirstamp) $(prefs_GEN_FCN_FILES): prefs/$(octave_dirstamp) $(set_GEN_FCN_FILES): set/$(octave_dirstamp) @@ -269,6 +285,9 @@ geometry/$(octave_dirstamp): $(MKDIR_P) geometry : > geometry/$(octave_dirstamp) +gui/$(octave_dirstamp): + $(MKDIR_P) gui + : > gui/$(octave_dirstamp) help/$(octave_dirstamp): $(MKDIR_P) help : > help/$(octave_dirstamp) @@ -296,9 +315,15 @@ pkg/$(octave_dirstamp): $(MKDIR_P) pkg : > pkg/$(octave_dirstamp) -plot/$(octave_dirstamp): - $(MKDIR_P) plot - : > plot/$(octave_dirstamp) +plot/appearance/$(octave_dirstamp): + $(MKDIR_P) plot/appearance + : > plot/appearance/$(octave_dirstamp) +plot/draw/$(octave_dirstamp): + $(MKDIR_P) plot/draw + : > plot/draw/$(octave_dirstamp) +plot/util/$(octave_dirstamp): + $(MKDIR_P) plot/util + : > plot/util/$(octave_dirstamp) polynomial/$(octave_dirstamp): $(MKDIR_P) polynomial : > polynomial/$(octave_dirstamp) diff -r 20d1b911b4e7 -r c702371ff6df scripts/audio/lin2mu.m --- a/scripts/audio/lin2mu.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/audio/lin2mu.m Sat Oct 05 11:22:09 2013 -0400 @@ -74,3 +74,4 @@ y = 64 * sig - 16 * e - fix (32 * f) + 335; endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/audio/loadaudio.m --- a/scripts/audio/loadaudio.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/audio/loadaudio.m Sat Oct 05 11:22:09 2013 -0400 @@ -79,3 +79,4 @@ fclose (num); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/audio/mu2lin.m --- a/scripts/audio/mu2lin.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/audio/mu2lin.m Sat Oct 05 11:22:09 2013 -0400 @@ -80,3 +80,4 @@ endif endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/audio/record.m --- a/scripts/audio/record.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/audio/record.m Sat Oct 05 11:22:09 2013 -0400 @@ -63,3 +63,4 @@ X = Y - 127; endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/audio/saveaudio.m --- a/scripts/audio/saveaudio.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/audio/saveaudio.m Sat Oct 05 11:22:09 2013 -0400 @@ -86,3 +86,4 @@ fclose (num); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/audio/setaudio.m --- a/scripts/audio/setaudio.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/audio/setaudio.m Sat Oct 05 11:22:09 2013 -0400 @@ -41,3 +41,4 @@ endif endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/audio/wavread.m --- a/scripts/audio/wavread.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/audio/wavread.m Sat Oct 05 11:22:09 2013 -0400 @@ -177,8 +177,8 @@ length = (param(2)-param(1)+1) * channels; elseif (nparams == 4 && char (param) == "size") ## Size of the file is requested. - tmp = idivide (8 * data_size, channels * bits_per_sample); - y = [tmp, channels]; + y = idivide (8 * data_size, channels * bits_per_sample); + samples_per_sec = channels; return; else error ("wavread: invalid PARAM argument"); diff -r 20d1b911b4e7 -r c702371ff6df scripts/audio/wavwrite.m --- a/scripts/audio/wavwrite.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/audio/wavwrite.m Sat Oct 05 11:22:09 2013 -0400 @@ -154,46 +154,65 @@ %! fname = tmpnam (); %!test -%! A = [-1:0.1:1; -1:0.1:1]; +%! A = [-1:0.1:1; -1:0.1:1]'; %! wavwrite (A, fname); %! [B, samples_per_sec, bits_per_sample] = wavread (fname); +%! unlink (fname); %! assert (A,B, 1/2^15); %! assert (samples_per_sec, 8000); %! assert (bits_per_sample, 16); -%! unlink (fname); -% + %!test -%! A = [-1:0.1:1; -1:0.1:1]; +%! A = [-1:0.1:1; -1:0.1:1]'; %! wavwrite (A, 4000, fname); %! [B, samples_per_sec, bits_per_sample] = wavread (fname); +%! unlink (fname); %! assert (A,B, 1/2^15); %! assert (samples_per_sec, 4000); %! assert (bits_per_sample, 16); -%! unlink (fname); -% + %!test -%! A = [-1:0.1:1; -1:0.1:1]; +%! A = [-1:0.1:1; -1:0.1:1]'; %! wavwrite (A, 4000, 8, fname); %! [B, samples_per_sec, bits_per_sample] = wavread (fname); +%! unlink (fname); %! assert (A,B, 1/128); %! assert (samples_per_sec, 4000); %! assert (bits_per_sample, 8); -%! unlink (fname); -% + %!test %! A = [-2:2]'; %! wavwrite (A, fname); %! B = wavread (fname); +%! unlink (fname); %! B *= 32768; %! assert (B, [-32768 -32768 0 32767 32767]'); -%! unlink (fname); -% + %!test %! A = [-1:0.1:1]; %! wavwrite (A, fname); %! [B, samples_per_sec, bits_per_sample] = wavread (fname); +%! unlink (fname); %! assert (A', B, 1/2^15); %! assert (samples_per_sec, 8000); %! assert (bits_per_sample, 16); + +%!test +%! A = [-1:0.1:1; -1:0.1:1]'; +%! wavwrite (A, fname); +%! B = wavread (fname, 15); %! unlink (fname); +%! assert (A(1:15,:) ,B, 1/2^15); +%! wavwrite (A, fname); +%! B = wavread (fname, [10, 20]); +%! unlink (fname); +%! assert (A(10:20,:) ,B, 1/2^15); +%!test +%! A = [-1:0.1:1; -1:0.1:1]'; +%! wavwrite (A, fname); +%! [nsamp, nchan] = wavread (fname, "size"); +%! unlink (fname); +%! assert (nsamp, 21); +%! assert (nchan, 2); + diff -r 20d1b911b4e7 -r c702371ff6df scripts/deprecated/__error_text__.m --- a/scripts/deprecated/__error_text__.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/deprecated/__error_text__.m Sat Oct 05 11:22:09 2013 -0400 @@ -34,3 +34,4 @@ [msg, msgid] = lasterr (varargin{:}); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/deprecated/cut.m --- a/scripts/deprecated/cut.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/deprecated/cut.m Sat Oct 05 11:22:09 2013 -0400 @@ -69,3 +69,4 @@ endif endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/deprecated/error_text.m --- a/scripts/deprecated/error_text.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/deprecated/error_text.m Sat Oct 05 11:22:09 2013 -0400 @@ -34,3 +34,4 @@ [msg, msgid] = lasterr (varargin{:}); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/deprecated/isequalwithequalnans.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/deprecated/isequalwithequalnans.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,50 @@ +## Copyright (C) 2005-2012 William Poetra Yoga Hadisoeseno +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {} isequalwithequalnans (@var{x1}, @var{x2}, @dots{}) +## This function has been deprecated. Use @code{@file{isequaln}} instead. +## @seealso{isequaln} +## @end deftypefn + +## Deprecated in 3.8 + +function retval = isequalwithequalnans (varargin) + + persistent warned = false; + if (! warned) + warned = true; + warning ("Octave:deprecated-function", + "isequalwithequalnans is obsolete and will be removed from a future version of Octave, please use isequaln instead"); + endif + + retval = isequaln (varargin{:}); + +endfunction + + +## test for equality +%!assert (isequalwithequalnans ({1,2,NaN,4},{1,2,NaN,4}), true) +%!assert (isequalwithequalnans ([1,2,NaN,4],[1,2,NaN,4]), true) +## test for inequality +%!assert (isequalwithequalnans ([1,2,NaN,4],[1,NaN,3,4]), false) +%!assert (isequalwithequalnans ([1,2,NaN,4],[1,2,3,4]), false) +## test for equality (struct) +%!assert (isequalwithequalnans (struct ('a',NaN,'b',2),struct ('a',NaN,'b',2),struct ('a',NaN,'b',2)), true) +%!assert (isequalwithequalnans (1,2,1), false) + diff -r 20d1b911b4e7 -r c702371ff6df scripts/deprecated/isstr.m --- a/scripts/deprecated/isstr.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/deprecated/isstr.m Sat Oct 05 11:22:09 2013 -0400 @@ -38,3 +38,4 @@ retval = ischar (varargin{:}); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/deprecated/java_convert_matrix.m --- a/scripts/deprecated/java_convert_matrix.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/deprecated/java_convert_matrix.m Sat Oct 05 11:22:09 2013 -0400 @@ -23,9 +23,9 @@ ## Query or set the internal variable that controls whether Java arrays are ## automatically converted to Octave matrices. The default value is false. ## -## When called from inside a function with the "local" option, the variable is -## changed locally for the function and any subroutines it calls. The original -## variable value is restored when exiting the function. +## When called from inside a function with the @qcode{"local"} option, the +## variable is changed locally for the function and any subroutines it calls. +## The original variable value is restored when exiting the function. ## @seealso{java_matrix_autoconversion, java_unsigned_conversion, java_debug} ## @end deftypefn diff -r 20d1b911b4e7 -r c702371ff6df scripts/deprecated/java_debug.m --- a/scripts/deprecated/java_debug.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/deprecated/java_debug.m Sat Oct 05 11:22:09 2013 -0400 @@ -24,9 +24,9 @@ ## information regarding the initialization of the JVM and any Java exceptions ## is printed. ## -## When called from inside a function with the "local" option, the variable is -## changed locally for the function and any subroutines it calls. The original -## variable value is restored when exiting the function. +## When called from inside a function with the @qcode{"local"} option, the +## variable is changed locally for the function and any subroutines it calls. +## The original variable value is restored when exiting the function. ## @seealso{debug_java, java_convert_matrix, java_unsigned_conversion} ## @end deftypefn diff -r 20d1b911b4e7 -r c702371ff6df scripts/deprecated/java_unsigned_conversion.m --- a/scripts/deprecated/java_unsigned_conversion.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/deprecated/java_unsigned_conversion.m Sat Oct 05 11:22:09 2013 -0400 @@ -25,9 +25,9 @@ ## arrays of class Byte or Integer are converted to matrices of class uint8 or ## uint32 respectively. ## -## When called from inside a function with the "local" option, the variable is -## changed locally for the function and any subroutines it calls. The original -## variable value is restored when exiting the function. +## When called from inside a function with the @qcode{"local"} option, the +## variable is changed locally for the function and any subroutines it calls. +## The original variable value is restored when exiting the function. ## @seealso{java_unsigned_autoconversion, java_convert_matrix, debug_java} ## @end deftypefn diff -r 20d1b911b4e7 -r c702371ff6df scripts/deprecated/module.mk --- a/scripts/deprecated/module.mk Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/deprecated/module.mk Sat Oct 05 11:22:09 2013 -0400 @@ -9,6 +9,7 @@ deprecated/java_debug.m \ deprecated/error_text.m \ deprecated/gen_doc_cache.m \ + deprecated/isequalwithequalnans.m \ deprecated/isstr.m \ deprecated/java_convert_matrix.m \ deprecated/java_get.m \ diff -r 20d1b911b4e7 -r c702371ff6df scripts/deprecated/polyderiv.m --- a/scripts/deprecated/polyderiv.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/deprecated/polyderiv.m Sat Oct 05 11:22:09 2013 -0400 @@ -98,6 +98,7 @@ endfunction + %!assert(all (all (polyderiv ([1, 2, 3]) == [2, 2]))); %!assert(polyderiv (13) == 0); diff -r 20d1b911b4e7 -r c702371ff6df scripts/deprecated/shell_cmd.m --- a/scripts/deprecated/shell_cmd.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/deprecated/shell_cmd.m Sat Oct 05 11:22:09 2013 -0400 @@ -23,11 +23,11 @@ ## @deftypefnx {Built-in Function} {[@var{status}, @var{output}] =} shell_cmd (@dots{}) ## @deftypefnx {Built-in Function} {[@var{status}, @var{output}] =} shell_cmd (@var{string}, @var{return_output}, @var{type}) ## Execute a shell command specified by @var{string}. -## If the optional argument @var{type} is "async", the process +## If the optional argument @var{type} is @qcode{"async"}, the process ## is started in the background and the process id of the child process ## is returned immediately. Otherwise, the process is started and ## Octave waits until it exits. If the @var{type} argument is omitted, it -## defaults to a value of "sync". +## defaults to a value of @qcode{"sync"}. ## ## If the optional argument @var{return_output} is true and the subprocess ## is started synchronously, or if @var{shell_cmd} is called with one input diff -r 20d1b911b4e7 -r c702371ff6df scripts/deprecated/studentize.m --- a/scripts/deprecated/studentize.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/deprecated/studentize.m Sat Oct 05 11:22:09 2013 -0400 @@ -78,6 +78,7 @@ endfunction + %!assert(studentize ([1,2,3]), [-1,0,1]) %!assert(studentize (int8 ([1,2,3])), [-1,0,1]) #%!assert(studentize (ones (3,2,0,2)), zeros (3,2,0,2)) diff -r 20d1b911b4e7 -r c702371ff6df scripts/deprecated/sylvester_matrix.m --- a/scripts/deprecated/sylvester_matrix.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/deprecated/sylvester_matrix.m Sat Oct 05 11:22:09 2013 -0400 @@ -57,6 +57,7 @@ endfunction + %!assert((sylvester_matrix (1) == [1, 1; 1, -1] %! && (sylvester_matrix (2) %! == [1, 1, 1, 1; 1, -1, 1, -1; 1, 1, -1, -1; 1, -1, -1, 1]))); diff -r 20d1b911b4e7 -r c702371ff6df scripts/elfun/atan2d.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/elfun/atan2d.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,41 @@ +## Copyright (C) 2013 Rik Wehbring +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {} atan2d (@var{y}, @var{x}) +## Compute atan2 (@var{y} / @var{x}) in degrees for corresponding elements +## from @var{y} and @var{x}. +## @seealso{tand, atan2} +## @end deftypefn + +function retval = atan2d (y, x) + + if (nargin != 2) + print_usage (); + endif + + retval = 180 ./ pi .* atan2 (y, x); + +endfunction + + +%!assert (atan2d (-1:.1:1, 1:-.1:-1), 180/pi * atan2 (-1:.1:1, 1:-.1:-1), -10*eps) + +%!error atan2d () +%!error atan2d (1) + diff -r 20d1b911b4e7 -r c702371ff6df scripts/elfun/module.mk --- a/scripts/elfun/module.mk Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/elfun/module.mk Sat Oct 05 11:22:09 2013 -0400 @@ -12,6 +12,7 @@ elfun/asecd.m \ elfun/asech.m \ elfun/asind.m \ + elfun/atan2d.m \ elfun/atand.m \ elfun/cosd.m \ elfun/cot.m \ diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/accumarray.m --- a/scripts/general/accumarray.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/accumarray.m Sat Oct 05 11:22:09 2013 -0400 @@ -61,7 +61,7 @@ ## that in the first column counts how many occurrences each number in ## the second column has, taken from the vector @var{x}. Note the usage ## of @code{unique} for assigning to all repeated elements of @var{x} -## the same index (@pxref{docXunique}). +## the same index (@pxref{XREFunique,,unique}). ## ## @example ## @group @@ -92,7 +92,7 @@ ## @end example ## ## The sparse option can be used as an alternative to the @code{sparse} -## constructor (@pxref{docXsparse}). Thus +## constructor (@pxref{XREFsparse,,sparse}). Thus ## ## @example ## sparse (@var{i}, @var{j}, @var{sv}) diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/accumdim.m --- a/scripts/general/accumdim.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/accumdim.m Sat Oct 05 11:22:09 2013 -0400 @@ -108,7 +108,7 @@ subsc{dim} = mask; A(subsc{:}) = fillval; endif - return + return; endif ## The general case. diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/bicubic.m --- a/scripts/general/bicubic.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/bicubic.m Sat Oct 05 11:22:09 2013 -0400 @@ -221,6 +221,7 @@ endfunction + %!demo %! clf; %! colormap ("default"); diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/bitcmp.m --- a/scripts/general/bitcmp.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/bitcmp.m Sat Oct 05 11:22:09 2013 -0400 @@ -49,6 +49,9 @@ if (isa (A, "double")) bmax = bitmax; amax = ceil (log2 (bmax)); + elseif (isa (A, "single")) + bmax = bitmax ("single"); + amax = ceil (log2 (bmax)); else if (isa (A, "uint8")) amax = 8; @@ -93,6 +96,13 @@ %! assert (bitcmp (A,Amax-1), bitshift (1,Amax-2)); %! assert (bitcmp (A,Amax-2), 0); %!test +%! Amax = 24; +%! Bmax = bitmax ("single"); +%! A = bitshift (Bmax,-2); +%! assert (bitcmp (A,Amax),bitor (bitshift (single (1),Amax-1), bitshift (single (1),Amax-2))); +%! assert (bitcmp (A,Amax-1), bitshift (single (1),Amax-2)); +%! assert (bitcmp (A,Amax-2), single (0)); +%!test %! Amax = 8; %! Bmax = intmax ("uint8"); %! A = bitshift (Bmax,-2); diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/bitget.m --- a/scripts/general/bitget.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/bitget.m Sat Oct 05 11:22:09 2013 -0400 @@ -39,8 +39,11 @@ endif if (isa (A, "double")) - Amax = log2 (bitmax) + 1; + Amax = ceil (log2 (bitmax)); _conv = @double; + elseif (isa (A, "single")) + Amax = ceil (log2 (bitmax ("single"))); + _conv = @single; else if (isa (A, "uint8")) Amax = 8; @@ -83,6 +86,7 @@ %!test %! assert (bitget ([4, 14], [3, 3]), logical ([1, 1])); +%! assert (bitget (single ([4, 14]), [3, 3]), logical ([1, 1])); %! pfx = {"", "u"}; %! for i = 1:2 %! for prec = [8, 16, 32, 64] @@ -94,6 +98,9 @@ %!error bitget (0, 0) %!error bitget (0, 55) +%!error bitget (single (0), 0) +%!error bitget (single (0), 26) + %!error bitget (int8 (0), 9) %!error bitget (uint8 (0), 9) diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/bitset.m --- a/scripts/general/bitset.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/bitset.m Sat Oct 05 11:22:09 2013 -0400 @@ -54,10 +54,10 @@ if (isfloat (A) && isreal (A)) Bmax = bitmax (cl); - Amax = log2 (Bmax); + Amax = ceil (log2 (Bmax)); elseif (isinteger (A)) Bmax = intmax (cl); - Amax = round (log2 (Bmax)); + Amax = ceil (log2 (Bmax)); else error ("bitset: invalid class %s", cl); endif @@ -91,6 +91,7 @@ %!test %! assert (bitset ([0, 10], [3, 3]), [4, 14]); +%! assert (bitset (single ([0, 10]), [3, 3]), single ([4, 14])); %! pfx = {"", "u"}; %! for i = 1:2 %! for prec = [8, 16, 32, 64] @@ -108,6 +109,8 @@ %!error bitset ("1", 2) %!error bitset (0, 0) %!error bitset (0, 55) +%!error bitset (single (0), 0) +%!error bitset (single (0), 26) %!error bitset (uint8 (0), 0) %!error bitset (uint8 (0), 9) %!error bitset (int8 (0), 9) diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/cell2mat.m --- a/scripts/general/cell2mat.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/cell2mat.m Sat Oct 05 11:22:09 2013 -0400 @@ -21,8 +21,8 @@ ## @deftypefn {Function File} {@var{m} =} cell2mat (@var{c}) ## Convert the cell array @var{c} into a matrix by concatenating all ## elements of @var{c} into a hyperrectangle. Elements of @var{c} must -## be numeric, logical or char matrices, or cell arrays, and @code{cat} -## must be able to concatenate them together. +## be numeric, logical, or char matrices; or cell arrays; or structs; and +## @code{cat} must be able to concatenate them together. ## @seealso{mat2cell, num2cell} ## @end deftypefn @@ -42,38 +42,48 @@ m = []; else - ## We only want numeric, logical, and char matrices. + ## Check first for valid matrix types valid = cellfun ("isnumeric", c); - valid |= cellfun ("islogical", c); - valid |= cellfun ("isclass", c, "char"); - validc = cellfun ("isclass", c, "cell"); - valids = cellfun ("isclass", c, "struct"); - - if (! all (valid(:)) && ! all (validc(:)) && ! all (valids(:))) - error ("cell2mat: wrong type elements or mixed cells, structs and matrices"); + valid = cellfun ("islogical", c(! valid)); + valid = cellfun ("isclass", c(! valid), "char"); + if (! all (valid(:))) + valid = cellfun ("isclass", c, "cell"); + if (! all (valid(:))) + valid = cellfun ("isclass", c, "struct"); + if (! all (valid(:))) + error ("cell2mat: wrong type elements or mixed cells, structs, and matrices"); + endif + endif endif - ## The goal is to minimize the total number of cat() calls. - ## The dimensions can be concatenated along in arbitrary order. - ## The numbers of concatenations are: - ## n / d1 - ## n / (d1 * d2) - ## n / (d1 * d2 * d3) - ## etc. - ## This is minimized if d1 >= d2 >= d3... + sz = size (c); + if (all (cellfun ("numel", c)(:) == 1)) + ## Special case of all scalars + m = reshape (cat (1, c{:}), sz); + else - sc = size (c); - nd = ndims (c); - [~, isc] = sort (sc); - for idim = isc - if (sc(idim) == 1) - continue; - endif - xdim = [1:idim-1, idim+1:nd]; - cc = num2cell (c, xdim); - c = cellfun ("cat", {idim}, cc{:}, "uniformoutput", false); - endfor - m = c{1}; + ## The goal is to minimize the total number of cat() calls. + ## The dimensions can be concatenated along in arbitrary order. + ## The numbers of concatenations are: + ## n / d1 + ## n / (d1 * d2) + ## n / (d1 * d2 * d3) + ## etc. + ## This is minimized if d1 >= d2 >= d3... + + nd = ndims (c); + [~, isz] = sort (sz, "descend"); + for idim = isz + if (sz(idim) == 1) + continue; + endif + xdim = [1:idim-1, idim+1:nd]; + cc = num2cell (c, xdim); + c = cellfun ("cat", {idim}, cc{:}, "uniformoutput", false); + endfor + m = c{1}; + + endif endif endfunction @@ -103,3 +113,10 @@ %! m = {1, 2, 3}; %! assert (cell2mat (mat2cell (m, 1, [1 1 1])), m); +%!error cell2mat () +%!error cell2mat (1,2) +%!error cell2mat ([1,2]) +%!error cell2mat ({[1], struct()}) +%!error cell2mat ({[1], {1}}) +%!error cell2mat ({struct(), {1}}) + diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/celldisp.m --- a/scripts/general/celldisp.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/celldisp.m Sat Oct 05 11:22:09 2013 -0400 @@ -89,3 +89,4 @@ %!error celldisp () %!error celldisp ({}, "name", 1) %!error celldisp (1) + diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/colon.m --- a/scripts/general/colon.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/colon.m Sat Oct 05 11:22:09 2013 -0400 @@ -43,3 +43,4 @@ %!error colon (1) ## FIXME -- what does colon () mean since it doesn't set a return value? + diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/cplxpair.m --- a/scripts/general/cplxpair.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/cplxpair.m Sat Oct 05 11:22:09 2013 -0400 @@ -161,6 +161,6 @@ %!assert (cplxpair ([z(randperm(7)),z(randperm(7))],[],1), [z,z]) %!assert (cplxpair ([z(randperm(7)).';z(randperm(7)).'],[],2), [z.';z.']) -%!## tolerance test +## tolerance test %!assert (cplxpair ([1i, -1i, 1+(1i*eps)],2*eps), [-1i, 1i, 1+(1i*eps)]) - + diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/dblquad.m --- a/scripts/general/dblquad.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/dblquad.m Sat Oct 05 11:22:09 2013 -0400 @@ -40,7 +40,8 @@ ## is @code{quadcc}. ## ## Additional arguments, are passed directly to @var{f}. To use the default -## value for @var{tol} or @var{quadf} one may pass ':' or an empty matrix ([]). +## value for @var{tol} or @var{quadf} one may pass @qcode{':'} or an empty +## matrix ([]). ## @seealso{triplequad, quad, quadv, quadl, quadgk, quadcc, trapz} ## @end deftypefn diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/del2.m --- a/scripts/general/del2.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/del2.m Sat Oct 05 11:22:09 2013 -0400 @@ -157,3 +157,4 @@ D = D ./ nd; endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/display.m --- a/scripts/general/display.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/display.m Sat Oct 05 11:22:09 2013 -0400 @@ -19,7 +19,7 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} display (@var{a}) ## Display the contents of an object. If @var{a} is an object of the -## class "myclass", then @code{display} is called in a case like +## class @qcode{"myclass"}, then @code{display} is called in a case like ## ## @example ## myclass (@dots{}) @@ -27,7 +27,7 @@ ## ## @noindent ## where Octave is required to display the contents of a variable of the -## type "myclass". +## type @qcode{"myclass"}. ## ## @seealso{class, subsref, subsasgn} ## @end deftypefn @@ -48,3 +48,4 @@ endif endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/fieldnames.m --- a/scripts/general/fieldnames.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/fieldnames.m Sat Oct 05 11:22:09 2013 -0400 @@ -31,7 +31,7 @@ ## properties of the object. ## ## When the input is a Java object @var{javaobj} or Java classname -## @var{jclassname}) the name are the public data elements of the object or +## @var{jclassname} the name are the public data elements of the object or ## class. ## @seealso{struct, methods} ## @end deftypefn diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/genvarname.m --- a/scripts/general/genvarname.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/genvarname.m Sat Oct 05 11:22:09 2013 -0400 @@ -82,14 +82,15 @@ ## an underscore. Also, variables may not begin with a digit; in this ## case an underscore is added before the variable name. ## -## Variable names beginning and ending with two underscores "__" are valid but -## they are used internally by octave and should generally be avoided, therefore -## genvarname will not generate such names. +## Variable names beginning and ending with two underscores @qcode{"__"} are +## valid but they are used internally by octave and should generally be +## avoided, therefore genvarname will not generate such names. ## ## genvarname will also make sure that returned names do not clash with -## keywords such as "for" and "if". A number will be appended if necessary. -## Note, however, that this does @strong{not} include function names, -## such as "sin". Such names should be included in @var{avoid} if necessary. +## keywords such as @qcode{"for"} and @qcode{"if"}. A number will be +## appended if necessary. Note, however, that this does @strong{not} include +## function names, such as @qcode{"sin"}. Such names should be included in +## @var{avoid} if necessary. ## @seealso{isvarname, exist, tmpnam, eval} ## @end deftypefn @@ -119,7 +120,7 @@ error ("genvarname: STR must be a string or a cellstr"); endif - validchars = cstrcat ("A":"Z", "a":"z", "0":"9", "_"); + validchars = ["A":"Z", "a":"z", "0":"9", "_"]; varname = cell (size (str)); for i = 1:numel (str) @@ -130,7 +131,7 @@ str{i}(! ismember (str{i}, validchars)) = "_"; ## do not use keywords if (iskeyword (str{i})) - str{i} = cstrcat ("_", str{i}); + str{i} = ["_" str{i}]; endif ## double underscores at the beginning and end are reserved variables underscores = (str{i} == "_"); @@ -145,7 +146,7 @@ endif ## it cannot start with a number if (ismember (str{i}(1), "0":"9")) - str{i} = cstrcat ("_", str{i}); + str{i} = ["_" str{i}]; endif ## make sure that the variable is unique relative to other variables diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/idivide.m --- a/scripts/general/idivide.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/idivide.m Sat Oct 05 11:22:09 2013 -0400 @@ -28,25 +28,25 @@ ## a string with one of the values: ## ## @table @asis -## @item "fix" +## @item @qcode{"fix"} ## Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded ## towards zero. ## -## @item "round" +## @item @qcode{"round"} ## Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded ## towards the nearest integer. ## -## @item "floor" +## @item @qcode{"floor"} ## Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded ## towards negative infinity. ## -## @item "ceil" +## @item @qcode{"ceil"} ## Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded ## towards positive infinity. ## @end table ## ## @noindent -## If @var{op} is not given it defaults to @code{"fix"}. +## If @var{op} is not given it defaults to @qcode{"fix"}. ## An example demonstrating these rounding rules is ## ## @example diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/int2str.m --- a/scripts/general/int2str.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/int2str.m Sat Oct 05 11:22:09 2013 -0400 @@ -67,9 +67,9 @@ ifmt = get_fmt (n(idx{:}), 0); idx(2) = 2:sz(2); rfmt = get_fmt (n(idx{:}), 2); - fmt = cstrcat (ifmt, repmat (rfmt, 1, nc-1), "\n"); + fmt = [ifmt repmat(rfmt,1,nc-1) "\n"]; else - fmt = cstrcat (get_fmt (n, 0), "\n"); + fmt = [get_fmt(n, 0) "\n"]; endif tmp = sprintf (fmt, permute (n, [2, 1, 3 : nd])); tmp(end) = ""; @@ -86,7 +86,7 @@ fmt = sprintf ("%%%dd", 1 + sep); else ## Maybe have some zeros. - nan_inf = isinf (t) | isnan (t); + nan_inf = ! isfinite (t); if (any (nan_inf)) if (any (t(nan_inf) < 0)) min_fw = 4 + sep; diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/interp1.m --- a/scripts/general/interp1.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/interp1.m Sat Oct 05 11:22:09 2013 -0400 @@ -26,25 +26,25 @@ ## ## One-dimensional interpolation. Interpolates to determine the value of ## @var{yi} at the points, @var{xi}. If not specified, @var{x} is taken -## to be the indices of @var{y}. If @var{y} is an array, treat the columns -## of @var{y} separately. +## to be the indices of @var{y}. If @var{y} is a matrix or an N-dimensional +## array, the interpolation is performed on each column of @var{y}. ## ## Method is one of: ## ## @table @asis -## @item "nearest" +## @item @qcode{"nearest"} ## Return the nearest neighbor. ## -## @item "linear" +## @item @qcode{"linear"} ## Linear interpolation from nearest neighbors ## -## @item "pchip" +## @item @qcode{"pchip"} ## Piecewise cubic Hermite interpolating polynomial ## -## @item "cubic" +## @item @qcode{"cubic"} ## Cubic interpolation (same as @code{pchip}) ## -## @item "spline" +## @item @qcode{"spline"} ## Cubic spline interpolation---smooth first and second derivatives ## throughout the curve ## @end table @@ -52,18 +52,18 @@ ## Appending '*' to the start of the above method forces @code{interp1} ## to assume that @var{x} is uniformly spaced, and only @code{@var{x}(1)} ## and @code{@var{x}(2)} are referenced. This is usually faster, -## and is never slower. The default method is "linear". +## and is never slower. The default method is @qcode{"linear"}. ## -## If @var{extrap} is the string "extrap", then extrapolate values beyond -## the endpoints. If @var{extrap} is a number, replace values beyond the -## endpoints with that number. If @var{extrap} is missing, assume NA. +## If @var{extrap} is the string @qcode{"extrap"}, then extrapolate values +## beyond the endpoints. If @var{extrap} is a number, replace values beyond +## the endpoints with that number. If @var{extrap} is missing, assume NA. ## -## If the string argument "pp" is specified, then @var{xi} should not be +## If the string argument @qcode{"pp"} is specified, then @var{xi} should not be ## supplied and @code{interp1} returns the piecewise polynomial that ## can later be used with @code{ppval} to evaluate the interpolation. ## There is an equivalence, such that @code{ppval (interp1 (@var{x}, -## @var{y}, @var{method}, "pp"), @var{xi}) == interp1 (@var{x}, @var{y}, -## @var{xi}, @var{method}, "extrap")}. +## @var{y}, @var{method}, @qcode{"pp"}), @var{xi}) == interp1 (@var{x}, @var{y}, +## @var{xi}, @var{method}, @qcode{"extrap"})}. ## ## Duplicate points in @var{x} specify a discontinuous interpolant. There ## may be at most 2 consecutive points with the same value. @@ -71,10 +71,11 @@ ## right-continuous. If @var{x} is decreasing, the default discontinuous ## interpolant is left-continuous. ## The continuity condition of the interpolant may be specified by using -## the options, "-left" or "-right", to select a left-continuous +## the options, @qcode{"-left"} or @qcode{"-right"}, to select a left-continuous ## or right-continuous interpolant, respectively. -## Discontinuous interpolation is only allowed for "nearest" and "linear" -## methods; in all other cases, the @var{x}-values must be unique. +## Discontinuous interpolation is only allowed for @qcode{"nearest"} and +## @qcode{"linear"} methods; in all other cases, the @var{x}-values must be +## unique. ## ## An example of the use of @code{interp1} is ## @@ -149,7 +150,11 @@ if (isempty (xi) && firstnumeric && ! ispp) xi = y; y = x; - x = 1:numel (y); + if (isvector (y)) + x = 1:numel (y); + else + x = 1:rows (y); + endif endif ## reshape matrices for convenience @@ -182,15 +187,15 @@ rightcontinuous = false; else rightcontinuous = true; - end + endif endif if ((rightcontinuous && (x(end) < x(1))) - || (~ rightcontinuous && (x(end) > x(1)))) + || (! rightcontinuous && (x(end) > x(1)))) ## Switch between left-continuous and right-continuous x = flipud (x); y = flipud (y); - end + endif starmethod = method(1) == "*"; @@ -212,91 +217,93 @@ ## Proceed with interpolating by all methods. switch (method) - case "nearest" - pp = mkpp ([x(1); (x(1:nx-1)+x(2:nx))/2; x(nx)], shiftdim (y, 1), szy(2:end)); - pp.orient = "first"; + case "nearest" + pp = mkpp ([x(1); (x(1:nx-1)+x(2:nx))/2; x(nx)], + shiftdim (y, 1), szy(2:end)); + pp.orient = "first"; - if (ispp) - yi = pp; - else - yi = ppval (pp, reshape (xi, szx)); - endif - case "*nearest" - pp = mkpp ([x(1), x(1)+[0.5:(nx-1)]*dx, x(nx)], shiftdim (y, 1), szy(2:end)); - pp.orient = "first"; - if (ispp) - yi = pp; - else - yi = ppval (pp, reshape (xi, szx)); - endif - case "linear" - dy = diff (y); - dx = diff (x); - dx = repmat (dx, [1 size(dy)(2:end)]); - coefs = [(dy./dx).'(:), y(1:nx-1, :).'(:)]; - xx = x; + if (ispp) + yi = pp; + else + yi = ppval (pp, reshape (xi, szx)); + endif + case "*nearest" + pp = mkpp ([x(1), x(1)+[0.5:(nx-1)]*dx, x(nx)], + shiftdim (y, 1), szy(2:end)); + pp.orient = "first"; + if (ispp) + yi = pp; + else + yi = ppval (pp, reshape (xi, szx)); + endif + case "linear" + dy = diff (y); + dx = diff (x); + dx = repmat (dx, [1 size(dy)(2:end)]); + coefs = [(dy./dx).'(:), y(1:nx-1, :).'(:)]; + xx = x; - if (have_jumps) - ## Omit zero-size intervals. - coefs(jumps, :) = []; - xx(jumps) = []; - endif + if (have_jumps) + ## Omit zero-size intervals. + coefs(jumps, :) = []; + xx(jumps) = []; + endif - pp = mkpp (xx, coefs, szy(2:end)); - pp.orient = "first"; + pp = mkpp (xx, coefs, szy(2:end)); + pp.orient = "first"; - if (ispp) - yi = pp; - else - yi = ppval (pp, reshape (xi, szx)); - endif + if (ispp) + yi = pp; + else + yi = ppval (pp, reshape (xi, szx)); + endif - case "*linear" - dy = diff (y); - coefs = [(dy/dx).'(:), y(1:nx-1, :).'(:)]; - pp = mkpp (x, coefs, szy(2:end)); - pp.orient = "first"; + case "*linear" + dy = diff (y); + coefs = [(dy/dx).'(:), y(1:nx-1, :).'(:)]; + pp = mkpp (x, coefs, szy(2:end)); + pp.orient = "first"; - if (ispp) - yi = pp; - else - yi = ppval (pp, reshape (xi, szx)); - endif + if (ispp) + yi = pp; + else + yi = ppval (pp, reshape (xi, szx)); + endif - case {"pchip", "*pchip", "cubic", "*cubic"} - if (nx == 2 || starmethod) - x = linspace (x(1), x(nx), ny); - endif + case {"pchip", "*pchip", "cubic", "*cubic"} + if (nx == 2 || starmethod) + x = linspace (x(1), x(nx), ny); + endif - if (ispp) - y = shiftdim (reshape (y, szy), 1); - yi = pchip (x, y); - yi.orient = "first"; - else - y = shiftdim (y, 1); - yi = pchip (x, y, reshape (xi, szx)); - if (! isvector (y)) - yi = shiftdim (yi, 1); + if (ispp) + y = shiftdim (reshape (y, szy), 1); + yi = pchip (x, y); + yi.orient = "first"; + else + y = shiftdim (y, 1); + yi = pchip (x, y, reshape (xi, szx)); + if (! isvector (y)) + yi = shiftdim (yi, 1); + endif + endif + case {"spline", "*spline"} + if (nx == 2 || starmethod) + x = linspace (x(1), x(nx), ny); endif - endif - case {"spline", "*spline"} - if (nx == 2 || starmethod) - x = linspace (x(1), x(nx), ny); - endif - if (ispp) - y = shiftdim (reshape (y, szy), 1); - yi = spline (x, y); - yi.orient = "first"; - else - y = shiftdim (y, 1); - yi = spline (x, y, reshape (xi, szx)); - if (! isvector (y)) - yi = shiftdim (yi, 1); + if (ispp) + y = shiftdim (reshape (y, szy), 1); + yi = spline (x, y); + yi.orient = "first"; + else + y = shiftdim (y, 1); + yi = spline (x, y, reshape (xi, szx)); + if (! isvector (y)) + yi = shiftdim (yi, 1); + endif endif - endif - otherwise - error ("interp1: invalid method '%s'", method); + otherwise + error ("interp1: invalid method '%s'", method); endswitch if (! ispp) diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/interp1q.m --- a/scripts/general/interp1q.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/interp1q.m Sat Oct 05 11:22:09 2013 -0400 @@ -21,9 +21,10 @@ ## One-dimensional linear interpolation without error checking. ## Interpolates @var{y}, defined at the points @var{x}, at the points ## @var{xi}. The sample points @var{x} must be a strictly monotonically -## increasing column vector. If @var{y} is an array, treat the columns -## of @var{y} separately. If @var{y} is a vector, it must be a column -## vector of the same length as @var{x}. +## increasing column vector. If @var{y} is a matrix or an N-dimensional +## array, the interpolation is performed on each column of @var{y}. If +## @var{y} is a vector, it must be a column vector of the same length as +## @var{x}. ## ## Values of @var{xi} beyond the endpoints of the interpolation result ## in NA being returned. diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/interp2.m --- a/scripts/general/interp2.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/interp2.m Sat Oct 05 11:22:09 2013 -0400 @@ -36,8 +36,9 @@ ## matrices @var{xi}, @var{yi}. ## ## If the last argument is a string, the interpolation method can -## be specified. The method can be "linear", "nearest" or "cubic". -## If it is omitted "linear" interpolation is assumed. +## be specified. The method can be @qcode{"linear"}, @qcode{"nearest"} or +## @qcode{"cubic"}. If it is omitted @qcode{"linear"} interpolation is +## assumed. ## ## @item interp2 (@var{z}, @var{xi}, @var{yi}) ## Assumes @code{@var{x} = 1:rows (@var{z})} and @code{@var{y} = @@ -52,19 +53,19 @@ ## interpolation. It can take one of the following values ## ## @table @asis -## @item "nearest" +## @item @qcode{"nearest"} ## Return the nearest neighbor. ## -## @item "linear" +## @item @qcode{"linear"} ## Linear interpolation from nearest neighbors. ## -## @item "pchip" +## @item @qcode{"pchip"} ## Piecewise cubic Hermite interpolating polynomial. ## -## @item "cubic" +## @item @qcode{"cubic"} ## Cubic interpolation from four nearest neighbors. ## -## @item "spline" +## @item @qcode{"spline"} ## Cubic spline interpolation---smooth first and second derivatives ## throughout the curve. ## @end table diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/interp3.m --- a/scripts/general/interp3.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/interp3.m Sat Oct 05 11:22:09 2013 -0400 @@ -28,9 +28,9 @@ ## array @var{v} represents a value at a location given by the parameters ## @var{x}, @var{y}, and @var{z}. The parameters @var{x}, @var{x}, and ## @var{z} are either 3-dimensional arrays of the same size as the array -## @var{v} in the "meshgrid" format or vectors. The parameters @var{xi}, etc. -## respect a similar format to @var{x}, etc., and they represent the points -## at which the array @var{vi} is interpolated. +## @var{v} in the @qcode{"meshgrid"} format or vectors. The parameters +## @var{xi}, etc. respect a similar format to @var{x}, etc., and they +## represent the points at which the array @var{vi} is interpolated. ## ## If @var{x}, @var{y}, @var{z} are omitted, they are assumed to be ## @code{x = 1 : size (@var{v}, 2)}, @code{y = 1 : size (@var{v}, 1)} and @@ -42,25 +42,25 @@ ## Method is one of: ## ## @table @asis -## @item "nearest" +## @item @qcode{"nearest"} ## Return the nearest neighbor. ## -## @item "linear" +## @item @qcode{"linear"} ## Linear interpolation from nearest neighbors. ## -## @item "cubic" +## @item @qcode{"cubic"} ## Cubic interpolation from four nearest neighbors (not implemented yet). ## -## @item "spline" +## @item @qcode{"spline"} ## Cubic spline interpolation---smooth first and second derivatives ## throughout the curve. ## @end table ## -## The default method is "linear". +## The default method is @qcode{"linear"}. ## -## If @var{extrap} is the string "extrap", then extrapolate values beyond -## the endpoints. If @var{extrap} is a number, replace values beyond the -## endpoints with that number. If @var{extrap} is missing, assume NA. +## If @var{extrap} is the string @qcode{"extrap"}, then extrapolate values +## beyond the endpoints. If @var{extrap} is a number, replace values beyond +## the endpoints with that number. If @var{extrap} is missing, assume NA. ## @seealso{interp1, interp2, spline, meshgrid} ## @end deftypefn diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/interpft.m --- a/scripts/general/interpft.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/interpft.m Sat Oct 05 11:22:09 2013 -0400 @@ -22,9 +22,9 @@ ## ## Fourier interpolation. If @var{x} is a vector, then @var{x} is ## resampled with @var{n} points. The data in @var{x} is assumed to be -## equispaced. If @var{x} is an array, then operate along each column of -## the array separately. If @var{dim} is specified, then interpolate -## along the dimension @var{dim}. +## equispaced. If @var{x} is a matrix or an N-dimensional array, the +## interpolation is performed on each column of @var{x}. If @var{dim} is +## specified, then interpolate along the dimension @var{dim}. ## ## @code{interpft} assumes that the interpolated function is periodic, ## and so assumptions are made about the endpoints of the interpolation. @@ -68,9 +68,9 @@ x = permute (x, perm); m = rows (x); - inc = max (1, fix (m/n)); + inc = ceil (m/n); y = fft (x) / m; - k = floor (m / 2); + k = ceil (m / 2); sz = size (x); sz(1) = n * inc - m; @@ -79,6 +79,18 @@ z = cat (1, y(idx{:}), zeros (sz)); idx{1} = k+1:m; z = cat (1, z, y(idx{:})); + + ## When m is an even number of rows, the FFT has a single Nyquist bin. + ## If zero-padded above, distribute the value of the Nyquist bin evenly + ## between the new corresponding positive and negative frequency bins. + if (sz(1) > 0 && k == m/2) + idx{1} = n * inc - k + 1; + tmp = z(idx{:}) / 2; + z(idx{:}) = tmp; + idx{1} = k + 1; + z(idx{:}) = tmp; + endif + z = n * ifft (z); if (inc != 1) @@ -108,6 +120,18 @@ %!assert (interpft (y', n), y', 20*eps); %!assert (interpft ([y,y],n), [y,y], 20*eps); +%% Test case with complex input from bug #39566 +%!test +%! x = (1 + j) * [1:4]'; +%! y = ifft ([15 + 15*j; -6; -1.5 - 1.5*j; 0; -1.5 - 1.5*j; -6*j]); +%! assert (interpft (x, 6), y, 10*eps); + +%% Test for correct spectral symmetry with even/odd lengths +%!assert (max (abs (imag (interpft ([1:8], 20)))), 0, 20*eps); +%!assert (max (abs (imag (interpft ([1:8], 21)))), 0, 21*eps); +%!assert (max (abs (imag (interpft ([1:9], 20)))), 0, 20*eps); +%!assert (max (abs (imag (interpft ([1:9], 21)))), 0, 21*eps); + %% Test input validation %!error interpft () %!error interpft (1) diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/interpn.m --- a/scripts/general/interpn.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/interpn.m Sat Oct 05 11:22:09 2013 -0400 @@ -29,9 +29,9 @@ ## at a location given by the parameters @var{x1}, @var{x2}, @dots{}, @var{xn}. ## The parameters @var{x1}, @var{x2}, @dots{}, @var{xn} are either ## @var{n}-dimensional arrays of the same size as the array @var{v} in -## the "ndgrid" format or vectors. The parameters @var{y1}, etc. respect a -## similar format to @var{x1}, etc., and they represent the points at which -## the array @var{vi} is interpolated. +## the @qcode{"ndgrid"} format or vectors. The parameters @var{y1}, etc. +## respect a similar format to @var{x1}, etc., and they represent the points +## at which the array @var{vi} is interpolated. ## ## If @var{x1}, @dots{}, @var{xn} are omitted, they are assumed to be ## @code{x1 = 1 : size (@var{v}, 1)}, etc. If @var{m} is specified, then @@ -42,21 +42,21 @@ ## Method is one of: ## ## @table @asis -## @item "nearest" +## @item @qcode{"nearest"} ## Return the nearest neighbor. ## -## @item "linear" +## @item @qcode{"linear"} ## Linear interpolation from nearest neighbors. ## -## @item "cubic" +## @item @qcode{"cubic"} ## Cubic interpolation from four nearest neighbors (not implemented yet). ## -## @item "spline" +## @item @qcode{"spline"} ## Cubic spline interpolation---smooth first and second derivatives ## throughout the curve. ## @end table ## -## The default method is "linear". +## The default method is @qcode{"linear"}. ## ## If @var{extrapval} is the scalar value, use it to replace the values ## beyond the endpoints with that number. If @var{extrapval} is missing, diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/isa.m --- a/scripts/general/isa.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/isa.m Sat Oct 05 11:22:09 2013 -0400 @@ -23,13 +23,14 @@ ## @var{classname} may also be one of the following class categories: ## ## @table @asis -## @item "float" -## Floating point value comprising classes "double" and "single". +## @item @qcode{"float"} +## Floating point value comprising classes @qcode{"double"} and +## @qcode{"single"}. ## -## @item "integer" +## @item @qcode{"integer"} ## Integer value comprising classes (u)int8, (u)int16, (u)int32, (u)int64. ## -## @item "numeric" +## @item @qcode{"numeric"} ## Numeric value comprising either a floating point or integer value. ## @end table ## @seealso{class, typeinfo} diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/isdir.m --- a/scripts/general/isdir.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/isdir.m Sat Oct 05 11:22:09 2013 -0400 @@ -19,7 +19,7 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} isdir (@var{f}) ## Return true if @var{f} is a directory. -## @seealso{is_absolute_filename, is_rooted_relative_filename} +## @seealso{exist, stat, is_absolute_filename, is_rooted_relative_filename} ## @end deftypefn function retval = isdir (f) @@ -32,6 +32,7 @@ endfunction + %!assert (isdir (pwd ())) %!assert (! isdir ("this is highly unlikely to be a directory name")) diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/isequal.m --- a/scripts/general/isequal.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/isequal.m Sat Oct 05 11:22:09 2013 -0400 @@ -19,7 +19,7 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} isequal (@var{x1}, @var{x2}, @dots{}) ## Return true if all of @var{x1}, @var{x2}, @dots{} are equal. -## @seealso{isequalwithequalnans} +## @seealso{isequaln} ## @end deftypefn function retval = isequal (x1, varargin) @@ -74,3 +74,12 @@ ## test for inequality (struct) %!assert (isequal (struct ('a',NaN,'b',2),struct ('a',NaN,'b',2),struct ('a',NaN,'b',2)), false) +## test for sparse matrices +%!assert (isequal (sparse (0,1), sparse (0,1)), true) +%!assert (isequal (sparse (0,1), sparse (1,0)), false) +%!assert (isequal (sparse (2, 2), sparse (2, 2)), true) + +## Input validation +%!error isequal () +%!error isequal (1) + diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/isequaln.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/general/isequaln.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,51 @@ +## Copyright (C) 2005-2012 William Poetra Yoga Hadisoeseno +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {} isequaln (@var{x1}, @var{x2}, @dots{}) +## Return true if all of @var{x1}, @var{x2}, @dots{} are equal under the +## additional assumption that NaN == NaN (no comparison of NaN placeholders +## in dataset). +## @seealso{isequal} +## @end deftypefn + +function retval = isequaln (x1, varargin) + + if (nargin < 2) + print_usage (); + endif + + retval = __isequal__ (true, x1, varargin{:}); + +endfunction + + +## test for equality +%!assert (isequaln ({1,2,NaN,4},{1,2,NaN,4}), true) +%!assert (isequaln ([1,2,NaN,4],[1,2,NaN,4]), true) +## test for inequality +%!assert (isequaln ([1,2,NaN,4],[1,NaN,3,4]), false) +%!assert (isequaln ([1,2,NaN,4],[1,2,3,4]), false) +## test for equality (struct) +%!assert (isequaln (struct ('a',NaN,'b',2),struct ('a',NaN,'b',2),struct ('a',NaN,'b',2)), true) +%!assert (isequaln (1,2,1), false) + +## Input validation +%!error isequaln () +%!error isequaln (1) + diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/isequalwithequalnans.m --- a/scripts/general/isequalwithequalnans.m Thu Sep 12 21:08:07 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -## Copyright (C) 2005-2012 William Poetra Yoga Hadisoeseno -## -## 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 -## . - -## -*- texinfo -*- -## @deftypefn {Function File} {} isequalwithequalnans (@var{x1}, @var{x2}, @dots{}) -## Assuming NaN == NaN, return true if all of @var{x1}, @var{x2}, @dots{} -## are equal. -## @seealso{isequal} -## @end deftypefn - -function retval = isequalwithequalnans (x1, varargin) - - if (nargin < 2) - print_usage (); - endif - - retval = __isequal__ (true, x1, varargin{:}); - -endfunction - - -## test for equality -%!assert (isequalwithequalnans ({1,2,NaN,4},{1,2,NaN,4}), true) -%!assert (isequalwithequalnans ([1,2,NaN,4],[1,2,NaN,4]), true) -## test for inequality -%!assert (isequalwithequalnans ([1,2,NaN,4],[1,NaN,3,4]), false) -%!assert (isequalwithequalnans ([1,2,NaN,4],[1,2,3,4]), false) -## test for equality (struct) -%!assert (isequalwithequalnans (struct ('a',NaN,'b',2),struct ('a',NaN,'b',2),struct ('a',NaN,'b',2)), true) -%!assert (isequalwithequalnans (1,2,1), false) - diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/loadobj.m --- a/scripts/general/loadobj.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/loadobj.m Sat Oct 05 11:22:09 2013 -0400 @@ -39,3 +39,4 @@ function b = loadobj (a) error ('loadobj: not defined for class "%s"', class (a)); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/module.mk --- a/scripts/general/module.mk Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/module.mk Sat Oct 05 11:22:09 2013 -0400 @@ -46,7 +46,7 @@ general/iscolumn.m \ general/isdir.m \ general/isequal.m \ - general/isequalwithequalnans.m \ + general/isequaln.m \ general/isrow.m \ general/isscalar.m \ general/issquare.m \ diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/num2str.m --- a/scripts/general/num2str.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/num2str.m Sat Oct 05 11:22:09 2013 -0400 @@ -92,10 +92,9 @@ if (isnumeric (x)) ## Setup a suitable format string, ignoring inf entries dgt = floor (log10 (max (abs (x(!isinf (x(:))))))); - - ## If the whole input array is inf... if (isempty (dgt)) - dgt = 0; + ## If the whole input array is inf... + dgt = 1; endif if (any (x(:) != fix (x(:)))) @@ -115,14 +114,14 @@ fmt = "%3d"; endif endif - fmt = cstrcat (deblank (repmat (fmt, 1, columns (x))), "\n"); + fmt = [deblank(repmat(fmt, 1, columns(x))), "\n"]; nd = ndims (x); tmp = sprintf (fmt, permute (x, [2, 1, 3:nd])); retval = strtrim (char (ostrsplit (tmp(1:end-1), "\n"))); else # Complex matrix input if (nargin == 2) if (ischar (arg)) - fmt = cstrcat (arg, "%-+", arg(2:end), "i"); + fmt = [arg "%-+" arg(2:end) "i"]; elseif (isnumeric (arg) && isscalar (arg) && arg >= 0) fmt = sprintf ("%%%d.%dg%%-+%d.%dgi", arg+7, arg, arg+7, arg); else @@ -130,8 +129,13 @@ endif else ## Setup a suitable format string - dgt = floor (log10 (max (max (abs (real (x(:)))), - max (abs (imag (x(:))))))); + dgt = floor (log10 (max (max (abs (real (x(!isinf (real (x(:))))))), + max (abs (imag (x(!isinf (imag (x(:)))))))))); + if (isempty (dgt)) + ## If the whole input array is inf... + dgt = 1; + endif + if (any (x(:) != fix (x(:)))) ## Floating point input dgt = max (dgt + 4, 5); # Keep 4 sig. figures after decimal point @@ -157,7 +161,7 @@ x = horzcat (real (x), imag (x)); x = x(idx{:}); - fmt = cstrcat (deblank (repmat (fmt, 1, nc)), "\n"); + fmt = [deblank(repmat(fmt, 1, nc)), "\n"]; tmp = sprintf (fmt, permute (x, [2, 1, 3:nd])); ## Put the "i"'s where they are supposed to be. @@ -183,7 +187,16 @@ %!assert (num2str (2^33+1i), "8589934592+1i") %!assert (num2str (-2^33+1i), "-8589934592+1i") %!assert (num2str (inf), "Inf") +%!assert (num2str ([inf -inf]), "Inf -Inf") +%!assert (num2str ([complex(Inf,0), complex(0,-Inf)]), "Inf+0i 0-Infi") +%!assert (num2str (complex(Inf,1)), "Inf+1i") +%!assert (num2str (complex(1,Inf)), "1+Infi") %!assert (num2str (nan), "NaN") +%!assert (num2str (complex (NaN, 1)), "NaN+1i") +%!assert (num2str (complex (1, NaN)), "1+NaNi") +%!assert (num2str (NA), "NA") +%!assert (num2str (complex (NA, 1)), "NA+1i") +%!assert (num2str (complex (1, NA)), "1+NAi") ## FIXME: Integers greater than bitmax() should be masked to show just ## 16 digits of precision. diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/pol2cart.m --- a/scripts/general/pol2cart.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/pol2cart.m Sat Oct 05 11:22:09 2013 -0400 @@ -55,7 +55,7 @@ r = theta(:,2); theta = theta(:,1); else - error ("pol2car: matrix input must have 2 or 3 columns [THETA, R (, Z)]"); + error ("pol2cart: matrix input must have 2 or 3 columns [THETA, R (, Z)]"); endif elseif (nargin == 2) if (! ((ismatrix (theta) && ismatrix (r)) diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/private/__isequal__.m --- a/scripts/general/private/__isequal__.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/private/__isequal__.m Sat Oct 05 11:22:09 2013 -0400 @@ -48,10 +48,6 @@ function t = __isequal__ (nans_compare_equal, x, varargin) - if (nargin < 3) - print_usage (); - endif - l_v = nargin - 2; ## Generic tests. @@ -160,7 +156,7 @@ t = (l_f_x == length (f_y)) && all (f_x == f_y); if (!t) - return; + break; endif y = y(f_y); @@ -172,11 +168,18 @@ endif if (!t) - return; + break; endif endfor endif endif + if (!t) + t = false; + else + t = true; + endif + endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/private/__splinen__.m --- a/scripts/general/private/__splinen__.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/private/__splinen__.m Sat Oct 05 11:22:09 2013 -0400 @@ -26,14 +26,11 @@ ## FIXME: Allow arbitrary grids.. function yi = __splinen__ (x, y, xi, extrapval, f) - if (nargin != 5) - error ("__splinen__: Incorrect number of arguments"); - endif ## ND isvector function. isvec = @(x) numel (x) == length (x); if (!iscell (x) || length (x) < ndims (y) || any (! cellfun (isvec, x)) || !iscell (xi) || length (xi) < ndims (y) || any (! cellfun (isvec, xi))) - error ("__splinen__: %s: non gridded data or dimensions inconsistent", f); + error ("__splinen__: %s: non-gridded data or dimensions inconsistent", f); endif yi = y; for i = length (x):-1:1 @@ -47,3 +44,4 @@ endfor yi(idx) = extrapval; endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/profexplore.m --- a/scripts/general/profexplore.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/profexplore.m Sat Oct 05 11:22:09 2013 -0400 @@ -17,13 +17,15 @@ ## . ## -*- texinfo -*- -## @deftypefn {Function File} {} profexplore (@var{data}) +## @deftypefn {Function File} {} profexplore () +## @deftypefnx {Function File} {} profexplore (@var{data}) ## Interactively explore hierarchical profiler output. ## ## Assuming @var{data} is the structure with profile data returned by -## @code{profile ("info")}, this command opens an interactive prompt +## @code{profile (@qcode{"info"})}, this command opens an interactive prompt ## that can be used to explore the call-tree. Type @kbd{help} to get a list -## of possible commands. +## of possible commands. If @var{data} is omitted, @code{profile ("info")} +## is called and used in its place. ## @seealso{profile, profshow} ## @end deftypefn @@ -32,7 +34,9 @@ function profexplore (data) - if (nargin != 1) + if (nargin == 0) + data = profile ("info"); + elseif (nargin != 1) print_usage (); endif @@ -78,12 +82,13 @@ cmd = input ("profexplore> ", "s"); option = fix (str2double (cmd)); - if (strcmp (cmd, "exit")) + if (strcmp (cmd, "exit") || strcmp (cmd, "quit")) rv = 0; return; elseif (strcmp (cmd, "help")) printf ("\nCommands for profile explorer:\n\n"); printf ("exit Return to Octave prompt.\n"); + printf ("quit Return to Octave prompt.\n"); printf ("help Display this help message.\n"); printf ("up [N] Go up N levels, where N is an integer. Default is 1.\n"); printf ("N Go down a level into option N.\n"); @@ -130,3 +135,4 @@ endwhile endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/profile.m --- a/scripts/general/profile.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/profile.m Sat Oct 05 11:22:09 2013 -0400 @@ -44,7 +44,7 @@ ## @item @var{S} = profile ("status") ## Return a structure filled with certain information about the current status ## of the profiler. At the moment, the only field is @code{ProfilerStatus} -## which is either "on" or "off". +## which is either @qcode{"on"} or @qcode{"off"}. ## ## @item @var{T} = profile ("info") ## Return the collected profiling statistics in the structure @var{T}. diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/quadgk.m --- a/scripts/general/quadgk.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/quadgk.m Sat Oct 05 11:22:09 2013 -0400 @@ -61,7 +61,7 @@ ## for the integral @var{q}. ## ## Alternatively, properties of @code{quadgk} can be passed to the function as -## pairs @code{"@var{prop}", @var{val}}. Valid properties are +## pairs @qcode{"@var{prop}", @var{val}}. Valid properties are ## ## @table @code ## @item AbsTol @@ -78,12 +78,12 @@ ## unacceptable error are subdivided and re-evaluated. If the number of ## subintervals exceeds 650 subintervals at any point then a poor ## convergence is signaled and the current estimate of the integral is -## returned. The property "MaxIntervalCount" can be used to alter the +## returned. The property @qcode{"MaxIntervalCount"} can be used to alter the ## number of subintervals that can exist before exiting. ## ## @item WayPoints ## Discontinuities in the first derivative of the function to integrate can be -## flagged with the @code{"WayPoints"} property. This forces the ends of +## flagged with the @qcode{"WayPoints"} property. This forces the ends of ## a subinterval to fall on the breakpoints of the function and can result in ## significantly improved estimation of the error in the integral, faster ## computation, or both. For example, @@ -454,6 +454,7 @@ %!assert (quadgk (@(x) exp (-x .^ 2),-Inf,Inf), sqrt (pi), 1e-6) %!assert (quadgk (@(x) exp (-x .^ 2),-Inf,0), sqrt (pi)/2, 1e-6) -%error (quadgk (@sin)) -%error (quadgk (@sin, -pi)) -%error (quadgk (@sin, -pi, pi, "DummyArg")) +%!error (quadgk (@sin)) +%!error (quadgk (@sin, -pi)) +%!error (quadgk (@sin, -pi, pi, "DummyArg")) + diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/quadv.m --- a/scripts/general/quadv.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/quadv.m Sat Oct 05 11:22:09 2013 -0400 @@ -106,7 +106,7 @@ if (nfun > 10000) warning ("maximum iteration count reached"); - elseif (any (isnan (q)(:) | isinf (q)(:))) + elseif (any (! isfinite (q(:)))) warning ("infinite or NaN function evaluations were returned"); elseif (hmin < (b - a) * myeps) warning ("minimum step size reached -- possibly singular integral"); diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/randi.m --- a/scripts/general/randi.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/randi.m Sat Oct 05 11:22:09 2013 -0400 @@ -34,8 +34,8 @@ ## with a lower and upper bound in which case the returned integers will be ## on the interval @w{[@var{imin}, @var{imax}]}. ## -## The optional argument "@var{class}" will return a matrix of the requested -## type. The default is "double". +## The optional argument @var{class} will return a matrix of the requested +## type. The default is @qcode{"double"}. ## ## The following example returns 150 integers in the range 1-10. ## @@ -44,7 +44,7 @@ ## @end example ## ## Implementation Note: @code{randi} relies internally on @code{rand} which -## uses class "double" to represent numbers. This limits the maximum +## uses class @qcode{"double"} to represent numbers. This limits the maximum ## integer (@var{imax}) and range (@var{imax} - @var{imin}) to the value ## returned by the @code{bitmax} function. For IEEE floating point numbers ## this value is @w{@math{2^{53} - 1}}. @@ -111,6 +111,7 @@ endfunction + %!test %! ri = randi (10, 1000, 1); %! assert (ri, fix (ri)); diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/repmat.m --- a/scripts/general/repmat.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/repmat.m Sat Oct 05 11:22:09 2013 -0400 @@ -117,7 +117,7 @@ cidx{2,i} = ones (1, idx (i)); endfor aaidx = aidx; - # add singleton dims + ## add singleton dims aaidx(2,:) = 1; A = reshape (A, aaidx(:)); x = reshape (A (cidx{:}), idx .* aidx); @@ -125,6 +125,7 @@ endfunction + # Tests for ML compatibility %!shared x %! x = [1 2 3]; diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/saveobj.m --- a/scripts/general/saveobj.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/saveobj.m Sat Oct 05 11:22:09 2013 -0400 @@ -42,3 +42,4 @@ function b = saveobj (a) error ('saveobj: not defined for class "%s"', class (a)); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/structfun.m --- a/scripts/general/structfun.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/structfun.m Sat Oct 05 11:22:09 2013 -0400 @@ -34,12 +34,11 @@ ## a string value. If the function returns more than one argument, they are ## returned as separate output variables. ## -## If the parameter "UniformOutput" is set to true (the default), then the -## function -## must return a single element which will be concatenated into the -## return value. If "UniformOutput" is false, the outputs are placed into a -## structure -## with the same fieldnames as the input structure. +## If the parameter @qcode{"UniformOutput"} is set to true (the default), +## then the function must return a single element which will be concatenated +## into the return value. If @qcode{"UniformOutput"} is false, the outputs +## are placed into a structure with the same fieldnames as the input +## structure. ## ## @example ## @group @@ -55,8 +54,9 @@ ## @end group ## @end example ## -## Given the parameter "ErrorHandler", @var{errfunc} defines a function to -## call in case @var{func} generates an error. The form of the function is +## Given the parameter @qcode{"ErrorHandler"}, @var{errfunc} defines a +## function to call in case @var{func} generates an error. The form of the +## function is ## ## @example ## function [@dots{}] = errfunc (@var{se}, @dots{}) @@ -65,10 +65,10 @@ ## @noindent ## where there is an additional input argument to @var{errfunc} relative to ## @var{func}, given by @nospell{@var{se}}. This is a structure with the -## elements "identifier", "message" and "index", giving respectively the error -## identifier, the error message, and the index into the input arguments -## of the element that caused the error. For an example on how to use -## an error handler, @pxref{docXcellfun, @code{cellfun}}. +## elements @qcode{"identifier"}, @qcode{"message"} and @qcode{"index"}, +## giving respectively the error identifier, the error message, and the index +## into the input arguments of the element that caused the error. For an +## example on how to use an error handler, @pxref{XREFcellfun,,cellfun}. ## ## @seealso{cellfun, arrayfun, spfun} ## @end deftypefn diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/subsindex.m --- a/scripts/general/subsindex.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/subsindex.m Sat Oct 05 11:22:09 2013 -0400 @@ -23,7 +23,7 @@ ## overloading method that allows the conversion of this class object to ## a valid indexing vector. It is important to note that ## @code{subsindex} must return a zero-based real integer vector of the -## class "double". For example, if the class constructor +## class @qcode{"double"}. For example, if the class constructor ## ## @example ## @group diff -r 20d1b911b4e7 -r c702371ff6df scripts/general/triplequad.m --- a/scripts/general/triplequad.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/general/triplequad.m Sat Oct 05 11:22:09 2013 -0400 @@ -40,7 +40,8 @@ ## is @code{quadcc}. ## ## Additional arguments, are passed directly to @var{f}. To use the default -## value for @var{tol} or @var{quadf} one may pass ':' or an empty matrix ([]). +## value for @var{tol} or @var{quadf} one may pass @qcode{':'} or an empty +## matrix ([]). ## @seealso{dblquad, quad, quadv, quadl, quadgk, quadcc, trapz} ## @end deftypefn diff -r 20d1b911b4e7 -r c702371ff6df scripts/geometry/delaunay.m --- a/scripts/geometry/delaunay.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/geometry/delaunay.m Sat Oct 05 11:22:09 2013 -0400 @@ -18,12 +18,15 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} delaunay (@var{x}, @var{y}) -## @deftypefnx {Function File} {@var{tri} =} delaunay (@var{x}, @var{y}) -## @deftypefnx {Function File} {@var{tri} =} delaunay (@var{x}, @var{y}, @var{options}) +## @deftypefnx {Function File} {} delaunay (@var{x}) +## @deftypefnx {Function File} {} delaunay (@dots{}, @var{options}) +## @deftypefnx {Function File} {@var{tri} =} delaunay (@dots{}) ## Compute the Delaunay triangulation for a 2-D set of points. ## The return value @var{tri} is a set of triangles which satisfies the ## Delaunay circum-circle criterion, i.e., only a single data point from ## [@var{x}, @var{y}] is within the circum-circle of the defining triangle. +## The input @var{x} may also be a matrix with two columns where the first +## column contains x-data and the second y-data. ## ## The set of triangles @var{tri} is a matrix of size [n, 3]. Each ## row defines a triangle and the three columns are the three vertices @@ -31,7 +34,7 @@ ## @var{x} and @var{y} for the location of the j-th vertex of the i-th ## triangle. ## -## An optional third argument, which must be a string or cell array of strings, +## The optional last argument, which must be a string or cell array of strings, ## contains options passed to the underlying qhull command. ## See the documentation for the Qhull library for details ## @url{http://www.qhull.org/html/qh-quick.htm#options}. @@ -61,24 +64,56 @@ ## Author: Kai Habel -function tri = delaunay (x, y, options) +function tri = delaunay (varargin) - if (nargin != 2 && nargin != 3) + if (nargin < 1 || nargin > 3) print_usage (); endif - if (! (isvector (x) && isvector (y) && length (x) == length (y)) - && ! size_equal (x, y)) + options = []; + + switch (nargin) + + case 1 + if (! ismatrix (varargin{1}) || columns (varargin{1}) != 2) + error ("delaunay: X must be a matrix with 2 columns"); + else + x = varargin{1}(:,1); + y = varargin{1}(:,2); + endif + + case 2 + if (isnumeric (varargin{2})) + x = varargin{1}; + y = varargin{2}; + elseif (ischar (varargin{2}) || iscellstr (varargin{2})) + options = varargin{2}; + if (! ismatrix (varargin{1}) && columns (varargin{1}) != 2) + error ("delaunay: X must be a matrix with 2 columns"); + else + x = varargin{1}(:,1); + y = varargin{1}(:,2); + endif + else + error ("delaunay: OPTIONS must be a string or cell array of strings"); + endif + + case 3 + x = varargin{1}; + y = varargin{2}; + options = varargin{3}; + + if (! (ischar (options) || iscellstr (options))) + error ("delaunay: OPTIONS must be a string or cell array of strings"); + endif + + endswitch + + if (! (isequal(size(x),size(y)))) error ("delaunay: X and Y must be the same size"); - elseif (nargin == 3 && ! (ischar (options) || iscellstr (options))) - error ("delaunay: OPTIONS must be a string or cell array of strings"); endif - if (nargin == 2) - T = delaunayn ([x(:), y(:)]); - else - T = delaunayn ([x(:), y(:)], options); - endif + T = delaunayn ([x(:), y(:)], options); if (nargout == 0) x = x(:).'; @@ -112,9 +147,23 @@ %! assert (sortrows (sort (delaunay (x, y), 2)), [1,2,4;2,3,4]); %!testif HAVE_QHULL +%! x = [-1, 0, 1, 0]; +%! y = [0, 1, 0, -1]; +%! assert (sortrows (sort (delaunay ([x(:) y(:)]), 2)), [1,2,4;2,3,4]); + +%!testif HAVE_QHULL %! x = [-1, 0, 1, 0, 0]; %! y = [0, 1, 0, -1, 0]; %! assert (sortrows (sort (delaunay (x, y), 2)), [1,2,5;1,4,5;2,3,5;3,4,5]); +%!testif HAVE_QHULL +%! x = [-1, 0; 0, 1; 1, 0; 0, -1; 0, 0]; +%! assert (sortrows (sort (delaunay (x), 2)), [1,2,5;1,4,5;2,3,5;3,4,5]); + +%!testif HAVE_QHULL +%! x = [1 5 2; 5 6 7]; +%! y = [5 7 8; 1 2 3]; +%! assert (sortrows (sort (delaunay (x, y), 2)), [1,2,4;1,3,4;1,3,5;3,4,6]); + %% FIXME: Need input validation tests diff -r 20d1b911b4e7 -r c702371ff6df scripts/geometry/griddata.m --- a/scripts/geometry/griddata.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/geometry/griddata.m Sat Oct 05 11:22:09 2013 -0400 @@ -29,8 +29,8 @@ ## The interpolation points are all @code{(@var{xi}, @var{yi})}. If ## @var{xi}, @var{yi} are vectors then they are made into a 2-D mesh. ## -## The interpolation method can be @code{"nearest"}, @code{"cubic"} or -## @code{"linear"}. If method is omitted it defaults to @code{"linear"}. +## The interpolation method can be @qcode{"nearest"}, @qcode{"cubic"} or +## @qcode{"linear"}. If method is omitted it defaults to @qcode{"linear"}. ## @seealso{griddata3, griddatan, delaunay} ## @end deftypefn diff -r 20d1b911b4e7 -r c702371ff6df scripts/geometry/griddata3.m --- a/scripts/geometry/griddata3.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/geometry/griddata3.m Sat Oct 05 11:22:09 2013 -0400 @@ -25,8 +25,8 @@ ## The function is defined by @code{@var{v} = f (@var{x}, @var{y}, @var{z})}. ## The interpolation points are specified by @var{xi}, @var{yi}, @var{zi}. ## -## The interpolation method can be @code{"nearest"} or @code{"linear"}. -## If method is omitted it defaults to @code{"linear"}. +## The interpolation method can be @qcode{"nearest"} or @qcode{"linear"}. +## If method is omitted it defaults to @qcode{"linear"}. ## ## The optional argument @var{options} is passed directly to Qhull when ## computing the Delaunay triangulation used for interpolation. See diff -r 20d1b911b4e7 -r c702371ff6df scripts/geometry/griddatan.m --- a/scripts/geometry/griddatan.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/geometry/griddatan.m Sat Oct 05 11:22:09 2013 -0400 @@ -25,8 +25,8 @@ ## The function is defined by @code{@var{y} = f (@var{x})}. ## The interpolation points are all @var{xi}. ## -## The interpolation method can be @code{"nearest"} or @code{"linear"}. -## If method is omitted it defaults to @code{"linear"}. +## The interpolation method can be @qcode{"nearest"} or @qcode{"linear"}. +## If method is omitted it defaults to @qcode{"linear"}. ## ## The optional argument @var{options} is passed directly to Qhull when ## computing the Delaunay triangulation used for interpolation. See diff -r 20d1b911b4e7 -r c702371ff6df scripts/geometry/inpolygon.m --- a/scripts/geometry/inpolygon.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/geometry/inpolygon.m Sat Oct 05 11:22:09 2013 -0400 @@ -1,5 +1,5 @@ ## Copyright (C) 2006-2012 Frederick (Rick) A Niles -## and S�ren Hauberg +## and Søren Hauberg ## ## This file is part of Octave. ## @@ -30,7 +30,7 @@ ## Author: Frederick (Rick) A Niles ## Created: 14 November 2006 -## Vectorized by S�ren Hauberg +## Vectorized by Søren Hauberg ## The method for determining if a point is in in a polygon is based on ## the algorithm shown on diff -r 20d1b911b4e7 -r c702371ff6df scripts/geometry/voronoi.m --- a/scripts/geometry/voronoi.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/geometry/voronoi.m Sat Oct 05 11:22:09 2013 -0400 @@ -26,9 +26,10 @@ ## Plot the Voronoi diagram of points @code{(@var{x}, @var{y})}. ## The Voronoi facets with points at infinity are not drawn. ## -## If "linespec" is given it is used to set the color and line style of the -## plot. If an axis graphics handle @var{hax} is supplied then the Voronoi -## diagram is drawn on the specified axis rather than in a new figure. +## If @qcode{"linespec"} is given it is used to set the color and line style +## of the plot. If an axis graphics handle @var{hax} is supplied then the +## Voronoi diagram is drawn on the specified axis rather than in a new +## figure. ## ## The @var{options} argument, which must be a string or cell array of strings, ## contains options passed to the underlying qhull command. @@ -74,13 +75,13 @@ narg = 1; if (isscalar (varargin{1}) && ishandle (varargin{1})) - handl = varargin{1}; - if (! strcmp (get (handl, "type"), "axes")) - error ("voronoi: expecting first argument to be an axes object"); + hax = varargin{1}; + if (! isaxes (harg)) + error ("imagesc: HAX argument must be an axes object"); endif narg++; elseif (nargout < 2) - handl = gca (); + hax = gca (); endif if (nargin < 1 + narg || nargin > 3 + narg) @@ -154,7 +155,7 @@ Vvy = reshape (p(edges, 2), size (edges)); if (nargout < 2) - h = plot (handl, Vvx, Vvy, linespec{:}, x, y, '+'); + h = plot (hax, Vvx, Vvy, linespec{:}, x, y, '+'); lim = [xmin, xmax, ymin, ymax]; axis (lim + 0.1 * [[-1, 1] * xdelta, [-1, 1] * ydelta]); if (nargout == 1) diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/guidata.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/guidata.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,67 @@ +## Copyright (C) 2012 Michael Goffioul +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{data} =} guidata (@var{h}) +## @deftypefnx {Function File} {} guidata (@var{h}, @var{data}) +## Query or set user-custom GUI data. +## +## The GUI data is stored in the figure handle @var{h}. If @var{h} is not a +## figure handle then it's parent figure will be used for storage. +## +## @var{data} must be a single object which means it is usually preferable +## for it to be a data container such as a cell array or struct so that +## additional data items can be added easily. +## +## @seealso{getappdata, setappdata, get, set, getpref, setpref} +## @end deftypefn + +## Author: goffioul + +function dataout = guidata (h, data) + + if (nargin < 1 || nargin > 2) + print_usage (); + endif + + if (! ishandle (h)) + error ("guidata: H must be a valid object handle"); + endif + h = ancestor (h, "figure"); + if (isempty (h)) + error ("guidata: no ancestor figure of H found"); + endif + + if (nargin == 1) + dataout = get (h, "__guidata__"); + else + set (h, "__guidata__", data); + if (nargout == 1) + dataout = data; + endif + endif + +endfunction + + +%% Test input validation +%!error guidata () +%!error guidata (1,2,3) +%!error guidata ({1}) +%!error guidata (0) + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/guihandles.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/guihandles.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,80 @@ +## Copyright (C) 2012 Michael Goffioul +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{hdata} =} guihandles (@var{h}) +## @deftypefnx {Function File} {@var{hdata} =} guihandles +## Return a structure of object handles for the figure associated with +## handle @var{h}. +## +## If no handle is specified the current figure returned by @code{gcf} is used. +## +## The fieldname for each entry of @var{hdata} is taken from the @qcode{"tag"} +## property of the graphic object. If the tag is empty then the handle is not +## returned. If there are multiple graphic objects with the same tag then +## the entry in @var{hdata} will be a vector of handles. @code{guihandles} +## includes all possible handles, including those for +## which @qcode{"HandleVisibility"} is @qcode{"off"}. +## @seealso{guidata, findobj, findall, allchild} +## @end deftypefn + +## Author: goffioul + +function hdata = guihandles (h) + + if (nargin > 2) + print_usage (); + endif + + if (nargin == 1) + if (! ishandle (h)) + error ("guidata: H must be a valid object handle"); + endif + h = ancestor (h, "figure"); + if (isempty (h)) + error ("guidata: no ancestor figure of H found"); + endif + else + h = gcf (); + endif + + hdata = __make_guihandles_struct__ (h, []); + +endfunction + +function hdata = __make_guihandles_struct__ (h, hdata) + + tag = get (h, "tag"); + if (! isempty (tag)) + if (isfield (hdata, tag)) + hdata.(tag) = [hdata.(tag), h]; + else + try + hdata.(tag) = h; + catch + end_try_catch + endif + endif + + kids = allchild (h); + for hkid = kids' + hdata = __make_guihandles_struct__ (hkid, hdata); + endfor + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/module.mk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/module.mk Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,35 @@ +FCN_FILE_DIRS += gui + +gui_PRIVATE_FCN_FILES = \ + gui/private/__file_filter__.m \ + gui/private/__fltk_file_filter__.m \ + gui/private/__is_function__.m \ + gui/private/__uigetdir_fltk__.m \ + gui/private/__uigetfile_fltk__.m \ + gui/private/__uiobject_split_args__.m \ + gui/private/__uiputfile_fltk__.m + +gui_FCN_FILES = \ + gui/guidata.m \ + gui/guihandles.m \ + gui/uicontextmenu.m \ + gui/uicontrol.m \ + gui/uigetdir.m \ + gui/uigetfile.m \ + gui/uimenu.m \ + gui/uipanel.m \ + gui/uipushtool.m \ + gui/uiputfile.m \ + gui/uiresume.m \ + gui/uitoggletool.m \ + gui/uitoolbar.m \ + gui/uiwait.m \ + gui/waitbar.m \ + gui/waitforbuttonpress.m \ + $(gui_PRIVATE_FCN_FILES) + +FCN_FILES += $(gui_FCN_FILES) + +PKG_ADD_FILES += gui/PKG_ADD + +DIRSTAMP_FILES += gui/$(octave_dirstamp) diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/private/__file_filter__.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/private/__file_filter__.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,94 @@ +## Copyright (C) 2010-2012 Kai Habel +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {} __file_filter__ (@var{file_filter}) +## Undocumented internal function. +## @end deftypefn + +## Author: Kai Habel + +function [retval, defname, defdir] = __file_filter__ (file_filter, name) + + revtal = {}; + defname = ""; + defdir = ""; + + if (iscell (file_filter)) + [r, c] = size (file_filter); + if (c != 1 && c != 2) + error ("%s: invalid filter specification", name); + endif + if (c == 1) + retval = cell (r, 2); + for i = 1:r + retval{i, 1} = file_filter{i}; + retval{i, 2} = __default_filtername__ (file_filter{i}); + endfor + else + retval = file_filter; + for i = 1:r + if (isempty (retval{i, 2})) + retval{i, 2} = __default_filtername__ (retval{i, 1}); + endif + endfor + endif + elseif (ischar (file_filter)) + [defdir, fname, fext] = fileparts (file_filter); + if (! strcmp (fname, "*")) + defname = strcat (fname, fext); + endif + if (length (fext) > 0) + fext = strcat ("*", fext); + retval = {fext, __default_filtername__(fext)}; + endif + endif + + retval(end+1,:) = {"*", __default_filtername__("*")}; + +endfunction + +function name = __default_filtername__ (filterext) + + name = ""; + + switch (filterext) + case "*" + name = "All Files"; + case "*.m" + name = "Octave Source Files"; + case "*.c" + name = "C Source Files"; + case {"*.cc" "*.c++" "*.cpp"} + name = "C++ Source Files"; + case "*.oct" + name = "Octave Compiled Files"; + endswitch + + if (isempty (name)) + extlist = ostrsplit (filterext, ";"); + extlist = strrep (extlist, "*.", ""); + extlist = toupper (extlist); + extlist(end+1, :) = repmat ({","}, 1, length (extlist)); + extlist = strcat (extlist{:}); + extlist = extlist(1:end-1); + name = strcat (extlist, "-Files"); + endif + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/private/__fltk_file_filter__.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/private/__fltk_file_filter__.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,65 @@ +## Copyright (C) 2012 Michael Goffioul +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{filterspec} =} __fltk_file_filter__ (@var{filter}) +## Undocumented internal function. +## @end deftypefn + +## Author: Michael Goffioul + +function retval = __fltk_file_filter__ (file_filter) + + retval = ""; + [r, c] = size (file_filter); + if ((c == 0) || (c > 2)) + error ("expecting 1 or to 2 columns for file filter cell"); + endif + fltk_str = ""; + for idx = 1 : r + + curr_ext = file_filter{idx, 1}; + curr_ext = ostrsplit (curr_ext, ";"); + + if (length (curr_ext) > 1) + curr_ext = regexprep (curr_ext, '\*\.', ','); + curr_ext = strcat (curr_ext{:})(2 : end); + curr_ext = strcat ("*.{", curr_ext, "}"); + else + curr_ext = curr_ext{:}; + endif + + curr_desc = strcat (curr_ext(3:end), "-Files"); + + if (c == 2) + curr_desc = file_filter{idx, 2}; + curr_desc = regexprep (curr_desc, '\(', '<'); + curr_desc = regexprep (curr_desc, '\)', '>'); + endif + + if (length (fltk_str) > 0) + fltk_str = strcat (fltk_str, "\t", curr_desc, " (", curr_ext, ")"); + else + fltk_str = strcat (curr_desc, " (", curr_ext, ")"); + endif + + endfor + retval = fltk_str; + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/private/__is_function__.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/private/__is_function__.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,32 @@ +## Copyright (C) 2012 Michael Goffioul +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{result} =} __is_function__ (@var{func}) +## Undocumented internal function. +## @end deftypefn + +## Author: Michael Goffioul + +function result = __is_function__ (func) + + existval = exist (func); + result = (existval == 2 || existval == 3 || existval == 5 || existval == 6); + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/private/__uigetdir_fltk__.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/private/__uigetdir_fltk__.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,35 @@ +## Copyright (C) 2012 Michael Goffioul +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{dirname} =} __uigetdir_fltk__ (@var{start_path}, @var{dialog_title}) +## Undocumented internal function. +## @end deftypefn + +## Author: Michael Goffioul + +function dirname = __uigetdir_fltk__ (start_path, dialog_title) + + if (exist ("__fltk_uigetfile__") != 3) + error ("uigetdir: fltk graphics toolkit required"); + endif + + dirname = __fltk_uigetfile__ ("", dialog_title, start_path, [240, 120], "dir"); + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/private/__uigetfile_fltk__.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/private/__uigetfile_fltk__.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,39 @@ +## Copyright (C) 2012 Michael Goffioul +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {[@var{fname}, @var{fpath}, @var{fltidx}] =} __uigetfile_fltk__ () +## Undocumented internal function. +## @end deftypefn + +## Author: Michael Goffioul + +function [retval, retpath, retindex] = __uigetfile_fltk__ (filters, title, defval, position, multiselect, defdir) + + if (exist ("__fltk_uigetfile__") != 3) + error ("uigetfile: fltk graphics toolkit required"); + endif + + filters = __fltk_file_filter__ (filters); + if (length (defdir) > 0) + defval = fullfile (defdir, defval); + endif + [retval, retpath, retindex] = __fltk_uigetfile__ (filters, title, defval, position, multiselect); + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/private/__uiobject_split_args__.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/private/__uiobject_split_args__.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,67 @@ +## Copyright (C) 2012 Michael Goffioul +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {[@var{p}, @var{args}] =} __uiobject_split_args__ (@var{who}, @var{args}, @var{parent_type}, @var{use_gcf}) +## @end deftypefn + +## Author: goffioul + +function [parent, args] = __uiobject_split_args__ (who, in_args, parent_type = {}, use_gcf = 1) + + parent = []; + args = {}; + offset = 1; + + if (! isempty (in_args)) + if (ishandle (in_args{1})) + parent = in_args{1}; + offset = 2; + elseif (! ischar (in_args{1})) + error ("%s: invalid parent handle.", who); + endif + + args = in_args(offset:end); + endif + + if (rem (length (args), 2)) + error ("%s: expecting PROPERTY/VALUE pairs", who); + endif + + if (! isempty (args)) + i = find (strcmpi (args(1:2:end), "parent"), 1, "first"); + if (! isempty (i) && length (args) >= 2*i) + parent = args{2*i}; + if (! ishandle (parent)) + error ("%s: invalid parent handle.", who); + endif + args([2*i-1, 2*i]) = []; + endif + endif + + if (! isempty (parent)) + if (! isempty (parent_type) && isempty (find (strcmpi (get (parent, "type"), parent_type)))) + error ("%s: invalid parent, the parent type must be: %s", ... + who, sprintf ("%s, ", parent_type{:})(1:end-2)); + endif + elseif (use_gcf) + parent = gcf (); + endif + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/private/__uiputfile_fltk__.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/private/__uiputfile_fltk__.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,39 @@ +## Copyright (C) 2012 Michael Goffioul +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {[@var{fname}, @var{fpath}, @var{fltidx}] =} __uiputfile_fltk__ () +## Undocumented internal function. +## @end deftypefn + +## Author: Michael Goffioul + +function [retval, retpath, retindex] = __uiputfile_fltk__ (filters, title, defval, position, tag, defdir) + + if (exist ("__fltk_uigetfile__") != 3) + error ("uiputfile: fltk graphics toolkit required"); + endif + + filters = __fltk_file_filter__ (filters); + if (length (defdir) > 0) + defval = fullfile (defdir, defval); + endif + [retval, retpath, retindex] = __fltk_uigetfile__ (filters, title, defval, position, tag); + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/uicontextmenu.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/uicontextmenu.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,31 @@ +## Copyright (C) 2012 Michael Goffioul +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{handle} =} uicontextmenu ("Name", value, @dots{}) +## @end deftypefn + +## Author: goffioul + +function handle = uicontextmenu (varargin) + + [h, args] = __uiobject_split_args__ ("uicontextmenu", varargin, {"figure"}); + handle = __go_uicontextmenu__ (h, args{:}); + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/uicontrol.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/uicontrol.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,37 @@ +## Copyright (C) 2012 Michael Goffioul +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{handle} =} uicontrol ("Name", value, @dots{}) +## @deftypefnx {Function File} {@var{handle} =} uicontrol (@var{parent}, "Name", value, @dots{}) +## @deftypefnx {Function File} {} uicontrol (@var{handle}) +## @end deftypefn + +## Author: goffioul + +function handle = uicontrol (varargin) + + if (nargin == 1 && ishandle (varargin{1}) && strcmpi (get (varargin{1}, "type"), "uicontrol")) + error ("uicontrol focusing not implemented yet."); + else + [h, args] = __uiobject_split_args__ ("uicontrol", varargin, {"figure", "uipanel", "uibuttongroup"}); + handle = __go_uicontrol__ (h, args{:}); + endif + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/uigetdir.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/uigetdir.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,81 @@ +## Copyright (C) 2010-2012 Kai Habel +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{dirname} =} uigetdir () +## @deftypefnx {Function File} {@var{dirname} =} uigetdir (@var{init_path}) +## @deftypefnx {Function File} {@var{dirname} =} uigetdir (@var{init_path}, @var{dialog_name}) +## Open a GUI dialog for selecting a directory. If @var{init_path} is not +## given the current working directory is used. @var{dialog_name} may be +## used to customize the dialog title. +## @seealso{uigetfile, uiputfile} +## @end deftypefn + +## Author: Kai Habel + +function dirname = uigetdir (init_path = pwd, dialog_name = "Select Directory to Open") + + if (! __octave_link_enabled__ ()) + defaulttoolkit = get (0, "defaultfigure__graphics_toolkit__"); + funcname = ["__uigetdir_", defaulttoolkit, "__"]; + functype = exist (funcname); + if (! __is_function__ (funcname)) + funcname = "__uigetdir_fltk__"; + if (! __is_function__ (funcname)) + error ("uigetdir: fltk graphics toolkit required"); + elseif (! strcmp (defaulttoolkit, "gnuplot")) + warning ("uigetdir: no implementation for toolkit '%s', using 'fltk' instead", + defaulttoolkit); + endif + endif + endif + + if (nargin > 2) + print_usage (); + endif + + if (!ischar (init_path) || !ischar (dialog_name)) + error ("uigetdir: INIT_PATH and DIALOG_NAME must be string arguments"); + endif + + if (!isdir (init_path)) + init_path = fileparts (init_path); + endif + + if (__octave_link_enabled__ ()) + file_filter = cell (0, 2); + default_file_name = ""; + dialog_position = [240, 120]; + dialog_mode = "dir"; + + [filename, dirname, filterindex] ... + = __octave_link_file_dialog__ (file_filter, dialog_name, + default_file_name, dialog_position, + dialog_mode, init_path); + else + dirname = feval (funcname, init_path, dialog_name); + endif +endfunction + + +%!demo +%! uigetdir (pwd, 'Select Directory'); + +## Remove from test statistics. No real tests possible. +%!assert (1) + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/uigetfile.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/uigetfile.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,203 @@ +## Copyright (C) 2010-2012 Kai Habel +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {[@var{fname}, @var{fpath}, @var{fltidx}] =} uigetfile () +## @deftypefnx {Function File} {[@dots{}] =} uigetfile (@var{flt}) +## @deftypefnx {Function File} {[@dots{}] =} uigetfile (@var{flt}, @var{dialog_name}) +## @deftypefnx {Function File} {[@dots{}] =} uigetfile (@var{flt}, @var{dialog_name}, @var{default_file}) +## @deftypefnx {Function File} {[@dots{}] =} uigetfile (@dots{}, "Position", [@var{px} @var{py}]) +## @deftypefnx {Function File} {[@dots{}] =} uigetfile (@dots{}, "MultiSelect", @var{mode}) +## +## Open a GUI dialog for selecting a file and return the filename @var{fname}, +## the path to this file @var{fpath}, and the filter index @var{fltidx}. +## @var{flt} contains a (list of) file filter string(s) in one of the following +## formats: +## +## @table @asis +## @item @qcode{"/path/to/filename.ext"} +## If a filename is given then the file extension is extracted and used as +## filter. In addition, the path is selected as current path and the filename +## is selected as default file. Example: @code{uigetfile ("myfun.m")} +## +## @item A single file extension @qcode{"*.ext"} +## Example: @code{uigetfile ("*.ext")} +## +## @item A 2-column cell array +## containing a file extension in the first column and a brief description +## in the second column. +## Example: @code{uigetfile (@{"*.ext", "My Description";"*.xyz", +## "XYZ-Format"@})} +## +## The filter string can also contain a semicolon separated list of filter +## extensions. +## Example: @code{uigetfile (@{"*.gif;*.png;*.jpg", "Supported Picture +## Formats"@})} +## @end table +## +## @var{dialog_name} can be used to customize the dialog title. +## If @var{default_file} is given then it will be selected in the GUI dialog. +## If, in addition, a path is given it is also used as current path. +## +## The screen position of the GUI dialog can be set using the +## @qcode{"Position"} key and a 2-element vector containing the pixel +## coordinates. Two or more files can be selected when setting the +## @qcode{"MultiSelect"} key to @qcode{"on"}. In that case @var{fname} is a +## cell array containing the files. +## @seealso{uiputfile, uigetdir} +## @end deftypefn + +## Author: Kai Habel + +function [retfile, retpath, retindex] = uigetfile (varargin) + + if (! __octave_link_enabled__ ()) + defaulttoolkit = get (0, "defaultfigure__graphics_toolkit__"); + funcname = ["__uigetfile_", defaulttoolkit, "__"]; + functype = exist (funcname); + if (! __is_function__ (funcname)) + funcname = "__uigetfile_fltk__"; + if (! __is_function__ (funcname)) + error ("uigetfile: fltk graphics toolkit required"); + elseif (! strcmp (defaulttoolkit, "gnuplot")) + warning ("uigetfile: no implementation for toolkit '%s', using 'fltk' instead", + defaulttoolkit); + endif + endif + endif + + if (nargin > 7) + error ("uigetfile: number of input arguments must be less than eight"); + endif + + defaultvals = {cell(0, 2), # File Filter + "Open File", # Dialog Title + "", # Default file name + [240, 120], # Dialog Position (pixel x/y) + "off", # MultiSelect on/off + pwd}; # Default directory + + outargs = cell (6, 1); + for i = 1 : 6 + outargs{i} = defaultvals{i}; + endfor + + idx1 = idx2 = []; + if (length (varargin) > 0) + for i = 1 : length (varargin) + val = varargin{i}; + if (ischar (val)) + val = tolower (val); + if (strcmp (val, "multiselect")) + idx1 = i; + elseif (strcmp (val, "position")) + idx2 = i; + endif + endif + endfor + endif + + stridx = [idx1, idx2, 0]; + if (length (stridx) > 1) + stridx = min (stridx(1 : end - 1)); + endif + + args = varargin; + if (stridx) + args = varargin(1 : stridx - 1); + endif + + len = length (args); + if (len > 0) + file_filter = args{1}; + [outargs{1}, outargs{3}, defdir] = __file_filter__ (file_filter); + if (length (defdir) > 0) + outargs{6} = defdir; + endif + else + outargs{1} = __file_filter__ (outargs{1}); + endif + + if (len > 1) + if (ischar (args{2})) + if (length (args{2}) > 0) + outargs{2} = args{2}; + endif + elseif (! isempty (args{2})) + print_usage (); + endif + endif + + if (len > 2) + if (ischar (args{3})) + [fdir, fname, fext] = fileparts (args{3}); + if (length (fdir) > 0) + outargs{6} = fdir; + endif + if (length (fname) > 0 || length (fext) > 0) + outargs{3} = strcat (fname, fext); + endif + elseif (! isempty (args{3})) + print_usage (); + endif + endif + + if (stridx) + ## we have string arguments ("position" or "multiselect") + + ## check for even number of remaining arguments, prop/value pair(s) + if (rem (nargin - stridx + 1, 2)) + error ("uigetfile: expecting property/value pairs"); + endif + + for i = stridx : 2 : nargin + prop = varargin{i}; + val = varargin{i + 1}; + if (strcmpi (prop, "position")) + if (ismatrix (val) && length (val) == 2) + outargs{4} = val; + else + error ("uigetfile: expecting 2-element vector for position argument"); + endif + elseif (strcmpi (prop, "multiselect")) + if (ischar (val)) + outargs{5} = tolower (val); + else + error ("uigetfile: expecting string argument (on/off) for multiselect"); + endif + else + error ("uigetfile: unknown argument"); + endif + endfor + endif + + if (__octave_link_enabled__ ()) + [retfile, retpath, retindex] = __octave_link_file_dialog__ (outargs{:}); + else + [retfile, retpath, retindex] = feval (funcname, outargs{:}); + endif + +endfunction + + +%!demo +%! uigetfile ({'*.gif;*.png;*.jpg', 'Supported Picture Formats'}); + +## Remove from test statistics. No real tests possible. +%!assert (1) + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/uimenu.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/uimenu.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,147 @@ +## Copyright (C) 2010-2012 Kai Habel +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {} uimenu (@var{property}, @var{value}, @dots{}) +## @deftypefnx {Function File} {} uimenu (@var{h}, @var{property}, @var{value}, @dots{}) +## Create a uimenu object and return a handle to it. If @var{h} is omitted +## then a top-level menu for the current figure is created. If @var{h} +## is given then a submenu relative to @var{h} is created. +## +## uimenu objects have the following specific properties: +## +## @table @asis +## @item @qcode{"accelerator"} +## A string containing the key combination together with CTRL to execute this +## menu entry (e.g., @qcode{"x"} for CTRL+x). +## +## @item @qcode{"callback"} +## Is the function called when this menu entry is executed. It can be either a +## function string (e.g., @qcode{"myfun"}), a function handle (e.g., @@myfun) +## or a cell array containing the function handle and arguments for the +## callback function (e.g., @{@@myfun, arg1, arg2@}). +## +## @item @qcode{"checked"} +## Can be set @qcode{"on"} or @qcode{"off"}. Sets a mark at this menu entry. +## +## @item @qcode{"enable"} +## Can be set @qcode{"on"} or @qcode{"off"}. If disabled the menu entry +## cannot be selected and it is grayed out. +## +## @item @qcode{"foregroundcolor"} +## A color value setting the text color for this menu entry. +## +## @item @qcode{"label"} +## A string containing the label for this menu entry. A @qcode{"&"}-symbol +## can be used to mark the @qcode{"accelerator"} character (e.g., +## @nospell{@qcode{"E&xit"}}) +## +## @item @qcode{"position"} +## An scalar value containing the relative menu position. The entry with the +## lowest value is at the first position starting from left or top. +## +## @item @qcode{"separator"} +## Can be set @qcode{"on"} or @qcode{"off"}. If enabled it draws a separator +## line above the current position. It is ignored for top level entries. +## +## @end table +## +## Examples: +## +## @example +## @group +## f = uimenu ("label", "&File", "accelerator", "f"); +## e = uimenu ("label", "&Edit", "accelerator", "e"); +## uimenu (f, "label", "Close", "accelerator", "q", ... +## "callback", "close (gcf)"); +## uimenu (e, "label", "Toggle &Grid", "accelerator", "g", ... +## "callback", "grid (gca)"); +## @end group +## @end example +## @seealso{figure} +## @end deftypefn + +## Author: Kai Habel + +function hui = uimenu (varargin) + + [h, args] = __uiobject_split_args__ ("uimenu", varargin, {"figure", "uicontextmenu", "uimenu"}); + + tmp = __go_uimenu__ (h, args{:}); + + if (nargout > 0) + hui = tmp; + endif + +endfunction + + +%!demo +%! clf; +%! surfl (peaks); +%! colormap (copper (64)); +%! shading ('interp'); +%! f = uimenu ('label', '&File', 'accelerator', 'f'); +%! e = uimenu ('label', '&Edit', 'accelerator', 'e'); +%! uimenu (f, 'label', 'Close', 'accelerator', 'q', 'callback', 'close (gcf)'); +%! uimenu (e, 'label', 'Toggle &Grid', 'accelerator', 'g', 'callback', 'grid (gca)'); + +%!testif HAVE_FLTK +%! toolkit = graphics_toolkit ("fltk"); +%! hf = figure ("visible", "off"); +%! unwind_protect +%! ui = uimenu ("label", "mylabel"); +%! assert (findobj (hf, "type", "uimenu"), ui); +%! assert (get (ui, "label"), "mylabel"); +%! assert (get (ui, "checked"), "off"); +%! assert (get (ui, "separator"), "off"); +%! assert (get (ui, "enable"), "on"); +%! assert (get (ui, "position"), 9); +%! unwind_protect_cleanup +%! close (hf); +%! graphics_toolkit (toolkit); +%! end_unwind_protect + +%% check for top level menus file, edit, and help +%!testif HAVE_FLTK +%! toolkit = graphics_toolkit ("fltk"); +%! hf = figure ("visible", "off"); +%! unwind_protect +%! uif = findall (hf, "label", "&file"); +%! assert (ishghandle (uif)); +%! uie = findall (hf, "label", "&edit"); +%! assert (ishghandle (uie)); +%! uih = findall (hf, "label", "&help"); +%! assert (ishghandle (uih)); +%! unwind_protect_cleanup +%! close (hf); +%! graphics_toolkit (toolkit); +%! end_unwind_protect + +%!testif HAVE_FLTK +%! toolkit = graphics_toolkit ("fltk"); +%! hf = figure ("visible", "off"); +%! unwind_protect +%! uie = findall (hf, "label", "&edit"); +%! myui = uimenu (uie, "label", "mylabel"); +%! assert (ancestor (myui, "uimenu", "toplevel"), uie); +%! unwind_protect_cleanup +%! close (hf); +%! graphics_toolkit (toolkit); +%! end_unwind_protect + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/uipanel.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/uipanel.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,32 @@ +## Copyright (C) 2012 Michael Goffioul +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{handle} =} uipanel ("Name", value, @dots{}) +## @deftypefnx {Function File} {@var{handle} =} uipanel (@var{parent}, "Name", value, @dots{}) +## @end deftypefn + +## Author: goffioul + +function handle = uipanel (varargin) + + [h, args] = __uiobject_split_args__ ("uipanel", varargin, {"figure", "uipanel", "uibuttongroup"}); + handle = __go_uipanel__ (h, args{:}); + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/uipushtool.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/uipushtool.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,40 @@ +## Copyright (C) 2012 Michael Goffioul +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{handle} =} uipushtool ("Name", value, @dots{}) +## @deftypefnx {Function File} {@var{handle} =} uipushtool (@var{parent}, "Name", value, @dots{}) +## @end deftypefn + +## Author: goffioul + +function handle = uipushtool (varargin) + + [h, args] = __uiobject_split_args__ ("uipushtool", varargin, {"uitoolbar"}, 0); + if (isempty (h)) + h = findobj (gcf, "-depth", 1, "type", "uitoolbar"); + if (isempty (h)) + h = uitoolbar (); + else + h = h(1); + endif + endif + handle = __go_uipushtool__ (h, args{:}); + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/uiputfile.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/uiputfile.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,136 @@ +## Copyright (C) 2010-2012 Kai Habel +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {[@var{fname}, @var{fpath}, @var{fltidx}] =} uiputfile () +## @deftypefnx {Function File} {[@var{fname}, @var{fpath}, @var{fltidx}] =} uiputfile (@var{flt}) +## @deftypefnx {Function File} {[@var{fname}, @var{fpath}, @var{fltidx}] =} uiputfile (@var{flt}, @var{dialog_name}) +## @deftypefnx {Function File} {[@var{fname}, @var{fpath}, @var{fltidx}] =} uiputfile (@var{flt}, @var{dialog_name}, @var{default_file}) +## Open a GUI dialog for selecting a file. @var{flt} contains a (list of) file +## filter string(s) in one of the following formats: +## +## @table @asis +## @item @qcode{"/path/to/filename.ext"} +## If a filename is given the file extension is extracted and used as filter. +## In addition the path is selected as current path and the filename is +## selected as default file. Example: @code{uiputfile ("myfun.m")} +## +## @item @qcode{"*.ext"} +## A single file extension. +## Example: @code{uiputfile ("*.ext")} +## +## @item @code{@{"*.ext", "My Description"@}} +## A 2-column cell array containing the file extension in the 1st column and +## a brief description in the 2nd column. +## Example: @code{uiputfile (@{"*.ext","My Description";"*.xyz", +## "XYZ-Format"@})} +## @end table +## +## The filter string can also contain a semicolon separated list of filter +## extensions. +## Example: @code{uiputfile (@{"*.gif;*.png;*.jpg", +## "Supported Picture Formats"@})} +## +## @var{dialog_name} can be used to customize the dialog title. +## If @var{default_file} is given it is preselected in the GUI dialog. +## If, in addition, a path is given it is also used as current path. +## @seealso{uigetfile, uigetdir} +## @end deftypefn + +## Author: Kai Habel + +function [retfile, retpath, retindex] = uiputfile (varargin) + + if (! __octave_link_enabled__ ()) + defaulttoolkit = get (0, "defaultfigure__graphics_toolkit__"); + funcname = ["__uiputfile_", defaulttoolkit, "__"]; + functype = exist (funcname); + if (! __is_function__ (funcname)) + funcname = "__uiputfile_fltk__"; + if (! __is_function__ (funcname)) + error ("uiputfile: fltk graphics toolkit required"); + elseif (! strcmp (defaulttoolkit, "gnuplot")) + warning ("uiputfile: no implementation for toolkit '%s', using 'fltk' instead", + defaulttoolkit); + endif + endif + endif + + if (nargin > 3) + print_usage (); + endif + + defaultvals = {cell(0, 2), # File Filter + "Save File", # Dialog Title + "", # Default file name + [240, 120], # Dialog Position (pixel x/y) + "create", + pwd}; # Default directory + + outargs = cell (6, 1); + for i = 1 : 6 + outargs{i} = defaultvals{i}; + endfor + + if (nargin > 0) + file_filter = varargin{1}; + [outargs{1}, outargs{3}, defdir] = __file_filter__ (file_filter); + if (length (defdir) > 0) + outargs{6} = defdir; + endif + else + outargs{1} = __file_filter__ (outargs{1}); + endif + + if (nargin > 1) + if (ischar (varargin{2})) + outargs{2} = varargin{2}; + elseif (! isempty (varargin{2})) + print_usage (); + endif + endif + + if (nargin > 2) + if (ischar (varargin{3})) + [fdir, fname, fext] = fileparts (varargin{3}); + if (! isempty (fdir)) + outargs{6} = fdir; + endif + if (! isempty (fname) || ! isempty (fext)) + outargs{3} = strcat (fname, fext); + endif + elseif (! isempty (varargin{3})) + print_usage (); + endif + endif + + if (__octave_link_enabled__ ()) + [retfile, retpath, retindex] = __octave_link_file_dialog__ (outargs{:}); + else + [retfile, retpath, retindex] = feval (funcname, outargs{:}); + endif + +endfunction + + +%!demo +%! uiputfile ({'*.gif;*.png;*.jpg', 'Supported Picture Formats'}); + +## Remove from test statistics. No real tests possible. +%!assert (1) + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/uiresume.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/uiresume.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,46 @@ +## Copyright (C) 2012 Michael Goffioul +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {} uiresume (@var{h}) +## Resume program execution suspended with @code{uiwait}. The handle @var{h} +## must be the same as the on specified in @code{uiwait}. If the handle +## is invalid or there is no @code{uiwait} call pending for the figure +## with handle @var{h}, this function does nothing. +## @seealso{uiwait} +## @end deftypefn + +## Author: goffioul + +function uiresume (h) + + if (! isfigure (h)) + error ("uiresume: invalid figure handle H"); + endif + + try + uiwait_state = get (h, "__uiwait_state__"); + if (strcmp (uiwait_state, "active")) + set (h, "__uiwait_state__", "triggered"); + endif + catch + ## Ignore exception + end_try_catch + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/uitoggletool.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/uitoggletool.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,40 @@ +## Copyright (C) 2012 Michael Goffioul +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{handle} =} uitoggletool ("Name", value, @dots{}) +## @deftypefnx {Function File} {@var{handle} =} uitoggletool (@var{parent}, "Name", value, @dots{}) +## @end deftypefn + +## Author: goffioul + +function handle = uitoggletool (varargin) + + [h, args] = __uiobject_split_args__ ("uitoggletool", varargin, {"uitoolbar"}, 0); + if (isempty (h)) + h = findobj (gcf, "-depth", 1, "type", "uitoolbar"); + if (isempty (h)) + h = uitoolbar (); + else + h = h(1); + endif + endif + handle = __go_uitoggletool__ (h, args{:}); + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/uitoolbar.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/uitoolbar.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,32 @@ +## Copyright (C) 2012 Michael Goffioul +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{handle} =} uitoolbar ("Name", value, @dots{}) +## @deftypefnx {Function File} {@var{handle} =} uitoolbar (@var{parent}, "Name", value, @dots{}) +## @end deftypefn + +## Author: goffioul + +function handle = uitoolbar (varargin) + + [h, args] = __uiobject_split_args__ ("uitoolbar", varargin, {"figure"}); + handle = __go_uitoolbar__ (h, args{:}); + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/uiwait.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/uiwait.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,81 @@ +## Copyright (C) 2012 Michael Goffioul +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {} uiwait +## @deftypefnx {Function File} {} uiwait (@var{h}) +## @deftypefnx {Function File} {} uiwait (@var{h}, @var{timeout}) +## Suspend program execution until the figure with handle @var{h} is +## deleted or @code{uiresume} is called. When no figure handle is specified, +## this function uses the current figure. +## +## If the figure handle is invalid or there is no current figure, this +## functions returns immediately. +## +## When specified, @var{timeout} defines the number of seconds to wait +## for the figure deletion or the @code{uiresume} call. The timeout value +## must be at least 1. If a smaller value is specified, a warning is issued +## and a timeout value of 1 is used instead. If a non-integer value is +## specified, it is truncated towards 0. If @var{timeout} is not specified, +## the program execution is suspended indefinitely. +## @seealso{uiresume, waitfor} +## @end deftypefn + +## Author: goffioul + +function uiwait (varargin) + + h = []; + timeout = []; + + if (nargin == 0) + h = get (0, "currentfigure"); + else + h = varargin{1}; + if (! isfigure (h)) + error ("uiwait: invalid figure handle H"); + endif + if (nargin > 1) + timeout = varargin{2}; + endif + endif + + if (! isempty (h)) + unwind_protect + try + addproperty ("__uiwait_state__", h, "radio", "none|{active}|triggered"); + catch + if (! strcmp (get (h, "__uiwait_state__"), "none")) + error ("uiwait: an active uiwait call for this figure already exists"); + endif + set (h, "__uiwait_state__", "active"); + end_try_catch + waitfor_args = {h, "__uiwait_state__", "triggered"}; + if (! isempty (timeout)) + waitfor_args(end+1:end+2) = {"timeout", timeout}; + endif + waitfor (waitfor_args{:}); + unwind_protect_cleanup + if (ishandle (h) && isprop (h, "__uiwait_state__")) + set (h, "__uiwait_state__", "none"); + endif + end_unwind_protect + endif + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/waitbar.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/waitbar.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,199 @@ +## Copyright (C) 2012 John W. Eaton +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{h} =} waitbar (@var{frac}) +## @deftypefnx {Function File} {@var{h} =} waitbar (@var{frac}, @var{msg}) +## @deftypefnx {Function File} {@var{h} =} waitbar (@dots{}, "FigureProperty", "Value", @dots{}) +## @deftypefnx {Function File} {} waitbar (@var{frac}) +## @deftypefnx {Function File} {} waitbar (@var{frac}, @var{hwbar}) +## @deftypefnx {Function File} {} waitbar (@var{frac}, @var{hwbar}, @var{msg}) +## Return a handle @var{h} to a new waitbar object. +## +## The waitbar is filled to fraction @var{frac} which must be in the range +## [0, 1]. The optional message @var{msg} is centered and displayed above the +## waitbar. The appearance of the waitbar figure window can be configured by +## passing property/value pairs to the function. +## +## When called with a single input the current waitbar, if it exists, is +## updated to the new value @var{frac}. If there are multiple outstanding +## waitbars they can be updated individually by passing the handle @var{hwbar} +## of the specific waitbar to modify. +## @end deftypefn + +## Author: jwe + +function h = waitbar (varargin) + + persistent curr_waitbar; + + if (nargin < 1) + print_usage (); + endif + + frac = varargin{1}; + varargin(1) = []; + + if (! (isnumeric (frac) && isscalar (frac) && frac >= 0 && frac <= 1)) + error ("waitbar: FRAC must be between 0 and 1"); + endif + + ## Use existing waitbar if it still points to a valid graphics handle. + if (nargin == 1 && ishandle (curr_waitbar)) + hf = curr_waitbar; + else + hf = false; + endif + + if (! isempty (varargin) && isnumeric (varargin{1})) + hf = varargin{1}; + varargin(1) = []; + if (! isfigure (hf) || ! strcmp (get (hf, "tag"), "waitbar")) + error ("waitbar: H must be a handle to a waitbar object"); + endif + endif + + msg = false; + + if (! isempty (varargin)) + msg = varargin{1}; + varargin(1) = []; + if (! (ischar (msg) || iscellstr (msg))) + error ("waitbar: MSG must be a character string or cell array of strings"); + endif + endif + + if (rem (numel (varargin), 2) != 0) + error ("waitbar: invalid number of property/value pairs"); + endif + + if (hf) + gd = get (hf, "__guidata__"); + ## Get the cached handles. + ax = gd(1); + hp = gd(2); + + set (hp, "xdata", [0; frac; frac; 0]); + + if (ischar (msg) || iscellstr (msg)) + th = get (ax, "title"); + curr_msg = get (th, "string"); + ## graphics handles always store data as column vectors + if (iscellstr (msg)) + msg = msg(:); + endif + cmp = strcmp (msg, curr_msg); + if (! all (cmp(:))) + set (th, "string", msg); + endif + endif + else + ## Save and restore current figure + cf = get (0, "currentfigure"); + + hf = figure ("position", [250, 500, 400, 100], + "numbertitle", "off", + "menubar", "none", "toolbar", "none", + "integerhandle", "off", + "handlevisibility", "callback", + "tag", "waitbar", + varargin{:}); + + ax = axes ("parent", hf, + "xtick", [], "ytick", [], + "xlim", [0, 1], "ylim", [0, 1], + "position", [0.1, 0.3, 0.8, 0.2]); + + hp = patch (ax, [0; frac; frac; 0], [0; 0; 1; 1], [0, 0.35, 0.75]); + + ## Cache the axes and patch handles. + set (hf, "__guidata__", [ax hp]); + + if (! (ischar (msg) || iscellstr (msg))) + msg = "Please wait..."; + endif + title (ax, msg); + + if (! isempty (cf)) + set (0, "currentfigure", cf); + endif + endif + + drawnow (); + + if (nargout > 0) + h = hf; + endif + + ## If there were no errors, update current waitbar. + curr_waitbar = hf; + +endfunction + + +%!demo +%! h = waitbar (0, '0.00%'); +%! for i = 0:0.01:1 +%! waitbar (i, h, sprintf ('%.2f%%', 100*i)); +%! end +%! close (h); + +%!demo +%! h = waitbar (0, 'please wait...'); +%! for i = 0:0.01:0.6 +%! waitbar (i); +%! end +%! i = 0.3; +%! waitbar (i, h, 'don''t you hate taking a step backward?'); +%! pause (0.5); +%! for i = i:0.005:0.7 +%! waitbar (i, h); +%! end +%! waitbar (i, h, 'or stalling?'); +%! pause (1); +%! for i = i:0.003:0.8 +%! waitbar (i, h, 'just a little longer now'); +%! end +%! for i = i:0.001:1 +%! waitbar (i, h, 'please don''t be impatient'); +%! end +%! close (h); + +%!demo +%! h1 = waitbar (0, 'Waitbar #1'); +%! h2 = waitbar (0, 'Waitbar #2'); +%! h2pos = get (h2, 'position'); +%! h2pos(1) = h2pos(1) + (h2pos(3) + 50); +%! set (h2, 'position', h2pos); +%! pause (0.5); +%! for i = 1:4 +%! waitbar (i/4, h1); +%! pause (0.5); +%! waitbar (i/4, h2); +%! pause (0.5); +%! end +%! pause (0.5); +%! close (h1); +%! close (h2); + +%% Test input validation +%!error waitbar (-0.5) +%!error waitbar (1.5) +%!error waitbar (0.5, struct ()) +%!error waitbar (0.5, "msg", "Name") + diff -r 20d1b911b4e7 -r c702371ff6df scripts/gui/waitforbuttonpress.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gui/waitforbuttonpress.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,55 @@ +## Copyright (C) 2004-2012 Petr Mikulik +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {} waitforbuttonpress () +## @deftypefnx {Function File} {@var{a} =} waitforbuttonpress () +## Wait for mouse click or key press over the current figure window. +## +## The return value of @var{b} is 0 if a mouse button was pressed or 1 if a +## key was pressed. +## @seealso{waitfor, ginput, kbhit} +## @end deftypefn + +## The original version of this code bore the copyright +## Author: Petr Mikulik +## License: public domain + +function b = waitforbuttonpress () + + if (nargin != 0 || nargout > 1) + print_usage (); + endif + + [x, y, k] = ginput (1); + + if (nargout == 1) + if (k <= 5) + b = 0; + else + b = 1; + endif + endif + +endfunction + + +%% Test input validation +%!error waitforbuttonpress (1) +%!error [a,b,c] = waitforbuttonpress () + diff -r 20d1b911b4e7 -r c702371ff6df scripts/help/__gripe_missing_component__.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/help/__gripe_missing_component__.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,56 @@ +## Copyright (C) 2013 Mike Miller +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} __gripe_missing_component__ (@var{caller}, @var{component}) +## Undocumented internal function. +## @end deftypefn + +function __gripe_missing_component__ (caller, component) + + if (nargin != 2) + print_usage (); + endif + + msg = ""; + fcn = missing_component_hook (); + + ftype = exist (fcn); + if (ftype == 2 || ftype == 3 || ftype == 5 || ftype == 103) + msg = feval (fcn, component); + endif + + if (isempty (msg)) + switch (component) + case "info-file" + msg = "unable to find the Octave info manual, Octave installation is incomplete"; + case "mkoctfile" + msg = "unable to find the mkoctfile command, Octave installation is incomplete"; + case "octave" + msg = "unable to find the octave executable, Octave installation is incomplete"; + case "octave-config" + msg = "unable to find the octave-config command, Octave installation is incomplete"; + otherwise + msg = ["unable to find required Octave component \"" component "\""]; + endswitch + endif + + error ("%s: %s\n", caller, msg); + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/help/__makeinfo__.m --- a/scripts/help/__makeinfo__.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/help/__makeinfo__.m Sat Oct 05 11:22:09 2013 -0400 @@ -1,4 +1,4 @@ -## Copyright (C) 2009-2012 S�ren Hauberg +## Copyright (C) 2009-2012 Søren Hauberg ## ## This file is part of Octave. ## @@ -72,6 +72,9 @@ error ("__makeinfo__: second input argument must be a string"); endif + ## NOTE: The 3rd argument is used by Octave-Forge function + ## generate_package_html, not by core Octave. This functionality + ## can only be removed when that function has been updated. if (nargin < 3) if (strcmpi (output_type, "plain text")) fsee_also = @(T) strcat ... @@ -100,7 +103,7 @@ error ("unable to open %s for reading", file); else macros_text = fread (fid, Inf, "*char")'; - text = cstrcat (macros_text, text); + text = [macros_text text]; endif fclose (fid); diff -r 20d1b911b4e7 -r c702371ff6df scripts/help/__unimplemented__.m --- a/scripts/help/__unimplemented__.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/help/__unimplemented__.m Sat Oct 05 11:22:09 2013 -0400 @@ -40,59 +40,464 @@ ## Some smarter cases, add more as needed. switch (fcn) + case {"avifile", "aviinfo", "aviread"} + txt = ["Basic video file support is provided in the video package. ", ... + "See @url{http://octave.sf.net/video/}."]; - case "quad2d" - txt = ["quad2d is not implemented. Consider using dblquad."]; + case "exifread" + txt = ["exifread is deprecated. " ... + "The functionality is available in the imfinfo function."]; + + case "gsvd" + txt = ["gsvd is not currently part of core Octave. ", ... + "See the linear-algebra package at ", ... + "@url{http://octave.sourceforge.net/linear-algebra/}."]; + + case "funm" + txt = ["funm is not currently part of core Octave. ", ... + "See the linear-algebra package at ", ... + "@url{http://octave.sourceforge.net/linear-algebra/}."]; + + case "griddedInterpolant" + txt = ["griddedInterpolant is not implemented. ", ... + "Consider using griddata."]; + + case "integral" + txt = ["Octave provides many routines for 1-D numerical integration. ", ... + "Consider quadcc, quad, quadv, quadl, quadgk."]; + + case "integral2" + txt = ["integral2 is not implemented. Consider using dblquad."]; - case "gsvd" - txt = ["gsvd is not currently part of core Octave. See the ",... - "linear-algebra package at ",... - "@url{http://octave.sourceforge.net/linear-algebra/}."]; + case "integral3" + txt = ["integral3 is not implemented. Consider using triplequad"]; + + case "linprog" + txt = ["Octave does not currently provide linprog. ", ... + "Linear programming problems may be solved using @code{glpk}. ", ... + "Try @code{help glpk} for more info."]; + + case "matlabrc" + txt = ["matlabrc is not implemented. ", ... + 'Octave uses the file ".octaverc" instead.']; + + case {"ode113", "ode15i", "ode15s", "ode23", "ode23s", "ode23t", ... + "ode23tb", "ode45", "odeget", "odeset"} + txt = ["Octave provides lsode for solving differential equations. ", ... + "For more information try @code{help lsode}. ", ... + "Matlab-compatible ODE functions are provided by the odepkg ", ... + "package. See @url{http://octave.sourceforge.net/odepkg/}."]; + + case "startup" + txt = ["startup is not implemented. ", ... + 'Octave uses the file ".octaverc" instead.']; + + case "quad2d" + txt = ["quad2d is not implemented. Consider using dblquad."]; + + case {"xlsread", "xlsfinfo", "xlswrite", "wk1read", "wk1finfo", "wk1write"} + txt = ["Functions for spreadsheet style I/O ", ... + "(.xls .xlsx .sxc .ods .dbf .wk1 etc.) " , ... + "are provided in the io package. ", ... + "See @url{http://octave.sf.net/io/}."]; - case "funm" - txt = ["funm is not currently part of core Octave. See the ",... - "linear-algebra package at @url{http://octave.sf.net/linear-algebra/}."]; + ## control system + case {"absorbDelay", "allmargin", "append", "augstate", "balreal", ... + "balred", "balredOptions", "bandwidth", "bdschur", "bode", ... + "bodemag", "bodeoptions", "bodeplot", "c2d", "c2dOptions", ... + "canon", "care", "chgFreqUnit", "chgTimeUnit", "connect", ... + "connectOptions", "covar", "ctrb", "ctrbf", "ctrlpref", "d2c", ... + "d2cOptions", "d2d", "d2dOptions", "damp", "dare", "db2mag", ... + "dcgain", "delay2z", "delayss", "dlqr", "dlyap", "dlyapchol", ... + "drss", "dsort", "dss", "dssdata", "esort", "estim", "evalfr", ... + "feedback", "filt", "frd", "frdata", "freqresp", "gcare", "gdare", ... + "genfrd", "genmat", "gensig", "genss", "get", "getBlockValue", ... + "getDelayModel", "getGainCrossover", "getIOTransfer", ... + "getLFTModel", "getLoopTransfer", "getNominal", "getoptions", ... + "getPeakGain", "getSwitches", "getValue", "gram", "hasdelay", ... + "hasInternalDelay", "hsvd", "hsvdOptions", "hsvoptions", ... + "hsvplot", "imp2exp", "impulse", "impulseplot", "initial", ... + "initialplot", "iopzmap", "iopzplot", "isct", "isdt", "isempty", ... + "isfinite", "isParametric", "isproper", "isreal", "issiso", ... + "isstable", "isstatic", "kalman", "kalmd", "lft", "loopswitch", ... + "lqg", "lqgreg", "lqgtrack", "lqi", "lqr", "lqrd", "lqry", "lsim", ... + "lsiminfo", "lsimplot", "ltiview", "lyap", "lyapchol", "mag2db", ... + "margin", "minreal", "modred", "modsep", "nblocks", "ndims", ... + "ngrid", "nichols", "nicholsoptions", "nicholsplot", "nmodels", ... + "norm", "nyquist", "nyquistoptions", "nyquistplot", "obsv", ... + "obsvf", "order", "pade", "parallel", "permute", "pid", "piddata", ... + "pidstd", "pidstddata", "pidtool", "pidtune", "pidtuneOptions", ... + "place", "pole", "prescale", "pzmap", "pzoptions", "pzplot", ... + "realp", "reg", "replaceBlock", "repsys", "reshape", "rlocus", ... + "rlocusplot", "rss", "series", "set", "setBlockValue", ... + "setDelayModel", "setoptions", "setValue", "sgrid", ... + "showBlockValue", "showTunable", "sigma", "sigmaoptions", ... + "sigmaplot", "sisoinit", "sisotool", "size", "sminreal", "ss", ... + "ss2ss", "ssdata", "stabsep", "stabsepOptions", "stack", "step", ... + "stepDataOptions", "stepinfo", "stepplot", "sumblk", "tf", ... + "tfdata", "thiran", "timeoptions", "totaldelay", "tzero", ... + "updateSystem", "upsample", "xperm", "zero", "zgrid", "zpk", ... + "zpkdata"} + txt = check_package (fcn, "control"); - case "linprog" - txt = ["Octave does not currently provide linprog. ",... - "Linear programming problems may be solved using @code{glpk}. ",... - "Try @code{help glpk} for more info."]; - - case {"ode113", "ode15i", "ode15s", "ode23", "ode23s", "ode23t", "ode45", "odeget", "odeset"} - txt = ["Octave provides lsode for solving differential equations. ",... - "For more information try @code{help lsode}. ",... - "Matlab-compatible ODE functions are provided by the odepkg package. ",... - "See @url{http://octave.sourceforge.net/odepkg/}."]; + ## communications + case {"algdeintrlv", "algintrlv", "alignsignals", "amdemod", "ammod", ... + "arithdeco", "arithenco", "awgn", "bchdec", "bchenc", ... + "bchgenpoly", "bchnumerr", "berawgn", "bercoding", "berconfint", ... + "berfading", "berfit", "bersync", "bertool", "bi2de", "bin2gray", ... + "biterr", "bsc", "cma", "commscope", "compand", "convdeintrlv", ... + "convenc", "convintrlv", "convmtx", "cosets", "cyclgen", ... + "cyclpoly", "de2bi", "decode", "deintrlv", "dfe", "dftmtx", ... + "distspec", "doppler", "dpcmdeco", "dpcmenco", "dpcmopt", ... + "dpskdemod", "dpskmod", "dvbs2ldpc", "encode", "equalize", ... + "eyediagram", "EyeScope", "finddelay", "fmdemod", "fmmod", ... + "fskdemod", "fskmod", "gaussdesign", "gen2par", "genqamdemod", ... + "genqammod", "gf", "gfadd", "gfconv", "gfcosets", "gfdeconv", ... + "gfdiv", "gffilter", "gflineq", "gfminpol", "gfmul", "gfpretty", ... + "gfprimck", "gfprimdf", "gfprimfd", "gfrank", "gfrepcov", ... + "gfroots", "gfsub", "gftable", "gftrunc", "gftuple", "gfweight", ... + "gray2bin", "hammgen", "heldeintrlv", "helintrlv", ... + "helscandeintrlv", "helscanintrlv", "huffmandeco", "huffmandict", ... + "huffmanenco", "intdump", "intrlv", "iscatastrophic", ... + "isprimitive", "istrellis", "legacychannelsim", "lineareq", ... + "lloyds", "lms", "log", "lteZadoffChuSeq", "marcumq", ... + "mask2shift", "matdeintrlv", "matintrlv", "minpol", "mldivide", ... + "mlseeq", "modnorm", "muxdeintrlv", "muxintrlv", "noisebw", ... + "normlms", "oct2dec", "oqpskdemod", "oqpskmod", "pamdemod", ... + "pammod", "pmdemod", "pmmod", "poly2trellis", "primpoly", ... + "pskdemod", "pskmod", "qamdemod", "qammod", "qfunc", "qfuncinv", ... + "quantiz", "randdeintrlv", "randerr", "randintrlv", "randsrc", ... + "rayleighchan", "rcosdesign", "rectpulse", "reset", "ricianchan", ... + "rls", "rsdec", "rsenc", "rsgenpoly", "rsgenpolycoeffs", ... + "scatterplot", "sdrexamples", "sdrfgensysace", "sdrfroot", ... + "sdrinfo", "sdrload", "sdrsetup", "semianalytic", "shift2mask", ... + "signlms", "ssbdemod", "ssbmod", "stdchan", ... + "supportPackageInstaller", "symerr", "syndtable", "varlms", ... + "vec2mat", "vitdec", "wgn"} + txt = check_package (fcn, "communications"); - case {"javaArray", "javaMethod", "javaMethodEDT", "javaObject", "javaObjectEDT", "javaaddpath", "javaclasspath", "javarmpath"} - txt = ["Java objects and methods can be used with the java package. ",... - "See @url{http://octave.sf.net/java/}."]; - - case {"errordlg", "helpdlg", "inputdlg", "listdlg", "questdlg", "warndlg"} - txt = ["Several dialog functions are provided in the java package. ",... - "See @url{http://octave.sf.net/java/}."]; + ## finance + case {"abs2active", "accrfrac", "acrubond", "acrudisc", "active2abs", ... + "addEquality", "addEquality", "addEquality", "addGroupRatio", ... + "addGroupRatio", "addGroupRatio", "addGroups", "addGroups", ... + "addGroups", "addInequality", "addInequality", "addInequality", ... + "adline", "adosc", "amortize", "annurate", "annuterm", ... + "arith2geom", "ascii2fts", "beytbill", "binprice", "blkimpv", ... + "blkprice", "blsdelta", "blsgamma", "blsimpv", "blslambda", ... + "blsprice", "blsrho", "blstheta", "blsvega", "bndconvp", ... + "bndconvy", "bnddurp", "bnddury", "bndkrdur", "bndprice", ... + "bndspread", "bndtotalreturn", "bndyield", "bolling", "bollinger", ... + "boxcox", "busdate", "busdays", "candle", "cdai", "cdprice", ... + "cdyield", "cfamounts", "cfbyzero", "cfconv", "cfdates", "cfdur", ... + "cfplot", "cfport", "cfprice", "cfspread", "cftimes", "cfyield", ... + "chaikosc", "chaikvolat", "chartfts", "checkFeasibility", ... + "checkFeasibility", "checkFeasibility", "chfield", "convert2sur", ... + "convertto", "corr2cov", "cov2corr", "cpncount", "cpndaten", ... + "cpndatenq", "cpndatep", "cpndaysp", "cpnpersz", "createholidays", ... + "cumsum", "cur2frac", "cur2str", "date2time", "dateaxis", ... + "datedisp", "datefind", "datemnth", "datewrkdy", "day", "days360", ... + "days360e", "days360isda", "days360psa", "days365", "daysact", ... + "daysadd", "daysdif", "dec2thirtytwo", "depfixdb", "depgendb", ... + "deprdv", "depsoyd", "depstln", "diff", "disc2zero", "discrate", ... + "ecmmvnrfish", "ecmmvnrmle", "ecmmvnrobj", "ecmmvnrstd", ... + "ecmnfish", "ecmnhess", "ecmninit", "ecmnmle", "ecmnobj", ... + "ecmnstd", "effrr", "elpm", "emaxdrawdown", "end", "eomdate", ... + "estimateAssetMoments", "estimateBounds", "estimateBounds", ... + "estimateBounds", "estimateFrontier", "estimateFrontier", ... + "estimateFrontier", "estimateFrontierByReturn", ... + "estimateFrontierByReturn", "estimateFrontierByReturn", ... + "estimateFrontierByRisk", "estimateFrontierByRisk", ... + "estimateFrontierByRisk", "estimateFrontierLimits", ... + "estimateFrontierLimits", "estimateFrontierLimits", ... + "estimateMaxSharpeRatio", "estimatePortMoments", ... + "estimatePortReturn", "estimatePortReturn", "estimatePortReturn", ... + "estimatePortRisk", "estimatePortRisk", "estimatePortRisk", ... + "estimatePortStd", "estimatePortStd", "estimatePortVaR", ... + "estimateScenarioMoments", "estimateScenarioMoments", "ewstats", ... + "exp", "extfield", "fbusdate", "fetch", "fieldnames", "fillts", ... + "fints", "floatdiscmargin", "floatmargin", "fpctkd", "frac2cur", ... + "freqnum", "freqstr", "frontcon", "frontier", "fts2ascii", ... + "fts2mat", "ftsbound", "ftsgui", "ftsinfo", "ftstool", "ftsuniq", ... + "fvdisc", "fvfix", "fvvar", "fwd2zero", "geom2arith", ... + "getAssetMoments", "getBounds", "getBounds", "getBounds", ... + "getBudget", "getBudget", "getBudget", "getCosts", "getCosts", ... + "getCosts", "getEquality", "getEquality", "getEquality", ... + "getGroupRatio", "getGroupRatio", "getGroupRatio", "getGroups", ... + "getGroups", "getGroups", "getInequality", "getInequality", ... + "getInequality", "getnameidx", "getOneWayTurnover", ... + "getOneWayTurnover", "getOneWayTurnover", "getScenarios", ... + "getScenarios", "hhigh", "highlow", "holdings2weights", ... + "holidays", "horzcat", "hour", "inforatio", "irr", "isbusday", ... + "iscompatible", "isempty", "isfield", "issorted", "kagi", "lagts", ... + "lbusdate", "leadts", "length", "linebreak", "llow", "log", ... + "log10", "log2", "lpm", "lweekdate", "m2xdate", "macd", ... + "maxdrawdown", "medprice", "merge", "minus", "minute", "mirr", ... + "month", "months", "movavg", "mrdivide", "mtimes", "mvnrfish", ... + "mvnrmle", "mvnrobj", "mvnrstd", "nancov", "nanmax", "nanmean", ... + "nanmedian", "nanmin", "nanstd", "nansum", "nanvar", "negvolidx", ... + "nomrr", "nweekdate", "nyseclosures", "onbalvol", "opprofit", ... + "payadv", "payodd", "payper", "payuni", "pcalims", "pcgcomp", ... + "pcglims", "pcpval", "peravg", "periodicreturns", "plotFrontier", ... + "plotFrontier", "plotFrontier", "plus", "pointfig", "portalloc", ... + "portalpha", "portcons", "Portfolio", "PortfolioCVaR", ... + "PortfolioMAD", "portopt", "portrand", "portror", "portsim", ... + "portstats", "portvar", "portvrisk", "posvolidx", "power", ... + "prbyzero", "prcroc", "prdisc", "priceandvol", "prmat", "prtbill", ... + "pvfix", "pvtrend", "pvvar", "pyld2zero", "rdivide", "renko", ... + "resamplets", "ret2tick", "rmfield", "rsindex", "selectreturn", ... + "setAssetList", "setAssetList", "setAssetList", "setAssetMoments", ... + "setBounds", "setBounds", "setBounds", "setBudget", "setBudget", ... + "setBudget", "setCosts", "setCosts", "setCosts", ... + "setDefaultConstraints", "setDefaultConstraints", ... + "setDefaultConstraints", "setEquality", "setEquality", ... + "setEquality", "setGroupRatio", "setGroupRatio", "setGroupRatio", ... + "setGroups", "setGroups", "setGroups", "setInequality", ... + "setInequality", "setInequality", "setInitPort", "setInitPort", ... + "setInitPort", "setOneWayTurnover", "setOneWayTurnover", ... + "setOneWayTurnover", "setProbabilityLevel", "setScenarios", ... + "setScenarios", "setSolver", "setSolver", "setSolver", ... + "setTurnover", "setTurnover", "setTurnover", "sharpe", ... + "simulateNormalScenariosByData", "simulateNormalScenariosByData", ... + "simulateNormalScenariosByMoments", ... + "simulateNormalScenariosByMoments", "size", "smoothts", "sortfts", ... + "spctkd", "stochosc", "subsasgn", "subsref", "targetreturn", ... + "taxedrr", "tbilldisc2yield", "tbillprice", "tbillrepo", ... + "tbillval01", "tbillyield", "tbillyield2disc", "tbl2bond", ... + "thirdwednesday", "thirtytwo2dec", "tick2ret", "time2date", ... + "times", "toannual", "todaily", "today", "todecimal", "tomonthly", ... + "toquarterly", "toquoted", "tosemi", "totalreturnprice", ... + "toweekly", "tr2bonds", "transprob", "transprobbytotals", ... + "transprobfromthresholds", "transprobgrouptotals", ... + "transprobprep", "transprobtothresholds", "tsaccel", "tsmom", ... + "tsmovavg", "typprice", "ugarch", "ugarchllf", "ugarchpred", ... + "ugarchsim", "uicalendar", "uminus", "uplus", "vertcat", ... + "volarea", "volroc", "wclose", "weeknum", "weights2holdings", ... + "willad", "willpctr", "wrkdydif", "x2mdate", "xirr", "year", ... + "yeardays", "yearfrac", "ylddisc", "yldmat", "yldtbill", ... + "zbtprice", "zbtyield", "zero2disc", "zero2fwd", "zero2pyld"} + txt = check_package (fcn, "financial"); - case {"xlsread", "xlsfinfo", "xlswrite", "wk1read", "wk1finfo", "wk1write"} - txt = ["Functions for spreadsheet style I/O (.xls .xlsx .sxc .ods .dbf .wk1 etc.) " , ... - "are provided in the io package. ",... - "See @url{http://octave.sf.net/io/}."]; + ## image processing + case {"activecontour", "adapthisteq", "affine2d", "affine3d", ... + "analyze75info", "analyze75read", "applycform", "applylut", ... + "axes2pix", "bestblk", "blockproc", "bwarea", "bwareaopen", ... + "bwboundaries", "bwconncomp", "bwconvhull", "bwdist", ... + "bwdistgeodesic", "bweuler", "bwhitmiss", "bwlabel", "bwlabeln", ... + "bwlookup", "bwmorph", "bwpack", "bwperim", "bwselect", ... + "bwtraceboundary", "bwulterode", "bwunpack", "checkerboard", ... + "col2im", "colfilt", "conndef", "convmtx2", "corner", ... + "cornermetric", "corr2", "cp2tform", "cpcorr", "cpselect", ... + "cpstruct2pairs", "dct2", "dctmtx", "deconvblind", "deconvlucy", ... + "deconvreg", "deconvwnr", "decorrstretch", "demosaic", ... + "dicomanon", "dicomdict", "dicominfo", "dicomlookup", "dicomread", ... + "dicomuid", "dicomwrite", "edge", "edgetaper", "entropy", ... + "entropyfilt", "fan2para", "fanbeam", "findbounds", "fitgeotrans", ... + "fliptform", "freqz2", "fsamp2", "fspecial", "ftrans2", "fwind1", ... + "fwind2", "getheight", "getimage", "getimagemodel", "getline", ... + "getneighbors", "getnhood", "getpts", "getrect", "getsequence", ... + "graycomatrix", "graycoprops", "graydist", "grayslice", ... + "graythresh", "hdrread", "hdrwrite", "histeq", "hough", ... + "houghlines", "houghpeaks", "iccfind", "iccread", "iccroot", ... + "iccwrite", "idct2", "ifanbeam", "im2bw", "im2col", "im2double", ... + "im2int16", "im2java2d", "im2single", "im2uint16", "im2uint8", ... + "imabsdiff", "imadd", "imadjust", "ImageAdapter", "imageinfo", ... + "imapplymatrix", "imapprox", "imattributes", "imbothat", ... + "imclearborder", "imclose", "imcolormaptool", "imcomplement", ... + "imcontour", "imcontrast", "imcrop", "imdilate", "imdisplayrange", ... + "imdistline", "imdivide", "imellipse", "imerode", "imextendedmax", ... + "imextendedmin", "imfill", "imfilter", "imfindcircles", ... + "imfreehand", "imfuse", "imgca", "imgcf", "imgetfile", ... + "imgradient", "imgradientxy", "imhandles", "imhist", ... + "imhistmatch", "imhmax", "imhmin", "imimposemin", "imlincomb", ... + "imline", "immagbox", "immovie", "immultiply", "imnoise", ... + "imopen", "imoverview", "imoverviewpanel", "impixel", ... + "impixelinfo", "impixelinfoval", "impixelregion", ... + "impixelregionpanel", "implay", "impoint", "impoly", "improfile", ... + "impyramid", "imquantize", "imreconstruct", "imrect", "imref2d", ... + "imref3d", "imregconfig", "imregionalmax", "imregionalmin", ... + "imregister", "imregtform", "imresize", "imroi", "imrotate", ... + "imsave", "imscrollpanel", "imsharpen", "imshowpair", ... + "imsubtract", "imtool", "imtophat", "imtransform", "imwarp", ... + "interfileinfo", "interfileread", "intlut", "iptaddcallback", ... + "iptcheckconn", "iptcheckhandle", "iptgetapi", ... + "iptGetPointerBehavior", "iptgetpref", "ipticondir", ... + "iptPointerManager", "iptprefs", "iptremovecallback", ... + "iptSetPointerBehavior", "iptsetpref", "iptwindowalign", "iradon", ... + "isflat", "isicc", "isrset", "lab2double", "lab2uint16", ... + "lab2uint8", "label2rgb", "labelmatrix", "makecform", ... + "makeConstrainToRectFcn", "makehdr", "makelut", "makeresampler", ... + "maketform", "mat2gray", "mean2", "medfilt2", "montage", ... + "multithresh", "nitfinfo", "nitfread", "nlfilter", "normxcorr2", ... + "openrset", "ordfilt2", "otf2psf", "padarray", "para2fan", ... + "phantom", "poly2mask", "projective2d", "psf2otf", "qtdecomp", ... + "qtgetblk", "qtsetblk", "radon", "rangefilt", "reflect", ... + "regionprops", "rgb2gray", "rgb2ycbcr", "roicolor", "roifill", ... + "roifilt2", "roipoly", "rsetwrite", "std2", "stdfilt", "strel", ... + "stretchlim", "subimage", "tformarray", "tformfwd", "tforminv", ... + "tonemap", "translate", "truesize", "viscircles", "warp", ... + "watershed", "whitepoint", "wiener2", "xyz2double", "xyz2uint16", ... + "ycbcr2rgb"} + txt = check_package (fcn, "image"); + + ## signal processing + case {"ac2poly", "ac2rc", "angle", "arburg", "arcov", "armcov", ... + "aryule", "bandpower", "barthannwin", "besselap", "besself", ... + "bilinear", "bitrevorder", "blackmanharris", "bohmanwin", ... + "buffer", "buttap", "butter", "buttord", "cceps", "cconv", ... + "cell2sos", "cfirpm", "cheb1ap", "cheb1ord", "cheb2ap", ... + "cheb2ord", "chebwin", "cheby1", "cheby2", "chirp", "convmtx", ... + "corrmtx", "cpsd", "czt", "db", "db2mag", "db2pow", "dct", ... + "decimate", "demod", "design", "designmethods", "designopts", ... + "dfilt", "dftmtx", "digitrevorder", "diric", "downsample", "dpss", ... + "dpssclear", "dpssdir", "dpssload", "dspdata", "dspfwiz", ... + "dutycycle", "ellip", "ellipap", "ellipord", "enbw", "equiripple", ... + "falltime", "fdatool", "fdesign", "filt2block", "filterbuilder", ... + "filternorm", "filtfilt", "filtic", "filtord", "findpeaks", ... + "fir1", "fir2", "fircls", "fircls1", "firls", "firpm", "firpmord", ... + "firrcos", "firtype", "flattopwin", "freqs", "freqsamp", "fvtool", ... + "fwht", "gauspuls", "gaussdesign", "gaussfir", "gausswin", ... + "gmonopuls", "goertzel", "grpdelay", "hann", "hilbert", "icceps", ... + "idct", "ifwht", "impinvar", "impz", "impzlength", "interp", ... + "intfilt", "invfreqs", "invfreqz", "is2rc", "isallpass", ... + "islinphase", "ismaxphase", "isminphase", "isstable", "kaiser", ... + "kaiserord", "kaiserwin", "lar2rc", "latc2tf", "latcfilt", ... + "levinson", "lp2bp", "lp2bs", "lp2hp", "lp2lp", "lpc", "lsf2poly", ... + "mag2db", "marcumq", "maxflat", "medfilt1", "midcross", ... + "modulate", "mscohere", "nuttallwin", "overshoot", "parzenwin", ... + "pburg", "pcov", "peak2peak", "peak2rms", "peig", "phasedelay", ... + "phasez", "pmcov", "pmtm", "pmusic", "poly2ac", "poly2lsf", ... + "poly2rc", "polyscale", "polystab", "pow2db", "prony", ... + "pulseperiod", "pulsesep", "pulsewidth", "pulstran", "pwelch", ... + "pyulear", "rc2ac", "rc2is", "rc2lar", "rc2poly", "rceps", ... + "rcosdesign", "realizemdl", "rectpuls", "rectwin", "resample", ... + "residuez", "risetime", "rlevinson", "rms", "rooteig", ... + "rootmusic", "rssq", "sawtooth", "schurrc", "seqperiod", ... + "setspecs", "settlingtime", "sfdr", "sgolay", "sgolayfilt", ... + "shiftdata", "sigwin", "sinad", "slewrate", "snr", "sos2cell", ... + "sos2ss", "sos2tf", "sos2zp", "sosfilt", "spectrogram", ... + "spectrum", "sptool", "square", "ss2sos", "ss2tf", "ss2zp", ... + "statelevels", "stepz", "stmcb", "strips", "taylorwin", "tf2latc", ... + "tf2sos", "tf2ss", "tf2zp", "tf2zpk", "tfestimate", "thd", "toi", ... + "triang", "tripuls", "tukeywin", "udecode", "uencode", ... + "undershoot", "unshiftdata", "upfirdn", "upsample", ... + "validstructures", "vco", "window", "wintool", "wvtool", "xcorr", ... + "xcorr2", "xcov", "yulewalk", "zerophase", "zp2sos", "zp2ss", ... + "zp2tf", "zplane"} + txt = check_package (fcn, "signal"); - case {"avifile", "aviinfo", "aviread"} - txt = ["Basic video file support is provided in the video package. ",... - "See @url{http://octave.sf.net/video/}."]; + ## statistics + case {"addedvarplot", "addlevels", "addTerms", "addTerms", "adtest", ... + "andrewsplot", "anova1", "anova2", "anovan", "ansaribradley", ... + "aoctool", "barttest", "bbdesign", "betafit", "betalike", ... + "betastat", "binofit", "binostat", "biplot", "bootci", "bootstrp", ... + "boxplot", "candexch", "candgen", "canoncorr", "capability", ... + "capaplot", "caseread", "casewrite", "ccdesign", "cdf", "cdf", ... + "cdfplot", "cell2dataset", "chi2gof", "chi2stat", "cholcov", ... + "ClassificationBaggedEnsemble", "ClassificationDiscriminant", ... + "ClassificationEnsemble", "ClassificationKNN", ... + "ClassificationPartitionedEnsemble", ... + "ClassificationPartitionedModel", "ClassificationTree", ... + "classify", "classregtree", "cluster", "clusterdata", "cmdscale", ... + "coefCI", "coefCI", "coefCI", "coefCI", "coefTest", "coefTest", ... + "coefTest", "coefTest", "combnk", "compact", ... + "CompactClassificationDiscriminant", ... + "CompactClassificationEnsemble", "CompactClassificationTree", ... + "CompactRegressionEnsemble", "CompactRegressionTree", ... + "CompactTreeBagger", "compare", "confusionmat", "controlchart", ... + "controlrules", "cophenet", "copulacdf", "copulafit", ... + "copulaparam", "copulapdf", "copularnd", "copulastat", "cordexch", ... + "corrcov", "covarianceParameters", "coxphfit", "createns", ... + "crosstab", "crossval", "cvpartition", "datasample", "dataset", ... + "dataset2cell", "dataset2struct", "dataset2table", "datasetfun", ... + "daugment", "dcovary", "dendrogram", "designMatrix", ... + "devianceTest", "dfittool", "disp", "disp", "disp", "disp", ... + "disttool", "droplevels", "dummyvar", "dwtest", "dwtest", "ecdf", ... + "ecdfhist", "evalclusters", "evcdf", "evfit", "evinv", "evlike", ... + "evpdf", "evrnd", "evstat", "ExhaustiveSearcher", "expfit", ... + "explike", "export", "expstat", "factoran", "feval", "feval", ... + "feval", "ff2n", "fitdist", "fitensemble", "fitglm", "fitlm", ... + "fitlme", "fitlmematrix", "fitnlm", "fitted", "fixedEffects", ... + "fracfact", "fracfactgen", "friedman", "fsurfht", "fullfact", ... + "gagerr", "gamfit", "gamlike", "gamstat", ... + "GeneralizedLinearModel", "geomean", "geostat", "getlabels", ... + "getlevels", "gevcdf", "gevfit", "gevinv", "gevlike", "gevpdf", ... + "gevrnd", "gevstat", "gline", "glmfit", "glmval", "glyphplot", ... + "gmdistribution", "gname", "gpcdf", "gpfit", "gpinv", "gplike", ... + "gplotmatrix", "gppdf", "gprnd", "gpstat", "grp2idx", "grpstats", ... + "gscatter", "haltonset", "harmmean", "hist3", "histfit", ... + "hmmdecode", "hmmestimate", "hmmgenerate", "hmmtrain", ... + "hmmviterbi", "hougen", "hygestat", "icdf", "icdf", ... + "inconsistent", "interactionplot", "invpred", "islevel", ... + "ismissing", "isundefined", "iwishrnd", "jackknife", "jbtest", ... + "johnsrnd", "join", "KDTreeSearcher", "kmeans", "knnsearch", ... + "kruskalwallis", "ksdensity", "kstest", "kstest2", "labels", ... + "lasso", "lassoglm", "lassoPlot", "levelcounts", "leverage", ... + "lhsdesign", "lhsnorm", "lillietest", "LinearMixedModel", ... + "LinearModel", "linhyptest", "linkage", "lognfit", "lognlike", ... + "lognstat", "lsline", "mad", "mahal", "maineffectsplot", ... + "makedist", "manova1", "manovacluster", "mat2dataset", "mdscale", ... + "mergelevels", "mhsample", "mle", "mlecov", "mnpdf", "mnrfit", ... + "mnrnd", "mnrval", "multcompare", "multivarichart", "mvncdf", ... + "mvnpdf", "mvnrnd", "mvregress", "mvregresslike", "mvtcdf", ... + "mvtpdf", "mvtrnd", "NaiveBayes", "nancov", "nanmax", "nanmean", ... + "nanmedian", "nanmin", "nanstd", "nansum", "nanvar", "nbinfit", ... + "nbinstat", "ncfcdf", "ncfinv", "ncfpdf", "ncfrnd", "ncfstat", ... + "nctcdf", "nctinv", "nctpdf", "nctrnd", "nctstat", "ncx2cdf", ... + "ncx2inv", "ncx2pdf", "ncx2rnd", "ncx2stat", "negloglik", ... + "negloglik", "nlinfit", "nlintool", "nlmefit", "nlmefitsa", ... + "nlparci", "nlpredci", "nnmf", "nominal", "NonLinearModel", ... + "normfit", "normlike", "normplot", "normspec", "normstat", ... + "optimalleaforder", "ordinal", "parallelcoords", "paramci", ... + "paretotails", "partialcorr", "partialcorri", "pca", "pcacov", ... + "pcares", "pdf", "pdf", "pdist", "pdist2", "pearsrnd", ... + "perfcurve", "plotAdded", "plotAdjustedResponse", ... + "plotDiagnostics", "plotDiagnostics", "plotDiagnostics", ... + "plotEffects", "plotInteraction", "plotResiduals", ... + "plotResiduals", "plotResiduals", "plotResiduals", "plotSlice", ... + "plotSlice", "plotSlice", "plsregress", "poissfit", "poisstat", ... + "polyconf", "polytool", "ppca", "predict", "predict", "predict", ... + "predict", "predict", "predict", "predict", "predict", "princomp", ... + "ProbDistUnivKernel", "ProbDistUnivParam", "probplot", ... + "procrustes", "proflik", "qrandset", "qrandstream", "random", ... + "random", "random", "random", "random", "random", "randomEffects", ... + "randsample", "randtool", "rangesearch", "ranksum", "raylcdf", ... + "raylfit", "raylinv", "raylpdf", "raylrnd", "raylstat", "rcoplot", ... + "refcurve", "refline", "regress", "RegressionBaggedEnsemble", ... + "RegressionEnsemble", "RegressionPartitionedEnsemble", ... + "RegressionPartitionedModel", "RegressionTree", "regstats", ... + "relieff", "removeTerms", "removeTerms", "residuals", "response", ... + "ridge", "robustdemo", "robustfit", "rotatefactors", "rowexch", ... + "rsmdemo", "rstool", "runstest", "sampsizepwr", "scatterhist", ... + "sequentialfs", "setlabels", "signrank", "signtest", "silhouette", ... + "slicesample", "sobolset", "squareform", "statget", "statset", ... + "step", "step", "stepwise", "stepwisefit", "stepwiseglm", ... + "stepwiselm", "struct2dataset", "surfht", "svmclassify", ... + "svmtrain", "table2dataset", "tabulate", "tblread", "tblwrite", ... + "tdfread", "tiedrank", "TreeBagger", "trimmean", "truncate", ... + "tstat", "ttest", "ttest2", "unidstat", "unifit", "unifstat", ... + "vartest", "vartest2", "vartestn", "wblfit", "wbllike", "wblplot", ... + "wblstat", "wishrnd", "x2fx", "xlsread", "xptread", "ztest"} + txt = check_package (fcn, "statistics"); - otherwise - if (ismember (fcn, missing_functions ())) - txt = sprintf ("the '%s' function is not yet implemented in Octave", fcn); - else - is_matlab_function = false; - txt = ""; - endif + ## optimization + case {"bintprog", "color", "fgoalattain", "fmincon", "fminimax", ... + "fminsearch", "fseminf", "fzmult", "gangstr", "ktrlink", ... + "linprog", "lsqcurvefit", "lsqlin", "lsqnonlin", "optimoptions", ... + "optimtool", "quadprog"} + txt = check_package (fcn, "optim"); + + otherwise + if (ismember (fcn, missing_functions ())) + txt = ["the '" fcn "' function is not yet implemented in Octave"]; + else + is_matlab_function = false; + txt = ""; + endif endswitch if (is_matlab_function) - txt = [txt, "\n\n@noindent\nPlease read ",... - "@url{http://www.octave.org/missing.html} to learn how ",... + txt = [txt, "\n\n@noindent\nPlease read ", ... + "@url{http://www.octave.org/missing.html} to learn how ", ... "you can contribute missing functionality."]; txt = __makeinfo__ (txt); endif @@ -103,24 +508,43 @@ endfunction +function txt = check_package (fcn, name) + txt = sprintf ("the '%s' function belongs to the %s package from Octave Forge", + fcn, name); + + [~, status] = pkg ("describe", name); + switch (tolower (status{1})) + case "loaded", + txt = sprintf ("%s but has not yet been implemented.", txt); + case "not loaded", + txt = sprintf (["%s which you have installed but not loaded. To ", ... + "load the package, run `pkg load %s' from the ", ... + "Octave prompt."], txt, name); + otherwise + ## this includes "not installed" and anything else if pkg changes + ## the output of describe + txt = sprintf ("%s which seems to not be installed in your system.", txt); + endswitch +endfunction + function list = missing_functions () persistent list = { - "DelaunayTri", "MException", "RandStream", - "TriRep", - "TriScatteredInterp", + "Tiff", + "VideoReader", + "VideoWriter", "align", "alim", "alpha", "alphamap", "annotation", "audiodevinfo", + "audioinfo", "audioplayer", + "audioread", "audiorecorder", - "aufinfo", - "auread", - "auwrite", + "audiowrite", "bar3", "bar3h", "bench", @@ -155,50 +579,50 @@ "cdfwrite", "cellplot", "checkin", + "checkcode", "checkout", "cholinc", "clearvars", "clipboard", "cmopts", - "cmpermute", - "cmunique", "colordef", "colormapeditor", "commandhistory", "commandwindow", "condeig", "coneplot", + "containers.Map", "contourslice", "createClassFromWsdl", "createSoapMessage", "customverctrl", - "daqread", "datacursormode", - "datatipinfo", "dbmex", "dde23", "ddeget", + "ddensd", "ddesd", "ddeset", "decic", + "delaunayTriangulation", "depdir", "depfun", "deval", "dialog", "dither", - "docopt", "docsearch", "dragrect", "dynamicprops", "echodemo", "evalc", - "exifread", "export2wsdlg", "figurepalette", "filebrowser", "fill3", + "fitsdisp", "fitsinfo", "fitsread", + "fitswrite", "flow", "frame2im", "freqspace", @@ -206,41 +630,44 @@ "gammaincinv", "getframe", "getpixelposition", + "gobjects", "grabcode", "graymon", + "griddedInterpolant", "gsvd", "guidata", "guide", "guihandles", "handle", - "hdf", - "hdf5", - "hdf5info", - "hdf5read", - "hdf5write", + "h5create", + "h5disp", + "h5info", + "h5read", + "h5readatt", + "h5write", + "h5writeatt", "hdfinfo", "hdfread", - "hdftool", - "helpbrowser", - "helpdesk", - "helpwin", "hgexport", "hgload", "hgsave", "hgsetget", "hgtransform", - "hostid", + "ichol", "ilu", "im2frame", "im2java", "imapprox", - "imformats", "import", "inmem", "inputParser", "inspect", + "instrcallback", "instrfind", "instrfindall", + "integral", + "integral2", + "integral3", "interpstreamspeed", "iscom", "isinterface", @@ -259,32 +686,37 @@ "lighting", "linkaxes", "linkdata", - "linsolve", "listfonts", "loadlibrary", "lscov", "lsqr", "makehgtform", "material", + "matfile", "matlabrc", - "maxNumCompThreads", "memmapfile", "memory", "metaclass", "methodsview", "minres", - "mlint", "mlintrpt", "mmfileinfo", - "mmreader", "movegui", "movie", "movie2avi", - "msgbox", "multibandread", "multibandwrite", "native2unicode", + "nccreate", + "ncdisp", + "ncinfo", + "ncread", + "ncreadatt", + "ncwrite", + "ncwriteatt", + "ncwriteschema", "noanimate", + "notebook", "ode113", "ode15i", "ode15s", @@ -293,7 +725,6 @@ "ode23t", "ode23tb", "ode45", - "odefile", "odeget", "odeset", "odextend", @@ -305,38 +736,37 @@ "ordqz", "ordschur", "padecoef", - "pagesetupdlg", "pan", "parseSoapResponse", - "path2rc", "pathtool", "pcode", "pdepe", "pdeval", - "playshow", "plotbrowser", "plotedit", "plottools", - "prefdir", - "preferences", "printdlg", "printopt", "printpreview", "profsave", "propedit", "propertyeditor", + "psi", "publish", "qmr", "quad2d", "rbbox", "reducepatch", "reducevolume", - "root", + "readasync", + "rng", "rotate", "rotate3d", + "scatteredInterpolant", "selectmoveresize", "sendmail", "serial", + "serialbreak", "setpixelposition", "showplottool", "smooth3", @@ -344,6 +774,8 @@ "sound", "soundsc", "ss2tf", + "startup", + "stopasync", "stream2", "stream3", "streamline", @@ -354,7 +786,6 @@ "strings", "subvolume", "superclasses", - "support", "surf2patch", "symmlq", "syntax", @@ -362,10 +793,10 @@ "textwrap", "tfqmr", "timer", - "timerfind", - "timerfindall", "timeseries", + "todatenum", "toolboxdir", + "triangulation", "tscollection", "tstool", "uibuttongroup", @@ -392,19 +823,15 @@ "unmesh", "userpath", "validateattributes", + "verctrl", "verLessThan", "viewmtx", "visdiff", "volumebounds", - "waitfor", - "wavfinfo", - "wavplay", - "wavrecord", "web", "whatsnew", - "wk1finfo", - "wk1read", - "wk1write", + "winopen", + "winqueryreg", "workspace", "xmlread", "xmlwrite", @@ -421,3 +848,4 @@ %! assert (str(1:51), "quad2d is not implemented. Consider using dblquad."); %! str = __unimplemented__ ("MException"); %! assert (str(1:58), "the 'MException' function is not yet implemented in Octave"); + diff -r 20d1b911b4e7 -r c702371ff6df scripts/help/doc.m --- a/scripts/help/doc.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/help/doc.m Sat Oct 05 11:22:09 2013 -0400 @@ -1,4 +1,4 @@ -## Copyright (C) 2005-2012 Søren Hauberg +## Copyright (C) 2005-2012 Søren Hauberg ## ## This file is part of Octave. ## @@ -53,53 +53,64 @@ fname = ""; endif - if (ftype == 2 || ftype == 3) - ffile = which (fname); - else - ffile = ""; - endif - - if (isempty (ffile)) - info_dir = octave_config_info ("infodir"); + ## if GUI is running, let it display the function + if isguirunning () + __octave_link_show_doc__ (fname); else - info_dir = fileparts (ffile); - endif - - ## Determine if a file called doc.info exist in the same - ## directory as the function. + + if (ftype == 2 || ftype == 3) + ffile = which (fname); + else + ffile = ""; + endif - info_file_name = fullfile (info_dir, "doc.info"); - - [stat_info, err] = stat (info_file_name); + if (isempty (ffile)) + info_dir = octave_config_info ("infodir"); + else + info_dir = fileparts (ffile); + endif - if (err < 0) - info_file_name = info_file (); - endif + ## Determine if a file called doc.info exist in the same + ## directory as the function. + + info_file_name = fullfile (info_dir, "doc.info"); + + [stat_info, err] = stat (info_file_name); + + if (err < 0) + info_file_name = info_file (); - ## FIXME -- don't change the order of the arguments below because - ## the info-emacs-info script currently expects --directory DIR as - ## the third and fourth arguments. Someone should fix that. + if (! exist (info_file_name, "file")) + __gripe_missing_component__ ("doc", "info-file"); + endif + endif + + ## FIXME -- don't change the order of the arguments below because + ## the info-emacs-info script currently expects --directory DIR as + ## the third and fourth arguments. Someone should fix that. + + cmd = sprintf ("\"%s\" --file \"%s\" --directory \"%s\"", + info_program (), info_file_name, info_dir); + + have_fname = ! isempty (fname); - cmd = sprintf ("\"%s\" --file \"%s\" --directory \"%s\"", - info_program (), info_file_name, info_dir); + if (have_fname) + status = system (sprintf ("%s --index-search \"%s\"", cmd, fname)); + endif + - have_fname = ! isempty (fname); + if (! (have_fname && status == 0)) + status = system (cmd); + if (status == 127) + warning ("unable to find info program '%s'", info_program ()); + endif + endif - if (have_fname) - status = system (sprintf ("%s --index-search \"%s\"", cmd, fname)); + if (nargout > 0) + retval = status; + endif + endif - - if (! (have_fname && status == 0)) - status = system (cmd); - if (status == 127) - warning ("unable to find info program '%s'", info_program ()); - endif - endif - - if (nargout > 0) - retval = status; - endif - else print_usage (); endif diff -r 20d1b911b4e7 -r c702371ff6df scripts/help/doc_cache_create.m --- a/scripts/help/doc_cache_create.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/help/doc_cache_create.m Sat Oct 05 11:22:09 2013 -0400 @@ -1,4 +1,4 @@ -## Copyright (C) 2009-2012 S�ren Hauberg +## Copyright (C) 2009-2012 Søren Hauberg ## ## This file is part of Octave. ## @@ -42,7 +42,7 @@ if (isempty (directory)) cache = gen_builtin_cache (); elseif (iscell (directory)) - if (all (cellfun (@ischar, directory))) + if (all (cellfun ("isclass", directory, "char"))) cache = gen_doc_cache_in_dir (directory); else error ("doc_cache_create: cell must contain only strings"); @@ -95,7 +95,7 @@ ## For each function: for n = 1:length (list) - f = list {n}; + f = list{n}; ## Get help text [text, format] = get_help_text (f); @@ -108,9 +108,9 @@ endif ## Store the help text - cache (1, end+1) = f; - cache (2, end) = text; - cache (3, end) = first_sentence; + cache(1, end+1) = f; + cache(2, end) = text; + cache(3, end) = first_sentence; endfor endfunction @@ -119,27 +119,27 @@ ## If 'directory' is not in the current path, add it so we search it dir_in_path = ismember (directory, ostrsplit (path (), pathsep ())); - # dirs not in path + ## dirs not in path if (! iscell (directory)) directory = {directory}; endif dirs_notpath = {directory{!dir_in_path}}; - # add them + ## add them if (! isempty (dirs_notpath)) - cellfun (@addpath, dirs_notpath); + addpath (dirs_notpath{:}); endif - # create cache + ## create cache func = @(s_) create_cache (__list_functions__ (s_)); - cache = cellfun (func, directory, 'UniformOutput', false); + cache = cellfun (func, directory, "UniformOutput", false); - # concatenate results + ## concatenate results cache = [cache{:}]; - #remove dirs form path + ## remove dirs form path if (! isempty (dirs_notpath)) - cellfun (@rmpath, dirs_notpath); + rmpath (dirs_notpath{:}); endif endfunction @@ -157,3 +157,4 @@ %% No true tests desirable for this function. %% Test input validation %!error doc_cache_create (1) + diff -r 20d1b911b4e7 -r c702371ff6df scripts/help/get_first_help_sentence.m --- a/scripts/help/get_first_help_sentence.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/help/get_first_help_sentence.m Sat Oct 05 11:22:09 2013 -0400 @@ -1,4 +1,4 @@ -## Copyright (C) 2009-2012 S�ren Hauberg +## Copyright (C) 2009-2012 Søren Hauberg ## ## This file is part of Octave. ## @@ -157,7 +157,8 @@ endfunction -%!assert (get_first_help_sentence ('get_first_help_sentence'), "Return the first sentence of a function's help text.") +%!assert (get_first_help_sentence ('get_first_help_sentence'), ... +%! "Return the first sentence of a function's help text.") %% Test input validation %!error get_first_help_sentence () diff -r 20d1b911b4e7 -r c702371ff6df scripts/help/help.m --- a/scripts/help/help.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/help/help.m Sat Oct 05 11:22:09 2013 -0400 @@ -1,4 +1,4 @@ -## Copyright (C) 2009-2012 S�ren Hauberg +## Copyright (C) 2009-2012 Søren Hauberg ## ## This file is part of Octave. ## @@ -20,7 +20,7 @@ ## @deftypefn {Command} {} help @var{name} ## @deftypefnx {Command} {} help @code{--list} ## @deftypefnx {Command} {} help @code{.} -## Display the help text for @var{name}. For example, the command +## Display the help text for @var{name}. For example, the command ## @kbd{help help} prints a short message describing the @code{help} ## command. ## @@ -155,7 +155,7 @@ endif endfor - retval = cstrcat (operators, keywords, builtins, flist); + retval = [operators, keywords, builtins, flist]; endfunction @@ -209,4 +209,3 @@ %!assert (! isempty (strfind (help ("ls"), "List directory contents"))) %!error help (42) - diff -r 20d1b911b4e7 -r c702371ff6df scripts/help/lookfor.m --- a/scripts/help/lookfor.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/help/lookfor.m Sat Oct 05 11:22:09 2013 -0400 @@ -1,4 +1,4 @@ -## Copyright (C) 2009-2012 Søren Hauberg +## Copyright (C) 2009-2012 Søren Hauberg ## ## This file is part of Octave. ## @@ -24,7 +24,7 @@ ## Search for the string @var{str} in all functions found in the current ## function search path. By default, @code{lookfor} searches for @var{str} ## in the first sentence of the help string of each function found. The entire -## help text of each function can be searched if the "-all" argument is +## help text of each function can be searched if the @qcode{"-all"} argument is ## supplied. All searches are case insensitive. ## ## Called with no output arguments, @code{lookfor} prints the list of @@ -36,8 +36,9 @@ ## sentence of the help text is dependent on the format of the ## function's help. All Octave core functions are correctly ## formatted, but the same can not be guaranteed for external packages and -## user-supplied functions. Therefore, the use of the "-all" argument may -## be necessary to find related functions that are not a part of Octave. +## user-supplied functions. Therefore, the use of the @qcode{"-all"} +## argument may be necessary to find related functions that are not a part of +## Octave. ## @seealso{help, doc, which} ## @end deftypefn diff -r 20d1b911b4e7 -r c702371ff6df scripts/help/module.mk --- a/scripts/help/module.mk Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/help/module.mk Sat Oct 05 11:22:09 2013 -0400 @@ -5,6 +5,7 @@ help/private/__strip_html_tags__.m help_FCN_FILES = \ + help/__gripe_missing_component__.m \ help/__makeinfo__.m \ help/__unimplemented__.m \ help/doc.m \ diff -r 20d1b911b4e7 -r c702371ff6df scripts/help/print_usage.m --- a/scripts/help/print_usage.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/help/print_usage.m Sat Oct 05 11:22:09 2013 -0400 @@ -1,4 +1,4 @@ -## Copyright (C) 2009-2012 S�ren Hauberg +## Copyright (C) 2009-2012 Søren Hauberg ## ## This file is part of Octave. ## @@ -31,22 +31,22 @@ if (nargin == 0) ## Determine the name of the calling function if (numel (x) > 1) - name = x (2).name; + name = x(2).name; else error ("Octave:invalid-context", "print_usage: invalid function\n"); endif - fullpath = evalin ("caller", "mfilename (""fullpath"")"); + fullpath = evalin ("caller", 'mfilename ("fullpath")'); if (strcmp (fullpath(end-length(name)+1:end), name)) - fullname = [fullpath, ".m"]; + fullname = [fullpath ".m"]; endif - elseif (!ischar (name)) + elseif (! ischar (name)) error ("Octave:invalid-input-arg", - "print_usage: input argument must be a string"); + "print_usage: input argument must be a string"); else fullname = name; endif - ## Determine if we're called from top level. + ## Determine if we were called from top level. at_toplev = length (x) < 2 || (length (x) == 2 && strcmp (x(2).name, name)); ## Do the actual work @@ -74,7 +74,8 @@ endif if (at_toplev) - error ("Octave:invalid-fun-call", "Invalid call to %s. Correct usage is:\n\n%s\n%s", + error ("Octave:invalid-fun-call", + "Invalid call to %s. Correct usage is:\n\n%s\n%s", name, usage_string, __additional_help_message__ ()); else msg = sprintf ("Invalid call to %s. Correct usage is:\n\n%s", @@ -102,25 +103,23 @@ ## concatenated with the following line. help_text = strrep (help_text, "@\n", " "); - ## Find, and keep, lines that start with @def or @end def. This should include things - ## such as @deftypefn, @deftypefnx, @defvar, etc. and their corresponding @end's + ## Find, and keep, lines that start with @def or @end def. This should + ## include things such as @deftypefn, @deftypefnx, @defvar, etc. and their + ## corresponding @end's. def_idx = strfind (help_text, "@def"); - if (!isempty (def_idx)) - buffer = ""; + if (! isempty (def_idx)) + endf_idx = strfind (help_text, "@end def"); + def_idx = sort ([def_idx, endf_idx]); endl_idx = find (help_text == "\n"); + buffer = ""; for k = 1:length (def_idx) - endl = endl_idx (find (endl_idx > def_idx (k), 1)); + endl = endl_idx (find (endl_idx > def_idx(k), 1)); if (isempty (endl)) - buffer = strcat (buffer, help_text (def_idx (k):end), "\n"); + buffer = strcat (buffer, help_text (def_idx(k):end), "\n"); else - buffer = strcat (buffer, help_text (def_idx (k):endl)); + buffer = strcat (buffer, help_text (def_idx(k):endl)); endif endfor - - end_def_idx = strfind (help_text, "@end def"); - if (!isempty (end_def_idx)) - buffer = strcat (buffer, help_text (end_def_idx:end)); - endif else [retval, status] = get_usage_plain_text (help_text, max_len); endif @@ -140,3 +139,4 @@ ## Stop reporting function as missing tests. No good tests possible. %!assert (1) + diff -r 20d1b911b4e7 -r c702371ff6df scripts/help/private/__additional_help_message__.m --- a/scripts/help/private/__additional_help_message__.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/help/private/__additional_help_message__.m Sat Oct 05 11:22:09 2013 -0400 @@ -1,4 +1,4 @@ -## Copyright (C) 2009-2012 Søren Hauberg +## Copyright (C) 2009-2012 Søren Hauberg ## ## This file is part of Octave. ## @@ -37,3 +37,4 @@ endif endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/help/private/__strip_html_tags__.m --- a/scripts/help/private/__strip_html_tags__.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/help/private/__strip_html_tags__.m Sat Oct 05 11:22:09 2013 -0400 @@ -1,4 +1,4 @@ -## Copyright (C) 2009-2012 Søren Hauberg +## Copyright (C) 2009-2012 Søren Hauberg ## ## This file is part of Octave. ## @@ -79,3 +79,4 @@ ## Actually remove the elements text = text (keep); endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/help/type.m --- a/scripts/help/type.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/help/type.m Sat Oct 05 11:22:09 2013 -0400 @@ -1,4 +1,4 @@ -## Copyright (C) 2009-2012 S�ren Hauberg +## Copyright (C) 2009-2012 Søren Hauberg ## ## This file is part of Octave. ## @@ -19,24 +19,24 @@ ## -*- texinfo -*- ## @deftypefn {Command} {} type @var{name} @dots{} ## @deftypefnx {Command} {} type -q @var{name} @dots{} -## @deftypefnx {Function File} {dfns =} type ("@var{name}", @dots{}) -## Display the definition of each @var{name} that refers to a function. +## @deftypefnx {Function File} {text =} type ("@var{name}", @dots{}) +## Display the contents of @var{name} which may be a file, function (m-file), +## variable, operator, or keyword. ## -## Normally also displays whether each @var{name} is user-defined or built-in; -## the @option{-q} option suppresses this behavior. +## @code{type} normally prepends a header line describing the category +## of @var{name} such as function or variable; The @option{-q} option +## suppresses this behavior. ## -## If an output argument is requested nothing is displayed. Instead, a cell -## array of strings is returned, where each element corresponds to the -## definition of each requested function. +## If no output variable is used the contents are displayed on screen. +## Otherwise, a cell array of strings is returned, where each element +## corresponds to the contents of each requested function. ## @end deftypefn -function retval = type (varargin) - ## Parse input +function text = type (varargin) + if (nargin == 0) - error ("type: not enough input arguments"); - endif - - if (!iscellstr (varargin)) + print_usage (); + elseif (! iscellstr (varargin)) error ("type: input arguments must be strings"); endif @@ -44,18 +44,18 @@ idx = strcmpi (varargin, "-q") | strcmpi (varargin, "-quiet"); if (any (idx)) quiet = true; - varargin (idx) = []; + varargin(idx) = []; endif if (nargout > 0) - retval = cell (size (varargin)); + text = cell (size (varargin)); endif for n = 1:length (varargin) - name = varargin {n}; + name = varargin{n}; ## Find function and get its code - text = ""; + txt = ""; cmd = sprintf ("exist ('%s')", name); e = evalin ("caller", cmd); if (e == 1) @@ -63,17 +63,20 @@ cmd = sprintf ("disp (%s);", name); desc = evalin ("caller", cmd); if (quiet) - text = desc; + txt = desc; else - text = sprintf ("%s is a variable\n%s", name, desc); + txt = sprintf ("%s is a variable\n%s", name, desc); endif elseif (e == 2) ## m-file or ordinary file file = which (name); - if (isempty (file)) + if (length (file) > 2) + ext = file(end-1:end); + endif + if (isempty (file) || ! strcmpi (ext, ".m")) ## 'name' is an ordinary file, and not a function name. - ## FIXME: Should we just print it anyway? - error ("type: '%s' undefined\n", name); + file = file_in_loadpath (name); + quiet = true; endif ## Read the file @@ -85,28 +88,27 @@ fclose (fid); if (quiet) - text = contents; + txt = contents; else - text = sprintf ("%s is the user-defined function defined from: %s\n\n%s", + txt = sprintf ("%s is the user-defined function defined from: %s\n\n%s", name, file, contents); endif elseif (e == 3) - text = sprintf ("%s is a dynamically-linked function", name); + txt = sprintf ("%s is a dynamically-linked function", name); elseif (e == 5) - text = sprintf ("%s is a built-in function", name); + txt = sprintf ("%s is a built-in function", name); elseif (any (strcmp (__operators__ (), name))) - text = sprintf ("%s is an operator", name); + txt = sprintf ("%s is an operator", name); elseif (any (strcmp (__keywords__ (), name))) - text = sprintf ("%s is a keyword", name); + txt = sprintf ("%s is a keyword", name); else error ("type: '%s' undefined\n", name); endif - ## Should we return the text or print if if (nargout == 0) - disp (text); + disp (txt); else - retval {n} = text; + text{n} = txt; endif endfor endfunction @@ -114,13 +116,25 @@ %!test %! var = 1; -%! typestr = type ("var"); -%! typestr = typestr{1}(1:17); +%! text = type ("var"); +%! typestr = text{1}(1:17); %! assert (typestr, "var is a variable"); +%!test +%! text = type ("ls"); +%! typestr = text{1}(1:31); +%! assert (typestr, "ls is the user-defined function"); + +%!test +%! text = type ("ls", "-q"); +%! typestr = text{1}(1:21); +%! assert (typestr, "## Copyright (C) 2006"); + %!assert (type ("amd"){1}, "amd is a dynamically-linked function") %!assert (type ("cat"){1}, "cat is a built-in function") %!assert (type ("+"){1}, "+ is an operator") %!assert (type ("end"){1}, "end is a keyword") -%!error (type ('NO_NAME')) + +%!error type () +%!error <'__NO_NAME__' undefined> type ('__NO_NAME__') diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/cmpermute.m --- a/scripts/image/cmpermute.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/image/cmpermute.m Sat Oct 05 11:22:09 2013 -0400 @@ -25,7 +25,7 @@ ## When called with only two arguments, @code{cmpermute} randomly rearranges ## the colormap @var{map} and returns a new colormap @var{newmap}. It also ## returns the indexed image @var{Y} which is the equivalent of the original -## input image @var{X} when displayed using @var{newmap}. +## input image @var{X} when displayed using @var{newmap}. ## ## When called with an optional third argument the order of colors in the ## new colormap is defined by @var{index}. diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/cmunique.m --- a/scripts/image/cmunique.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/image/cmunique.m Sat Oct 05 11:22:09 2013 -0400 @@ -78,12 +78,12 @@ endif else switch (size (X,3)) - case (1) + case 1 ## I case [newmap,i,j] = unique (X); # calculate unique colormap newmap = repmat (newmap,1,3); # get a RGB colormap Y = reshape (j, rows (X), columns (X)); # Y is j reshaped - case (3) + case 3 ## RGB case ## build a map with all values map = [X(:,:,1)(:), X(:,:,2)(:), X(:,:,3)(:)]; diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/colorcube.m --- a/scripts/image/colorcube.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/image/colorcube.m Sat Oct 05 11:22:09 2013 -0400 @@ -46,12 +46,12 @@ return; endif - # Create colorcube of evenly spaced points with side length of n^1/3 + ## Create colorcube of evenly spaced points with side length of n^1/3 cubelen = fix (cbrt (n)); reserve = n - cubelen^3; if (reserve == 0) - # Steal space from blue to put the gray gradient + ## Steal space from blue to put the gray gradient [r, g, b] = meshgrid (linspace (0,1,cubelen), linspace (0,1,cubelen), linspace (0,1,cubelen-1)); @@ -61,16 +61,16 @@ linspace (0,1,cubelen)); endif - # Create map and weed out grays + ## Create map and weed out grays map = [r(:), g(:), b(:)]; idx = any (bsxfun (@ne, map(:, 1), map(:, 2:3)), 2); map = map(idx, :); - # Weed out pure colors + ## Weed out pure colors idx = sum (map == 0, 2); map = map(idx != 2, :); - # Put in remaining gradients of pure red, green, blue, and gray + ## Put in remaining gradients of pure red, green, blue, and gray reserve = n - rows (map) - 1; csteps = fix (reserve/4); cstepsz = 1 / csteps; diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/colormap.m --- a/scripts/image/colormap.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/image/colormap.m Sat Oct 05 11:22:09 2013 -0400 @@ -21,11 +21,16 @@ ## @deftypefn {Function File} {@var{cmap} =} colormap () ## @deftypefnx {Function File} {@var{cmap} =} colormap (@var{map}) ## @deftypefnx {Function File} {@var{cmap} =} colormap ("default") -## @deftypefnx {Function File} {@var{cmap} =} colormap ("list") -## @deftypefnx {Function File} {@var{cmap} =} colormap ("register", "@var{name}") -## @deftypefnx {Function File} {@var{cmap} =} colormap ("unregister", "@var{name}") +## @deftypefnx {Function File} {@var{cmap} =} colormap ("@var{map_name}") +## @deftypefnx {Function File} {@var{cmap} =} colormap (@var{hax}, @dots{}) +## @deftypefnx {Command} {} colormap @var{map_name} +## @deftypefnx {Function File} {@var{cmaps} =} colormap ("list") +## @deftypefnx {Function File} {} colormap ("register", "@var{name}") +## @deftypefnx {Function File} {} colormap ("unregister", "@var{name}") ## Query or set the current colormap. ## +## With no input arguments, @code{colormap} returns the current color map. +## ## @code{colormap (@var{map})} sets the current colormap to @var{map}. The ## colormap should be an @var{n} row by 3 column matrix. The columns ## contain red, green, and blue intensities respectively. All entries @@ -34,11 +39,19 @@ ## @code{colormap ("default")} restores the default colormap (the ## @code{jet} map with 64 entries). The default colormap is returned. ## -## @code{colormap ("list")} returns a cell array with all the available -## colormaps. The options @code{"register"} and @code{"unregister"} -## will add or remove the colormap @var{name} to it. +## The map may also be specified by a string, @qcode{"@var{map_name}"}, where +## @var{map_name} is the name of a function that returns a colormap. +## +## If the first argument @var{hax} is an axes handle, then the colormap for +## the parent figure of @var{hax} is queried or set. ## -## With no arguments, @code{colormap} returns the current color map. +## For convenience, it is also possible to use this function with the +## command form, @code{colormap @var{map_name}}. +## +## @code{colormap ("list")} returns a cell array with all of the available +## colormaps. The options @qcode{"register"} and @qcode{"unregister"} +## add or remove the colormap @var{name} from this list. +## ## @seealso{jet} ## @end deftypefn @@ -46,16 +59,23 @@ ## Created: July 1994 ## Adapted-By: jwe -function cmap = colormap (map, name) +function cmap = colormap (varargin) + persistent map_list = cell (); + + [hax, varargin, nargin] = __plt_get_axis_arg__ ("colormap", varargin{:}); if (nargin > 2) print_usage (); endif - persistent map_list = cell (); + if (! isempty (hax)) + cf = ancestor (hax, "figure"); + else + cf = get (0, "currentfigure"); + endif if (nargin == 1) - + map = varargin{1}; if (ischar (map)) if (strcmp (map, "default")) map = jet (64); @@ -75,28 +95,90 @@ if (any (map(:) < 0) || any (map(:) > 1)) error ("colormap: all MAP values must be in the range [0,1]"); endif + if (isempty (cf)) + cf = gcf (); + endif ## Set the new color map - set (gcf (), "colormap", map); + set (cf, "colormap", map); endif elseif (nargin == 2) - if (! ischar (map) || all (! strcmp (map, {"register", "unregister"}))) + opt = varargin{1}; + name = varargin{2}; + if (! ischar (opt) || ! any (strcmp (opt, {"register", "unregister"}))) print_usage (); elseif (! ischar (name)) error ("colormap: to register/unregister a colormap, NAME must be a string"); - elseif (strcmp (map, "register")) + elseif (strcmp (opt, "register")) map_list{end+1} = name; - elseif (strcmp (map, "unregister")) + elseif (strcmp (opt, "unregister")) map_list(strcmp (name, map_list)) = []; endif endif ## Return current color map. if (nargout > 0 || (nargout == 0 && nargin == 0)) - cmap = get (gcf (), "colormap"); + if (isempty (cf)) + cf = gcf (); + endif + cmap = get (cf, "colormap"); endif endfunction -%% FIXME: Need some demos/tests +%!demo +%! ## Create an image for displaying a colormap +%! image (1:64, linspace (0, 1, 64), repmat ((1:64)', 1, 64)); +%! axis ([1, 64, 0, 1], "ticy", "xy"); +%! ## Show 'jet' colormap +%! colormap (jet (64)); +%! title "colormap (jet (64))" +%! disp ("Press a key to continue"); +%! pause (); +%! ## Show 'colorcube' colormap +%! colormap (colorcube (64)); +%! title "colormap (colorcube (64))" + +%!test +%! hf = figure ("visible", "off"); +%! cmaptst = [0 1 0; 1 0 1; 1 1 1]; +%! cmap = colormap (cmaptst); +%! assert (cmap, cmaptst); +%! cmap = colormap (); +%! assert (cmap, cmaptst); +%! cmap = (get (gcf, "colormap")); +%! assert (cmap, cmaptst); +%! colormap ("default"); +%! assert (colormap (), jet (64)); +%! colormap ("ocean"); +%! assert (colormap, ocean (64)); +%! close (hf); # done with temp. figure + +%!test +%! cmaplst = colormap ("list"); +%! assert (iscell (cmaplst)); +%! colormap ("register", "__mycmap__"); +%! cmaplst2 = colormap ("list"); +%! assert (numel (cmaplst2), numel (cmaplst) + 1); +%! assert (any (strcmp (cmaplst2, "__mycmap__"))); +%! colormap ("unregister", "__mycmap__"); +%! cmaplst2 = colormap ("list"); +%! assert (numel (cmaplst2), numel (cmaplst)); +%! assert (! any (strcmp (cmaplst2, "__mycmap__"))); +%! ## Unregister again and verify that nothing has happened +%! colormap ("unregister", "__mycmap__"); +%! cmaplst3 = colormap ("list"); +%! assert (isequal (cmaplst2, cmaplst3)); + +## Test input validation +%!error colormap (1,2,3) +%!error colormap ({1,2,3}) +%!error colormap ([1 i 1]) +%!error colormap (ones(3,3,3)) +%!error colormap ([1 0 1 0]) +%!error colormap ([-1 0 0]) +%!error colormap ([2 0 0]) +%!error colormap ("invalid", "name") +%!error colormap ("register", 1) + diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/hsv2rgb.m --- a/scripts/image/hsv2rgb.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/image/hsv2rgb.m Sat Oct 05 11:22:09 2013 -0400 @@ -75,8 +75,8 @@ ## are outside range [0, 1]. We could also simply allow those values ## and re-instate this code to produce saturating semantics. ## Trim map to range [0, 1] - #hsv_map(hsv_map < 0) = 0; - #hsv_map(hsv_map > 1) = 1; + ## hsv_map(hsv_map < 0) = 0; + ## hsv_map(hsv_map > 1) = 1; h = hsv_map(:,1); s = hsv_map(:,2); diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/image.m --- a/scripts/image/image.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/image/image.m Sat Oct 05 11:22:09 2013 -0400 @@ -39,7 +39,7 @@ ## upper left. For ordinary plots, the origin is located in the lower ## left. Octave handles this inversion by plotting the data normally, ## and then reversing the direction of the y-axis by setting the -## @code{ydir} property to "reverse". This has implications whenever +## @code{ydir} property to @qcode{"reverse"}. This has implications whenever ## an image and an ordinary plot need to be overlaid. The recommended ## solution is to display the image and then plot the reversed ydata ## using, for example, @code{flipud (ydata)}. @@ -53,7 +53,11 @@ function h = image (varargin) - [ax, varargin, nargin] = __plt_get_axis_arg__ ("image", varargin{:}); + [hax, varargin, nargin] = __plt_get_axis_arg__ ("image", varargin{:}); + + if (isempty (hax)) + hax = gca (); + endif chararg = find (cellfun ("isclass", varargin, "char"), 1, "first"); @@ -71,15 +75,9 @@ img = varargin{3}; chararg = 4; endif - - oldax = gca (); - unwind_protect - axes (ax); - htmp = __img__ (x, y, img, varargin{chararg:end}); - set (ax, "layer", "top"); - unwind_protect_cleanup - axes (oldax); - end_unwind_protect + + htmp = __img__ (hax, x, y, img, varargin{chararg:end}); + set (hax, "layer", "top"); if (nargout > 0) h = htmp; @@ -97,9 +95,7 @@ ## Created: July 1994 ## Adapted-By: jwe -function h = __img__ (x, y, img, varargin) - - newplot (); +function h = __img__ (hax, x, y, img, varargin) if (isempty (img)) error ("__img__: matrix is empty"); @@ -136,9 +132,7 @@ endif endif - ca = gca (); - - htmp = __go_image__ (ca, "cdata", img, "xdata", xdata, "ydata", ydata, + htmp = __go_image__ (hax, "cdata", img, "xdata", xdata, "ydata", ydata, "cdatamapping", "direct", varargin {:}); px = __image_pixel_size__ (htmp); @@ -162,22 +156,22 @@ ## explicitly setting the values here. But then what information is ## available to axes::update_axis_limits to determine that the ## adjustment is necessary? - set (ca, "xlim", xlim, "ylim", ylim); + set (hax, "xlim", xlim, "ylim", ylim); if (ndims (img) == 3) if (isinteger (img)) cls = class (img); mn = intmin (cls); mx = intmax (cls); - set (ca, "clim", double ([mn, mx])); + set (hax, "clim", double ([mn, mx])); endif endif - set (ca, "view", [0, 90]); + set (hax, "view", [0, 90]); - if (strcmp (get (ca, "nextplot"), "replace")) - # Always reverse y-axis for images, unless hold is on - set (ca, "ydir", "reverse"); + if (strcmp (get (hax, "nextplot"), "replace")) + ## Always reverse y-axis for images, unless hold is on + set (hax, "ydir", "reverse"); endif if (nargout > 0) diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/imagesc.m --- a/scripts/image/imagesc.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/image/imagesc.m Sat Oct 05 11:22:09 2013 -0400 @@ -20,12 +20,12 @@ ## @deftypefn {Function File} {} imagesc (@var{img}) ## @deftypefnx {Function File} {} imagesc (@var{x}, @var{y}, @var{img}) ## @deftypefnx {Function File} {} imagesc (@dots{}, @var{climits}) -## @deftypefnx {Function File} {} imagesc (@var{h}, @dots{}) +## @deftypefnx {Function File} {} imagesc (@var{hax}, @dots{}) ## @deftypefnx {Function File} {@var{h} =} imagesc (@dots{}) ## Display a scaled version of the matrix @var{img} as a color image. The ## colormap is scaled so that the entries of the matrix occupy the entire ## colormap. If @code{@var{climits} = [@var{lo}, @var{hi}]} is given, then that -## range is set to the "clim" of the current axes. +## range is set to the @qcode{"clim"} of the current axes. ## ## The axis values corresponding to the matrix elements are specified in ## @var{x} and @var{y}, either as pairs giving the minimum and maximum @@ -45,14 +45,14 @@ if (nargin < 1 || nargin > 4) print_usage (); elseif (isscalar (varargin{1}) && ishandle (varargin{1})) - harg = varargin{1}; - if (! strcmp (get (harg, "type"), "axes")) - error ("imagesc: expecting first argument to be an axes object"); + hax = varargin{1}; + if (! isaxes (hax)) + error ("imagesc: HAX argument must be an axes object"); endif oldh = gca (); unwind_protect axes (h); - htmp = __imagesc__ (harg, varargin{2:end}); + htmp = __imagesc__ (hax, varargin{2:end}); unwind_protect_cleanup axes (oldh); end_unwind_protect diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/imfinfo.m --- a/scripts/image/imfinfo.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/image/imfinfo.m Sat Oct 05 11:22:09 2013 -0400 @@ -18,22 +18,29 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {@var{info} =} imfinfo (@var{filename}) +## @deftypefnx {Function File} {@var{info} =} imfinfo (@var{filename}, @var{ext}) ## @deftypefnx {Function File} {@var{info} =} imfinfo (@var{url}) ## Read image information from a file. ## ## @code{imfinfo} returns a structure containing information about the image -## stored in the file @var{filename}. The output structure contains the -## following fields. +## stored in the file @var{filename}. If there is no file @var{filename}, +## and @var{ext} was specified, it will look for a file named @var{filename} +## and extension @var{ext}, i.e., a file named @var{filename}.@var{ext}. +## +## The output structure @var{info} contains the following fields: ## ## @table @samp ## @item Filename ## The full name of the image file. ## +## @item FileModDate +## Date of last modification to the file. +## ## @item FileSize ## Number of bytes of the image on disk ## -## @item FileModDate -## Date of last modification to the file. +## @item Format +## Image format (e.g., @qcode{"jpeg"}). ## ## @item Height ## Image height in pixels. @@ -44,11 +51,9 @@ ## @item BitDepth ## Number of bits per channel per pixel. ## -## @item Format -## Image format (e.g., @code{"jpeg"}). -## -## @item LongFormat -## Long form image format description. +## @item ColorType +## Image type. Value is @qcode{"grayscale"}, @qcode{"indexed"}, +## @qcode{"truecolor"}, @qcode{"CMYK"}, or @qcode{"undefined"}. ## ## @item XResolution ## X resolution of the image. @@ -56,102 +61,101 @@ ## @item YResolution ## Y resolution of the image. ## -## @item TotalColors -## Number of unique colors in the image. +## @item ResolutionUnit +## Units of image resolution. Value is @qcode{"Inch"}, +## @qcode{"Centimeter"}, or @qcode{"undefined"}. ## -## @item TileName -## Tile name. -## -## @item AnimationDelay +## @item DelayTime ## Time in 1/100ths of a second (0 to 65535) which must expire before displaying ## the next image in an animated sequence. ## -## @item AnimationIterations -## Number of iterations to loop an animation (e.g., Netscape loop extension) -## for. +## @item LoopCount +## Number of iterations to loop an animation. ## ## @item ByteOrder -## Endian option for formats that support it. Value is @code{"little-endian"}, -## @code{"big-endian"}, or @code{"undefined"}. +## Endian option for formats that support it. Value is @qcode{"little-endian"}, +## @qcode{"big-endian"}, or @qcode{"undefined"}. ## ## @item Gamma ## Gamma level of the image. The same color image displayed on two different ## workstations may look different due to differences in the display monitor. ## -## @item Matte -## @code{true} if the image has transparency. +## @item Quality +## JPEG/MIFF/PNG compression level. Value is an integer in the range [0 100]. +## +## @item DisposalMethod +## Only valid for GIF images, control how successive frames are rendered (how +## the preceding frame is disposed of) when creating a GIF animation. Values +## can be @qcode{"doNotSpecify"}, @qcode{"leaveInPlace"}, @qcode{"restoreBG"}, +## or @qcode{"restorePrevious"}. For non-GIF files, value is an empty string. +## +## @item Chromaticities +## Value is a 1x8 Matrix with the x,y chromaticity values for white, red, +## green, and blue points, in that order. ## -## @item ModulusDepth -## Image modulus depth (minimum number of bits required to support -## red/green/blue components without loss of accuracy). +## @item Comment +## Image comment. ## -## @item Quality -## JPEG/MIFF/PNG compression level. +## @item Compression +## Compression type. Value can be @qcode{"none"}, @qcode{"bzip"}, +## @qcode{"fax3"}, @qcode{"fax4"}, @qcode{"jpeg"}, @qcode{"lzw"}, +## @qcode{"rle"}, @qcode{"deflate"}, @qcode{"lzma"}, @qcode{"jpeg2000"}, +## @qcode{"jbig2"}, @qcode{"jbig2"}, or @qcode{"undefined"}. +## +## @item Colormap +## Colormap for each image. +## +## @item Orientation +## The orientation of the image with respect to the rows and columns. Value +## is an integer between 1 and 8 as defined in the TIFF 6 specifications, and +## for @sc{matlab} compatibility. ## -## @item QuantizeColors -## Preferred number of colors in the image. +## @item Software +## Name and version of the software or firmware of the camera or image input +## device used to generate the image. ## -## @item ResolutionUnits -## Units of image resolution. Value is @code{"pixels per inch"}, -## @code{"pixels per centimeter"}, or @code{"undefined"}. +## @item Make +## The manufacturer of the recording equipment. This is the manufacture of the +## @nospell{DSC}, scanner, video digitizer or other equipment that generated +## the image. +## +## @item Model +## The model name or model number of the recording equipment as mentioned +## on the field @qcode{"Make"}. ## -## @item ColorType -## Image type. Value is @code{"grayscale"}, @code{"indexed"}, -## @code{"truecolor"}, or @code{"undefined"}. +## @item DateTime +## The date and time of image creation as defined by the Exif standard, i.e., +## it is the date and time the file was changed. +## +## @item ImageDescription +## The title of the image as defined by the Exif standard. ## -## @item View -## FlashPix viewing parameters. +## @item Artist +## Name of the camera owner, photographer or image creator. +## +## @item Copyright +## Copyright notice of the person or organization claiming rights to the image. +## +## @item DigitalCamera +## A struct with information retrieved from the Exif tag. +## +## @item GPSInfo +## A struct with geotagging information retrieved from the Exif tag. ## @end table ## -## @seealso{imread, imwrite, imshow} +## @seealso{imread, imwrite, imshow, imformats} ## @end deftypefn ## Author: Soren Hauberg -function info = imfinfo (filename) - - if (nargin < 1) +function info = imfinfo (varargin) + if (nargin < 1 || nargin > 2) print_usage (); - endif - - if (! ischar (filename)) + elseif (! ischar (varargin{1})) error ("imfinfo: FILENAME must be a string"); + elseif (nargin > 1 && ! ischar (varargin{2})) + error ("imfinfo: EXT must be a string"); endif - - filename = tilde_expand (filename); - - delete_file = false; - - unwind_protect - - fn = file_in_path (IMAGE_PATH, filename); - - if (isempty (fn)) - - ## Couldn't find file. See if it's an URL. - - tmp = tmpnam (); + info = imageIO (@__imfinfo__, "info", varargin, varargin{:}); +endfunction - [fn, status, msg] = urlwrite (filename, tmp); - - if (! status) - error ("imfinfo: cannot find %s", filename); - endif - - if (! isempty (fn)) - delete_file = true; - endif - - endif - - info = __magick_finfo__ (fn); - - unwind_protect_cleanup - - if (delete_file) - unlink (fn); - endif - - end_unwind_protect - -endfunction diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/imformats.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/image/imformats.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,329 @@ +## Copyright (C) 2013 Carnë Draug +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {} imformats () +## @deftypefnx {Function File} {@var{formats} =} imformats (@var{ext}) +## @deftypefnx {Function File} {@var{formats} =} imformats (@var{format}) +## @deftypefnx {Function File} {@var{formats} =} imformats ("add", @var{format}) +## @deftypefnx {Function File} {@var{formats} =} imformats ("remove", @var{ext}) +## @deftypefnx {Function File} {@var{formats} =} imformats ("update", @var{ext}, @var{format}) +## @deftypefnx {Function File} {@var{formats} =} imformats ("factory") +## Manage supported image formats. +## +## @var{formats} is a structure with information about each supported file +## format, or from a specific format @var{ext}, the value displayed on the +## field @code{ext}. It contains the following fields: +## +## @table @asis +## @item ext +## The name of the file format. This may match the file extension but Octave +## will automatically detect the file format. +## +## @item description +## A long description of the file format. +## +## @item @nospell{isa} +## A function handle to confirm if a file is of the specified format. +## +## @item write +## A function handle to write if a file is of the specified format. +## +## @item read +## A function handle to open files the specified format. +## +## @item info +## A function handle to obtain image information of the specified format. +## +## @item alpha +## Logical value if format supports alpha channel (transparency or matte). +## +## @item multipage +## Logical value if format supports multipage (multiple images per file). +## @end table +## +## It is possible to change the way Octave manages file formats with the options +## @qcode{"add"}, @qcode{"remove"}, and @qcode{"update"}, and supplying a +## structure @var{format} with the required fields. The option +## @qcode{"factory"} resets the configuration to the default. +## +## This can be used by Octave packages to extend the image reading capabilities +## Octave, through use of the PKG_ADD and PKG_DEL commands. +## +## @seealso{imfinfo, imread, imwrite} +## @end deftypefn + +## Author: Carnë Draug + +function varargout = imformats (arg1, arg2, arg3) + if (nargin > 3) + print_usage (); + endif + + persistent formats = default_formats (); + + if (nargin == 0 && nargout == 0) + error ("imformats: pretty print not yet implemented."); + elseif (nargin >= 1) + if (isstruct (arg1)) + arrayfun (@is_valid_format, arg1); + ## FIXME: what is the return value in this situation? + formats = arg1; + + elseif (ischar (arg1)) + switch (tolower (arg1)) + case "add", + if (! isstruct (arg2)) + error ("imformats: FORMAT to %s must be a structure.", arg1); + endif + arrayfun (@is_valid_format, arg2); + formats(end + 1: end + numel (arg2)) = arg2; + varargout{1} = formats; + + case {"remove", "update"}, + if (! ischar (arg2)) + error ("imformats: EXT to %s must be a string.", arg1); + endif + ## FIXME: suppose a format with multiple extensions. If one of + ## them is requested to be removed, should we remove the + ## whole format, or just that extension from the format? + match = find_ext_idx (formats, arg2); + if (! any (match)) + error ("imformats: no EXT `%s' found.", arg2); + endif + if (strcmpi (arg1, "remove")) + formats(match) = []; + else + ## then it's update + if (! isstruct (arg3)) + error ("imformats: FORMAT to update must be a structure."); + endif + is_valid_format (arg3); + formats(match) = arg3; + endif + varargout{1} = formats; + + case "factory", + formats = default_formats (); + otherwise + ## then we look for a format with that extension. + match = find_ext_idx (formats, arg1); + ## For matlab compatibility, if we don't find any format we must + ## return an empty struct with NO fields. We can't use match as mask + if (any (match)) + varargout{1} = formats(match); + else + varargout{1} = struct (); + endif + endswitch + else + error ("imformats: first argument must be either a structure or string."); + endif + else + varargout{1} = formats; + endif +endfunction + +function formats = default_formats () + + ## The available formats are dependent on what the user has installed at + ## a given time, and how GraphicsMagick was built. Checking for + ## GraphicsMagick features when building Octave is not enough since it + ## delegates some of them to external programs which can be removed or + ## installed at any time. + ## The recommended method would be to use CoderInfoList() to get a list of + ## all available coders and try to write and read back a small test image. + ## But this will not work since some coders are readable or writable only. + ## It will still fail if we test only the ones marked as readable and + ## writable because some RW coders are not of image formats (NULL, 8BIM, + ## or EXIF for example). + ## So we'd need a blacklist (unacceptable because a `bad' coder may be + ## added later) or a whitelist. A whitelist means that even with a + ## super-fancy recent build of GraphicsMagick, some formats won't be listed + ## by imformats but in truth, we will still be able to read and write them + ## since imread() and imwrite() will give it a try anyway. + ## + ## For more info and comments from the GraphicsMagick main developer, see + ## http://sourceforge.net/mailarchive/forum.php?thread_name=alpine.GSO.2.01.1304301916050.2267%40freddy.simplesystems.org&forum_name=graphicsmagick-help + + persistent formats = struct ( "coder", {}, + "ext", {}, + "isa", {}, + "info", {}, + "read", {}, + "write", {}, + "alpha", {}, + "description", {}, + "multipage", {}); + + ## Image IO abilities won't change during the same Octave session, + ## there's no need to go and calculate it all over again if we are + ## requested to reset back to factory. + if (! isempty (formats)) + return; + endif + + ## Building the formats info + ## + ## As mentioned above we start with a whitelist of coders. Since the + ## GraphicsMagick build may be missing some coders, we will remove those + ## from the list. Some info can be obtained directly from GraphicsMagick + ## through the CoderInfo object. However, some will need to be hardcoded. + ## + ## The association between file extensions and coders needs to be done + ## with a manually coded list (file extensions do not define the image + ## format and GraphicsMagick will not be fooled by changing the extension). + ## + ## We can get the read, write, description and multipage fields from + ## CoderInfo in C++. We should do the same for alpha (GraphicsMagick + ## calls it matte) but it's not available from CoderInfo. The only way to + ## check it is to create a sample image with each coder, then try to read + ## it back with GraphicsMagick and use the matte method on the Image class. + ## But making such test for each Octave session... meh! While technically + ## it may be possible that the same coder has different support for alpha + ## channel in different versions and builds, this doesn't seem to happen. + ## So we also hardcode those. In the future, maybe the CoderInfo class will + ## have a matte method like it does for multipage. + ## + ## Other notes: some formats have more than one coder that do the same. For + ## example, for jpeg images there is both the JPG and JPEG coders. However, + ## it seems that when reading images, GraphicsMagick only uses one of them + ## and that's the one we list (it's the one reported by imfinfo and that we + ## can use for isa). However, in some cases GraphicsMagick seems to rely + ## uniquely on the file extension ((JBIG and JBG at least. Create an image + ## with each of those coders, swap their extension and it will report the + ## other coder). We don't have such cases on the whitelist but if we did, we + ## would need two entries for such cases. + + ## each row: 1st => Coder, 2nd=> file extensions, 3rd=> alpha + coders = {"BMP", {"bmp"}, true; + "CUR", {"cur"}, false; + "GIF", {"gif"}, true; + "ICO", {"ico"}, true; + "JBG", {"jbg"}, false; + "JBIG", {"jbig"}, false; + "JP2", {"jp2", "jpx"}, true; + "JPEG", {"jpg", "jpeg"}, false; # there is also a JPG coder + "PBM", {"pbm"}, false; + "PCX", {"pcx"}, true; + "PGM", {"pgm"}, false; + "PGM", {"pgm"}, false; + "PNG", {"png"}, true; + ## PNM is a family of formats supporting portable bitmaps (PBM), + ## graymaps (PGM), and pixmaps (PPM). There is no file format + ## associated with pnm itself. If PNM is used as the output format + ## specifier, then GraphicsMagick automatically selects the most + ## appropriate format to represent the image. + "PNM", {"pnm"}, true; + "PPM", {"ppm"}, false; + "SUN", {"ras"}, true; # SUN Rasterfile + "TGA", {"tga", "tpic"}, true; + "TIFF", {"tif", "tiff"}, true; + "XBM", {"xbm"}, false; + "XPM", {"xpm"}, true; + "XWD", {"xwd"}, false; + }; + + for fidx = 1: rows(coders) + formats(fidx).coder = coders{fidx, 1}; + formats(fidx).ext = coders{fidx, 2}; + formats(fidx).alpha = coders{fidx, 3}; + ## default isa is to check if the format returned by imfinfo is the coder + formats(fidx).isa = @(x) isa_magick (coders{fidx,1}, x); + endfor + + ## the default info, read, and write functions + [formats.info ] = deal (@__imfinfo__); + [formats.read ] = deal (@__imread__); + [formats.write] = deal (@__imwrite__); + + ## fills rest of format information by checking with GraphicsMagick + formats = __magick_formats__ (formats); +endfunction + +function is_valid_format (format) + ## the minimal list of fields required in the structure. We don't + ## require multipage because it doesn't exist in matlab + min_fields = {"ext", "read", "isa", "write", "info", "alpha", "description"}; + fields_mask = isfield (format, min_fields); + if (! all (fields_mask)) + error ("imformats: structure has missing field `%s'.", min_fields(! fields_mask){1}); + endif +endfunction + +function match = find_ext_idx (formats, ext) + ## FIXME: is matlab sensitive to file extensions? + ## XXX: what should we do if there's more than one hit? + ## Should this function prevent the addition of + ## duplicated extensions? + match = cellfun (@(x) any (strcmp (x, ext)), {formats.ext}); +endfunction + +function bool = isa_magick (coder, filename) + bool = false; + try + info = __magick_ping__ (filename, 1); + bool = strcmp (coder, info.Format); + end_try_catch +endfunction + + +## changing the function to read +%!testif HAVE_MAGICK +%! fmt = imformats ("jpg"); +%! fmt.read = @(x) size (x, 2); +%! imformats ("update", "jpg", fmt); +%! assert (imread ("this is 30 characters long.jpg"), 30); + +## adding a new format +%!testif HAVE_MAGICK +%! fmt = imformats ("jpg"); +%! fmt.ext = "junk"; +%! fmt.read = @(x) true(); +%! imformats ("add", fmt); +%! assert (imread ("some file.junk"), true); + +## adding multiple formats in one way +%!testif HAVE_MAGICK +%! fmt = imformats ("jpg"); +%! fmt.ext = "junk1"; +%! fmt.read = @(x) true(); +%! fmt(2) = fmt(1); +%! fmt(2).ext = "junk2"; +%! imformats ("add", fmt); +%! assert (imread ("some file.junk1"), true); +%! assert (imread ("some file.junk2"), true); + +## changing format +%!testif HAVE_MAGICK +%! ori_fmt = mod_fmt = imformats ("jpg"); +%! mod_fmt.description = "Another description"; +%! imformats ("update", "jpg", mod_fmt); +%! new_fmt = imformats ("jpg"); +%! assert (new_fmt.description, mod_fmt.description); +%! imformats ("factory"); +%! new_fmt = imformats ("jpg"); +%! assert (new_fmt.description, ori_fmt.description); + +## FIXME: how to test for error together with testif? +## update to an invalid format +#%!testif HAVE_MAGICK +#%! fmt = imformats ("jpg"); +#%! fmt = rmfield (fmt, "read"); +#%! error imformats ("update", "jpg", fmt); + diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/imread.m --- a/scripts/image/imread.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/image/imread.m Sat Oct 05 11:22:09 2013 -0400 @@ -1,3 +1,4 @@ +## Copyright (C) 2013 Carnë Draug ## Copyright (C) 2008-2012 Thomas L. Scofield ## Copyright (C) 2008 Kristian Rumberg ## Copyright (C) 2006 Thomas Weber @@ -20,79 +21,90 @@ ## along with Octave; see the file COPYING. If not, see ## . +## -*- texinfo -*- +## @deftypefn {Function File} {[@var{img}, @var{map}, @var{alpha}] =} imread (@var{filename}) +## @deftypefnx {Function File} {[@dots{}] =} imread (@var{filename}, @var{ext}) +## @deftypefnx {Function File} {[@dots{}] =} imread (@var{url}) +## @deftypefnx {Function File} {[@dots{}] =} imread (@dots{}, @var{idx}) +## @deftypefnx {Function File} {[@dots{}] =} imread (@dots{}, @var{param1}, @var{val1}, @dots{}) +## Read images from various file formats. +## +## Reads an image as a matrix from the file @var{filename}. If there is +## no file @var{filename}, and @var{ext} was specified, it will look for +## a file named @var{filename} and extension @var{ext}, i.e., a file named +## @var{filename}.@var{ext}. +## +## The size and class of the output depends on the +## format of the image. A color image is returned as an +## @nospell{MxNx3} matrix. Gray-level and black-and-white images are +## of size @nospell{MxN}. Multipage images will have an additional 4th +## dimension. +## +## The bit depth of the image determines the +## class of the output: @qcode{"uint8"}, @qcode{"uint16"} or @qcode{"single"} +## for gray and color, and @qcode{"logical"} for black and white. +## Note that indexed images always return the indexes for a colormap, +## independent if @var{map} is a requested output. To obtain the actual +## RGB image, use @code{ind2rgb}. When more than one indexed image is being +## read, @var{map} is obtained from the first. In some rare cases this +## may be incorrect and @code{imfinfo} can be used to obtain the colormap of +## each image. +## +## See the Octave manual for more information in representing images. +## +## Some file formats, such as TIFF and GIF, are able to store multiple +## images in a single file. @var{idx} can be a scalar or vector +## specifying the index of the images to read. By default, Octave +## will only read the first page. +## +## Depending on the file format, it is possible to configure the reading +## of images with @var{param}, @var{val} pairs. The following options +## are supported: +## +## @table @samp +## @item @qcode{"Frames"} or @qcode{"Index"} +## This is an alternative method to specify @var{idx}. When specifying it +## in this way, its value can also be the string @qcode{"all"}. +## +## @item @qcode{"Info"} +## This option exists for @sc{matlab} compatibility and has no effect. For +## maximum performance while reading multiple images from a single file, +## use the Index option. +## +## @item @qcode{"PixelRegion"} +## Controls the image region that is read. Takes as value a cell array +## with two arrays of 3 elements @code{@{@var{rows} @var{cols}@}}. The +## elements in the array are the start, increment and end pixel to be +## read. If the increment value is omitted, defaults to 1. +## @end table +## +## @seealso{imwrite, imfinfo, imformats} +## @end deftypefn + +## Author: Carnë Draug ## Author: Thomas L. Scofield ## Author: Kristian Rumberg ## Author: Thomas Weber ## Author: Stefan van der Walt ## Author: Andy Adler -## -*- texinfo -*- -## @deftypefn {Function File} {[@var{img}, @var{map}, @var{alpha}] =} imread (@var{filename}) -## Read images from various file formats. -## -## The size and numeric class of the output depends on the -## format of the image. A color image is returned as an -## @nospell{MxNx3} matrix. Gray-level and black-and-white images are -## of size @nospell{MxN}. -## The color depth of the image determines the numeric -## class of the output: "uint8" or "uint16" for gray -## and color, and "logical" for black and white. -## -## @seealso{imwrite, imfinfo} -## @end deftypefn - -function varargout = imread (filename, varargin) - +function [img, varargout] = imread (varargin) if (nargin < 1) print_usage (); - endif - - if (! ischar (filename)) + elseif (! ischar (varargin{1})) error ("imread: FILENAME must be a string"); endif - - filename = tilde_expand (filename); - - fn = file_in_path (IMAGE_PATH, filename); - - if (isempty (fn)) - error ("imread: cannot find %s", filename); + ## In case the file format was specified as a separate argument we + ## do this. imageIO() will ignore the second part if filename on its + ## own is enough. And if the second argument was a parameter name instead + ## of an extension, it is still going to be passed to the next function + ## since we are passing the whole function input as well. + filename = {varargin{1}}; + if (nargin > 1 && ischar (varargin {2})) + filename{2} = varargin{2}; endif - try - [varargout{1:nargout}] = __magick_read__ (fn, varargin{:}); - catch - - magick_error = lasterr (); - - img_field = false; - x_field = false; - map_field = false; - - try - vars = load (fn); - if (isstruct (vars)) - img_field = isfield (vars, "img"); - x_field = isfield (vars, "X"); - map_field = isfield (vars, "map"); - endif - catch - error ("imread: invalid image file: %s", magick_error); - end_try_catch - - if (map_field && (img_field || x_field)) - varargout{2} = vars.map; - if (img_field) - varargout{1} = vars.img; - else - varargout{1} = vars.X; - endif - else - error ("imread: invalid Octave image file format"); - endif - - end_try_catch - + [img, varargout{1:nargout-1}] = imageIO (@__imread__, "read", filename, varargin{:}); endfunction @@ -114,11 +126,15 @@ %! 16, 28, 160, 16, 0, 197, 214, 13, 34, 74, ... %! 117, 213, 17, 0, 0, 0, 0, 73, 69, 78, ... %! 68, 174, 66, 96, 130]; -%! fid = fopen ("test.png", "wb"); -%! fwrite (fid, vpng); -%! fclose (fid); -%! A = imread ("test.png"); -%! delete ("test.png"); +%! filename = [tmpnam() ".png"]; +%! unwind_protect +%! fid = fopen (filename, "wb"); +%! fwrite (fid, vpng); +%! fclose (fid); +%! A = imread (filename); +%! unwind_protect_cleanup +%! unlink (filename); +%! end_unwind_protect %! assert (A(:,:,1), uint8 ([0, 255, 0; 255, 237, 255; 0, 255, 0])); %! assert (A(:,:,2), uint8 ([0, 255, 0; 255, 28, 255; 0, 255, 0])); %! assert (A(:,:,3), uint8 ([0, 255, 0; 255, 36, 255; 0, 255, 0])); diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/imshow.m --- a/scripts/image/imshow.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/image/imshow.m Sat Oct 05 11:22:09 2013 -0400 @@ -43,7 +43,7 @@ ## @var{value1}. @var{string_param1} can be any of the following: ## ## @table @asis -## @item "displayrange" +## @item @qcode{"displayrange"} ## @var{value1} is the display range as described above. ## @end table ## diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/imwrite.m --- a/scripts/image/imwrite.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/image/imwrite.m Sat Oct 05 11:22:09 2013 -0400 @@ -1,4 +1,5 @@ ## Copyright (C) 2008-2012 John W. Eaton +## Copyright (C) 2013 Carnë Draug ## ## This file is part of Octave. ## @@ -18,166 +19,75 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} imwrite (@var{img}, @var{filename}) -## @deftypefnx {Function File} {} imwrite (@var{img}, @var{filename}, @var{fmt}) -## @deftypefnx {Function File} {} imwrite (@var{img}, @var{filename}, @var{fmt}, @var{p1}, @var{v1}, @dots{}) -## @deftypefnx {Function File} {} imwrite (@var{img}, @var{map}, @var{filename}, @dots{}) +## @deftypefnx {Function File} {} imwrite (@var{img}, @var{filename}, @var{ext}) +## @deftypefnx {Function File} {} imwrite (@var{img}, @var{map}, @var{filename}) +## @deftypefnx {Function File} {} imwrite (@dots{}, @var{param1}, @var{val1}, @dots{}) ## Write images in various file formats. ## -## If @var{fmt} is not supplied, the file extension of @var{filename} is used -## to determine the format. +## The image @var{img} can be a binary, grayscale, RGB, or multi-dimensional +## image. The size and class of @var{img} should be the same as what should +## be expected when reading it with @code{imread}: the 3rd and 4th dimensions +## reserved for color space, and multiple pages respectively. If it's an +## indexed image, the colormap @var{map} must also be specified. ## -## The parameter-value pairs (@var{p1}, @var{v1}, @dots{}) are optional. -## Currently the following options are supported for @t{JPEG} images: +## If @var{ext} is not supplied, the file extension of @var{filename} is used +## to determine the format. The actual supported formats are dependent on +## options made during the build of Octave. Use @code{imformats} to check +## the support of the different image formats. +## +## Depending on the file format, it is possible to configure the writing +## of images with @var{param}, @var{val} pairs. The following options +## are supported: ## ## @table @samp +## @item Alpha +## Alpha (transparency) channel for the image. This must be a matrix with +## same class, and number of rows and columns of @var{img}. In case of a +## multipage image, the size of the 4th dimension must also match and the third +## dimension must be a singleton. By default, image will be completely +## opaque. +## ## @item Quality ## Set the quality of the compression. The value should be an ## integer between 0 and 100, with larger values indicating higher visual -## quality and lower compression. +## quality and lower compression. Defaults to 75. +## +## @item WriteMode +## Some file formats, such as TIFF and GIF, are able to store multiple +## images in a single file. This option specifies if @var{img} should be +## appended to the file (if it exists) or if a new file should be created +## for it (possibly overwriting an existing file). The value should be +## the string @qcode{"Overwrite"} (default), or @qcode{"Append"}. +## +## Despite this option, the most efficient method of writing a multipage +## image is to pass a 4 dimensional @var{img} to @code{imwrite}, the +## same matrix that could be expected when using @code{imread} with the +## option @qcode{"Index"} set to @qcode{"all"}. +## ## @end table ## -## @strong{Supported Formats} -## @multitable @columnfractions .33 .66 -## @headitem Extension @tab Format -## @item bmp @tab Windows Bitmap -## @item gif @tab Graphics Interchange Format -## @item jpg and jpeg @tab Joint Photographic Experts Group -## @item pbm @tab Portable Bitmap -## @item pcx @tab -## @item pgm @tab Portable Graymap -## @item png @tab Portable Network Graphics -## @item pnm @tab Portable Anymap -## @item ppm @tab Portable Pixmap -## @item ras @tab Sun Raster -## @item tif and tiff @tab Tagged Image File Format -## @item xwd @tab X11 Dump -## @end multitable -## -## @strong{Unsupported Formats} -## @multitable @columnfractions .33 .66 -## @headitem Extension @tab Format -## @item hdf @tab Hierarchical Data Format V4 -## @item @nospell{jp2} and jpx @tab Joint Photographic Experts Group 2000 -## @end multitable -## -## @seealso{imread, imfinfo} +## @seealso{imread, imfinfo, imformats} ## @end deftypefn -function imwrite (img, varargin) - - persistent imwrite_possible_formats = { - "bmp"; "gif"; "jp2"; "jpg"; "jpx"; "jpeg"; "hdf"; "pbm"; "pcx"; - "pgm"; "png"; "pnm"; "ppm"; "ras"; "tif"; "tiff"; "xwd" }; - - persistent accepted_formats = __magick_format_list__ (imwrite_possible_formats); - - if (nargin < 2 || ! (isnumeric (img) || islogical (img))) - print_usage (); - endif - - map = []; - fmt = ""; - - offset = 1; - if (isnumeric (varargin{1})) - map = varargin{1}; - if (isempty (map)) - error ("imwrite: colormap must not be empty"); - endif - offset = 2; - endif - if (offset <= length (varargin) && ischar (varargin{offset})) - filename = varargin{offset}; - offset++; - if (rem (length (varargin) - offset, 2) == 0 && ischar (varargin{offset})) - fmt = varargin{offset}; - offset++; - endif - else +function imwrite (varargin) + if (nargin < 2) print_usage (); endif - if (offset < length (varargin)) - has_param_list = 1; - for ii = offset:2:(length (varargin) - 1) - options.(varargin{ii}) = varargin{ii + 1}; - endfor - else - has_param_list = 0; - endif - - filename = tilde_expand (filename); - - if (isempty (fmt)) - [d, n, fmt] = fileparts (filename); - if (! isempty (fmt)) - fmt = fmt(2:end); - endif - endif - - if (isempty (img)) - error ("imwrite: invalid empty image"); - endif - - if (issparse (img) || issparse (map)) - error ("imwrite: sparse images not supported"); - endif - - if (! strcmp (fmt, accepted_formats)) - error ("imwrite: %s: unsupported or invalid image format", fmt); - endif - - img_class = class (img); - map_class = class (map); - nd = ndims (img); + [filename, ext] = imwrite_filename (varargin{2:end}); - if (isempty (map)) - if (any (strcmp (img_class, {"logical", "uint8", "uint16", "double"}))) - if ((nd == 2 || nd == 3) && strcmp (img_class, "double")) - img = uint8 (img * 255); - endif - ## FIXME: should we handle color images with alpha channel here? - if (nd == 3 && size (img, 3) < 3) - error ("imwrite: invalid dimensions for truecolor image"); - endif - if (nd > 5) - error ("imwrite: invalid %d-dimensional image data", nd); - endif - else - error ("imwrite: %s: invalid class for truecolor image", img_class); + fmt = imformats (ext); + ## When there is no match, fmt will be a 1x1 structure with + ## no fields, so we can't just use `isempty (fmt)'. + if (isempty (fieldnames (fmt))) + if (isempty (ext)) + error ("imwrite: no extension found for %s to identify the image format", + filename); endif - if (has_param_list) - __magick_write__ (filename, fmt, img, options); - else - __magick_write__ (filename, fmt, img); - endif + warning ("imwrite: unlisted image format %s (see imformats). Trying to save anyway.", + ext); + __imwrite__ (varargin{:}); else - if (any (strcmp (img_class, {"uint8", "uint16", "double"}))) - if (strcmp (img_class, "double")) - img = uint8 (img - 1); - endif - if (nd != 2 && nd != 4) - error ("imwrite: invalid size for indexed image"); - endif - else - error ("imwrite: %s: invalid class for indexed image data", img_class); - endif - if (! iscolormap (map)) - error ("imwrite: invalid indexed image colormap"); - endif - - ## FIXME: we should really be writing indexed images here but - ## __magick_write__ needs to be fixed to handle them. - - [r, g, b] = ind2rgb (img, map); - tmp = uint8 (cat (3, r, g, b) * 255); - - if (has_param_list) - __magick_write__ (filename, fmt, tmp, options); - ## __magick_write__ (filename, fmt, img, map, options); - else - __magick_write__ (filename, fmt, tmp); - ## __magick_write__ (filename, fmt, img, map); - endif + fmt.write (varargin{:}); endif endfunction @@ -194,3 +104,14 @@ %!error imwrite ([], "filename.jpg") # Empty img matrix %!error imwrite (spones (2), "filename.jpg") # Invalid sparse img +%!testif HAVE_MAGICK +%! imw = randi (255, 100, "uint8"); +%! filename = [tmpnam() ".png"]; +%! unwind_protect +%! imwrite (imw, filename); +%! imr = imread (filename); +%! unwind_protect_cleanup +%! unlink (filename); +%! end_unwind_protect +%! assert (imw, imr) + diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/ind2gray.m --- a/scripts/image/ind2gray.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/image/ind2gray.m Sat Oct 05 11:22:09 2013 -0400 @@ -30,7 +30,7 @@ ## ## Implementation Note: There are several ways of converting colors to ## grayscale intensities. This functions uses the luminance value obtained -## from @code{rgb2ntsc} which is @code{I = 0.299*R + 0.587*G + 0.114*B}. +## from @code{rgb2ntsc} which is @code{I = 0.299*R + 0.587*G + 0.114*B}. ## Other possibilities include the value component from @code{rgb2hsv} or ## using a single color channel from @code{ind2rgb}. ## @seealso{gray2ind, ind2rgb} diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/lines.m --- a/scripts/image/lines.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/image/lines.m Sat Oct 05 11:22:09 2013 -0400 @@ -20,7 +20,7 @@ ## @deftypefn {Function File} {@var{map} =} lines () ## @deftypefnx {Function File} {@var{map} =} lines (@var{n}) ## Create color colormap. This colormap is composed of the list of colors -## in the current axes "ColorOrder" property. The default is blue, +## in the current axes @qcode{"ColorOrder"} property. The default is blue, ## green, red, cyan, pink, yellow, and gray. ## The argument @var{n} must be a scalar. ## If unspecified, the length of the current colormap, or 64, is used. diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/module.mk --- a/scripts/image/module.mk Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/image/module.mk Sat Oct 05 11:22:09 2013 -0400 @@ -1,6 +1,11 @@ FCN_FILE_DIRS += image image_PRIVATE_FCN_FILES = \ + image/private/__imfinfo__.m \ + image/private/__imread__.m \ + image/private/__imwrite__.m \ + image/private/imageIO.m \ + image/private/imwrite_filename.m \ image/private/ind2x.m image_FCN_FILES = \ @@ -25,6 +30,7 @@ image/image.m \ image/imagesc.m \ image/imfinfo.m \ + image/imformats.m \ image/imread.m \ image/imshow.m \ image/imwrite.m \ diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/private/__imfinfo__.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/image/private/__imfinfo__.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,72 @@ +## Copyright (C) 2008-2012 Soren Hauberg +## Copyright (C) 2013 Carnë Draug +## +## 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 +## . + +## This function does al the work of imfinfo. It exists here as private +## function so that imfinfo can use other functions if imformats is +## configured to. It is also needed so that imformats can create a +## function handle for it. + +## Author: Soren Hauberg + +function info = __imfinfo__ (filename, ext) + + if (nargin < 1 || nargin > 2) + print_usage ("imfinfo"); + endif + + if (! ischar (filename)) + error ("imfinfo: FILENAME must be a string"); + elseif (nargin >= 2 && ! ischar (ext)) + error ("imfinfo: EXT must be a string"); + endif + filename = tilde_expand (filename); + + delete_file = false; + unwind_protect + + fn = file_in_path (IMAGE_PATH, filename); + if (isempty (fn)) + ## We couldn't find the file so... + if (nargin >= 2) + ## try adding a possible file extesion + filename = [filename "." ext]; + fn = file_in_path (IMAGE_PATH, filename); + if (isempty (fn)) + error ("imfinfo: cannot find file %s", filename); + endif + else + ## try filename as an URL + [fn, status, msg] = urlwrite (filename, tmpnam ()); + if (! status) + error ("imfinfo: cannot find or download %s: %s", filename, msg); + endif + delete_file = true; + endif + endif + + info = __magick_finfo__ (fn); + + unwind_protect_cleanup + if (delete_file) + unlink (fn); + endif + end_unwind_protect + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/private/__imread__.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/image/private/__imread__.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,207 @@ +## Copyright (C) 2013 Carnë Draug +## Copyright (C) 2008-2012 Thomas L. Scofield +## Copyright (C) 2008 Kristian Rumberg +## Copyright (C) 2006 Thomas Weber +## Copyright (C) 2005 Stefan van der Walt +## Copyright (C) 2002 Andy Adler +## +## 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 +## . + +## This function does all the work of imread. It exists here as private +## function so that imread can use other functions if imformats is +## configured to. It is also needed so that imformats can create a +## function handle for it. + +## Author: Carnë Draug +## Author: Thomas L. Scofield +## Author: Kristian Rumberg +## Author: Thomas Weber +## Author: Stefan van der Walt +## Author: Andy Adler + +function varargout = __imread__ (filename, varargin) + + if (nargin < 1) + print_usage ("imread"); + elseif (! ischar (filename)) + error ("imread: FILENAME must be a string"); + endif + + ## keep track of the varargin offset we're looking at each moment + offset = 1; + + filename = tilde_expand (filename); + fn = file_in_path (IMAGE_PATH, filename); + if (isempty (fn) && nargin >= offset + 1 && ischar (varargin{offset})) + ## if we can't find the file, check if the next input is the file extension + filename = [filename "." varargin{offset}]; + fn = file_in_path (IMAGE_PATH, filename); + offset++; + endif + if (isempty (fn)) + error ("imread: cannot find %s", filename); + endif + + ## It is possible for an file with multiple pages to have very different + ## images on each page. Specifically, they may have different sizes. Because + ## of this, we need to first find out the index of the images to read so + ## we can set up defaults for things such as PixelRegion later on. + options = struct ("index", 1); # default image index + + ## Index is the only option that can be defined without the parameter/value + ## pair style. When defining it here, the string "all" is invalid though. + ## Also, for matlab compatibility, if index is defined both as an option here + ## and parameter/value pair, silently ignore the first. + if (nargin >= offset + 1 && ! ischar (varargin{offset})) + if (! is_valid_index_option (options.index)) + error ("imread: IDX must be a numeric vector"); + endif + options.index = varargin{offset}; + offset++; + endif + + if (rem (numel (varargin) - offset + 1, 2) != 0) + error ("imread: no pair for all arguments (odd number left over)"); + endif + + ## Check key/value options. + indexes = cellfun ("isclass", varargin, "char"); + indexes(indexes) &= ismember (varargin(indexes), {"frames", "index"}); + indexes = find (indexes); + if (indexes) + options.index = varargin{indexes+1}; + if (! (is_valid_index_option (options.index)) && + ! (ischar (options.index) && strcmpi (options.index, "all"))) + error ("imread: value for %s must be a vector or the string `all'"); + endif + endif + + try + ## Use information from the first image to be read to set defaults. + info = __magick_ping__ (fn, options.index(1)); + + ## Set default for options. + options.region = {1:1:info.rows 1:1:info.columns}; + + for idx = offset:2:(numel (varargin) - offset + 1) + switch (tolower (varargin{idx})) + + case "pixelregion", + options.region = varargin{idx+1}; + if (! iscell (options.region) || numel (options.region) != 2) + error ("imread: value for %s must be a 2 element cell array", + varargin{idx}); + endif + for reg_idx = 1:2 + if (numel (options.region{reg_idx}) == 3) + ## do nothing + elseif (numel (options.region{reg_idx}) == 2) + options.region{reg_idx}(3) = options.region{reg_idx}(2); + options.region{reg_idx}(2) = 1; + else + error ("imread: range for %s must be a 2 or 3 element vector", + varargin{idx}); + endif + options.region{reg_idx} = floor (options.region{reg_idx}(1)): ... + floor (options.region{reg_idx}(2)): ... + floor (options.region{reg_idx}(3)); + endfor + if (options.region{1}(end) > info.rows) + error ("imread: end ROWS for PixelRegions option is larger than image height"); + elseif (options.region{2}(end) > info.columns) + error ("imread: end COLS for PixelRegions option is larger than image width"); + endif + + case "info", + ## We ignore this option. This parameter exists in Matlab to + ## speed up the reading of multipage TIFF by passing a structure + ## that contains information about the start on the file of each + ## page. We can't control it through GraphicsMagic but at least + ## we allow to load multiple pages with one command. + + otherwise + error ("imread: invalid PARAMETER `%s'", varargin{idx}); + + endswitch + endfor + + [varargout{1:nargout}] = __magick_read__ (fn, options); + + catch + ## If we can't read it with Magick, maybe the image is in Octave's + ## native image format. This is from back before Octave had 'imread' + ## and 'imwrite'. Then we had the functions 'loadimage' and 'saveimage'. + ## + ## This "image format" seems to be any file that can be read with + ## load() and contains 2 variables. The variable named "map" is a + ## colormap and must exist whether the image is indexed or not. The + ## other variable must be named "img" or "X" for a "normal" or + ## indexed image. + ## + ## FIXME: this has been deprecated for the next major release (3.8 or 4.0). + ## If someone wants to revive this as yet another image format, a + ## separate Octave package can be written for it, that register the + ## format through imformats. + + magick_error = lasterr (); + + img_field = false; + x_field = false; + map_field = false; + + try + vars = load (fn); + if (isstruct (vars)) + img_field = isfield (vars, "img"); + x_field = isfield (vars, "X"); + map_field = isfield (vars, "map"); + endif + catch + error ("imread: invalid image file: %s", magick_error); + end_try_catch + + if (map_field && (img_field || x_field)) + varargout{2} = vars.map; + if (img_field) + varargout{1} = vars.img; + else + varargout{1} = vars.X; + endif + persistent warned = false; + if (! warned) + warning ("Octave's native image format has been deprecated."); + warned = true; + endif + else + error ("imread: invalid Octave image file format"); + endif + + end_try_catch + +endfunction + +## Tests if the value passed to the Index or Frames is valid. This option +## can be defined in two places, but only in one place can it also be the +## string "all" +function bool = is_valid_index_option (arg) + ## is the index option + bool = false; + if (isvector (arg) && isnumeric (arg) && isreal (arg)) + bool = true; + endif +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/private/__imwrite__.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/image/private/__imwrite__.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,119 @@ +## Copyright (C) 2008-2012 John W. Eaton +## Copyright (C) 2013 Carnë Draug +## +## 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 +## . + +## This function does all the work of imwrite. It exists here as private +## function so that imwrite can use other functions if imformats is +## configured to. It is also needed so that imformats can create a +## function handle for it. + +function __imwrite__ (img, varargin) + + if (nargin < 2 || ! (isnumeric (img) || islogical (img))) + print_usage ("imwrite"); + endif + + [filename, ext, map, param_list] = imwrite_filename (varargin{:}); + + if (isempty (img)) + error ("imwrite: invalid empty image"); + elseif (issparse (img) || issparse (map)) + error ("imwrite: sparse images are not supported"); + endif + + if (rem (numel (param_list), 2) != 0) + error ("imwrite: no pair for all arguments (odd number left)"); + endif + + ## set default for options + options = struct ("writemode", "overwrite", + "quality", 75, + "alpha", cast ([], class (img))); + + for idx = 1:2:numel (param_list) + + switch (tolower (param_list{idx})) + + case "alpha" + options.alpha = param_list{idx+1}; + if (! isnumeric (options.alpha)) + error ("imwrite: value for %s option must be a numeric matrix", + param_list{idx}); + elseif (size (options.alpha, 3) != 1) + error ("imwrite: 3rd dimension of matrix for %s must be singleton", + param_list{idx}); + elseif (ndims (options.alpha) > 4 || + any (size (options.alpha)([1 2]) != size (img)([1 2])) || + size (options.alpha, 4) != size (img, 4)) + error ("imwrite: matrix for %s must have same dimension as image", + param_list{idx}); + endif + + case "writemode", + options.writemode = param_list{idx+1}; + if (! ischar (options.writemode) + || ! any (strcmpi (options.writemode, {"append", "overwrite"}))) + error ('imwrite: value for %s option must be "append" or "overwrite"', + param_list{idx}); + endif + options.writemode = tolower (options.writemode); + + case "quality", + options.quality = param_list{idx+1}; + if (! isnumeric (options.quality) || ! isscalar (options.quality) + || options.quality < 0 || options.quality > 100) + error ("imwrite: value for %s option must be a scalar between 0 and 100", + param_list{idx}); + endif + options.quality = round (options.quality); + + otherwise + error ("imwrite: invalid PARAMETER `%s'", varargin{idx}); + + endswitch + endfor + + if (! isempty (map)) + if (! iscolormap (map)) + error ("imwrite: invalid MAP for indexed image"); + elseif (ndims (img) != 2 && ndims (img) != 4) + error ("imwrite: indexed image must have 2 or 4 dimensions (found %i)", ndims (img)); + endif + ## If the image is floating point, then we convert it to integer (makes + ## it easier in __magick_write__ since it only handles integers. Also, + ## if it's floating point, it has an offset of 1 + if (isfloat (img)) + if (rows (map) <= 256) + img = uint8 (img - 1); + else + img = uint16 (img - 1); + endif + endif + endif + + if (ndims (img) > 4) + error ("imwrite: invalid %d-dimensional image data", ndims (img)); + elseif (all (size (img, 3) != [1 3 4])) + ## 1, 3, or 4 for grayscle, RGB, and CMYK respectively + error ("imwrite: IMG 3rd dimension must be 1, 3, or 4"); + endif + + __magick_write__ (filename, ext, img, map, options); + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/private/imageIO.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/image/private/imageIO.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,69 @@ +## Copyright (C) 2013 Carnë Draug +## +## 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 +## . + +## This function simply connects imread and imfinfo() to the function +## to be used based on their format. It does it by checking the file extension +## of the file and redirecting to the appropriate function after checking +## with imformats. +## +## First argument is a function handle for the default imageIO function (what +## to use if the file extension for the image file is not listed by imformats). +## Second argument is the fieldname in the struct returned by imformats with a +## function handle for the function to use. Third argument is a cell array, its +## first element the filename, and the second, an optional file extension to +## add to filename, if filename alone does not exist. All the others are the +## original input arguments passed to the original imageIO function which will +## be passed on to the destination function. +## +## No input checking whatsoever is performed. That should be performed by the +## function calling it. + +function varargout = imageIO (core_func, fieldname, filename, varargin) + + ## It should not be this function job to check if the file exists or not. + ## However, we need to know the file extension to use with imformats and + ## that means we need to know the actual filename that will be used which + ## is dependent on whether a file exists. + ## + ## If a file named filename{1} exists, then that's it, we will use that + ## wether it has an extension or not. If it does not exist and we have + ## something in filename{2}, then we will consider it the file extension. + ## Note the detail that if we find a file using filename{1} only, then we + ## should completely ignore filename{2}. It won't even be used by + ## imformats() at all, even if filename{1} has no extension to use with + ## imformats(). + if (isscalar (filename) || ! isempty (file_in_path (IMAGE_PATH, filename{1}))) + [~, ~, ext] = fileparts (filename{1}); + if (! isempty (ext)) + ## remove dot from extension + ext = ext(2:end); + endif + else + ext = filename{2}; + endif + + fmt = imformats (ext); + ## When there is no match, fmt will be a 1x1 structure with no fields, + ## so we can't just use `isempty (fmt)'. + if (isempty (fieldnames (fmt))) + [varargout{1:nargout}] = core_func (varargin{:}); + else + [varargout{1:nargout}] = fmt.(fieldname) (varargin{:}); + endif +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/private/imwrite_filename.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/image/private/imwrite_filename.m Sat Oct 05 11:22:09 2013 -0400 @@ -0,0 +1,69 @@ +## Copyright (C) 2013 Carnë Draug +## +## 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 +## . + +## The input check for imwrite needs to be done twice, once when imwrite +## is called the first time to find where the filename is, and a second +## time by __imwrite__ after imformats decides what function to use. +## Because a user can, and is encouraged to, get a function handle to +## __imwrite__, the input check is also done there. +## In addition, the input check for imwrite is not that straightforward +## in order to support the multiple ways the function can be called, +## and interpretations of Matlab documentation. +## +## Anyway, this will only do the input check until it finds the filename +## to be used, the only part that imwrite actually needs. + +function [filename, ext, cmap, options] = imwrite_filename (varargin) + + ## First, we check if the first argument is a colormap or a filename. + cmap = []; + if (ischar (varargin{1})) + filename_idx = 1; + elseif (numel (varargin) >= 2 && iscolormap (varargin{1}) && ischar (varargin{2})) + filename_idx = 2; + cmap = varargin{1}; + else + error ("imwrite: no FILENAME specified"); + endif + filename = tilde_expand (varargin{filename_idx}); + + ## Next, we get the file extension. + ## if we have an odd number of leftover arguments, and the next argument + ## is a string, we consider it the file extension. Otherwise we will + ## extract what we can from the previously found filename. + options_idx = filename_idx + 1; + if (numel (varargin) > filename_idx && + rem (length (varargin) - filename_idx, 2) != 0 && + ischar (varargin{filename_idx + 1})) + ext = varargin{filename_idx + 1}; + filename = [filename "." ext]; + options_idx++; + else + [~, ~, ext] = fileparts (filename); + if (! isempty (ext)) + ## remove dot from extension + ext = ext(2:end); + endif + endif + + ## After all the work finding where the filename was, we might as well + ## send the leftovers list (they should be in key value pairs) + options = varargin(options_idx:end); + +endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/private/ind2x.m --- a/scripts/image/private/ind2x.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/image/private/ind2x.m Sat Oct 05 11:22:09 2013 -0400 @@ -22,8 +22,8 @@ function [x, map] = ind2x (caller, x, map) ## Check if X is an indexed image. - ## an indexed image is defined has having only 2D, and that's how matlab - ## behaves. But we want to support ND images, so we will allow up to 4D + ## an indexed image is defined has having only 2D, and that's how Matlab + ## behaves. But we want to support ND images, so we will allow up to 4D ## and check that the 3rd is a singleton if (all (ndims (x) != [2 4]) || size (x, 3) != 1 || issparse (x) || (isfloat (x) && ! isindex (x)) || @@ -51,9 +51,10 @@ num_colors = rows (map); if (num_colors < maxidx) - ## Pad with the last color in the map for matlab compatibility + ## Pad with the last color in the map for Matlab compatibility pad = repmat (map(end,:), maxidx - num_colors, 1); map(end+1:maxidx, :) = pad; endif endfunction + diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/rgb2ind.m --- a/scripts/image/rgb2ind.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/image/rgb2ind.m Sat Oct 05 11:22:09 2013 -0400 @@ -37,19 +37,17 @@ ## ## The input image @var{rgb} must be an N-dimensional RGB image ## (@nospell{MxNxO}@dots{}x3 array) where M,N,O@dots{} are the image -## dimensions, and the -## final dimension contains the values in the red, green and blue -## channels. Alternatively, the red, green and blue color channels can -## be input as separate arrays @var{R}, @var{G} and @var{B}. +## dimensions, and the final dimension contains the values in the red, green +## and blue channels. Alternatively, the red, green and blue color channels +## can be input as separate arrays @var{R}, @var{G}, and @var{B}. ## -## The input @var{map} defines the colormap to be used. Alternatively, -## @var{n} or @var{tol} may be used to define the maximum number of -## colors to use in an automatically generated colormap. @var{n} is -## related to @var{tol} by: @var{n} = (floor (1/@var{tol}) + 1)^3; -## @var{tol} must be >0 and @leq{}1. +## The input @var{map} defines the colormap to be used. Alternatively, @var{n} +## or @var{tol} may be used to define the maximum number of colors to use in an +## automatically generated colormap. @var{n} is related to @var{tol} by: +## @var{n} = (floor (1/@var{tol}) + 1)^3; where 0 < @var{tol} @leq{} 1. ## ## @var{dither_option} is a string which enables or disables dithering: -## 'dither' (default) or 'nodither'. +## @qcode{"dither"} (default) or @qcode{"nodither"}. ## ## @seealso{ind2rgb, rgb2hsv, rgb2ntsc} ## @end deftypefn @@ -66,7 +64,7 @@ else ## Test for dither_option, by checking if the final input is a string - if ischar (varargin{end}) + if (ischar (varargin{end})) dither_option = varargin{end}; dither_check = true; else @@ -143,14 +141,14 @@ ## If image is an ND array, convert it to a tiled 2D image ## before processing it with Graphicsmagick - if numel (sz)>3 + if (numel (sz) > 3) rgb = reshape (rgb, [prod(sz(1:end-2)), sz(end-1), 3]); - end + endif ## Prepare the Graphicsmagick dithering option - if strcmp (dither_option, "nodither") + if (strcmp (dither_option, "nodither")) ditherstr = "+dither"; - elseif strcmp (dither_option, "dither") + elseif (strcmp (dither_option, "dither")) ditherstr = "-dither"; endif @@ -167,7 +165,7 @@ ## Conversion of rgb image to x,map pr = prod (sz(1:end-1)); x = zeros (sz(1:end-1)); - [map,~,x(:)] = unique (reshape(rgb, [pr, 3]), "rows"); + [map,~,x(:)] = unique (reshape (rgb, [pr, 3]), "rows"); ## a colormap is of class double and values between 0 and 1 switch (class (rgb)) diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/rgb2ntsc.m --- a/scripts/image/rgb2ntsc.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/image/rgb2ntsc.m Sat Oct 05 11:22:09 2013 -0400 @@ -98,9 +98,9 @@ %% Test pure RED, GREEN, BLUE colors -%assert (rgb2ntsc ([1 0 0]), [.299 .587 .114]) -%assert (rgb2ntsc ([0 1 0]), [.596 -.274 -.322]) -%assert (rgb2ntsc ([1 0 1]), [.211 -.523 .312]) +%!assert (rgb2ntsc ([1 0 0]), [.299 .596 .211]) +%!assert (rgb2ntsc ([0 1 0]), [.587 -.274 -.523]) +%!assert (rgb2ntsc ([0 0 1]), [.114 -.322 .312]) %!test %! rgb_map = rand (64, 3); diff -r 20d1b911b4e7 -r c702371ff6df scripts/image/spinmap.m --- a/scripts/image/spinmap.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/image/spinmap.m Sat Oct 05 11:22:09 2013 -0400 @@ -23,7 +23,7 @@ ## @deftypefnx {Function File} {} spinmap ("inf") ## Cycle the colormap for @var{t} seconds with a color increment of @var{inc}. ## Both parameters are optional. The default cycle time is 5 seconds and the -## default increment is 2. If the option "inf" is given then cycle +## default increment is 2. If the option @qcode{"inf"} is given then cycle ## continuously until @kbd{Control-C} is pressed. ## ## When rotating the original color 1 becomes color 2, color 2 becomes diff -r 20d1b911b4e7 -r c702371ff6df scripts/io/beep.m --- a/scripts/io/beep.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/io/beep.m Sat Oct 05 11:22:09 2013 -0400 @@ -36,3 +36,4 @@ %!error (beep (1)) + diff -r 20d1b911b4e7 -r c702371ff6df scripts/io/csvwrite.m --- a/scripts/io/csvwrite.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/io/csvwrite.m Sat Oct 05 11:22:09 2013 -0400 @@ -41,14 +41,15 @@ %!test %! csvwrite (fname, magic (3)); -%! assert (csvread (fname), magic (3)); +%! data = csvread (fname); %! unlink (fname); +%! assert (data, magic (3)); %!test %! csvwrite (fname, magic (3), "precision", "%2.1f", "newline", "unix"); %! fid = fopen (fname, "rt"); %! txt = char (fread (fid,Inf,'char')'); %! fclose (fid); +%! unlink (fname); %! assert (txt, "8.0,1.0,6.0\n3.0,5.0,7.0\n4.0,9.0,2.0\n"); -%! unlink (fname); diff -r 20d1b911b4e7 -r c702371ff6df scripts/io/dlmwrite.m --- a/scripts/io/dlmwrite.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/io/dlmwrite.m Sat Oct 05 11:22:09 2013 -0400 @@ -35,32 +35,32 @@ ## The value of @var{c} specifies the number of delimiters to prepend to ## each line of data. ## -## If the argument @code{"-append"} is given, append to the end of +## If the argument @qcode{"-append"} is given, append to the end of ## @var{file}. ## ## In addition, the following keyword value pairs may appear at the end ## of the argument list: ## ## @table @asis -## @item "append" -## Either @samp{"on"} or @samp{"off"}. See @samp{"-append"} above. +## @item @qcode{"append"} +## Either @qcode{"on"} or @qcode{"off"}. See @qcode{"-append"} above. ## -## @item "delimiter" +## @item @qcode{"delimiter"} ## See @var{delim} above. ## -## @item "newline" +## @item @qcode{"newline"} ## The character(s) to use to separate each row. Three special cases -## exist for this option. @samp{"unix"} is changed into "\n", -## @samp{"pc"} is changed into "\r\n", and @samp{"mac"} is changed -## into "\r". Other values for this option are kept as is. +## exist for this option. @qcode{"unix"} is changed into @qcode{"\n"}, +## @qcode{"pc"} is changed into @qcode{"\r\n"}, and @qcode{"mac"} is changed +## into @qcode{"\r"}. Other values for this option are kept as is. ## -## @item "roffset" +## @item @qcode{"roffset"} ## See @var{r} above. ## -## @item "coffset" +## @item @qcode{"coffset"} ## See @var{c} above. ## -## @item "precision" +## @item @qcode{"precision"} ## The precision to use when writing the file. It can either be a ## format string (as used by fprintf) or a number of significant digits. ## @end table @@ -151,6 +151,11 @@ endif endwhile + ## Expand '\t' to TAB for Matlab compatibility + if (strcmp (delim, '\t')) + delim = "\t"; + endif + if (ischar (file)) [fid, msg] = fopen (file, opentype); elseif (isscalar (file) && isnumeric (file)) diff -r 20d1b911b4e7 -r c702371ff6df scripts/io/fileread.m --- a/scripts/io/fileread.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/io/fileread.m Sat Oct 05 11:22:09 2013 -0400 @@ -53,8 +53,8 @@ %! fprintf (fid, "%s\n", cstr{:}); %! fclose (fid); %! str = fileread (fname); +%! unlink (fname); %! assert (str, [cstr{1} "\n" cstr{2} "\n" cstr{3} "\n"]); -%! unlink (fname); %% Test input validation %!error fileread () diff -r 20d1b911b4e7 -r c702371ff6df scripts/io/importdata.m --- a/scripts/io/importdata.m Thu Sep 12 21:08:07 2013 -0400 +++ b/scripts/io/importdata.m Sat Oct 05 11:22:09 2013 -0400 @@ -22,22 +22,21 @@ ## @deftypefnx {Function File} {@var{A} =} importdata (@var{fname}, @var{delimiter}, @var{header_rows}) ## @deftypefnx {Function File} {[@var{A}, @var{delimiter}] =} importdata (@dots{}) ## @deftypefnx {Function File} {[@var{A}, @var{delimiter}, @var{header_rows}] =} importdata (@dots{}) -## Importing data from file. -## -## Importing the contents of file @var{fname} into workspace. +## Import data from the file @var{fname}. ## ## Input parameters: ## ## @itemize ## @item @var{fname} -## The file name for the file to import. +## The name of the file containing data. ## ## @item @var{delimiter} ## The character separating columns of data. Use @code{\t} for tab. -## (Only valid for ascii files) +## (Only valid for ASCII files) ## ## @item @var{header_rows} -## Number of header rows before the data begins. (Only valid for ascii files) +## The number of header rows before the data begins. (Only valid for ASCII +## files) ## @end itemize ## ## Different file types are supported: @@ -45,7 +44,7 @@ ## @itemize ## @item ASCII table ## -## Importing ASCII table using the specified number of header rows and +## Import ASCII table using the specified number of header rows and ## the specified delimiter. ## ## @item Image file @@ -63,79 +62,57 @@ ## Author: Erik Kjellson -function [output, delimiter, header_rows] = importdata (varargin) +function [output, delimiter, header_rows] = importdata (fname, delimiter = "", header_rows = -1) - ## Default values - fname = ""; - delimiter = ""; - header_rows = -1; - - ########## - - ## Check input arguments - - if (nargin < 1) + if (nargin < 1 || nargin > 3) print_usage (); endif - fname = varargin{1}; - ## Check that the file name really is a string if (! ischar (fname)) - error ("importdata: file name needs to be a string"); - endif - if ( strcmpi (fname, "-pastespecial")) + error ("importdata: FNAME must be a string"); + elseif (strcmpi (fname, "-pastespecial")) error ("importdata: option -pastespecial not implemented"); endif if (nargin > 1) - delimiter = varargin{2}; - ## Check that the delimiter really is a string - if (!ischar (delimiter)) - error("importdata: delimiter needs to be a character"); + if (! ischar (delimiter) + || (length (delimiter) > 1 && ! strcmp (delimiter, '\t'))) + error("importdata: DELIMITER must be a single character"); endif - if (length (delimiter) > 1 && !strcmpi (delimiter, "\\t")) - error("importdata: delimiter cannot be longer than 1 character"); - endif - if (strcmpi (delimiter, "\\")) - delimiter = "\\\\"; + if (strcmp (delimiter, '\t')) + delimiter = "\t"; endif endif if (nargin > 2) - header_rows = varargin{3}; - if (!isnumeric (header_rows) || header_rows < 0) - error ("importdata: number of header rows needs to be an integer number >= 0"); + if (! isnumeric (header_rows) || header_rows < 0 + || header_rows != fix (header_rows)) + error ("importdata: HEADER_ROWS must be an integer >= 0"); endif endif - if (nargin > 3) - error ("importdata: too many input arguments"); - endif - - ########## - ## Check file format ## Get the extension from the file name. - [d n fileExt v] = fileparts (fname); - ## Make sure file extension is in lower case. - fileExt = lower (fileExt); + [~, ~, ext, ~] = fileparts (fname); + ext = lower (ext); - switch fileExt - case {".au", ".snd"} - error ("importdata: not implemented for file format %s", fileExt); - case ".avi" - error ("importdata: not implemented for file format %s", fileExt); - case {".bmp", ".cur", ".gif", ".hdf", ".ico", ".jpe", ".jpeg", ".jpg", \ - ".pbm", ".pcx", ".pgm", ".png", ".pnm", ".ppm", ".ras", \ - ".tif", ".tiff", ".xwd"} - delimiter = NaN; + switch (ext) + case {".au", ".snd", ".flac", ".ogg"} + error ("importdata: not implemented for file format %s", ext); + case {".avi", ".mj2", ".mpg", ".asf", ".asx", ".wmv", ".mp4", ".m4v", ... + ".mov"} + error ("importdata: not implemented for file format %s", ext); + case {".bmp", ".cur", ".gif", ".hdf", ".ico", ".jpe", ".jpeg", ".jpg", ... + ".jp2", ".jpf", ".jpx", ".j2c", ".j2k", ".pbm", ".pcx", ".pgm", ... + ".png", ".pnm", ".ppm", ".ras", ".tif", ".tiff", ".xwd"} + delimiter = NaN; header_rows = 0; [output.cdata, output.colormap, output.alpha] = imread (fname); case ".mat" - delimiter = NaN; + delimiter = NaN; header_rows = 0; output = load (fname); - case {".wk1", ".xls", ".xlsx", ".dbf", ".pxl"} + case {".xls", ".xlsx", ".wk1", ".dbf", ".pxl"} ## If there's no Excel file support simply fall back to unimplemented.m output = xlsread (fname); case {".ods", ".sxc", ".fods", ".uos", ".xml"} @@ -147,228 +124,285 @@ output = xlsread (fname); end_try_catch case {".wav", ".wave"} - delimiter = NaN; + delimiter = NaN; header_rows = 0; [output.data, output.fs] = wavread (fname); otherwise - ## Assume the file is in ascii format. - [output, delimiter, header_rows] = \ + ## Assume the file is in ASCII format. + [output, delimiter, header_rows] = ... importdata_ascii (fname, delimiter, header_rows); endswitch ## If there are any empty fields in the output structure, then remove them - if (isstruct (output) && length (output) == 1) + if (isstruct (output) && numel (output) == 1) fields = fieldnames (output); for i=1:length (fields) - if (isempty (getfield (output, fields{i}))) + if (isempty (output.(fields{i}))) output = rmfield (output, fields{i}); endif endfor ## If only one field is left, replace the structure with the field, - ## i.e. output = output.onlyFieldLeft + ## i.e., output = output.onlyFieldLeft ## Update the list of fields fields = fieldnames (output); - if (length (fields) == 1) - output = getfield (output, fields{1}); + if (numel (fields) == 1) + output = output.(fields{1}); endif endif -endfunction - - -######################################## - -function [output, delimiter, header_rows] = \ - importdata_ascii (fname, delimiter, header_rows) - - ## Define the fields in the output structure so that the order will be - ## correct. - - output.data = []; - output.textdata = []; - output.rowheaders = []; - output.colheaders = []; - - ## Read file into string and count the number of header rows - file_content = fileread (fname); - - ## Split the file into rows (using \n and/or \r as delimiters between rows). - file_content_rows = regexp (file_content, "\n|\n\r|\r|\r\n", "split"); - - ## FIXME: guess delimiter, if it isn't defined - if (isempty (delimiter)) - error ("importdata: Guessing delimiter is not implemented yet, you have to specify it."); - endif - ## FIXME: A more intelligent way to count number of header rows. This - ## is needed e.g. when delimiter=' ' and the header contains spaces... +endfunction + +function [output, delimiter, header_rows] = importdata_ascii (fname, delimiter, num_header_rows) - ## If number of header rows is undefined, then count the number of - ## header rows by step through row by row and look for the delimiter. - ## Assume that the header can't contain any delimiter. - if (header_rows < 0) - header_rows = 0; - for i=1:length (file_content_rows) - if (isempty (regexp(file_content_rows{i}, delimiter, "once"))) - header_rows++; - else - ## Data part has begun and therefore no more header rows can be - ## found - break; - endif - endfor - endif + ## Define fields in the output structure so that the order will be correct. + output.data = []; + output.textdata = {}; + output.rowheaders = {}; + output.colheaders = {}; - ## Put the header rows in output.textdata. - if (header_rows > 0) - output.textdata = file_content_rows (1:header_rows)'; - endif - - ## If space is the delimiter, then remove spaces in the beginning of - ## each data row. - if (strcmpi (delimiter, " ")) - for i=(header_rows+1):length (file_content_rows) - ## strtrim does not only remove the leading spaces but also the - ## tailing spaces, but that doesn't really matter. - file_content_rows{i} = strtrim (file_content_rows{i}); - endfor + [fid, msg] = fopen (fname, "r"); + if (fid == -1) + error (msg); endif - ## Remove empty data rows. Go through them backwards so that you wont - ## get out of bounds. - for i=length (file_content_rows):-1:(header_rows + 1) - if (length (file_content_rows{i}) < 1) - file_content_rows = [file_content_rows(1:i-1), \ - file_content_rows(i+1:length(file_content_rows))]; - endif - endfor + header_rows = 0; + header_cols = 0; + + ## Work through first few rows line by line until a delimiter is found. + while (ischar (row = fgetl (fid))) - ## Count the number of data columns. If there are different number of - ## columns, use the greatest value. - data_columns = 0; - delimiter_pattern = delimiter; - ## If space is the delimiter, then multiple spaces should count as ONE - ## delimiter. Also ignore leading spaces. - if (strcmpi (delimiter, " ")) - delimiter_pattern = ' +'; - endif - for i=(header_rows+1):length(file_content_rows) - data_columns = max (data_columns, - length (regexp (file_content_rows{i}, - delimiter_pattern, "split"))); - endfor + ## If no delimiter determined yet, make a guess. + if (isempty (delimiter)) + ## This pattern can be fooled, but mostly does the job just fine. + delim = regexp (row, '[+-\d.eE\*ij ]+([^+-\d.ij])[+-\d.ij]', + 'tokens', 'once'); + if (! isempty (delim)) + delimiter = delim{1}; + endif + endif - ## FIXME: Make it behave like Matlab when importing a table where a whole - ## column is text only. E.g. - ## abc 12 34 - ## def 56 78 - ## This would give a 3x2 data matrix with the left column = nan(2,1), and - ## the text would end up in textdata. - ## In Matlab the data matrix would only be a 2x2 matrix, see example at: - ## http://www.mathworks.se/help/matlab/import_export/import-numeric-data-and-header-text-from-a-text-file.html - - ## Go through the data and put it in either output.data or - ## output.textdata depending on if it is numeric or not. - output.data = NaN (length (file_content_rows) - header_rows, data_columns); - for i=(header_rows+1):length(file_content_rows) - ## Only use the row if it contains anything other than white-space - ## characters. - if (any (file_content_rows{i} != " ")) - row_data = regexp (file_content_rows{i}, delimiter_pattern, "split"); + if (delimiter == " ") + row_entries = regexp (strtrim (row), ' +', 'split'); + else + row_entries = ostrsplit (row, delimiter); + endif + row_data = str2double (row_entries); + if (all (isnan (row_data)) || header_rows < num_header_rows) + header_rows++; + output.textdata{end+1, 1} = row; + else + if (! isempty (output.textdata)) + if (delimiter == " ") + output.colheaders = regexp (strtrim (output.textdata{end}), + ' +', 'split'); + else + output.colheaders = ostrsplit (output.textdata{end}, delimiter); + endif + endif + header_cols = find (! isnan (row_data), 1) - 1; + ## The number of header rows and header columns is now known. + break; + endif - for j=1:length(row_data) - ## Try to convert the column to a number, if it works put it in - ## output.data, otherwise in output.textdata - if (!isempty (row_data{j})) - data_numeric = str2double (row_data{j}); - if (!isnan (data_numeric)) - output.data(i-header_rows, j) = data_numeric; - else - output.textdata{i,j} = row_data{j}; - endif - endif - endfor + endwhile + + fclose (fid); - endif - endfor - - ## Check wether rowheaders or colheaders should be used - if ((header_rows == data_columns) && (size (output.textdata, 2) == 1)) - output.rowheaders = output.textdata; - elseif (size (output.textdata, 2) == data_columns) - output.colheaders = output.textdata(end,:); + if (row == -1) + error ("importdata: Unable to determine delimiter"); + endif + if (num_header_rows >= 0) + header_rows = num_header_rows; endif - ## When delimiter = "\\t" convert it to a tab, done for Matlab compatibility. - if (strcmp (delimiter, '\t')) - delimiter = "\t"; + ## Now, let the efficient built-in routine do the bulk of the work. + if (delimiter == " ") + output.data = dlmread (fname, "", header_rows, header_cols, + "emptyvalue", NA); + else + output.data = dlmread (fname, delimiter, header_rows, header_cols, + "emptyvalue", NA); + endif + + ## Go back and correct any individual values that did not convert. + na_idx = isna (output.data); + if (header_cols > 0) + na_idx = [(true (rows (na_idx), header_cols)), na_idx]; + endif + if (any (na_idx(:))) + + file_content = ostrsplit (fileread (fname), "\n"); + + na_rows = find (any (na_idx, 2)); + for ridx = na_rows(:)' + row = file_content{ridx+header_rows}; + if (delimiter == " ") + fields = regexp (strtrim (row), ' +', 'split'); + else + fields = ostrsplit (row, delimiter); + endif + + text = fields(na_idx(ridx,:)); + text = text(! strcmpi (text, "NA")); # Remove valid "NA" entries + if (! isempty (text)) + output.textdata(end+1:end+numel (text), 1) = text; + endif + if (header_cols) + output.rowheaders(end+1, :) = fields(1:header_cols); + endif + endfor + + endif + + ## Final cleanup to satisfy output configuration + if (all (cellfun ("isempty", output.textdata))) + output = output.data; + elseif (! isempty (output.rowheaders) && ! isempty (output.colheaders)) + output = struct ("data", {output.data}, "textdata", {output.textdata}); endif endfunction -######################################## - %!test -%! # Comma separated values +%! ## Comma separated values %! A = [3.1 -7.2 0; 0.012 6.5 128]; %! fn = tmpnam (); %! fid = fopen (fn, "w"); %! fputs (fid, "3.1,-7.2,0\n0.012,6.5,128"); %! fclose (fid); -%! [a,d,h] = importdata (fn, ","); +%! [a1,d1,h1] = importdata (fn, ","); +%! [a2,d2,h2] = importdata (fn); %! unlink (fn); -%! assert (a, A); -%! assert (d, ","); -%! assert (h, 0); +%! assert (a1, A); +%! assert (d1, ","); +%! assert (h1, 0); +%! assert (a2, A); +%! assert (d2, ","); +%! assert (h2, 0); %!test -%! # Tab separated values +%! ## Tab separated values %! A = [3.1 -7.2 0; 0.012 6.5 128]; %! fn = tmpnam (); %! fid = fopen (fn, "w"); %! fputs (fid, "3.1\t-7.2\t0\n0.012\t6.5\t128"); %! fclose (fid); -%! [a,d,h] = importdata (fn, "\\t"); +%! [a1,d1,h1] = importdata (fn, "\t"); +%! [a2,d2,h2] = importdata (fn); +%! unlink (fn); +%! assert (a1, A); +%! assert (d1, "\t"); +%! assert (h1, 0); +%! assert (a2, A); +%! assert (d2, "\t"); +%! assert (h2, 0); + +%!test +%! ## Space separated values, using multiple spaces to align in columns. +%! A = [3.1 -7.2 0; 0.012 6.5 128]; +%! fn = tmpnam (); +%! fid = fopen (fn, "w"); +%! fprintf (fid, "%10.3f %10.3f %10.3f\n", A'); +%! fclose (fid); +%! [a1,d1,h1] = importdata (fn, " "); +%! [a2,d2,h2] = importdata (fn); +%! unlink (fn); +%! assert (a1, A); +%! assert (d1, " "); +%! assert (h1, 0); +%! assert (a2, A); +%! assert (d2, " "); +%! assert (h2, 0); + +%!test +%! ## No separator, 1 column of data only +%! A = [3.1;-7.2;0;0.012;6.5;128]; +%! fn = tmpnam (); +%! fid = fopen (fn, "w"); +%! fprintf (fid, "%f\n", A); +%! fclose (fid); +%! [a1,d1,h1] = importdata (fn, ""); +%! [a2,d2,h2] = importdata (fn); +%! unlink (fn); +%! assert (a1, A); +%! assert (d1, ""); +%! assert (h1, 0); +%! assert (a2, A); +%! assert (d2, ""); +%! assert (h2, 0); + +%!test +%! ## Header text +%! A.data = [3.1 -7.2 0; 0.012 6.5 128]; +%! A.textdata = {"This is a header row."; ... +%! "this row does not contain any data, but the next one does."}; +%! A.colheaders = A.textdata (2); +%! fn = tmpnam (); +%! fid = fopen (fn, "w"); +%! fprintf (fid, "%s\n", A.textdata{:}); +%! fputs (fid, "3.1\t-7.2\t0\n0.012\t6.5\t128"); +%! fclose (fid); +%! [a,d,h] = importdata (fn, '\t'); +%! unlink (fn); +%! assert (a, A); +%! assert (d, "\t"); +%! assert (h, 2); + +%!test +%! ## Column headers, only last row is returned in colheaders +%! A.data = [3.1 -7.2 0; 0.012 6.5 128]; +%! A.textdata = {"Label1\tLabel2\tLabel3"; +%! "col 1\tcol 2\tcol 3"}; +%! A.colheaders = {"col 1", "col 2", "col 3"}; +%! fn = tmpnam (); +%! fid = fopen (fn, "w"); +%! fprintf (fid, "%s\n", A.textdata{:}); +%! fputs (fid, "3.1\t-7.2\t0\n0.012\t6.5\t128"); +%! fclose (fid); +%! [a,d,h] = importdata (fn, '\t'); +%! unlink (fn); +%! assert (a, A); +%! assert (d, "\t"); +%! assert (h, 2); + +%!test +%! ## Row headers +%! A.data = [3.1 -7.2 0; 0.012 6.5 128]; +%! A.textdata = {"row1"; "row2"}; +%! A.rowheaders = A.textdata; +%! fn = tmpnam (); +%! fid = fopen (fn, "w"); +%! fputs (fid, "row1\t3.1\t-7.2\t0\nrow2\t0.012\t6.5\t128"); +%! fclose (fid); +%! [a,d,h] = importdata (fn, '\t'); %! unlink (fn); %! assert (a, A); %! assert (d, "\t"); %! assert (h, 0); %!test -%! # Space separated values, using multiple spaces to align in columns. -%! A = [3.1 -7.2 0; 0.012 6.5 128]; +%! ## Row/Column headers and Header Text +%! A.data = [3.1 -7.2 0; 0.012 6.5 128]; +%! A.textdata = {"This is introductory header text" +%! " col1 col2 col3" +%! "row1" +%! "row2"}; %! fn = tmpnam (); %! fid = fopen (fn, "w"); -%! fprintf (fid, "%10.3f %10.3f %10.3f\n", A(1,:)); -%! fprintf (fid, "%10.3f %10.3f %10.3f\n", A(2,:)); +%! fprintf (fid, "%s\n", A.textdata{1:2}); +%! fputs (fid, "row1\t3.1\t-7.2\t0\nrow2\t0.012\t6.5\t128"); %! fclose (fid); -%! [a,d,h] = importdata (fn, " "); -%! unlink (fn); -%! assert (a, A); -%! assert (d, " "); -%! assert (h, 0); - -%!test -%! # Header -%! A.data = [3.1 -7.2 0; 0.012 6.5 128]; -%! A.textdata = {"This is a header row."; \ -%! "this row does not contain any data, but the next one does."}; -%! fn = tmpnam (); -%! fid = fopen (fn, "w"); -%! fputs (fid, [A.textdata{1} "\n"]); -%! fputs (fid, [A.textdata{2} "\n"]); -%! fputs (fid, "3.1\t-7.2\t0\n0.012\t6.5\t128"); -%! fclose (fid); -%! [a,d,h] = importdata (fn, "\\t"); +%! [a,d,h] = importdata (fn, '\t'); %! unlink (fn); %! assert (a, A); %! assert (d, "\t"); %! assert (h, 2); %!test -%! # Ignore empty rows containing only spaces +%! ## Ignore empty rows containing only spaces %! A = [3.1 -7.2 0; 0.012 6.5 128]; %! fn = tmpnam (); %! fid = fopen (fn, "w"); @@ -383,67 +417,93 @@ %! assert (h, 0); %!test -%! # Exponentials +%! ## Exponentials %! A = [3.1 -7.2 0; 0.012 6.5 128]; %! fn = tmpnam (); %! fid = fopen (fn, "w"); %! fputs (fid, "+3.1e0\t-72E-1\t0\n12e-3\t6.5\t128"); %! fclose (fid); -%! [a,d,h] = importdata (fn, "\\t"); +%! [a,d,h] = importdata (fn, '\t'); %! unlink (fn); %! assert (a, A); %! assert (d, "\t"); %! assert (h, 0); %!test -%! # Complex numbers +%! ## Complex numbers %! A = [3.1 -7.2 0-3.4i; 0.012 -6.5+7.2i 128]; %! fn = tmpnam (); %! fid = fopen (fn, "w"); %! fputs (fid, "3.1\t-7.2\t0-3.4i\n0.012\t-6.5+7.2i\t128"); %! fclose (fid); -%! [a,d,h] = importdata (fn, "\\t"); +%! [a,d,h] = importdata (fn, '\t'); +%! unlink (fn); +%! assert (a, A); +%! assert (d, "\t"); +%! assert (h, 0); + +%!test +%! ## Exceptional values (Inf, NaN, NA) +%! A = [3.1 Inf NA; -Inf NaN 128]; +%! fn = tmpnam (); +%! fid = fopen (fn, "w"); +%! fputs (fid, "3.1\tInf\tNA\n-Inf\tNaN\t128"); +%! fclose (fid); +%! [a,d,h] = importdata (fn, '\t'); %! unlink (fn); %! assert (a, A); %! assert (d, "\t"); %! assert (h, 0); %!test -%! # Missing values -%! A = [3.1 NaN 0; 0.012 6.5 128]; +%! ## Missing values and Text Values +%! A.data = [3.1 NA 0; 0.012 NA 128]; +%! A.textdata = {char(zeros(1,0)) +%! "NO DATA"}; %! fn = tmpnam (); %! fid = fopen (fn, "w"); -%! fputs (fid, "3.1\t\t0\n0.012\t6.5\t128"); +%! fputs (fid, "3.1\t\t0\n0.012\tNO DATA\t128"); %! fclose (fid); -%! [a,d,h] = importdata (fn, "\\t"); +%! [a,d,h] = importdata (fn, '\t'); %! unlink (fn); %! assert (a, A); %! assert (d, "\t"); %! assert (h, 0); -%!test -%! # CRLF for line breaks +%!#test +%! ## CRLF for line breaks %! A = [3.1 -7.2 0; 0.012 6.5 128]; %! fn = tmpnam (); %! fid = fopen (fn, "w"); %! fputs (fid, "3.1\t-7.2\t0\r\n0.012\t6.5\t128"); %! fclose (fid); -%! [a,d,h] = importdata (fn, "\\t"); +%! [a,d,h] = importdata (fn, '\t'); %! unlink (fn); %! assert (a, A); %! assert (d, "\t"); %! assert (h, 0); -%!test -%! # CR for line breaks +%!#test +%! ## CR for line breaks %! A = [3.1 -7.2 0; 0.012 6.5 128]; %! fn = tmpnam (); %! fid = fopen (fn, "w"); %! fputs (fid, "3.1\t-7.2\t0\r0.012\t6.5\t128"); %! fclose (fid); -%! [a,d,h] = importdata (fn, "\\t"); +%! [a,d,h] = importdata (fn, '\t'); %! unlink (fn); %! assert (a, A); %! assert (d, "\t"); %! assert (h, 0); +%!error importdata () +%!error importdata (1,2,3,4) +%!error importdata (1) +%!error