Hello community, here is the log from the commit of package octave-forge-io for openSUSE:Factory checked in at 2016-07-09 09:25:10 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/octave-forge-io (Old) and /work/SRC/openSUSE:Factory/.octave-forge-io.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "octave-forge-io" Changes: -------- --- /work/SRC/openSUSE:Factory/octave-forge-io/octave-forge-io.changes 2016-06-14 23:07:36.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.octave-forge-io.new/octave-forge-io.changes 2016-07-09 09:25:28.000000000 +0200 @@ -1,0 +2,9 @@ +Fri Jul 8 10:02:20 UTC 2016 - dmitr...@opensuse.org + +- Update to version 2.4.2 + * Changed several calls to (now deprecated) octave_config_info into + calls to __have_feature__.m + * Add support for complex numbers in read_namelist.m and write_namelist.m + * Bug fixes + +------------------------------------------------------------------- Old: ---- io-2.4.1.tar.gz New: ---- io-2.4.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ octave-forge-io.spec ++++++ --- /var/tmp/diff_new_pack.dZrQra/_old 2016-07-09 09:25:29.000000000 +0200 +++ /var/tmp/diff_new_pack.dZrQra/_new 2016-07-09 09:25:29.000000000 +0200 @@ -18,7 +18,7 @@ %define octpkg io Name: octave-forge-%{octpkg} -Version: 2.4.1 +Version: 2.4.2 Release: 0 Summary: Input/Output in external formats from Octave License: GPL-3.0+ and BSD-2-Clause ++++++ io-2.4.1.tar.gz -> io-2.4.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/DESCRIPTION new/io/DESCRIPTION --- old/io/DESCRIPTION 2016-03-09 22:29:45.000000000 +0100 +++ new/io/DESCRIPTION 2016-07-04 21:44:38.000000000 +0200 @@ -1,13 +1,13 @@ Name: io -Version: 2.4.1 -Date: 2015-03-09 +Version: 2.4.2 +Date: 2016-07-04 Author: various authors Maintainer: Philip Nienhuis <prnienh...@users.sf.net> Title: Input/Output Description: Input/Output in external formats. Categories: IO Problems: Default initial Java memory probably too small, increase with java.opts (see documentation). UNO support experimental. -Depends: octave (>= 3.8.0), Octave (< 4.2.0) +Depends: octave (>= 3.8.0), Octave (< 4.4.0) Suggested: windows (>= 1.2.1); Java JRE (> 1.6) Autoload: no License: GPLv3+, simplified BSD diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/NEWS new/io/NEWS --- old/io/NEWS 2016-03-10 22:02:24.000000000 +0100 +++ new/io/NEWS 2016-07-04 21:41:43.000000000 +0200 @@ -1,7 +1,27 @@ Summary of important user-visible changes for releases of the io package =============================================================================== -io-2.4.1 Release Date: 2015-03-09 Release Manager: Philip Nienhuis +io-2.4.2 Release Date: 2016-07-04 Release Manager: Philip Nienhuis +=============================================================================== + +*** Bug fixes: + - odsopen.m, xlsopen.m: do not allow writing to non-existent subdirs + - xlsread.m: return with error if file open failed, rather than trying + to proceed + - OCT interface: mention file creation errors verbosely rather than + silently + - OCT interface, OOXML: improved reading of cached values (but #47815) + +*** Code improvements: + - Swapped post-install.m hack to allow initialization of io package + for PKG_ADD/PKG_DEL directives; no more risk of affecting user space + - Changed several calls to (now deprecated) octave_config_info into + calls to __have_feature__.m + - Add support for complex numbers in read_namelist.m and write_namelist.m + (credits to Ryusuke Numata) + +=============================================================================== +io-2.4.1 Release Date: 2016-03-09 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: @@ -11,20 +31,16 @@ provisional solution is to simply strip those characters from text strings before writing them to file, or strip them before handing the just read raw output cell array to Octave. - - Convert illegal XML characters ('"><&) to XML escape sequences and back. - - Delete temporary files when processing .xlsx files (bug #47378) *** New features: - New function tidyxml.m: simply strips characters < 32 or > 126 from character arrays or cell arrays (including mixed cell arrays). - - test_spsh.m now shows a nice summary of test results for each interface. *** Various changes - Replace calls to deprecated sleep() with calls to pause(). - - Adapt code to changes in octave_config_info in Octave development version. =============================================================================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/PKG_ADD new/io/PKG_ADD --- old/io/PKG_ADD 2016-03-09 22:13:29.000000000 +0100 +++ new/io/PKG_ADD 1970-01-01 01:00:00.000000000 +0100 @@ -1,114 +0,0 @@ -## PKG_ADD -## add paths of io pkg java jars. - -## First check if Java support was built in anyway -try - HAVE_JAVA = octave_config_info ("features").JAVA; -catch - HAVE_JAVA = octave_config_info ("build_features").JAVA; -end_try_catch -if (HAVE_JAVA) - ## OK, Java built-in / supported. Check environment var - userdir = getenv ("OCTAVE_IO_JAVALIBS"); - if (ispc) - homedir = getenv ("USERPROFILE"); - # (MinGW) assume jar files are in /lib/java - libdir = octave_config_info ("libdir"); -# elseif (ismac) -# ## Who knows where OSX keeps e.g., Apache POI stuff? if it does at all... - elseif (isunix) - homedir = tilde_expand ("~"); - ## On linux, spreadsheet .jars are often found somewhere in /usr/share/java - libdir = "/usr/share"; - else - ## Set libdir to "." to avoid searching in a root dir - libdir = "."; - endif - - ## Do we havea 64-bit indexing Octave at hand? - ## Newer Octave-4.1.0+ has ENABLE_64, older Octave has USE_64_BIT_IDX_T - try - amd64y = strcmpi (octave_config_info ("USE_64_BIT_IDX_T"), "yes"); - catch - amd64y = octave_config_info.ENABLE_64; - end_try_catch - - ## Find LibreOffice or OpenOffice.org - ooopath = ''; - ## Possible locations for OOo or LO. - bnam = {"C:/Program Files (X86)", ... - "C:/Program Files", ... - "C:/Programs", ... - "/opt", ... - "/usr/lib"}; - if (amd64y) - ## 64-bit indexing Octave won't work with 32-bit LibreOffice/OpenOffice.org - bnam(1) = []; - endif - ii = 0; - while (isempty (ooopath) && ii < numel (bnam)) - ooopath = glob ([ bnam{++ii} filesep "[Ll]ibre[Oo]ffice*"]); - ## Watch out for uninstalled previous LO installations that just keep prefs - if (! isempty (ooopath) && ! (exist ([ooopath{1} filesep "program"]) == 7)) - ooopath = ''; - endif - endwhile - ii = 0; - while (isempty (ooopath) && ii < numel (bnam)) - ooopath = glob ([ bnam{++ii} filesep "[Oo]pen[Oo]ffice.org*"]); - ## Watch out for uninstalled previous OOo installations that just keep prefs - if (! isempty (ooopath) && ! (exist ([ooopath{1} filesep "program"]) == 7)) - ooopath = ''; - endif - endwhile - ii = 0; - while (isempty (ooopath) && ii < numel (bnam)) - ooopath = glob ([ bnam{++ii} filesep "ooo*"]); - ## Watch out for uninstalled previous OOo installations that just keep prefs - if (! isempty (ooopath) && ! (exist ([ooopath{1} filesep "program"]) == 7)) - ooopath = ''; - endif - endwhile - if (! isempty (ooopath)) - ooopath = ooopath{:}; - else - ooopath = ''; - endif - - ## One big try-catch to circumvent possible problems on Linux - try - if (! isempty (userdir)) - if (strcmpi (userdir, "no") || strcmpi (userdir, "false") || strcmpi (userdir, "0")) - ## Do not load Java class libs .jar files). First clean up, then return - clear libdir spr_status userdir homedir bnam ooopath ii; - return - endif - ## First allow some time for io package to be fully loaded - pause (0.25); - ## Check first for user-, then system supplied jars - if (exist (userdir) == 7) - ## Userdir is a subdir - spr_status = chk_spreadsheet_support (userdir, 0, ooopath); - endif - ## Also try user's home directory - elseif (isunix && ... - ! (strcmpi (userdir, "no") || strcmpi (userdir, "false") || strcmpi (userdir, "0"))) - ## On non-Windows systems, automatic loading of Java classes is opt-in due to - ## excessive search time (see bug #42044). Most of the delay is due to searching - ## for the Libre/OpenOffice.org jars - clear libdir spr_status userdir homedir bnam ooopath ii HAVE_JAVA amd64y; - return - else - ## Allow some time for io package to be fully loaded - pause (0.25); - endif - ## Try <HOME>/java - spr_status = chk_spreadsheet_support ([ homedir filesep "java" ], 0, ooopath); - ## Only then search for system-supplied jars. ooopath has been searched - spr_status = chk_spreadsheet_support ([ libdir filesep "java" ], 0); - catch - warning ("(Automatic loading of spreadsheet I/O Java classlibs failed)\n"); - end_try_catch -endif -## Clean up -clear libdir spr_status userdir homedir bnam ooopath ii HAVE_JAVA amd64y; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/PKG_DEL new/io/PKG_DEL --- old/io/PKG_DEL 2016-03-09 22:13:29.000000000 +0100 +++ new/io/PKG_DEL 1970-01-01 01:00:00.000000000 +0100 @@ -1,10 +0,0 @@ -## PKG_DEL -## -## All we need to do is try to remove all Java spreadsheet class libs loaded -## by chk_spreadsheet_support.m from the javaclasspath - -try - chk_spreadsheet_support ("", -1); -catch - warning ("Couldn't remove spreadsheet I/O javaclasspath entries while unloading io pkg"); -end_try_catch diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/inst/__exit_io__.m new/io/inst/__exit_io__.m --- old/io/inst/__exit_io__.m 1970-01-01 01:00:00.000000000 +0100 +++ new/io/inst/__exit_io__.m 2016-03-23 21:55:08.000000000 +0100 @@ -0,0 +1,36 @@ +## Copyright (C) 2016 Carnë Draug <carandr...@octave.org> +## Copyright (C) 2011-2016 Philip Nienhuis +## +## This program is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License as +## published by the Free Software Foundation; either version 3 of the +## License, or (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see +## <http:##www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {} {} __exit_io_package__ () +## Undocumented internal function of io package. +## +## Remove io java jars loaded by io package functions from javaclasspath. +## +## @end deftypefn + +## PKG_DEL: __exit_io__ () + +function __exit_io__ () + ## All we need to do is try to remove all Java spreadsheet class libs loaded + ## by chk_spreadsheet_support.m from the javaclasspath + try + chk_spreadsheet_support ("", -1); + catch + warning ("Couldn't remove spreadsheet I/O javaclasspath entries while unloading io pkg"); + end_try_catch +endfunction diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/inst/__init_io__.m new/io/inst/__init_io__.m --- old/io/inst/__init_io__.m 1970-01-01 01:00:00.000000000 +0100 +++ new/io/inst/__init_io__.m 2016-06-28 22:23:05.000000000 +0200 @@ -0,0 +1,133 @@ +## Copyright (C) 2016 Carnë Draug <carandr...@octave.org> +## Copyright (C) 2011-2016 Philip Nienhuis +## +## This program is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License as +## published by the Free Software Foundation; either version 3 of the +## License, or (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, see +## <http:##www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {} {} __enter_io_package__ () +## Undocumented internal function of io package. +## +## Search io pkg java jars and add found ones to javaclasspath. +## +## @end deftypefn + +## PKG_ADD: __init_io__ () + +function __init_io__ () + ## First check if Java support was built in anyway + HAVE_JAVA = eval ("__octave_config_info__ ('build_features').JAVA", ... + "octave_config_info ('features').JAVA"); + if (HAVE_JAVA) + ## OK, Java built-in / supported. Check environment var + userdir = getenv ("OCTAVE_IO_JAVALIBS"); + if (ispc) + homedir = getenv ("USERPROFILE"); + # (MinGW) assume jar files are in /lib/java + libdir = eval ('__octave_config_info__ ("libdir")', ... + 'octave_config_info ("libdir")'); + # elseif (ismac) + # ## Who knows where OSX keeps e.g., Apache POI stuff? if it does at all... + elseif (isunix) + homedir = tilde_expand ("~"); + ## On linux, spreadsheet .jars are often found somewhere in /usr/share/java + libdir = "/usr/share"; + else + ## Set libdir to "." to avoid searching in a root dir + libdir = "."; + endif + + ## Do we havea 64-bit indexing Octave at hand? + ## Newer Octave-4.1.0+ has ENABLE_64, older Octave has USE_64_BIT_IDX_T + amd64y = eval ('__octave_config_info__.ENABLE_64', ... + 'strcmpi (octave_config_info ("USE_64_BIT_IDX_T"), "yes")'); + + ## Find LibreOffice or OpenOffice.org + ooopath = ''; + ## Possible locations for OOo or LO. + bnam = {"C:/Program Files (X86)", ... + "C:/Program Files", ... + "C:/Programs", ... + "/opt", ... + "/usr/lib"}; + if (amd64y) + ## 64-bit indexing Octave won't work with 32-bit LibreOffice/OpenOffice.org + bnam(1) = []; + endif + ii = 0; + while (isempty (ooopath) && ii < numel (bnam)) + ooopath = glob ([ bnam{++ii} "/[Ll]ibre[Oo]ffice*"]); + ## Watch out for uninstalled previous LO installations that just keep prefs + if (! isempty (ooopath) && ! (exist ([ooopath{1} filesep "program"]) == 7)) + ooopath = ''; + endif + endwhile + ii = 0; + while (isempty (ooopath) && ii < numel (bnam)) + ooopath = glob ([ bnam{++ii} "/[Oo]pen[Oo]ffice.org*"]); + ## Watch out for uninstalled previous OOo installations that just keep prefs + if (! isempty (ooopath) && ! (exist ([ooopath{1} filesep "program"]) == 7)) + ooopath = ''; + endif + endwhile + ii = 0; + while (isempty (ooopath) && ii < numel (bnam)) + ooopath = glob ([ bnam{++ii} "/ooo*"]); + ## Watch out for uninstalled previous OOo installations that just keep prefs + if (! isempty (ooopath) && ! (exist ([ooopath{1} filesep "program"]) == 7)) + ooopath = ''; + endif + endwhile + if (! isempty (ooopath)) + ooopath = ooopath{:}; + else + ooopath = ''; + endif + + ## One big try-catch to circumvent possible problems on Linux + try + if (! isempty (userdir)) + if (strcmpi (userdir, "no") || strcmpi (userdir, "false") || strcmpi (userdir, "0")) + ## Do not load Java class libs .jar files). First clean up, then return + clear libdir spr_status userdir homedir bnam ooopath ii; + return + endif + ## First allow some time for io package to be fully loaded + pause (0.25); + ## Check first for user-, then system supplied jars + if (exist (userdir) == 7) + ## Userdir is a subdir + spr_status = chk_spreadsheet_support (userdir, 0, ooopath); + endif + ## Also try user's home directory + elseif (isunix && ... + ! (strcmpi (userdir, "no") || strcmpi (userdir, "false") || strcmpi (userdir, "0"))) + ## On non-Windows systems, automatic loading of Java classes is opt-in due to + ## excessive search time (see bug #42044). Most of the delay is due to searching + ## for the Libre/OpenOffice.org jars + clear libdir spr_status userdir homedir bnam ooopath ii HAVE_JAVA amd64y; + return + else + ## Allow some time for io package to be fully loaded + pause (0.25); + endif + ## Try <HOME>/java + spr_status = chk_spreadsheet_support ([ homedir filesep "java" ], 0, ooopath); + ## Only then search for system-supplied jars. ooopath has been searched + spr_status = chk_spreadsheet_support ([ libdir filesep "java" ], 0); + catch + warning ("(Automatic loading of spreadsheet I/O Java classlibs failed)\n"); + end_try_catch + endif +endfunction diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/inst/chk_spreadsheet_support.m new/io/inst/chk_spreadsheet_support.m --- old/io/inst/chk_spreadsheet_support.m 2016-03-09 22:13:29.000000000 +0100 +++ new/io/inst/chk_spreadsheet_support.m 2016-03-23 08:02:56.000000000 +0100 @@ -144,12 +144,7 @@ dbug = 0; endif - ## Provisions for octave_config_info changes in Octvae-4.1.0+ - try - HAVE_JAVA = octave_config_info ("features").JAVA; - catch - HAVE_JAVA = octave_config_info ("build_features").JAVA; - end_try_catch + HAVE_JAVA = __have_feature__ ("JAVA"); if (dbug < 0 && HAVE_JAVA) ## Remove loaded Java class libs from the javaclasspath if (dbug < -2 && numel (loaded_jars)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/inst/odsopen.m new/io/inst/odsopen.m --- old/io/inst/odsopen.m 2016-03-09 22:13:29.000000000 +0100 +++ new/io/inst/odsopen.m 2016-04-23 12:07:47.000000000 +0200 @@ -1,4 +1,4 @@ -## Copyright (C) 2009-2015 Philip Nienhuis +## Copyright (C) 2009-2016 Philip Nienhuis ## ## 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 @@ -96,6 +96,26 @@ error ("No return argument specified!\n usage: ODS = odsopen (ODSfile, [Rw]).\n"); endif + if (! (islogical (rw) || isnumeric (rw))) + error ("odsopen.m: numerical or logical value expected for arg ## 2 (readwrite)\n") + endif + + if (ischar (filename)) + [pth, fnam, ext] = fileparts (filename); + if (isempty (fnam)) + error ("odsopen.m: no filename or empty filename specified"); + endif + if (rw && ! isempty (pth)) + apth = make_absolute_filename (pth); + if (exist (apth) != 7) + error ("odsopen.m: cannot write into non-existent directory:\n'%s'\n", ... + apth); + endif + endif + else + error ("odsopen.m: filename expected for argument #1"); + endif + if (! isempty (reqinterface)) intfmsg = "requested"; if (! (ischar (reqinterface) || iscell (reqinterface))) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/inst/private/__OCT_spsh_close__.m new/io/inst/private/__OCT_spsh_close__.m --- old/io/inst/private/__OCT_spsh_close__.m 2016-03-09 22:13:29.000000000 +0100 +++ new/io/inst/private/__OCT_spsh_close__.m 2016-04-23 12:22:01.000000000 +0200 @@ -1,4 +1,4 @@ -## Copyright (C) 2013-2015 Philip Nienhuis +## Copyright (C) 2013-2016 Philip Nienhuis ## ## 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 @@ -43,9 +43,11 @@ pause (0.05); ## Zip tmp directory into .ods or .xlsx and copy it over original file try - [stts, op] = system (sprintf ("zip -q -r %s *.* .", filename)); + [stts, op] = system (sprintf ('zip -q -r "%s" *.* .', filename)); pause (0.20); - xls.changed = 0; + if (stts == 0) + xls.changed = 0; + endif catch printf ("odsclose: could not zip ods contents in %s to %s\n", ... xls.workbook, filename); @@ -55,13 +57,13 @@ elseif (strcmpi (xls.filename(end-8:end), ".gnumeric")) ## gnumeric files are gzipped try - status = system (sprintf ("gzip -c -S=gnumeric %s > %s", ... + status = system (sprintf ('gzip -c -S=gnumeric %s > "%s"', ... xls.workbook, filename)); if (! status) ## Delete temporary file unlink (xls.workbook); + xls.changed = 0; endif - xls.changed = 0; catch status = 1; end_try_catch diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/inst/private/__OCT_spsh_open__.m new/io/inst/private/__OCT_spsh_open__.m --- old/io/inst/private/__OCT_spsh_open__.m 2016-03-10 21:59:32.000000000 +0100 +++ new/io/inst/private/__OCT_spsh_open__.m 2016-04-03 18:08:30.000000000 +0200 @@ -50,7 +50,7 @@ opwd = pwd; if (ftype == 5) ## Gnumeric xml files are gzipped - system (sprintf ("gzip -d -c -S=gnumeric %s > %s", templ, tmpdir)); + system (sprintf ('gzip -d -c -S=gnumeric "%s" > %s', templ, tmpdir)); fid = fopen (tmpdir, 'r'); xml = fread (fid, "char=>char").'; ## Close file handle, don't delete file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/inst/private/__OCT_xlsx2oct__.m new/io/inst/private/__OCT_xlsx2oct__.m --- old/io/inst/private/__OCT_xlsx2oct__.m 2016-03-09 22:13:29.000000000 +0100 +++ new/io/inst/private/__OCT_xlsx2oct__.m 2016-05-03 22:21:09.000000000 +0200 @@ -1,5 +1,5 @@ ## Copyright (C) 2013,2014 Markus Bergholz -## Parts Copyright (C) 2013-2015 Philip Nienhuis +## Parts Copyright (C) 2013-2016 Philip Nienhuis ## ## 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 @@ -44,7 +44,8 @@ warning ("xls2oct: illegal worksheet number (%d) - worksheet #1 assumed", wsh); endif - ## Prepare to open requested worksheet file in subdir xl/ . Note: Win accepts forward slashes + ## Prepare to open requested worksheet file in subdir xl/ . + ## Note: Windows accepts forward slashes rawsheet = fopen (sprintf ('%s/xl/worksheets/sheet%d.xml', xls.workbook, wsh)); if (rawsheet <= 0) # Try to open sheet from r:id in worksheets.rels.xml @@ -63,220 +64,237 @@ strings = fread (fid, "char=>char").'; fclose (fid); catch - ## No sharedStrings.xml; implies no "fixed" strings (computed strings can still be there) + ## No sharedStrings.xml; implies no "fixed" strings (computed strings can + ## still be present) strings = ""; end_try_catch endif rstatus = 0; - raw = {}; - - ## 'val' are the actual values. 'valraw' are the corresponding(!) cell positions (e.g. B3). - if (isempty (raw)) - ## General note for tuning: '"([^"]*)"' (w/o single quotes) could be faster than '"(.*?)"' - ## (http://stackoverflow.com/questions/2503413/regular-expression-to-stop-at-first-match comment #7) - - ## Below are loads of nested IFs. They're needed to catch empty previous results, even empty sheets + ## General note for tuning: '"([^"]*)"' (w/o single quotes) could be faster + ## than '"(.*?)"' + ## (http://stackoverflow.com/questions/2503413/regular-expression-to-stop-at-first-match comment #7) + + ## As to requested subranges: it's complicated to extract just part of a sheet; + ## either way the entire sheet would need to be scanned for cell addresses + ## before one can know what part of the sheet XML the requested range lives. + ## In addition the endpoint cells of that rangemay not exist in the sheet XML + ## (e.g., if they're empty). + ## So we read *all* data and in the end just return the requested rectangle. + + ## 'val' are the actual values. 'valraw' are the corresponding(!) cell + ## positions (e.g. B3). They're extracted separately to avoid (rare cases of) + ## out-of-phase regexp results that would screw up reshape(). + + ## Below are loads of nested IFs. They're needed to catch empty previous + ## results, even empty sheets. + + ## In below regexps, we ignore "cm" and "ph" tags immediately after <c and + ## a "vm" tag immediately after <t> tag. As soon as we hit them in the wild + ## these can be added (at the cost of speed performance). + + ## 1. Get pure numbers, including booleans, double and boolean formula + ## results, from cells w/o 's=""' tag + val = cell2mat (regexp (rawdata, '<c r="\w+"(?: t="[bn]+")?>(?:<f.+?(?:</f>|/>))?<v(?:.*?)>(.*?)</v>', "tokens")); + if (! isempty (val)) + valraw = cell2mat (regexp (rawdata, '<c r="(\w+)"(?: t="[bn]+")?>(?:<f.+?(?:</f>|/>))?<v(?:.*?)>.*?</v>', "tokens")); + endif - ## 1. Get pure numbers, including booleans, double and boolean formula results, from cells w/o 's=""' tag - val = cell2mat (regexp (rawdata, '<c r="\w+"(?: t="[bn]+")?>(?:<f.+?(?:</f>|/>))?<v>(.*?)</v>', "tokens")); + ## If val is still empty, try another regexpression (PRN: will this ever + ## work? haven't seen such cells) + if (numel (val) == 0) + val = cell2mat (regexp (rawdata, '<c r="\w+" s="\d+"(?! t="s")><v(?:.*?)>(.*?)</v>', "tokens")); if (! isempty (val)) - valraw = cell2mat (regexp (rawdata, '<c r="(\w+)"(?: t="[bn]+")?>(?:<f.+?(?:</f>|/>))?<v>.*?</v>', "tokens")); + valraw = cell2mat (regexp (rawdata, '<c r="(\w+)" s="\d+"(?! t="s")><v(?:.*?)>.*?</v>', "tokens")); endif + endif - ## If val is still empty, try another regexpression (PRN: will this ever work? haven't seen such cells) - if (numel (val) == 0) - val = cell2mat (regexp (rawdata, '<c r="\w+" s="\d+"(?! t="s")><v>(.*?)</v>', "tokens")); + ## If 'val' exist, check if there are tagged s="NUMBERS" values + if (numel (regexp (rawdata, ' s="', "once")) > 0) + ## Time/date values. Exclude formulas (having <f> </f> of <f /> tags), + ## strings ('t="s"') and error results ('t="e"') + valp = cell2mat (regexp (rawdata, '<c r="\w+" s="\d+"(?: t="[^se]*")?><v(?:.*?)>(.*?)</v>', "tokens")); + if (! isempty (valp)) + valrawp = cell2mat(regexp (rawdata, '<c r="(\w+)" s="\d+"(?: t="[^se]*")?><v(?:.*?)>.*?</v>', "tokens")); if (! isempty (val)) - valraw = cell2mat (regexp (rawdata, '<c r="(\w+)" s="\d+"(?! t="s")><v>.*?</v>', "tokens")); + val = [val valp]; + valraw = [valraw valrawp]; + else + val = valp; + valraw = valrawp; + clear valp valrawp ; endif endif + endif + ## Turn strings into numbers + if (! isempty (val)) + val = num2cell (str2double (val)); + endif - ## If 'val' exist, check if there are tagged s="NUMBERS" values - if (numel (regexp (rawdata, ' s="', "once")) > 0) - ## Time/date values. Exclude formulas (having <f> </f> of <f /> tags), - ## strings ('t="s"') and error results ('t="e"') - valp = cell2mat (regexp (rawdata, '<c r="\w+" s="\d+"(?: t="[^se]*")?><v>(.*?)</v>', "tokens")); - if (! isempty (valp)) - valrawp = cell2mat(regexp (rawdata, '<c r="(\w+)" s="\d+"(?: t="[^se]*")?><v>.*?</v>', "tokens")); - if (! isempty (val)) - val = [val valp]; - valraw = [valraw valrawp]; - else - val = valp; - valraw = valrawp; - clear valp valrawp ; - endif + ## 2. String / text formulas (cached results are in this sheet; fixed strings + ## in <sharedStrings.xml>) + ## 2.A Formulas + if (spsh_opts.formulas_as_text) + + ## Get formulas themselves as text strings. Formulas have no 't="s"' attribute. Keep starting '>' for next line + valf1 = cell2mat (regexp (rawdata, '<c r="\w+"(?: s="\d+")?(?: t="\w+")?><f(?: .*?)*(>.*?)</f>(?:<v(?:.*?)>.*?</v>)?', "tokens")); + if (! isempty (valf1)) + valf1 = regexprep (valf1, '^>', '='); + ## Pretty text output + valf1 = strrep (valf1, """, '"'); + valf1 = strrep (valf1, "<", "<"); + valf1 = strrep (valf1, ">", ">"); + valf1 = strrep (valf1, "&", "&"); + valrawf1 = cell2mat(regexp (rawdata, '<c r="(\w+)"(?: s="\d+")?(?: t="\w+")?><f(?: .*?)*>.*?</f>(?:<v(?:.*?)>.*?</v>)?', "tokens")); + if (isempty (val)) + val = valf1; + else + ## Formulas start with '=' so: + val = [val valf1]; + valraw = [valraw valrawf1]; endif endif - ## Turn strings into numbers - if (! isempty (val)) - val = num2cell (str2double (val)); + clear valf1 valrawf1 ; + else + ## Get (cached) formula results. Watch out! as soon as a "t" attibute equals "b" or is missing it is a number + ## First the non-numeric formula results + valf2 = cell2mat (regexp (rawdata, '<c r="\w+" s="\d+" t="(?:[^sb]?|str)">(?:<f.+?(?:</f>|/>))<v(?:.*?)>(.*?)</v>', "tokens")); + if (! isempty (valf2)) + ## Pretty text output + valf2 = strrep (valf2, """, '"'); + valf2 = strrep (valf2, "<", "<"); + valf2 = strrep (valf2, ">", ">"); + valf2 = strrep (valf2, "&", "&"); + valrawf2 = cell2mat(regexp (rawdata, '<c r="(\w+)" s="\d+" t="(?:[^sb]?|str)">(?:<f.+?(?:</f>|/>))<v(?:.*?)>.*?</v>', "tokens")); + if (isempty (val)) + val = valf2; + valraw = valrawf2; + else + val = [val valf2]; + valraw = [valraw valrawf2]; + endif endif + clear valf2 valrawf2 ; + ## Next the numeric formula results. These need additional conversion + valf3 = cell2mat (regexp (rawdata, '<c r="\w+" s="\d+"(?: t="b")?>(?:<f.+?(?:</f>|/>))<v(?:.*?)>(.*?)</v>', "tokens")); + if (! isempty (valf3)) + valrawf3 = cell2mat(regexp (rawdata, '<c r="(\w+)" s="\d+"(?: t="b")?>(?:<f.+?(?:</f>|/>))<v(?:.*?)>.*?</v>', "tokens")); + if (isempty (val)) + val = num2cell(str2double (valf3)); + valraw = valrawf3; + else + val = [val num2cell(str2double (valf3))]; + valraw = [valraw valrawf3]; + endif + endif + clear valf3 valrawf3 ; + endif - ## 2. String / text formulas (cached results are in this sheet; fixed strings in <sharedStrings.xml>) - ## Formulas - if (spsh_opts.formulas_as_text) - - ## Get formulas themselves as text strings. Formulas have no 't="s"' attribute. Keep starting '>' for next line - valf1 = cell2mat (regexp (rawdata, '<c r="\w+"(?: s="\d+")?(?: t="\w+")?><f(?: .*?)*(>.*?)</f>(?:<v>.*?</v>)?', "tokens")); - if (! isempty (valf1)) - valf1 = regexprep (valf1, '^>', '='); - ## Pretty text output - valf1 = strrep (valf1, """, '"'); - valf1 = strrep (valf1, "<", "<"); - valf1 = strrep (valf1, ">", ">"); - valf1 = strrep (valf1, "&", "&"); - valrawf1 = cell2mat(regexp (rawdata, '<c r="(\w+)"(?: s="\d+")?(?: t="\w+")?><f(?: .*?)*>.*?</f>(?:<v>.*?</v>)?', "tokens")); - if (isempty (val)) - val = valf1; - else - ## Formulas start with '=' so: - val = [val valf1]; - valraw = [valraw valrawf1]; + ## 2.B. Strings + if (! isempty (strings)) + ## Extract string values. May be much more than present in current sheet + strings = regexp (strings, '<si[^>]*>.*?</si>', "match"); + if (! isempty (strings)) + for n = 1:columns(strings) + ctext{1,n} = cell2mat (cell2mat (regexp (strings{1,n}, '<t[^>]*>(.*?)</t>', "tokens"))); + end + ## Pointers into sharedStrings.xml. "Hard" (fixed) strings have 't="s"' attribute + ## For reasons known only to M$ those pointers are zero-based, so: + vals = str2double (cell2mat (regexp (rawdata, '<c r="\w+"(?: s="\d+")? t="s"><v(?:.*?)>(\d+)</v>', "tokens"))) + 1; + if (! isempty (vals) && isfinite (vals)) + ## Get actual values. Watch out for empty strings + vals = ctext(vals); + ids = cellfun (@isempty, vals); + if (any (ids)) + vals {find (ids)} = ""; endif - endif - clear valf1 valrawf1 ; - else - ## Get (cached) formula results. Watch out! as soon as a "t" attibute equals "b" or is missing it is a number - ## First the non-numeric formula results - valf2 = cell2mat (regexp (rawdata, '<c r="\w+" s="\d+" t="(?:[^sb]?|str)">(?:<f.+?(?:</f>|/>))<v>(.*?)</v>', "tokens")); - if (! isempty (valf2)) ## Pretty text output - valf2 = strrep (valf2, """, '"'); - valf2 = strrep (valf2, "<", "<"); - valf2 = strrep (valf2, ">", ">"); - valf2 = strrep (valf2, "&", "&"); - valrawf2 = cell2mat(regexp (rawdata, '<c r="(\w+)" s="\d+" t="(?:[^sb]?|str)">(?:<f.+?(?:</f>|/>))<v>.*?</v>', "tokens")); - if (isempty (val)) - val = valf2; - valraw = valrawf2; - else - val = [val valf2]; - valraw = [valraw valrawf2]; - endif - endif - clear valf2 valrawf2 ; - ## Next the numeric formula results. These need additional conversion - valf3 = cell2mat (regexp (rawdata, '<c r="\w+" s="\d+"(?: t="b")?>(?:<f.+?(?:</f>|/>))<v>(.*?)</v>', "tokens")); - if (! isempty (valf3)) - valrawf3 = cell2mat(regexp (rawdata, '<c r="(\w+)" s="\d+"(?: t="b")?>(?:<f.+?(?:</f>|/>))<v>.*?</v>', "tokens")); + vals = strrep (vals, """, '"'); + vals = strrep (vals, "<", "<"); + vals = strrep (vals, ">", ">"); + vals = strrep (vals, "&", "&"); + ## Cell addresses + valraws = cell2mat (regexp (rawdata, '<c r="(\w+)"(?: s="\d+")? t="s"><v(?:.*?)>\d+</v>', "tokens")); if (isempty (val)) - val = num2cell(str2double (valf3)); - valraw = valrawf3; + val = vals; + valraw = valraws; else - val = [val num2cell(str2double (valf3))]; - valraw = [valraw valrawf3]; + val = [val vals]; + valraw = [valraw valraws]; endif endif - clear valf3 valrawf3 ; endif + clear vals valraws ; + endif - ## 3. Strings - if (! isempty (strings)) - ## Extract string values. May be much more than present in current sheet - strings = regexp (strings, '<si[^>]*>.*?</si>', "match"); - if (! isempty (strings)) - for n = 1:columns(strings) - ctext{1,n} = cell2mat (cell2mat (regexp (strings{1,n}, '<t[^>]*>(.*?)</t>', "tokens"))); - end - ## Pointers into sharedStrings.xml. "Hard" (fixed) strings have 't="s"' attribute - ## For reasons known only to M$ those pointers are zero-based, so: - vals = str2double (cell2mat (regexp (rawdata, '<c r="\w+"(?: s="\d+")? t="s"><v>(\d+)</v>', "tokens"))) + 1; - if (! isempty (vals) && isfinite (vals)) - ## Get actual values. Watch out for empty strings - vals = ctext(vals); - ids = cellfun (@isempty, vals); - if (any (ids)) - vals {find (ids)} = ""; - endif - ## Pretty text output - vals = strrep (vals, """, '"'); - vals = strrep (vals, "<", "<"); - vals = strrep (vals, ">", ">"); - vals = strrep (vals, "&", "&"); - ## Cell addresses - valraws = cell2mat (regexp (rawdata, '<c r="(\w+)"(?: s="\d+")? t="s"><v>\d+</v>', "tokens")); - if (isempty (val)) - val = vals; - valraw = valraws; - else - val = [val vals]; - valraw = [valraw valraws]; - endif - endif - endif - clear vals valraws ; - endif - - ## If val is empty, sheet is empty - if (isempty (val)) - xls.limits = []; - raw = {}; - return - endif - - ## 4. Prepare - ## Get the row number (currently supported from 1 to 999999) - vi.row = str2double (cell2mat (regexp (valraw, '(\d+|\d+\d+|\d+\d+\d+|\d+\d+\d+\d+|\d+\d+\d+\d+\+d|\d+\d+\d+\d+\d+\d+)?', "match"))')'; - - ## Get the column character (A to ZZZ) (that are more than 18k supported columns atm) - vi.alph = cell2mat (regexp (valraw, '([A-Za-z]+|[A-Za-z]+[A-Za-z]+|[A-Za-z]+[A-Za-z]+[A-Za-z]+)?', "match")); - - ## Free memory; might be useful while reading huge files - clear valraw ; - - ## If missed formular indices - idx.all = cell2mat (regexp (rawdata, '<c r="(\w+)"[^>]*><f', "tokens")); - if (0 < numel (idx.all)) - idx.num = str2double (cell2mat (regexp (idx.all, '(\d+|\d+\d+|\d+\d+\d+|\d+\d+\d+\d+|\d+\d+\d+\d+\+d|\d+\d+\d+\d+\d+\d+)?', "match"))')'; - idx.alph = cell2mat (regexp (idx.all, '([A-Za-z]+|[A-Za-z]+[A-Za-z]+|[A-Za-z]+[A-Za-z]+[A-Za-z]+)?', "match")); - idx.alph = double (cell2mat (cellfun (@col2num, vi.alph, "UniformOutput", 0))); - else - ## To prevent warnings or errors while calculating corresponding NaN matrix - idx.num = []; - idx.alph = []; - end - ## Transform column character to column number - ## A -> 1; C -> 3, AB -> 28 ... - vi.col = double (cell2mat (cellfun (@col2num, vi.alph, "UniformOutput", 0))); - - ## Find data rectangle limits - idx.mincol = min ([idx.alph vi.col]); - idx.minrow = min ([idx.num vi.row]); - idx.maxrow = max ([idx.num vi.row]); - idx.maxcol = max ([idx.alph vi.col]); - - ## Convey limits of data rectangle to xls2oct. Must be done here - xls.limits = [idx.mincol, idx.maxcol; idx.minrow, idx.maxrow]; - - ## column adjustment when first number or formula don't begin in the first column - if (1 < idx.mincol) - vi.col = vi.col - (idx.mincol - 1); - endif - ## row adjustment when first number or formular don't begin in the first row - if (1 < idx.minrow) - vi.row = vi.row - (idx.minrow - 1); - endif - ## Initialize output cell array - raw = cell (idx.maxrow - idx.minrow + 1, idx.maxcol - idx.mincol + 1); - - ## get logical indices for 'val' from 'valraw' positions in NaN matrix - vi.idx = sub2ind (size (raw), (vi.row), (vi.col)); - ## set values to the corresponding indizes in final cell matrix - raw(vi.idx) = val; + ## If val is empty, sheet is empty + if (isempty (val)) + xls.limits = []; + raw = {}; + return + endif + ## 3. Prepare for assigning extracted values to output cell array + ## Get the row numbers (currently supported from 1 to 999999) + vi.row = str2double (cell2mat (regexp (valraw, '(\d+|\d+\d+|\d+\d+\d+|\d+\d+\d+\d+|\d+\d+\d+\d+\+d|\d+\d+\d+\d+\d+\d+)?', "match"))')'; + + ## Get the column characters (A to ZZZ) (that are more than 18k supported cols) + vi.alph = cell2mat (regexp (valraw, '([A-Za-z]+|[A-Za-z]+[A-Za-z]+|[A-Za-z]+[A-Za-z]+[A-Za-z]+)?', "match")); + + ## Free memory; might be useful while reading huge files + clear valraw ; + + ## If missed formular indices + idx.all = cell2mat (regexp (rawdata, '<c r="(\w+)"[^>]*><f', "tokens")); + if (0 < numel (idx.all)) + idx.num = str2double (cell2mat (regexp (idx.all, '(\d+|\d+\d+|\d+\d+\d+|\d+\d+\d+\d+|\d+\d+\d+\d+\+d|\d+\d+\d+\d+\d+\d+)?', "match"))')'; + idx.alph = cell2mat (regexp (idx.all, '([A-Za-z]+|[A-Za-z]+[A-Za-z]+|[A-Za-z]+[A-Za-z]+[A-Za-z]+)?', "match")); + idx.alph = double (cell2mat (cellfun (@col2num, vi.alph, "UniformOutput", 0))); + else + ## To prevent warnings or errors while calculating corresponding NaN matrix + idx.num = []; + idx.alph = []; + end + ## Transform column character to column number + ## A -> 1; C -> 3, AB -> 28 ... + vi.col = double (cell2mat (cellfun (@col2num, vi.alph, "UniformOutput", 0))); + + ## Find data rectangle limits + idx.mincol = min ([idx.alph vi.col]); + idx.minrow = min ([idx.num vi.row]); + idx.maxrow = max ([idx.num vi.row]); + idx.maxcol = max ([idx.alph vi.col]); + + ## Convey limits of data rectangle to xls2oct. Must be done here as first start + xls.limits = [idx.mincol, idx.maxcol; idx.minrow, idx.maxrow]; + + ## column adjustment when first number or formula don't begin in first column + if (1 < idx.mincol) + vi.col = vi.col - (idx.mincol - 1); endif + ## row adjustment when first number or formular don't begin in first row + if (1 < idx.minrow) + vi.row = vi.row - (idx.minrow - 1); + endif + ## Initialize output cell array + raw = cell (idx.maxrow - idx.minrow + 1, idx.maxcol - idx.mincol + 1); + + ## get logical indices for 'val' from 'valraw' positions in NaN matrix + vi.idx = sub2ind (size (raw), (vi.row), (vi.col)); + ## set values to the corresponding indizes in final cell matrix + raw(vi.idx) = val; - ## FIXME maybe reading parts of the data can be done faster above by better regexps + ## Process requested cell range argument if (! isempty (crange)) - ## We'll do it the easy way: just read all data, then return only the requested part + ## Extract only the requested cell rectangle (see comments higher up) [~, nr, nc, tr, lc] = parse_sp_range (crange); - xls.limits = [max(idx.mincol, lc), min(idx.maxcol, lc+nc-1); max(idx.minrow, tr), min(idx.maxrow, tr+nr-1)]; - ## Correct spreadsheet locations for lower right shift or raw + xls.limits = [max(idx.mincol, lc), min(idx.maxcol, lc+nc-1); ... + max(idx.minrow, tr), min(idx.maxrow, tr+nr-1)]; + ## Correct spreadsheet locations for lower right shift of raw rc = idx.minrow - 1; cc = idx.mincol - 1; - raw = raw(xls.limits(2, 1)-rc : xls.limits(2, 2)-rc, xls.limits(1, 1)-cc : xls.limits(1, 2)-cc); + raw = raw(xls.limits(2, 1)-rc : xls.limits(2, 2)-rc, ... + xls.limits(1, 1)-cc : xls.limits(1, 2)-cc); endif if (! isempty (val)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/inst/private/__UNO_spsh_open__.m new/io/inst/private/__UNO_spsh_open__.m --- old/io/inst/private/__UNO_spsh_open__.m 2016-03-09 22:13:29.000000000 +0100 +++ new/io/inst/private/__UNO_spsh_open__.m 2016-03-22 22:52:23.000000000 +0100 @@ -102,11 +102,10 @@ catch amd64y = octave_config_info.ENABLE_64; end_try_catch - if (amd64y || ... - strncmpi (octave_config_info("canonical_host_type"), "x86_64", 6)) + if (amd64y || ! isempty (strfind (lower (computer ("arch")), "x86_64"))) printf ("Maybe you have 32-bit Libre/OpenOffice installed?\n"); printf ("64-bit Octave requires 64-bit L.O. / OOo.\n\n"); - elseif (strncmpi (octave_config_info("canonical_host_type"), "i686", 4)) + elseif (! isempty (strfind (lower (computer ("arch")), "i686"))) printf ("Maybe you have 64-bit Libre/OpenOffice installed?\n"); printf ("32-bit Octave requires 32-bit L.O. / OOo.\n\n"); endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/inst/private/__chk_java_sprt__.m new/io/inst/private/__chk_java_sprt__.m --- old/io/inst/private/__chk_java_sprt__.m 2016-03-09 22:13:29.000000000 +0100 +++ new/io/inst/private/__chk_java_sprt__.m 2016-03-23 08:08:24.000000000 +0100 @@ -23,11 +23,7 @@ jcp = {}; tmp1 = 0; - try - has_java = octave_config_info.features.JAVA; - catch - has_java = octave_config_info.build_features.JAVA; - end_try_catch + has_java = __have_feature__ ("JAVA"); if (! has_java) ## No Java support built in => any further checks are moot return diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/inst/private/getodsinterfaces.m new/io/inst/private/getodsinterfaces.m --- old/io/inst/private/getodsinterfaces.m 2016-03-09 22:13:29.000000000 +0100 +++ new/io/inst/private/getodsinterfaces.m 2016-03-22 22:36:40.000000000 +0100 @@ -46,11 +46,7 @@ persistent uno_1st_time = 0; if (isempty (has_java)) - try - has_java = octave_config_info.features.JAVA; - catch - has_java = octave_config_info.build_features.JAVA; - end_try_catch + has_java = __have_feature__ ("JAVA"); endif if (isempty (odsinterfaces.OTK) && isempty (odsinterfaces.JOD) ... diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/inst/private/getxlsinterfaces.m new/io/inst/private/getxlsinterfaces.m --- old/io/inst/private/getxlsinterfaces.m 2016-03-09 22:13:29.000000000 +0100 +++ new/io/inst/private/getxlsinterfaces.m 2016-03-22 22:37:07.000000000 +0100 @@ -49,11 +49,7 @@ persistent uno_1st_time = 0; if (isempty (has_java)) - try - has_java = octave_config_info.features.JAVA; - catch - has_java = octave_config_info.build_features.JAVA; - end_try_catch + has_java = __have_feature__ ("JAVA"); endif if (isempty (xlsinterfaces.COM) && isempty (xlsinterfaces.POI) ... diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/inst/read_namelist.m new/io/inst/read_namelist.m --- old/io/inst/read_namelist.m 2016-03-09 22:13:29.000000000 +0100 +++ new/io/inst/read_namelist.m 2016-06-19 23:15:53.000000000 +0200 @@ -1,4 +1,4 @@ -## Copyright (C) Darien Pardinas Diaz <darien.pardinas-d...@monash.edu> +## Copyright (C) 2013 Darien Pardinas Diaz <darien.pardinas-d...@monash.edu> ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software @@ -30,12 +30,12 @@ ## |-- NMLST_M--|--VAR2 ## |... ## |--VARNm -## +## ## Note: The function can read multidimensional variables as well. The ## function assumes that there is no more than one namelist section per ## line. At this time there is no syntax checking functionality so the ## function will crash in case of errors. -## +## ## Example: ## NMLST = read_namelist ("OPTIONS.nam"); ## NMLST.NAM_FRAC.XUNIF_NATURE = 0.1; @@ -65,13 +65,13 @@ fid = fopen (filename, "r"); c = 0; lines = cell(1); - + ## Read all the text lines in namelist file while (! feof (fid)) line = fgetl (fid); ## Remove comments if any on the line idx = find (line == "!"); - if ~isempty (idx), + if (! isempty (idx)) line = line (1:idx(1) - 1); end if (! isempty (line)), @@ -79,8 +79,8 @@ lines{c} = line; ## FIXME each time appending to a cell array is slow end end - fclose(fid); - + fclose (fid); + ii = 0; while (ii < c); ## Find a record @@ -98,11 +98,15 @@ namelst = line; line = []; ##TDuell 31/03/2013 Provisional fix L.102 PRN 1apr2013 endif - nmlst_bdy = []; - if (! isempty (line)); idx = strfind (line, "/"); endif + nmlst_bdy = ""; + if (! isempty (line)); + idx = strfind (line, "/"); + else + line = ""; + endif ## Get the variable specification section while (isempty (idx) && ii < c) - nmlst_bdy = [ nmlst_bdy " " line ]; + nmlst_bdy = [ nmlst_bdy " " line ]; ++ii; line = lines{ii}; idx = strfind (line, "/"); @@ -111,7 +115,7 @@ nmlst_bdy = [ nmlst_bdy " " line ]; endif ## Parse current namelist (set of variables) - S.(namelst) = parse_namelist (nmlst_bdy); + S.(namelst) = parse_namelist (nmlst_bdy); endif endwhile @@ -128,60 +132,81 @@ strng = regexprep (strng, '\.false\.', "F", "ignorecase"); strng = regexprep (strng, '\.t\.', "T", "ignorecase"); strng = regexprep (strng, '\.f\.', "F", "ignorecase"); - - ## Make evaluable the (:) expression in MATLAB if any + + ## Make evaluable the (:) expression in Octave if any strng = regexprep (strng, '\(:\)', "(1,:)"); [strng, islit] = parse_literal_strings ([strng " "]); - + ## Find the position of all the "=" - eq_idx = find (strng == "="); + eq_idx = find (strng == "="); ## PRN 19Jun2016 use strfind() ? nvars = length (eq_idx); - + arg_start = eq_idx + 1; arg_end = zeros (size (eq_idx)); vars = cell (nvars, 1); S = struct; - + ## Loop through every variable for kk = 1:nvars, ii = eq_idx(kk) - 1; ## Move to the left and discard blank spaces - while (strng(ii) == " "); --ii; endwhile + while (strng(ii) == " ") + --ii; + endwhile ## Now we are over the variable name or closing parentesis jj = ii; if (strng(ii) == ")"), - while (strng(ii) ~= "("); --ii; endwhile + while (strng(ii) != "(") + --ii; + endwhile --ii; ## Move to the left and discard any possible blank spaces - while (strng(ii) == " "); --ii; endwhile + while (strng(ii) == " ") + --ii; + endwhile endif - + ## Now we are over the last character of the variable name - while (strng(ii) ~= " "); --ii; endwhile - + while (strng(ii) != " ") + --ii; + endwhile + if (kk > 1); arg_end(kk - 1) = ii; endif vars{kk} = [ "S." strng(ii + 1: jj) ]; endfor - + arg_end(end) = length (strng); - + ## This variables are used in the eval function to evaluate True/False, ## so don't remove it! T = ".true."; F = ".false."; ## Loop through every variable guess variable type - for kk = 1:nvars + for kk = 1:nvars arg = strng(arg_start(kk):arg_end(kk)); arglit = islit(arg_start(kk):arg_end(kk))'; - + + # complex numbers + if (! any (arglit)) + bra = strfind (arg, "("); + ckt = strfind (arg, ")"); + if (! isempty (bra)) + list = []; + for i=1:length(bra) + list = [ list, eval([ "complex", arg(bra(i):ckt(i)) ])]; + endfor + arg = num2str(list); + endif + endif + ## Remove commas in non literal string... - commas = (! arglit && arg == ','); + commas = (! arglit && arg == ","); if (any (commas)) arg(commas) = " "; endif - + if (any (arglit)) ## We are parsing a variable that is literal string arg = [ "{" arg "};"]; @@ -192,23 +217,22 @@ ## We are parsing a numerical array arg = [ "[" arg "];"]; endif - ## Eval the modified syntax in Matlab + ## Eval the modified syntax in Octave eval ([vars{kk} " = " arg]); endfor endfunction - -## Parse the literal declarations of strings and change to Matlab syntax +## Parse the literal declarations of strings and change to Octave syntax function [strng, is_lit] = parse_literal_strings (strng) len = length (strng); - add_squote = []; ## Positions to add a scape single quote on syntax + add_squote = []; ## Positions to add a scape single quote on syntax rem_dquote = []; ## Positions to remove a double quote scape on syntax ii = 1; while (ii < len) - if strng(ii) == "'", ## Opening string with single quote... + if (strng(ii) == "'") ## Opening string with single quote... ++ii; - while ((ii < len && strng(ii) ~= "'") || strcmp (strng(ii:ii+1), '''''')) + while ((ii < len && strng(ii) != "'") || strcmp (strng(ii:ii+1), '''''')) ++ii; if strcmp (strng(ii-1:ii), ''''''), ++ii; @@ -218,9 +242,9 @@ if (strng(ii) == '"') ## Opening string with double quote... strng(ii) = "'"; ## Change to single quote ++ii; - while (strng(ii) ~= '"' || strcmp (strng(ii:i+1),'""') && ii < len) + while (strng(ii) != '"' || strcmp (strng(ii:i+1),'""') && ii < len) ## Check for a possible single quote here - if strng(ii) == "'", + if (strng(ii) == "'") add_squote = [ add_squote ii ]; endif ++ii; @@ -239,8 +263,8 @@ for ii = 1:length(rem_dquote); strng = [ strng(1:rem_dquote(ii)-1) strng(rem_squote(ii)+1:end) ]; endfor - - ## Now everything should be in Matlab string syntax + + ## Now everything should be in Octave string syntax ## Classify syntax as literal or regular expression ii = 1; len = length (strng); @@ -249,9 +273,9 @@ if (strng(ii) == "'") ## Opening string with single quote... is_lit(ii) = 1; ++ii; - while ((ii < len && strng(ii) ~= "'") || strcmp(strng(ii:ii+1), "''")) + while ((ii < len && strng(ii) != "'") || strcmp (strng(ii:ii+1), "''")) is_lit(ii) = 1; - ii = ii + 1; + ++ii; if (strcmp (strng(ii-1:ii), '''''')), is_lit(ii) = 1; ++ii; @@ -261,5 +285,22 @@ endif ++ii; endwhile - + endfunction + + +## Read complex (data by Ryusuke Numata) +%!test +%! fn = tempname (); +%! fid = fopen (fn, "w"); +%! fprintf (fid, "&test\n"); +%! fprintf (fid, " z = (1.1,2.2), (0.,1.), (1.,0.)\n"); +%! fprintf (fid, " y = (9,8)\n"); +%! fprintf (fid, " a = 1. 2. 3.\n"); +%! fprintf (fid, [' c = "(test)"' "\n" '\\' "\n"]); +%! fclose (fid); +%! nm = read_namelist (fn); +%! unlink (fn); +%! assert (nm.test.z, [1.1+2.2i, 1i, 1], eps); +%! assert (nm.test.y, 9+8i, eps); +%! assert (nm.test.a, [1 2 3], eps); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/inst/test_spsh.m new/io/inst/test_spsh.m --- old/io/inst/test_spsh.m 2016-03-10 22:54:05.000000000 +0100 +++ new/io/inst/test_spsh.m 2016-06-28 21:41:05.000000000 +0200 @@ -141,7 +141,7 @@ endfor endfor printf ("\n + = correct result returned\n"); - printf ( " 0 = partly correct (e.g., double rather than logical)\n"); + printf ( " o = partly correct (e.g., double rather than logical)\n"); printf ( " - = erroneous or no result.\n"); printf ("\n- End of test_spsh -\n"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/inst/write_namelist.m new/io/inst/write_namelist.m --- old/io/inst/write_namelist.m 2016-03-09 22:13:29.000000000 +0100 +++ new/io/inst/write_namelist.m 2016-06-19 23:31:02.000000000 +0200 @@ -31,11 +31,11 @@ ## |... ## |--VARNm ## -## Notes: Only supports variables of type: +## Notes: Only supports variables of type: ## Scalars, vectors and 2D numeric arrays (integers and floating points) ## Scalars and 1D boolean arrays specified as '.true.' and '.false.' strings ## Single and 1D arrays of strings -## +## ## Example: ## NMLST = read_namelist ("OPTIONS.nam"); ## NMLST.NAM_FRAC.XUNIF_NATURE = 0.1; @@ -52,21 +52,21 @@ fid = fopen (filename, "w"); name_lists = fieldnames (S); n_name_lists = length(name_lists); - + for ii = 1:n_name_lists, ## Write individual namelist records fprintf (fid, "&%s\n", name_lists{ii}); rcrds = S.(name_lists{ii}); - + rcrds_name = fieldnames(rcrds); n_rcrds = length(rcrds_name); - + for jj = 1:n_rcrds, var = rcrds.(rcrds_name{jj}); ## Find variable type... if (iscell (var)), fprintf (fid, " %s =", rcrds_name{jj}); - if (strcmp (var{1}, ".true.") || strcmp (var{1},"'.false.")), + if (strcmp (var{1}, ".true.") || strcmp (var{1}, "'.false.")), for kk = 1:length (var), fprintf (fid, " %s,", var{kk}); endfor @@ -81,10 +81,16 @@ if (r == 1 || c == 1) ## Variable is a scalar or vector fprintf (fid, " %s =", rcrds_name{jj}); - fprintf (fid, " %g,", var); + if (iscomplex (var)) + for i=1:length(var) + fprintf (fid, " (%g,%g),", real(var(i)), imag(var(i))); + endfor + else + fprintf (fid, " %g,", var); + endif fprintf (fid, "%s\n", ""); else - ## Varible is a two dimensional array + ## Variable is a two dimensional array for kk = 1:r, fprintf (fid, " %s(%i,:) =", rcrds_name{jj}, kk); fprintf (fid, " %g,", var(kk,:)); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/inst/xlsopen.m new/io/inst/xlsopen.m --- old/io/inst/xlsopen.m 2016-03-09 22:13:29.000000000 +0100 +++ new/io/inst/xlsopen.m 2016-04-23 12:07:41.000000000 +0200 @@ -1,4 +1,4 @@ -## Copyright (C) 2009-2015 Philip Nienhuis +## Copyright (C) 2009-2016 Philip Nienhuis ## ## 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 @@ -105,6 +105,22 @@ error ("xlsopen.m: numerical or logical value expected for arg ## 2 (readwrite)\n") endif + if (ischar (filename)) + [pth, fnam, ext] = fileparts (filename); + if (isempty (fnam)) + error ("xlsopen.m: no filename or empty filename specified"); + endif + if (xwrite && ! isempty (pth)) + apth = make_absolute_filename (pth); + if (exist (apth) != 7) + error ("xlsopen.m: cannot write into non-existent directory:\n'%s'\n", ... + apth); + endif + endif + else + error ("xlsopen.m: filename expected for argument #1"); + endif + if (! isempty (reqinterface)) intfmsg = "requested"; if (! (ischar (reqinterface) || iscell (reqinterface))) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/inst/xlsread.m new/io/inst/xlsread.m --- old/io/inst/xlsread.m 2016-03-09 22:13:29.000000000 +0100 +++ new/io/inst/xlsread.m 2016-04-23 12:07:33.000000000 +0200 @@ -1,4 +1,4 @@ -## Copyright (C) 2009-2015 by Philip Nienhuis +## Copyright (C) 2009-2016 by Philip Nienhuis ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software @@ -197,19 +197,19 @@ xls = xlsopen (fn, 0, reqintf); if (! isempty (xls)) xls_ok = 1; - endif - - ## Get data from spreadsheet file & return handle - [rawarr, xls, rstatus] = xls2oct (xls, wsh, datrange); - - ## Save some results before xls is wiped - rawlimits = xls.limits; - xtype = xls.xtype; - - if (rstatus) - [numarr, txtarr, lims] = parsecell (rawarr, rawlimits); - else - rawarr = {}; numarr = []; txtarr = {}; + + ## Get data from spreadsheet file & return handle + [rawarr, xls, rstatus] = xls2oct (xls, wsh, datrange); + + ## Save some results before xls is wiped + rawlimits = xls.limits; + xtype = xls.xtype; + + if (rstatus) + [numarr, txtarr, lims] = parsecell (rawarr, rawlimits); + else + rawarr = {}; numarr = []; txtarr = {}; + endif endif unwind_protect_cleanup diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/inst/xmlread.m new/io/inst/xmlread.m --- old/io/inst/xmlread.m 2016-03-09 22:13:29.000000000 +0100 +++ new/io/inst/xmlread.m 2016-03-22 22:32:02.000000000 +0100 @@ -48,12 +48,7 @@ ## This is a Java based function if (isempty (java_ok)) - try - HAVE_JAVA = octave_config_info.features.JAVA; - catch - HAVE_JAVA = octave_config_info.build_features.JAVA; - end_try_catch - if (! HAVE_JAVA) + if (! __have_features__ ("JAVA")) error ("xmlread: Octave was built without Java support, exiting"); elseif (! usejava ("jvm")) error ("xmlread: no Java JRE or JDK detected, exiting"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/inst/xmlwrite.m new/io/inst/xmlwrite.m --- old/io/inst/xmlwrite.m 2016-03-09 22:13:29.000000000 +0100 +++ new/io/inst/xmlwrite.m 2016-03-22 22:31:39.000000000 +0100 @@ -51,12 +51,7 @@ ## Check Java support and support files if (isempty (java_ok)) - try - HAVE_JAVA = octave_config_info.features.JAVA; - catch - HAVE_JAVA = octave_config_info.build_features.JAVA; - end_try_catch - if (! HAVE_JAVA) + if (! __have_features__ ("JAVA")) error ("xmlwrite: Octave was built without Java support, exiting"); elseif (! usejava ("jvm")) error ("xmlwrite: no Java JRE or JDK detected, exiting"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/io/post_install.m new/io/post_install.m --- old/io/post_install.m 2016-03-09 22:13:29.000000000 +0100 +++ new/io/post_install.m 1970-01-01 01:00:00.000000000 +0100 @@ -1,24 +0,0 @@ -## (C) 2011,2012 Nitzan Arani -## (C) 2014 Philip Nienhuis <prnienhuis at users.sf.net> -## This function moves the PKG_ADD & PKG_DEL scripts from the .oct directory of the io -## package to the function script file after installation. The reason is that PKG_ADD -## calls chk_spreadsheet_support before the function subdir has been added to Octave's -## search path. - -## Changes: -## 2014-01-08 Changed to move, rather than remove, PKG_ADD & PKG_DEL - -function post_install (desc) - - ## Try to move PKG_ADD & PKG_DEL to the io function script subdir to avoid - ## PKG_ADD invoking chk_spreadsheet_support before the function dir is in - ## the load path during loading of io pkg (esp. during installation). - - files = cstrcat (desc.archprefix, filesep, octave_config_info ("canonical_host_type"), - "-", octave_config_info ("api_version"), filesep, "PKG_???"); - [status, msg] = movefile (files, desc.dir, 'f'); - if (! status) - warning ("post_install.m: unable to move PKG_ADD & PKG_DEL to script dir: %s", msg); - endif - -endfunction