./PaxHeaders.5973/io-2.4.100000644000000000000000000000013213226215407011753 xustar0030 mtime=1515789063.608155636 30 atime=1515789065.028183488 30 ctime=1515789065.028183488 io-2.4.10/0000755000175000017500000000000013226215407012133 5ustar00olafolaf00000000000000io-2.4.10/PaxHeaders.5973/INDEX0000644000000000000000000000013213226215407012465 xustar0030 mtime=1515789063.552154538 30 atime=1515789063.552154538 30 ctime=1515789065.028183488 io-2.4.10/INDEX0000644000175000017500000000142713226215407012731 0ustar00olafolaf00000000000000io >> Input from and output to external formats File I/O append_save fexist rfsearch Miscellaneous conversion functions object2json pch2mat read_namelist utf82unicode unicode2utf8 write_namelist CSV file functions cell2csv csv2cell csvconcat csvexplode DBF I/O dbfread dbfwrite XML I/O xmlread xmlwrite getxmlattv getxmlnode tidyxml Spreadsheet I/O user functions for MS-Excel oct2xls xls2oct xlsclose xlsfinfo xlsopen xlsread xlswrite Spreadsheet I/O user functions for OpenOffice.org Calc oct2ods ods2oct odsclose odsfinfo odsopen odsread odswrite Spreadsheet utility functions calccelladdress chk_spreadsheet_support parsecell Spreadsheet function test scripts io_ods_testscript io_xls_testscript test_spsh io-2.4.10/PaxHeaders.5973/Makefile0000644000000000000000000000013213226215407013333 xustar0030 mtime=1515789063.552154538 30 atime=1515789063.552154538 30 ctime=1515789065.028183488 io-2.4.10/Makefile0000644000175000017500000002066413226215407013603 0ustar00olafolaf00000000000000## Copyright 2015-2016 Carnë Draug ## Copyright 2015-2016 Oliver Heimlich ## Copyright 2017 Julien Bect ## Copyright 2017 Olaf Till ## ## Copying and distribution of this file, with or without modification, ## are permitted in any medium without royalty provided the copyright ## notice and this notice are preserved. This file is offered as-is, ## without any warranty. ## Some basic tools (can be overriden using environment variables) SED ?= sed TAR ?= tar GREP ?= grep CUT ?= cut TR ?= tr ## Note the use of ':=' (immediate set) and not just '=' (lazy set). ## http://stackoverflow.com/a/448939/1609556 package := $(shell $(GREP) "^Name: " DESCRIPTION | $(CUT) -f2 -d" " | \ $(TR) '[:upper:]' '[:lower:]') version := $(shell $(GREP) "^Version: " DESCRIPTION | $(CUT) -f2 -d" ") ## These are the paths that will be created for the releases. target_dir := target release_dir := $(target_dir)/$(package)-$(version) release_tarball := $(target_dir)/$(package)-$(version).tar.gz html_dir := $(target_dir)/$(package)-html html_tarball := $(target_dir)/$(package)-html.tar.gz ## Using $(realpath ...) avoids problems with symlinks due to bug ## #50994 in Octaves scripts/pkg/private/install.m. But at least the ## release directory above is needed in the relative form, for 'git ## archive --format=tar --prefix=$(release_dir). real_target_dir := $(realpath .)/$(target_dir) installation_dir := $(real_target_dir)/.installation package_list := $(installation_dir)/.octave_packages install_stamp := $(installation_dir)/.install_stamp ## These can be set by environment variables which allow to easily ## test with different Octave versions. ifndef OCTAVE OCTAVE := octave endif OCTAVE := $(OCTAVE) --no-gui --silent --no-history --norc MKOCTFILE ?= mkoctfile ## Command used to set permissions before creating tarballs FIX_PERMISSIONS ?= chmod -R a+rX,u+w,go-w,ug-s ## Detect which VCS is used vcs := $(if $(wildcard .hg),hg,$(if $(wildcard .git),git,unknown)) ifeq ($(vcs),hg) release_dir_dep := .hg/dirstate endif ifeq ($(vcs),git) release_dir_dep := .git/index endif ## .PHONY indicates targets that are not filenames ## (https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html) .PHONY: help ## make will display the command before runnning them. Use @command ## to not display it (makes specially sense for echo). help: @echo "Targets:" @echo " dist - Create $(release_tarball) for release." @echo " html - Create $(html_tarball) for release." @echo " release - Create both of the above and show md5sums." @echo " install - Install the package in $(installation_dir), where it is not visible in a normal Octave session." @echo " check - Execute package tests." @echo " doctest - Test the help texts with the doctest package." @echo " run - Run Octave with the package installed in $(installation_dir) in the path." @echo " clean - Remove everything made with this Makefile." ## ## Recipes for release tarballs (package + html) ## .PHONY: release dist html clean-tarballs clean-unpacked-release ## To make a release, build the distribution and html tarballs. release: dist html md5sum $(release_tarball) $(html_tarball) @echo "Upload @ https://sourceforge.net/p/octave/package-releases/new/" @echo " and note the changeset the release corresponds to" ## dist and html targets are only PHONY/alias targets to the release ## and html tarballs. dist: $(release_tarball) html: $(html_tarball) ## An implicit rule with a recipe to build the tarballs correctly. %.tar.gz: % $(TAR) -c -f - --posix -C "$(target_dir)/" "$(notdir $<)" | gzip -9n > "$@" clean-tarballs: @echo "## Cleaning release tarballs (package + html)..." -$(RM) $(release_tarball) $(html_tarball) @echo ## Create the unpacked package. ## ## Notes: ## * having ".hg/dirstate" (or ".git/index") as a prerequesite means it is ## only rebuilt if we are at a different commit. ## * the variable RM usually defaults to "rm -f" ## * having this recipe separate from the one that makes the tarball ## makes it easy to have packages in alternative formats (such as zip) ## * note that if a commands needs to be run in a specific directory, ## the command to "cd" needs to be on the same line. Each line restores ## the original working directory. $(release_dir): $(release_dir_dep) -$(RM) -r "$@" ifeq (${vcs},hg) hg archive --exclude ".hg*" --type files "$@" endif ifeq (${vcs},git) git archive --format=tar --prefix="$@/" HEAD | $(TAR) -x $(RM) "$@/.gitignore" endif ## Don't fall back to run the supposed necessary contents of ## 'bootstrap' here. Users are better off if they provide ## 'bootstrap'. Administrators, checking build reproducibility, can ## put in the missing 'bootstrap' file if they feel they know its ## necessary contents. ifneq (,$(wildcard src/bootstrap)) cd "$@/src" && ./bootstrap && $(RM) -r "autom4te.cache" endif ## Uncomment this if your src/Makefile.in has these targets for ## pre-building something for the release (e.g. documentation). # cd "$@/src" && ./configure && $(MAKE) prebuild && \ # $(MAKE) distclean && $(RM) Makefile ## ${FIX_PERMISSIONS} "$@" run_in_place = $(OCTAVE) --eval ' pkg ("local_list", "$(package_list)"); ' \ --eval ' pkg ("load", "$(package)"); ' html_options = --eval 'options = get_html_options ("octave-forge");' ## Uncomment this for package documentation. # html_options = --eval 'options = get_html_options ("octave-forge");' \ # --eval 'options.package_doc = "$(package).texi";' $(html_dir): $(install_stamp) $(RM) -r "$@"; $(run_in_place) \ --eval ' pkg load generate_html; ' \ $(html_options) \ --eval ' generate_package_html ("$(package)", "$@", options); '; $(FIX_PERMISSIONS) "$@"; clean-unpacked-release: @echo "## Cleaning unpacked release tarballs (package + html)..." -$(RM) -r $(release_dir) $(html_dir) @echo ## ## Recipes for installing the package. ## .PHONY: install clean-install octave_install_commands = \ ' llist_path = pkg ("local_list"); \ mkdir ("$(installation_dir)"); \ load (llist_path); \ local_packages(cellfun (@ (x) strcmp ("$(package)", x.name), local_packages)) = []; \ save ("$(package_list)", "local_packages"); \ pkg ("local_list", "$(package_list)"); \ pkg ("prefix", "$(installation_dir)", "$(installation_dir)"); \ pkg ("install", "-local", "-verbose", "$(release_tarball)"); ' ## Install unconditionally. Maybe useful for testing installation with ## different versions of Octave. install: $(release_tarball) @echo "Installing package under $(installation_dir) ..." $(OCTAVE) --eval $(octave_install_commands) touch $(install_stamp) ## Install only if installation (under target/...) is not current. $(install_stamp): $(release_tarball) @echo "Installing package under $(installation_dir) ..." $(OCTAVE) --eval $(octave_install_commands) touch $(install_stamp) clean-install: @echo "## Cleaning installation under $(installation_dir) ..." -$(RM) -r $(installation_dir) @echo ## ## Recipes for testing purposes ## .PHONY: run doctest check ## Start an Octave session with the package directories on the path for ## interactice test of development sources. run: $(install_stamp) $(run_in_place) --persist ## Test example blocks in the documentation. Needs doctest package ## https://octave.sourceforge.io/doctest/index.html doctest: $(install_stamp) $(run_in_place) --eval 'pkg load doctest;' \ --eval "targets = '$(shell (ls inst; ls src | $(GREP) .oct) | $(CUT) -f2 -d@ | $(CUT) -f1 -d.)';" \ --eval "targets = strsplit (targets, ' '); doctest (targets);" ## Test package. octave_test_commands = \ ' dirs = {"inst", "src"}; \ dirs(cellfun (@ (x) ! isdir (x), dirs)) = []; \ if (isempty (dirs)) error ("no \"inst\" or \"src\" directory"); exit (1); \ else __run_test_suite__ (dirs, {}); endif ' ## the following works, too, but provides no overall summary output as ## __run_test_suite__ does: ## ## else cellfun (@runtests, horzcat (cellfun (@ (dir) ostrsplit (([~, dirs] = system (sprintf ("find %s -type d", dir))), "\n\r", true), dirs, "UniformOutput", false){:})); endif ' check: $(install_stamp) $(run_in_place) --eval $(octave_test_commands) ## ## CLEAN ## .PHONY: clean clean: clean-tarballs clean-unpacked-release clean-install @echo "## Removing target directory (if empty)..." -rmdir $(target_dir) @echo @echo "## Cleaning done" @echo io-2.4.10/PaxHeaders.5973/inst0000644000000000000000000000013213226215407012573 xustar0030 mtime=1515789063.608155636 30 atime=1515789065.028183488 30 ctime=1515789065.028183488 io-2.4.10/inst/0000755000175000017500000000000013226215407013110 5ustar00olafolaf00000000000000io-2.4.10/inst/PaxHeaders.5973/xmlread.m0000644000000000000000000000013213226215407014462 xustar0030 mtime=1515789063.604155557 30 atime=1515789063.604155557 30 ctime=1515789065.028183488 io-2.4.10/inst/xmlread.m0000644000175000017500000000665713226215407014740 0ustar00olafolaf00000000000000## Copyright (C) 2015-2017 Pantxo Diribarne ## ## 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{node} =} xmlread (@var{fname}) ## ## Parse an xml file @var{fname} using Xerces Java library and return ## a Java object representing an xml DOM document. ## ## Octave does not ship with a Xerces library so you should take care ## of adding the required .jar files to your java_path, e.g: ## ## @example ## @code{javaaddpath ("/path/to/xerces-2_11_0/xercesImpl.jar");} ## @code{javaaddpath ("/path/to/xerces-2_11_0/xml-apis.jar");} ## @end example ## ## xmlread will check for Java support and proper xerces Java libraries ## in the javaclasspath until the check passes, or if it is called without ## arguments. In the latter case it will return the found xerces entries ## in the javaclasspath and xerces version to standard output. ## ## @seealso{xmlwrite} ## @end deftypefn function node = xmlread (fname) persistent java_ok = []; if (nargin < 1) ## Reset Java support check results java_ok = []; elseif (nargin != 1 || ! ischar (fname)) print_usage () endif ## This is a Java based function if (isempty (java_ok)) if (! __have_feature__ ("JAVA")) error ("xmlread: Octave was built without Java support, exiting"); elseif (! usejava ("jvm")) error ("xmlread: no Java JRE or JDK detected, exiting"); endif ## Default verbosity for Java lib search vrbs = 0; if (nargin < 1) vrbs = 3; endif ## Check if required Java class libs are in the javaclasspath chk = __XMLrw_chk_sprt__ (javaclasspath ("-all"), vrbs); if (chk) java_ok = 1; ## If xmlread was called w/o args it means reset .jar search results if (nargin < 1) node = []; return endif else error ("xmlread: no xercesImpl.jar and/or xml-apis.jar > v2.11.0 in \ javaclasspath"); endif endif ## Checks OK, read XML file try parser = javaObject ("org.apache.xerces.parsers.DOMParser"); catch disp (lasterr ()); error ("xmlread: couldn't load Xerces parser object"); end_try_catch try parser.parse (make_absolute_filename (fname)); node = parser.getDocument (); catch disp (lasterr ()); error ("xmlread: couldn't load and parse \"%s\"", fname); end_try_catch endfunction %!demo %! ## Create an svg file, which is nothing but an xml tree %! tk = graphics_toolkit (); %! graphics_toolkit ("fltk"); %! hf = figure (); %! sombrero (); %! fname = [tempname(), ".svg"]; %! print (fname); %! close (hf) %! graphics_toolkit (tk); %! %! ## Read the svg file and check the root node is named "svg" %! dom = xmlread (fname); %! if (dom.hasChildNodes ()) %! root_node = dom.getChildNodes ().item (0); %! printf ("The name of the root node is \"%s\"\n", ... %! char (root_node.getNodeName ())) %! endif io-2.4.10/inst/PaxHeaders.5973/xlsread.m0000644000000000000000000000013213226215407014470 xustar0030 mtime=1515789063.604155557 30 atime=1515789063.604155557 30 ctime=1515789065.028183488 io-2.4.10/inst/xlsread.m0000644000175000017500000002652313226215407014740 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 ## 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [@var{numarr}, @var{txtarr}, @var{rawarr}, @var{limits}] = xlsread (@var{filename}) ## @deftypefnx {Function File} [@var{numarr}, @var{txtarr}, @var{rawarr}, @var{limits}] = xlsread (@var{filename}, @var{wsh}) ## @deftypefnx {Function File} [@var{numarr}, @var{txtarr}, @var{rawarr}, @var{limits}] = xlsread (@var{filename}, @var{range}) ## @deftypefnx {Function File} [@var{numarr}, @var{txtarr}, @var{rawarr}, @var{limits}] = xlsread (@var{filename}, @var{wsh}, @var{range}) ## @deftypefnx {Function File} [@var{numarr}, @var{txtarr}, @var{rawarr}, @var{limits}, @var{extout}] = xlsread (@var{filename}, @var{wsh}, @var{range}, @var{options}, @dots{}) ## ## Read data contained in range @var{range} from worksheet @var{wsh} ## in Excel spreadsheet file @var{filename}. Gnumeric files can also ## be read. ## ## Return argument @var{numarr} contains the numeric data, optional ## return arguments @var{txtarr} and @var{rawarr} contain text strings ## and the raw spreadsheet cell data, respectively. Return argument ## @var{limits} contains the outer column/row numbers of the read ## spreadsheet range where @var{numarr}, @var{txtarr} and @var{rawarr} ## have come from (remember, xlsread trims outer rows and columns). ## ## If @var{filename} does not contain any directory, the file is ## assumed to be in the current directory. The filename extension ## (.xls or .xlsx) must be included in the file name; when using the ## COM interface all file formats can be read that are supported by the ## locally installed MS-Excel version (e.g., wk1, csv, dbf, .xlsm, etc.). ## The same holds for UNO (OpenOffice.org or LibreOffice). ## ## @var{range} is expected to be a regular spreadsheet range format, ## or "" (empty string, indicating all data in a worksheet). ## If no range is specified the occupied cell range will have to be ## determined behind the scenes first; this can take some time for the ## Java-based interfaces (but the results may be more reliable than ## that of ActiveX/COM). Instead of a spreadsheet range a Named range ## defined in the spreadsheet file can be used as well. In that case ## the Named range should be specified as 3rd argument and the value ## of 2nd argument @var{wsh} doesn't matter as the worksheet associated ## with the specified Named range will be used. ## ## @var{wsh} is either numerical or text; in the latter case it is ## case-sensitive and it may be max. 31 characters long. ## Note that in case of a numerical @var{wsh} this number refers to the ## position in the worksheet stack, counted from the left in an Excel ## window. The default is numerical 1, i.e. corresponding to the ## leftmost worksheet tab in the spreadsheet file. ## ## If only the first argument is specified, xlsread will try to read ## all contents (as if a range of @'' (empty string) was specified) ## from the first = leftmost (or the only) worksheet ## ## If only two arguments are specified, xlsread assumes the second ## argument to be @var{range} if it is a string argument and contains ## a ":" or if it is @'' (empty string), and in those cases assumes ## the data must be read from the first worksheet (not necessarily ## Sheet1! but the leftmost sheet). ## ## However, if only two arguments are specified and the second argument ## is numeric or a text string that does not contain a ":", it is ## assumed to be @var{wsh} and to refer to a worksheet. In that case ## xlsread tries to read all data contained in that worksheet. ## ## To be able to use Named ranges, the second input argument should ## refer to a worksheet and the third should be the Named range. ## ## After these input arguments a number of optional arguments can be ## supplied in any desired order: ## ## @table @asis ## @item @var{Interface} ## @var{Interface} (a three-character text sting) can be used to override ## the automatic interface selection by xlsread out of the supported ## ones: COM/Excel, Java/Apache POI, Java/JExcelAPI, Java/OpenXLS, ## Java/UNO (OpenOffice.org), or native Octave (in that -built in- ## order of preference). ## For I/O to/from .xlsx files a value of 'com', 'poi', 'uno', or 'oct' ## must be specified for @var{reqintf} (see help for xlsopen). For ## Excel'95 files use 'com', or if Excel is not installed use 'jxl', ## 'basic' or 'uno'. POI can't read Excel'95 but will try to fall back ## to JXL. As @var{reqintf} can also be a cell array of strings, one ## can select or exclude one or more interfaces. ## In addition the OCT interface offers .gnumeric read support. ## @end item ## ## @item Function handle ## If a function handle is specified, the pertinent function (having at ## most two output arrays) will be applied to the numeric output data of ## xlsread. Any second output of the function will be in a 5th output ## argument @var{extout} of xlsread. ## @end item ## ## @item Options struct ## xlsread's output can be influenced to some extent by a number of ## options. See OPTIONS in "help xls2oct" for an overview. ## @end item ## @end table ## ## Erroneous data and empty cells are set to NaN in @var{numarr} and ## turn up empty in @var{txtarr} and @var{rawarr}. Date/time values in ## Excel are returned as numerical values in @var{numarr}. Note that ## Excel and Octave have different date base values (epoch; 1/1/1900 & ## 1/1/0000, resp.). When using the COM interface, spreadsheet date ## values lying before 1/1/1900 are returned as strings, formatted as ## they appear in the spreadsheet. The returned date format for other ## interfaces depend on interface type and support SW version. ## @var{numarr} and @var{txtarr} are trimmed from empty outer rows ## and columns. Be aware that Excel does the same for @var{rawarr}, ## so any returned array may turn out to be smaller than requested in ## @var{range}. Use the fourth return argument @var{LIMS} for info on the ## cell ranges your date came from. ## ## When reading from merged cells, all array elements NOT corresponding ## to the leftmost or upper Excel cell will be treated as if the ## "corresponding" Excel cells are empty. ## ## xlsread is just a wrapper for a collection of scripts that find out ## the interface to be used (COM, Java/POI, Java/JXL Java/OXS, Java/UNO, ## OCT) and do the actual reading. For each call to xlsread the interface ## must be started and the Excel file read into memory. When reading ## multiple ranges (in optionally multiple worksheets) a significant speed ## boost can be obtained by invoking those scripts directly as in: ## xlsopen / xls2oct [/ parsecell] / ... / xlsclose ## ## Beware: when using the COM interface, hidden Excel invocations may be ## kept running silently if not closed explicitly. ## ## Examples: ## ## @example ## A = xlsread ('test4.xls', '2nd_sheet', 'C3:AB40'); ## (which returns the numeric contents in range C3:AB40 in worksheet ## '2nd_sheet' from file test4.xls into numeric array A) ## @end example ## ## @example ## [An, Tn, Ra, limits] = xlsread ('Sales2009.xls', 'Third_sheet'); ## (which returns all data in worksheet 'Third_sheet' in file 'Sales2009.xls' ## into array An, the text data into array Tn, the raw cell data into ## cell array Ra and the ranges from where the actual data came in limits) ## @end example ## ## @example ## numarr = xlsread ('Sales2010.xls', 4, [], @{'JXL', 'COM'@}); ## (Read all data from 4th worksheet in file Sales2010.xls using either JXL ## or COM interface (i.e, exclude POI interface). ## @end example ## ## @seealso {xlswrite, xlsopen, xls2oct, xlsclose, xlsfinfo, oct2xls} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-10-16 function [ numarr, txtarr, rawarr, lims, extout ] = xlsread (fn, wsh, datrange, varargin) rstatus = 0; if (nargin < 1) error ("xlsread: no input arguments specified\n") numarr = []; txtarr={}; rawarr = {}; return elseif (! ischar (fn)) error ("filename (text string) expected for argument #1, not a %s\n", class (fn)); elseif (nargin == 1) wsh = 1; datrange = ""; elseif (nargin == 2) ## Find out whether 2nd argument = worksheet or range if (isnumeric (wsh) || (isempty (findstr (wsh, ":" )) && ~isempty (wsh))) ## Apparently a worksheet specified datrange = ""; else ## Range specified datrange = wsh; wsh = 1; endif endif reqintf = hndl = opts = extout = []; if (nargin > 3) for ii=1:nargin-3 if (ischar (varargin{ii})) ## Request a certain interface reqintf = varargin{ii}; ## A small gesture for Matlab compatibility. JExcelAPI supports BIFF5. if (! isempty (reqintf) && ischar (reqintf) && strcmpi (reqintf, "BASIC")) reqintf = {"JXL"}; printf ("(BASIC (BIFF5) support request translated to JXL)\n"); endif elseif (strcmp (class (varargin{ii}), "function_handle")) ## Function handle to apply to output "num" hndl = varargin{ii}; elseif (isstruct (varargin{ii})) ## Various spreadsheet output options opts = varargin{ii}; else error ("xlsread: illegal input arg. #%d", ii); endif endfor endif ## Checks done. First check for .csv as that doesn't need xlsopen etc; ## a convenience for lazy Matlab users (see bugs #40993 & #44511): [~, ~, ext] = fileparts (fn); if strcmpi (ext, ".csv") if (isempty (datrange)) numarr = dlmread (fn, ","); else numarr = dlmread (fn, ",", datrange); endif txtarr = rawarr = lims = []; return else ## Get raw data into cell array "rawarr". xlsopen finds out what interface ## to use. If none found, just return as xlsopen will complain enough. unwind_protect ## Needed to catch COM errors & able to close stray Excel ## invocations ## Get pointer array to spreadsheet file xls_ok = 0; xls = xlsopen (fn, 0, reqintf); if (! isempty (xls)) xls_ok = 1; ## Get data from spreadsheet file & return handle [rawarr, xls, rstatus] = xls2oct (xls, wsh, datrange, opts); ## Save some results before xls is wiped rawlimits = xls.limits; xtype = xls.xtype; if (rstatus) [numarr, txtarr, lims] = parsecell (rawarr, rawlimits); if (! isempty (hndl) && ! isempty (numarr)) try [numarr, extout] = feval (hndl, numarr); catch warning ("xlsread: applying specified function handle failed with:\ error\n'%s'\n", lasterr); end_try_catch endif else rawarr = {}; numarr = []; txtarr = {}; extout = []; endif endif unwind_protect_cleanup ## Close Excel file if (xls_ok) xls = xlsclose (xls); endif end_unwind_protect endif endfunction io-2.4.10/inst/PaxHeaders.5973/__exit_io__.m0000644000000000000000000000013213226215407015262 xustar0030 mtime=1515789063.556154616 30 atime=1515789063.552154538 30 ctime=1515789065.028183488 io-2.4.10/inst/__exit_io__.m0000644000175000017500000000245713226215407015532 0ustar00olafolaf00000000000000## Copyright (C) 2016 Carnë Draug ## Copyright (C) 2011-2017 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 ## . ## -*- 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\n"); end_try_catch endfunction io-2.4.10/inst/PaxHeaders.5973/xls2oct.m0000644000000000000000000000013213226215407014424 xustar0030 mtime=1515789063.604155557 30 atime=1515789063.604155557 30 ctime=1515789065.028183488 io-2.4.10/inst/xls2oct.m0000644000175000017500000002522313226215407014670 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [ @var{rawarr}, @var{xls}, @var{rstatus} ] = xls2oct (@var{xls}) ## @deftypefnx {Function File} [ @var{rawarr}, @var{xls}, @var{rstatus} ] = xls2oct (@var{xls}, @var{wsh}) ## @deftypefnx {Function File} [ @var{rawarr}, @var{xls}, @var{rstatus} ] = xls2oct (@var{xls}, @var{wsh}, @var{range}) ## @deftypefnx {Function File} [ @var{rawarr}, @var{xls}, @var{rstatus} ] = xls2oct (@var{xls}, @var{wsh}, @var{range}, @var{options}) ## ## Read data contained within cell range @var{range} from worksheet @var{wsh} ## in an Excel spreadsheet file pointed to in struct @var{xls}; Gnumeric ## files can be read as well. ## ## @var{xls} is supposed to have been created earlier by xlsopen in the ## same octave session. ## ## @var{wsh} is either numerical or text, in the latter case it is ## case-sensitive and it may be max. 31 characters long. ## Note that in case of a numerical @var{wsh} this number refers to the ## position in the worksheet stack, counted from the left in an Excel ## window. The default is numerical 1, i.e. corresponding to the leftmost ## worksheet tab in the Excel file. ## ## @var{range} is expected to be either a regular spreadsheet range ## format, "" (empty string, indicating all data in a worksheet), or a ## "Named range" defined in the spreadsheet file. In case of a Named ## range, the worksheet associated with that Named range will be used ## instead of the one specified in @var{wsh}. ## If no range is specified the occupied cell range will have to be ## determined behind the scenes first; this can take some time for the ## Java-based interfaces. Be aware that in COM/ActiveX interface the ## used range can be outdated. The Java-based interfaces are more ## reliable in this respect albeit much slower. ## ## Optional argument @var{options}, a structure, can be used to ## specify various read modes by setting option fields in the struct ## to true (1) or false (0). Currently recognized option fields are: ## ## @table @asis ## @item "formulas_as_text" ## If set to TRUE or 1, spreadsheet formulas (if at all present) ## are read as formula strings rather than the evaluated formula ## result values. The default value is 0 (FALSE). ## ## @item 'strip_array' ## Set the value of this field set to TRUE or 1 to strip the returned ## output array @var{rawarr} from empty outer columns and rows. The ## spreadsheet cell rectangle limits from where the data actually ## came will be updated. The default value is FALSE or 0 (no cropping). ## When using the COM interface, the output array is always cropped. ## ## @item 'convert_utf' ## If set to 1 or TRUE, xls2oct tries to do a best job of converting ## UTF-8 characters to one-byte characters so that they display ## properly in Octave if that uses a terminal that does not support ## UTF-8 encoding (e.g., Windows 7 and below). ## For the COM interface this conversion is done by libraries ## outside Octave so for COM this option has no effect. ## @end table ## ## If only the first argument @var{xls} is specified, xls2oct will try ## to read all contents from the first = leftmost (or the only) ## worksheet (as if a range of @'' (empty string) was specified). ## ## If only two arguments are specified, xls2oct assumes the second ## argument to be @var{wsh}. In that case xls2oct will try to read ## all data contained in that worksheet. ## ## Return argument @var{rawarr} contains the raw spreadsheet cell data. ## Use parsecell() to separate numeric and text values from @var{rawarr}. ## ## Optional return argument @var{xls} contains the pointer struct, ## If any data have been read, field @var{xls}.limits contains the ## outermost column and row numbers of the actually returned cell range. ## ## Optional return argument @var{rstatus} will be set to 1 if the ## requested data have been read successfully, 0 otherwise. ## ## Erroneous data and empty cells turn up empty in @var{rawarr}. ## Date/time values in Excel are returned as numerical values. ## Note that Excel and Octave have different date base values (epoch; ## 1/1/1900 and 1/1/0000, respectively). The epoch of returned date values ## depending on interface and version of the support SW. ## Be aware that Excel trims @var{rawarr} from empty outer rows & columns, ## so any returned cell array may turn out to be smaller than requested ## in @var{range}, independent of field 'formulas_as_text' in @var{options}. ## When using COM, POI, or UNO interface, formulas in cells are evaluated; if ## that fails cached values are retrieved. These may be outdated depending ## on Excel's "Automatic calculation" settings when the spreadsheet was saved. ## ## When reading from merged cells, all array elements NOT corresponding ## to the leftmost or upper Excel cell will be treated as if the ## "corresponding" Excel cells are empty. ## ## Beware: when the COM interface is used, hidden Excel invocations may be ## kept running silently in case of COM errors. ## ## Examples: ## ## @example ## A = xls2oct (xls1, '2nd_sheet', 'C3:AB40'); ## (which returns the numeric contents in range C3:AB40 in worksheet ## '2nd_sheet' from a spreadsheet file pointed to in pointer struct xls1, ## into numeric array A) ## @end example ## ## @example ## [An, xls2, status] = xls2oct (xls2, 'Third_sheet'); ## @end example ## ## @seealso {oct2xls, xlsopen, xlsclose, parsecell, xlsread, xlsfinfo, xlswrite } ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2010-10-16 function [ rawarr, xls, rstatus ] = xls2oct (xls, wsh=1, datrange="", spsh_opts=[]) ## Check if xls struct pointer seems valid if (! isstruct (xls)) error ("File ptr struct expected for arg @ 1\n"); endif test1 = ! isfield (xls, "xtype"); test1 = test1 || ~isfield (xls, "workbook"); test1 = test1 || isempty (xls.workbook); test1 = test1 || isempty (xls.app); test1 = test1 || ~ischar (xls.xtype); if test1 error ("Invalid xls file pointer struct\n"); endif ## Check worksheet ptr if (! (ischar (wsh) || isnumeric (wsh))) error ("Integer (index) or text (wsh name) expected for arg # 2\n"); elseif (isempty (wsh)) wsh = 1; endif ## Check range if (! (isempty (datrange) || ischar (datrange))) error ("Character string expected for arg # 3 (range)\n"); elseif (! isempty (datrange)) ## Check for range name and convert it to range & optionally sheet ## 1. Check if it matches a range [datrange, wsh, xls] = chknmrange (xls, datrange, wsh); endif ## Check & setup options struct if (nargin < 4 || isempty (spsh_opts)) spsh_opts.formulas_as_text = 0; spsh_opts.strip_array = 1; spsh_opts.convert_utf = 0; ## Future options: elseif (isstruct (spsh_opts)) if (! isfield (spsh_opts, "formulas_as_text")) spsh_opts.formulas_as_text = 0; endif if (! isfield (spsh_opts, "strip_array")) spsh_opts.strip_array = 1; endif if (! isfield (spsh_opts, "convert_utf")) spsh_opts.convert_utf = 0; endif ## Future options: else error ("Structure expected for arg # 4 (options)\n"); endif ## Select the proper interfaces if (strcmp (xls.xtype, "COM")) ## Call Excel tru COM / ActiveX server [rawarr, xls, rstatus] = __COM_spsh2oct__ (xls, wsh, datrange, spsh_opts); elseif (strcmp (xls.xtype, "POI")) ## Read xls file tru Java POI [rawarr, xls, rstatus] = __POI_spsh2oct__ (xls, wsh, datrange, spsh_opts); elseif (strcmp (xls.xtype, "JXL")) ## Read xls file tru JExcelAPI [rawarr, xls, rstatus] = __JXL_spsh2oct__ (xls, wsh, datrange, spsh_opts); elseif (strcmp (xls.xtype, "OXS")) ## Read xls file tru OpenXLS [rawarr, xls, rstatus] = __OXS_spsh2oct__ (xls, wsh, datrange, spsh_opts); elseif (strcmp (xls.xtype, "UNO")) ## Read xls file tru OpenOffice.org UNO (Java) bridge [rawarr, xls, rstatus] = __UNO_spsh2oct__ (xls, wsh, datrange, spsh_opts); elseif (strcmp (xls.xtype, "OCT")) ## Read xls file tru native Octave if (strcmpi (xls.app, "xlsx")) [rawarr, xls, rstatus] = __OCT_xlsx2oct__ (xls, wsh, datrange, spsh_opts); elseif (strcmpi (xls.app, "gnumeric")) [rawarr, xls, rstatus] = __OCT_gnm2oct__ (xls, wsh, datrange); elseif (strcmpi (xls.app, "ods")) [rawarr, xls, rstatus] = __OCT_ods2oct__ (xls, wsh, datrange, spsh_opts); else error ("xls2oct.m: file format not supported for OCT interface\n"); endif ## Replace XML escape sequences by regular characters idx = cellfun (@ischar, rawarr); rawarr(idx) = strrep (rawarr(idx), "&", "&"); rawarr(idx) = strrep (rawarr(idx), "<", "<"); rawarr(idx) = strrep (rawarr(idx), ">", ">"); rawarr(idx) = strrep (rawarr(idx), "'", "'"); rawarr(idx) = strrep (rawarr(idx), """, '"'); ##elseif ---- ## Call to next interface else error (sprintf ("xls2oct: unknown Excel .xls interface - %s.\n", xls.xtype)); endif ## Convert from UTF-8 and strip characters that are not supported by Octave ## (any chars < 32 or > 255). if (! strcmp (xls.xtype, "COM") && (spsh_opts.convert_utf)) if (exist ("native2unicode", "file")) conv_fcn = @(str) unicode2native (native2unicode (str, "UTF-8")); else conv_fcn = @utf82unicode; endif rawarr = tidyxml (rawarr, conv_fcn); endif ## Optionally strip empty outer rows and columns & keep track of original data location if (spsh_opts.strip_array) emptr = cellfun ("isempty", rawarr); if (all (all (emptr))) rawarr = {}; xls.limits = []; else nrows = size (rawarr, 1); ncols = size (rawarr, 2); irowt = 1; while (all (emptr(irowt, :))), irowt++; endwhile irowb = nrows; while (all (emptr(irowb, :))), irowb--; endwhile icoll = 1; while (all (emptr(:, icoll))), icoll++; endwhile icolr = ncols; while (all (emptr(:, icolr))), icolr--; endwhile ## Crop output cell array and update limits rawarr = rawarr(irowt:irowb, icoll:icolr); xls.limits = xls.limits + [icoll-1, icolr-ncols; irowt-1, irowb-nrows]; endif endif endfunction io-2.4.10/inst/PaxHeaders.5973/test_spsh.m0000644000000000000000000000013213226215407015042 xustar0030 mtime=1515789063.600155479 30 atime=1515789063.600155479 30 ctime=1515789065.028183488 io-2.4.10/inst/test_spsh.m0000644000175000017500000001225113226215407015303 0ustar00olafolaf00000000000000## Copyright (C) 2013-2017 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 Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## @deftypefn {Function File} [ @var{void} ] = test_sprdsh () ## Test functionality of supported spreadsheet interfaces. ## ## test_spsh tests simply tests all interfaces that are found to be ## supported by chk_spreadsheet_support() function, one by one. ## It invokes the functions io_xls_testscript.m and io_ods_testscript.m ## for the actual testing. ## ## As it is meant to be used interactively, no output arguments ## are returned. ## ## @seealso {io_xls_testscript, io_ods_testscript} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2013-04-21 function [] = test_spsh (numb = []) persistent xls_intf = {"com", "poi", "oox", "jxl", "oxs", " - ", " - ", "uno"}; persistent ods_intf = {" - ", " - ", " - ", " - ", " - ", "otk", "jod", "uno"}; page_screen_output (0, "local"); ## Get available interfaces avail_intf = uint16 (chk_spreadsheet_support ()); rslts = cell (0, 11); ## First all Excel xls/xlsx interfaces intf2 = ""; for ii = 1:numel (xls_intf) try intfpatt = bitset (uint16 (0), ii, 1);## uint16 so more intfs can be added intfchk = bitand (intfpatt, avail_intf); intf = []; fname = "io-test.xls"; switch intfchk case 1 ## COM (ActiveX / hidden MS-Excel) intf = intf2 = "com"; case 2 ## POI (Apache POI) intf = "poi"; tst_oct = 1; case 4 ## POI/OOXML (Apache POI) intf = intf2 = "poi"; fname = "io-test.xlsx"; case 8 ## JXL (JExcelAPI) intf = "jxl"; case 16 ## OXS (OpenXLS/ Extentech) intf = "oxs"; case 128 ## UNO (LibreOffice Java-UNO bridge) intf = intf2 = "uno"; otherwise endswitch ## If present, test selected interfaces if (! isempty (intf)) printf ("\nInterface \"%s\" found.\n", upper (intf)); rslts = [rslts ; io_xls_testscript(intf, fname)]; endif catch printf ("\n======== Oops, error with interface %s ========\n\n", ... upper (intf)); end_try_catch ## Allow the OS some time for cleaning up pause (0.25); endfor ## Test OCT interface if possible rslts = [rslts; io_xls_testscript("OCT", "io-test.xlsx")]; ## Next, all (OOo/LO) ods interfaces intf2 = ""; for ii = 1:numel (ods_intf) try intfpatt = bitset (uint16 (0), ii, 1);## uint16 so more intfs can be added intfchk = bitand (intfpatt, avail_intf); intf = []; switch intfchk case 32 ## OTK (ODF Toolkit) intf = intf2 = "otk"; case 64 ## JOD (jOpenDocument) intf = intf2 = "jod"; case 128 ## UNO (LibreOffice Java-UNO bridge) intf = intf2 = "uno"; otherwise endswitch ## If present, test selected interfaces if (! isempty (intf)) printf ("\nInterface \"%s\" found.\n", upper (intf)); rslts = [rslts ; io_ods_testscript(intf, "io-test.ods")]; endif catch printf ("\n======== Oops, error with interface %s ========\n\n", ... upper (intf)); end_try_catch ## Allow the OS some time for cleaning up pause (0.25); endfor ## Test OCT interface if possible rslts = [rslts ; io_ods_testscript("OCT", "io-test.ods")]; ## Test OCT interface for gnumeric rslts = [rslts ; io_ods_testscript("OCT", "io-test.gnumeric")]; tstmsg = {"Numeric array p.1: ",... "Numeric array p.2: ",... "Numeric array p.3: ",... "Numeric array p.4: ",... "Cellstr array p.1: ",... "Cellstr array p.2: ",... " ...special chars: ",... "Boolean value : ",... "Formula read back: "}; printf ("\nInterface: "); for jj=1:size (rslts, 1) printf (" %s ", rslts{jj, 1}); endfor printf ("\nFile type ") for jj=1:size (rslts, 1) printf ("%4s ", rslts{jj, 11}(2:end)); endfor for ii=1:9 printf ("\n%s", tstmsg{ii}); for jj=1:size (rslts, 1) printf (" %2s ", rslts{jj, ii+1}); endfor endfor printf ("\n + = correct result returned\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"); endfunction io-2.4.10/inst/PaxHeaders.5973/odsclose.m0000644000000000000000000000013213226215407014641 xustar0030 mtime=1515789063.560154694 30 atime=1515789063.560154694 30 ctime=1515789065.028183488 io-2.4.10/inst/odsclose.m0000644000175000017500000001016513226215407015104 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [@var{ods}] = odsclose (@var{ods}) ## @deftypefnx {Function File} [@var{ods}] = odsclose (@var{ods}, @var{filename}) ## @deftypefnx {Function File} [@var{ods}] = odsclose (@var{ods}, "FORCE") ## Close the OpenOffice_org Calc / Gnumeric spreadsheet pointed to in struct ## @var{ods}, if needed write the file to disk. ## ## odsclose will determine if the file must be written to disk based on ## information contained in @var{ods}. ## An empty pointer struct will be returned if no errors occurred. ## Optional argument @var{filename} can be used to write changed spreadsheet ## files to an other file than opened by odsopen(). ## Optional string argument "FORCE" can be specified to force resetting the ## file pointer struct. However, in case of UNO, a hidden OOo invocation ## may linger on in memory then, preventing proper closing of Octave. ## ## @var{ods} must be a valid pointer struct made by odsopen() in the same ## octave session. ## ## Examples: ## ## @example ## ods1 = odsclose (ods1); ## (Close spreadsheet file pointed to in pointer struct ods1; ods1 is reset) ## @end example ## ## @seealso {odsopen, odsread, odswrite, ods2oct, oct2ods, odsfinfo, chk_spreadsheet_support} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-12-13 function [ ods ] = odsclose (ods, varargs) ## If needed warn that dangling spreadsheet pointers may be left if (nargout < 1) warning ("odsclose.m: return argument missing - ods invocation not reset.\n"); endif force = 0; if (isempty (ods)) warning ("odsclose: file pointer struct is empty; was it already closed?\n")'; return endif if (nargin > 1) for ii=2:nargin if (strcmpi(varargin{ii}, "force")) ## Close .ods anyway even if write errors occur force = 1; elseif (! isempty (strfind (tolower (varargin{ii}), "."))) ## Apparently a file name. First some checks.... if (ods.changed == 0 || ods.changed > 2) warning ("odsclose.m: file %s wasn't changed, new filename ignored.\n", ods.filename); elseif (! strcmp (xls.xtype, "UNO") && ... isempty (strfind ( lower (filename), ".ods"))) ## UNO will write any file type, all other interfaces only .ods error ("odsclose.m: .ods suffix lacking in filename %s\n", filename); else ## Preprocessing / -checking ready. ## Assign filename arg to file ptr struct ods.nfilename = filename; endif endif endfor endif if (strcmp (ods.xtype, "OTK")) ## Java & ODF toolkit ods = __OTK_spsh_close__ (ods, force); elseif (strcmp (ods.xtype, "JOD")) ## Java & jOpenDocument ods = __JOD_spsh_close__ (ods); elseif (strcmp (ods.xtype, "UNO")) ## Java & UNO bridge ods = __UNO_spsh_close__ (ods, force); elseif (strcmp (ods.xtype, "OCT")) ## Native Octave ods = __OCT_spsh_close__ (ods, "odsclose"); ##elseif ---- < Other interfaces here > else error (sprintf ("ods2close: unknown OpenOffice.org .ods interface - %s.\n",... ods.xtype)); endif if (ods.changed && ods.changed < 3) error (sprintf ("odsclose.m: could not save file %s - read-only or in use elsewhere?\n",... ods.filename)); if (force) ods = []; else printf ("(File pointer preserved)\n"); endif else ## Reset file pointer ods = []; endif endfunction io-2.4.10/inst/PaxHeaders.5973/__init_io__.m0000644000000000000000000000013213226215407015254 xustar0030 mtime=1515789063.556154616 30 atime=1515789063.556154616 30 ctime=1515789065.028183488 io-2.4.10/inst/__init_io__.m0000644000175000017500000001231613226215407015517 0ustar00olafolaf00000000000000## Copyright (C) 2016 Carnë Draug ## Copyright (C) 2011-2017 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 ## . ## -*- 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 /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 io-2.4.10/inst/PaxHeaders.5973/odswrite.m0000644000000000000000000000013213226215407014666 xustar0030 mtime=1515789063.564154773 30 atime=1515789063.564154773 30 ctime=1515789065.028183488 io-2.4.10/inst/odswrite.m0000644000175000017500000001277713226215407015144 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} @var{rstatus} = odswrite (@var{filename}, @var{arr}) ## @deftypefnx {Function File} @var{rstatus} = odswrite (@var{filename}, @var{arr}, @var{wsh}) ## @deftypefnx {Function File} @var{rstatus} = odswrite (@var{filename}, @var{arr}, @var{wsh}, @var{range}) ## @deftypefnx {Function File} @var{rstatus} = odswrite (@var{filename}, @var{arr}, @var{wsh}, @var{range}, @var{reqintf}) ## Add data in 1D/2D array @var{arr} into sheet @var{wsh} in ## OpenOffice_org Calc spreadsheet file @var{filename} in cell range ## @var{range}. Gnumeric files can also be written. ## ## @var{rstatus} returns 1 if write succeeded, 0 otherwise. ## ## @var{filename} must be a valid .ods OpenOffice.org file name (including ## file name extension). If @var{filename} does not contain any directory ## path, the file is saved in the current directory. ## ## @var{arr} can be any 1D or 2D array containing numerical, logical and/or ## character data (cellstr) except complex. Mixed numeric/logical/text ## arrays can only be cell arrays. ## ## @var{wsh} can be a number or string. In case of a not yet existing ## OpenOffice.org spreadsheet, the first sheet will be used & named ## according to @var{wsh} - no extra empty sheets are created. ## In case of existing files, some checks are made for existing sheet ## names or numbers, or whether @var{wsh} refers to an existing sheet with ## a type other than sheet (e.g., chart). ## When new sheets are to be added to the spreadsheet file, they are ## inserted to the right of all existing sheets. The pointer to the ## "active" sheet (shown when OpenOffice.org Calc opens the file) remains ## untouched. ## ## @var{range} is expected to be a regular spreadsheet range. ## Data is added to the sheet; existing data in the requested ## range will be overwritten. Instead of a spreadsheet range a Named ## range defined in the spreadsheet file can be used as well. In that ## case the Named range should be specified as 4th argument and the value ## of 3rd argument @var{wsh} doesn't matter as the worksheet associated ## with the specified Named range will be used. ## Array @var{arr} will be clipped at the right and/or bottom if its size ## is bigger than can be accommodated in @var{range}. ## If @var{arr} is smaller than the @var{range} allows, it is placed ## in the top left rectangle of @var{range} and cell values outside that ## rectangle will be untouched. ## If the third argument is a sheet name and @var{range} is specified as ## just one cell, it is taken as the topleft cell and the bottomright ## cell range address is determinded form the data. ## ## If @var{range} contains merged cells, only the elements of @var{arr} ## corresponding to the top or left Calc cells of those merged cells ## will be written, other array cells corresponding to that cell will be ## ignored. ## ## The optional last argument @var{reqintf} can be used to override ## the automatic selection by odswrite of one interface out of the ## supported ones: Java/ODFtooolkit ('OTK'), Java/jOpenDocument ('JOD'), ## Java/OpenOffice.org ('UNO'), or native Octave ('OCT'). For writing ## gnumeric, the OCT interface is automatically selected and need not ## be specified. ## ## odswrite is a mere wrapper for various scripts which find out what ## ODS interface to use (ODF toolkit, jOpenDocument, Open/LibreOffice or ## native Octave) plus code to mimic the other brand's xlswrite syntax ## (and quirks). ## For each call to odswrite such an interface must be started and ## possibly an ODS file loaded. When writing to multiple ranges and/or ## worksheets in the same ODS file, a speed bonus can be obtained by ## invoking those scripts (odsopen / octods / .... / odsclose) directly. ## ## Example: ## ## @example ## status = odswrite ('test4.ods', 'arr', 'Eight_sheet', 'C3:AB40'); ## (which adds the contents of array arr (any type) to range C3:AB40 ## in sheet 'Eight_sheet' in file test4.ods and returns a logical ## True (= numerical 1) in status if al went well) ## @end example ## ## @seealso {odsread, oct2ods, ods2oct, odsopen, odsclose, odsfinfo} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-12-14 function [ rstatus ] = odswrite (filename, data, wsh=1, crange="", reqintf=[]) ## Input validity checks if (nargin < 2) error ("Insufficient arguments - see 'help odswrite'\n"); endif ods = odsopen (filename, 1, reqintf); if (! isempty (ods)) [ods, rstatus] = oct2ods (data, ods, wsh, crange); ## If rstatus was not OK, reset change indicator in ods pointer if (! rstatus) ods.changed = rstatus; warning ("odswrite: data transfer errors, file not rewritten\n"); endif ods = odsclose (ods); if (! isempty (ods)) ## Apparently the file pointer couldn't be cleared, usually due to errors rstatus = 0; endif endif endfunction io-2.4.10/inst/PaxHeaders.5973/ods2oct.m0000644000000000000000000000013213226215407014403 xustar0030 mtime=1515789063.560154694 30 atime=1515789063.560154694 30 ctime=1515789065.028183488 io-2.4.10/inst/ods2oct.m0000644000175000017500000002370013226215407014645 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [ @var{rawarr}, @var{ods}, @var{rstatus} ] = ods2oct (@var{ods}) ## @deftypefnx {Function File} [ @var{rawarr}, @var{ods}, @var{rstatus} ] = ods2oct (@var{ods}, @var{wsh}) ## @deftypefnx {Function File} [ @var{rawarr}, @var{ods}, @var{rstatus} ] = ods2oct (@var{ods}, @var{wsh}, @var{range}) ## @deftypefnx {Function File} [ @var{rawarr}, @var{ods}, @var{rstatus} ] = ods2oct (@var{ods}, @var{wsh}, @var{range}, @var{options}) ## ## Read data contained within cell range @var{range} from worksheet @var{wsh} ## in an OpenOffice_org Calc or Gnumeric spreadsheet file pointed to ## in struct @var{ods}. ## ## @var{ods} is supposed to have been created earlier by odsopen() in the ## same octave session. ## ## @var{wsh} is either numerical or text, in the latter case it is ## case-sensitive. ## Note that in case of a numerical @var{wsh} this number refers to the ## position in the worksheet stack, counted from the left in a Calc ## window. The default is numerical 1, i.e. the leftmost worksheet ## in the ODS or gnumeric file. ## ## @var{range} is expected to be a regular spreadsheet range format, ## "" (empty string, indicating all data in a worksheet), or a ## "Named range" defined in the spreadsheet file. In case of a Named ## range, the worksheet associated with that Named range will be used ## instead of the one specified in @var{wsh}. ## If no range is specified the occupied cell range will have to be ## determined behind the scenes first; this can take some time. ## ## Optional argument @var{options}, a structure, can be used to ## specify various read modes by setting option fields in the struct ## to true (1) or false (0). Currently recognized option fields are: ## ## @table @asis ## @item "formulas_as_text" ## If set to TRUE or 1, spreadsheet formulas (if at all present) ## are read as formula strings rather than the evaluated formula ## result values. This only works for the OTK, UNO and OCT interfaces. ## The default value is 0 (FALSE). ## ## @item 'strip_array' ## Set the value of this field set to TRUE or 1 to strip the returned ## output array @var{rawarr} from empty outer columns and rows. The ## spreadsheet cell rectangle limits from where the data actually ## came will be updated. The default value is FALSE or 0 (no cropping). ## ## @item 'convert_utf' ## If set to 1 or TRUE, ods2oct tries to do a best job of converting ## UTF-8 characters to one-byte characters so that they display ## properly in Octave if that uses a terminal that does not support ## UTF-8 encoding (e.g., Windows 7 and below). ## @end table ## ## If only the first argument @var{ods} is specified, ods2oct will ## try to read all contents from the first = leftmost (or the only) ## worksheet (as if a range of @'' (empty string) was specified). ## ## If only two arguments are specified, ods2oct assumes the second ## argument to be @var{wsh}. In that case ods2oct will try to read ## all data contained in that worksheet. ## ## Return argument @var{rawarr} contains the raw spreadsheet cell data. ## Use parsecell() to separate numeric and text values from @var{rawarr}. ## ## Optional return argument @var{ods} contains the pointer struct. Field ## @var{ods}.limits contains the outermost column and row numbers of the ## actually read cell range. ## ## Optional return argument @var{rstatus} will be set to 1 if the ## requested data have been read successfully, 0 otherwise. ## ## Erroneous data and empty cells turn up empty in @var{rawarr}. ## Date/time values in OpenOffice.org or Gnumeric are returned as numerical ## values with base 1-1-0000 (same as octave). But beware that Excel ## spreadsheets rewritten by OpenOffice.org into .ods format may have ## numerical date cells with epoch (base) 01-01-1900 (same as MS-Excel). ## ## When reading from merged cells, all array elements NOT corresponding ## to the leftmost or upper OpenOffice.org Calc or Gnumeric cell will be ## treated as if the "corresponding" cells are empty. ## ## Examples: ## ## @example ## A = ods2oct (ods1, '2nd_sheet', 'C3:ABS40000'); ## (which returns the numeric contents in range C3:ABS40000 in worksheet ## '2nd_sheet' from a spreadsheet file pointed to in pointer struct ods1, ## into numeric array A) ## @end example ## ## @example ## [An, ods2, status] = ods2oct (ods2, 'Third_sheet'); ## @end example ## ## @seealso {odsopen, odsclose, parsecell, odsread, odsfinfo, oct2ods, odswrite} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-12-13 function [ rawarr, ods, rstatus ] = ods2oct (ods, wsh=1, datrange=[], spsh_opts=[]) ## Check if ods struct pointer seems valid if (! isstruct (ods)) error ("File ptr struct expected for arg @ 1"); endif test1 = ! isfield (ods, "xtype"); test1 = test1 || ! isfield (ods, "workbook"); test1 = test1 || isempty (ods.workbook); test1 = test1 || isempty (ods.app); if (test1) error ("Arg #1 is an invalid ods file struct\n"); endif ## Check worksheet ptr if (! (ischar (wsh) || isnumeric (wsh))) error ("Integer (index) or text (wsh name) expected for arg # 2\n"); elseif (isempty (wsh)) wsh = 1; endif ## Check range if (! (isempty (datrange) || ischar (datrange))) error ("Character string (range) expected for arg # 3\n"); elseif (! isempty (datrange)) ## Check for range name and convert it to range & optionally sheet ## 1. Check if it matches a range [datrange, wsh, ods] = chknmrange (ods, datrange, wsh); endif ## Check & setup options struct if (nargin < 4 || isempty (spsh_opts)) spsh_opts.formulas_as_text = 0; spsh_opts.strip_array = 1; spsh_opts.convert_utf = 0; ## Other options here: elseif (! isstruct (spsh_opts)) error ("struct expected for OPTIONS argument (# 4)\n"); else if (! isfield (spsh_opts, "formulas_as_text")) spsh_opts.formulas_as_text = 0; endif if (! isfield (spsh_opts, "strip_array")) spsh_opts.strip_array = 1; endif if (! isfield (spsh_opts, "convert_utf")) spsh_opts.convert_utf = 0; endif ## Future options: endif ## Select the proper interfaces if (strcmp (ods.xtype, "OTK")) ## Read ods file tru Java & ODF toolkit switch ods.odfvsn case "0.7.5" [rawarr, ods, rstatus] = __OTK_ods2oct__ (ods, wsh, datrange, spsh_opts); case {"0.8.6", "0.8.7", "0.8.8"} [rawarr, ods, rstatus] = __OTK_spsh2oct__ (ods, wsh, datrange, spsh_opts); otherwise error ("Unsupported odfdom version or invalid ods file pointer.\n"); endswitch elseif (strcmp (ods.xtype, "JOD")) ## Read ods file tru Java & jOpenDocument. First check for formula support if ((ods.odfvsn < 4) && spsh_opts.formulas_as_text) ## Not supported in jOpenDucument < 1.3 warning (["ods2oct.m: option 'formulas_as_text' not supported\n", ... "in jOpenDocument < 1.3; please upgrade. Option ignored.\n"]); spsh_opts.formulas_as_text = 0; endif [rawarr, ods, rstatus] = __JOD_spsh2oct__ (ods, wsh, datrange, spsh_opts); elseif (strcmp (ods.xtype, "UNO")) ## Read ods file tru Java & UNO [rawarr, ods, rstatus] = __UNO_spsh2oct__ (ods, wsh, datrange, spsh_opts); elseif (strcmp (ods.xtype, "OCT")) if (strcmpi (ods.app, "ods")) ## Read ods file tru native Octave [rawarr, ods, rstatus] = __OCT_ods2oct__ (ods, wsh, datrange, spsh_opts); elseif (strcmpi (ods.app, "gnumeric")) ## Read gnumeric. Gnumeric does not support formula evaluation nor supports ## cached values. Stripping output is processed below, spsh_opts is ignored [rawarr, ods, rstatus] = __OCT_gnm2oct__ (ods, wsh, datrange); endif ## Replace XML escape sequences by regular characters idx = cellfun (@ischar, rawarr); rawarr(idx) = strrep (rawarr(idx), "&", "&"); rawarr(idx) = strrep (rawarr(idx), "<", "<"); rawarr(idx) = strrep (rawarr(idx), ">", ">"); rawarr(idx) = strrep (rawarr(idx), "'", "'"); rawarr(idx) = strrep (rawarr(idx), """, '"'); ##elseif ## ---- < Other interfaces here > else error (sprintf ("ods2oct: unknown OpenOffice.org .ods interface - %s.\n", ods.xtype)); endif ## Convert from UTF-8 and strip characters that are not supported by Octave ## (any chars < 32 or > 255). if (spsh_opts.convert_utf) if (exist ("native2unicode", "file")) conv_fcn = @(str) unicode2native (native2unicode (str, "UTF-8")); else conv_fcn = @utf82unicode; endif rawarr = tidyxml (rawarr, conv_fcn); endif rstatus = ! isempty (rawarr); ## Optionally strip empty outer rows and columns & keep track of original data location if (spsh_opts.strip_array && rstatus) emptr = cellfun ("isempty", rawarr); if (all (all (emptr))) rawarr = {}; ods.limits= []; else nrows = size (rawarr, 1); ncols = size (rawarr, 2); irowt = 1; while (all (emptr(irowt, :))); irowt++; endwhile irowb = nrows; while (all (emptr(irowb, :))); irowb--; endwhile icoll = 1; while (all (emptr(:, icoll))); icoll++; endwhile icolr = ncols; while (all (emptr(:, icolr))); icolr--; endwhile # Crop outer rows and columns and update limits rawarr = rawarr(irowt:irowb, icoll:icolr); ods.limits = ods.limits + [icoll-1, icolr-ncols; irowt-1, irowb-nrows]; endif endif endfunction io-2.4.10/inst/PaxHeaders.5973/pch2mat.m0000644000000000000000000000013213226215407014364 xustar0030 mtime=1515789063.564154773 30 atime=1515789063.564154773 30 ctime=1515789065.028183488 io-2.4.10/inst/pch2mat.m0000644000175000017500000001012313226215407014621 0ustar00olafolaf00000000000000%% Copyright (C) 2011-2017 Bilen Oytun Peksel %% All rights reserved. %% %% Redistribution and use in source and binary forms, with or without %% modification, are permitted provided that the following conditions are met: %% %% 1 Redistributions of source code must retain the above copyright notice, %% this list of conditions and the following disclaimer. %% 2 Redistributions in binary form must reproduce the above copyright %% notice, this list of conditions and the following disclaimer in the %% documentation and/or other materials provided with the distribution. %% %% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' %% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE %% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE %% ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR %% ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL %% DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR %% SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER %% CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, %% OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE %% OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. %% -*- texinfo -*- %% @deftypefn {Function File} {@var{data} =} pch2mat (@var{filename}) %% Converts NASTRAN PCH file (SORT2) to a data structure and frequency vector. A %% filename as a string is the only needed input. %% %% The output is in the form of struct. containing a freq vector n x 1 called %% data.f, and the remaining data are in the form of subcases, point ids %% and directions respectively. for ex. data.S1.p254686.x and they are n x 2 %% %% @end deftypefn function [data] = pch2mat(filename); %% Open the file and read the file line by line to form a line character array fid = fopen(filename); l = 1; while (~feof(fid)) raw{l} = fgets(fid); l = l + 1; end %% Determine Freq_count and number of lines for each case a = find (strcmp ('$TITLE',raw)); lines = a(2) -a(1); %number of lines on each subcase and related point id freq_count = (lines-7)/4; %% Read from array C = length(raw) / lines; %number of subcase and related point id for k = 1 : C; %looping through every case scase = char(raw{(k-1) * lines + 3}(12:16)); scase = genvarname(scase); pid = char(raw{(k-1) * lines + 7}(16:25)); pid = genvarname(['p' pid]); if (k==1) data.f = zeros(freq_count,1); end; data.(scase).(pid).x = zeros(freq_count,2); data.(scase).(pid).y = zeros(freq_count,2); data.(scase).(pid).z = zeros(freq_count,2); data.(scase).(pid).r1 = zeros(freq_count,2); data.(scase).(pid).r2 = zeros(freq_count,2); data.(scase).(pid).r3 = zeros(freq_count,2); i = (k-1) * lines + 8 ; j = 0; while( i <= (lines * k)) %loop for each case j=j+1; if (k==1) data.f(j) = str2double(raw{i}(5:17)); end data.(scase).(pid).x(j,1) = str2double(raw{i}(25:37)); data.(scase).(pid).y(j,1) = str2double(raw{i}(43:55)); data.(scase).(pid).z(j,1) = str2double(raw{i}(61:73)); i=i+1; data.(scase).(pid).r1(j,1) = str2double(raw{i}(25:37)); data.(scase).(pid).r2(j,1) = str2double(raw{i}(43:55)); data.(scase).(pid).r3(j,1) = str2double(raw{i}(61:73)); i=i+1; data.(scase).(pid).x(j,2) = str2double(raw{i}(25:37)); data.(scase).(pid).y(j,2) = str2double(raw{i}(43:55)); data.(scase).(pid).z(j,2) = str2double(raw{i}(61:73)); i=i+1; data.(scase).(pid).r1(j,2) = str2double(raw{i}(25:37)); data.(scase).(pid).r2(j,2) = str2double(raw{i}(43:55)); data.(scase).(pid).r3(j,2) = str2double(raw{i}(61:73)); i=i+1; end end end io-2.4.10/inst/PaxHeaders.5973/tidyxml.m0000644000000000000000000000013213226215407014520 xustar0030 mtime=1515789063.600155479 30 atime=1515789063.600155479 30 ctime=1515789065.028183488 io-2.4.10/inst/tidyxml.m0000644000175000017500000000460513226215407014765 0ustar00olafolaf00000000000000## Copyright (C) 2016-2017 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 . ## -*- texinfo -*- ## @deftypefn {} {@var{ostr} =} tidyxml (@var{istr}, @var{conv_fcn}) ## Optionally convert character using the function handle in @var{conv_fcn}, ## remove characters (<32 >255) from text string or cell array @var{istr} ## and return the result in @var{ostr}. ## ## tidyxml is useful for converting strings in XML that have been partly ## or wholly encoded as double-byte characters. Such strings occur when ## dealing with a.o., spreadsheet programs reading/writing from/to ## XML-based formats and cannot be processed by Octave as Octave doesn't ## support unicode. For (optionally: nested) nested cell arrays tidyxml ## is called recursively and only processes cells containing text strings. ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2016-01-13 function [ostr] = tidyxml (istr="", conv_fcn=[]) if (iscell (istr)) idx = find (cellfun (@ischar, istr)); ostr = istr; ostr(idx) = cellfun (@(instr) tidyxml (instr, conv_fcn), istr(idx), "uni", 0); elseif (! ischar (istr)) print_usage (); elseif (isempty (istr)) ostr = ""; else if (isempty (conv_fcn)) ustr = uint8 (istr); else if (nargout (conv_fcn) > 1) [ustr, error_flag] = conv_fcn (istr); if (error_flag) warning ("Encoding conversion failed; some characters might be lost"); endif else try ustr = conv_fcn (istr); catch err warning ("Encoding conversion failed; some characters might be lost"); ustr = istr; end_try_catch endif endif ostr = char (ustr(ustr > 31 & ustr < 256)); endif endfunction io-2.4.10/inst/PaxHeaders.5973/io_ods_testscript.m0000644000000000000000000000013213226215407016566 xustar0030 mtime=1515789063.560154694 30 atime=1515789063.560154694 30 ctime=1515789065.028183488 io-2.4.10/inst/io_ods_testscript.m0000644000175000017500000001566413226215407017042 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} io_ods_testscript (@var{intf1}) ## @deftypefnx {Function File} io_ods_testscript (@var{intf1}, @var{fname}) ## @deftypefnx {Function File} io_ods_testscript (@var{intf1}, @var{fname}, @var{intf2}) ## Try to check proper operation of ODS spreadsheet scripts using ## interface @var{intf1}. ## ## @var{intf1} can be one of OTK, JOD, UNO, or OCT. No checks ## are made as to whether the requested interface is supported at all. If ## @var{fname} is supplied, that filename is used for the tests, otherwise ## filename "io-test.ods" is chosen by default. This parameter is required ## to have e.g., JOD distinguish between testing (reading) .ods (ODS 1.2) ## and .sxc (old OpenOffice.org & StarOffice) files (that UNO can write). ## ## If @var{intf2} is supplied, that interface will be used for writing the ## spreadsheet file and @var{intf1} will be used for reading. The OCT ## interface doesn't have write support (yet), so it will read spreadsheet ## files made by OTK (if supported) unless another interface is supplied ## for @var{intf2}. ## ## As the tests are meant to be run interactively, no output arguments are ## returned. The results of all test steps are printed on the terminal. ## ## @seealso {test_spsh, io_xls_testscript} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2012-02-25 function rslts = io_ods_testscript (intf, fname="io-test.ods", intf2='') printf ("\nTesting .ods interface %s using file %s...\n", upper (intf), fname); isuno = false; dly = 0.25; if (isempty (intf2)) intf2 = intf; else printf ("(Writing files is done with interface %s)\n", upper (intf2)); endif rslts = repmat ({"-"}, 1, 11); rslts{1} = upper (intf); [~, ~, ext] = fileparts (fname); rslts{11} = ext; if (strcmpi (intf, "uno") || strcmpi (intf2, "uno")); isuno = true; endif ## 1. Initialize test arrays printf ("\n 1. Initialize arrays.\n"); arr1 = [ 1 2; 3 4.5]; arr2 = {"r1c1", "=c2+sin(d3)"; "", "r2c2"; true, -83.4; "> < & \" '", " "}; opts = struct ("formulas_as_text", 0); try ## 2. Insert empty sheet printf ("\n 2. Insert first empty sheet.\n"); odswrite (fname, {""}, "EmptySheet", "b4", intf2); pause (dly); ## 3. Add data to test sheet printf ("\n 3. Add data to test sheet.\n"); odswrite (fname, arr1, "Testsheet", "c2:d3", intf2); if (isuno); pause (dly); endif odswrite (fname, arr2, "Testsheet", "d4:z20", intf2); pause (dly); ## 4. Insert another sheet printf ("\n 4. Add another sheet with just one number in A1.\n"); odswrite (fname, [1], "JustOne", "A1", intf2); pause (dly); ## 5. Get sheet info & find sheet with data and data range printf ("\n 5. Explore sheet info.\n"); [~, shts] = odsfinfo (fname, intf); shnr = find (strcmp ("Testsheet", shts(:, 1))); # Note case! crange = shts{shnr, 2}; pause (dly); ## 6. Read data back printf ("\n 6. Read data back.\n"); [num, txt, raw, lims] = odsread (fname, shnr, crange, intf); pause (dly); ## First check: has anything been read at all? if (isempty (raw)) printf ("No data at all have been read... test failed.\n"); return elseif (isempty (num)) printf ("No numeric data have been read... test failed.\n"); return elseif (isempty (txt)) printf ("No text data have been read... test failed.\n"); return endif ## 7. Here come the tests, part 1 printf ("\n 7. Tests part 1 (basic I/O):\n"); try printf (" ...Numeric array... "); assert (num(1:2, 1:3), [1, 2, NaN; 3, 4.5, NaN], 1e-10); rslts{2} = "+"; assert (num(4:5, 1:3), [NaN, NaN, NaN; NaN, 1, -83.4], 1e-10); rslts{3} = "+"; assert (num(3, 1:2), [NaN, NaN], 1e-10); rslts{4} = "+"; # Just check if it's numeric, the value depends too much on cached results assert (isnumeric (num(3,3)), true); rslts{5} = "+"; printf ("matches.\n"); catch printf ("Hmmm.... error, see 'num'\n"); num end_try_catch try printf (" ...Cellstr array... "); assert (txt{1, 1}, "r1c1"); rslts{6} = "+"; assert (txt{2, 2}, "r2c2"); rslts{7} = "+"; printf ("matches...\n"); printf (" ...special characters... "); assert (txt{4, 1}, "> < & \" '"); rslts(8) = "+"; printf ("matches.\n"); catch printf ("Hmmm.... error, see 'txt'\n"); txt end_try_catch try printf (" ...Boolean... "); assert (islogical (raw{5, 2}), true); ## Fails on older JOD rslts{9} = "+"; printf ("recovered.\n"); catch if (size (raw, 1) < 5 || size (raw, 2) < 2) printf ("Too little data read, boolean value not in expected data limits.\n"); elseif (isnumeric (raw{5, 2})) printf ("recovered as numeric '1' rather than logical TRUE\n"); rslts{9} = "o"; else printf ("Hmmm.... error, see 'raw'\n"); raw endif end_try_catch pause (dly); ## Check if formulas_as_text works: printf ("\n 8. Repeat reading, now return formulas as text\n"); opts.formulas_as_text = 1; ods = odsopen (fname, 0, intf); raw = ods2oct (ods, shnr, crange, opts); ods = odsclose (ods); clear ods; ## 9. Here come the tests, part 2. Fails on COM printf (["\n 9. Tests part 2 (read back as formula):\n" ... " (Note: just a check for a string rather than a numerical value)\n"] ); try # Just check if it contains a '+' character assert ( (ischar (raw{3, 3}) && (! isempty (strfind (raw{3, 3}, "+")))), true); rslts{10} = "+"; printf (" ...OK, formula recovered ('%s').\n", raw{3, 3}); catch printf ("Hmmm.... error, see 'raw(3, 3)'"); if (isempty (raw{3, 3})) printf (" (, should be a string like '=c2+d2')\n"); elseif (isnumeric (raw{3, 3})) printf (" (equals %f, should be a string like '=c2+d2')\n", raw{3, 3}); else printf ("\n"); endif end_try_catch ## 10. Clean up printf ("\n10. Cleaning up....."); delete (fname); printf (" OK\n"); catch ## Just to preserve rslts array printf ("\n%s\n\n", lasterr ()); end_try_catch endfunction io-2.4.10/inst/PaxHeaders.5973/odsread.m0000644000000000000000000000013213226215407014447 xustar0030 mtime=1515789063.564154773 30 atime=1515789063.564154773 30 ctime=1515789065.028183488 io-2.4.10/inst/odsread.m0000644000175000017500000002177113226215407014717 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [@var{numarr}, @var{txtarr}, @var{rawarr}, @var{limits}] = odsread (@var{filename}) ## @deftypefnx {Function File} [@var{numarr}, @var{txtarr}, @var{rawarr}, @var{limits}] = odsread (@var{filename}, @var{wsh}) ## @deftypefnx {Function File} [@var{numarr}, @var{txtarr}, @var{rawarr}, @var{limits}] = odsread (@var{filename}, @var{wsh}, @var{range}) ## @deftypefnx {Function File} [@var{numarr}, @var{txtarr}, @var{rawarr}, @var{limits}, @var{extout}] = odsread (@var{filename}, @var{wsh}, @var{range}, @var{OPTS}, @dots{}) ## ## Read data contained in cell range @var{range} in worksheet @var{wsh} ## in OpenOffice_org Calc spreadsheet file @var{filename}. Reading ## Gnumeric xml files is also supported. ## ## @var{filename} should include the filename extension (e.g., .ods). ## ## @var{wsh} is either numerical or text, in the latter case it is ## case-sensitive and it should conform to OpenOffice.org Calc or ## Gnumeric sheet name requirements. ## Note that in case of a numerical @var{wsh} this number refers to the ## position in the worksheet stack, counted from the left in a Calc ## window. The default is numerical 1, i.e. the leftmost worksheet ## in the Calc file. ## ## @var{range} is expected to be a regular spreadsheet range format, ## or "" (empty string, indicating all data in a worksheet). ## If no range is specified the occupied cell range will have to be ## determined behind the scenes first; this can take some time. ## Instead of a spreadsheet range a Named range defined in the ## spreadsheet file can be used as well. In that case the Named range ## should be specified as 3rd argument and the value of 2nd argument ## @var{wsh} doesn't matter as the worksheet associated with the ## specified Named range will be used. ## ## If only the first argument is specified, odsread will try to read ## all contents from the first = leftmost (or the only) worksheet (as ## if a range of @'' (empty string) was specified). ## ## If only two arguments are specified, odsread assumes the second ## argument to be @var{wsh} and to refer to a worksheet. In that case ## odsread tries to read all data contained in that worksheet. ## ## After these input arguments a number of optional arguments can be ## supplied in any desired order: ## ## @table @asis ## @item @var{Interface} ## @var{Interface} (a three-character text sting) can be used to ## override the automatic interface selection by odsread out of the ## supported ones: Java/ODFtoolkit ('OTK'), Java/jOpenDocument ('JOD'), ## Java/UNO bridge ('UNO'), or native Octave (OCT). Octave selects one ## of these, preferrably in the order above, based on presence of ## support software and the file at hand. In addition the OCT interface ## offers .gnumeric read support. ## @end item ## ## @item Function handle ## If a function handle is specified, the pertinent function (having at ## most two output arrays) will be applied to the numeric output data of ## odsread. Any second output of the function will be in a 5th output ## argument @var{extout} of odsread. ## @end item ## ## @item Options struct ## odsread's output can be influenced to some extent by a number of ## options. See OPTIONS in "help ods2oct" for an overview. ## @end itme ## @end table ## ## Return argument @var{numarr} contains the numeric data, optional ## return arguments @var{txtarr} and @var{rawarr} contain text strings ## and the raw spreadsheet cell data, respectively, and @var{limits} is ## a struct containing the data origins of the various returned arrays. ## If a function handle was specified, fifth output array @var{extout} ## contains optional second output of the invoked function. ## ## Erroneous data and empty cells are set to NaN in @var{numarr} and ## turn up empty in @var{txtarr} and @var{rawarr}. Date/time values ## in date/time formatted cells are returned as numerical values in ## @var{obj} with base 1-1-0000. Note that OpenOfice.org and MS-Excel ## have different date base values (epoch; 1/1/0000 & 1/1/1900, resp.) ## and internal representation so MS-Excel spreadsheets rewritten into ## .ods format by OpenOffice.org Calc may have different date base ## values than expected. ## As there's no gnumeric formula evaluator and gnumeric doesn't store ## cached formula results, formulas are returned as text strings when ## reading from Gnumeric files. ## ## @var{numarr} and @var{txtarr} are trimmed from empty outer rows ## and columns, so any returned array may turn out to be smaller than ## requested in @var{range}. ## ## When reading from merged cells, all array elements NOT corresponding ## to the leftmost or upper spreadsheet cell will be treated as if the ## "corresponding" cells are empty. ## ## A native Octave interface (OCT) is available, but presently still ## experimental; it offers .gnumeric read support as well. ## For ODS only the supported Java-based interfaces offer more flexibility ## and better speed. For those you need a Java JRE or JDK and one or both ## of jopendocument-.jar or preferrably: (odfdom.jar (versions ## 0.7.5 or 0.8.6-0.8.8) & xercesImpl.jar v. 2.9.1) in your javaclasspath. ## There is also experimental support invoking OpenOffice.org/LibreOffice ## or clones through a Java/UNO bridge. For Octave older than 3.8.0 the ## octave-forge Java package >= 1.2.9 is required then; newer Octave versions ## should have Java support built-in. ## ## odsread.m is just a wrapper for a collection of scripts that find out ## the interface to be used and do the actual reading. For each call ## to odsread the interface must be started and the spreadsheet file read into ## memory. When reading multiple ranges (in optionally multiple worksheets) ## a significant speed boost can be obtained by invoking those scripts ## directly (odsopen / ods2oct [/ parsecell] / ... / odsclose). This also ## offers more flexibility (e.g. formula results or the formulas ## themselves; stripping output arrays from empty enveloping rows/columns). ## ## Examples: ## ## @example ## A = odsread ('test4.ods', '2nd_sheet', 'C3:AB40'); ## (which returns the numeric contents in range C3:AB40 in worksheet ## '2nd_sheet' from file test4.ods into numeric array A) ## @end example ## ## @example ## [An, Tn, Ra, limits] = odsread ('Sales2009.ods', 'Third_sheet'); ## (which returns all data in worksheet 'Third_sheet' in file test4.ods ## into array An, the text data into array Tn, the raw cell data into ## cell array Ra and the ranges from where the actual data came in limits) ## @end example ## ## @seealso {odsopen, ods2oct, oct2ods, odsclose, odswrite, odsfinfo, parsecell} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-12-12 function [ numarr, txtarr, rawarr, lim, extout ] = odsread (filename, wsh=1, datrange=[], varargin) if (! ischar (filename)) error ("odsread: filename (text string) expected for argument #1, not a %s\n", class (filename)); endif if (nargin < 1 || ! (strcmpi (".ods", filename(end-3:end)) || ... strcmpi (".sxc", filename(end-3:end)) || ... strcmpi (".gnumeric", filename(end-8:end)))) error ("odsread: filename (incl. suffix) of a supported file type is required\n"); endif reqintf = hndl = opts = extout = []; if (nargin > 3) for ii=1:nargin-3 if (ischar (varargin{ii})) ## Request a certain interface reqintf = varargin{ii}; elseif (strcmp (class (varargin{ii}), "function_handle")) ## Function handle to apply to output "num" hndl = varargin{ii}; elseif (isstruct (varargin{ii})) ## Various spreadsheet output options opts = varargin{ii}; else error ("odsread: illegal input arg. #%d", ii); endif endfor endif ods = odsopen (filename, 0, reqintf); if (~isempty (ods)) [rawarr, ods, rstatus] = ods2oct (ods, wsh, datrange, opts); if (rstatus) [numarr, txtarr, lim] = parsecell (rawarr, ods.limits); if (! isempty (hndl) && ! isempty (numarr)) try [numarr, extout] = feval (hndl, numarr); catch warning ("xlsread: applying specified function handle failed with:\ error\n'%s'\n", lasterr); end_try_catch endif else warning (sprintf ("No data read from %s.\n", filename)); rawarr = {}; numarr = []; txtarr = {}; extout = []; endif ods = odsclose (ods); endif endfunction io-2.4.10/inst/PaxHeaders.5973/read_namelist.m0000644000000000000000000000013213226215407015635 xustar0030 mtime=1515789063.600155479 30 atime=1515789063.600155479 30 ctime=1515789065.028183488 io-2.4.10/inst/read_namelist.m0000644000175000017500000002560513226215407016105 0ustar00olafolaf00000000000000## Copyright (C) 2013-2017 Darien Pardinas Diaz ## ## 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 . ## S = READ_NAMELIST (FILENAME) returns the struct S containing namelists and ## variables in the file FILENAME organised in hierachical way: ## ## |--VAR1 ## |--VAR2 ## |-- NMLST_A--|... ## | |--VARNa ## | ## | |--VAR1 ## |-- NMLST_B--|--VAR2 ## | |... ## S --| ... |--VARNb ## | ## | |--VAR1 ## |-- 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; ## write_namelist(NMlST, "MOD_OPTIONS.nam"); ## Written by: Darien Pardinas Diaz (darien.pardinas-diaz@monash.edu) ## Version: 1.0 ## Date: 16 Dec 2011 ## ## Released under GPL License 30/3/2013 ## ## Notes Re: Use in Octave. ## -Line 83 causes a problem. Seems to work OK if commented out.FIXED ## -Copes with Fortran comment (!) e.g. ## &data1 ## a = 100.0 ! length metres ## b = 25.0 ! mass kg ## / ## is read OK ## Terry Duell 31 mar 2013 function S = read_namelist (filename) S = struct (); ## Open and read the text file containing the namelists 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)) line = line (1:idx(1) - 1); end if (! isempty (line)), ++c; lines{c} = line; ## FIXME each time appending to a cell array is slow end end fclose (fid); ii = 0; while (ii < c); ## Find a record ++ii; line = lines{ii}; idx = find (line == "&"); if (! isempty (idx)) ## i.e. a namelist start line = line(idx(1) + 1:end); ## find next space idx = find (line == " "); if (! isempty (idx)) namelst = line(1:idx(1) - 1); line = line(idx(1) + 1:end); else namelst = line; line = []; ##TDuell 31/03/2013 Provisional fix L.102 PRN 1apr2013 endif nmlst_bdy = ""; if (! isempty (line)) idx = find_ending_idx (line); else line = ""; endif ## Get the variable specification section while (isempty (idx) && ii < c) nmlst_bdy = [ nmlst_bdy " " line ]; ++ii; line = lines{ii}; idx = find_ending_idx (line); endwhile if (! isempty (idx) && idx(1) > 1) nmlst_bdy = [ nmlst_bdy " " line(1:idx(1)-1) ]; endif ## Parse current namelist (set of variables) S.(namelst) = parse_namelist (nmlst_bdy); endif endwhile endfunction ## Internal function to find the position of the slash terminating the namelist function idx = find_ending_idx (strng) ## Find all / idx_all = strfind (strng, "/"); idx = []; ## Only keep the ones not quoted for ii = 1:size (idx_all, 2) if (! is_quoted (strng, idx_all(ii), '"') && ... ! is_quoted (strng, idx_all(ii), '''')) idx = [idx idx_all(ii)]; endif endfor endfunction ## Internal function to check if a character at a position idx in a string ## 'strng' is quoted by the character quote function ll = is_quoted (strng, idx, quote) ## Find location of all quotes idx_quotes = strfind (strng, quote); if (isempty (idx_quotes)) ## There are no quotes ll = false; return endif ii = 1; while (ii <= size (idx_quotes, 2)) ## Find the first quote after the character if (idx_quotes(ii) > idx) ## If we counted an even number of quote, this character is quoted if (mod (ii, 2) == 0) ll = true; return else ll = false; return endif endif ++ii; endwhile ## The character is behind all quotes ll = false; endfunction ## Internal function to parse the body text of a namelist section. ## Limitations: the following patterns are prohibited inside the literal ## strings: ".t." ".f." ".true." ".false." "(:)" function S = parse_namelist (strng) ## Get all .true., .t. and .false., .f. to T and F strng = regexprep (strng, '\.true\.' , "T", "ignorecase"); strng = regexprep (strng, '\.false\.', "F", "ignorecase"); strng = regexprep (strng, '\.t\.', "T", "ignorecase"); strng = regexprep (strng, '\.f\.', "F", "ignorecase"); ## 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 == "="); ## 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 ## Now we are over the variable name or closing parentesis jj = ii; if (strng(ii) == ")"), while (strng(ii) != "(") --ii; endwhile --ii; ## Move to the left and discard any possible blank spaces while (strng(ii) == " ") --ii; endwhile endif ## Now we are over the last character of the variable name 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 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 == ","); if (any (commas)) arg(commas) = " "; endif if (any (arglit)) ## We are parsing a variable that is literal string arg = [ "{" arg "};"]; elseif (! isempty (find (arg == "T" || arg == "F", 1))), ## We are parsing a boolean variable arg = [ "{" arg "};" ]; else ## We are parsing a numerical array arg = [ "[" arg "];"]; endif ## Eval the modified syntax in Octave eval ([vars{kk} " = " arg]); endfor endfunction ## 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 rem_dquote = []; ## Positions to remove a double quote scape on syntax ii = 1; while (ii < len) if (strng(ii) == "'") ## Opening string with single quote... ++ii; while ((ii < len && strng(ii) != "'") || strcmp (strng(ii:ii+1), '''''')) ++ii; if strcmp (strng(ii-1:ii), ''''''), ++ii; endif endwhile endif 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) ## Check for a possible single quote here if (strng(ii) == "'") add_squote = [ add_squote ii ]; endif ++ii; if (strcmp (strng(ii-1:ii), '""')) rem_dquote = [ rem_dquote ii-1 ]; ++ii; endif endwhile strng(ii) = "'"; ## Change to single quote endif ++ii; endwhile for ii = 1:length (add_squote); strng = [ strng(1:add_squote(ii)) strng(add_squote(ii):end) ]; endfor 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 Octave string syntax ## Classify syntax as literal or regular expression ii = 1; len = length (strng); is_lit = zeros(len, 1); while (ii < len) if (strng(ii) == "'") ## Opening string with single quote... is_lit(ii) = 1; ++ii; while ((ii < len && strng(ii) != "'") || strcmp (strng(ii:ii+1), "''")) is_lit(ii) = 1; ++ii; if (strcmp (strng(ii-1:ii), '''''')), is_lit(ii) = 1; ++ii; endif endwhile is_lit(ii) = 1; 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); ## Check if namelists with a whitespace before the ending / can be read %!test %! fn = tempname (); %! fid = fopen (fn, "w"); %! fprintf (fid, "&test\n"); %! fprintf (fid, " a = 1,\n"); %! fprintf (fid, " /\n"); %! fclose (fid); %! nm = read_namelist (fn); %! unlink (fn); %! assert (nm.test.a, 1, eps); ## Check if character sequences can contain the / character %!test %! fn = tempname(); %! fid = fopen (fn, "w"); %! fprintf (fid, "&test\n"); %! fprintf (fid, " a = '/',\n"); % inside apostrophes %! fprintf (fid, " b = ""/"",\n"); % inside double quotes %! fprintf (fid, " c = '""/',\n"); % with double quotes inside apostrophes %! fprintf (fid, " d = ""'/"",\n"); % with apostrophes inside double quotes %! fprintf (fid, "/\n"); %! fclose (fid); %! nm = read_namelist (fn); %! unlink (fn); %! assert (strcmp(nm.test.a, '/'), 1, eps); %! assert (strcmp(nm.test.b, '/'), 1, eps); %! assert (strcmp(nm.test.c, '"/'), 1, eps); %! assert (strcmp(nm.test.d, '''/'), 1, eps); io-2.4.10/inst/PaxHeaders.5973/xlsfinfo.m0000644000000000000000000000013213226215407014656 xustar0030 mtime=1515789063.604155557 30 atime=1515789063.604155557 30 ctime=1515789065.028183488 io-2.4.10/inst/xlsfinfo.m0000644000175000017500000001625613226215407015130 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [@var{filetype}] = xlsfinfo (@var{filename} [, @var{reqintf}]) ## @deftypefnx {Function File} [@var{filetype}, @var{sh_names}] = xlsfinfo (@var{filename} [, @var{reqintf}]) ## @deftypefnx {Function File} [@var{filetype}, @var{sh_names}, @var{fformat}] = xlsfinfo (@var{filename} [, @var{reqintf}]) ## @deftypefnx {Function File} [@var{filetype}, @var{sh_names}, @var{fformat}, @var{nmranges}] = xlsfinfo (@var{filename} [, @var{reqintf}]) ## Query Excel spreadsheet file @var{filename} for some info about its ## contents. ## ## If @var{filename} is a recognizable Excel spreadsheet file, ## @var{filetype} returns the string "Microsoft Excel Spreadsheet", or ## @'' (empty string) otherwise. ## ## If @var{filename} is a recognizable Excel spreadsheet file, optional ## argument @var{sh_names} contains a Nx2 list (cell array) of sheet ## names (and in case Excel is installed: sheet types) and total used data ## range for each worksheet contained in @var{filename}, in the order ## (from left to right) in which they occur in the worksheet stack. ## ## Optional return value @var{fformat} currently returns @'' (empty ## string) unless @var{filename} is a readable Excel 97-2003 .xls file or ## an Excel 2007 .xlsx / .xlsb file in which case @var{fformat} is set to ## "xlWorkbookNormal". Excel 95 .xls files can only be read through the JXL ## (JExcelAPI) or UNO (OpenOffice.org) Java-based interfaces. ## ## Optional return argument @var{nmranges} is a cell array containing all ## named data ranges in the file in the first column, the relevant sheet and ## the cell range in the second and third column and if appropriate the ## scope of the range in the fourth column. For named ranges defined for ## the entire workbook the fourth column entry is empty. ## Named ranges only work for the COM, POI, OXS, UNO and OCT interfaces. ## ## If no return arguments are specified the sheet names are echoed to the ## terminal screen; in case of Java interfaces for each sheet the actual ## occupied data range is echoed as well. The occupied cell range will have ## to be determined behind the scenes first; this can take some time for the ## Java-based interfaces. Any Named ranges defined in the spreadsheet file ## will be listed on screen as well. ## ## If multiple xls interfaces have been installed, @var{reqintf} can be ## specified. This can sometimes be handy, e.g. to get an idea of occupied ## cell ranges in each worksheet using different interfaces (due to cached ## info and/or different treatment of empty but formatted cells, each ## interfaces may give different results). ## ## For OOXML spreadsheets no external SW is required but full POI and/or ## UNO support (see xlsopen) may work better or faster; to use those specify ## 'poi' or 'uno' for @var{reqintf}. For Excel 95 files use 'com' (windows ## only), 'jxl' or 'uno'. Gnumeric files can be explored with the built-in ## OCT interface (no need to specify @var{reqintf} then). ## ## Examples: ## ## @example ## exist = xlsfinfo ('test4.xls'); ## (Just checks if file test4.xls is a readable Excel file) ## @end example ## ## @example ## [exist, names] = xlsfinfo ('test4.xls'); ## (Checks if file test4.xls is a readable Excel file and return a ## list of sheet names and -types) ## @end example ## ## @seealso {oct2xls, xlsread, xls2oct, xlswrite} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-10-27 function [ filetype, sh_names, fformat, nmranges ] = xlsfinfo (filename, reqintf=[]) persistent str2; str2 = " "; ## 33 spaces persistent lstr2; lstr2 = length (str2); xls = xlsopen (filename, 0, reqintf); if (isempty (xls)) return; endif toscreen = nargout < 1; ## If any valid xls-pointer struct has been returned, it must be a valid ## spreadsheet. Find out what format [~, ~, ext] = fileparts (xls.filename); switch ext case {"xls", "xlsx", "xlsm", ".xlsb", ".xls", ".xlsx", ".xlsm", ".xlsb"} filetype = "Microsoft Excel Spreadsheet"; case {"ods", ".ods"} filetype = "OpenOffice.org Calc spreadsheet"; case {"gnumeric", ".gnumeric"} filetype = "Gnumeric spreadsheet"; otherwise endswitch fformat = ""; if (strcmp (xls.xtype, "COM")) [sh_names] = __COM_spsh_info__ (xls); elseif (strcmp (xls.xtype, "POI")) [sh_names] = __POI_spsh_info__ (xls); elseif (strcmp (xls.xtype, "JXL")) [sh_names] = __JXL_spsh_info__ (xls); elseif (strcmp (xls.xtype, "OXS")) [sh_names] = __OXS_spsh_info__ (xls); elseif (strcmp (xls.xtype, "UNO")) [sh_names] = __UNO_spsh_info__ (xls); elseif (strcmp (xls.xtype, "OCT")) [sh_names] = __OCT_spsh_info__ (xls); ##elseif else error (sprintf ("xlsfinfo: unknown Excel .xls interface - %s.\n", xls.xtype)); endif sh_cnt = size (sh_names, 1); if (toscreen) ## Echo sheet names to screen for ii=1:sh_cnt str1 = sprintf ("%3d: %s", ii, sh_names{ii, 1}); if (index (sh_names{ii, 2}, ":")) str3 = [ "(Used range ~ " sh_names{ii, 2} ")" ]; else str3 = sh_names{ii, 2}; endif printf ("%s%s%s\n", str1, str2(1:lstr2-length (sh_names{ii, 1})), str3); endfor ## Echo named ranges nmranges = getnmranges (xls); snmr = size (nmranges, 1); if(snmr > 0) ## Find max length of entries nmrl = min (35, max ([cellfun("length", nmranges(:, 1)); 10])); shtl = min (31, max ([cellfun("length", nmranges(:, 2)); 6])); rnml = max ([cellfun("length", nmranges(:, 3)); 5]); frmt = sprintf ("%%%ds %%%ds %%%ds\n" , nmrl, shtl, rnml); printf (["\n" frmt], "Range name", "Sheet", "Range"); printf (frmt, "----------", "-----", "-----" ); for ii=1:size (nmranges, 1) printf (frmt, nmranges(ii, 1:3){:}); endfor endif else if (sh_cnt > 0 && nargout > 2) if (strcmpi (xls.filename(end-2:end), "xls")) fformat = "xlWorkbookNormal"; ## FIXME could nowadays be "xlExcel8" elseif (strcmpi (xls.filename(end-2:end), "csv")) fformat = "xlCSV"; ## Works only with COM elseif (strcmpi (xls.filename(end-3:end-1), "xls")) fformat = "xlOpenXMLWorkbook"; elseif (strfind (lower (xls.filename(end-3:end)), 'htm')) fformat = "xlHtml"; ## Works only with COM else fformat = ""; endif endif if (nargout > 3) ## Echo named ranges nmranges = getnmranges (xls); endif endif xlsclose (xls); endfunction io-2.4.10/inst/PaxHeaders.5973/templates0000644000000000000000000000013213226215407014571 xustar0030 mtime=1515789063.600155479 30 atime=1515789065.028183488 30 ctime=1515789065.028183488 io-2.4.10/inst/templates/0000755000175000017500000000000013226215407015106 5ustar00olafolaf00000000000000io-2.4.10/inst/templates/PaxHeaders.5973/template.xlsx0000644000000000000000000000013213226215407017401 xustar0030 mtime=1515789063.600155479 30 atime=1515789063.600155479 30 ctime=1515789065.028183488 io-2.4.10/inst/templates/template.xlsx0000644000175000017500000001630713226215407017650 0ustar00olafolaf00000000000000PK!AيdocProps/app.xml (Ao0  9: bH7bvgMc$׏i{ڍ{xDI]:_Pk* $jcJŵAmrL-QZIJsgۼih:$/AH@1%z:ځvZ}K;kocC\TLuU[k<9X7#(2P`m˨UO,\k0T7ٙ@5ئf}Bw̏*Ɇi8svr4pqn&wͧHdIiB!}{h8" %PK!#Ӆ xl/styles.xmlT[o0~`hȒ RnNګ& Ml16/wsszs=1cVB*u._`uTUTh2|dߥ3@(s͂[J7LZIfGlc$pJ$  Y mRˆ:傻c,; z&H0/ID?F K|@~A~g3@m˅7:\J8?]qQi+g/'VVg/I"w*,5f/Nل1pNݘkJPI\'A16vҤ4ާp.F4ݗCaLJU 9B8cvd&` /}'<Ó?f;(_|ٟ_㹎O~s;&[x{W# >$1U|`1Mydc!b@ض^] ju[) xy~sA,#_b+r,y2u lc(1B۟@Ydau8‘!Ɩ&pn%Cr`$Ri -˨m=|d"@B~h.Pl39D1Dd#HG:Dz)sc̹ϵ ={tTC]Ę0Bʙ$B":63yq@p"BptUT$|2O->.a2 $9SONԳtZ;)Z;|?(=4Ocxg ;~^7څPuv7.'}x;4@Vj+72(iT'e#"`_U)MO3cVYm)j08۱VrwGhvm 4]ʼNnyI@'$Lu Ʋw$΅E¢)/C@mX?9j Qr_{PK!>B͢P4F4wR&;4s7d1rR@0Xc=z"vHr1nS @ !%fJ%ӂ)&.cRAWÐwjk00@GHvDqF}Lj:K*7M0ұ6'P5֔1N{bb^Yv."ԅ|K|YاgA|Ig_"n _:]ٿFQAwp i!w쥷4+HdL6Ҥ^tllHA=t=H<3a>0D"mo5nTjPK!p-xl/_rels/workbook.xml.rels (j0E}=v ٔB!Ėf_@H6s$mw?NNCY_U}Z7"z)[уKRz 6@#W&9`ϻU1ѵLTE)N9;l01HO>4Q+(2wiɆ%?-27AzeCHr+;>(2~YD[2geϢԯyir#~> $1i8PD R"PK!U0#L _rels/.rels (MO0 HݐBKwAH!T~I$ݿ'TG~(:sчd$+aBOmd<$ P0+;گraлMۙ7sE#Dw-Kƽm %^o4>Ogѿ(,zg\ʹ smS\R:ETZmw̤'Ot&0 ",GsO\37e%lEXxc4X{a+~PK3!EPKqD}%meta.xmlSr0++ c &i:SgziMb# }؉}('T=]tcVYZHn礌%*4\r"ߪ,J۸7jfRǩ>ZZ5 9wRƿ;RaH<զEx٠P]Kp ;:_S#ڒUhOɲM!w ,y̱$aGW 6*J:ɺ`N˷;v #m'^j"p!hQy970l <wH4Sr.*^JbEa%J"/gV%8}cP$/3-su@TބU;L~w`kٷĽ\ $XAurfL7cpzK{ׯPKk6Dl9..mimetypeapplication/vnd.oasis.opendocument.spreadsheetPKk6D settings.xmlZ[w8~_kO%M8 =2nHb &la+qȯ_ CxKad4, Gf(,D]a_ARfE5Qy"(T+#ƠFtk,@t3wm,y">\s)ZE#~\VMWwU~1]RV)>QX5߯_į,B֦]Je׌m^aƦQ.Ո4 oF3=|tr`|NwE?YS=!/ Eۧh5F_b/^H!&K5hTvFwL`ky!rq̨ =桤ڈK慞~,KsďhއOqOe?F&fKTIO[ JAGIԕH꿂 Y8ISԨK[*_~'ҚWZQ}ʷp0鸜2<\V`Gh3HDJf8[/ɻ0~W h)WO՞`}A {!9\5^_ dChJj+Qgwj/0B?B4C4ondv?ia% ^<ߺ.qW]nsG=h `ڠn":æ AT?3@Î[&8h(+tUS?\,Mb+Y?ۤyޜ]0(GW g@ٯC_i+^(NVϮ~$֛-nmp1h?z}mLlI@Hg@QM߀b7]m) 2{}Ƒ9 "3od,[NETwqr$X>Alۣk4Z* hh=[ՁcU5՞wd H0@W4Wk1E^Q'90ySr- (% D~<0*$;wϥW5I8p  ěPmTT擩AZr,Uq9MQS_lrt-LۡrLˤ)#u67Oqg)lr5 )s*E^湁ޟ97Yxhgi@xBޢ%N/v¥VtX|3kFϢԺc dRQ F~T $ۣR>EGV@Y7^~cQˇOpSn:Sz[;!|^F<S^5T/|LkE)0Y6'`ߑrj1Zp[Ugр%pFV T/[/Pq40=d'~xTȑp*iӋJӹq%Θ_6bAonooobRvHx^6k"`>=ڝƝVݥ~PfAqk=gMz<>F3.zھ DgO NIGD֒N0Fщ 4FW~ i qf W@VR}g1_FExZ?o9 @Y.@8.mPK3YPKk6DHldThumbnails/thumbnail.pngPNG  IHDRixIDATx1 @[~4Ѕ)=3 .|7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|C P7 o(|CnێĘIENDB`PKk6D'Configurations2/accelerator/current.xmlPKk6DWConfigurations2/images/Bitmaps/PK?w6DERz $ content.xml ެެ7]'PKk6Dh 7manifest.rdfPKk6D3!EvMETA-INF/manifest.xmlPK?qD}%$ meta.xml l_ /Bl_ /Bl_ /BPKk6Dl9..mimetypePKk6DͶGp$'  settings.xmlPKk6D3Y sstyles.xmlPKk6DHldThumbnails/thumbnail.pngPK io-2.4.10/inst/templates/PaxHeaders.5973/template.gnumeric0000644000000000000000000000013213226215407020214 xustar0030 mtime=1515789063.600155479 30 atime=1515789063.600155479 30 ctime=1515789065.028183488 io-2.4.10/inst/templates/template.gnumeric0000644000175000017500000000104113226215407020450 0ustar00olafolaf00000000000000ΣoSgnm_templTMo0+,"a]Uj ^wUyߛy3g~Sd5 Fp+Yeey}7`2cͫ(@^{xeBǶ\0NqJdH>><,Xp ̃OJ  6ۭ͠kh GߖpJL8N1n:ooK*,GkpUjSVHG=v+ABOُ@+6l6#@mRDjTp<qUS Ԓ/[Ӈ/3&mQɖaB y[?^/N>e e&qtLSh2g7E"DxN̡kWrl \Kߙ`MBr2 ְW-,[Ӻ\끥p 쯶/Pu.Vʃv2¤7?^!x_AN8 p:8^mk9&:[;OՒio-2.4.10/inst/PaxHeaders.5973/odsopen.m0000644000000000000000000000013213226215407014475 xustar0030 mtime=1515789063.564154773 30 atime=1515789063.564154773 30 ctime=1515789065.028183488 io-2.4.10/inst/odsopen.m0000644000175000017500000002616613226215407014750 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## @deftypefn {Function File} @var{ods} = odsopen (@var{filename}) ## @deftypefnx {Function File} @var{ods} = odsopen (@var{filename}, @var{readwrite}) ## @deftypefnx {Function File} @var{ods} = odsopen (@var{filename}, @var{readwrite}, @var{reqintf}) ## Get a pointer to an OpenOffice_org spreadsheet in the form of return ## argument @var{ods}. ## ## Calling odsopen without specifying a return argument is fairly useless! ## ## Octave links to external software for read/write support of spreadsheets; ## these links are "interfaces". For I/O from/to ODS 1.2 and Gnumeric ## XML, in principle no external SW is required, this "interface" is called ## 'OCT'. For more flexibility and better performance, you need a Java JRE ## or JDK plus one or more of (ODFtoolkit (version 0.7.5 or 0.8.6 - 0.8.8) & ## xercesImpl v.2.9.1), jOpenDocument, or OpenOffice.org (or clones) installed ## on your computer + proper javaclasspath set. These interfaces are referred ## to as OTK, JOD, and UNO resp., and are preferred in that order by default ## (depending on their presence; the OCT interface has lowest priority). ## The relevant Java class libs for spreadsheet I/O had best be added to the ## javaclasspath by utility function chk_spreadsheet_support(). ## For the OTK, JOD and UNO interfaces in Octave older than 3.8.0, the ## octave-forge Java package >=1.2.9 is required. Newer Octave versions ## should have Java support built-in. ## ## @var{filename} must be a valid .ods OpenOffice.org Calc, or Gnumeric, file ## name including .ods or .gnumeric suffix. If @var{filename} does not contain ## any directory path, the file is saved in the current directory. For UNO ## bridge, filenames need to be in the form "file:////filename"; ## a URL will also work. If a plain file name is given (absolute or relative), ## odsopen() will try to transform it into a proper form. ## ## @var{readwrite} must be set to true or numerical 1 if writing to spreadsheet ## is desired immediately after calling odsopen(). It merely serves proper ## handling of file errors (e.g., "file not found" or "new file created"). ## ## Optional input argument @var{reqintf} can be used to override the ODS ## interface automatically selected by odsopen. Currently implemented ## interfaces are 'OTK' (Java/ODF Toolkit), 'JOD' (Java/jOpenDocument), 'UNO' ## (Java/OpenOffice.org UNO bridge), and 'OCT' (native Octave, for Gnumeric. ## In most situations this parameter is unneeded as odsopen ## automatically selects the most useful interface present ("default ## interface"). Depending on file type, odsopen.m can invoke other detected ## interfaces than the default one. ## ## Beware: ## The UNO interface is still experimental. While in itself reliable, it may ## have undesired side effects on Open-/LibreOffice windows outside Octave. ## ## Examples: ## ## @example ## ods = odsopen ('test1.ods'); ## (get a pointer for reading from spreadsheet test1.ods) ## ## ods = odsopen ('test2.ods', [], 'JOD'); ## (as above, indicate test2.ods will be read from; in this case using ## the jOpenDocument interface is requested) ## @end example ## ## @seealso {odsclose, odsread, oct2ods, ods2oct, odsfinfo, chk_spreadsheet_support} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-12-13 function [ ods ] = odsopen (filename, rw=0, reqinterface=[]) persistent odsinterfaces; persistent chkintf; persistent lastintf; if (isempty (chkintf)) odsinterfaces = struct ( "OTK", [], "JOD", [], "UNO", [] , "OCT", []); chkintf = 1; endif if (isempty (lastintf)); lastintf = "---"; endif odsintf_cnt = 1; if (nargout < 1) 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))) error ("odsopen.m: arg # 3 (interface) not recognized\n"); endif ## Turn arg3 into cell array if needed if (! iscell (reqinterface)) reqinterface = {reqinterface}; endif ## Check if previously used interface matches a requested interface if (isempty (regexpi (reqinterface, lastintf, "once"){1})) ## New interface requested. OCT is always supported but it must be ## possible to disable it odsinterfaces.OTK = 0; odsinterfaces.JOD = 0; odsinterfaces.UNO = 0; odsinterfaces.OCT = 0; for ii=1:numel (reqinterface) reqintf = toupper (reqinterface {ii}); ## Try to invoke requested interface(s) for this call. Check if it ## is supported anyway by emptying the corresponding var. if (strcmpi (reqintf, "OTK")) odsinterfaces.OTK = []; elseif (strcmpi (reqintf, "JOD")) odsinterfaces.JOD = []; elseif (strcmpi (reqintf, "UNO")) odsinterfaces.UNO = []; elseif (strcmpi (reqintf, "OCT")) odsinterfaces.OCT = []; else error (sprintf (["odsopen.m: unknown .ods interface \"%s\" requested.\n" ... "Only OTK, JOD, UNO and OCT supported\n"], reqinterface{})); endif endfor printf ("Checking requested interface(s):\n"); odsinterfaces = getodsinterfaces (odsinterfaces); ## Well, is/are the requested interface(s) supported on the system? for ii=1:numel (reqinterface) if (! odsinterfaces.(toupper (reqinterface{ii}))) ## No it aint printf ("%s is not supported.\n", toupper (reqinterface{ii})); else ++odsintf_cnt; endif endfor ## Reset interface check indicator if no requested support found if (! odsintf_cnt) chkintf = []; ods = []; return endif endif else intfmsg = "available"; endif ## Var rw is really used to avoid creating files when wanting to read, or ## not finding not-yet-existing files when wanting to write a new one. ## Be sure it's either 0 or 1 initially if (rw) [~, ~, ext] = fileparts (filename); ## .ods write support is supported rw = 1; endif ## Check if file exists. Set open mode based on rw argument if (rw) fmode = "r+b"; else fmode = "rb"; endif fid = fopen (filename, fmode); if (fid < 0) if (! rw) ## Read mode requested but file doesn't exist err_str = sprintf ("odsopen.m: file %s not found\n", filename); error (err_str) else ## For writing we need more info: fid = fopen (filename, "rb"); ## Check if it can be opened for reading if (fid < 0) ## Not found => create it ## printf ("Creating file %s\n", filename); rw = 3; else ## Found but not writable = error fclose (fid); ## Do not forget to close the handle neatly error (sprintf ("odsopen.m: write mode requested but file %s is not writable\n",... filename)) endif endif else ## Close file anyway to avoid Java errors fclose (fid); endif ## Check for the various ODS interfaces. No problem if they've already ## been checked, getodsinterfaces (far below) just returns immediately then. [odsinterfaces] = getodsinterfaces (odsinterfaces); ## Supported interfaces determined; now check ODS file type. ftype = 0; [~, ~, ext] = fileparts (filename); switch ext case {"xls", ".xls"} ## Because LibreOffice/OpenOffice.org accept Excel as well ftype = 1; case {"xlsx", "xlsm", ".xlsb", ".xlsx", ".xlsm", ".xlsb"} ## Because LibreOffice/OpenOffice.org accept Excel as well ftype = 2; case ".ods" ## ODS 1.2 ftype = 3; case ".sxc" ## jOpenDocument (JOD) can read from .sxc files, ftype = 4; ## but only if odfvsn = 2 case ".gnumeric" ## Zipped XML / gnumeric ftype = 5; case ".csv" ## ODS 1.2 ftype = 6; otherwise endswitch ods = struct ("xtype", [], "app", [], "filename", [], "workbook", [], "changed", 0, "limits", [], "odfvsn", []); ## Preferred interface = OTK (ODS toolkit & xerces), so it comes first. ## Keep track of which interface is selected. Can be used (later) for ## fallback to other interface odssupport = 0; if (odsinterfaces.OTK && ! odssupport && ftype == 3) [ ods, odssupport, lastintf ] = ... __OTK_spsh_open__ (ods, rw, filename, odssupport); endif if (odsinterfaces.JOD && ! odssupport && (ftype == 3 || ftype == 4)) [ ods, odssupport, lastintf ] = ... __JOD_spsh_open__ (ods, rw, filename, odssupport); endif if (odsinterfaces.UNO && ! odssupport && ismember (ftype, [1:3, 6])) [ ods, odssupport, lastintf ] = ... __UNO_spsh_open__ (ods, rw, filename, odssupport); endif if (odsinterfaces.OCT && ! odssupport && ismember (ftype, [2, 3, 5])) [ ods, odssupport, lastintf ] = ... __OCT_spsh_open__ (ods, rw, filename, odssupport, ftype); endif ## if ## if (! odssupport) ## Below message follows after getodsinterfaces printf ("None.\n"); warning ("odsopen.m: no %s spreadsheet I/O support with %s interface(s).\n", ... ext, intfmsg); ods = []; chkintf = []; else # From here on rw is tracked via ods.changed in the various lower # level r/w routines and it is only used to determine if an informative # message is to be given when saving a newly created ods file. ods.changed = rw; # ods.changed = 0 (existing/only read from), 1 (existing/data added), 2 (new, # data added) or 3 (pristine, no data added). # Until something was written to existing files we keep status "unchanged". if (ods.changed == 1); ods.changed = 0; endif endif endfunction io-2.4.10/inst/PaxHeaders.5973/chk_spreadsheet_support.m0000644000000000000000000000013213226215407017756 xustar0030 mtime=1515789063.556154616 30 atime=1515789063.556154616 30 ctime=1515789065.028183488 io-2.4.10/inst/chk_spreadsheet_support.m0000644000175000017500000005606013226215407020225 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {[ @var{retval}, @var{intfs}, @var{ljars} ]} = chk_spreadsheet_support () ## @deftypefnx {Function File} {[ @var{retval}, @var{intfs}, @var{ljars} ]} = chk_spreadsheet_support ( @var{path_to_jars} ) ## @deftypefnx {Function File} {[ @var{retval}, @var{intfs}, @var{ljars} ]} = chk_spreadsheet_support ( @var{path_to_jars}, @var{debug_level} ) ## @deftypefnx {Function File} {[ @var{retval}, @var{intfs}, @var{ljars} ]} = chk_spreadsheet_support ( @var{path_to_jars}, @var{debug_level}, @var{path_to_ooo} ) ## Check Octave environment for spreadsheet I/O support, report any problems, ## and optionally add or remove Java class libs for spreadsheet support. ## ## chk_spreadsheet_support first checks ActiveX (native MS-Excel); then ## Java JRE presence, then Java support (if builtin); then checks existing ## javaclasspath for Java class libraries (.jar files) needed for various ## Java-based spreadsheet I/O interfaces. If requested chk_spreadsheet_support ## will try to add the relevant Java class libs to the dynamic javaclasspath. ## chk_spreadsheet_support remembers which Java class libs it has added to ## the javaclasspath; optionally it can unload them as well. ## ## @var{path_to_jars} - relative or absolute path name to subdirectory ## containing these classes. TAKE NOTICE: /forward/ slashes are needed! ## chk_spreadsheet_support() will recurse into at most two subdir levels; ## if the Java class libs are scattered across deeper subdir levels or ## further apart in the file system, multiple calls to ## chk_spreadsheet_support may be required. @var{path_to_jars} can be [] ## or '' if no class libs need to be added to the javaclasspath. ## ## @var{path_to_ooo} - installation directory of OpenOffice.org (again with ## /forward/ slashes). Usually that is something like (but no guarantees): ## @table @asis ## - Windows: C:/Program Files/OpenOffice.org or ## C:/Program Files (X86)/LibreOffice ## ## - *nix: /usr/lib/ooo or /opt/libreoffice ## ## - Mac OSX: ????? ## ## IMPORTANT: @var{path_to_ooo} should be such that both: ## @example ## @group ## 1. PATH_TO_OOO/program/ ## and ## 2. PATH_TO_OOO/ure/.../ridl.jar ## resolve OK. ## @end group ## @end example ## @end table ## ## (Note that LibreOffice/OOo should match the bit width (32bit or 64bit) of the ## Java version Octave was built with.) ## ## @var{debug_level}: (integer) between [0 (no output) .. 3 (full output] ## @table @asis ## @indent ## @item 0 ## No debug output is generated. ## ## @item 1 ## Only proper operation of main interface groups (COM, Java) is shown. ## If @var{path_to_jars} and/or @var{path_to_ooo} was supplied, ## chk_spreadsheet_support indicates whether it could find the required ## Java class libs for all interfaces ## ## @item 2 ## Like 1, proper working of individual implemented Java-based interfaces is ## shown as well. If @var{path_to_jars} and/or @var{path_to_ooo} was supplied, ## chk_spreadsheet_support indicates for each individual Java-based interface ## whether it could add the required Java class libs. ## ## @item 3 ## Like 2, also presence of individual javaclass libs in javaclasspath is ## indicated. If @var{path_to_jars} and/or @var{path_to_ooo} was supplied, ## chk_spreadsheet_support reports for each individual Java-based interface ## which required Java class libs it could find and add to the javaclasspath. ## ## @item -1 (or any negative number) ## Remove all directories and Java class libs that chk_spreadsheet_support ## added to the javaclasspath. If @var{debug_level} < 1 report number of ## removed javclasspath entries; if @var{debug_level} < 2 report each ## individual removed entry. ## @noindent ## @end table ## ## Output: ## @var{retval} = 0: only spreadsheet support for OOXML & ODS 1.2 ## and read support for gnumeric present through OCT interface, or ## @var{retval} <> 0: At least one read/write spreadsheet I/O ## interface found based on external software. ## RETVAL will be set to the sum of values for found interfaces: ## @example ## 0 = OCT (Native Octave) ## (read/write support for .xlsx, .ods and .gnumeric) ## ----------- XLS (Excel) interfaces: ---------- ## 1 = COM (ActiveX / Excel) (any file format supported by MS-Excel) ## 2 = POI (Java / Apache POI) (Excel 97-2003 = BIFF8) ## 4 = POI+OOXML (Java / Apache POI) (Excel 2007-2010 = OOXML) ## 8 = JXL (Java / JExcelAPI) (Excel 95-read and Excel-97-2003-r/w) ## 16 = OXS (Java / OpenXLS) (Excel 97-2003) ## ---- ODS (OpenOffice.org Calc) interfaces ---- ## 32 = OTK (Java/ ODF Toolkit) (ODS 1.2) ## 64 = JOD (Java / jOpenDocument) (.sxc (old OOo)-read, ODS 1.2) ## ------------------ XLS & ODS: ---------------- ## 0 = OOXML / ODS read/write-, gnumeric read support (built-in) ## 128 = UNO (Java/UNO bridge - LibreOffice / OOs) (any format ## supported by LibreOffice/OOo) ## @end example ## ## @var{INTFS}: listing of supported spreadsheet interfaces. The OCT ## interface is always supported. ## ## @var{ljars}: listing of full paths of Java class libs and directories ## that chk_spreadsheet_support has added to the javaclasspath. ## ## @end deftypefn ## Author: Philip Nienhuis ## Created 2010-11-03 for Octave function [ retval, s_interfaces, jars_loaded ] = chk_spreadsheet_support (path_to_jars, dbug, path_to_ooo) ## Keep track of which Java class libs were loaded persistent loaded_jars; ## Java .jar class libs added to ## javaclasspath by this func persistent sinterfaces; ## Interfaces found to be supported sinterfaces = {"OCT"}; jcp = []; retval = 0; if (nargin < 3) path_to_ooo= ""; endif if (nargin < 2) dbug = 0; endif HAVE_JAVA = __have_feature__ ("JAVA"); if (dbug < 0 && HAVE_JAVA) ## Remove loaded Java class libs from the javaclasspath if (dbug < -2 && numel (loaded_jars)) printf ("Removing javaclasspath entries loaded by chk_spreadsheet_support:\n"); endif for ii=1:numel (loaded_jars) javarmpath (loaded_jars{ii}); if (dbug < -2) printf ("%s\n", loaded_jars{ii}); endif endfor if (dbug < -1) printf ("%d jars removed from javaclasspath\n", numel (loaded_jars)); endif loaded_jars = {}; ## Re-assess supported interfaces sinterfaces = {"OCT"}; retval = 0; if (ismember ("COM", sinterfaces)) sinterfaces = [sinterfaces, "COM"]; retval = 1; endif jars_loaded = loaded_jars; s_interfaces = sinterfaces; return elseif (dbug > 0) printf ("\n"); endif interfaces = {"COM", "POI", "POI+OOXML", "JXL", "OXS", "OTK", "JOD", "UNO", "OCT"}; ## Order = vital ## Just mention OCT interface if (dbug > 1) printf ("(OCT interface... OK, included in io package)\n\n"); endif ## Check if MS-Excel COM ActiveX server runs. Only needed on Windows systems if (ispc) if (__COM_chk_sprt__ (dbug)) retval = retval + 1; sinterfaces = [ sinterfaces, "COM" ]; endif endif ## Check Java if (dbug > 1) printf ("1. Checking Octave's Java support... "); endif if (! HAVE_JAVA) ## Nothing to do here anymore if (abs (dbug) > 1) printf ("none.\nThis Octave has no built-in Java support. Skipping Java checks\n"); if (! retval) printf ("Only ODS 1.2 (.ods) & OOXML (.xlsx) & .gnumeric r/w support present\n"); endif endif return elseif (dbug > 1) printf ("OK.\n"); endif if (dbug > 1) printf ("2. Checking Java dependencies...\n"); endif if (dbug > 1) printf (" Checking Java JRE presence.... "); endif ## Try if Java is installed at all if (ispc) ## FIXME the following call fails on 64-bit Windows jtst = (system ("java -version 2> nul")); else jtst = (system ("java -version 2> /dev/null")); endif if (dbug) if (jtst) printf ("Apparently no Java JRE installed.\n"); if (! retval) printf ("\nOnly ODS 1.2 (.ods) & OOXML (.xlsx) r/w support & .gnumeric read support present\n"); endif return; else if (dbug > 1) printf ("OK, found one.\n"); endif endif endif try ## OK sufficient info to investigate further [tmp1, jcp] = __chk_java_sprt__ (dbug); if (tmp1) if (dbug > 1) ## Check JVM virtual memory settings jrt = javaMethod ("getRuntime", "java.lang.Runtime"); jmem = jrt.maxMemory (); ## Some Java versions return jmem as octave_value => convert to double if (! isnumeric (jmem)) jmem = jmem.doubleValue(); endif jmem = int16 (jmem/1024/1024); printf (" Maximum JVM memory: %5d MiB; ", jmem); if (jmem < 400) printf ("should better be at least 400 MB!\n"); printf (" Hint: adapt setting -Xmx in file 'java.opts' (supposed to be here:)\n"); printf (" %s\n", [matlabroot filesep "share" filesep "octave" filesep "packages" filesep "java-" filesep "java.opts\n"]); else printf ("sufficient.\n"); endif endif endif catch ## No Java support tmp1 = 0; end_try_catch if (! tmp1) ## We can return as for below code Java is required. if (dbug > 1) printf ("No Java support found.\n"); if (! retval) printf ("Only ODS 1.2 (.ods) & OOXML (.xlsx) r/w support & .gnumeric read support present\n"); endif endif return endif if (dbug) printf ("Checking javaclasspath for .jar class libraries needed for spreadsheet I/O...:\n"); endif ## FIXME Below only the javaclasspath is checked. Some unsupported .jar ## versions can only be detected after they've been added to the ## javaclasspath. That happens lower in the code; so shortly after that ## we run another check for version and if needed, call the below ## interface-specific functions again to remove the offending jar from ## the javaclasspath. All in all messy, but there's no other way yet. ## Try Java & Apache POI [chk, missing1, missing2] = __POI_chk_sprt__ (jcp, dbug); if (chk) sinterfaces = [ sinterfaces, "POI" ]; retval += 2; if (isempty (missing2)) sinterfaces = [ sinterfaces, "POI+OOXML" ]; retval += 4; endif endif ## Try Java & JExcelAPI [chk, missing3] = __JXL_chk_sprt__ (jcp, dbug); if (chk) retval = retval + 8; sinterfaces = [ sinterfaces, "JXL" ]; endif ## Try Java & OpenXLS [chk, missing4] = __OXS_chk_sprt__ (jcp, dbug); ## Beware of unsupported openxls jar versions if (isempty (missing4) && chk) retval = retval + 16; sinterfaces = [ sinterfaces, "OXS" ]; elseif (chk < 0) ## Probably unsupported jar versions. Avoid loading it missing4 = {}; endif ## Try Java & ODF toolkit [chk, missing5] = __OTK_chk_sprt__ (jcp, dbug); ## Beware of unsupported odfdom jar versions if (isempty (missing5) && chk) retval = retval + 32; sinterfaces = [ sinterfaces, "OTK" ]; elseif (chk < 0) ## Probably unsupported jar versions. Avoid reloading it missing5 = {}; endif ## Try Java & jOpenDocument [chk, missing6] = __JOD_chk_sprt__ (jcp, dbug); if (isempty (missing6) && chk) retval = retval + 64; sinterfaces = [ sinterfaces, "JOD" ]; endif ## Try Java & UNO [chk, missing0] = __UNO_chk_sprt__ (jcp, dbug); if (isempty (missing0) && chk) retval = retval + 128; sinterfaces = [ sinterfaces, "UNO" ]; endif ## ----------Add missing jars for Java interfaces except UNO-------------------- missing = [missing1 missing2 missing3 missing4 missing5 missing6]; jars_complete = isempty (missing); if (dbug) if (jars_complete) printf ("All Java-based interfaces (save UNO) fully supported.\n\n"); else printf ("Some class libs lacking yet...\n\n"); endif endif if (! jars_complete && nargin > 0 && ! isempty (path_to_jars)) ## Add missing jars to javaclasspath. Assume they're all in the same place ## FIXME: add checks for proper odfdom && OpenXLS jar versions if (dbug) printf ("Trying to add missing java class libs to javaclasspath...\n"); endif if (! ischar (path_to_jars)) printf ("Path expected for arg # 1\n"); return; endif ## First combine all entries targt = numel (missing); ## For each interface, search tru list of missing entries for ii=1:6 ## Adapt number in case of future new interfaces tmpm = eval ([ "missing" char(ii + "0") ]); tmpmcnt = numel (tmpm); if (tmpmcnt) for jj=1:numel (tmpm) if (iscellstr (tmpm{jj})) rtval = 0; kk = 1; while (kk <= numel (tmpm{jj}) && isnumeric (rtval)) jtmpm = tmpm{jj}{kk}; rtval = add_jars_to_jcp (path_to_jars, jtmpm, dbug); ++kk; endwhile else rtval = add_jars_to_jcp (path_to_jars, tmpm{jj}, dbug); endif ## Here's the moment to run checks for unsupported .jar versions. switch ii case 2 ## Apache POI, for POI >= 3.15 ## Check if common-collections4 is req'd (only for POI >= 3.15) try poiv = javaObject ("org.apache.poi.Version").getVersion(); if (compare_versions (poiv, "3.14", "<=") && strncmpi (tmpm{jj}, "commons-collections4", 8)) --targt; --tmpmcnt; endif catch ## Happens when POI hasn't been completely loaded yet. ## No action needed end_try_catch case 4 ## OpenXLS chk = __OXS_chk_sprt__ (javaclasspath, dbug); if (chk < 0) rtval = 0; endif case 5 ## ODFDOM chk = __OTK_chk_sprt__ (javaclasspath, dbug); if (chk < 0) rtval = 0; endif otherwise endswitch if (ischar (rtval)) --targt; --tmpmcnt; if (isempty (loaded_jars)) ## Make sure we get a cellstr array loaded_jars = {rtval}; else loaded_jars = [ loaded_jars; rtval ]; endif endif endfor if (! tmpmcnt) retval = retval + 2^ii; endif endif if (! tmpmcnt && ! any (ismember (sinterfaces, interfaces{ii+1}))) ## Add interface to list. COM = 1, so start at #2 (add 1 to ii) sinterfaces = [ sinterfaces, interfaces{ii+1} ]; ## Consider POI+OOXML i.c.o. adding plain POI if (ii == 1 && isempty (missing2)) ## Apparently only POI itself missed jars, POI+OOXML was complete sinterfaces = [ sinterfaces, interfaces{ii+2} ]; retval = retval + 4; endif endif endfor if (dbug) if (targt) printf ("Some class libs still lacking...\n\n"); endif endif endif ## ----------UNO (LO / OOo) ---------- (still experimental) ## If requested, try to add UNO stuff to javaclasspath ujars_complete = isempty (missing0); if ((! ujars_complete) && nargin > 0 && (! isempty (path_to_ooo))) if (dbug) printf ("\nTrying to add missing program subdir & UNO Java class libs to javaclasspath...\n"); endif if (! ischar (path_to_ooo)) printf ("Path expected for arg # 3\n"); return; endif if (dbug && ! isempty (strfind (path_to_ooo, '\'))) printf ("\n(forward slashes are preferred over backward slashes in path)\n"); endif ## Add missing jars to javaclasspath. ## 1. Find out how many are still lacking targt = numel (missing0); ## 2. Find where URE is located. Watch out because ## case of ./ure is unknown uredir = get_dir_ (path_to_ooo, "ure"); new_lo = 0; if (isempty (uredir)) ## In newer LO, java jars live in /program/classes uredir = get_dir_ ([path_to_ooo filesep "program"], "classes"); new_lo = 1; endif if (isempty (uredir)) if (dbug > 1) warning ("Wrong path to OOo/LO, or incomplete OOo/LO installation\n"); endif return endif ## 3. Most jars live in ./ure/share/java or ./ure/java. Construct unojarpath if (new_lo) ## Newer LO version? /progam/classes has no "java" subdir unojarpath = uredir; else unojardir = get_dir_ (uredir, "share"); if (isempty (unojardir)) tmp = uredir; else tmp = unojardir; endif unojarpath = get_dir_ (tmp, "java"); endif ## 4. Now search for UNO jars. There may be two special cases A. and B. for ii=1:numel (missing0) if (strcmpi (missing0{ii}, "program")) ## A. Add program dir (= where soffice or soffice.exe or ooffice resides) programdir = [path_to_ooo filesep missing0{ii}]; if (exist (programdir, "dir")) if (dbug > 2) printf (" Found %s, adding it to javaclasspath ... ", programdir); endif try javaaddpath (programdir); targt -= targt; if (dbug > 2) printf ("OK\n"); endif if (isempty (loaded_jars)) loaded_jars = { programdir }; else loaded_jars = [ loaded_jars; programdir]; endif catch if (dbug > 2) printf ("FAILED\n"); endif end_try_catch else if (dbug > 2) printf ("Suggested OpenOffice.org install directory: %s not found!\n", ... path_to_ooo); return endif endif else ## Rest of missing UNO entries if (new_lo) ## Search in /program/classes sfile = dir ([unojarpath filesep missing0{ii} "*"]); jfile = [unojarpath filesep sfile.name]; elseif (strcmpi (missing0{ii}, "unoil")) ## B. Special case as unoil.jar usually resides in ## ./Basis/program/classes ## Find out the exact name of Basis..... basisdirlst = dir ([path_to_ooo filesep "?asis" "*"]); jj = 1; if (numel (basisdirlst) > 0) while (jj <= size (basisdirlst, 1) && jj > 0) basisdir = basisdirlst(jj).name; if (basisdirlst(jj).isdir) basisdir = basisdirlst(jj).name; jj = 0; else jj = jj + 1; endif endwhile basisdir = [path_to_ooo filesep basisdir ]; else basisdir = path_to_ooo; endif basisdirentries = {"program", "classes"}; tmp = basisdir; jj=1; while (! isempty (tmp) && jj <= numel (basisdirentries)) tmp = get_dir_ (tmp, basisdirentries{jj}); jj = jj + 1; endwhile ## sfile below = struct, not a string sfile = dir ([ tmp filesep missing0{ii} "*" ]); jfile = [tmp filesep sfile.name]; else ## A "normal" case. sfile = struct, not a string sfile = dir ([unojarpath filesep missing0{ii} "*"]); jfile = [unojarpath filesep sfile.name]; endif ## Path found, now try to add jar if (isempty (sfile)) if (dbug > 2) printf (" ? %s<...>.jar ?\n", missing0{ii}); endif else if (dbug > 2) printf (" Found %s, adding it to javaclasspath ... ", sfile.name); endif try javaaddpath (jfile); targt -= targt; if (dbug > 2) printf ("OK\n"); endif if (isempty (loaded_jars)) loaded_jars = {jfile}; else loaded_jars = [ loaded_jars; jfile ]; endif catch if (dbug > 2) printf ("FAILED\n"); endif end_try_catch endif endif endfor ## Check if all entries have been found if (! targt) ## Yep retval = retval + 128; sinterfaces = [sinterfaces, "UNO"]; endif if (dbug) if (targt) printf ("Some UNO class libs still lacking...\n\n"); else printf ("UNO interface supported now.\n\n"); endif endif endif jars_loaded = loaded_jars; s_interfaces = sinterfaces; endfunction function [ ret_dir ] = get_dir_ (base_dir, req_dir) ## Construct path to subdirectory req_dir in a subdir tree, aimed ## at taking care of proper case (esp. for *nix) of existing subdir ## in the result. Case of input var req_dir is ignored on purpose. ret_dir = ''; ## Get list of directory entries ret_dir_list = dir (base_dir); ## Find matching entries idx = find (strcmpi ({ret_dir_list.name}, req_dir)); ## On *nix, several files and subdirs in one dir may have the same name as long as case differs if (! isempty (idx)) ii = 1; while (! ret_dir_list(idx(ii)).isdir) ii = ii + 1; if (ii > numel (idx)) return; endif endwhile ## If we get here, a dir with proper name has been found. Construct path ret_dir = [ base_dir filesep ret_dir_list(idx(ii)).name ]; endif endfunction function [ retval ] = add_jars_to_jcp (path_to_jars, jarname, dbug) ## Given a subdirectory path and a (sufficiently unique part of a) Java class ## lib file (.jar) name, checks if it can find the file in the subdir and ## tries to add it to the javaclasspath. Only two more subdir levels below the ## path_to_jar subdir will be searched to limit excessive search time. ## If found, return the full pathname retval = 0; ## Search subdirs. Max search depth = 2 to avoid undue search time file = rfsearch (path_to_jars, jarname, 2); if (isempty (file)) ## Still not found... if (dbug > 2) printf (" ? %s<...>.jar ?\n", jarname); endif elseif (stat ([path_to_jars filesep file]).size < 1024) ## Probably too small for a jar => apparently a symlink if (dbug > 2) printf (" File %s is probably a symlink ... \n", file); endif else ## FIXME: cache subdir in file name to speed up search if (dbug > 2) printf (" Found %s, adding it to javaclasspath ... ", file); endif try javaaddpath ([path_to_jars filesep file]); if (dbug > 2) printf ("OK\n"); endif retval = [path_to_jars filesep file]; catch if (dbug > 2) printf ("FAILED\n"); endif end_try_catch endif endfunction io-2.4.10/inst/PaxHeaders.5973/xlsclose.m0000644000000000000000000000013213226215407014662 xustar0030 mtime=1515789063.604155557 30 atime=1515789063.604155557 30 ctime=1515789065.028183488 io-2.4.10/inst/xlsclose.m0000644000175000017500000001250113226215407015121 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [@var{xls}] = xlsclose (@var{xls}) ## @deftypefnx {Function File} [@var{xls}] = xlsclose (@var{xls}, @var{filename}) ## @deftypefnx {Function File} [@var{xls}] = xlsclose (@var{xls}, "FORCE") ## Close the Excel spreadsheet pointed to in struct @var{xls}, if needed ## write the file to disk. Based on information contained in @var{xls}, ## xlsclose will determine if the file should be written to disk. ## ## If no errors occured during writing, the xls file pointer struct will be ## reset and -if COM interface was used- ActiveX/Excel will be closed. ## However if errors occurred, the file pointer will be untouched so you can ## clean up before a next try with xlsclose(). ## Be warned that until xlsopen is called again with the same @var{xls} pointer ## struct, hidden Excel or Java applications with associated (possibly large) ## memory chunks are kept in memory, taking up resources. ## If (string) argument "FORCE" is supplied, the file pointer will be reset ## regardless, whether the possibly modified file has been saved successfully ## or not. Hidden Excel (COM) or OpenOffice.org (UNO) invocations may live on, ## possibly even impeding proper shutdown of Octave. ## ## @var{filename} can be used to write changed spreadsheet files to ## an other file than opened with xlsopen(); unfortunately this doesn't work ## with JXL (JExcelAPI) interface. ## ## For other file formats than OOXML, ODS or gnumeric, you need MS-Excel ## (95 - 2010), and/or the Java package => 1.2.8 plus Apache POI > 3.5 and/or ## JExcelAPI and/or OpenXLS and/or OpenOffice.org or clones installed on your ## computer + proper javaclasspath set, to make this function work at all. ## For Octave >= 3.8.0 the Java package isn't needed as Java support should ## be built-in. ## ## @var{xls} must be a valid pointer struct made by xlsopen() in the same ## octave session. ## ## Examples: ## ## @example ## xls1 = xlsclose (xls1); ## (Close spreadsheet file pointed to in pointer struct xls1; xls1 is reset) ## @end example ## ## @seealso {xlsopen, xlsread, xlswrite, xls2oct, oct2xls, xlsfinfo} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-11-29 function [ xls ] = xlsclose (xls, varargin) if (isempty (xls)) warning ("xlsclose: file pointer struct was already closed\n"); return endif force = 0; if (nargin > 1) for ii=1:nargin-1 if (strcmpi (varargin{ii}, "force")) ## Close .xls anyway even if write errors occur force = 1; ## Interface-specific clauses here: elseif (! isempty (strfind (tolower (varargin{ii}), "."))) ## Apparently a file name. First some checks.... if (xls.changed == 0 || xls.changed > 2) warning ("xlsclose: file %s wasn't changed, new filename ignored.\n", xls.filename); elseif (strcmp (xls.xtype, "JXL")) error ("xlsclose: JXL doesn't support changing filename, new filename ignored.\n"); elseif (isempty (strfind ( lower (varargin{ii}), ".xls")) && ... (! (strcmp (xls.xtype, "COM") || strcmp (xls.xtype, "UNO")))) # Excel/ActiveX && OOo (UNO bridge) will write any valid filetype; POI/JXL/OXS need .xls[x] error ("xlsclose: .xls or .xlsx suffix lacking in filename %s\n", varargin{ii}); else ## For multi-user environments, uncomment below AND relevant stanza in xlsopen ## In case of COM, be sure to first close the open workbook ##if (strcmp (xls.xtype, 'COM')) ## xls.app.Application.DisplayAlerts = 0; ## xls.workbook.close(); ## xls.app.Application.DisplayAlerts = 0; ##endif ## Preprocessing / -checking ready. Assign filename arg to file ptr struct xls.nfilename = varargin{ii}; endif endif endfor endif if (strcmp (xls.xtype, "COM")) xls = __COM_spsh_close__ (xls); elseif (strcmp (xls.xtype, "POI")) xls = __POI_spsh_close__ (xls); elseif (strcmp (xls.xtype, "JXL")) xls = __JXL_spsh_close__ (xls); elseif (strcmp (xls.xtype, "OXS")) xls = __OXS_spsh_close__ (xls); elseif (strcmp (xls.xtype, "UNO")) xls = __UNO_spsh_close__ (xls, force); elseif (strcmp (xls.xtype, "OCT")) xls = __OCT_spsh_close__ (xls, "xlsclose"); ## elseif endif if (xls.changed && xls.changed < 3) warning (sprintf ("xlsclose: file %s could not be saved. Read-only or in use elsewhere?\n", ... xls.filename)); if (force) xls = []; else printf ("(File pointer preserved. Try saving again later...)\n"); endif else xls = []; endif endfunction io-2.4.10/inst/PaxHeaders.5973/append_save.m0000644000000000000000000000013213226215407015313 xustar0030 mtime=1515789063.556154616 30 atime=1515789063.556154616 30 ctime=1515789065.028183488 io-2.4.10/inst/append_save.m0000644000175000017500000001005713226215407015556 0ustar00olafolaf00000000000000## Copyright (C) 2003 Tomer Altman ## ## 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 . ## append_save M-file function ## ## Objective: be able to add variables to existing save files. Works for ## all the types of save files that "save" supports. ## ## Input: ## 1) A string which specifies the existing save file. ## 2) The options you need to pass to the 'save' function to save to the ## file type that you want. ## 3) A 1x2 cell, with the first element being a string representation ## of the variable/symbol that you're trying to add, followed by the ## actual variable/symbol itself. ## 4) Any number of additional 1x2 cells, following the same format as ## the 3rd argument specified immediately before this one. ## ## Output: ## Currently, none. But there might be some debugging / error-code ## messages in the future. ## ## Example: ## octave> B = ones(2,2); ## octave> append_save( "test.txt", "-binary", {"B", B } ) function [ return_value ] = append_save ( filename, option, var_val_cell, varargin ) ## Input checking: if ( nargin < 3 ) error("append_save: needs three arguments."); elseif ( !ischar(filename) ) error("append_save: filename must be a string."); elseif ( !ischar(option) ) error("append_save: option must be a string." ); elseif ( !iscell(var_val_cell) ) error("append_save: variable-value pairs must be cells.") elseif ( nargin > 3 ) for i=1:(nargin-3) current_cell = varargin(i); if ( !iscell(current_cell) ) error("append_save: variable-value pairs must be cells."); elseif ( ( columns( current_cell ) != 2 ) || ( rows( current_cell ) != 1 ) ) error("append_save: variable-value pairs must be 1x2 cells.") elseif ( !ischar(current_cell{1} ) ) error("append_save: variable in pair must be a string." ) endif endfor endif ## First step: load into the environment what is already stuffed in ## the target file. Then, add their name to the list for "save". env1 = who; eval([ "load -force ", ... option, " ", ... filename ] ); env2 = who; num_orig_vars = rows(env1); # Not really 'current' env... num_current_vars = rows(env2); num_new_vars = num_current_vars - num_orig_vars; var_str = ""; ## This double 'for loop' weeds out only the loaded vars for ## inclusion. if ( num_new_vars ) for i=1:num_current_vars current_var = env2{i,1}; old_bool = 0; for j=1:num_orig_vars if ( strcmp( env1{j,1}, env2{i,1} ) || strcmp( env2{i,1}, "env1" ) ) old_bool = 1; endif endfor if ( old_bool == 0 ) var_name = env2{i,1}; var_str = [ var_str, " ", var_name, " " ]; endif endfor endif ## Second step: load into the environment the variable pairs. Then, ## add the name to the string for "save". var_name = var_val_cell{1}; var_val = var_val_cell{2}; temp = var_val; eval([ var_name, "=temp;" ]); var_str = [ var_str, " ", var_name, " " ]; ## Third step: do the same as step two, but loop through the possible ## variable arguments. for i=1:(nargin-3) current_cell = varargin(i); var_name = current_cell{1}; var_val = current_cell{2}; temp = var_val; eval([ var_name, "=temp;" ]); var_str = [ var_str, " ", var_name, " " ]; var_str endfor ## Finally, save all of the variables into the target file: eval( [ "save ", ... option, " ", ... filename, " ", var_str; ] ); endfunction io-2.4.10/inst/PaxHeaders.5973/fexist.m0000644000000000000000000000013213226215407014330 xustar0030 mtime=1515789063.556154616 30 atime=1515789063.556154616 30 ctime=1515789065.028183488 io-2.4.10/inst/fexist.m0000644000175000017500000000467113226215407014600 0ustar00olafolaf00000000000000## Copyright (C) 2008 Jaroslav Hajek ## ## 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 . ## -*- texinfo -*- ## @deftypefn{Function File} ex = fexist (file, tspec, aspec) ## Checks whether a file exists. ## @var{file} is the queried file path. ## @var{tspec} is a combination of letters f,d,p,S, corresponding ## to file types: ## @itemize ## @item f: regular file ## @item d: directory ## @item p: named pipe (FIFO special file) ## @item S: socket ## @end itemize ## ## The query is true if the actual file type matches any of ## the specified options. ## ## @var{aspec} is a combination of letters r,w,x, corresponding ## to queried access privileges to the file. The query is true ## if the current user has all the spefied types of access, either ## through "user", "group" or "other" specs. ## ## @seealso{stat, lstat} ## @end deftypefn function ex = fexist (file, tspec, aspec) s = stat (file); if (isempty (s)) ex = 0; else ex = 1; if (nargin >= 2 && ! isempty (tspec)) ft = 0; for c = tspec switch (c) case 'f' ft |= S_ISREG (s.mode); case 'd' ft |= S_ISDIR (s.mode); case 'p' ft |= S_ISFIFO (s.mode); case 'S' ft |= S_ISSOCK (s.mode); otherwise error ("invalid file type spec: %s", c) endswitch endfor ex &= ft; endif if (ex && nargin >= 3 && ! isempty (aspec)) at = 1; mypid = (s.uid == getuid ()); mygid = (s.gid == getgid ()); mstr = s.modestr(2:end); for c = aspec switch (c) case 'r' at &= (mypid && mstr(1) == c) || (mygid && mstr(4) == c) || mstr(7) == c; case 'w' at &= (mypid && mstr(2) == c) || (mygid && mstr(5) == c) || mstr(8) == c; case 'x' at &= (mypid && mstr(3) == c) || (mygid && mstr(6) == c) || mstr(9) == c; otherwise error ("invalid access type spec: %s", c) endswitch endfor ex &= at; endif endif io-2.4.10/inst/PaxHeaders.5973/xlsopen.m0000644000000000000000000000013213226215407014516 xustar0030 mtime=1515789063.604155557 30 atime=1515789063.604155557 30 ctime=1515789065.028183488 io-2.4.10/inst/xlsopen.m0000644000175000017500000003434413226215407014766 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## @deftypefn {Function File} @var{xls} = xlsopen (@var{filename}) ## @deftypefnx {Function File} @var{xls} = xlsopen (@var{filename}, @var{readwrite}) ## @deftypefnx {Function File} @var{xls} = xlsopen (@var{filename}, @var{readwrite}, @var{reqintf}) ## Get a pointer to an Excel spreadsheet in the form of return argument ## (file pointer struct) @var{xls}. After processing the spreadsheet, ## the file pointer must be explicitly closed by calling xlsclose(). ## ## Calling xlsopen without specifying a return argument is fairly useless! ## ## xlsopen works with interfaces, which are links to external software. ## For I/O from/to OOXML (Excel 2007 and up), ODS 1.2 and Gnumeric, no ## additional software is required when the OCT interface is used (see below). ## For all other spreadsheet formats, you need one or more of MS-Excel ## (95 - 2013), or a Java JRE plus Apache POI >= 3.5 and/or JExcelAPI ## and/or OpenXLS and/or OpenOffice.org (or clones) installed on your computer ## + proper javaclasspath set. These interfaces are referred to as COM, POI, ## JXL, OXS, and UNO, resp., and are preferred in that order by default ## (depending on their presence). Currently the OCT interface has the lowest ## priority as it is still experimental. ## For OOXML read/write support in principle no additional SW is needed. ## However, the COM, POI and UNO interfaces may provide better OOXML write ## performance and/or more flexibility. ## Excel'95 spreadsheets (BIFF5) can only be read using the COM (Excel-ActiveX), ## JXL (JExcelAPI), and UNO (Open-/LibreOffice) interfaces. ## ## @var{filename} should be a valid .xls or .xlsx Excel file name (including ## extension). But if you use the COM interface you can specify any extension ## that your installed Excel version can read AND write; the same goes for UNO ## (OpenOffice.org). Using the other Java interfaces, only .xls or .xlsx are ## allowed. If @var{filename} does not contain any directory path, the file ## is saved in the current directory. Reading/writing .xlsm and .xlsb files ## may be possible using the COM and UNO interfaces only, but is untested. ## ## If @var{readwrite} is set to 0 (default value) or omitted, the spreadsheet ## file is opened for reading. If @var{readwrite} is set to true or 1, a ## spreadsheet file is opened (or created) for reading & writing. ## ## Optional input argument @var{reqintf} can be used to override the Excel ## interface that otherwise is automatically selected by xlsopen. Currently ## implemented interfaces (in order of preference) are 'COM' (Excel/COM), ## 'POI' (Java/Apache POI), 'JXL' (Java/JExcelAPI), 'OXS' (Java/OpenXLS), ## 'UNO' (Java/OpenOffice.org - EXPERIMENTAL!), or 'OCT' (native Octave). ## In most situations this parameter is unneeded as xlsopen automatically ## selects the most useful interface present. ## ## Beware: Excel invocations may be left running invisibly in case of COM ## errors or forgetting to close the file pointer. Similarly for OpenOffice.org ## which may even prevent Octave from being closed. ## ## Examples: ## ## @example ## xls = xlsopen ('test1.xls'); ## (get a pointer for reading from spreadsheet test1.xls) ## ## xls = xlsopen ('test2.xls', 1, 'POI'); ## (as above, indicate test2.xls will be written to; in this case using Java ## and the Apache POI interface are requested) ## @end example ## ## @seealso {xlsclose, xlsread, xlswrite, xls2oct, oct2xls, xlsfinfo} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-11-29 function [ xls ] = xlsopen (filename, xwrite=0, reqinterface=[]) persistent xlsinterfaces; persistent chkintf; persistent lastintf; ## xlsinterfaces. = [] (not yet checked), 0 (found to be unsupported) or 1 (OK) if (isempty (chkintf)); chkintf = 1; xlsinterfaces = struct ('COM', [], 'POI', [], 'JXL', [], 'OXS', [], 'UNO', [], "OCT", 1); endif if (isempty (lastintf)) lastintf = "---"; endif xlsintf_cnt = 1; xlssupport = 0; if (nargout < 1) error ("xlsopen.m: no return argument specified!\n usage: XLS = xlsopen (Xlfile [, Rw] [, reqintf])\n"); endif if (! (islogical (xwrite) || isnumeric (xwrite))) 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))) error ("Arg ## 3 (interface) not recognized - character value required\n"); endif ## Turn arg3 into cell array if needed if (! iscell (reqinterface)) reqinterface = {reqinterface}; endif ## Check if previously used interface matches a requested interface if (isempty (regexpi (reqinterface, lastintf, 'once'){1}) || ! xlsinterfaces.(upper (reqinterface{1}))) ## New interface requested xlsinterfaces.COM = 0; xlsinterfaces.POI = 0; xlsinterfaces.JXL = 0; xlsinterfaces.OXS = 0; xlsinterfaces.UNO = 0; xlsinterfaces.OCT = 0; for ii=1:numel (reqinterface) reqintf = toupper (reqinterface {ii}); ## Try to invoke requested interface(s) for this call. Check if it ## is supported anyway by emptying the corresponding var. if (strcmpi (reqintf, 'COM')) xlsinterfaces.COM = []; elseif (strcmpi (reqintf, 'POI')) xlsinterfaces.POI = []; elseif (strcmpi (reqintf, 'JXL')) xlsinterfaces.JXL = []; elseif (strcmpi (reqintf, 'OXS')) xlsinterfaces.OXS = []; elseif (strcmpi (reqintf, 'UNO')) xlsinterfaces.UNO = []; elseif (strcmpi (reqintf, 'OCT')) xlsinterfaces.OCT = []; else error (sprintf (["xlsopen.m: unknown .xls interface \"%s\" requested.\n" "Only COM, POI, JXL, OXS, UNO, or OCT) supported\n"], reqinterface{})); endif endfor printf ("Checking requested interface(s):\n"); xlsinterfaces = getxlsinterfaces (xlsinterfaces); ## Well, is/are the requested interface(s) supported on the system? xlsintf_cnt = 0; for ii=1:numel (reqinterface) if (! xlsinterfaces.(toupper (reqinterface{ii}))) ## No it aint printf ("%s is not supported.\n", upper (reqinterface{ii})); else ++xlsintf_cnt; endif endfor ## Reset interface check indicator if no requested support found if (! xlsintf_cnt) chkintf = []; xls = []; return endif endif else intfmsg = "available"; endif ## Check if Excel file exists. First check for (supported) file name suffix: ftype = 0; has_suffix = 1; [sfxpos, ~, ~, ext] = regexpi (filename, '(\.xlsx?|\.gnumeric|\.ods|\.csv)'); if (! isempty (sfxpos)) ext = lower (ext{end}); ## .xls or .xls[x,m,b] or .gnumeric is there, but at the right(most) position? if (sfxpos(end) <= length (filename) - length (ext)) ## Apparently not, or it is an unrecognized extension ## If xwrite = 0, check file suffix, else add .xlsx has_suffix = 0; else switch ext case ".xls" ## Regular (binary) BIFF ftype = 1; case {".xlsx", ".xlsm", ".xlsb"} ## Zipped XML / OOXML. Catches xlsx, xlsb, xlsm ftype = 2; case ".ods" ## ODS 1.2 (Excel 2007+ & OOo/LO can read ODS) ftype = 3; case ".gnumeric" ## Zipped XML / gnumeric ftype = 5; case ".csv" ## csv. Detected for xlsread afficionados ftype = 6; otherwise warning ("xlsopen: file type ('%s' extension) not supported\n", ext); endswitch endif else has_suffix = 0; endif ## Var readwrite is really used to avoid creating files when wanting to read, ## or not finding not-yet-existing files when wanting to write a new one. ## Adapt file open mode for readwrite argument if (xwrite) fmode = 'r+b'; if (! has_suffix) ## Provisionally add .xlsx suffix to filename (most used format) filename = [filename ".xlsx"]; ext = ".xlsx"; ftype = 2; endif else fmode = 'rb'; if (! has_suffix) ## Try to find find existing file name. We ignore .gnumeric filnm = dir ([filename ".xls*"]); if (! isempty (filnm)) ## Simply choose the first one if (isstruct (filnm)) filename = filnm(1).name; else filename = filnm; endif endif endif endif fid = fopen (filename, fmode); if (fid < 0) ## File doesn't exist... if (! xwrite) ## ...which obviously is fatal for reading... ## FIXME process open apps (Excel, LibreOffice, etc) before hard crash error ( sprintf ("xlsopen.m: file %s not found\n", filename)); else ## ...but for writing, we need more info: fid = fopen (filename, 'rb'); ## Check if it exists at all... if (fid < 0) ## File didn't exist yet. Simply create it xwrite = 3; else ## File exists, but isn't writable => Error fclose (fid); ## Do not forget to close the handle neatly error (sprintf ("xlsopen.m: write mode requested but file %s is not writable\n", filename)) endif endif else ## Close file anyway to avoid COM or Java errors fclose (fid); endif ## Check for the various Excel interfaces. No problem if they've already ## been checked, getxlsinterfaces (far below) just returns immediately then. xlsinterfaces = getxlsinterfaces (xlsinterfaces); ## If no external interface was detected and no suffix was given, use .xlsx if (! has_suffix && ! (xlsinterfaces.COM + xlsinterfaces.POI + ... xlsinterfaces.JXL + xlsinterfaces.OXS + ... xlsinterfaces.UNO)) ftype = 2; endif ## Initialize file ptr struct xls = struct ("xtype", 'NONE', "app", [], "filename", [], "workbook", [], "changed", 0, "limits", []); ## Keep track of which interface is selected xlssupport = 0; ## Interface preference order is defined below: currently COM -> POI -> JXL -> OXS -> UNO -> OCT ## ftype (file type) is conveyed depending on interface capabilities if ((! xlssupport) && xlsinterfaces.COM && (ftype != 5)) ## Excel functioning has been tested above & file exists, so we just invoke it. [ xls, xlssupport, lastintf ] = __COM_spsh_open__ (xls, xwrite, filename, xlssupport); endif if ((! xlssupport) && xlsinterfaces.POI && (ftype == 1)) [ xls, xlssupport, lastintf ] = __POI_spsh_open__ (xls, xwrite, filename, xlssupport, ftype, xlsinterfaces); endif if ((! xlssupport) && xlsinterfaces.POI == 2 && (ftype == 2)) [ xls, xlssupport, lastintf ] = __POI_spsh_open__ (xls, xwrite, filename, xlssupport, ftype, xlsinterfaces); endif if ((! xlssupport) && xlsinterfaces.JXL && ftype == 1) [ xls, xlssupport, lastintf ] = __JXL_spsh_open__ (xls, xwrite, filename, xlssupport, ftype, xlsinterfaces); endif if ((! xlssupport) && xlsinterfaces.OXS && ftype == 1) [ xls, xlssupport, lastintf ] = __OXS_spsh_open__ (xls, xwrite, filename, xlssupport, ftype); endif if ((! xlssupport) && xlsinterfaces.UNO && (ftype != 5)) ## Warn for LO / OOo stubbornness if (ftype == 0 || ftype == 5 || ftype == 6) warning ("UNO interface will write ODS format for unsupported file extensions\n") endif [ xls, xlssupport, lastintf ] = __UNO_spsh_open__ (xls, xwrite, filename, xlssupport); endif if ((! xlssupport) && xlsinterfaces.OCT && ... (ftype == 2 || ftype == 3 || ftype == 5)) [ xls, xlssupport, lastintf ] = __OCT_spsh_open__ (xls, xwrite, filename, xlssupport, ftype); endif ## if ## ---- other interfaces ## endif ## Rounding up. If none of the xlsinterfaces is supported we're out of luck. if (! xlssupport) if (isempty (reqinterface)) ## If no suitable interface was detected (COM or UNO can read .csv), handle ## .csv in xlsread (as that's where Matlab n00bs would expect .csv support) if (ftype != 6) ## This message is appended after message from getxlsinterfaces() printf ("None.\n"); warning ("xlsopen.m: no '%s' spreadsheet I/O support with %s interfaces.\n", ... ext, intfmsg); endif else ## No match between file type & interface found warning ("xlsopen.m: file type not supported by %s %s %s %s %s %s\n", reqinterface{:}); endif xls = []; ## Reset found interfaces for re-testing in the next call. Add interfaces if needed. chkintf = []; else ## From here on xwrite is tracked via xls.changed in the various lower ## level r/w routines xls.changed = xwrite; ## xls.changed = 0 (existing/only read from), 1 (existing/data added), 2 (new, ## data added) or 3 (pristine, no data added). ## Until something was written to existing files we keep status "unchanged". if (xls.changed == 1) xls.changed = 0; endif endif endfunction io-2.4.10/inst/PaxHeaders.5973/object2json.m0000644000000000000000000000013213226215407015250 xustar0030 mtime=1515789063.560154694 30 atime=1515789063.560154694 30 ctime=1515789065.028183488 io-2.4.10/inst/object2json.m0000644000175000017500000001710413226215407015513 0ustar00olafolaf00000000000000%% Copyright (C) 2010-2017 Torre Herrera, Daniel de %% %% 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 . %% Returns a valid json string that will describe object; the string will %% be in a compact form (no spaces or line breaks). %% %% It will map simple octave values this way: %% function handles: string with the name of the function %% double (numbers): depends: %% If it's real it will map to a string representing that number %% If it's complex it will map to an object with the next properties: %% real: real part of the number %% imag: imaginary part of the number %% char: A string enclosed by double quotes representing that character %% logical: text sring "true" or "false" (w/o double quotes) %% And will map more complex octave values this other way: %% struct: an object with properties equal to the struct's field names %% and value equal to the json counterpart of that field %% cell: it will be mapped depending on the value of the cell (for %% example {i} will be mapped to an object with real=0 and imag=1) %% vectors or cell arrays: it will map them to a corresponding js %% array (same size) with the values transformed to their json %% counterpart (Note: that in javascript all arrays are like octave's %% cells ,i.e. they can store different type and size variables) %% strings or char vectors: they will be mapped to the same string %% enclosed by double quotes %% Other octave values will be mapped to a string enclosed by double %% quotes with the value that the class() function returns %% It can handle escape sequences and special chars automatically. %% If they're valid in JSON it will keep them if not they'll be %% escaped so they can become valid %% object2json.m %% Created: 2010-12-06 %% Updates: %% 2011-01-23 Added support for especial chars and escaped sequences %% 2011-04-01 Fixed error: Column vectors not working correctly %% 2011-09-08 (Philip Nienhuis) layout & style changes cf. Octave coding style %% 2011-08-13 (Keith Sheppard) Added logical types to object2json (bug #39429) function json = object2json (object) s = size (object); if (all (s==1)) % It's not a vector so we must check how to map it % Depending on the class of the object we must do one or another thing switch (class (object)) case 'function_handle' % For a function handle we will only print the name fun = functions (object); json = [ '"', fun.function, '"' ]; case 'struct' fields = fieldnames (object); results = cellfun (@object2json, struct2cell (object), "UniformOutput", false); json = '{'; if (numel (fields) > 1) sep = ','; else sep = ''; endif for (tmp = 1:numel (fields)) json = [ json, '"', fields{tmp}, '":', results{tmp}, sep ]; if(tmp >= numel (fields)-1) sep = ''; endif endfor json(end+1) = '}'; case 'cell' % We dereference the cell and use it as a new value json = object2json (object{1}); case 'double' if (isreal (object)) json = num2str (object); else if (iscomplex (object)) json = [ '{"real":', num2str(real(object)), ',"imag":' , num2str(imag(object)), '}' ]; endif endif case 'char' % Here we handle a single char % JSON only admits the next escape sequences: % \", \\, \/, \b, \f, \n, \r, \t and \u four-hex-digits % so we must be sure that every other sequence gets replaced object = replace_non_JSON_escapes (object); json = [ '"', object, '"' ]; case 'logical' if object json = 'true'; else json = 'false'; endif otherwise % We don't know what is it so we'll put the class name json = [ '"', class(object), '"' ]; endswitch else % It's a vector so it maps to an array sep = ''; if (numel (s) > 2) json = '['; for (tmp=1:s(1)) json = [ json, sep, object2json(reshape(object(tmp, :), s(2:end))) ]; sep = ','; endfor json(end+1) = ']'; else % We can have three cases here: % Object is a row -> array with all the elements % Object is a column -> each element is an array in it's own % Object is a 2D matrix -> separate each row if (s(1) == 1) % Object is a row if (ischar (object)) % If it's a row of chars we will take it as a string % JSON only admits the next escape sequences: % \", \\, \/, \b, \f, \n, \r, \t and \u four-hex-digits % so we must be sure that every other sequence gets replaced object = replace_non_JSON_escapes (object); json = [ '"', object, '"']; else json = '['; for (tmp=1:s(2)) json = [ json, sep, object2json(object(1, tmp)) ]; sep = ','; endfor json(end+1) = ']'; endif elseif (s(2) == 1) % Object is a column json = '['; for (tmp=1:s(1)) json = [ json, sep, '[', object2json(object(tmp, 1)), ']' ]; sep = ','; endfor json(end+1) = ']'; else % Object is a 2D matrix json = '['; for (tmp=1:s(1)) json = [ json, sep, object2json(object(tmp, :)) ]; sep = ','; endfor json(end+1) = ']'; endif endif endif endfunction % JSON only admits the next escape sequences: % \", \\, \/, \b, \f, \n, \r, \t and \u four-hex-digits % This function replace every escaped sequence that isn't on that list % with a compatible version % Note that this function uses typeinfo so it may need to be updated % with each octave release function object = replace_non_JSON_escapes (object) if (strcmp (typeinfo (object), 'string')) % It's a double quoted string so newlines and other chars need % to be converted back into escape sequences before anything object = undo_string_escapes (object); endif % This first regex handles double quotes and slashes that are not % after a backslash and thus aren't escaped object = regexprep (object, '(?= 90; %! car.leased = logical(1); %! car.european = logical(0); %! assert(object2json(car), '{"name":"Mzd R8","speedsamples":[[98,33,50],[56,120,102],[77,82,93]],"toofast":[[true,false,false],[false,true,true],[false,false,true]],"leased":true,"european":false}'); io-2.4.10/inst/PaxHeaders.5973/odsfinfo.m0000644000000000000000000000013213226215407014635 xustar0030 mtime=1515789063.560154694 30 atime=1515789063.560154694 30 ctime=1515789065.028183488 io-2.4.10/inst/odsfinfo.m0000644000175000017500000001537013226215407015103 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [@var{filetype}] = odsfinfo (@var{filename} [, @var{reqintf}]) ## @deftypefnx {Function File} [@var{filetype}, @var{sh_names}] = odsfinfo (@var{filename} [, @var{reqintf}]) ## @deftypefnx {Function File} [@var{filetype}, @var{sh_names}, @var{nmranges}] = odsfinfo (@var{filename} [, @var{reqintf}]) ## @deftypefnx {Function File} [@var{filetype}, @var{sh_names}, @var{fformat}, @var{nmranges}] = odsfinfo (@var{filename} [, @var{reqintf}]) ## Query an OpenOffice_org or Gnumeric spreadsheet file @var{filename} ## (with ods or gnumeric suffix) for some info about its contents. ## ## If @var{filename} is a recognizable OpenOffice.org or Gnumeric spreadsheet ## file, @var{filetype} returns the string "OpenOffice.org Calc spreadsheet" ## (or "Gnumeric spreadsheet"), or @'' (empty string) otherwise. ## ## If @var{filename} is a recognizable OpenOffice.org Calc or Gnumeric ## spreadsheet file, optional argument @var{sh_names} contains a Nx2 list ## (cell array) of sheet names contained in @var{filename} and total used ## data ranges for each sheet, in the order (from left to right) in which ## they occur in the sheet stack. ## ## Optional output argument @var{fformat} is a string describing the file ## contents. ## ## Optional return argument @var{nmranges} returns a list of Named ranges ## defined in the spreadsheet, if any. ## ## If you omit return arguments @var{filetype} and @var{sh_names} altogether, ## odsfinfo returns the sheet names and for each sheet the actual occupied ## data ranges to the screen. The occupied cell range will have to be ## determined behind the scenes first; this can take some time. If any ## Named ranges are defined in the spreadsheet file, they will be listed ## on the screen as well. Named ranges work only for the OCT interface, ## with the UNO interface it doesn't work for .ods files. ## ## odsfinfo execution can take its time for large spreadsheets as the entire ## spreadsheet has to be parsed to get the sheet names, let alone exploring ## used data ranges. ## ## By specifying a value of 'jod', 'otk', 'uno' or 'oct' for @var{reqintf} the ## automatic selection of the Java interface is bypassed and the specified ## interface will be used (if at all present). ## ## Examples: ## ## @example ## exist = odsfinfo ('test4.ods'); ## (Just checks if file test4.ods is a readable Calc file) ## @end example ## ## @example ## [exist, names] = odsfinfo ('test4.ods'); ## (Checks if file test4.ods is a readable Calc file and return a ## list of sheet names) ## @end example ## ## @seealso {odsread, odsopen, ods2oct, odsclose} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-12-17 function [ filetype, sh_names, fformat, nmranges ] = odsfinfo (filename, reqintf=[]) persistent str2; str2 = " "; # 33 spaces persistent lstr2; lstr2 = length (str2); toscreen = nargout < 1; ods = odsopen (filename, 0, reqintf); ## If no ods support was found, odsopen will have complained. Just return here if (isempty (ods)), return; endif ## If any valid xls-pointer struct has been returned, it must be a valid ## spreadsheet. Find out what format [~, ~, ext] = fileparts (ods.filename); switch ext case {".ods", "ods", ".sxc", "sxc"} filetype = "OpenOffice.org Calc Document"; case {"gnumeric", ".gnumeric"} filetype = "Gnumeric spreadsheet"; case {"xls", "xlsx", "xlsm", ".xlsb", ".xls", ".xlsx", ".xlsm", ".xlsb"} ## UNO (LO/OOo) and OCT also accept Excel spreadsheet files filetype = "Microsoft Excel Spreadsheet"; otherwise filetype = ""; endswitch ## To save execution time, only proceed if sheet names are wanted if ~(nargout == 1) if (strcmp (ods.xtype, "OTK")) [sh_names] = __OTK_spsh_info__ (ods); elseif (strcmp (ods.xtype, "JOD")) [sh_names] = __JOD_spsh_info__ (ods); elseif (strcmp (ods.xtype, "UNO")) [sh_names] = __UNO_spsh_info__ (ods); elseif (strcmp (ods.xtype, "OCT")) [sh_names] = __OCT_spsh_info__ (ods); else ## Below error will have been catched in odsopen() above ##error (sprintf ("odsfinfo: unknown OpenOffice.org .ods interface - %s.",... ## ods.xtype)); endif endif sh_cnt = size (sh_names, 1); if (toscreen) # Echo sheet names to screen for ii=1:sh_cnt str1 = sprintf ("%3d: %s", ii, sh_names{ii, 1}); if (index (sh_names{ii, 2}, ":")) str3 = ["(Used range ~ " sh_names{ii, 2} ")"]; else str3 = sh_names{ii, 2}; endif printf ("%s%s%s\n", str1, str2(1:lstr2-length (sh_names{ii, 1})), str3); endfor ## Echo named ranges nmranges = getnmranges (ods); snmr = size (nmranges, 1); if (snmr > 0) ## Find max length of entries nmrl = min (35, max ([cellfun("length", nmranges(:, 1)); 10])); shtl = min (31, max ([cellfun("length", nmranges(:, 2)); 6])); rnml = max ([cellfun("length", nmranges(:, 3)); 5]); frmt = sprintf ("%%%ds %%%ds %%%ds\n" , nmrl, shtl, rnml); printf (["\n" frmt], "Range name", "Sheet", "Range"); printf (frmt, "----------", "-----", "-----" ); for ii=1:size (nmranges, 1) printf (frmt, nmranges(ii, 1:3){:}); endfor endif elseif (sh_cnt > 0 && nargout > 2) ## Echo file format & named ranges if (strcmpi (ods.filename(end-2:end), "ods")) fformat = "ODSWorkbook"; elseif (strcmpi (ods.filename(end-2:end), "sxc")) fformat = "StarOfficeWorkbook"; elseif (strcmpi (ods.filename(end-7:end), "gnumeric")) fformat = "GnumericWorkbook"; ## Below options exist because Open?LibreOffice also swallow Excel files elseif (strcmpi (ods.filename(end-2:end), "xls")) fformat = "xlWorkbookNormal"; elseif (strcmpi (ods.filename(end-2:end), "csv")) fformat = "xlCSV"; ## Works only with COM elseif (strcmpi (ods.filename(end-3:end-1), "xls")) fformat = "xlOpenXMLWorkbook"; else fformat = ""; endif nmranges = getnmranges (ods); endif ods = odsclose (ods); endfunction io-2.4.10/inst/PaxHeaders.5973/dbfread.m0000644000000000000000000000013213226215407014415 xustar0030 mtime=1515789063.556154616 30 atime=1515789063.556154616 30 ctime=1515789065.028183488 io-2.4.10/inst/dbfread.m0000644000175000017500000003363113226215407014663 0ustar00olafolaf00000000000000## Copyright (C) 2014-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [@var{data}, @var{datinfo}] = dbfread (@var{fname}) ## @deftypefnx {Function File} [@var{data}, @var{datinfo}] = dbfread (@var{fname}, @var{recs}) ## @deftypefnx {Function File} [@var{data}, @var{datinfo}] = dbfread (@var{fname}, @var{recs}, @var{cols}) ## @deftypefnx {Function File} [@var{data}, @var{datinfo}] = dbfread (@var{fname}, @var{recs}, @var{cols}, @var{re}) ## Read contents of a dbase (dbf) file, provisionally dbase III+, IV or V. ## ## @itemize ## @item ## @var{fname} should be the name of a valid dbase file; the file extension ## isn't required. ## ## @item ## @var{recs} can be an integer or logical array containing record numbers or ## record indicators for those records that need to be returned. If omitted, ## all records are read. Indices supplied in @var{recs} can be specified in ## any order, but the returned data are sorted in order of records in the file. ## ## @item ## @var{cols} can be a logical, integer, cellstr or character array indicating ## from which file columns the data should be returned. If a numeric array is ## supplied, it is considered to be like a logical array if the maximum entry ## value equals 1. Character arrays should have column names stacked in the ## vertical (first) dimension. @var{cols} cellstr or char arrays can be ## supplied in any order, yet the returned data column order matches that of ## the columns order in the dbase file. For dbase files containing multiple ## columns with the same name, specify a numeric or logical array to select ## columns to be returned. If omitted, data from all file columns are ## returned. ## ## @item ## If a value of 1 or true is entered for @var{re}, dbfread also tries to ## return data from erased records. No guarantee can be given for these data ## to be correct or consistent! If omitted, erased records are skipped. ## ## @item ## Return value @var{data} is a N+1 x M cellstr array where the uppermost row ## contains the column names and the rest of the rows the record data. ## ## @item ## Optional return argument @var{datinfo} is a struct array containing various ## information of the dbase file and record build-up. ## @end itemize ## ## Arguments @var{recs} and @var{cols} need not be as long as the number of ## records and columns in the file, resp.; dbfread will stop reading data if ## any of @var{recs} or @var{cols} (if supplied) is exhausted. ## ## Sometimes dbase files contain records indicated as being erased. The data ## in such records is silently skipped, unless the @var{re} flag is set ## and/or @var{recs} is supplied and erased records happen to be present in the ## requested record numbers. ## ## Examples: ## ## @example ## A = dbfread ("file.dbf"); ## (returns all data in file.dbf in array A) ## @end example ## ## ## @example ## [A, B] = dbfread ("file.dbf", [], ["colB"; "colF"]); ## (returns all data in columns named "colB" and "colF" from ## file.dbf in array A and information on the database ## build-up in struct B) ## @end example ## ## @example ## A = dbfread ("file.dbf", [0 1 0 0 1 0 0]); ## -or- ## A = dbfread ("file.dbf", [2 5]); ## (returns data from record numbers 2 and 5 in ## file.dbf in array A) ## @end example ## ## @example ## A = dbfread ("file", [0 1 0 0 1 0]); ## (returns data from record numbers 2 and 5 in ## file.dbf in array A) ## @end example ## ## @example ## [~, B] = dbfread ("file.dbf", 0); ## (to returns info on column names and number of ## records, plus more info) ## @end example ## ## @example ## [A] = dbfread ("file", [], @{"Header1", "Col5"@}); ## (returns data from columns with names (headers) ## Header1 and Col5, resp.) ## @end example ## ## @seealso{xlsread} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2014-11-03 ## References: ## http://ulisse.elettra.trieste.it/services/doc/dbase/DBFstruct.htm ## http://www.dbf2002.com/dbf-file-format.html ## http://www.dbase.com/KnowledgeBase/int/db7_file_fmt.htm function [data, datinfo] = dbfread (fname, recs=[], cols=[], rd_erased='') ## Check file name if (ischar (fname)) [~, fnm, ext] = fileparts (fname); if (isempty (ext)) fname = [fname ".dbf"]; endif else error ("dbfread: file name expected for arg # 1.\n"); endif ## Check recs arg. If needed turn into indices if (! isempty (recs)) if (! (isnumeric (recs) || islogical (recs))) error ("dbfread: numeric or logical array expected for arg # 2\n"); elseif (isnumeric (recs)) if (any (recs < 0)) error ("dbfread: illegal record selection indices\n"); elseif (min (recs) == 0 && max (recs) < 2) recs = find (recs); if (isempty (recs)) recs = -1; endif endif elseif (islogical (recs)) recs = find (recs); endif endif ## Check cols arg. If needed turn into indices if (! isempty (cols)) if (! (isnumeric (cols) || ischar (cols) || iscellstr (cols) || islogical (cols))) error ("dbfread: numeric, cellstr, logical, or character array expected for arg # 3\n"); elseif (isnumeric (cols)) if (any (cols < 0)) error ("dbfread: illegal column selection indices\n"); elseif (min (cols) == 0 && max (cols) < 2) cols = find (cols); if (isempty (cols)) cols = -1; endif endif elseif (islogical (cols)) cols = find (cols); endif endif ## Check rd_erased arg. if (! isempty (rd_erased) && ! (islogical (rd_erased) || isnumeric (rd_erased))) error ("dbfread: numeric or logical value expected for arg # 4\n"); endif ## Open file fid = fopen (fname, "r"); if (fid < 0) error ("dbfread: file %s couldn't be opened.\n", fname); endif ## Rewind, just to be sure fseek (fid, 0, "bof"); ## First check proper type fbyte = uint8 (fread (fid, 1, "uint8")); ## Provisional type check. ## 3 = dbase III+ w/o memos ## 83 = dbase III+ w memos ## ... vsn = bitand (fbyte, 7); if (! ismember (vsn, [3, 4, 5])) error ("dbfread: unsupported file type, only dbase III[+], IV & V supported.\n"); endif ## Memos present for fbyte == 83, and bits 3 and/or 7 set (1-based bit pos.) hasmemo = (fbyte == 83) || (bitand (fbyte, 8)) || (bitand (fbyte, uint8 (128))); ## Start reading header lasty = fread (fid, 1, "uint8") + 1900; ## Last dbf update lastm = fread (fid, 1, "uint8"); ## month lastd = fread (fid, 1, "uint8"); ## day nrecs = fread (fid, 1, "uint32"); lhdr = fread (fid, 1, "uint16"); recl = fread (fid, 1, "uint16"); ## Field descriptors nfields = 0; fseek (fid, 32, "bof"); fdesc = fread (fid, 32, "char=>char")'; do ++nfields; ## Get fields into struct dbf(nfields).fldnam = deblank (fdesc(1:11)); ## Field name dbf(nfields).fldtyp = fdesc(12); ## Field type ## Skip field dspl. dbf(nfields).fldlng = int32 (fdesc(17)); ## Field length dbf(nfields).flddec = int32 (fdesc(18)); ## Decimal places dbf(nfields).fldflg = int8 (fdesc(19)); ## Flags ## Get next field descriptors fdesc = fread (fid, 32, "char=>char")'; until (ftell (fid) >= lhdr) ## Seek to position after header terminator byte fseek (fid, lhdr, "bof"); ## Read rest of data. Skip if no records need be read. Turn into char array if (recs > 0 || isempty (recs)) txt = fread (fid, [recl, nrecs], "char=>char")'; else txt = ""; endif ## .dbf file is no longer needed fclose (fid); ## Preallocate upper data row data = cell (1, numel (dbf)); data(1, :) = {dbf.fldnam}; ## If required, select requested records. Beware; truncate indices > nrecs recs = sort (recs); if (any (recs > nrecs)) recs (find (recs > nrecs)) = []; ## Check if we still have a selection... if (isempty (recs)) ## No more, signal this to below code recs = -1; endif endif if (! isempty (recs) && ! isempty (txt)) if (any (recs < 0)) ## No data returned. Explore erased records anyway wipedrec = txt(:, 1)' == "*"; txt = ""; recs = 0; scol = numel (dbf); else txt = txt(recs, :); ## Preallocate data cell array for selected records data = [data; cell(numel (recs), numel (dbf))]; endif else ## Preallocate data cell array for all records data = [data; cell(nrecs, numel (dbf))]; endif if (! isempty (txt)) ## There's something to read ;-) First, read memo file, if any if (hasmemo) ## Also open accompanying .dbt file fjd = fopen ([fnm ".dbt"], "r"); if (fjd < 0) warning ("dbfread: associated memo file (%s) couldn't be opened.\n", ... [fnm ".dbt"]); printf ("(dbfread: skipping memo fields)\n"); memos = {}; else fseek (fjd,0, "bof"); ## Read memo fields memos = fread (fjd, Inf, "char=>char")'; fclose (fjd); ## Pimp memos: replace all non-alphanumeric chars by space memos(find (int8(memos) > 122)) = char(32); memos(find (int8(memos) < 32)) = char(32); switch fbyte case {83, 131} ## Dbase III[+] ## Make it into a Nx512 char array. Pad unit length = multiple of 512 pad = ceil (length (memos) / 512) * 512 - length (memos); memos = [memos repmat(int8 (32), 1, pad)]; memos = cellstr (reshape (memos, 512, [])'); otherwise ## FIXME: Dbase V, VII to follow endswitch endif endif txtp = 2; ## Init output array column pointer scol = 0; for ii=1:numel (dbf) ## First process selection if arg. cols was given... if (! isempty (cols)) try ## try-catch, as cols array < nr. of cols is allowed. ## Switch dependent of cols input arg. type switch class (cols) case "cell" getcol = any (strcmp (cols{scol+1}, dbf(ii).fldnam)); case "char" getcol = strcmp (strtrim (cols(scol+1, :)), dbf(ii).fldnam); case "double" getcol = ! isempty (find (cols == ii)); otherwise endswitch catch getcol = 0; end_try_catch else ## No cols arg. was given, so we'll read this column anyway getcol = 1; endif if (getcol) ## Read column # ii ++scol; fld = txt(:, txtp : txtp+dbf(ii).fldlng - 1); switch (dbf(ii).fldtyp) case {"B", "G"} ## Block number into .dbt file, other than memo data(2:end, scol) = num2cell (str2double (fld)); case "C" ## Text data(2:end, scol) = cellstr (fld); case "D" ## Date dlf = cellstr (fld); ## Catch empty date fields. Put ridiculous value in dlf(find (strcmp (cellstr (fld), "00000000"))) = "99991231"; dlf(find (cellfun ("isempty", dlf))) = "99991231"; dlf = datenum (dlf, "yyyymmdd"); ## Reset temp values for empty dates dlf (dlf >= 3652425) = 0; data(2:end, scol) = num2cell (dlf); case "L" ## Logical / boolean data(2:end, scol) = false; data(regexpi (fld, "[yt]")+1, scol) = true; case {"F", "N"} ## Numeric data(2:end, scol) = num2cell (str2double (fld)); case "M" ## Memo field pointer into .dbt file if (! isempty (memos)) switch (fbyte) case {83, 131} ## Dbase III[+] idx = str2double (fld); idx (find (isnan (idx))) = 1; data(2:end, scol) = memos(idx); otherwise ## FIXME other .dbf file versions to be implemented... endswitch endif otherwise endswitch else ## Remove data column header & associated column from output array data(:, scol+1) = []; endif ## Next column of data from .dbf file txtp += dbf(ii).fldlng; endfor ## Only now check for erased records, to avoid false positives below wipedrec = txt(:, 1)' == "*"; if (! rd_erased) ## No erased records in user-supplied record selection => no worries data (find (wiperec), :) = []; elseif (sum (wipedrec) && ! isempty (recs)) ## User did request erased record # => warn warning ("(dbfread: %d erased records read\n", wipedrec); endif else wipedrec = []; scol = 0; endif if (isempty (data)) data = {}; endif if (nargout <= 1) ## Only data requested datinfo = []; else ## Also (or only) dbf info struct requested if (isempty (recs)) ## Infer nr. of records from file recs = size (data, 1) - 1; endif datinfo.type = fbyte; datinfo.date = datenum (lasty, lastm, lastd); datinfo.erasedrec = find (wipedrec); datinfo.nrec = nrecs; datinfo.srecs = recs; datinfo.recl = recl; datinfo.ncols = numel (dbf); datinfo.scols = scol; datinfo.data = dbf; endif endfunction io-2.4.10/inst/PaxHeaders.5973/io_xls_testscript.m0000644000000000000000000000013213226215407016607 xustar0030 mtime=1515789063.560154694 30 atime=1515789063.560154694 30 ctime=1515789065.028183488 io-2.4.10/inst/io_xls_testscript.m0000644000175000017500000002017713226215407017056 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} io_xls_testscript (@var{intf1}) ## @deftypefnx {Function File} io_xls_testscript (@var{intf1}, @var{fname}) ## @deftypefnx {Function File} io_xls_testscript (@var{intf1}, @var{fname}, @var{intf2}) ## Try to check proper operation of XLS / XLSX spreadsheet scripts using ## interface @var{intf1}. ## ## @var{intf1} can be one of COM, POI, JXL, OXS, UNO, or OCT. No checks ## are made as to whether the requested interface is supported at all. If ## @var{fname} is supplied, that filename is used for the tests, otherwise ## filename "io-test.xls" is chosen by default. This parameter is required ## to have e.g., POI distinguish between testing .xls (BIFF8) and .xlsx ## (OOXML) files. ## ## If @var{intf2} is supplied, that interface will be used for writing the ## spreadsheet file and @var{intf1} will be used for reading. The OCT ## interface doesn't have write support (yet), so it will read spreadsheet ## files made by POI (if supported) unless another interface is supplied ## for @var{intf2}. ## ## As the tests are meant to be run interactively, no output arguments are ## returned. The results of all test steps are printed on the terminal. ## ## @seealso {test_spsh, io_ods_testscript} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2012-02-25 function rslts = io_xls_testscript (intf, fname="io-test.xls", intf2=[]) printf ("\nTesting .xls interface %s using file %s...\n", upper (intf), fname); isuno = false; dly = 0.25; ## If no intf2 is supplied, write with intf1 if (isempty (intf2)) intf2 = intf; endif rslts = repmat ({"-"}, 1, 11); rslts{1} = upper (intf); [~, ~, ext] = fileparts (fname); rslts{11} = ext; ## Allow the OS some delay to accomodate for file operations (zipping etc.) if (strcmpi (intf, "uno") || strcmpi (intf2, "uno") || strcmpi (intf, "oct") || strcmpi (intf2, "oct")); isuno = true; endif ## 1. Initialize test arrays printf ("\n 1. Initialize arrays.\n"); arr1 = [ 1 2; 3 4.5]; arr2 = {"r1c1", "=c2+d2"; "", "r2c2"; true, -83.4; "> < & \" '", " "}; opts = struct ("formulas_as_text", 0); try ## 2. Insert empty sheet printf ("\n 2. Insert first empty sheet.\n"); xlswrite (fname, {""}, "EmptySheet", "b4", intf2); if (isuno) pause (dly); endif ## 3. Add data to test sheet printf ("\n 3. Add data to test sheet.\n"); xlswrite (fname, arr1, "Testsheet", "c2:d3", intf2); if (isuno) pause (dly); endif xlswrite (fname, arr2, "Testsheet", "d4:z20", intf2); if (isuno) pause (dly); if (strcmpi (intf, "oct") || strcmpi (intf2, "oct")) ## Some more delay to give zip a breath pause (dly); pause (dly); endif endif ## 4. Insert another sheet printf ("\n 4. Add another sheet with just one number in A1.\n"); xlswrite (fname, [1], "JustOne", "A1", intf2); if (isuno) pause (dly); endif ## 5. Get sheet info & find sheet with data and data range printf ("\n 5. Explore sheet info.\n"); [~, shts] = xlsfinfo (fname, intf); if (isuno) pause (dly); endif shnr = find (strcmp ("Testsheet", shts(:, 1))); ## Note case! if (isempty (shnr)) printf ("Worksheet with data not found - not properly written ... test failed.\n"); return endif crange = shts{shnr, 2}; ## Range can be unreliable if (strcmpi (crange, "A1:A1")) crange = ""; endif ## 6. Read data back printf ("\n 6. Read data back.\n"); [num, txt, raw, lims] = xlsread (fname, shnr, crange, intf); if (isuno) pause (dly); endif ## First check: has anything been read at all?x if (isempty (raw)) printf ("No data at all have been read... test failed.\n"); return elseif (isempty (num)) printf ("No numeric data have been read... test failed.\n"); return elseif (isempty (txt)) printf ("No text data have been read... test failed.\n"); return endif ## 7. Here come the tests, part 1 err = 0; printf ("\n 7. Tests part 1 (basic I/O):\n"); try printf (" ...Numeric array... "); assert (num(1:2, 1:3), [1, 2, NaN; 3, 4.5, NaN], 1e-10); rslts{2} = "+"; assert (num(4:5, 1:3), [NaN, NaN, NaN; NaN, 1, -83.4], 1e-10); rslts{3} = "+"; assert (num(3, 1:2), [NaN, NaN], 1e-10); rslts{4} = "+"; # Just check if it's numeric, the value depends too much on cached results assert (isnumeric (num(3,3)), true); rslts{5} = "+"; printf ("matches...\n"); catch printf ("Hmmm.... error, see 'num'\n"); err = 1; end_try_catch try printf (" ...Cellstr array... "); assert (txt{1, 1}, "r1c1"); rslts{6} = "+"; assert (txt{2, 2}, "r2c2"); rslts{7} = "+"; printf ("matches...\n"); printf (" ...special characters... "); assert (txt{4, 1}, "> < & \" '"); rslts(8) = "+"; printf ("matches...\n"); catch printf ("Hmmm.... error, see 'txt'\n"); err = 1; end_try_catch try printf (" ...Boolean... "); assert (islogical (raw{5, 2}), true); ## Fails on COM rslts{9} = "+"; printf ("recovered...\n"); catch try if (isnumeric (raw{5, 2})) printf ("returned as numeric '1' rather than logical TRUE.\n"); rslts{9} = "o"; else printf ("Hmmm.... error, see 'raw{5, 2}'\n"); endif catch err = 1; printf ("Hmmm.... error....\n"); end_try_catch end_try_catch if (err) ## Echo array to screen printf ("These are the data read back:\n"); raw printf ("...and this what they should look like:\n"); printf ("%s\n", ... "{\n [1,1] = 1\n [2,1] = 3\n [3,1] = [](0x0)\n [4,1] = [](0x0)\n [5,1] = [](0x0)\n [1,2] = 2\n [2,2] = 4.5000\n [3,2] = r1c1\n [4,2] =\n [5,2] = 1\n [1,3] = [](0x0)\n [2,3] = [](0x0)\n [3,3] = 3\n [4,3] = r2c2\n [5,3] = -83.400\n}"); endif ## Check if "formulas_as_text" option works: printf ("\n 8. Repeat reading, now return formulas as text\n"); opts.formulas_as_text = 1; xls = xlsopen (fname, 0, intf); if (isuno) pause (dly); endif raw = xls2oct (xls, shnr, crange, opts); if (isuno) pause (dly); endif xls = xlsclose (xls); if (isuno) pause (dly); endif clear xls; ## 9. Here come the tests, part 2. printf ("\n 9. Tests part 2 (read back formula):\n"); try # Just check if it contains any string assert ( (ischar (raw{3, 3}) && ! isempty (raw(3, 3)) && raw{3, 3}(1) == "="), true); rslts{10} = "+"; printf (" ...OK, formula recovered ('%s').\n", raw{3, 3}); catch printf ("Hmmm.... error, see 'raw(3, 3)'"); if (size (raw, 1) >= 3 && size (raw, 2) >= 3) if (isempty (raw{3, 3})) printf (" (empty, should be a string like '=c2+d2')\n"); elseif (isnumeric (raw{3, 3})) printf (" (equals %f, should be a string like '=c2+d2')\n", raw{3, 3}); else printf ("\n"); endif else printf (".. raw{3, 3} doesn't even exist, array too small... Test failed.\n"); endif end_try_catch ## 10. Clean up printf ("\n10. Cleaning up....."); delete (fname); printf (" OK\n"); catch ## Just to preserve rslts array printf ("\n%s\n\n", lasterr ()); end_try_catch endfunction io-2.4.10/inst/PaxHeaders.5973/oct2ods.m0000644000000000000000000000013213226215407014403 xustar0030 mtime=1515789063.560154694 30 atime=1515789063.560154694 30 ctime=1515789065.028183488 io-2.4.10/inst/oct2ods.m0000644000175000017500000002105413226215407014645 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [ @var{ods}, @var{rstatus} ] = oct2ods (@var{arr}, @var{ods}) ## @deftypefnx {Function File} [ @var{ods}, @var{rstatus} ] = oct2ods (@var{arr}, @var{ods}, @var{wsh}) ## @deftypefnx {Function File} [ @var{ods}, @var{rstatus} ] = oct2ods (@var{arr}, @var{ods}, @var{wsh}, @var{range}) ## @deftypefnx {Function File} [ @var{ods}, @var{rstatus} ] = oct2ods (@var{arr}, @var{ods}, @var{wsh}, @var{range}, @var{options}) ## ## Transfer data to an OpenOffice_org Calc (or gnumeric) spreadsheet ## previously opened by odsopen(). ## ## Data in 1D/2D array @var{arr} are transferred into a cell range ## @var{range} in sheet @var{wsh}. @var{ods} must have been made earlier ## by odsopen(). Return argument @var{ods} should be the same as supplied ## argument @var{ods} and is updated by oct2ods. A subsequent call to ## odsclose is needed to write the updated spreadsheet to disk (and ## -if needed- close the Java invocation holding the file pointer). ## ## @var{arr} can be any 1D or 2D array containing numerical or character ## data (cellstr) except complex. Mixed numeric/text arrays can only be ## cell arrays. ## ## @var{ods} must be a valid pointer struct created earlier by odsopen. ## ## @var{wsh} can be a number (sheet name) or string (sheet number). ## In case of a yet non-existing Calc file, the first sheet will be ## used & named according to @var{wsh}. ## In case of existing files, some checks are made for existing sheet ## names or numbers. ## When new sheets are to be added to the Calc file, they are ## inserted to the right of all existing sheets. The pointer to the ## "active" sheet (shown when Calc opens the file) remains untouched. ## ## If @var{range} is omitted, the top left cell where the data will be ## put is supposed to be 'A1'; only a top left cell address can be ## specified as well. In these cases the actual range to be used is ## determined by the size of @var{arr}. If defined in the spreadsheet ## file, a "Named range" can also be specified. In that case @var{wsh} ## will be ignored and the worksheet associated with the specified ## Named range will be used. ## Be aware that large data array sizes may exhaust the java shared ## memory space. For larger arrays, appropriate memory settings are ## needed in the file java.opts; then the maximum array size for the ## java-based spreadsheet options can be in the order of perhaps 10^6 ## elements. ## ## Optional argument @var{options}, a structure, can be used to specify ## various write modes. ## @table @asis ## @item "formulas_as_text" ## If set to 1 or TRUE formula strings ( i.e., text strings (assumed to ## start with "=" and end in a ")" ) are to be written as litteral ## text strings rather than as spreadsheet formulas (the latter is the ## default). As jOpenDocument doesn't support formula I/O at all yet, ## this option is ignored for the JOD interface. ## ## @item 'convert_utf' ## If set to 1 or TRUE, oct2ods converts one-byte characters outside the ## range [32:127] to UTF-8 so that they are properly entered as UTF-8 ## encoded text in spreadsheets. The default value is 0. ## @end table ## ## Data are added to the sheet, ignoring other data already present; ## existing data in the range to be used will be overwritten. ## ## If @var{range} contains merged cells, also the elements of @var{arr} ## not corresponding to the top or left Calc cells of those merged cells ## will be written, however they won't be shown until in Calc the merge is ## undone. ## ## Examples: ## ## @example ## [ods, status] = oct2ods (arr, ods, 'Newsheet1', 'AA31:GH165'); ## Write array arr into sheet Newsheet1 with upperleft cell at AA31 ## @end example ## ## @example ## [ods, status] = oct2ods (@{'String'@}, ods, 'Oldsheet3', 'B15:B15'); ## Put a character string into cell B15 in sheet Oldsheet3 ## @end example ## ## @seealso {ods2oct, odsopen, odsclose, odsread, odswrite, odsfinfo} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-12-13 function [ ods, rstatus ] = oct2ods (c_arr, ods, wsh=1, crange="", spsh_opts=[]) if (nargin < 2) error ("oct2xls needs a minimum of 2 arguments."); endif ## Check if input array is cell if (isempty (c_arr)) warning ("oct2ods: request to write empty matrix - ignored.\n"); rstatus = 1; return; elseif (isnumeric (c_arr)) c_arr = num2cell (c_arr); elseif (ischar(c_arr)) c_arr = {c_arr}; printf ("(oct2ods: input character array converted to 1x1 cell)\n"); elseif (! iscell (c_arr)) error ("oct2ods: input array neither cell nor numeric array.\n"); endif if (ndims (c_arr) > 2) error ("oct2ods: only 2-dimensional arrays can be written to spreadsheet.\n"); endif ## Check ods file pointer struct test1 = ! isfield (ods, "xtype"); test1 = test1 || ! isfield (ods, "workbook"); test1 = test1 || isempty (ods.workbook); test1 = test1 || isempty (ods.app); if test1 error ("oct2ods: arg #2: Invalid ods file pointer struct.\n"); endif ## Check worksheet ptr if (! (ischar (wsh) || isnumeric (wsh))) error ("oct2ods: integer (index) or text (wsh name) expected for arg # 3\n"); elseif (isempty (wsh)) wsh = 1; endif ## Check range if (! isempty (crange) && ! ischar (crange)) error ("oct2ods: character string (range) expected for arg # 4\n"); elseif (isempty (crange)) crange = ""; elseif (! isempty (crange)) ## Check for range name and convert it to range & optionally sheet ## 1. Check if it matches a range [crange, wsh, ods] = chknmrange (ods, crange, wsh); endif ## Various options if (isempty (spsh_opts)) spsh_opts.formulas_as_text = 0; spsh_opts.convert_utf = 0; ## other options to be implemented here elseif (isstruct (spsh_opts)) if (! isfield (spsh_opts, "formulas_as_text")) spsh_opts.formulas_as_text = 0; endif if (! isfield (spsh_opts, "convert_utf")) spsh_opts.convert_utf = 0; endif ## other options to be implemented here: else error ("oct2ods: structure expected for arg # 5\n" (options)); endif if (nargout < 1) printf ("oct2ods: warning: no output spreadsheet file pointer specified.\n"); endif ## Convert to UTF-8 if (spsh_opts.convert_utf) if (exist ("native2unicode", "file")) conv_fcn = @(str) unicode2native (native2unicode (uint8 (str)), "UTF-8"); else conv_fcn = @unicode2utf8; endif c_arr = tidyxml (c_arr, conv_fcn); endif if (strcmp (ods.xtype, "OTK")) ## Write ods file tru Java & ODF toolkit. switch ods.odfvsn case "0.7.5" [ ods, rstatus ] = __OTK_oct2ods__ (c_arr, ods, wsh, crange, spsh_opts); case {"0.8.6", "0.8.7", "0.8.8"} [ ods, rstatus ] = __OTK_oct2spsh__ (c_arr, ods, wsh, crange, spsh_opts); otherwise error ("oct2ods: unsupported odfdom version\n"); endswitch elseif (strcmp (ods.xtype, "JOD")) ## Write ods file tru Java & jOpenDocument. API still leaves lots to be wished... [ ods, rstatus ] = __JOD_oct2spsh__ (c_arr, ods, wsh, crange); elseif (strcmp (ods.xtype, "UNO")) ## Write ods file tru UNO [ ods, rstatus ] = __UNO_oct2spsh__ (c_arr, ods, wsh, crange, spsh_opts); elseif (strcmp (ods.xtype, "OCT")) ## Replace illegal XML characters by XML escape sequences idx = cellfun (@ischar, c_arr); c_arr(idx) = strrep (c_arr(idx), "&", "&" ); c_arr(idx) = strrep (c_arr(idx), "<", "<" ); c_arr(idx) = strrep (c_arr(idx), ">", ">" ); c_arr(idx) = strrep (c_arr(idx), "'", "'"); c_arr(idx) = strrep (c_arr(idx), '"', """); ## Write ods or gnumeric file tru native Octave [ ods, rstatus ] = __OCT_oct2spsh__ (c_arr, ods, wsh, crange, spsh_opts); ##elseif ##---- < Other interfaces here > else error (sprintf ("ods2oct: unknown OpenOffice.org .ods interface - %s.\n",... ods.xtype)); endif if (rstatus) ods.limits = []; endif endfunction io-2.4.10/inst/PaxHeaders.5973/write_namelist.m0000644000000000000000000000013213226215407016054 xustar0030 mtime=1515789063.604155557 30 atime=1515789063.604155557 30 ctime=1515789065.028183488 io-2.4.10/inst/write_namelist.m0000644000175000017500000000655313226215407016325 0ustar00olafolaf00000000000000## Copyright (C) 2011-2017 Darien Pardinas Diaz ## ## 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 . ## WRITE_NAMELIST(S, FILENAME) writes a namelist data structure S to a ## file FILENAME. S should follow the following structure: ## ## |--VAR1 ## |--VAR2 ## |-- NMLST_A--|... ## | |--VARNa ## | ## | |--VAR1 ## |-- NMLST_B--|--VAR2 ## | |... ## S --| ... |--VARNb ## | ## | |--VAR1 ## |-- NMLST_M--|--VAR2 ## |... ## |--VARNm ## ## 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; ## write_namelist(NMlST, "MOD_OPTIONS.nam"); ## Written by: Darien Pardinas Diaz (darien.pardinas-diaz@monash.edu) ## Version: 1.0 ## Date: 16 Dec 2011 ## ## Released under GPL License 30/3/2013 function [ ret ] = write_namelist (S, filename) 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.")), for kk = 1:length (var), fprintf (fid, " %s,", var{kk}); endfor else for kk = 1:length (var), fprintf (fid, " %s,", [ "'" var{kk} "'" ]); endfor endif fprintf (fid, "%s\n", ""); else [r, c] = size (var); if (r == 1 || c == 1) ## Variable is a scalar or vector fprintf (fid, " %s =", rcrds_name{jj}); 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 ## Variable is a two dimensional array for kk = 1:r, fprintf (fid, " %s(%i,:) =", rcrds_name{jj}, kk); fprintf (fid, " %g,", var(kk,:)); fprintf (fid, "%s\n", ""); endfor endif endif endfor fprintf (fid, "%s\n", "/"); endfor fclose (fid); endfunction io-2.4.10/inst/PaxHeaders.5973/getxmlattv.m0000644000000000000000000000013213226215407015225 xustar0030 mtime=1515789063.556154616 30 atime=1515789063.556154616 30 ctime=1515789065.028183488 io-2.4.10/inst/getxmlattv.m0000644000175000017500000000303213226215407015463 0ustar00olafolaf00000000000000## Copyright (C) 2013-2017 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 Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## @deftypefn {Function File} [@var{retval}] = getxmlattv (@var{xmlnode}, @var{att}) ## Get value of attribute @var{att} in xml node (char string) @var{xmlnode}, ## return empty if attribute isn't present. ## ## @seealso{getxmlnode} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2013-09-08 function [retval] = getxmlattv (xmlnode, att) retval = ''; ## Get end of first tag iend = index (xmlnode, ">"); ## Get start of value string. Concat '="' to ensure minimal ambiguity vals = index (xmlnode, [att '="']); if (vals == 0) ## Attribute not in current tag return elseif (vals) vals = vals + length (att) + 2; vale = regexp (xmlnode(vals:end), '"[ >/]'); if (! isempty (vale)) retval = xmlnode(vals:vals+vale-2); endif endif endfunction io-2.4.10/inst/PaxHeaders.5973/dbfwrite.m0000644000000000000000000000013213226215407014634 xustar0030 mtime=1515789063.556154616 30 atime=1515789063.556154616 30 ctime=1515789065.028183488 io-2.4.10/inst/dbfwrite.m0000644000175000017500000001430413226215407015076 0ustar00olafolaf00000000000000## Copyright (C) 2015-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [@var{status}] = dbfwrite (@var{fname}, @var{data}) ## Write data in a cell array to a dbf (xBase) file, provisionally dBase III+. ## ## @var{fname} must be a valid file name, optionally with '.dbf' suffix. ## @var{data} should be a cell array of which the top row contains column ## names (character strings). Each column must contain only one class of data, ## except of course the top entry (the column header). ## Value type that can be written are character (text sring), numeric ## (integer and float, the latter with 6 decimal places), and logical. ## ## Ouput argument @var{status} is 1 if the file was written successfully, 0 ## otherwise. ## ## Provisionally only dBase v. III+ files can be written without memos. ## ## @seealso{dbfread} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2014-12-24 function [status] = dbfwrite (fname, data) status = 0; ## Input validation if (! ischar (fname)) error ("dbfwrite: file name expected for argument #1\n"); elseif (! iscell (data)) error ("dbfwrite: cell array expected for argument #2\n"); elseif (! iscellstr (data (1, :))) error ("dbfwrite: column header titles (text) expected on first row of data\n"); endif ## Column headers length cannot exceed 10 characters toolong = []; for ii=1:size (data, 2) title = data{1, ii}; if (length (title) > 10) toolong = [ toolong, ii ]; data(1, ii) = title(1:10); endif endfor if (! isempty (toolong)) ## Truncate headers if required and check for uniqueness warning ("dbfwrite: one or more column header(s) > 10 characters - truncated\n"); fmt = [repmat(sprintf ("%d "), 1, numel (toolong))(:)]; printf ("Applies to columns %s\n", sprintf (fmt, toolong)); if (numel (unique (data(1, :))) < numel (data(1, :))) error ("dbfwrite: column headers aren't unique - please fix data\n"); endif endif ## Assess nr of records ## Data contains header row. Data toprow = 2 nrecs = size (data, 1) - 1; tr = 2; ## Check file name [pth, fnm, ext] = fileparts (fname); if (isempty (ext)) fname = [fname ".dbf"]; elseif (! strcmpi (ext, ".dbf")) error ("dbfwrite: file name should have a '.dbf' suffix\n"); endif ## Try to open file fid = fopen (fname, "w+"); if (fid < 0) error ("dbfwrite: could not open file %s\n", fname); endif ## Start writing header ## Provisionally assume dbase III+ w/o memos fwrite (fid, 3, "uint8"); upd = datevec (date); fwrite (fid, upd(1) - 1900, "uint8"); fwrite (fid, upd(2), "uint8"); fwrite (fid, upd(3), "uint8"); fwrite (fid, nrecs, "uint32"); ## The next two uint16 fields are to be written later, just fill temporarily pos_lhdr = ftell (fid); fwrite (fid, 0, "uint32"); ## Another place holder, write enough to allow next fseek to succeed fwrite (fid, uint32 (zeros (1, 7)), "uint32"); ## Write record descriptors nfields = size (data, 2); fldtyp = ""; fldlngs = {}; reclen = 1; ## "Erased" byte first fseek (fid, 32, "bof"); for ii=1:nfields decpl = 0; recdesc = sprintf ("%d", uint32 (zeros (1, 8))); recdesc(1:10) = strjust (sprintf ("%10s", data{1, ii}), "left"); ## Field name if (isnumeric ([data{tr:end, ii}])) if (isinteger ([data{tr:end, ii}]) || all ([data{tr:end, ii}] - floor([data{tr:end, ii}]) < eps)) ftype = "N"; decpl = 0; else ftype = "F"; ## ML compatibility for .dbf/.shp file: 6 decimal places decpl = 6; endif fldlng = 20; elseif (ischar ([data{tr:end, ii}])) ftype = "C"; fldlng = max (cellfun (@(x) length(x), data(tr:end))) + 1; elseif (islogical ([data{tr:end, ii}])) ftype = "L"; fldlng = 1; endif recdesc(12) = ftype; ## Field type fldtyp = [ fldtyp ftype ]; recdesc(17) = uint8 (fldlng); ## Field length recdesc(18) = uint8 (decpl); ## Decimal places recdesc(32) = "\0"; ## Fill to byte# 32 fwrite (fid, recdesc, "char"); reclen += fldlng; fldlngs = [ fldlngs; sprintf("%d", fldlng) ]; endfor ## Write header record terminator fwrite (fid, 13, "uint8"); ## Remember position fpos_data = ftell (fid); ## Write missing data in header fseek (fid, pos_lhdr, "bof"); fwrite (fid, fpos_data, "uint16"); fwrite (fid, reclen, "uint16"); ## Write data2 fseek (fid, fpos_data, "bof"); ## FIXME replace by vectorized code (num2str etc) & concatenating columns ## for speeding up for ii=tr:nrecs+tr-1 ## Write "erased" byte fwrite (fid, "\0", "uint8"); for jj=1:nfields switch fldtyp(jj) case "C" txt = sprintf (["%" fldlngs{jj} "s"], data{ii, jj}); case "N" txt = sprintf (["%" fldlngs{jj} "d"], data{ii, jj}); case "L" if (data{ii, jj}) txt = "Y"; else txt = "N"; endif case "F" txt = sprintf (["%" fldlngs{jj} "f"], data{ii, jj}); case "D" % txt = sprintf (["%" fldlngs{jj} "s"], data{ii, jj}); otherwise endswitch fwrite (fid, txt, "char"); endfor endfor ## Close file fclose (fid); status = 1; endfunction io-2.4.10/inst/PaxHeaders.5973/xlswrite.m0000644000000000000000000000013213226215407014707 xustar0030 mtime=1515789063.604155557 30 atime=1515789063.604155557 30 ctime=1515789065.028183488 io-2.4.10/inst/xlswrite.m0000644000175000017500000002216313226215407015153 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} @var{rstatus} = xlswrite (@var{filename}, @var{arr}) ## @deftypefnx {Function File} @var{rstatus} = xlswrite (@var{filename}, @var{arr}, @var{wsh}) ## @deftypefnx {Function File} @var{rstatus} = xlswrite (@var{filename}, @var{arr}, @var{wsh}, @var{range}) ## @deftypefnx {Function File} @var{rstatus} = xlswrite (@var{filename}, @var{arr}, @var{wsh}, @var{range}, @var{reqintf}) ## Add data in 1D/2D array @var{arr} to worksheet @var{wsh} in Excel ## spreadsheet file @var{filename} in cell range @var{range}. Gnumeric ## files can also be written. ## ## @var{rstatus} returns 1 if writing succeeded, 0 otherwise. ## ## @var{filename} must be a valid Excel file name (including file ## name extension). If @var{filename} does not contain any directory path, ## the file is saved in the current directory. Writing .xlsm and .xlsb ## is untested but may only reliably be possible with the COM and UNO ## interfaces. ## ## @var{arr} can be any 1D or 2D array containing numerical, logical and/or ## character data (cellstr) except complex. Mixed numeric/text arrays can ## only be cell arrays. ## ## If only 3 arguments are given, the 3rd is assumed to be a spreadsheet ## range if it contains a ":" or is a completely empty string (interpreted ## as A1:IV65336 for regular .xls or A1:XFD1048576 for OOXML .xlsx). The ## 3rd argument is assumed to refer to a worksheet if it is a numeric value ## or a non-empty text string not containing ":" ## ## @var{wsh} can be a number or string (max. 31 chars). ## In case of a not yet existing Excel file, the first worksheet will be ## used & named according to @var{wsh} - the extra worksheets that Excel ## usually creates by default are deleted (COM) or simply not created. ## In case of existing files, some checks are made for existing worksheet ## names or numbers, or whether @var{wsh} refers to an existing sheet with ## a type other than worksheet (e.g., chart). ## When new worksheets are to be added to the Excel file, they are ## inserted to the right of all existing worksheets. The pointer to the ## "active" sheet (shown when Excel opens the file) remains untouched. ## ## @var{range} is expected to be a regular spreadsheet range. ## Data is added to the worksheet; existing data in the requested ## range will be overwritten. Instead of a spreadsheet range a Named ## range defined in the spreadsheet file can be used as well. In that ## case the Named range should be specified as 4th argument and the value ## of 3rd argument @var{wsh} doesn't matter as the worksheet associated ## with the specified Named range will be used. ## Array @var{arr} will be clipped at the right and/or bottom if its size ## is bigger than can be accommodated in @var{range}. ## If @var{arr} is smaller than the @var{range} allows, it is placed ## in the top left rectangle of @var{range} and remaining cell values ## outside the rectangle will be retained. ## If the third argument is a sheet name and @var{range} is specified as ## just one cell, it is taken as the topleft cell and the bottomright ## cell range address is determinded form the data. ## ## If @var{range} contains merged cells, only the elements of @var{arr} ## corresponding to the top or left Excel cells of those merged cells ## will be written, other array cells corresponding to that merged cell ## will be ignored. In other words, merged spreadsheet cells won't be ## "unmerged". ## ## As to the optional last argument @var{reqintf}: ## When no external support SW for spreadsheet I/O ('interface') is ## installed (see below), xlsread can only write to .xlsx, .ods and ## .gnumeric files using the default (built-in) 'OCT' interface. If ## external support SW is installed, xlswrite will try locate it ## automatically and invoke it, allowing more file types to be written. ## Multiple spreadsheet I/O 'interfaces' can be installed side-by-side; ## xlswrite will then try to invoke the most suitable one depending ## on file type. ## The optional last argument @var{reqintf} can be used to override ## that automatic selection by xlswrite. Supported interfaces ## comprise: 'com' (ActiveX/Excel), 'poi' (Java/Apache POI), 'jxl' ## (Java/JExcelAPI), 'uno' (Java/OpenOffice.org), or 'oct' (native ## Octave w/o any external support software). 'oxs' (Java/OpenXLS) ## works reliably and fast for .xls (BIFF8) but has been disabled for ## writing OOXML as that is too buggy. For writing to OOXML files ## (.xlsx) a value of 'com', 'poi', 'uno', or 'oct' must be specified ## for @var{reqintf}. The value of @var{reqintf} is case-insensitive. ## Multiple interfaces can be selected if entered as a cell array of ## strings. Writing gnumeric files can only be done with the OCT ## interface, it is selected automatically for that file type. ## ## xlswrite is a mere wrapper for various scripts which find out what ## Excel interface to use (COM, POI, etc) plus code to mimic the other ## brand's syntax. For each call to xlswrite such an interface must be ## started and possibly an Excel file loaded. When writing to multiple ## ranges and/or worksheets in the same Excel file, a speed bonus can be ## obtained by invoking those scripts directly with multiple calls to ## oct2xls (one for each sheet or range) surrounded by one call to ## xlsopen and xlsclose: ## (xlsopen / octxls / oct2xls / .... / xlsclose) ## ## Examples: ## ## @example ## status = xlswrite ... ## ('test4.xls', 'arr', 'Third_sheet', 'C3:AB40'); ## (which adds the contents of array arr (any type) to ## rangeC3:AB40 in worksheet 'Third_sheet' in file ## test4.xls and returns a logical True (= numerical 1) ## in 'status' if all went well) ## @end example ## ## @seealso {xlsread, oct2xls, xls2oct, xlsopen, xlsclose, xlsfinfo} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-10-16 function [ rstatus ] = xlswrite (filename, arr, arg3, arg4, arg5) rstatus = r_extnd = 0; ## Sanity checks if (nargin < 2) error ("Insufficient arguments - see 'help xlswrite'\n"); elseif (! ischar (filename)) error ("xlswrite: first argument must be a filename (incl. suffix)\n"); elseif (nargin == 2) ## Assume first worksheet and full worksheet starting at A1 wsh = 1; if (strcmpi (filename(end-4:end-1), ".xls")) crange = "A1:XFD1048576"; ## OOXML has ridiculously large limits else crange = "A1:IV65536"; ## Regular xls limits endif elseif (nargin == 3) ## Find out whether 3rd argument = worksheet or range if (isnumeric (arg3) || (isempty (findstr (arg3, ":")) && ~isempty (arg3))) ## Apparently a worksheet specified wsh = arg3; if (strcmpi (filename(end-4:end-1), ".xls")) crange = "A1:XFD1048576"; ## OOXML has ridiculously large limits else crange = "A1:IV65536"; ## Regular xls limits endif else ## Range specified wsh = 1; crange = arg3; endif elseif (nargin >= 4) wsh = arg3; crange = arg4; r_extnd = (! isempty (crange) && isempty (strfind (crange, ":")) && nargin >= 4); endif if (nargin == 5) reqintf = arg5; else reqintf = []; endif if (isempty (wsh)) wsh = 1; endif if (isempty (crange) || r_extnd) if (r_extnd) tlcl = crange; else tlcl = "A1"; endif if (strcmpi (filename(end-4:end-1), ".xls")) crange = [tlcl ":XFD1048576"]; ## OOXML has ridiculously large limits else crange = [tlcl ":IV65536"]; ## Regular xls limits endif endif ## Parse range [topleft, nrows, ncols, trow, lcol] = parse_sp_range (crange); ## Check if arr fits in range [nr, nc] = size (arr); if ((nr > nrows) || (nc > ncols)) # Array too big; truncate nr = min (nrows, nr); nc = min (ncols, nc); warning ("xlswrite - array truncated to %d by %d to fit in range %s\n", ... nrows, ncols, crange); ## Adapt crange crange = [ calccelladdress(trow, lcol) ":" ... calccelladdress(trow+nrows-1, lcol+ncols-1) ]; endif unwind_protect ## Needed to be sure Excel can be closed i.c.o. errors xls_ok = 0; xls = xlsopen (filename, 1, reqintf); if (! isempty (xls)) xls_ok = 1; [xls, rstatus] = oct2xls (arr(1:nr, 1:nc), xls, wsh, crange); endif unwind_protect_cleanup if (xls_ok && ! isempty (xls)) xls = xlsclose (xls); endif end_unwind_protect if (! isempty (xls)) ## Apparently the file pointer couldn't be cleared, usually due to errors rstatus = 0; endif endfunction io-2.4.10/inst/PaxHeaders.5973/private0000644000000000000000000000013213226215407014245 xustar0030 mtime=1515789063.600155479 30 atime=1515789065.028183488 30 ctime=1515789065.028183488 io-2.4.10/inst/private/0000755000175000017500000000000013226215407014562 5ustar00olafolaf00000000000000io-2.4.10/inst/private/PaxHeaders.5973/__ods_get_sheet_dims__.m0000644000000000000000000000013213226215407021124 xustar0030 mtime=1515789063.596155401 30 atime=1515789063.596155401 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__ods_get_sheet_dims__.m0000644000175000017500000001314013226215407021363 0ustar00olafolaf00000000000000## Copyright (C) 2013-2017 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 Octave; see the file COPYING. If not, see ## . ## __ods_get_sheet_dims__ ## Internal function - get dimensions of occupied cell range in an ODS sheet. ## Author: Philip Nienhuis ## Created: 2013-09-29 (split off from __JOD_getusedrange__.m) function [trow, brow, lcol, rcol ] = __ods_get_sheet_dims__ (sh) ## 1. Get table-row pointers id_trow = strfind (sh, "") - 1; id_trow = [id_trow id]; trow = rcol = 0; lcol = 1024; brow = 0; if (~isempty (id)) ## 2. Loop over all table-rows rowrepcnt = 0; for irow = 1:length (id_trow)-1 ## Isolate single table-row tablerow = sh(id_trow(irow):id_trow(irow+1)-1); ## Search table-cells. table-c covers both table-cell & table-covered-cell id_tcell = strfind (tablerow, ". ## -*- texinfo -*- ## @deftypefn {Function File} {@var{nmr} =} getnmranges (@var{xls}) ## Get named ranges from spreadsheet pointed to in spreasheet file ptr xls ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2015-09-18 function [nmranges] = getnmranges (xls) intf = xls.xtype; switch intf case "COM" nmranges = __COM_getnmranges__ (xls); case "POI" nmranges = __POI_getnmranges__ (xls); case "JXL" nmranges = __JXL_getnmranges__ (xls); case "OXS" nmranges = __OXS_getnmranges__ (xls); case "UNO" nmranges = __UNO_getnmranges__ (xls); case "OTK" nmranges = __OTK_getnmranges__ (xls); case "JOD" nmranges = __JOD_getnmranges__ (xls); case "OCT" nmranges = __OCT_getnmranges__ (xls); otherwise error "(This error shouldn't happen, please enter bug report"); endswitch ## Remove quotes from sheet names with spaces nmranges(:, 2) = regexprep (nmranges(:, 2), "^'?([^'].*[' ]+.*)'$", '$1'); endfunction io-2.4.10/inst/private/PaxHeaders.5973/__UNO_spsh_open__.m0000644000000000000000000000013213226215407020013 xustar0030 mtime=1515789063.592155322 30 atime=1515789063.592155322 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__UNO_spsh_open__.m0000644000175000017500000001174313226215407020261 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## __UNO_xlsopen__ - Internal function for opening a spreadsheet file using Java / OOo/LO UNO ## Author: Philip Nienhuis ## Created: 2012-10-07 function [ xls, xlssupport, lastintf ] = __UNO_spsh_open__ (xls, xwrite, filename, xlssupport) ## First, the file name must be transformed into a URL if (! isempty (strfind (filename, "file:///")) || ... ! isempty (strfind (filename, "http://" )) || ... ! isempty (strfind (filename, "ftp://" )) || ... ! isempty (strfind (filename, "www://" ))) ## Seems in proper shape for OOo (at first sight) else ## Transform into URL form. ## FIXME on Windows, make_absolute_filename() doesn't work across ## drive(-letters) so until it is (ever) fixed we'll fall back on ## canonicalize_file_name() there. if (ispc) fname = canonicalize_file_name (filename); if (isempty (fname)) ## File doesn't exist yet? try make_absolute_filename() fname = make_absolute_filename (filename); endif else fname = make_absolute_filename (filename); endif ## On Windows, change backslash file separator into forward slash if (strcmp (filesep, "\\")) tmp = strsplit (fname, filesep); flen = numel (tmp); tmp(2:2:2*flen) = tmp; tmp(1:2:2*flen) = '/'; fname = [ tmp{:} ]; endif filename = [ "file://" fname ]; endif try xContext = javaMethod ("bootstrap", "com.sun.star.comp.helper.Bootstrap"); xMCF = xContext.getServiceManager (); oDesktop = xMCF.createInstanceWithContext ("com.sun.star.frame.Desktop", ... xContext); ## Workaround for .queryInterface(): unotmp = javaObject ("com.sun.star.uno.Type", ... "com.sun.star.frame.XComponentLoader"); aLoader = oDesktop.queryInterface (unotmp); ## Some trickery as Octave Java cannot create initialized arrays lProps = javaArray ("com.sun.star.beans.PropertyValue", 2); ## Set file type property [ftype, filtnam] = __get_ftype__ (filename); if (isempty (filtnam)) filtnam = "calc8"; endif lProp = javaObject ... ("com.sun.star.beans.PropertyValue", "FilterName", 0, filtnam, []); lProps(1) = lProp; ## Set hidden property lProp = javaObject ("com.sun.star.beans.PropertyValue", "Hidden", 0, true, []); lProps(2) = lProp; flags = 0; if (xwrite > 2) xComp = aLoader.loadComponentFromURL ("private:factory/scalc", ... "_blank", flags, lProps); else xComp = aLoader.loadComponentFromURL (filename, "_blank", flags, lProps); endif ## Workaround for .queryInterface(): unotmp = javaObject ("com.sun.star.uno.Type", ... "com.sun.star.sheet.XSpreadsheetDocument"); xSpdoc = xComp.queryInterface (unotmp); ## save in ods struct: xls.xtype = "UNO"; xls.workbook = xSpdoc; ## Needed to be able to close soffice in odsclose() xls.filename = filename; xls.app.xComp = xComp; ## Needed to be able to close soffice in odsclose() xls.app.aLoader = aLoader;## Needed to be able to close soffice in odsclose() xls.odfvsn = "UNO"; xlssupport += 16; lastintf = "UNO"; catch ## Check if we have a 32 vs. 64 bit clash printf ("\nOops, Octave hit an error.\n"); ## 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 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 (! 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 error ("Couldn't open file %s using UNO\n", filename); end_try_catch endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OTK_chk_sprt__.m0000644000000000000000000000013213226215407017626 xustar0030 mtime=1515789063.580155087 30 atime=1515789063.580155087 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OTK_chk_sprt__.m0000644000175000017500000000557513226215407020102 0ustar00olafolaf00000000000000## Copyright (C) 2014-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} __OTK_chk_sprt__ (@var{varargin}) ## Undocumented internal function ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2014-10-31 function [chk, missing5] = __OTK_chk_sprt__ (jcp, dbug=0) chk = 0; if (dbug > 1) printf ("\nODF Toolkit (.ods) :\n"); endif entries5 = {"odfdom", "xerces", {"xml-apis", "xml-commons-apis"}}; [jpchk, missing5] = chk_jar_entries (jcp, entries5, dbug); missing5 = entries5 (find (missing5)); ## Check xerces (version 2.9.1 = stand-alone, 2.10.+ needs xml-apis.jar) try xvsn = javaMethod ("getVersion", "org.apache.xerces.impl.Version"); if (index (xvsn, "2.9.1") && strncmp (missing5, "xml", 3)) jpchk++; endif if (dbug > 2) printf (" xerces version: %s\n", xvsn); endif catch end_try_catch if (jpchk >= numel (entries5)) ## Apparently all required classes present. Only now we can check for proper ## odfdom version (only 0.7.5 & 0.8.6-0.8.8 work OK). ## The odfdom team deemed it necessary to change the version call so we need this: odfvsn = " "; try ## New in 0.8.6 odfvsn = javaMethod ("getOdfdomVersion", "org.odftoolkit.odfdom.JarManifest"); catch ## Worked in 0.7.5 odfvsn = javaMethod ("getApplicationVersion", "org.odftoolkit.odfdom.Version"); end_try_catch if (dbug > 2) printf (" odfdom version: %s\n", odfvsn); endif ## For odfdom-incubator (= 0.8.8+), strip extra info after version odfvsn = regexp (odfvsn, '[0123456789]+\.[0123456789]+\.[01234567890]+', "match"){1}; if (! (strcmp (odfvsn, "0.7.5") || (compare_versions (odfvsn, "0.8.6", ">=") ... && compare_versions (odfvsn, "0.8.8", "<=")))) chk = -1; if (dbug > 1) printf (" *** odfdom version (%s) is not supported - use v. 0.8.6 - 0.8.8\n", ... odfvsn); endif else chk = 1; if (dbug > 1) printf (" => ODFtoolkit (OTK) OK.\n"); endif endif elseif (dbug > 1) printf (" => Not all required classes (.jar) in classpath for OTK\n"); endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__JOD_spsh2oct__.m0000644000000000000000000000013213226215407017535 xustar0030 mtime=1515789063.568154851 30 atime=1515789063.568154851 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__JOD_spsh2oct__.m0000644000175000017500000002026213226215407017777 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## __JOD_spsh2oct__ - get data out of an ODS spreadsheet into octave using jOpenDocument. ## Watch out, no error checks, and spreadsheet formula error results ## are conveyed as 0 (zero). ## ## Author: Philip Nienhuis ## Created: 2009-12-13 function [ rawarr, ods, rstatus] = __JOD_spsh2oct__ (ods, wsh, crange, spsh_opts) persistent months; months = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", ... "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"}; persistent octv = compare_versions (version, "4.1.0", ">="); rstatus = 0; ## Check jOpenDocument version sh = ods.workbook.getSheet (0); cl = sh.getCellAt (0, 0); if (ods.odfvsn >= 3) ## 1.2b3+ has public getValueType () persistent ctype; if (isempty (ctype)) BOOLEAN = char (__java_get__ ("org.jopendocument.dom.ODValueType", "BOOLEAN")); CURRENCY = char (__java_get__ ("org.jopendocument.dom.ODValueType", "CURRENCY")); DATE = char (__java_get__ ("org.jopendocument.dom.ODValueType", "DATE")); FLOAT = char (__java_get__ ("org.jopendocument.dom.ODValueType", "FLOAT")); PERCENTAGE = char (__java_get__ ("org.jopendocument.dom.ODValueType", "PERCENTAGE")); STRING = char (__java_get__ ("org.jopendocument.dom.ODValueType", "STRING")); TIME = char (__java_get__ ("org.jopendocument.dom.ODValueType", "TIME")); endif endif ## Sheet INDEX starts at 0 if (isnumeric (wsh)); --wsh; endif ## Check if sheet exists. If wsh = numeric, nonexistent sheets throw errors. try sh = ods.workbook.getSheet (wsh); catch error ("xls/ods2oct: illegal sheet number (%d) requested for file %s\n", ... wsh+1, ods.filename); end_try_catch ## If wsh = string, nonexistent sheets yield empty results if (isempty (sh)) error ("xls/ods2oct: no sheet called '%s' present in file %s\n", wsh, ... ods.filename); endif ## Either parse (given cell range) or prepare (unknown range) help variables if (isempty (crange)) if (ods.odfvsn < 3) error ("xls/ods2oct: no empty read range allowed in jOpenDocument version 1.2b2") else if (isnumeric (wsh)); wsh = wsh + 1; endif [ trow, brow, lcol, rcol ] = getusedrange (ods, wsh); nrows = brow - trow + 1; ## Number of rows to be read ncols = rcol - lcol + 1; ## Number of columns to be read endif else [dummy, nrows, ncols, trow, lcol] = parse_sp_range (crange); ## Check ODS column limits if (lcol > 1024 || trow > 65536) error ("xls/ods2oct: invalid range; max 1024 columns & 65536 rows."); endif ## Truncate range silently if needed rcol = min (lcol + ncols - 1, 1024); ncols = min (ncols, 1024 - lcol + 1); nrows = min (nrows, 65536 - trow + 1); brow = trow + nrows - 1; endif ## Create storage for data content rawarr = cell (nrows, ncols); if (ods.odfvsn >= 3) ## Version 1.2b3+ for ii=1:nrows for jj = 1:ncols try scell = sh.getCellAt (lcol+jj-2, trow+ii-2); if (spsh_opts.formulas_as_text) ## Check if it is a formula =[.C5]+[.C7] frml = scell.getFormula (); if (! isempty (frml)) ## For older jOpenDocument than 1.4.x frml = strrep (frml, "of:", ""); rawarr{ii, jj} = regexprep (frml, '\[\.(\$?[A-Z]+\$?[0-9]+)\]', '$1'); sctype = "FORMULA"; else sctype = char (scell.getValueType ()); endif else sctype = char (scell.getValueType ()); endif switch sctype ## try both char value (Octave) and ODValuetype (jOpenDocument) for ## backward compatibility with older jOpenDocument versions case { FLOAT, " FLOAT", CURRENCY, "CURRENCY", PERCENTAGE, "PERCENTAGE" } ## Next IF reqd. as temporary workaround for bugs #48013 and #48591 if (octv) rawarr{ii, jj} = scell.getValue ().doubleValue (); else rawarr{ii, jj} = scell.getValue (); endif case { BOOLEAN, "BOOLEAN" } rawarr {ii, jj} = scell.getValue () == 1; case { STRING, "STRING" } rawarr{ii, jj} = scell.getValue(); case { DATE, "DATE" } tmp = strsplit (char (scell.getValue ()), " "); yy = str2num (tmp{6}); mo = find (ismember (months, toupper (tmp{2})) == 1); dd = str2num (tmp{3}); hh = str2num (tmp{4}(1:2)); mi = str2num (tmp{4}(4:5)); ss = str2num (tmp{4}(7:8)); rawarr{ii, jj} = datenum (yy, mo, dd, hh, mi, ss); case { TIME, "TIME" } tmp = strsplit (char (scell.getValue ().getTime ()), " "); hh = str2num (tmp{4}(1:2)) / 24.0; mi = str2num (tmp{4}(4:5)) / 1440.0; ss = str2num (tmp{4}(7:8)) / 86600.0; rawarr {ii, jj} = hh + mi + ss; case "FORMULA" ## Do nothing, was catched above the switch stmt otherwise ## Workaround for sheets written by jOpenDocument (no value-type attrb): if (! isempty (scell.getValue) ) ## FIXME Assume cell contains string if there's a text attr. ## But it could be BOOLEAN too... rawarr{ii, jj} = scell.getValue(); if (findstr (". ## __JXL_spsh_close__ - internal function: close a spreadsheet file using JXL ## Author: Philip Nienhuis ## Created: 2012-10-12 function [ xls ] = __JXL_spsh_close__ (xls) if (xls.changed > 0 && xls.changed < 3) try xls.workbook.write (); xls.workbook.close (); if (xls.changed == 3) ## Upon entering write mode, JExcelAPI always resets disk file. ## Incomplete new files (no data added) had better be deleted. xls.workbook.close (); delete (xls.filename); endif xls.changed = 0; catch end_try_catch endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__COM_spsh_close__.m0000644000000000000000000000013213226215407020134 xustar0030 mtime=1515789063.568154851 30 atime=1515789063.568154851 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__COM_spsh_close__.m0000644000175000017500000000527213226215407020402 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## __COM_spsh_close__ - internal function: close a spreadsheet file using COM ## Author: Philip Nienhuis ## Created: 2012-10-12 function [ xls ] = __COM_spsh_close__ (xls) ## If file has been changed, write it out to disk. ## ## Note: COM / VB supports other Excel file formats as FileFormatNum: ## 4 = .wks - Lotus 1-2-3 / Microsoft Works ## 6 = .csv ## -4158 = .txt ## 36 = .prn ## 50 = .xlsb - xlExcel12 (Excel Binary Workbook in 2007 with or without macro's) ## 51 = .xlsx - xlOpenXMLWorkbook (without macro's in 2007) ## 52 = .xlsm - xlOpenXMLWorkbookMacroEnabled (with or without macro's in 2007) ## 56 = .xls - xlExcel8 (97-2003 format in Excel 2007) ## (see Excel Help, VB reference, Enumerations, xlFileType) ## xls.changed = 0: no changes: just close; ## 1: existing file with changes: save, close. ## 2: new file with data added: save, close ## 3: new file, no added added (empty): close & delete on disk xls.app.Application.DisplayAlerts = 0; try if (xls.changed > 0 && xls.changed < 3) if (isfield (xls, "nfilename")) fname = xls.nfilename; else fname = xls.filename; endif fname = make_absolute_filename (strsplit (fname, filesep){end}); if (xls.changed == 2) ## Probably a newly created, or renamed, Excel file ## SaveCopyAs rather than SaveAs seems more robust w. Excel2007+ xls.workbook.SaveCopyAs (fname); elseif (xls.changed == 1) ## Just updated existing Excel file xls.workbook.Save (); endif xls.changed = 0; xls.workbook.Close (fname); endif xls.app.Quit (); delete (xls.workbook); ## This statement actually closes the workbook delete (xls.app); ## This statement actually closes down Excel catch xls.app.Application.DisplayAlerts = 1; end_try_catch endfunction io-2.4.10/inst/private/PaxHeaders.5973/__JOD_getnmranges__.m0000644000000000000000000000013213226215407020302 xustar0030 mtime=1515789063.568154851 30 atime=1515789063.568154851 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__JOD_getnmranges__.m0000644000175000017500000000211213226215407020536 0ustar00olafolaf00000000000000## Copyright (C) 2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} __JOD_getnmranges__ (@var{input1}, @var{input2}) ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2015-09-20 function [nmr] = __JOD_getnmranges__ (ods) ## Currently just a stub. Named ranges do not work in jOpenDocument nmr = cell (0, 3); endfunction io-2.4.10/inst/private/PaxHeaders.5973/__JXL_spsh2oct__.m0000644000000000000000000000013213226215407017556 xustar0030 mtime=1515789063.572154929 30 atime=1515789063.572154929 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__JXL_spsh2oct__.m0000644000175000017500000002036613226215407020025 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## @deftypefn {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = __JXL_spsh2oct__ (@var{xls}) ## @deftypefnx {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = __JXL_spsh2oct__ (@var{xls}, @var{wsh}) ## @deftypefnx {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = __JXL_spsh2oct__ (@var{xls}, @var{wsh}, @var{range}) ## Get cell contents in @var{range} in worksheet @var{wsh} in an Excel ## file pointed to in struct @var{xls} into the cell array @var{obj}. ## @var{range} can be a range or just the top left cell of the range. ## ## __JXL_spsh2oct__ should not be invoked directly but rather through xls2oct. ## ## Examples: ## ## @example ## [Arr, status, xls] = __JXL_spsh2oct__ (xls, "Second_sheet", "B3:AY41"); ## B = __JXL_spsh2oct__ (xls, "Second_sheet"); ## @end example ## ## @seealso {xls2oct, oct2xls, xlsopen, xlsclose, xlsread, xlswrite, oct2jxla2xls} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-12-04 function [ rawarr, xls, rstatus ] = __JXL_spsh2oct__ (xls, wsh, cellrange, spsh_opts) persistent ctype; persistent months; if (isempty (ctype)) ctype = cell (11, 1); ## Get enumerated cell types. Beware as they start at 0 not 1 ctype( 1) = (__java_get__ ("jxl.CellType", "BOOLEAN")).toString (); ctype( 2) = (__java_get__ ("jxl.CellType", "BOOLEAN_FORMULA")).toString (); ctype( 3) = (__java_get__ ("jxl.CellType", "DATE")).toString (); ctype( 4) = (__java_get__ ("jxl.CellType", "DATE_FORMULA")).toString (); ctype( 5) = (__java_get__ ("jxl.CellType", "EMPTY")).toString (); ctype( 6) = (__java_get__ ("jxl.CellType", "ERROR")).toString (); ctype( 7) = (__java_get__ ("jxl.CellType", "FORMULA_ERROR")).toString (); ctype( 8) = (__java_get__ ("jxl.CellType", "NUMBER")).toString (); ctype( 9) = (__java_get__ ("jxl.CellType", "LABEL")).toString (); ctype(10) = (__java_get__ ("jxl.CellType", "NUMBER_FORMULA")).toString (); ctype(11) = (__java_get__ ("jxl.CellType", "STRING_FORMULA")).toString (); months = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"}; endif rstatus = 0; wb = xls.workbook; ## Check if requested worksheet exists in the file & if so, get pointer nr_of_sheets = wb.getNumberOfSheets (); shnames = char (wb.getSheetNames ()); if (isnumeric (wsh)) if (wsh > nr_of_sheets) error (sprintf ("Worksheet ## %d bigger than nr. of sheets (%d) in file %s",... wsh, nr_of_sheets, xls.filename)); endif sh = wb.getSheet (wsh - 1); ## JXL sheet count 0-based ## printf ("(Reading from worksheet %s)\n", shnames {wsh}); else sh = wb.getSheet (wsh); if (isempty (sh)) error (sprintf ("Worksheet %s not found in file %s", wsh, xls.filename)); endif end if (isempty (cellrange)) ## Get numeric sheet pointer (1-based) ii = 1; while (ii <= nr_of_sheets) if (strcmp (wsh, shnames{ii}) == 1) wsh = ii; ii = nr_of_sheets + 1; else ++ii; endif endwhile ## Get data rectangle row & column numbers (1-based) [firstrow, lastrow, lcol, rcol] = getusedrange (xls, wsh); if (firstrow == 0 && lastrow == 0) ## Empty sheet rawarr = {}; printf ("Worksheet '%s' contains no data\n", shnames {wsh}); rstatus = 1; return; else nrows = lastrow - firstrow + 1; ncols = rcol - lcol + 1; endif else ## Translate range to row & column numbers (1-based) [dummy, nrows, ncols, firstrow, lcol] = parse_sp_range (cellrange); ## Check for too large requested range against actually present range lastrow = min (firstrow + nrows - 1, sh.getRows ()); nrows = min (nrows, sh.getRows () - firstrow + 1); ncols = min (ncols, sh.getColumns () - lcol + 1); rcol = lcol + ncols - 1; endif ## Read contents into rawarr rawarr = cell (nrows, ncols); ## create placeholder for jj = lcol : rcol for ii = firstrow:lastrow scell = sh.getCell (jj-1, ii-1); switch char (scell.getType ()) case ctype{1} ## Boolean rawarr {ii+1-firstrow, jj+1-lcol} = scell.getValue (); case ctype{2} ## Boolean formula if (spsh_opts.formulas_as_text) tmp = scell.getFormula (); rawarr {ii+1-firstrow, jj+1-lcol} = ["=" tmp]; else rawarr {ii+1-firstrow, jj+1-lcol} = scell.getValue (); endif case ctype{3} ## Date try % Older JXL.JAR, returns float rawarr {ii+1-firstrow, jj+1-lcol} = scell.getValue (); catch % Newer JXL.JAR, returns date string w. epoch = 1-1-1900 :-( tmp = strsplit (char (scell.getDate ()), " "); yy = str2num (tmp{6}); mo = find (ismember (months, upper (tmp{2})) == 1); dd = str2num (tmp{3}); hh = str2num (tmp{4}(1:2)); mi = str2num (tmp{4}(4:5)); ss = str2num (tmp{4}(7:8)); if (scell.isTime ()) yy = mo = dd = 0; endif rawarr {ii+1-firstrow, jj+1-lcol} = datenum (yy, mo, dd, hh, mi, ss); end_try_catch case ctype{4} ## Date formula if (spsh_opts.formulas_as_text) tmp = scell.getFormula (); rawarr {ii+1-firstrow, jj+1-lcol} = ["=" tmp]; else unwind_protect % Older JXL.JAR, returns float tmp = scell.getValue (); % if we get here, we got a float (old JXL). % Check if it is time if (! scell.isTime ()) % Reset rawarr <> so it can be processed below as date string rawarr {ii+1-firstrow, jj+1-lcol} = []; else rawarr {ii+1-firstrow, jj+1-lcol} = tmp; end unwind_protect_cleanup if (isempty (rawarr {ii+1-firstrow, jj+1-lcol})) % Newer JXL.JAR, returns date string w. epoch = 1-1-1900 :-( tmp = strsplit (char (scell.getDate ()), " "); yy = str2num (tmp{6}); mo = find (ismember (months, upper (tmp{2})) == 1); dd = str2num (tmp{3}); hh = str2num (tmp{4}(1:2)); mi = str2num (tmp{4}(4:5)); ss = str2num (tmp{4}(7:8)); if (scell.isTime ()) yy = 0; mo = 0; dd = 0; end rawarr {ii+1-firstrow, jj+1-lcol} = datenum (yy, mo, dd, hh, mi, ss); endif end_unwind_protect endif case { ctype{5}, ctype{6}, ctype{7} } ## Empty, Error or Formula error. Nothing to do here case ctype{8} ## Number rawarr {ii+1-firstrow, jj+1-lcol} = scell.getValue (); case ctype{9} ## String rawarr {ii+1-firstrow, jj+1-lcol} = scell.getString (); case ctype{10} ## Numerical formula if (spsh_opts.formulas_as_text) tmp = scell.getFormula (); rawarr {ii+1-firstrow, jj+1-lcol} = ["=" tmp]; else rawarr {ii+1-firstrow, jj+1-lcol} = scell.getValue (); endif case ctype{11} ## String formula if (spsh_opts.formulas_as_text) tmp = scell.getFormula (); rawarr {ii+1-firstrow, jj+1-lcol} = ["=" tmp]; else rawarr {ii+1-firstrow, jj+1-lcol} = scell.getString (); endif otherwise ## Do nothing endswitch endfor endfor rstatus = 1; xls.limits = [lcol, rcol; firstrow, lastrow]; endfunction io-2.4.10/inst/private/PaxHeaders.5973/__COM_chk_sprt__.m0000644000000000000000000000013213226215407017607 xustar0030 mtime=1515789063.564154773 30 atime=1515789063.564154773 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__COM_chk_sprt__.m0000644000175000017500000000365513226215407020060 0ustar00olafolaf00000000000000## Copyright (C) 2014-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} __COM_chk_sprt__ (@var{dbug}) ## Undocumented internal function ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2014-10-31 function [retval] = __COM_chk_sprt__ (dbug) retval = false; if (dbug >= 1) printf ("Checking Excel/ActiveX/COM... "); endif try app = actxserver ("Excel.application"); ## If we get here, the call succeeded & COM works. xlsinterfaces.COM = 1; ## Close Excel to avoid zombie Excel invocation app.Quit(); delete(app); if (dbug >= 1) printf ("OK.\n\n"); endif retval = true; catch ## COM not supported if (dbug >= 1) printf ("not working.\n"); endif ## Check if Windows package is installed and loaded pkglist = pkg ("list"); winpkgind = find (cellfun (@(x) strcmp(x.name, "windows"), pkglist), 1, "first"); if (! isempty (winpkgind)) winpkg = pkglist{winpkgind}; if (winpkg.loaded && dbug) printf ("MS-Excel couldn't be started although OF windows is loaded...\n"); endif elseif (dbug >= 1) printf ("(OF windows package is required for COM/ActiveX support)\n"); endif end_try_catch endfunction io-2.4.10/inst/private/PaxHeaders.5973/__XMLrw_chk_sprt__.m0000644000000000000000000000013213226215407020202 xustar0030 mtime=1515789063.592155322 30 atime=1515789063.592155322 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__XMLrw_chk_sprt__.m0000644000175000017500000000336313226215407020447 0ustar00olafolaf00000000000000## Copyright (C) 2015-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} __XMLrw_chk_sprt__ (@var{input1}, @var{input2}) ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2015-11-03 function [chk, missing] = __XMLrw_chk_sprt__ (jcp, dbug=0) chk = 0; if (dbug > 2) printf ("xerces:\n"); endif ## We need xerces and one of xml-apis/xml-commons-apis entries = {"xerces", {"xml-apis", "xml-commons-apis"}}; [jpchk, missing] = chk_jar_entries (jcp, entries, dbug); missing = entries (find (missing)); ## Check xerces version (2.11.0+ needed) try xvsn = javaMethod ("getVersion", "org.apache.xerces.impl.Version"); ## Get version string proper xvsn = cell2mat (cell2mat (regexp (xvsn, '(\d+\.\d+\.\d+)', 'tokens'))); if (compare_versions (xvsn, "2.11.0", ">=") && isempty (missing)) chk = (jpchk == numel (entries)); endif if (dbug > 2) printf (" xerces version: %s\n", xvsn); endif catch end_try_catch endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OCT_xlsx2oct__.m0000644000000000000000000000013213226215407017567 xustar0030 mtime=1515789063.580155087 30 atime=1515789063.580155087 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OCT_xlsx2oct__.m0000644000175000017500000002256513226215407020041 0ustar00olafolaf00000000000000## Copyright (C) 2013,2014 Markus Bergholz ## Parts Copyright (C) 2013-2017 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 Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## @deftypefn {Function File} [ @var{raw}, @var{xls}, @var rstatus} ] = __OCT_xlsx2oct__ (@var{xlsx}, @var{wsh}, @var{range}, @spsh_opts) ## Internal function for reading data from an xlsx worksheet ## ## @seealso{} ## @end deftypefn ## Author: Markus Bergholz ## Created: 2013-10-04 function [ raw, xls, rstatus ] = __OCT_xlsx2oct__ (xls, wsh, crange="", spsh_opts) ## spsh_opts is guaranteed to be filled by caller ## If a worksheet if given, check if it's given by a name (string) or a number if (ischar (wsh)) ## Search for requested sheet name id = find (strcmp (xls.sheets.sh_names, wsh)); if (isempty (id)) error ("xls2oct: cannot find sheet '%s' in file %s", wsh, xls.filename); else wsh = id; endif elseif (wsh > numel (xls.sheets.sh_names)) error ("xls2oct: worksheet number %d > number of worksheets in file (%d)", wsh, numel (xls.sheets.sh_names)); elseif (wsh < 1) warning ("xls2oct: illegal worksheet number (%d) - worksheet #1 assumed\n", wsh); endif ## 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 wsh = xls.sheets.rels( xls.sheets.rels(:,1) == id ,2); rawsheet = fopen (sprintf ('%s/xl/worksheets/sheet%d.xml', xls.workbook, wsh)); if (rawsheet <= 0) error ("Couldn't open worksheet xml file sheet%d.xml\n", wsh); endif else ## Get data rawdata = fread (rawsheet, "char=>char").'; fclose (rawsheet); ## Strings try fid = fopen (sprintf ("%s/xl/sharedStrings.xml", xls.workbook)); strings = fread (fid, "char=>char").'; fclose (fid); catch ## No sharedStrings.xml; implies no "fixed" strings (computed strings can ## still be present) strings = ""; end_try_catch endif rstatus = 0; ## 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 range may 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. ## In below regexps, we ignore "cm" and "ph" tags immediately after tag. As soon as we hit them in the wild ## these can be added (at the cost of speed performance). ## Get cell addresses and contents of t=".." tags, "", "" and "" ## nodes, optionally just placeholders val = regexp (rawdata, ']*(>)|(?:[^t>]*t="(\w+)")>)(?:|/>))?(?:]*)>([^<]*)|([^<]*))', "tokens"); ## : (.*?) ## formula: .. if (any (cellfun (@length, val) != 3)) warning ("Error reading data from sheet %d", wsh); val = cell (0, 2); elseif (! isempty (val)) val = cat (1, val{:}); ## Booleans idx = strmatch ("b", val(:, 2)); if (! isempty (idx)) id = find (str2double (val(idx, 3))); val(idx, 3) = false; val(idx(id), 3) = true; endif ## Numeric data idx = strmatch (">", val(:, 2)); idx = [idx strmatch("n", val(:, 2))]; if (! isempty (idx)) val(idx, 3) = num2cell (str2double (val(idx, 3))); endif ## Date / time idx = strmatch ("d", val(:, 2)); ## Process date nodes if (! isempty (idx)) val(idx, 3) = num2cell (datenum(val(:, 3)), "yyyy-mm-ddTHH:MM"); endif ## 2.A. Formula strings if (spsh_opts.formulas_as_text) ## Drop t="str" entries. The formula node contents will be catched later idx = strmatch ("str", val(:, 2), "exact"); val(idx, :) = []; endif ## 2.B. Shared strings ## Don't mix with t="str" entries => "exact" option idx = strmatch ("s", val(:, 2), "exact"); if (! isempty (strings) && ! isempty (idx)) ## Extract string values. May be much more than present in current sheet strings = regexp (strings, ']*>.*?', "match"); ctext = cell (numel (strings)); if (! isempty (strings)) for n = 1:numel (strings) ctext{n, 1} = cell2mat (cell2mat (regexp (strings{1, n}, ']*>(.*?)', "tokens"))); end ## Get actual values. Watch out for empty strings val(idx, 3) = ctext(str2double (val(idx, 3)) + 1); ids = cellfun (@isempty, val(idx, 3)); if (any (ids)) vals(idx(ids)) = {""}; endif endif endif ## 2.C. Inline strings ## No need to process them, they're already catched as strings clear idx; endif ## 2. String / text formulas (cached results are in this sheet; fixed strings ## in ) ## 2.A Formulas if (spsh_opts.formulas_as_text) ## Get formulas themselves as text strings. Formulas can have a ## 't="str"' attribute. Keep starting '>' for next line ## FIXME: repeated formulas spanning several cells are not processed yet ## (see bug #51512) valf = regexp (rawdata, ')|(?:[^t>]*?t="(\w+)?")>).*?)', "tokens"); if (any (cellfun (@length, valf) != 3)) warning ("Error reading formula data from sheet %d", wsh); valf = cell (0, 2); elseif (! isempty (valf)) valf = cat (1, valf{:}); ## Formulas start with '=' so: valf(:, 3) = regexprep (valf(:, 3), "^>", "="); val = [val; valf]; endif clear valf; endif ## 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 (val(:, 1), '(\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 (val(:, 1), '([A-Za-z]+|[A-Za-z]+[A-Za-z]+|[A-Za-z]+[A-Za-z]+[A-Za-z]+)?', "match")); idx.all = val(:, 1); 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(:, 3); ## Process requested cell range argument if (! isempty (crange)) ## 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 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); endif if (! isempty (val)) rstatus = 1; endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__JXL_getnmranges__.m0000644000000000000000000000013213226215407020323 xustar0030 mtime=1515789063.572154929 30 atime=1515789063.572154929 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__JXL_getnmranges__.m0000644000175000017500000000211313226215407020560 0ustar00olafolaf00000000000000## Copyright (C) 2015-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} __JXL_getnmranges__ (@var{input1}, @var{input2}) ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2015-09-20 function [nmr] = __JXL_getnmranges__ (xls) ## Currently just a stub. Named ranges do not work in JExcelAPI nmr = cell (0, 3); endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OCT_merge_data__.m0000644000000000000000000000013213226215407020071 xustar0030 mtime=1515789063.576155008 30 atime=1515789063.576155008 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OCT_merge_data__.m0000644000175000017500000000515113226215407020333 0ustar00olafolaf00000000000000## Copyright (C) 2014-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} __OCT_merge_data__ (@var{input1}, @var{input2}) ## Internal function meant for merging existing sheet data and new data ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2014-01-29 function [rawarr, lims, onr, onc] = __OCT_merge_data__ (rawarr, lims, obj, obj_dims) ## C . If required, adapt current data array size to disjoint new data if (! isempty (rawarr)) ## Merge new & current data. Assess where to augment/overwrite current data [onr, onc] = size (rawarr); if (obj_dims.tr < lims(2, 1)) ## New data requested above current data. Add rows above current data rawarr = [ cell(lims(2, 1) - obj_dims.tr, onc) ; rawarr]; lims(2, 1) = obj_dims.tr; endif if (obj_dims.br > lims(2, 2)) ## New data requested below current data. Add rows below current data rawarr = [rawarr ; cell(obj_dims.br - lims(2, 2), onc)]; lims (2, 2) = obj_dims.br; endif ## Update number of rawarr rows onr = size (rawarr, 1); if (obj_dims.lc < lims(1, 1)) ## New data requested to left of curremnt data; prepend columns rawarr = [cell(onr, lims(1, 1) - obj_dims.lc), rawarr]; lims(1, 1) = obj_dims.lc; endif if (obj_dims.rc > lims(1, 2)) ## New data to right of current data; append columns rawarr = [rawarr, cell(onr, obj_dims.rc - lims(1, 2))]; lims(1, 2) = obj_dims.rc; endif ## Update number of columns onc = size (rawarr, 2); ## Copy new data into place objtr = obj_dims.tr - lims(2, 1) + 1; objbr = obj_dims.br - lims(2, 1) + 1; objlc = obj_dims.lc - lims(1, 1) + 1; objrc = obj_dims.rc - lims(1, 1) + 1; rawarr(objtr:objbr, objlc:objrc) = obj; else ## New sheet lims = [obj_dims.lc, obj_dims.rc; obj_dims.tr, obj_dims.br]; onc = obj_dims.nc; onr = obj_dims.nr; rawarr = obj; endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OTK_spsh_close__.m0000644000000000000000000000013213226215407020153 xustar0030 mtime=1515789063.584155165 30 atime=1515789063.584155165 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OTK_spsh_close__.m0000644000175000017500000000237213226215407020417 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## __OTK_spsh_close__ - internal function: close a spreadsheet file using OTK ## Author: Philip Nienhuis ## Created: 2012-10-12 function [ ods ] = __OTK_spsh_close__ (ods, force) try if (ods.changed && ods.changed < 3) if (isfield (ods, "nfilename")) ods.app.save (ods.nfilename); else ods.app.save (ods.filename); endif endif ods.changed = 0; ods.app.close (); catch if (force) ods.app.close (); endif end_try_catch endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OCT_getusedrange__.m0000644000000000000000000000013213226215407020456 xustar0030 mtime=1515789063.572154929 30 atime=1515789063.572154929 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OCT_getusedrange__.m0000644000175000017500000001332413226215407020721 0ustar00olafolaf00000000000000## Copyright (C) 2013-2017 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 Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} __OCT_getusedrange__ (@var{x} @var{y}) ## Get leftmost & rightmost occupied column numbers, and topmost and ## lowermost occupied row numbers (base 1). ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2013-09-08 function [ trow, brow, lcol, rcol ] = __OCT_getusedrange__ (spptr, ii) ## Check input nsheets = numel (spptr.sheets.sh_names); if (ii > nsheets) error ("getusedrange: sheet index (%d) out of range (1 - %d)", ii, nsheets); endif if (strcmpi (spptr.filename(end-3:end), ".ods")) [ trow, brow, lcol, rcol ] = __OCT_ods_getusedrange__ (spptr, ii); elseif (strcmpi (spptr.filename(end-4:end-1), ".xls")) [ trow, brow, lcol, rcol ] = __OCT_xlsx_getusedrange__ (spptr, ii); elseif (strcmpi (spptr.filename(end-8:end), ".gnumeric")) [ trow, brow, lcol, rcol ] = __OCT_gnm_getusedrange__ (spptr, ii); endif endfunction ##=============================OOXML======================== function [ trow, brow, lcol, rcol ] = __OCT_xlsx_getusedrange__ (spptr, ii); ## Approximation only! OOXML also counts empty cells (with only formatting) trow = brow = lcol = rcol = 0; ## Read first part of raw worksheet fid = fopen (sprintf ('%s/xl/worksheets/sheet%d.xml', spptr.workbook, ii)); if (fid > 0) xml = fread (fid, 512, "char=>char").'; ## Occupied range is in first 512 bytes fclose (fid); else ## We know the number must be good => apparently tmpdir is damaged or it has gone error ("getusedrange: sheet number nonexistent or corrupted file pointer struct"); endif node = getxmlnode (xml, "dimension"); crange = getxmlattv (node, "ref"); if (strcmpi (crange, "A1")) ## Looks like it has been written by POI OOXML or UNO. We need a better guess ## 1. Re-read entire worksheet fid = fopen (sprintf ('%s/xl/worksheets/sheet%d.xml', spptr.workbook, ii)); xml = fread (fid, Inf, "char=>char").'; fclose (fid); ## 2. Scan for cell addresses addr = cell2mat (regexp (xml, 'char").'; fclose (fid); endif ## Check if sheet contains any cell content at all ## FIXME: in far-fetched cases, cell string content may contain ' office:value' too if (isempty (strfind (sheet, " office:value"))) return endif [trow, brow, lcol, rcol ] = __ods_get_sheet_dims__ (sheet); endfunction ##===========================Gnumeric======================= function [ trow, brow, lcol, rcol ] = __OCT_gnm_getusedrange__ (spptr, ii); trow = brow = lcol = rcol = nrows = ncols = 0; if (isfield (spptr, "xml")) xml = spptr.xml; else ## Get requested sheet from info in ods struct pointer. Open file fid = fopen (spptr.workbook, 'r'); ## Go to start of requested sheet (real start, incl. xml id line) fseek (fid, spptr.sheets.shtidx(ii), 'bof'); ## Compute size of requested chunk nchars = spptr.sheets.shtidx(ii+1) - spptr.sheets.shtidx(ii); ## Get the sheet xml = fread (fid, nchars, "char=>char").'; fclose (fid); endif if (isempty (getxmlnode (xml, "gnm:Cell"))) ## No cell in sheet. We're done return endif ## Start processing cells. Although max row & column (0-based) are given in ## dedicated nodes in the xml, these don't seem exact, and no topleft limit ## is given anyway. cells = getxmlnode (xml, "gnm:Cells"); ## Min and max columns cols = regexp (cells, 'Col="\d*"', "match"); cols = regexprep (cols, 'Col="', ''); cols = regexprep (cols, '"', ''); cols = str2double (cols); lcol = min (cols) + 1; rcol = max (cols) + 1; ## Min and max rows rows = regexp (cells, 'Row="\d*"', "match"); rows = regexprep (rows, 'Row="', ''); rows = regexprep (rows, '"', ''); rows = str2double (rows); trow = min (rows) + 1; brow = max (rows) + 1; endfunction io-2.4.10/inst/private/PaxHeaders.5973/__chk_java_sprt__.m0000644000000000000000000000013213226215407020112 xustar0030 mtime=1515789063.596155401 30 atime=1515789063.596155401 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__chk_java_sprt__.m0000644000175000017500000000441413226215407020355 0ustar00olafolaf00000000000000## Copyright (C) 2013-2017 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 Octave; see the file COPYING. If not, see ## . ## __chk_java_sprt__ Internal io package function ## Author: Philip Nienhuis ## Created: 2013-03-01 function [ tmp1, jcp ] = __chk_java_sprt__ (dbug=0) jcp = {}; tmp1 = 0; has_java = __have_feature__ ("JAVA"); if (! has_java) ## No Java support built in => any further checks are moot return endif try jcp = javaclasspath ("-all"); # For java pkg >= 1.2.8 if (isempty (jcp)) # & Octave >= 3.7.2 jcp = javaclasspath; # For java pkg < 1.2.8 endif ## If we get here, at least Java works. if (dbug > 1) printf (" Java seems to work OK.\n"); endif ## Now check for proper version (>= 1.6) jver = ... char (javaMethod ("getProperty", "java.lang.System", "java.version")); cjver = strsplit (jver, "."); if (sscanf (cjver{2}, "%d") < 6) warning ... ("\nJava version too old - you need at least Java 6 (v. 1.6.x.x)\n"); if (dbug) printf (' At Octave prompt, try "!system ("java -version")"'); endif return else if (dbug > 2) printf (" Java (version %s) seems OK.\n", jver); endif endif ## Now check for proper entries in class path. Under *nix the classpath ## must first be split up. In java 1.2.8+ javaclasspath is already a cell array if (isunix && ! iscell (jcp)); jcp = strsplit (char (jcp), pathsep ()); endif tmp1 = 1; catch ## No Java support if (dbug) printf ("No Java support found.\n"); endif end_try_catch endfunction io-2.4.10/inst/private/PaxHeaders.5973/__UNO_oct2spsh__.m0000644000000000000000000000013213226215407017562 xustar0030 mtime=1515789063.592155322 30 atime=1515789063.592155322 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__UNO_oct2spsh__.m0000644000175000017500000001345313226215407020030 0ustar00olafolaf00000000000000## Copyright (C) 2011-2017 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 . ## oct2uno2xls - Internal function: write to spreadsheet file using UNO-Java bridge ## Author: Philip Nienhuis ## Created: 2011-05-18 function [ xls, rstatus ] = __UNO_oct2spsh__ (c_arr, xls, wsh, crange, spsh_opts) changed = 0; newsh = 0; ctype = [1, 2, 3, 4, 5]; ## Float, Logical, String, Formula, Empty ## Get handle to sheet, create a new one if needed sheets = xls.workbook.getSheets (); sh_names = sheets.getElementNames (); if (! iscell (sh_names)) ## Java array (LibreOffice 3.4.+); convert to cellstr sh_names = char (sh_names); else sh_names = {sh_names}; endif ## Clear default 2 last sheets in case of a new spreadsheet file if (xls.changed > 2) ii = numel (sh_names); while (ii > 1) shnm = sh_names{ii}; try ## Catch harmless Java RuntimeException "out of range" in LibreOffice 3.5rc1 sheets.removeByName (shnm); end_try_catch --ii; endwhile ## Give remaining sheet a name unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.sheet.XSpreadsheet"); sh = sheets.getByName (sh_names{1}).getObject.queryInterface (unotmp); if (isnumeric (wsh)); wsh = sprintf ("Sheet%d", wsh); endif unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.container.XNamed"); sh.queryInterface (unotmp).setName (wsh); else ## Check sheet pointer ## FIXME sheet capacity check needed if (isnumeric (wsh)) if (wsh < 1) error ("Illegal sheet index: %d", wsh); elseif (wsh > numel (sh_names)) ## New sheet to be added. First create sheet name but check if it already exists shname = sprintf ("Sheet%d", numel (sh_names) + 1); jj = find (strcmp (shname, sh_names)); if (! isempty (jj)) ## New sheet name already in file, try to create a unique & reasonable one ii = 1; filler = ""; maxtry = 5; while (ii <= maxtry) shname = sprintf ("Sheet%s%d", [filler "_"], numel (sh_names + 1)); if (isempty (find (strcmp (sh_names, shname)))) ii = 10; else ++ii; endif endwhile if (ii > maxtry + 1) error ("Could not add sheet with a unique name to file %s"); endif endif wsh = shname; newsh = 1; else ## turn wsh index into the associated sheet name wsh = sh_names {wsh}; endif else ## wsh is a sheet name. See if it exists already if (isempty (find (strcmp (wsh, sh_names)))) ## Not found. New sheet to be added newsh = 1; endif endif if (newsh) ## Add a new sheet. Sheet index MUST be a Java Short object shptr = javaObject ("java.lang.Short", sprintf ("%d", numel (sh_names) + 1)); sh = sheets.insertNewByName (wsh, shptr); endif ## At this point we have a valid sheet name. Use it to get a sheet handle unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.sheet.XSpreadsheet"); sh = sheets.getByName (wsh).getObject.queryInterface (unotmp); endif ## Check size of data array & range / capacity of worksheet & prepare vars [nr, nc] = size (c_arr); [topleft, nrows, ncols, trow, lcol] = ... spsh_chkrange (crange, nr, nc, xls.xtype, xls.filename); --trow; --lcol; ## Zero-based row ## & col ## if (nrows < nr || ncols < nc) warning ("Array truncated to fit in range\n"); c_arr = c_arr(1:nrows, 1:ncols); endif ## Parse data array, setup typarr and throw out NaNs to speed up writing; typearr = spsh_prstype (c_arr, nrows, ncols, ctype, spsh_opts, 0); if ~(spsh_opts.formulas_as_text) ## Find formulas (designated by a string starting with "=" and ending in ")") fptr = cellfun (@(x) ischar (x) && strncmp (x, "=", 1), c_arr); typearr(fptr) = ctype(4); ## FORMULA endif ## Transfer data to sheet for ii=1:nrows for jj=1:ncols try XCell = sh.getCellByPosition (lcol+jj-1, trow+ii-1); switch typearr(ii, jj) case 1 ## Float XCell.setValue (c_arr{ii, jj}); case 2 ## Logical. Convert to float as OOo has no Boolean type XCell.setValue (double (c_arr{ii, jj})); case 3 ## String unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.text.XText"); XCell.queryInterface (unotmp).setString (c_arr{ii, jj}); case 4 ## Formula if (spsh_opts.formulas_as_text) unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.text.XText"); XCell.queryInterface (unotmp).setString (c_arr{ii, jj}); else XCell.setFormula (c_arr{ii, jj}); endif otherwise ## Empty cell endswitch changed = 1; catch printf ("Error writing cell %s (typearr() = %d)\n",... calccelladdress(trow+ii, lcol+jj), typearr(ii, jj)); end_try_catch endfor endfor if (changed) ## Preserve 2 (new file), 1 (existing) xls.changed = max (min (xls.changed, 2), changed); rstatus = 1; endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OTK_ods2oct__.m0000644000000000000000000000013213226215407017366 xustar0030 mtime=1515789063.584155165 30 atime=1515789063.584155165 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OTK_ods2oct__.m0000644000175000017500000002006313226215407017627 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## __OTK_ods2oct__ - read ODS spreadsheet data using Java & odftoolkit 0.7.5 ## You need proper java-for-octave & odfdom.jar + xercesImpl.jar 2.9.1 ## in your javaclasspath. ## Author: Philip Nenhuis ## Created: 2009-12-24 function [ rawarr, ods, rstatus ] = __OTK_ods2oct__ (ods, wsh, crange, spsh_opts) ## Parts after user gfterry in ## http://www.oooforum.org/forum/viewtopic.phtml?t=69060 rstatus = 0; ## Get contents and table stuff from the workbook odfcont = ods.workbook; ## Use a local copy just to be sure. octave ## makes physical copies only when needed (?) xpath = ods.app.getXPath; ## ODS spreadsheets have the following hierarchy (after Xpath processing): ## - table nodes, the actual worksheets; ## - row nodes, the rows in a worksheet; ## - cell nodes, the cells in a row; ## Styles (formatting) are defined in a section "settings" outside the ## contents proper but are referenced in the nodes. ## Create an instance of type NODESET for use in subsequent statement NODESET = java_get ("javax.xml.xpath.XPathConstants", "NODESET"); ## Parse sheets ("tables") from ODS file sheets = xpath.evaluate ("//table:table", odfcont, NODESET); nr_of_sheets = sheets.getLength (); ## Check user input & find sheet pointer (1-based), using ugly hacks if (! isnumeric (wsh)) ## Search in sheet names, match sheet name to sheet number ii = 0; while (++ii <= nr_of_sheets && ischar (wsh)) ## Look in first part of the sheet nodeset sh_name = sheets.item(ii-1).getTableNameAttribute (); if (strcmp (sh_name, wsh)) ## Convert local copy of wsh into a number (pointer) wsh = ii; endif endwhile if (ischar (wsh)) error (sprintf ("xls/ods2oct: no worksheet '%s' found in file %s\n", ... wsh, ods.filename)); endif elseif (wsh > nr_of_sheets || wsh < 1) ## We already have a numeric sheet pointer. If it's not in range: error (sprintf ("xls/ods2oct: worksheet no. %d out of range (1 - %d)\n", ... wsh, nr_of_sheets)); endif ## Get table-rows in sheet no. wsh. Sheet count = 1-based (!) str = sprintf ("//table:table[%d]/table:table-row", wsh); sh = xpath.evaluate (str, odfcont, NODESET); nr_of_rows = sh.getLength (); ## Either parse (given cell range) or prepare (unknown range) help variables if (isempty (crange)) [ trow, brow, lcol, rcol ] = getusedrange (ods, wsh); nrows = brow - trow + 1; ## Number of rows to be read ncols = rcol - lcol + 1; ## Number of columns to be read else [dummy, nrows, ncols, trow, lcol] = parse_sp_range (crange); brow = min (trow + nrows - 1, nr_of_rows); ## Check ODS column limits if (lcol > 1024 || trow > 65536) error ("xls/ods2oct: invalid range; max 1024 columns & 65536 rows\n"); endif ## Truncate range silently if needed rcol = min (lcol + ncols - 1, 1024); ncols = min (ncols, 1024 - lcol + 1); nrows = min (nrows, 65536 - trow + 1); endif ## Create storage for data content rawarr = cell (nrows, ncols); ## Prepare reading sheet row by row rightmcol = 0; ## Used to find actual rightmost column ii = trow - 1; ## Spreadsheet row counter rowcnt = 0; ## Find uppermost requested *tablerow*. It may be influenced by nr-rows-repeated if (ii >= 1) tfillrows = 0; while (tfillrows < ii) row = sh.item(tfillrows); extrarows = row.getTableNumberRowsRepeatedAttribute (); tfillrows = tfillrows + extrarows; ++rowcnt; endwhile ## Desired top row may be in a nr-rows-repeated tablerow.... if (tfillrows > ii) ii = tfillrows; endif endif ## Read from worksheet row by row. Row numbers are 0-based while (ii < brow) row = sh.item(rowcnt++); nr_of_cells = min (row.getLength (), rcol); rightmcol = max (rightmcol, nr_of_cells); ## Keep track of max row length ## Read column (cell, "table-cell" in ODS speak) by column jj = lcol; while (jj <= rcol) tcell = row.getCellAt(jj-1); form = 0; if (! isempty (tcell)) ## If empty it's possibly in columns-repeated/spanned if (spsh_opts.formulas_as_text) ## Get spreadsheet formula rather than value ## Check for formula attribute tmp = tcell.getTableFormulaAttribute (); if isempty (tmp) form = 0; else if (strcmp (tolower (tmp(1:3)), "of:")) tmp (1:end-3) = tmp(4:end); endif rawarr(ii-trow+2, jj-lcol+1) = tmp; form = 1; endif endif if (! (form || index (char(tcell), "text:p>Err:") ... || index (char(tcell), "text:p>##DIV"))) ## Get data from cell ctype = tcell.getOfficeValueTypeAttribute (); cvalue = tcell.getOfficeValueAttribute (); switch deblank (ctype) case {"float", "currency", "percentage"} rawarr(ii-trow+2, jj-lcol+1) = cvalue; case "date" cvalue = tcell.getOfficeDateValueAttribute (); ## Dates are returned as octave datenums, i.e. 0-0-0000 based yr = str2double (cvalue(1:4)); mo = str2double (cvalue(6:7)); dy = str2double (cvalue(9:10)); if (index (cvalue, "T")) hh = str2double (cvalue(12:13)); mm = str2double (cvalue(15:16)); ss = str2double (cvalue(18:19)); rawarr(ii-trow+2, jj-lcol+1) = datenum (yr, mo, dy, hh, mm, ss); else rawarr(ii-trow+2, jj-lcol+1) = datenum (yr, mo, dy); endif case "time" cvalue = tcell.getOfficeTimeValueAttribute (); if (index (cvalue, "PT")) hh = str2double (cvalue(3:4)); mm = str2double (cvalue(6:7)); ss = str2double (cvalue(9:10)); rawarr(ii-trow+2, jj-lcol+1) = datenum (0, 0, 0, hh, mm, ss); endif case "boolean" cvalue = tcell.getOfficeBooleanValueAttribute (); rawarr(ii-trow+2, jj-lcol+1) = cvalue; case "string" cvalue = tcell.getOfficeStringValueAttribute (); if (isempty (cvalue)) ## Happens with e.g., hyperlinks tmp = char (tcell); ## Hack string value from between tags ist = findstr (tmp, " 0 && (ii + extrarows) < 65535) ## Expand rawarr cf. table-row nr_of_rows = nr_of_rows + extrarows; ii = ii + extrarows; endif ++ii; endwhile ## Keep track of data rectangle limits ods.limits = [lcol, rcol; trow, brow]; rstatus = 1; endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OCT_oct2spsh__.m0000644000000000000000000000013213226215407017546 xustar0030 mtime=1515789063.576155008 30 atime=1515789063.576155008 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OCT_oct2spsh__.m0000644000175000017500000000452713226215407020016 0ustar00olafolaf00000000000000## Copyright (C) 2014-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} __OCT_oct2spsh__ (@var{input1}, @var{input2}) ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2014-01-24 function [ ods, rstatus ] = __OCT_oct2spsh__ (obj, ods, wsh, crange, spsh_opts) ## Analyze data and requested range. Get size of data to write [nnr, nnc ] = size (obj); if (isempty (crange)) ## Infer range from data size nr = nnr; nc = nnc; ## Top left corner of range = cell A1 tr = lc = 1; else ## Parse requested cell range [~, nr, nc, tr, lc] = parse_sp_range (crange); endif ## First check row size if (nnr > nr) ## Truncate obj obj = obj(1:nr, :); elseif (nnr < nr) ## Truncate requested range nr = nnr; endif ## Next, column size if (nnc > nc) ## Truncate obj obj = obj(:, 1:nc); elseif (nnc < nc) ## Truncate requested range nc = nnc; endif obj_dims.tr = tr; obj_dims.br = tr + nr - 1; obj_dims.nr = nr; obj_dims.lc = lc; obj_dims.rc = lc + nc - 1; obj_dims.nc = nc; ## Invoke file type-dependent functions if (strcmpi (ods.app, "ods")) ## Write to .ods [ ods, rstatus ] = __OCT_oct2ods__ (obj, ods, wsh, crange, spsh_opts, obj_dims); elseif (strcmpi (ods.app, "xlsx")) ## Write to .xlsx [ ods, rstatus ] = __OCT_oct2xlsx__ (obj, ods, wsh, crange, spsh_opts, obj_dims); elseif (strcmpi (ods.app, "gnumeric")) ## Write to .gnumeric [ ods, rstatus ] = __OCT_oct2gnm__ (obj, ods, wsh, crange, spsh_opts, obj_dims); else error ("writing to file type %s not supported by OCT", xls.app); endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OTK_spsh_open__.m0000644000000000000000000000013213226215407020007 xustar0030 mtime=1515789063.584155165 30 atime=1515789063.584155165 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OTK_spsh_open__.m0000644000175000017500000000414313226215407020251 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## __OTK_SPSH_open ## Author: Philip Nienhuis ## Created: 2012-10-12 function [ ods, odssupport, lastintf ] = __OTK_spsh_open__ (ods, rw, filename, odssupport) ## Parts after user gfterry in ## http://www.oooforum.org/forum/viewtopic.phtml?t=69060 ## Get odfdom version persistent odfvsn; odfvsn = []; if (isempty (odfvsn)) try odfvsn = " "; ## New in 0.8.6 odfvsn = ... javaMethod ("getOdfdomVersion", "org.odftoolkit.odfdom.JarManifest"); catch odfvsn = ... javaMethod ("getApplicationVersion", "org.odftoolkit.odfdom.Version"); end_try_catch ## For odfdom-incubator (= 0.8.8+), strip extra info odfvsn = regexp (odfvsn, '\d\.\d\.\d+', "match"){1}; endif odftk = "org.odftoolkit.odfdom.doc"; try if (rw > 2) ## New spreadsheet wb = javaMethod ("newSpreadsheetDocument", [odftk ".OdfSpreadsheetDocument"]); else ## Existing spreadsheet wb = javaMethod ("loadDocument", [odftk ".OdfDocument"], filename); endif ods.workbook = wb.getContentDom (); # Reads the entire spreadsheet ods.xtype = "OTK"; ods.app = wb; ods.filename = filename; ods.odfvsn = odfvsn; odssupport += 1; lastintf = "OTK"; catch error ("Couldn't open file %s using OTK", filename); end_try_catch endfunction io-2.4.10/inst/private/PaxHeaders.5973/__JOD_oct2spsh__.m0000644000000000000000000000013213226215407017535 xustar0030 mtime=1515789063.568154851 30 atime=1515789063.568154851 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__JOD_oct2spsh__.m0000644000175000017500000001331213226215407017775 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## __JOD_oct2spsh__ - write data from octave to an ODS spreadsheet using the ## jOpenDocument interface. ## ## Author: Philip Nienhuis ## Created: 2009-12-13 function [ ods, rstatus ] = __JOD_oct2spsh__ (c_arr, ods, wsh, crange) rstatus = 0; sh = []; changed = 0; ## Get worksheet. Use first one if none given if (isempty (wsh)) wsh = 1; endif sh_cnt = ods.workbook.getSheetCount (); if (isnumeric (wsh)) if (wsh > 1024) error ("Sheet number out of range of ODS specification (>1024)"); elseif (wsh > sh_cnt) error ("Sheet number (%d) larger than number of sheets in file (%d)\n",... wsh, sh_cnt); else wsh = wsh - 1; sh = ods.workbook.getSheet (wsh); ## Workaround for JOD bug that introduces "A" & "B" col headers if (ods.changed >= 2) sh.getCellAt (0, 0).clearValue (); sh.getCellAt (1, 0).clearValue (); endif if (isempty (sh)) ## Sheet number wsh didn't exist yet wsh = sprintf ("Sheet%d", wsh+1); elseif (ods.changed > 2) sh.setName ("Sheet1"); changed = 1; endif endif endif ## wsh is now either a 0-based sheet no. or a string. In latter case: if (isempty (sh) && ischar (wsh)) sh = ods.workbook.getSheet (wsh); if (isempty (sh)) ## Still doesn't exist. Create sheet if (ods.odfvsn >= 3) if (ods.changed > 2) ## 1st "new" -unnamed- sheet has already been made when creating the spreadsheet sh = ods.workbook.getSheet (0); sh.setName (wsh); changed = 1; ## Workaround for JOD bug that introduces "A" & "B" col headers if (ods.changed >= 2) sh.getCellAt (0, 0).clearValue (); sh.getCellAt (1, 0).clearValue (); endif else ## For existing spreadsheets ## printf ("Adding sheet '%s'\n", wsh); sh = ods.workbook.addSheet (sh_cnt, wsh); changed = 1; endif ## jOpenDocument bug: JOD seems to add "A" to A1 and "B" to B1 try if (! isempty (sh.getCellAt (0, 0).getValue)) sh.getCellAt (0, 0).clearValue(); sh.getCellAt (1, 0).clearValue(); endif catch end_try_catch else error (["jOpenDocument v. 1.2b2 does not support adding sheets" ... " - upgrade to v. 1.4\n"]); endif endif endif [nr, nc] = size (c_arr); if (isempty (crange)) trow = 0; lcol = 0; nrows = nr; ncols = nc; elseif (isempty (strfind (deblank (crange), ":"))) [~, ~, ~, trow, lcol] = parse_sp_range (crange); nrows = nr; ncols = nc; ## Row/col = 0 based in jOpenDocument trow = trow - 1; lcol = lcol - 1; else [~, nrows, ncols, trow, lcol] = parse_sp_range (crange); ## Row/col = 0 based in jOpenDocument trow = trow - 1; lcol = lcol - 1; endif if (trow > 65535 || lcol > 1023) error ("Topleft cell beyond spreadsheet limits (AMJ65536)."); endif ## Check spreadsheet capacity beyond requested topleft cell nrows = min (nrows, 65536 - trow); ## Remember, lcol & trow are zero-based ncols = min (ncols, 1024 - lcol); ## Check array size and requested range nrows = min (nrows, nr); ncols = min (ncols, nc); if (nrows < nr || ncols < nc) warning ("Array truncated to fit in range\n"); endif if (isnumeric (c_arr)) c_arr = num2cell (c_arr); endif ## Ensure sheet capacity is large enough to contain new data try ## try-catch needed to work around bug in jOpenDocument v 1.2b3 and earlier sh.ensureColumnCount (lcol + ncols); ## Remember, lcol & trow are zero-based catch ## catch is needed for new empty sheets (first ensureColCnt() hits null ptr) sh.ensureColumnCount (lcol + ncols); ## Kludge needed because upper row is defective (NPE jOpenDocument bug). ?Fixed in 1.2b4? if (trow == 0) ## Shift rows one down to avoid defective upper row ++trow; printf ("Info: empy upper row above data added to avoid JOD bug.\n"); endif end_try_catch sh.ensureRowCount (trow + nrows); ## Write data to worksheet. JOD's left cell index = column not row for ii = 1 : nrows for jj = 1 : ncols val = c_arr {ii, jj}; if ((isnumeric (val) && ! isnan (val)) || ischar (val) || islogical (val)) ## jOpenDocument < 1.3 doesn't really support writing booleans (doesn't set OffValAttr) if ((ods.odfvsn <= 3) && islogical (val)) val = double (val); endif try sh.getCellAt (jj + lcol - 1, ii + trow - 1).clearValue(); jcell = sh.getCellAt (jj + lcol - 1, ii + trow - 1).setValue (val); changed = 1; catch ## No panic, probably a merged cell ## printf (sprintf ("Cell skipped at (%d, %d)\n", ii+lcol-1, jj+trow-1)); end_try_catch endif endfor endfor if (changed) ods.changed = max (min (ods.changed, 2), changed); # Preserve 2 (new file), 1 (existing) rstatus = 1; endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__POI_chk_sprt__.m0000644000000000000000000000013213226215407017620 xustar0030 mtime=1515789063.588155243 30 atime=1515789063.588155243 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__POI_chk_sprt__.m0000644000175000017500000000613213226215407020062 0ustar00olafolaf00000000000000## Copyright (C) 2014-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{vargout} =} __POI_chk_sprt__ (@var{varargin}) ## Undocumented internal function ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2014-10-31 function [chk, missing1, missing2] = __POI_chk_sprt__ (jcp, dbug=0) chk = 0; ## First Check basic .xls (BIFF8) support if (dbug > 1) printf ("\nBasic POI (.xls) :\n"); endif ## Below entries1 order = vital entries1 = {{"apache-poi.", "poi-3"}, {"apache-poi-ooxml.", "poi-ooxml-3"}}; ## Only under *nix we might use brute force: e.g., strfind (javaclasspath, classname) ## as javaclasspath is one long string. Under Windows however classpath is a cell array ## so we need the following more subtle, platform-independent approach: [jpchk1, missing1] = chk_jar_entries (jcp, entries1, dbug); missing1 = entries1 (find (missing1)); if (jpchk1 >= numel (entries1)) chk = 1; if (dbug > 1) printf (" => Apache (POI) OK\n"); endif elseif (dbug > 1); printf (" => Not all classes (.jar) required for POI in classpath\n"); endif ## Next, check OOXML support if (dbug > 1) printf ("\nPOI OOXML (.xlsx) :\n"); endif entries2 = {{"xbean", "xmlbean"}, {"apache-poi-ooxml-schemas", ... "poi-ooxml-schemas"}, "dom4j", "commons-collections4"}; [jpchk2, missing2] = chk_jar_entries (jcp, entries2, dbug); missing2 = entries2 (find (missing2)); ## Check if common-collections4 is req'd (only for POI >= 3.15) try ## ...cause POI may not yet be in the javaclasspath ... poiv = javaObject ("org.apache.poi.Version").getVersion(); if (compare_versions (poiv, "3.14", "<=") && strncmpi (missing2, "commons-collections4", 8)) ## Remove commons-collections from missing2 ic = find (cellfun (@ischar, missing2)); id = strmatch ("commons-collections4", missing2(ic)); missing2(ic(id)) = []; jpchk2++; if (dbug > 2) printf (" commons-collections4 not needed for POI <= 3.14\n"); endif endif end_try_catch if (jpchk2 >= numel (entries2)) ## Only bump chk if basic classes were all found if (chk) ++chk; endif if (dbug > 1) printf (" => POI OOXML OK\n"); endif elseif (dbug > 1) printf (" => Some classes for POI OOXML support missing\n"); endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__JOD_spsh_info__.m0000644000000000000000000000013213226215407017760 xustar0030 mtime=1515789063.568154851 30 atime=1515789063.568154851 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__JOD_spsh_info__.m0000644000175000017500000000240713226215407020223 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## __JOD_spsh_info__ ## Author: Philip Nienhuis ## Created: 2012-10-12 function [sh_names] = __JOD_spsh_info__ (ods) nr_of_sheets = ods.workbook.getSheetCount (); sh_names = cell (nr_of_sheets, 2); for ii=1:nr_of_sheets sh_names(ii) = ods.workbook.getSheet (ii-1).getName (); [ tr, lr, lc, rc ] = getusedrange (ods, ii); if (tr) sh_names(ii, 2) = sprintf ("%s:%s", calccelladdress (tr, lc),... calccelladdress (lr, rc)); else sh_names(ii, 2) = "Empty"; endif endfor endfunction io-2.4.10/inst/private/PaxHeaders.5973/__get_ftype__.m0000644000000000000000000000013213226215407017262 xustar0030 mtime=1515789063.596155401 30 atime=1515789063.596155401 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__get_ftype__.m0000644000175000017500000000652013226215407017525 0ustar00olafolaf00000000000000## Copyright (C) 2014-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{ftype} =} __get_ftype__ (@var{fname}) ## Get file type index from a file name, based on the file extension. ## ## Supported file type indices: ## 1 = .xls (BIFF8, also BIFF5) ## 2 = .xlsx (OOXML) ## 3 = .ods (ODS 1.2) ## 4 = .sxc (old OpenOffice.org format) ## 5 = .gnumeric (Gnumeric XML) ## 6 = .csv (Comma Separated Values) ## 7 = .uof (Unified Office Format) ## 8 = .fods (ODS Flat XML) ## 9 = .dbf (Dbase) ## 10 = .dif (Digital InterchangeFormat) ## ## @var{ftype} is set to 0 (zero) for any other file type. ## @var{ftype} is set to empty for file names without extension. ## In those cases filtnam is set to empty ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2014-01-01 function [ftype, filtnam] = __get_ftype__ (fname) persistent filtnams; filtnams = {"MS Excel 97", ## .xls "Calc MS Excel 2007 XML", ## .xlsx "calc8", ## .ods "StarOffice XML (Calc)", ## .sxc "---gnumeric---", ## .gnumeric "Text CSV", ## .csv "UOF spreadsheet", ## .uos "OpenDocument Spreadsheet Flat XML", ## .fods "dBase", ## .dbf "DIF"}; ## .dif [~, ~, ext] = fileparts (fname); if (! isempty (ext)) switch ext case ".xls" ## Regular (binary) BIFF ftype = 1; case {".xlsx", ".xlsm", ".xlsb"} ## Zipped XML / OOXML. Catches xlsx, xlsb, xlsm ftype = 2; case ".ods" ## ODS 1.2 (Excel 2007+ & OOo/LO can read ODS) ftype = 3; case ".sxc" ## old OpenOffice.org 1.0 Calc ftype = 4; case ".gnumeric" ## Zipped XML / gnumeric ftype = 5; case ".csv" ## csv. Detected for xlsread afficionados ftype = 6; case ".uof" ## Unified Office Format ftype = 7; case ".fods" ## ODS Flat HTML ftype = 8; case ".dbf" ## Dbase ftype = 9; case ".dif" ## Digital Interchange Format ftype = 10; otherwise ## Any other type = non-supported ftype = 0; endswitch else ftype = ''; endif if (ftype > 0) filtnam = filtnams{ftype}; else filtnam = ''; endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/chknmrange.m0000644000000000000000000000013213226215407016615 xustar0030 mtime=1515789063.596155401 30 atime=1515789063.596155401 30 ctime=1515789065.028183488 io-2.4.10/inst/private/chknmrange.m0000644000175000017500000000555013226215407017062 0ustar00olafolaf00000000000000## Copyright (C) 2015-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [ @var{range}, @var{wsh}, @var{xls}] = chkrange (@var{xls}, @var{range}, @var{wsh}) ## Internal function. Checks if range is Named range & act accordingly ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhu01 ## Created: 2015-09-29 function [datrange, wsh, xls] = chknmrange (xls, datrange, wsh) mtch = cell2mat (regexp (datrange, ... '(^[A-Za-z]+[0-9]+){1}(:[A-Za-z]+[0-9]+$)?', "tokens")); if (isempty (mtch) || ! strcmp ([mtch{:}], datrange)) ## Apparently not a range. Try range names if (! isfield (xls, "nmranges")) xls.nmranges = getnmranges (xls); endif idx = strmatch (datrange, xls.nmranges(:, 1)); if (isempty (idx)) error ("no range '%s' in workbook '%s'\n", datrange, xls.filename); else if (numel (idx) > 1) ## Multiple sheets with same Named range if (isnumeric (wsh)) ## No way to assess worksheet name here. Just take the first match idx = idx(1); printf ("multiple Range name matches for '%s', but no sheet *name* specified\n", ... datrange); warning ("Data read from first match = sheet '%s'\n", xls.nmranges{idx, 2}); elseif (ischar (wsh)) jdx = strmatch (wsh, xls.nmranges(idx, 2)); if (isempty (jdx)) ## No match with specified wsh => just pick the first idx = idx(1); warning ("Named Range '%s' not defined in sheet '%s'\n Sheet '%s' taken\n", ... datrange, wsh, xls.nmranges{idx, 2}); else ## In case of multiple matches, just pick the first idx = idx(jdx(1)); endif else error ("Illegal sheet name or index specified\n"); endif endif ## Get range and -optionally- sheet it refers to datrange = xls.nmranges{idx, 3}; if (! isempty (xls.nmranges{idx, 2})) wsh = xls.nmranges{idx, 2}; endif endif endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/getusedrange.m0000644000000000000000000000013213226215407017155 xustar0030 mtime=1515789063.596155401 30 atime=1515789063.596155401 30 ctime=1515789065.028183488 io-2.4.10/inst/private/getusedrange.m0000644000175000017500000000712413226215407017421 0ustar00olafolaf00000000000000## Copyright (C) 2010-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [ @var{toprow#}, @var{bottomrow#}, @var{leftcol#}, @var{rightcol#} ] = getusedrange (@var{spptr}, @var{shindex#}) ## Find occupied data range in worksheet @var{shindex#} in a spreadsheet ## pointed to in struct @var{spptr} (either MS-Excel or ## OpenOffice_org Calc). ## ## @var{shindex#} must be numeric and is 1-based. @var{spptr} can either ## refer to an MS-Excel spreadsheet (spptr returned by xlsopen) or an ## OpenOffice.org Calc spreadsheet (spptr returned by odsopen). ## None of these inputs are checked! ## ## Be aware that especially for OpenOffice.org Calc (ODS) spreadsheets ## the results can only be obtained by counting all cells in all rows; ## this can be fairly time-consuming. Reliable ods data size results can ## only be obtained using UNO interface. ## For the ActiveX (COM) interface the underlying Visual Basic call relies ## on cached range values and counts empty cells with only formatting too, ## so COM returns only approximate (but then usually too big) range values. ## ## Examples: ## ## @example ## [trow, brow, lcol, rcol] = getusedrange (ods2, 3); ## (which returns the outermost row & column numbers of the rectangle ## enveloping the occupied cells in the third sheet of an OpenOffice_org ## Calc spreadsheet pointedto in struct ods2) ## @end example ## ## @example ## [trow, brow, lcol, rcol] = getusedrange (xls3, 3); ## (which returns the outermost row & column numbers of the rectangle ## enveloping the occupied cells in the third sheet of an Excel ## spreadsheet pointed to in struct xls3) ## @end example ## ## @seealso {xlsopen, xlsclose, odsopen, odsclose, xlsfinfo, odsfinfo} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2010-03-18 (First usable version) for ODS (java/OTK) function [ trow, lrow, lcol, rcol ] = getusedrange (spptr, ii) ## Some checks if ~isstruct (spptr), error ("Illegal spreadsheet pointer argument"); endif if (strcmp (spptr.xtype, 'OTK')) [ trow, lrow, lcol, rcol ] = __OTK_getusedrange__ (spptr, ii); elseif (strcmp (spptr.xtype, "JOD")) [ trow, lrow, lcol, rcol ] = __JOD_getusedrange__ (spptr, ii); elseif (strcmp (spptr.xtype, "UNO")) [ trow, lrow, lcol, rcol ] = __UNO_getusedrange__ (spptr, ii); elseif (strcmp (spptr.xtype, "COM")) [ trow, lrow, lcol, rcol ] = __COM_getusedrange__ (spptr, ii); elseif (strcmp (spptr.xtype, "POI")) [ trow, lrow, lcol, rcol ] = __POI_getusedrange__ (spptr, ii); elseif (strcmp (spptr.xtype, "JXL")) [ trow, lrow, lcol, rcol ] = __JXL_getusedrange__ (spptr, ii); elseif (strcmp (spptr.xtype, "OXS")) [ trow, lrow, lcol, rcol ] = __OXS_getusedrange__ (spptr, ii); elseif (strcmp (spptr.xtype, "OCT")) [ trow, lrow, lcol, rcol ] = __OCT_getusedrange__ (spptr, ii); else error ... ("Unknown interface - only OTK, JOD, COM, POI, JXL, OXS, UNO and OCT implemented"); endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/getxlsinterfaces.m0000644000000000000000000000013213226215407020052 xustar0030 mtime=1515789063.596155401 30 atime=1515789063.596155401 30 ctime=1515789065.028183488 io-2.4.10/inst/private/getxlsinterfaces.m0000644000175000017500000001734513226215407020324 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## @deftypefn {Function File} @var{xlsinterfaces} = getxlsinterfaces (@var{xlsinterfaces}) ## Get supported Excel .xls file read/write interfaces from the system. ## Each interface for which the corresponding field is set to empty ## will be checked. So by manipulating the fields of input argument ## @var{xlsinterfaces} it is possible to specify which ## interface(s) should be checked. ## ## Currently implemented interfaces comprise: ## - ActiveX / COM (native Excel in the background) ## - Java & Apache POI ## - Java & JExcelAPI ## - Java & OpenXLS (only JRE >= 1.4 needed) ## - Java & UNO bridge (native OpenOffice.org in background) - EXPERIMENTAL!! ## - native Octave, only for .xlsx (OOXML), .ODS1.2, . gnumeric ## ## Examples: ## ## @example ## xlsinterfaces = getxlsinterfaces (xlsinterfaces); ## @end example ## Author: Philip Nienhuis ## Created: 2009-11-29 function [xlsinterfaces] = getxlsinterfaces (xlsinterfaces) ## tmp1 = [] (not initialized), 0 (No Java detected), or 1 (Working Java found) persistent tmp1 = []; persistent tmp2 = []; persistent has_java = []; ## Built-in Java support persistent jcp; ## Java class path persistent uno_1st_time = 0; if (isempty (has_java)) has_java = __have_feature__ ("JAVA"); endif if (isempty (xlsinterfaces.COM) && isempty (xlsinterfaces.POI) ... && isempty (xlsinterfaces.JXL) && isempty (xlsinterfaces.OXS) ... && isempty (xlsinterfaces.UNO)) ## Looks like first call to xlsopen. Check Java support printf ("Detected XLS interfaces: "); tmp1 = []; elseif (isempty (xlsinterfaces.COM) || isempty (xlsinterfaces.POI) ... || isempty (xlsinterfaces.JXL) || isempty (xlsinterfaces.OXS) ... || isempty (xlsinterfaces.UNO)) ## Can't be first call. Here one of the Java interfaces may be requested if (! tmp1) ## Check Java support again tmp1 = []; elseif (has_java) ## Renew jcp (javaclasspath) as it may have been updated since last call jcp = javaclasspath ("-all"); ## For java pkg >= 1.2.8 if (isempty (jcp)) ## For java pkg < 1.2.8 jcp = javaclasspath; endif if (isunix && ! iscell (jcp)); jcp = strsplit (char (jcp), pathsep ()); endif endif endif ## deflt signals that some default interface has been selected. Just used ## for cosmetic purposes deflt = 0; ## Check if MS-Excel COM ActiveX server runs (only on Windows!) if (ispc && isempty (xlsinterfaces.COM)) xlsinterfaces.COM = 0; try app = actxserver ("Excel.application"); ## Close Excel. Yep this is inefficient when we need only one r/w action, ## but it quickly pays off when we need to do more with the same file ## (+, MS-Excel code is in OS cache anyway after this call so no big deal) app.Quit(); delete (app); printf ("COM"); if (deflt) printf ("; "); else printf ("*; "); deflt = 1; endif ## If we get here, the call succeeded & COM works. xlsinterfaces.COM = 1; catch ## COM non-existent. Only print message if COM is explicitly requested (tmp1==[]) if (! isempty (tmp1)) printf ("ActiveX not working; no Excel installed?\n"); endif end_try_catch endif if (has_java) if (isempty (tmp1)) ## Check Java support [tmp1, jcp] = __chk_java_sprt__ (); if (! tmp1) ## No Java support found tmp1 = 0; if (isempty (xlsinterfaces.POI) || isempty (xlsinterfaces.JXL)... || isempty (xlsinterfaces.OXS) || isempty (xlsinterfaces.UNO)) ## Some or all Java-based interface(s) explicitly requested but no Java support warning ... (" No Java support found (no Java JRE? no Java pkg installed AND loaded?)"); endif ## Set Java-based interfaces to 0 anyway as there's no Java support xlsinterfaces.POI = 0; xlsinterfaces.JXL = 0; xlsinterfaces.OXS = 0; xlsinterfaces.UNO = 0; printf ("\n"); ## No more need to try any Java interface return endif endif ## Try Java & Apache POI if (isempty (xlsinterfaces.POI)) xlsinterfaces.POI = 0; ## Check basic .xls (BIFF8) support [chk, ~, missing2] = __POI_chk_sprt__ (jcp); if (chk) xlsinterfaces.POI = 1; printf ("POI"); if (isempty (missing2)) printf (" (& OOXML)"); xlsinterfaces.POI = 2; endif if (deflt) printf ("; "); else printf ("*; "); deflt = 1; endif endif endif ## Try Java & JExcelAPI if (isempty (xlsinterfaces.JXL)) xlsinterfaces.JXL = 0; chk = __JXL_chk_sprt__ (jcp); if (chk) xlsinterfaces.JXL = 1; printf ("JXL"); if (deflt) printf ("; "); else printf ("*; "); deflt = 1; endif endif endif ## Try Java & OpenXLS if (isempty (xlsinterfaces.OXS)) xlsinterfaces.OXS = 0; chk = __OXS_chk_sprt__ (jcp); ## Beware of unsupported openxls jar versions (chk must be > 0) if (chk >= 1) xlsinterfaces.OXS = 1; printf ("OXS"); if (deflt) printf ("; "); else printf ("*; "); deflt = 1; endif endif endif ## Try Java & UNO if (isempty (xlsinterfaces.UNO)) xlsinterfaces.UNO = 0; chk = __UNO_chk_sprt__ (jcp); if (chk) xlsinterfaces.UNO = 1; printf ("UNO"); if (deflt); printf ("; "); else printf ("*; "); deflt = 1; uno_1st_time = min (++uno_1st_time, 2); endif endif endif else ## Set Java-based interfaces to 0 anyway as there's no Java support xlsinterfaces.POI = 0; xlsinterfaces.JXL = 0; xlsinterfaces.OXS = 0; xlsinterfaces.UNO = 0; ## End of has_java block endif ## Native Octave if (isempty (xlsinterfaces.OCT)) ## Nothing to check, always supported xlsinterfaces.OCT = 1; printf ("OCT"); if (deflt) printf ("; "); else printf ("*; "); deflt = 1; endif endif ## ---- Other interfaces here, similar to the ones above. ## Java interfaces should be in the has-java if-block if (deflt) printf ("(* = default interface)\n"); endif ## FIXME the below stanza should be dropped once UNO is stable. # Echo a suitable warning about experimental status: if (uno_1st_time == 1) ++uno_1st_time; printf ("\nPLEASE NOTE: UNO (=OpenOffice.org-behind-the-scenes) is EXPERIMENTAL\n"); printf ("After you've opened a spreadsheet file using the UNO interface,\n"); printf ("xlsclose on that file will kill ALL OpenOffice.org invocations,\n"); printf ("also those that were started outside and/or before Octave!\n"); printf ("Trying to quit Octave w/o invoking xlsclose will only hang Octave.\n\n"); endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__UNO_chk_sprt__.m0000644000000000000000000000013213226215407017632 xustar0030 mtime=1515789063.592155322 30 atime=1515789063.592155322 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__UNO_chk_sprt__.m0000644000175000017500000000314113226215407020071 0ustar00olafolaf00000000000000## Copyright (C) 2014-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{varargout} =} __UNO_chk_sprt__ (@var{varargin}) ## Undocumented internal function ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2014-10-31 function [chk, missing0] = __UNO_chk_sprt__ (jcp, dbug=0) chk = 0; ## entries0(1) = not a jar but a directory (<000_install_dir/program/>) entries0 = {"program", "unoil", "jurt", "juh", "unoloader", "ridl"}; if (dbug > 1) printf ("\nUNO/Java (.ods, .xls, .xlsx, .sxc) :\n"); endif [jpchk, missing0] = chk_jar_entries (jcp, entries0, dbug); missing0 = entries0 (find (missing0)); if (jpchk >= numel (entries0)) chk = 1; if (dbug > 1) printf (" => UNO (OOo) OK\n"); endif elseif (dbug > 1) printf (" => One or more UNO classes (.jar) missing in javaclasspath\n"); endif ## No additional checks required endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OCT_ods2oct__.m0000644000000000000000000000013213226215407017356 xustar0030 mtime=1515789063.576155008 30 atime=1515789063.576155008 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OCT_ods2oct__.m0000644000175000017500000002546713226215407017634 0ustar00olafolaf00000000000000## Copyright (C) 2013-2017 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 Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## @deftypefn {Function File} [@var{raw}, @var{ods}, @var{rstatus} = __OCT_ods2oct__ (@var{ods}, @var{wsh}, @var{range}, @var{opts}) ## Internal function for reading data from an ods worksheet ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2013-09-08 function [ rawarr, ods, rstatus] = __OCT_ods2oct__ (ods, wsh, cellrange="", spsh_opts) rstatus = 0; ## Check if requested worksheet exists in the file & if so, get sheet if (isnumeric (wsh)) if (wsh > numel (ods.sheets.sh_names) || wsh < 1) error ("xls2/odsoct: sheet number (%d) out of range (1 - %d)", wsh, numel (ods.sheets.sh_names)); endif elseif (ischar (wsh)) idx = find (strcmp (wsh, ods.sheets.sh_names)); if (isempty (idx)) error ("xls/ods2oct: sheet '%s' not found in file %s", wsh, ods.filename); endif wsh = idx; endif ## Get requested sheet from info in ods struct pointer. Open file fid = fopen (sprintf ("%s/content.xml", ods.workbook), "r");; ## Go to start of requested sheet fseek (fid, ods.sheets.shtidx(wsh), "bof"); ## Compute size of requested chunk nchars = ods.sheets.shtidx(wsh+1) - ods.sheets.shtidx(wsh); ## Get the sheet sheet = fread (fid, nchars, "char=>char").'; fclose (fid); ## Add xml to struct pointer to avoid __OCT_getusedrange__ to read it again ods.xml = sheet; ## Check ranges [ firstrow, lastrow, lcol, rcol ] = getusedrange (ods, wsh); ## Clear xml from file ptr struct ods.xml = []; ods = rmfield (ods, "xml"); if (isempty (cellrange)) if (firstrow == 0 && lastrow == 0) ## Empty sheet rawarr = {}; ## printf ("Worksheet '%s' contains no data\n", ods.sheets.sh_names{wsh}); lims = []; rstatus = 1; return; else nrows = lastrow - firstrow + 1; ncols = rcol - lcol + 1; endif else [topleft, nrows, ncols, firstrow, lcol] = parse_sp_range (cellrange); ## Check if requested range exists if (firstrow > lastrow || lcol > rcol) ## Out of occupied range warning ("xls/ods2oct: requested range outside occupied range\n"); rawarr = {}; ods.limits = []; return endif lastrow = min (lastrow, firstrow + nrows - 1); rcol = min (rcol, lcol + ncols - 1); endif ## FIXME Preallocation + data reading can be more efficient ## Preallocate output array; provisionally assign max nr. of rows & columns rawarr = cell (lastrow, rcol); ## Get data re = 1; # Start table-row search at first char of sheet irow = 0; # Counts "real" spreadsheet rows trow = " "; ## Row index ii below does not necessarily match table-rows! while (irow < lastrow && (! isempty (trow))) ## Get next table-row [trow, ~, re] = getxmlnode (sheet, "table:table-row", re); if (! isempty (trow)) ## Check if table-row has any data datrow = index (trow, " office:"); ## Check repeat status and update row counter reprow = str2double (getxmlattv (trow, "table:number-rows-repeated")); if (isfinite (reprow)) reprow = min (reprow, lastrow - irow) - 1; endif irow++; ## Only process table-row contents if it has any data. Skip upper ## empty table-rows (that's why we need an OR), only start counting ## with the first table-row containing data if (datrow || irow) ce = 0; # Char pointer on table-row tcell = " "; icol = 0; # Count spreadsheet column while (icol < rcol && (! isempty (tcell))) ## Get next table-cell. First see if it is covered (merged) [tcell1, ~, ce1] = getxmlnode (trow, "table:covered-table-cell", ce+1); [tcell2, ~, ce2] = getxmlnode (trow, "table:table-cell", ce+1); if (ce1 > 0 && ce2 > 0) ## Both table-cell and a table-covered-cell are present if (ce1 < ce2) ## table-covered cell before table-cell. Set pointer at its end ce = ce1; tcell = tcell1; ## Signal code below that content parsing must be skipped ce2 = 0; else ## table-cell before table-covered cell. Pointer to end of table-cell ce = ce2; tcell = tcell2; endif else if (ce1 > 0) ## Only table-covered-cell found ce = ce1; tcell = tcell1; else ## Only table-cell found ce = ce2; tcell = tcell2; endif endif ## First check its repeat status and update column counter repcol = str2double (getxmlattv (tcell, "table:number-columns-repeated")); if (isfinite (repcol)) repcol = min (repcol, rcol - icol); endif icol++; if (! isempty (tcell)) ## Try to get value type ctype = ""; if (ce2) ctype = getxmlattv (tcell, "office:value-type"); if (isempty (ctype) && spsh_opts.formulas_as_text) ## Work around OTK bug (doesn't write office:value-type for formulas) if (! isempty (strfind (tcell, "formula"))) ctype = "cformula"; endif endif endif if (! isempty (ctype)) if (spsh_opts.formulas_as_text) form = getxmlattv (tcell, "table:formula"); if (! isempty (form)) ctype = "cformula"; endif endif ## Get value ctvalue = getxmlnode (tcell, "text:p")(9:end-9); ## Put proper translation into rawarr switch ctype case "cformula" ## Pimp ranges in formulas form = regexprep (form, '\[\.(\w+)\]', '$1'); form = regexprep (form, '\[\.(\w+):', '$1:'); form = regexprep (form, ':\.(\w+)\]', ':$1'); rawarr{irow, icol} = form; ## Remove of= rawarr{irow, icol} = form(4:end); case "float" ## Watch out for error values. If so, has #VALUE and office:value = 0 if (isfinite (str2double (ctvalue))) rawarr{irow, icol} = str2double (getxmlattv (tcell, "office:value")); else rawarr{irow, icol} = NaN; endif case "percentage" ## Watch out for error values. If so, has #VALUE and office:value = 0 ctvalue = ctvalue (1:end-1); if (isfinite (str2double (ctvalue))) rawarr{irow, icol} = str2double (getxmlattv (tcell, "office:value")); else rawarr{irow, icol} = NaN; endif case "currency" ## Watch out for error values. If so, has #VALUE and office:value = 0 idx = regexp (ctvalue, '[\d.\d]'); if (isempty (idx)) rawarr{irow, icol} = NaN; else rawarr{irow, icol} = str2double (getxmlattv (tcell, "office:value")); endif case "string" rawarr{irow, icol} = strjoin (cell2mat (regexp (tcell, ... '?(.*?)', "tokens")), "\n");; case "date" cvalue = getxmlattv (tcell, "office:date-value"); try cvalue = strsplit (cvalue, "T"); ## Date part cv = regexp (cvalue{1}, '[0-9]*', "match"); yr = str2double (cv(1)); mo = str2double (cv(2)); dy = str2double (cv(3)); rawarr{irow, icol} = datenum(yr, mo, dy) + 693960; ## Time part, if any (that's what the try-catch is for) cv = regexp (cvalue{2}, '[0-9]*', "match"); hh = str2double (cv(1)); mm = str2double (cv(2)); ss = str2double (cv(3)); rawarr{irow, icol} += datenum (0, 0, 0, hh, mm, ss); catch end_try_catch case "boolean" rawarr{irow, icol} = strcmpi (ctvalue, "true"); case "time" ## Time values usually have hours first, then minutes, optionally seconds hh = mi = ss = 0; ctvalue = regexp (getxmlattv (tcell, "office:time-value"), '[0-9]*', "match"); ## try-catch to catch missing seconds try hh = str2double (ctvalue(1)); mi = str2double (ctvalue(2)); ss = str2double (ctvalue(3)); catch end_try_catch rawarr{irow, icol} = datenum (0, 0, 0, hh, mi, ss); otherwise ## Do nothing endswitch endif ## Copy cell contents for repeated columns & bump column counter if (isfinite (repcol) && icol < rcol) rawarr(irow, icol+1:icol+repcol-1) = rawarr(irow, icol); icol += repcol - 1; repcol = ""; endif endif endwhile ## Copy row contents to repeated rows & bump row counter if (isfinite (reprow) && irow < lastrow) for kk=irow+1:min (nrows, irow+reprow-1) rawarr(kk, :) = rawarr(irow, :); endfor irow += reprow; reprow = ""; endif endif endif endwhile ## If required strip leftmost empty columns/topmost empty rows if (lcol > 1) rawarr(:, 1:ncols) = rawarr(:, lcol:rcol); rawarr(:, ncols+1:end) = []; endif if (firstrow > 1) rawarr(1:nrows, :) = rawarr(firstrow:lastrow, :); rawarr(nrows+1:end, :) = []; endif ## Keep track of data rectangle limits ods.limits = [lcol, rcol; firstrow, lastrow]; rstatus = 1; endfunction io-2.4.10/inst/private/PaxHeaders.5973/__UNO_getusedrange__.m0000644000000000000000000000013213226215407020472 xustar0030 mtime=1515789063.592155322 30 atime=1515789063.592155322 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__UNO_getusedrange__.m0000644000175000017500000000527213226215407020740 0ustar00olafolaf00000000000000## Copyright (C) 2011-2017 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 . ## __UNO_getusedrange__ ## Author: Philip Nienhuis ## Created: 2011-05-06 function [ srow, erow, scol, ecol ] = __UNO_getusedrange__ (ods, ii) # Get desired sheet sheets = ods.workbook.getSheets (); sh_names = sheets.getElementNames (); unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.sheet.XSpreadsheet"); sh = sheets.getByName (sh_names(ii)).getObject.queryInterface (unotmp); ## Prepare cell range query unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.sheet.XCellRangesQuery"); xRQ = sh.queryInterface (unotmp); Cellflgs = javaObject ("java.lang.Short", "23"); ccells = xRQ.queryContentCells (Cellflgs); ## Get addresses of all blocks containing data addrs = ccells.getRangeAddressesAsString (); ## Strip sheet name from addresses. Watch out, in LO3.5 they changed ## the separator from ',' to ';' (without telling me 8-Z) ## 1. Get nr of range blocks nblks = numel (strfind (addrs, sh_names(ii))); ## 2. First try with "," separator... adrblks = strsplit (addrs, ","); if (numel (adrblks) < nblks) ## Apparently we have a ';' separator, so try with semicolon adrblks = strsplit (addrs, ";"); endif if (isempty (adrblks) || isempty (adrblks{1})) srow = erow = scol = ecol = 0; return endif ## Find leftmost & rightmost columns, and highest and lowest row with data srow = scol = 1e10; erow = ecol = 0; for ii=1:numel (adrblks) ## Check if address contains a sheet name in quotes (happens if name contains a period) if (int8 (adrblks{ii}(1)) == 39) ## Strip sheet name part idx = findstr (adrblks{ii}, "'."); range = adrblks{ii}(idx+2 : end); else ## Same, but tru strsplit() range = strsplit (adrblks{ii}, "."){2}; endif [dummy, nrows, ncols, trow, lcol] = parse_sp_range (range); brow = trow + nrows - 1; rcol = lcol + ncols - 1; srow = min (srow, trow); scol = min (scol, lcol); erow = max (erow, brow); ecol = max (ecol, rcol); endfor endfunction io-2.4.10/inst/private/PaxHeaders.5973/chk_jar_entries.m0000644000000000000000000000013213226215407017632 xustar0030 mtime=1515789063.596155401 30 atime=1515789063.596155401 30 ctime=1515789065.028183488 io-2.4.10/inst/private/chk_jar_entries.m0000644000175000017500000000470613226215407020101 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## chk_jar_entries - internal function finding Java .jar names in javaclasspath ## Author: Philip Nienhuis ## Created: 2012-10-07 function [ retval, missing ] = chk_jar_entries (jcp, entries, dbug=0) retval = 0; missing = zeros (1, numel (entries)); for jj=1:length (entries) found = 0; for ii=1:length (jcp) ## Get jar (or folder/map/subdir) name from java classpath entry jentry = strsplit (lower (jcp{ii}), filesep){end}; kk = 0; while (++kk <= size (char (entries{jj}), 1) && ! found) if (! isempty (strfind (jentry, strtrim (lower (char (entries{jj})(kk, :)))))) ++retval; found = 1; if (dbug > 2) fprintf (" - %s OK\n", jentry); endif endif endwhile endfor if (! found) if (dbug > 2) if (iscellstr (entries{jj})) entrtxt = sprintf ("%s/", entries{jj}{:}); entrtxt(end) = ""; else entrtxt = entries{jj}; endif printf (" %s....jar missing\n", entrtxt); endif missing(jj) = 1; endif endfor endfunction ## FIXME -- reinstate these tests one there if a way is found to test private ## functions directly ##%!test ##%! entries = {"abc", {"def", "ghi"}, "jkl"}; ##%! jcp1 = {"/usr/lib/java/abcx.jar", "/usr/lib/java/defz.jar", "/usr/lib/java/jkl3.jar"}; ##%! jcp1 = strrep (jcp1, "/", filesep); ##%! assert (chk_jar_entries (jcp1, entries), 3); ##%!test ##%! entries = {"abc", {"def", "ghi"}, "xyz"}; ##%! jcp2 = {"/usr/lib/java/abcy.jar", "/usr/lib/java/ghiw.jar", "/usr/lib/java/jkl6.jar"}; ##%! jcp2 = strrep (jcp2, "/", filesep); ##%! [aaa, bbb] = chk_jar_entries (jcp2, entries); ##%! assert (aaa, 2); ##%! assert (bbb, [0 0 1]); io-2.4.10/inst/private/PaxHeaders.5973/__OCT_spsh_open__.m0000644000000000000000000000013213226215407017777 xustar0030 mtime=1515789063.580155087 30 atime=1515789063.580155087 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OCT_spsh_open__.m0000644000175000017500000001554713226215407020253 0ustar00olafolaf00000000000000## Copyright (C) 2013-2017 Philip Nienhuis ## Copyright (C) 2013 Markus Bergholz (.xlsx & archive unzip stuff) ## ## 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 Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} __OCT_spsh_open__ (@var{x} @var{y}) ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## File open stuff by Markus Bergholz ## Created: 2013-09-08 function [ xls, xlssupport, lastintf] = __OCT_spsh_open__ (xls, xwrite, filename, xlssupport, ftype) ## default output (on error) lastintf = ""; ## Open and unzip file to temp location (code by Markus Bergholz) ## create current work folder tmpdir = tmpnam; ## Get template if a new file is created if (xwrite == 3) if (ftype == 2) ext = ".xlsx"; elseif (ftype == 3) ext = ".ods"; elseif (ftype == 5) ext = ".gnumeric"; endif ## New file, get it from template. Use odsopen.m to find it templ = strrep (which ("xlsopen"), "xlsopen.m", ["templates" filesep "template" ext]); else templ = filename; endif ## zip operations sometimes transfer to temp dir; make sure we get back opwd = pwd; if (ftype == 5) ## Gnumeric xml files are gzipped 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 fclose (fid); else ## xlsx and ods are zipped try ## FIXME: Use "unpack" instead of system ("unzip...") when it is fixed [stts, op] = system (sprintf ('unzip -o "%s" -d %s', templ, tmpdir)); if (stts != 0) error ("UnZip failed with error %d\nOutput:\n%s\n", stts, op); endif catch err printf ("file %s couldn't be unpacked. Is it the proper file format?\n", filename); warning (err.message) warning (err.stack) xls = []; cd (opwd); return end_try_catch endif ## Make sure we get back to original work dir cd (opwd); ## Set up file pointer struct if (ftype == 2) ## ======================= XLSX =========================================== ## From xlsxread by Markus Bergholz ## https://github.com/markuman/xlsxread ## Get sheet names. Speeds up other functions a lot if we can do it here fid = fopen (sprintf ('%s/xl/workbook.xml', tmpdir)); if (fid < 0) ## File open error warning ("xls2open: file %s couldn't be unzipped\n", filename); xls = []; return endif ## Fill xlsx pointer xls.workbook = tmpdir; # subdir containing content.xml xls.xtype = "OCT"; # OCT is fall-back interface xls.app = 'xlsx'; # must NOT be an empty string! xls.filename = filename; # spreadsheet filename xls.changed = 0; # Dummy ## Get content.xml xml = fread (fid, "char=>char").'; ## Close file fclose (fid); ## Get sheet names and indices sheets = getxmlnode (xml, "sheets", [], 1); xls.sheets.sh_names = cell2mat (regexp (sheets, ' 0) str = fread (fid, "char=>char").'; fclose (fid); xls.sheets.rels = regexp (str, ... [''], "tokens"); xls.sheets.rels = reshape (str2double (cell2mat (xls.sheets.rels)), [], columns(xls.sheets.rels))'; else xls.sheets.rels = reshape ([xls.sheets.rid xls.sheets.rid], [], columns (xls.sheets.rid)); endif elseif (ftype == 3) ## ============== ODS. Read the actual data part in content.xml ============ fid = fopen (sprintf ("%s/content.xml", tmpdir), "r"); if (fid < 0) ## File open error error ("file %s couldn't be opened for reading", filename); else ## Read file contents xml = fread (fid, "char=>char").'; ## Close file but keep it around, store file name in struct pointer fclose (fid); ## To speed things up later on, get sheet names and starting indices shtidx = strfind (xml, ""); endif shtidx = [ shtidx sht_end ]; ## Get sheet names sh_names = cell (1, nsheets); for ii=1:nsheets sh_names(ii) = xml(shtidx(ii)+25 : shtidx(ii)+23+index (xml(shtidx(ii)+25:end), '"')); endfor ## Fill ods pointer. xls.workbook = tmpdir; # subdir containing content.xml xls.sheets.sh_names = sh_names; # sheet names xls.sheets.shtidx = shtidx; # start & end indices of sheets xls.xtype = "OCT"; # OCT is fall-back interface xls.app = 'ods'; # must NOT be an empty string! xls.filename = filename; # spreadsheet filename xls.changed = 0; # Dummy endif elseif (ftype == 5) ## ====================== Gnumeric ========================================= xls.workbook = tmpdir; # location of unzipped files xls.xtype = "OCT"; # interface xls.app = 'gnumeric'; # xls.filename = filename; # file name xls.changed = 0; # Dummy ## Get nr of sheets & pointers to start of Sheet nodes & end of Sheets node shtidx = strfind (xml, "") ]; xls.sheets.sh_names = cell (1, numel (shtidx)); sh_names = getxmlnode (xml, "gnm:SheetNameIndex"); jdx = 1; for ii=1:numel (shtidx) [xls.sheets.sh_names(ii), ~, jdx] = getxmlnode (sh_names, "gnm:SheetName", jdx, 1); endfor endif xlssupport += 1; lastintf = "OCT"; endfunction io-2.4.10/inst/private/PaxHeaders.5973/getodsinterfaces.m0000644000000000000000000000013213226215407020031 xustar0030 mtime=1515789063.596155401 30 atime=1515789063.596155401 30 ctime=1515789065.028183488 io-2.4.10/inst/private/getodsinterfaces.m0000644000175000017500000001413713226215407020277 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## @deftypefn {Function File} @var{odsinterfaces} = getodsinterfaces (@var{odsinterfaces}) ## Get supported OpenOffice.org .ods file read/write interfaces from ## the system. ## Each interface for which the corresponding field is set to empty ## will be checked. So by manipulating the fields of input argument ## @var{odsinterfaces} it is possible to specify which ## interface(s) should be checked. ## ## Currently implemented interfaces comprise: ## - Java & ODFtoolkit (www.apache.org) ## - Java & jOpenDocument (www.jopendocument.org) ## - Java & UNO bridge (OpenOffice.org) ## ## Examples: ## ## @example ## odsinterfaces = getodsinterfaces (odsinterfaces); ## @end example ## Author: Philip Nienhuis ## Created: 2009-12-27 function [odsinterfaces] = getodsinterfaces (odsinterfaces) ## tmp1 = [] (not initialized), 0 (No Java detected), or 1 (Working Java found) persistent tmp1 = []; persistent jcp={}; ## Java class path persistent has_java = []; ## Built-in Java support persistent uno_1st_time = 0; if (isempty (has_java)) has_java = __have_feature__ ("JAVA"); endif if (isempty (odsinterfaces.OTK) && isempty (odsinterfaces.JOD) ... && isempty (odsinterfaces.UNO)) ## Assume no interface detection has happened yet printf ("Detected ODS interfaces: "); tmp1 = []; elseif (isempty (odsinterfaces.OTK) || isempty (odsinterfaces.JOD) ... || isempty (odsinterfaces.UNO)) ## Can't be first call. Here one of the Java interfaces is requested if (tmp1) # Check Java support again tmp1 = []; elseif (has_java) ## Renew jcp (javaclasspath) as it may have been updated since last call jcp = javaclasspath ("-all"); ## For java pkg >= 1.2.8 if (isempty (jcp)) ## & Octave >= 3.7.2 jcp = javaclasspath; endif ## For java pkg < 1.2.8 if (isunix && ! iscell (jcp)); jcp = strsplit (char (jcp), pathsep ()); endif endif endif ## deflt signals that some default interface has been selected. Just used ## for cosmetic purposes deflt = 0; if (has_java) if (isempty (tmp1)) ## Check Java support [tmp1, jcp] = __chk_java_sprt__ (); if (! tmp1) ## No Java support found if (isempty (odsinterfaces.OTK) || isempty (odsinterfaces.JOD) ... || isempty (odsinterfaces.UNO)) ## Some or all Java-based interface explicitly requested; but no Java support warning ... (" No Java support found (no Java JRE or JDK?)\n"); endif ## Set Java-based interfaces to 0 anyway as there's no Java support odsinterfaces.OTK = 0; odsinterfaces.JOD = 0; odsinterfaces.UNO = 0; printf ("\n"); ## No more need to try any Java interface return; endif endif ## Try Java & ODF toolkit if (isempty (odsinterfaces.OTK)) odsinterfaces.OTK = 0; [chk, missing5] = __OTK_chk_sprt__ (jcp); ## Beware of unsupported odfdom jar versions if (chk >= 1) odsinterfaces.OTK = 1; printf ("OTK"); if (deflt) printf ("; "); else printf ("*; "); deflt = 1; endif endif endif ## Try Java & jOpenDocument if (isempty (odsinterfaces.JOD)) odsinterfaces.JOD = 0; chk = __JOD_chk_sprt__ (jcp); if (chk) odsinterfaces.JOD = 1; printf ("JOD"); if (deflt) printf ("; "); else printf ("*; "); deflt = 1; endif endif endif ## Try Java & UNO if (isempty (odsinterfaces.UNO)) odsinterfaces.UNO = 0; [chk, missing0] = __UNO_chk_sprt__ (jcp); if (isempty (missing0) && chk) odsinterfaces.UNO = 1; printf ("UNO"); if (deflt) printf ("; "); else printf ("*; "); deflt = 1; uno_1st_time = min (++uno_1st_time, 2); endif endif endif else ## Set Java-based interfaces to 0 anyway as there's no Java support odsinterfaces.OTK = 0; odsinterfaces.JOD = 0; odsinterfaces.UNO = 0; ## End of has_java block endif ## Native Octave (OCT). Can be zeroed when requesting specific interface if (isempty (odsinterfaces.OCT)) ## Nothing to check, always supported odsinterfaces.OCT = 1; printf ("OCT"); if (deflt) printf ("; "); else printf ("*; "); deflt = 1; endif endif ## ---- Other interfaces here, similar to the ones above if (deflt) printf ("(* = default interface)\n"); endif ## FIXME the below stanza should be dropped once UNO is stable. ## Echo a suitable warning about experimental status: if (uno_1st_time == 1) ++uno_1st_time; printf ("\nPLEASE NOTE: UNO (=OpenOffice.org-behind-the-scenes) is EXPERIMENTAL\n"); printf ("After you've opened a spreadsheet file using the UNO interface,\n"); printf ("odsclose on that file will kill ALL OpenOffice.org invocations,\n"); printf ("also those that were started outside and/or before Octave!\n"); printf ("Trying to quit Octave w/o invoking odsclose will only hang Octave.\n\n"); endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__POI_getusedrange__.m0000644000000000000000000000013213226215407020460 xustar0030 mtime=1515789063.588155243 30 atime=1515789063.588155243 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__POI_getusedrange__.m0000644000175000017500000000410513226215407020720 0ustar00olafolaf00000000000000## Copyright (C) 2010-2017 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 . ## __POI_getusedrange__ - get range of occupied data cells from Excel using java/POI ## Author: Philip Nienhuis ## Created: 2010-03-20 function [ trow, brow, lcol, rcol ] = __POI_getusedrange__ (xls, ii) persistent cblnk; cblnk = __java_get__ ("org.apache.poi.ss.usermodel.Cell", "CELL_TYPE_BLANK"); sh = xls.workbook.getSheetAt (ii-1); ## Java POI starts counting at 0 trow = sh.getFirstRowNum (); ## 0-based brow = sh.getLastRowNum (); ## 0-based ## Get column range lcol = 1048577; ## OOXML (xlsx) max. + 1 rcol = 0; botrow = brow; for jj=trow:brow irow = sh.getRow (jj); if (! isempty (irow)) scol = irow.getFirstCellNum; ## If getFirstCellNum < 0, row is empty if (scol >= 0) lcol = min (lcol, scol); ecol = irow.getLastCellNum - 1; rcol = max (rcol, ecol); ## Keep track of lowermost non-empty row as getLastRowNum() is unreliable if (! (irow.getCell(scol).getCellType () == cblnk ... && irow.getCell(ecol).getCellType () == cblnk)) botrow = jj; endif endif endif endfor if (lcol > 1048576) ## Empty sheet trow = 0; brow = 0; lcol = 0; rcol = 0; else ## 1-based retvals brow = min (brow, botrow) + 1; ++trow; ++lcol; ++rcol; endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__POI_spsh_info__.m0000644000000000000000000000013213226215407017773 xustar0030 mtime=1515789063.588155243 30 atime=1515789063.588155243 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__POI_spsh_info__.m0000644000175000017500000000276313226215407020243 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## __POI_spsh_info__ ## Author: Philip Nienhuis ## Created: 2012-10-12 function [sh_names] = __POI_spsh_info__ (xls) persistent cblnk; cblnk = __java_get__ ("org.apache.poi.ss.usermodel.Cell", "CELL_TYPE_BLANK"); sh_cnt = xls.workbook.getNumberOfSheets(); sh_names = cell (sh_cnt, 2); nsrows = zeros (sh_cnt, 1); for ii=1:sh_cnt sh = xls.workbook.getSheetAt (ii-1); # Java POI starts counting at 0 sh_names(ii, 1) = char (sh.getSheetName()); ## Java POI doesn't distinguish between worksheets and graph sheets [tr, lr, lc, rc] = getusedrange (xls, ii); if (tr) sh_names(ii, 2) = ... sprintf ("%s:%s", calccelladdress (tr, lc), calccelladdress (lr, rc)); else sh_names(ii, 2) = "Empty"; endif endfor endfunction io-2.4.10/inst/private/PaxHeaders.5973/__UNO_spsh2oct__.m0000644000000000000000000000013213226215407017562 xustar0030 mtime=1515789063.592155322 30 atime=1515789063.592155322 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__UNO_spsh2oct__.m0000644000175000017500000001137213226215407020026 0ustar00olafolaf00000000000000## Copyright (C) 2011-2017 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 . ## __UNO_spsh2oct__ - Inernal function for reading from spreadsheets using UNO/Java ## Author: Philip Nienhuis ## Created: 2011-05-05 function [rawarr, xls, rstatus] = __UNO_spsh2oct__ (xls, wsh, datrange, spsh_opts) sheets = xls.workbook.getSheets (); sh_names = sheets.getElementNames (); if (! iscell (sh_names)) ## Java array (LibreOffice 3.4.+), convert to cellstr sh_names = char (sh_names); else sh_names = {sh_names}; endif ## Check sheet pointer if (isnumeric (wsh)) if (wsh < 1 || wsh > numel (sh_names)) error ("Sheet index %d out of range 1-%d", wsh, numel (sh_names)); endif else ii = find (strcmp (wsh, sh_names)); if (isempty (ii)) error ("Sheet '%s' not found", wsh); endif wsh = ii; endif unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.sheet.XSpreadsheet"); sh = sheets.getByName(sh_names{wsh}).getObject.queryInterface (unotmp); unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.sheet.XCellRangesQuery"); xRQ = sh.queryInterface (unotmp); ## Get cell ranges of all rectangles containing data. Type values: ##__java_get__ ("com.sun.star.sheet.CellFlags", "VALUE") ans = 1 ##__java_get__ ("com.sun.star.sheet.CellFlags", "DATETIME") ans = 2 ##__java_get__ ("com.sun.star.sheet.CellFlags", "STRING") ans = 4 ##__java_get__ ("com.sun.star.sheet.CellFlags", "FORMULA") ans = 16 + ## -------- ## Yep, boolean is lacking... sum = 23 Cellflgs = javaObject ("java.lang.Short", "23"); ccells = xRQ.queryContentCells (Cellflgs); addrs = ccells.getRangeAddressesAsString (); ## Strip sheet name from addresses adrblks = strsplit (addrs, ","); if (isempty (adrblks)) warning ("Sheet %s contains no data\n", sh_names{wsh}); return endif ## Either parse (given cell range) or prepare (unknown range) help variables. ## As OpenOffice knows the occupied range, we need the limits anyway to avoid ## out-of-range errors [ trow, brow, lcol, rcol ] = getusedrange (xls, wsh); if (isempty (datrange)) nrows = brow - trow + 1; ## Number of rows to be read ncols = rcol - lcol + 1; ## Number of columns to be read else [dummy, nrows, ncols, srow, scol] = parse_sp_range (datrange); ## Truncate range silently if needed brow = min (srow + nrows - 1, brow); rcol = min (scol + ncols - 1, rcol); trow = max (trow, srow); lcol = max (lcol, scol); nrows = min (brow - trow + 1, nrows); ## Number of rows to be read ncols = min (rcol - lcol + 1, ncols); ## Number of columns to be read endif ## Create storage for data at Octave side rawarr = cell (nrows, ncols); ## Get data. Apparently row & column indices are 0-based in UNO for ii=trow-1:brow-1 for jj=lcol-1:rcol-1 XCell = sh.getCellByPosition (jj, ii); cType = XCell.getType ().getValue (); switch cType case 1 ## Value rawarr{ii-trow+2, jj-lcol+2} = XCell.getValue (); case 2 ## String unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.text.XText"); rawarr{ii-trow+2, jj-lcol+2} = XCell.queryInterface (unotmp).getString (); case 3 ## Formula if (spsh_opts.formulas_as_text) rawarr{ii-trow+2, jj-lcol+2} = XCell.getFormula (); else ## Unfortunately OOo gives no clue as to the type of formula result unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.text.XText"); rawarr{ii-trow+2, jj-lcol+2} = XCell.queryInterface (unotmp).getString (); tmp = str2double (rawarr{ii-trow+2, jj-lcol+2}); ## If the string happens to contain just a number we'll assume it is numeric if (! isnan (tmp)) rawarr{ii-trow+2, jj-lcol+2} = tmp; endif endif otherwise ## Empty cell endswitch endfor endfor ## Keep track of data rectangle limits xls.limits = [lcol, rcol; trow, brow]; rstatus = ! isempty (rawarr); endfunction io-2.4.10/inst/private/PaxHeaders.5973/parse_sp_range.m0000644000000000000000000000013213226215407017470 xustar0030 mtime=1515789063.596155401 30 atime=1515789063.596155401 30 ctime=1515789065.028183488 io-2.4.10/inst/private/parse_sp_range.m0000644000175000017500000000535013226215407017733 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## Parse a string representing a range of cells for a spreadsheet ## into nr of rows and nr of columns and also extract top left ## cell address + top row + left column. Some error checks are implemented. ## Author: Philip Nienhuis ## Created: 2009-06-20 function [topleft, nrows, ncols, toprow, lcol] = parse_sp_range (range_org) crange = strrep (deblank (upper (range_org)), " ", ""); range_error = 0; nrows = 0; ncols = 0; # Basic checks if (index (crange, ':') == 0) if (isempty (crange)) range_error = 0; leftcol = 'A'; rightcol = 'A'; else # Only upperleft cell given, just complete range to 1x1 # (needed for some routines) crange = [crange ":" crange]; endif endif # Split up both sides of the range [topleft, lowerright] = strtok (crange, ':'); # Get toprow and clean up left column [st, en] = regexp (topleft, '\d+'); toprow = str2double (topleft(st:en)); lcol = col2num (topleft(1:st-1)); # Get bottom row and clean up right column [st, en] = regexp (lowerright, '\d+'); bottomrow = str2double (lowerright(st:en)); rcol = col2num (lowerright (2:st-1)); # Check nr. of rows nrows = bottomrow - toprow + 1; if (nrows < 1) range_error = 1; endif if (range_error == 0) # Check ncols = rcol - lcol + 1; if (ncols < 1) range_error = 1; endif endif if (range_error > 0) ncols = 0; nrows = 0; error ("Spreadsheet range error!"); endif endfunction ## FIXME -- reinstate these tests one there if a way is found to test private ## functions directly #%!test #%! [a b c d e] = parse_sp_range ('A1:B2'); #%! assert ([a b c d e], ['A1', 2, 2, 1, 1]); #% #%!test #%! [a b c d e] = parse_sp_range ('A1:AB200'); #%! assert ([a b c d e], ['A1', 200, 28, 1, 1]); #% #%!test #%! [a b c d e] = parse_sp_range ('cd230:iY65536'); #%! assert ([a b c d e], ['CD230', 65307, 178, 230, 82]); #% #%!test #%! [a b c d e] = parse_sp_range ('BvV12798 : xFd1054786'); #%! assert ([b c d e], [1041989, 14439, 12798, 1946]); io-2.4.10/inst/private/PaxHeaders.5973/__JXL_spsh_info__.m0000644000000000000000000000013213226215407020001 xustar0030 mtime=1515789063.572154929 30 atime=1515789063.572154929 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__JXL_spsh_info__.m0000644000175000017500000000254013226215407020242 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## __JXL_spsh_info__ ## Author: Philip Nienhuis ## Created: 2012-10-12 function [sh_names, fformat] = __JXL_spsh_info__ (xls) sh_cnt = xls.workbook.getNumberOfSheets (); sh_names = cell (sh_cnt, 2); nsrows = zeros (sh_cnt, 1); sh_names(:,1) = char (xls.workbook.getSheetNames ()); for ii=1:sh_cnt [tr, lr, lc, rc] = getusedrange (xls, ii); if (tr) sh_names(ii, 2) = ... sprintf ("%s:%s", calccelladdress (tr, lc), calccelladdress (lr, rc)); else sh_names(ii, 2) = "Empty"; endif endfor if (sh_cnt > 0) fformat = "xlWorkbookNormal"; else fformat = ''; endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OCT_spsh_close__.m0000644000000000000000000000013213226215407020143 xustar0030 mtime=1515789063.580155087 30 atime=1515789063.580155087 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OCT_spsh_close__.m0000644000175000017500000000657313226215407020416 0ustar00olafolaf00000000000000## Copyright (C) 2013-2017 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 Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{xls} =} __OCT_spsh_close__ (@var{xls}) ## Internal function! do not call directly; close spreadsheet pointer ## struct xls; for native OCT interface just set it to empty. ## ## @end deftypefn ## Author: Philip Nenhuis ## Created: 2013-09-09 function [xls] = __OCT_spsh_close__ (xls, fcn) if (isfield (xls, "nfilename")) xls.filename = xls.nfilename; endif ## Check extension and full path to file [pth, fname, ext] = fileparts (xls.filename); opwd = pwd; if (isempty (pth)) filename = [ opwd filesep xls.filename ]; else filename = make_absolute_filename (xls.filename); endif ## .ods and.xlsx are both zipped if (strcmpi (ext, ".ods") || strcmpi (ext, ".xlsx")) if (xls.changed && xls.changed < 3) ## Go to temp dir where .ods or .xlsx file has been unzipped cd (xls.workbook); pause (0.05); ## Zip tmp directory into .ods or .xlsx and copy it over original file try if exist (fullfile (xls.workbook, [fname ".zip"]), "file") delete (fullfile (xls.workbook, [fname ".zip"])); endif [stts, op] = system (sprintf ('zip -q -r "%s" *', [fname ".zip"])); if (stts == 0) ## Move file from temp folder and rename [mvst, msg] = movefile (["." filesep fname ".zip"], filename, "f"); if ~mvst error ('%s: Moving file "%s" to "%s" failed with message: "%s"', ... fcn, fullfile (xls.workbook, [fname ".zip"]), filename, msg); endif xls.changed = 0; else error ("%s: Zipping xlsx-file failed with error %d\nOutput:\n%s\n", ... fcn, stts, op); endif catch err printf ("%s: could not zip files in %s to %s\n", ... fcn, xls.workbook, filename); warning (err.message) warning (err.stack) end_try_catch; endif elseif (strcmpi (xls.filename(end-8:end), ".gnumeric")) ## gnumeric files are gzipped try status = system (sprintf ('gzip -c -S=gnumeric %s > "%s"', ... xls.workbook, filename)); if (! status) ## Delete temporary file unlink (xls.workbook); xls.changed = 0; endif catch status = 1; end_try_catch if (status) printf ("%s: could not gzip gnumeric contents in %s to %s\n", ... fcn, xls.workbook, filename); endif endif ## Delete tmp file and return to work dir cd (opwd); if (! xls.changed) ## Below is needed for a silent delete of our tmpdir confirm_recursive_rmdir (0, "local"); rmdir (xls.workbook, "s"); endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__COM_getusedrange__.m0000644000000000000000000000013213226215407020447 xustar0030 mtime=1515789063.564154773 30 atime=1515789063.564154773 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__COM_getusedrange__.m0000644000175000017500000000332613226215407020713 0ustar00olafolaf00000000000000## Copyright (C) 2010-2017 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 . ## __COM_getusedrange__ ## Author: Philip Nienhuis ## Created: 2010-10-07 function [ trow, brow, lcol, rcol ] = __COM_getusedrange__ (xls, ii) sh = xls.workbook.Worksheets (ii); ## Decipher used range. Beware, UsedRange() returns *cached* rectangle of ## all spreadsheet cells containing *anything*, including just formatting ## (i.e., empty cells are included too). ==> This is an approximation only allcells = sh.UsedRange; ## Get top left cell as a Range object toplftcl = allcells.Columns(1).Rows(1); ## Count number of rows & cols in virtual range from A1 to top left cell lcol = sh.Range ("A1", toplftcl).columns.Count; trow = sh.Range ("A1", toplftcl).rows.Count; ## Add real occupied rows & cols to obtain end row & col brow = trow + allcells.rows.Count() - 1; rcol = lcol + allcells.columns.Count() - 1; ## Check if there are real data if ((lcol == rcol) && (trow == brow)) if (isempty (toplftcl.Value)) trow = brow = lcol = rcol = 0; endif endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OCT_xlsx_getnmranges__.m0000644000000000000000000000013213226215407021371 xustar0030 mtime=1515789063.580155087 30 atime=1515789063.580155087 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OCT_xlsx_getnmranges__.m0000644000175000017500000000352313226215407021634 0ustar00olafolaf00000000000000## Copyright (C) 2015-2016 Andreas Weber ## Copyright (C) 2015-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} __OCT_getnmranges__ (@var{input1}, @var{input2}) ## ## @seealso{} ## @end deftypefn ## Author: Andreas Weber ## Created: 2015-09-18 function [nmranges] = __OCT_xlsx_getnmranges__ (xls) fid = fopen (fullfile (xls.workbook, "xl", "workbook.xml"), "r"); axml = fread (fid, Inf, "char=>char").'; fclose (fid); ## Get named range nodes [axml] = getxmlnode (axml, "definedNames", 1, 1); ## Preallocate nmranges = cell (numel (strfind (axml, "")), 4); en = 1; ## Loop over definedName for ii=1:size (nmranges, 1) [node, ~, en] = getxmlnode (axml, "definedName", en); ## Range name from attr nmranges{ii, 1} = getxmlattv (node, "name"); ## Range scope from attr. Postprocess later nmranges{ii, 4} = getxmlattv (node, "localSheetId"); ## Sheet and range (node contents) ref = getxmlnode (node, "definedName", 1, 1); ind = index (ref, "!"); nmranges{ii, 2} = ref(1:ind-1); nmranges{ii, 3} = strrep (ref(ind+1:end), "$", ""); endfor endfunction io-2.4.10/inst/private/PaxHeaders.5973/__POI_spsh_open__.m0000644000000000000000000000013213226215407020001 xustar0030 mtime=1515789063.592155322 30 atime=1515789063.592155322 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__POI_spsh_open__.m0000644000175000017500000000374613226215407020253 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## __POI_xlsopen__ - Internal function for opening an xls(x) file using Java/Apache POI ## Author: Philip Nienhuis ## Created: 2012-10-07 function [ xls, xlssupport, lastintf ] = __POI_spsh_open__ (xls, xwrite, filename, xlssupport, ftype, xlsinterfaces) ## Trick to detect Java file handle xlsin = 1.5; ## Get handle to workbook try if (xwrite > 2) if (ftype == 1) wb = javaObject ("org.apache.poi.hssf.usermodel.HSSFWorkbook"); elseif (ftype == 2) wb = javaObject ("org.apache.poi.xssf.usermodel.XSSFWorkbook"); endif xls.app = "new_POI"; else xlsin = javaObject ("java.io.FileInputStream", filename); wb = javaMethod ("create", ... "org.apache.poi.ss.usermodel.WorkbookFactory",... xlsin); xls.app = xlsin; endif xls.xtype = "POI"; xls.workbook = wb; xls.filename = filename; xlssupport += 2; lastintf = "POI"; catch if (! strcmp (class (xlsin), "double")) xlsin.close (); endif if (ftype == 1 && (xlsinterfaces.JXL || xlsinterfaces.UNO)) printf ... (["Couldn't open file %s using POI;\n" ... "trying Excel'95 format with JXL or UNO...\n"], filename); endif end_try_catch endfunction io-2.4.10/inst/private/PaxHeaders.5973/__JOD_chk_sprt__.m0000644000000000000000000000013213226215407017605 xustar0030 mtime=1515789063.568154851 30 atime=1515789063.568154851 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__JOD_chk_sprt__.m0000644000175000017500000000273613226215407020055 0ustar00olafolaf00000000000000## Copyright (C) 2014-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{varargout} =} __JOD_chk_sprt__ (@var{varargin}) ## Undocumented internal function ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2014-10-31 function [chk, missing6] = __JOD_chk_sprt__ (jcp, dbug=0) chk = 0; if (dbug > 1) printf ("\njOpenDocument (.ods + experimental .sxc readonly) :\n"); endif entries6 = {"jOpenDocument"}; [jpchk, missing6] = chk_jar_entries (jcp, entries6, dbug); missing6 = entries6 (find (missing6)); if (jpchk >= numel(entries6)) chk = 1; if (dbug > 1) printf (" => jOpenDocument (JOD) OK.\n"); endif elseif (dbug > 1) printf (" => Not all required classes (.jar) for JOD in classpath\n"); endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__POI_getnmranges__.m0000644000000000000000000000013213226215407020315 xustar0030 mtime=1515789063.588155243 30 atime=1515789063.588155243 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__POI_getnmranges__.m0000644000175000017500000000340613226215407020560 0ustar00olafolaf00000000000000## Copyright (C) 2015-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} __POI_getnmranges__ (@var{input1}, @var{input2}) ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2015-09-20 function [nmr] = __POI_getnmranges__ (xls) ii = 0; inmr = 0; nmr = cell (0, 3); ## Because there's no POI call to get all named ranges, we use a try-catch try while (ii < 1e5) ## Should suffice nm = xls.workbook.getNameAt (ii); ## If we get here, the name at index ii exists rg = nm.getRefersToFormula (); rg = strrep (rg(index (rg, "!") + 1:end), "$", ""); ## Check if looks like a range mtch = cell2mat (regexp (rg, ... '(^[A-Za-z]+[0-9]+){1}(:[A-Za-z]+[0-9]+$)?', "tokens")); if (! isempty (mtch) && strcmp ([mtch{:}], rg)) ## Yep, a range ++inmr; nmr{inmr, 1} = nm.getNameName (); nmr{inmr, 2} = nm.getSheetName (); nmr{inmr, 3} = rg; endif ++ii; endwhile catch end_try_catch endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OCT_ods_getnmranges__.m0000644000000000000000000000013213226215407021160 xustar0030 mtime=1515789063.580155087 30 atime=1515789063.576155008 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OCT_ods_getnmranges__.m0000644000175000017500000000333013226215407021417 0ustar00olafolaf00000000000000## Copyright (C) 2015-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} __OCT_ods_getnmranges__ (@var{input1}, @var{input2}) ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2015-09-19 function [nmr] = __OCT_ods_getnmranges__ (ods) fid = fopen (sprintf ("%s/content.xml", ods.workbook), "r"); rxml = fread (fid, Inf, "char=>char").'; fclose (fid); rxml = getxmlnode (rxml, "table:database-ranges", 1, 1); if (isempty (rxml)) nmr = cell (0, 3); return else nmr = cell (numel (strfind (rxml, "table:name=")), 3); en = 1; for ii=1:size (nmr, 1) [node, ~, en] = getxmlnode (rxml, "table:database-range", en); nmr{ii, 1} = getxmlattv (node, "table:name"); ref = getxmlattv (node, "table:target-range-address"); ref = reshape (strsplit (ref, {'.', ':'}), [], 2); nmr{ii, 2} = ref{1, 1}; nmr{ii, 3} = strjoin (ref(2, :), ':'); endfor endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__JOD_spsh_open__.m0000644000000000000000000000013213226215407017766 xustar0030 mtime=1515789063.572154929 30 atime=1515789063.568154851 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__JOD_spsh_open__.m0000644000175000017500000000453613226215407020236 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## __JOD_spsh_open ## Author: Philip Nienhuis ## Created: 2012-10-12 function [ ods, odssupport, lastintf ] = __JOD_spsh_open__ (ods, rw, filename, odssupport) file = javaObject ("java.io.File", filename); jopendoc = "org.jopendocument.dom.spreadsheet.SpreadSheet"; try if (rw > 2) ## Create an empty 2 x 2 default TableModel template tmodel= javaObject ("javax.swing.table.DefaultTableModel", 2, 2); wb = javaMethod ("createEmpty", jopendoc, tmodel); else wb = javaMethod ("createFromFile", jopendoc, file); endif ods.workbook = wb; ods.filename = filename; ods.xtype = "JOD"; ods.app = "file"; ## Check jOpenDocument version. This can only work here when a ## workbook has been opened. Empty sheets lead to NPE so try all sheets nr_of_sheets = ods.workbook.getSheetCount (); ii = 0; do try sh = ods.workbook.getSheet (ii); cl = sh.getCellAt (0, 0); catch ++ii; cl = 0; end_try_catch until (isjava (cl) || ii == nr_of_sheets) try cl.getFormula (); ods.odfvsn = 4; catch try # 1.2b3 has public getValueType () cl.getValueType (); ods.odfvsn = 3; catch # 1.2b2 has not ods.odfvsn = 2; printf ("NOTE: jOpenDocument v. 1.2b2 has limited functionality. Try upgrading to 1.4\n"); end_try_catch end_try_catch odssupport += 2; lastintf = "JOD"; catch error ("Couldn't open file %s using JOD", filename); end_try_catch endfunction io-2.4.10/inst/private/PaxHeaders.5973/spsh_chkrange.m0000644000000000000000000000013213226215407017317 xustar0030 mtime=1515789063.600155479 30 atime=1515789063.600155479 30 ctime=1515789065.028183488 io-2.4.10/inst/private/spsh_chkrange.m0000644000175000017500000000627513226215407017571 0ustar00olafolaf00000000000000## Copyright (C) 2010-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [ @var{topleftaddr}, @var{nrows}, @var{ncols}, @var{toprow}, @var{leftcol} ] = spsh_chkrange ( @var{range}, @var{rowsize}, @var{colsize}, @var{intf-type}, @var{filename}) ## (Internal function) Get and check various cell and range address parameters for spreadsheet input. ## ## spsh_chkrange should not be invoked directly but rather through oct2xls or oct2ods. ## ## Example: ## ## @example ## [tl, nrw, ncl, trw, lcl] = spsh_chkrange (crange, nr, nc, xtype, fileptr); ## @end example ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2010-08-02 function [ topleft, nrows, ncols, trow, lcol ] = spsh_chkrange (crange, nr, nc, intf, filename=[]) if (nargin == 4) ## File pointer input assumed if (isstruct (intf)) xtype = intf.xtype; filename = intf.filename; else error ("Too few or improper arguments supplied."); endif else ## Interface type & filename supplied xtype = intf; endif ## Define max row & column capacity from interface type & file suffix switch xtype case { 'COM', 'POI' } if (strcmpi (filename(end-3:end), '.xls')) ## BIFF5 & BIFF8 ROW_CAP = 65536; COL_CAP = 256; else ## OOXML (COM needs Excel 2007+ for this) ROW_CAP = 1048576; COL_CAP = 16384; endif case { 'JXL', 'OXS' } ## JExcelAPI & OpenXLS can only process BIFF5 & BIFF8 ROW_CAP = 65536; COL_CAP = 256; case { 'OTK', 'JOD' } ## ODS ROW_CAP = 65536; COL_CAP = 1024; case { 'UNO' } ## ODS; LibreOffice has a higher row capacity ## FIXME - use UNO calls to check physical row capacity ## FIXME - LibreOffice has higher row capacity but its Java classes haven't been updated ROW_CAP = 1048576; COL_CAP = 1024; otherwise error (sprintf ("Unknown interface type - %s\n", xtype)); endswitch if (isempty (deblank (crange))) trow = 1; lcol = 1; nrows = nr; ncols = nc; topleft = 'A1'; elseif (isempty (strfind (deblank (crange), ':'))) ## Only top left cell specified [topleft, dummy1, dummy2, trow, lcol] = parse_sp_range (crange); nrows = nr; ncols = nc; else [topleft, nrows, ncols, trow, lcol] = parse_sp_range (crange); endif if (trow > ROW_CAP || lcol > COL_CAP) error ("Topleft cell (%s) beyond spreadsheet limits."); endif ## Check spreadsheet capacity beyond requested topleft cell nrows = min (nrows, ROW_CAP - trow + 1); ncols = min (ncols, COL_CAP - lcol + 1); ## Check array size and requested range nrows = min (nrows, nr); ncols = min (ncols, nc); endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OCT_gnm_getnmranges__.m0000644000000000000000000000013213226215407021154 xustar0030 mtime=1515789063.576155008 30 atime=1515789063.576155008 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OCT_gnm_getnmranges__.m0000644000175000017500000000371413226215407021421 0ustar00olafolaf00000000000000## Copyright (C) 2015-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} __OCT_gnm_getnmranges__ (@var{input1}, @var{input2}) ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2015-09-19 function [nmr] = __OCT_gnm_getnmranges__ (xls) ## Read xml fid = fopen (xls.workbook, "r"); xml = fread (fid, Inf, "char=>char").'; fclose (fid); ## Get gnm:name nodes with value subnodes containing a range. ## Whitespace is a dummy token here pttrn = '(\w+)(\s*)([\$A-Z0-9:]+?)'; ## First workbook scope; that precedes first sheet nmr = reshape (cell2mat (regexp (xml(1:xls.sheets.shtidx(1)), pttrn, "tokens")), [], 3); if (! isempty (nmr)) nmr(:, 2) = repmat ("", size (nmr, 1), 1); else nmr = cell (0, 3); endif ## Next, for each sheet for ii=1:numel (xls.sheets.sh_names) st = xls.sheets.shtidx(ii); en = xls.sheets.shtidx(ii+1) - 1; names = reshape (cell2mat (regexp (xml(st:en), pttrn, "tokens")), [], 3); if (! isempty (names)) names(:, 2) = repmat (xls.sheets.sh_names{ii}, size (names, 1), 1); nmr = [nmr ; names]; endif endfor nmr(:, 3) = strrep (nmr(:, 3), "$", ""); endfunction io-2.4.10/inst/private/PaxHeaders.5973/__COM_spsh_info__.m0000644000000000000000000000013213226215407017762 xustar0030 mtime=1515789063.568154851 30 atime=1515789063.568154851 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__COM_spsh_info__.m0000644000175000017500000000312113226215407020217 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## __COM_spsh_info__ ## Author: Philip Nienhuis ## Created: 2012-10-12 function [sh_names] = __COM_spsh_info__ (xls) xlWorksheet = -4167; xlChart = 4; ## See if desired worksheet number or name exists sh_cnt = xls.workbook.Sheets.count; sh_names = cell (sh_cnt, 2); ws_cnt = 0; ch_cnt = 0; o_cnt = 0; for ii=1:sh_cnt sh_names(ii, 1) = xls.workbook.Sheets(ii).Name; if (xls.workbook.Sheets(ii).Type == xlWorksheet) [tr, lr, lc, rc] = getusedrange (xls, ++ws_cnt); if (tr) sh_names(ii, 2) = sprintf ... ("%s:%s", calccelladdress (tr, lc), calccelladdress (lr, rc)); else sh_names(ii, 2) = "Empty"; endif elseif (xls.workbook.Sheets(ii).Type == xlChart) sh_names(ii, 2) = sprintf ("Chart"); ++ch_cnt; else sh_names(ii, 2) = "Other_type"; ++o_cnt; endif endfor endfunction io-2.4.10/inst/private/PaxHeaders.5973/__COM_spsh_open__.m0000644000000000000000000000013213226215407017770 xustar0030 mtime=1515789063.568154851 30 atime=1515789063.568154851 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__COM_spsh_open__.m0000644000175000017500000000375213226215407020237 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## __COM_xlsopen.m__ - Internal function for opening an xls(x) file using COM/ActiveX ## Author: Philip Nienhuis ## Created: 2012-10-07 function [ xls, xlssupport, lastintf ] = __COM_spsh_open__ (xls, xwrite, filename, xlssupport) app = actxserver ("Excel.Application"); try ## Because Excel itself can still crash on file formats etc. app.Application.DisplayAlerts = 0; filename = make_absolute_filename (filename); if (xwrite < 2) ## Open workbook wb = app.Workbooks.Open (filename); elseif (xwrite > 2) ## Create a new workbook wb = app.Workbooks.Add (); ## Uncommenting the below statement can be useful in multi-user environments. ## Be sure to uncomment correspondig stanza in xlsclose to avoid zombie Excels ## wb.SaveAs (make_absolute_filename (strsplit (filename, filesep){end})); endif xls.app = app; xls.xtype = "COM"; xls.workbook = wb; xls.filename = filename; xlssupport += 1; lastintf = "COM"; catch warning ( sprintf ("ActiveX error trying to open or create file %s\n",... filename)); app.Application.DisplayAlerts = 1; app.Quit (); delete (app); end_try_catch endfunction io-2.4.10/inst/private/PaxHeaders.5973/__COM_spsh2oct__.m0000644000000000000000000000013213226215407017537 xustar0030 mtime=1515789063.564154773 30 atime=1515789063.564154773 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__COM_spsh2oct__.m0000644000175000017500000001062313226215407020001 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 P.R. Nienhuis ## parts Copyright (C) 2007 Michael Goffioul ## ## 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = __COM_spsh2oct__ (@var{xls}) ## @deftypefnx {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = __COM_spsh2oct__ (@var{xls}, @var{wsh}) ## @deftypefnx {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = __COM_spsh2oct__ (@var{xls}, @var{wsh}, @var{range}) ## @deftypefnx {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = __COM_spsh2oct__ (@var{xls}, @var{wsh}, @var{range}, @var{spsh_opts}) ## Get cell contents in @var{range} in worksheet @var{wsh} in an Excel ## file pointed to in struct @var{xls} into the cell array @var{obj}. ## ## __COM_spsh2oct__ should not be invoked directly but rather through xls2oct. ## ## Examples: ## ## @example ## [Arr, status, xls] = __COM_spsh2oct__ (xls, 'Second_sheet', 'B3:AY41'); ## Arr = __COM_spsh2oct__ (xls, 'Second_sheet'); ## @end example ## ## @seealso {xls2oct, oct2xls, xlsopen, xlsclose, xlsread, xlswrite} ## ## @end deftypefn ## Author: Philip Nienhuis ## Based on mat2xls by Michael Goffioul (2007) ## Created: 2009-09-23 function [rawarr, xls, rstatus ] = __COM_spsh2oct__ (xls, wsh, crange, spsh_opts) rstatus = 0; rawarr = {}; ## Basic checks if (nargin < 2) error ("__COM_spsh2oct__ needs a minimum of 2 arguments."); endif if (size (wsh, 2) > 31) warning ("Worksheet name too long - truncated\n") wsh = wsh(1:31); endif app = xls.app; wb = xls.workbook; ## Check to see if ActiveX is still alive try wb_cnt = wb.Worksheets.count; catch error ("ActiveX invocation in file ptr struct seems non-functional"); end_try_catch ## Check & get handle to requested worksheet wb_cnt = wb.Worksheets.count; old_sh = 0; if (isnumeric (wsh)) if (wsh < 1 || wsh > wb_cnt) errstr = sprintf ("Worksheet number: %d out of range 1-%d", wsh, wb_cnt); error (errstr) rstatus = 1; return else old_sh = wsh; endif else ## Find worksheet number corresponding to name in wsh wb_cnt = wb.Worksheets.count; for ii =1:wb_cnt sh_name = wb.Worksheets(ii).name; if (strcmp (sh_name, wsh)) old_sh = ii; endif endfor if (~old_sh) errstr = sprintf ("Worksheet name \"%s\" not present", wsh); error (errstr) else wsh = old_sh; endif endif sh = wb.Worksheets (wsh); nrows = 0; if ((nargin == 2) || (isempty (crange))) allcells = sh.UsedRange; ## Get actually used range indices [trow, brow, lcol, rcol] = getusedrange (xls, old_sh); if (trow == 0 && brow == 0) ## Empty sheet rawarr = {}; printf ("Worksheet '%s' contains no data\n", sh.Name); return; else nrows = brow - trow + 1; ncols = rcol - lcol + 1; topleft = calccelladdress (trow, lcol); lowerright = calccelladdress (brow, rcol); crange = [topleft ":" lowerright]; endif else ## Extract top_left_cell from range [topleft, nrows, ncols, trow, lcol] = parse_sp_range (crange); brow = trow + nrows - 1; rcol = lcol + ncols - 1; endif; if (nrows >= 1) ## Get object from Excel sheet, starting at cell top_left_cell rr = sh.Range (crange); if (spsh_opts.formulas_as_text) rawarr = rr.Formula; else rawarr = rr.Value; endif delete (rr); ## Take care of actual singe cell range if (isnumeric (rawarr) || ischar (rawarr)) rawarr = {rawarr}; endif ## If we get here, all seems to have gone OK rstatus = 1; ## Keep track of data rectangle limits xls.limits = [lcol, rcol; trow, brow]; else error ("No data read from Excel file"); rstatus = 0; endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OTK_spsh_info__.m0000644000000000000000000000013213226215407020001 xustar0030 mtime=1515789063.584155165 30 atime=1515789063.584155165 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OTK_spsh_info__.m0000644000175000017500000000350213226215407020241 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## __OTK_spsh_info__ ## Author: Philip Nienhuis ## Created: 2012-10-12 function [sh_names] = __OTK_spsh_info__ (ods) ## Get contents and table (= sheet) stuff from the workbook if (strcmp (ods.odfvsn, "0.8.7") || strfind (ods.odfvsn, "0.8.8")) xpath = ods.workbook.getXPath; else xpath = ods.app.getXPath; endif ## Create an instance of type NODESET for use in subsequent statement NODESET = __java_get__ ("javax.xml.xpath.XPathConstants", "NODESET"); ## Parse sheets ("tables") from ODS file sheets = xpath.evaluate ("//table:table", ods.workbook, NODESET); nr_of_sheets = sheets.getLength(); sh_names = cell (nr_of_sheets, 2); ## Get sheet names (& optionally data row count estimate) for ii=1:nr_of_sheets ## Check in first part of the sheet nodeset sh_names (ii) = sheets.item(ii-1).getTableNameAttribute (); [ tr, lr, lc, rc ] = getusedrange (ods, ii); if (tr) sh_names(ii, 2) = sprintf ("%s:%s", calccelladdress (tr, lc),... calccelladdress (lr, rc)); else sh_names(ii, 2) = "Empty"; endif endfor endfunction io-2.4.10/inst/private/PaxHeaders.5973/__COM_oct2spsh__.m0000644000000000000000000000013213226215407017537 xustar0030 mtime=1515789063.564154773 30 atime=1515789063.564154773 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__COM_oct2spsh__.m0000644000175000017500000001730213226215407020002 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [@var{xlso}, @var{status}] = __COM_oct2spsh__ (@var{obj}, @var{xlsi}) ## @deftypefnx {Function File} [@var{xlso}, @var{status}] = __COM_oct2spsh__ (@var{obj}, @var{xlsi}, @var{wsh}) ## @deftypefnx {Function File} [@var{xlso}, @var{status}] = __COM_oct2spsh__ (@var{obj}, @var{xlsi}, @var{wsh}, @var{top_left_cell}) ## Save matrix @var{obj} into worksheet @var{wsh} in Excel file pointed ## to in struct @var{xlsi}. All elements of @var{obj} are converted into ## Excel cells, starting at cell @var{top_left_cell}. Return argument ## @var{xlso} is @var{xlsi} with updated fields. ## ## __COM_oct2spsh__ should not be invoked directly but rather through oct2xls. ## ## Excel invocations may be left running invisibly in case of COM errors. ## ## Example: ## ## @example ## xls = __COM_oct2spsh__ (rand (10, 15), xls, 'Third_sheet', 'BF24'); ## @end example ## ## @seealso {oct2xls, xls2oct, xlsopen, xlsclose, xlswrite, xlsread, xls2com2oct} ## ## @end deftypefn ## Author: Philip Nienhuis ## (originally based on mat2xls by Michael Goffioul) ## Rewritten: 2009-09-26 function [ xls, status ] = __COM_oct2spsh__ (obj, xls, wsh, crange, spsh_opts) ## Preliminary sanity checks ## FIXME - Excel can write to much more than .xls/.xlsx (but not to all ## formats with multiple sheets): ## .wk1 .wk3 .wk4 .csv .pxl .html .dbf .txt .prn .wks .wq1 .dif if (! strfind (lower (xls.filename(end-4:end)), '.xls')) error ("COM interface can only write to Excel .xls or .xlsx files\n") endif if (isnumeric (wsh)) if (wsh < 1) error ("Illegal worksheet number: %i\n", wsh); endif elseif (size (wsh, 2) > 31) error ("Illegal worksheet name - too long\n") endif ## Check to see if ActiveX is still alive try wb_cnt = xls.workbook.Worksheets.count; catch error ("ActiveX invocation in file ptr struct seems non-functional\n"); end_try_catch ## define some constants not yet in __COM__.cc xlWorksheet = -4167; ## xlChart= 4; ## scratch vars status = 0; ## Parse date ranges [nr, nc] = size (obj); [topleft, nrows, ncols, trow, lcol] = ... spsh_chkrange (crange, nr, nc, xls.xtype, xls.filename); lowerright = calccelladdress (trow + nrows - 1, lcol + ncols - 1); crange = [topleft ":" lowerright]; if (nrows < nr || ncols < nc) warning ("Array truncated to fit in range\n"); obj = obj(1:nrows, 1:ncols); endif ## Cleanup NaNs. Find where they are and mark as empty ctype = [0 1 2 3 4]; ## Numeric Boolean Text Formula Empty typearr = spsh_prstype (obj, nrows, ncols, ctype, spsh_opts); ## Make cells now indicated to be empty, empty fptr = ! (4 * (ones (size (typearr))) .- typearr); obj(fptr) = cellfun (@(x) [], obj(fptr), "Uniformoutput", false); if (spsh_opts.formulas_as_text) ## find formulas (designated by a string starting with "=" and ending in ")") fptr = cellfun (@(x) ischar (x) && strncmp (x, "=", 1) ... && strncmp (x(end:end), ")", 1), obj); ## ... and add leading "'" character obj(fptr) = cellfun (@(x) ["'" x], obj(fptr), "Uniformoutput", false); endif clear fptr; if (xls.changed < 3) ## Existing file OR a new file with data added in a previous oct2xls call. ## Some involved investigation is needed to preserve ## existing data that shouldn't be touched. ## ## See if desired *sheet* name exists. old_sh = 0; ws_cnt = xls.workbook.Sheets.count; if (isnumeric (wsh)) if (wsh <= ws_cnt) ## Here we check for sheet *position* in the sheet stack ## rather than a name like "Sheet" old_sh = wsh; else ## wsh > nr of sheets; proposed new sheet name. ## This sheet name can already exist to the left in the sheet stack! shnm = sprintf ("Sheet%d", wsh); shnm1 = shnm; endif endif if (! old_sh) ## Check if the requested (or proposed) sheet already exists ## COM objects are not OO (yet?), so we need a WHILE loop ii = 1; jj = 1; while ((ii <= ws_cnt) && ! old_sh) ## Get existing sheet names one by one sh_name = xls.workbook.Sheets(ii).name; if (! isnumeric (wsh) && strcmp (sh_name, wsh)) ## ...and check with requested sheet *name*... old_sh = ii; elseif (isnumeric (wsh) && strcmp (sh_name, shnm)) ## ... or proposed new sheet name (corresp. to requested sheet *number*) shnm = [shnm "_"]; ii = 0; ## Also check if this new augmented sheet name exists... if (strcmp (shnm1, sh_name)), jj++; endif if (jj > 5) ## ... but not unlimited times... error (sprintf ... (" > 5 sheets named [_]Sheet%d already present!\n", wsh)); endif endif ++ii; endwhile endif if (old_sh) ## Requested sheet exists. Check if it is a *work*sheet if (! (xls.workbook.Sheets(old_sh).Type == xlWorksheet)) ## Error as you can't write data to Chart sheet error (sprintf ("Existing sheet '%s' is not type worksheet.\n", wsh)); else ## Simply point to the relevant sheet sh = xls.workbook.Worksheets (old_sh); endif else ## Add a new worksheet. Earlier it was checked whether this is safe try sh = xls.workbook.Worksheets.Add (); catch error (sprintf ("Cannot add new worksheet to file %s\n", xls.filename)); end_try_catch if (! isnumeric (wsh)) sh.Name = wsh; else sh.Name = shnm; printf ("Writing to worksheet %s\n", shnm); endif ## Prepare to move new sheet to right of the worksheet stack anyway ws_cnt = xls.workbook.Worksheets.count; ## New count needed ## Find where Excel has left it. We have to, depends on Excel version :-( ii = 1; while ((ii < ws_cnt+1) && ! strcmp (sh.Name, xls.workbook.Worksheets(ii).Name) == 1) ++ii; endwhile ## Excel can't move it beyond the current last one, so we need a trick. ## First move it to just before the last one.... xls.workbook.Worksheets(ii).Move (before = xls.workbook.Worksheets(ws_cnt)); ## ....then move the last one before the new sheet. xls.workbook.Worksheets (ws_cnt).Move (before = xls.workbook.Worksheets(ws_cnt - 1)); endif else ## The easy case: a new Excel file. Workbook was created in xlsopen. ## Delete empty non-used sheets, last one first xls.app.Application.DisplayAlerts = 0; ii = xls.workbook.Sheets.count; while (ii > 1) xls.workbook.Worksheets(ii).Delete(); --ii; endwhile xls.app.Application.DisplayAlerts = 1; ## Write to first worksheet: sh = xls.workbook.Worksheets (1); ## Rename the sheet if (isnumeric (wsh)) sh.Name = sprintf ("Sheet%i", wsh); else sh.Name = wsh; endif xls.changed = 2; ## 3 => 2 endif ## MG's original part. ## Save object in Excel sheet, starting at cell top_left_cell if (! isempty(obj)) r = sh.Range (crange); try r.Value = obj; catch error (sprintf ("Cannot add data to worksheet %s in file %s\n",... sh.Name, xls.filename)); end_try_catch delete (r); endif ## If we get here, all went OK status = 1; xls.changed = max (xls.changed, 1); ## If it was 2, preserve it. endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OTK_oct2ods__.m0000644000000000000000000000013213226215407017366 xustar0030 mtime=1515789063.580155087 30 atime=1515789063.580155087 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OTK_oct2ods__.m0000644000175000017500000004340113226215407017630 0ustar00olafolaf00000000000000## Copyright (C) 2010-2017 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 . ## __OTK_oct2ods__ ## write data array to an ODS spreadsheet using Java & ODFtoolkit 0.7.5 ## Note: __OTK_oct2spsh__ uses more recent odfdom that operates at higher level ## I'm truly sorry that oct2jotk2ods is so ridiculously complex, ## and therefore so slow; but there's a good reason for that: ## Writing to ODS is already fairly complicated when just making a ## new sheet ("table"); but it really becomes a headache when ## writing to an existing sheet. In that case one should beware of ## table-number-columns-repeated, table-number-rows-repeated, ## covered (merged) cells, incomplete tables and rows, etc. ## ODF toolkit v. 0.7.5 does nothing to hide this from the user; ## you may sort it out all by yourself. ## Author: Philip Nienhuis ## Created: 2010-01-07 function [ ods, rstatus ] = __OTK_oct2ods__ (c_arr, ods, wsh, crange, spsh_opts) persistent ctype; if (isempty (ctype)) ## Number, Boolean, String, Formula, Empty, Date, Time (last 2 are ignored) ctype = [1, 2, 3, 4, 5, 6, 7]; endif rstatus = 0; f_errs = 0; ## Get some basic spreadsheet data from the pointer using ODFtoolkit odfcont = ods.workbook; xpath = ods.app.getXPath (); offsprdsh = ods.app.getContentRoot(); autostyles = odfcont.getOrCreateAutomaticStyles(); officestyles = ods.app.getOrCreateDocumentStyles(); ## Create an instance of type NODESET for use in subsequent statements NODESET = __java_get__ ("javax.xml.xpath.XPathConstants", "NODESET"); ## Parse sheets ("tables") from ODS file sheets = xpath.evaluate ("//table:table", odfcont, NODESET); nr_of_sheets = sheets.getLength (); newsh = 0; ## Assume existing sheet if (isempty (wsh)) wsh = 1; endif if (! isnumeric (wsh)) ## Sheet name specified ## Search in sheet names, match sheet name to sheet number. ## Beware, 0-based index, 1-based count! ii = 0; while (++ii <= nr_of_sheets && ischar (wsh)) ## Look in first part of the sheet nodeset sh_name = sheets.item(ii-1).getTableNameAttribute (); if (strcmp (sh_name, wsh)) ## Convert local copy of wsh into a number (pointer) wsh = ii - 1; endif endwhile if (ischar (wsh) && nr_of_sheets < 256) newsh = 1; endif else ## Sheet index specified if ((ods.changed > 2) || (wsh > nr_of_sheets && wsh < 256)) ## Max nr of sheets = 256 ## Create a new sheet newsh = 1; elseif (wsh <=nr_of_sheets && wsh > 0) ## Existing sheet. Count = 1-based, index = 0-based --wsh; sh = sheets.item(wsh); printf ("Writing to sheet %s\n", sh.getTableNameAttribute()); else error ("oct2ods/xls: illegal sheet number."); endif endif ## Check size of data array & range / capacity of worksheet & prepare vars [nr, nc] = size (c_arr); [topleft, nrows, ncols, trow, lcol] = ... spsh_chkrange (crange, nr, nc, ods.xtype, ods.filename); --trow; --lcol; ## Zero-based row ## & col ## if (nrows < nr || ncols < nc) warning ("oct2ods/xls: array truncated to fit in range\n"); c_arr = c_arr(1:nrows, 1:ncols); endif ## Parse data array, setup typarr and throw out NaNs to speed up writing; typearr = spsh_prstype (c_arr, nrows, ncols, ctype, spsh_opts, 0); if (! spsh_opts.formulas_as_text) ## Find formulas (designated by a string starting with "=" and ending in ")") fptr = cellfun (@(x) ischar (x) && strncmp (x, "=", 1) ... && strncmp (x(end:end), ")", 1), c_arr); typearr(fptr) = ctype(4); ## FORMULA endif ## Prepare worksheet for writing. If needed create new sheet if (newsh) if (ods.changed > 2) ## New spreadsheet. Prepare to use the default 1x1 first sheet. sh = sheets.item(0); else ## Other sheets exist, create a new sheet. First the basics sh = javaObject ("org.odftoolkit.odfdom.doc.table.OdfTable", odfcont); ## Append sheet to spreadsheet ( contentRoot) offsprdsh.appendChild (sh); ## Rebuild sheets nodes sheets = xpath.evaluate ("//table:table", odfcont, NODESET); endif ## Sheet name if (isnumeric (wsh)) ## Give sheet a name str = sprintf ("Sheet%d", wsh); sh.setTableNameAttribute (str); else ## Assign name to sheet and change wsh into numeric pointer sh.setTableNameAttribute (wsh); wsh = sheets.getLength () - 1; endif ## Fixup wsh pointer in case of new spreadsheet if (ods.changed > 2) wsh = 0; endif ## Add table-column entry for style etc col = sh.addTableColumn (); col.setTableDefaultCellStyleNameAttribute ("Default"); col.setTableNumberColumnsRepeatedAttribute (lcol + ncols + 1); col.setTableStyleNameAttribute ("co1"); ## Build up the complete row & cell structure to cover the data array. ## This will speed up processing later ## 1. Build empty table row template row = javaObject ("org.odftoolkit.odfdom.doc.table.OdfTableRow", odfcont); ## Create an empty tablecell & append it to the row scell = javaObject ("org.odftoolkit.odfdom.doc.table.OdfTableCell", odfcont); scell = row.appendCell (scell); scell.setTableNumberColumnsRepeatedAttribute (1024); ## 2. If needed add empty filler row above the data rows & if needed add repeat count if (trow > 0) sh.appendRow (row); if (trow > 1) row.setTableNumberRowsRepeatedAttribute (trow); endif endif ## 3. Add data rows; first one serves as a template drow = javaObject ("org.odftoolkit.odfdom.doc.table.OdfTableRow", odfcont); if (lcol > 0) scell = javaObject ("org.odftoolkit.odfdom.doc.table.OdfTableCell", odfcont); drow.appendCell (scell); if (lcol > 1) scell.setTableNumberColumnsRepeatedAttribute (lcol); endif endif ## 4. Add data cell placeholders scell = javaObject ("org.odftoolkit.odfdom.doc.table.OdfTableCell", odfcont); drow.appendCell (scell); for jj=2:ncols dcell = scell.cloneNode (1); ## Deep copy drow.appendCell (dcell); endfor ## 5. Last cell is remaining column counter rest = max (1024 - lcol - ncols); if (rest) dcell = scell.cloneNode (1); ## Deep copy drow.appendCell (dcell); if (rest > 1) dcell.setTableNumberColumnsRepeatedAttribute (rest); endif endif ## Only now add drow as otherwise for each cell an empty table-column is ## inserted above the rows (odftoolkit bug?) sh.appendRow (drow); if (ods.changed > 2) ## In case of a completely new spreadsheet, delete the first initial 1-cell row ## But check if it *is* a row... try sh.removeChild (drow.getPreviousRow ()); catch ## Nothing. Apparently there was only the just appended row. end_try_catch endif ## 6. Row template ready. Copy row template down to cover future array for ii=2:nrows nrow = drow.cloneNode (1); ## Deep copy sh.appendRow (nrow); endfor ods.changed = min (ods.changed, 2); ## Keep 2 for new spshsht, 1 for existing + changed else ## Existing sheet. We must be prepared for all situations, incomplete rows, ## number-rows/columns-repeated, merged (spanning) cells, you name it. ## First explore row buildup of existing sheet using an XPath sh = sheets.item(wsh); ## 0 - based str = sprintf ("//table:table[%d]/table:table-row", wsh + 1); ## 1 - based trows = xpath.evaluate (str, odfcont, NODESET); nr_of_trows = trows.getLength(); ## Nr. of existing table-rows, not data rows! ## For the first rows we do some preprocessing here. Similar stuff for cells ## i.e. table-cells (columns) is done in the loops below. ## Make sure the upper data array row doesn't end up in a nr-rows-repeated row ## Provisionally! set start table-row in case "while" & "if" (split) are skipped drow = trows.item(0); rowcnt = 0; trowcnt = 0; ## Spreadsheet/ table-rows, resp; while (rowcnt < trow && trowcnt < nr_of_trows) ## Count rows & table-rows UNTIL we reach trow ++trowcnt; ## Nr of table-rows row = drow; drow = row.getNextSibling (); repcnt = row.getTableNumberRowsRepeatedAttribute(); rowcnt = rowcnt + repcnt; ## Nr of spreadsheet rows endwhile rsplit = rowcnt - trow; if (rsplit > 0) ## Apparently a nr-rows-repeated top table-row must be split, as the ## first data row seems to be projected in it (1st while condition above!) row.removeAttribute ("table:number-rows-repeated"); row.getCellAt (0).removeAttribute ("table:number-columns-repeated"); nrow = row.cloneNode (1); drow = nrow; ## Future upper data array row if (repcnt > 1) row.setTableNumberRowsRepeatedAttribute (repcnt - rsplit); else row.removeAttribute ("table:number-rows-repeated"); endif rrow = row.getNextSibling (); sh.insertBefore (nrow, rrow); for jj=2:rsplit nrow = nrow.cloneNode (1); sh.insertBefore (nrow, rrow); endfor elseif (rsplit < 0) ## New data rows to be added below existing data & table(!) rows, i.e. ## beyond lower end of the current sheet. Add filler row and 1st data row row = javaObject ("org.odftoolkit.odfdom.doc.table.OdfTableRow", odfcont); drow = row.cloneNode (1); ## First data row row.setTableNumberRowsRepeatedAttribute (-rsplit); ## Filler row scell = javaObject ("org.odftoolkit.odfdom.doc.table.OdfTableCell", odfcont); dcell = scell.cloneNode (1); scell.setTableNumberColumnsRepeatedAttribute (COL_CAP); ## Filler cell row.appendCell (scell); sh.appendRow (row); drow.appendCell (dcell); sh.appendRow (drow); endif endif ## For each row, for each cell, add the data. Expand row/column-repeated nodes row = drow; ## Start row; pointer still exists from above stanzas for ii=1:nrows if (! newsh) ## Only for existing sheets the next checks should be made ## While processing next data rows, fix table-rows if needed if (isempty (row) || (row.getLength () < 1)) ## Append an empty row with just one empty cell row = javaObject ("org.odftoolkit.odfdom.doc.table.OdfTableRow", odfcont); scell = javaObject ("org.odftoolkit.odfdom.doc.table.OdfTableCell", odfcont); scell.setTableNumberColumnsRepeatedAttribute (lcol + 1); row.appendCell (scell); sh.appendRow (row); else ## If needed expand nr-rows-repeated repcnt = row.getTableNumberRowsRepeatedAttribute (); if (repcnt > 1) row.removeAttribute ("table:number-rows-repeated"); ## Insert new table-rows above row until our new data space is complete. ## Keep handle of upper new table-row as that's where data are added 1st drow = row.cloneNode (1); sh.insertBefore (drow, row); for kk=1:min (repcnt, nrows-ii) nrow = row.cloneNode (1); sh.insertBefore (nrow, row); endfor if (repcnt > nrows-ii+1) row.setTableNumberRowsRepeatedAttribute (repcnt - nrows +ii - 1); endif row = drow; endif endif ## Check if leftmost cell ends up in nr-cols-repeated cell colcnt = 0; tcellcnt = 0; rcellcnt = row.getLength(); dcell = row.getCellAt (0); while (colcnt < lcol && tcellcnt < rcellcnt) ## Count columns UNTIL we hit lcol ++tcellcnt; ## Nr of table-cells counted scell = dcell; dcell = scell.getNextSibling (); repcnt = scell.getTableNumberColumnsRepeatedAttribute (); colcnt = colcnt + repcnt; ## Nr of spreadsheet cell counted endwhile csplit = colcnt - lcol; if (csplit > 0) ## Apparently a nr-columns-repeated cell must be split scell.removeAttribute ("table:number-columns-repeated"); ncell = scell.cloneNode (1); if (repcnt > 1) scell.setTableNumberColumnsRepeatedAttribute (repcnt - csplit); else scell.removeAttribute ("table:number-columns-repeated"); endif rcell = scell.getNextSibling (); row.insertBefore (ncell, rcell); for jj=2:csplit ncell = ncell.cloneNode (1); row.insertBefore (ncell, rcell); endfor elseif (csplit < 0) ## New cells to be added beyond current last cell & table-cell in row dcell = javaObject ("org.odftoolkit.odfdom.doc.table.OdfTableCell", odfcont); scell = dcell.cloneNode (1); dcell.setTableNumberColumnsRepeatedAttribute (-csplit); row.appendCell (dcell); row.appendCell (scell); endif endif ## Write a row of data from data array, column by column for jj=1:ncols scell = row.getCellAt (lcol + jj - 1); if (! newsh) if (isempty (scell)) ## Apparently end of row encountered. Add cell scell = javaObject ("org.odftoolkit.odfdom.doc.table.OdfTableCell", odfcont); scell = row.appendCell (scell); else ## If needed expand nr-cols-repeated repcnt = scell.getTableNumberColumnsRepeatedAttribute (); if (repcnt > 1) scell.removeAttribute ("table:number-columns-repeated"); for kk=2:repcnt ncell = scell.cloneNode (1); row.insertBefore (ncell, scell.getNextSibling ()); endfor endif endif ## Clear text contents while (scell.hasChildNodes ()) tmp = scell.getFirstChild (); scell.removeChild (tmp); endwhile scell.removeAttribute ("table:formula"); endif ## Empty cell count stuff done. At last we can add the data switch (typearr (ii, jj)) case 1 ## float scell.setOfficeValueTypeAttribute ("float"); scell.setOfficeValueAttribute (c_arr{ii, jj}); case 2 ## boolean ## Beware, for unpatched-for-booleans java-1.2.7- we must resort to floats try ## First try the preferred java-boolean way scell.setOfficeValueTypeAttribute ("boolean"); scell.removeAttribute ("office:value"); if (c_arr{ii, jj}) scell.setOfficeBooleanValueAttribute (1); else scell.setOfficeBooleanValueAttribute (0); endif catch ## Unpatched java package. Fall back to transferring a float scell.setOfficeValueTypeAttribute ("float"); if (c_arr{ii, jj}) scell.setOfficeValueAttribute (1); else scell.setOfficeValueAttribute (0); endif end_try_catch case 3 ## string scell.setOfficeValueTypeAttribute ("string"); pe = javaObject ("org.odftoolkit.odfdom.doc.text.OdfTextParagraph",... odfcont,"", c_arr{ii, jj}); scell.appendChild (pe); case 4 ## Formula. ## As we don't know the result type, simply remove previous type info. ## Once OOo Calc reads it, it'll add the missing attributes scell.removeAttribute ("office:value"); scell.removeAttribute ("office:value-type"); ## Try-catch not strictly needed, there's no formula validator yet try scell.setTableFormulaAttribute (c_arr{ii, jj}); scell.setOfficeValueTypeAttribute ("string"); pe = javaObject ("org.odftoolkit.odfdom.doc.text.OdfTextParagraph",... odfcont,"", "##Recalc Formula##"); scell.appendChild (pe); catch ++f_errs; scell.setOfficeValueTypeAttribute ("string"); pe = javaObject ("org.odftoolkit.odfdom.doc.text.OdfTextParagraph",... odfcont,"", c_arr{ii, jj}); scell.appendChild (pe); end_try_catch case {0 5} ## Empty. Clear value attributes if (! newsh) scell.removeAttribute ("office:value-type"); scell.removeAttribute ("office:value"); endif case 6 ## Date (implemented but Octave has no "date" data type - yet?) scell.setOfficeValueTypeAttribute ("date"); [hh mo dd hh mi ss] = datevec (c_arr{ii,jj}); str = sprintf ("%4d-%2d-%2dT%2d:%2d:%2d", yy, mo, dd, hh, mi, ss); scell.setOfficeDateValueAttribute (str); case 7 ## Time (implemented but Octave has no "time" data type) scell.setOfficeValueTypeAttribute ("time"); [hh mo dd hh mi ss] = datevec (c_arr{ii,jj}); str = sprintf ("PT%2d:%2d:%2d", hh, mi, ss); scell.setOfficeTimeValuettribute (str); otherwise ## Nothing endswitch scell = scell.getNextSibling (); endfor row = row.getNextSibling (); endfor if (f_errs) printf ("%d formula errors encountered - please check input array\n", f_errs); endif ods.changed = max (min (ods.changed, 2), changed); ## Preserve 2 (new file), 1 (existing) rstatus = 1; endfunction io-2.4.10/inst/private/PaxHeaders.5973/__JOD_spsh_close__.m0000644000000000000000000000013213226215407020132 xustar0030 mtime=1515789063.568154851 30 atime=1515789063.568154851 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__JOD_spsh_close__.m0000644000175000017500000000233713226215407020377 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## __JOD_spsh_close__ - internal function: close a spreadsheet file using JOD ## Author: Philip Nienhuis ## Created: 2012-10-12 function [ ods ] = __JOD_spsh_close__ (ods) try if (ods.changed && ods.changed < 3) if (isfield (ods, "nfilename")) ofile = javaObject ("java.io.File", ods.nfilename); else ofile = javaObject ("java.io.File", ods.filename); endif ods.workbook.saveAs (ofile); ods.changed = 0; endif catch end_try_catch endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OCT_oct2xlsx__.m0000644000000000000000000000013213226215407017567 xustar0030 mtime=1515789063.576155008 30 atime=1515789063.576155008 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OCT_oct2xlsx__.m0000644000175000017500000005055513226215407020041 0ustar00olafolaf00000000000000## Copyright (C) 2013,2014 Markus Bergholz ## Parts Copyright (C) 2014-2017 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 . ## -*- texinfo -*- ## xlsxwrite function pure written in octave - no dependencies are needed. ## tested with MS Excel 2010, Gnumeric, LibreOffice 4.x ## ## usage: ## __OCT_oct2xlsx__(filename, matrix, wsh, range, spsh_opts) ## @end deftypefn ## Author: Markus Bergholz ## Amended by Philip Nienhuis ## 2013/11/08 - Initial Release function [xls, rstatus] = __OCT_oct2xlsx__ (arrdat, xls, wsh=1, crange="", spsh_opts, obj_dims) ## Analyze worksheet parameter & determine if new sheet is required new_sh = 0; if (xls.changed == 3) ## Pristine spreadsheet file new_sh = 1; ## Replace default sheet name if (ischar (wsh)) wsh_string = xls.sheets.sh_names(1) = wsh; elseif (isnumeric (wsh)) wsh_string = xls.sheets.sh_names(1) = sprintf ("Sheet%d", wsh); endif wsh_number = 1; elseif (ischar (wsh)) if (length (wsh) > 31) error ("Worksheet name longer than 31 characters is not supported by Excel\n"); endif wsh_number = find (strcmp (wsh, xls.sheets.sh_names)); if (isempty (wsh_number)) ## Worksheet not in stack; create a new sheet new_sh = 1; wsh_number = numel (xls.sheets.sh_names) + 1; xls.sheets.sh_names(end+1) = wsh; endif wsh_string = wsh; elseif (isnumeric (wsh)) if (wsh > numel (xls.sheets.sh_names)) ## New worksheet new_sh = 1; ## Default sheet name wsh_string = sprintf ("Sheet%d", wsh); ## Name may already be in use... append underscores while (! isempty (find (strcmp (wsh_string, xls.sheets.sh_names))) && ... length (wsh_string <= 31)) wsh_string = strrep (wsh_string, "Sheet", "Sheet_"); endwhile if (length (wsh_string) > 31) error ("oct2xls: cannot add worksheet with a unique name\n"); endif ## The sheet index number can't leave a gap in the stack, so: wsh_number = numel (xls.sheets.sh_names) + 1; xls.sheets.sh_names(end+1) = wsh_string; else wsh_number = wsh; endif endif if (new_sh) rawarr = {}; lims = []; else ## Get all data in sheet and row/column limits [rawarr, xls] = __OCT_xlsx2oct__ (xls, wsh, "", spsh_opts); lims = xls.limits; endif ## Merge old and new data. Provisionally allow empty new data to wipe old data [rawarr, lims, onr, onc] = __OCT_merge_data__ (rawarr, lims, arrdat, obj_dims); ## What needs to be done: ## - Find out worksheet number (easy, wsh_number). Relates 1:1 to rId ## - Write data to /xl/worksheets/sheet.xml ## * For each string, check (persistent var) if sharedStrings.xml exists ## > If not, create it. ## * For each string check if it is in /sharedStrings.xml ## > if YES, put pointer in new worksheet ## > if NO, add node in sharedStrings.xml and pointer in new worksheet ## - If needed (new file) update /workbook.xml w. sheet name & a sheetId ## higher than any existing sheetId ## - Update workbook.xml.rels ## Write data to worksheet file. If status > 1, new sharedStrings file entries are required [xls, status] = __OCT_oct2xlsx_sh__ (xls, wsh_number, rawarr, lims, onc, onr, spsh_opts); ## Update worksheet bookkeeping for new sheets only if (new_sh) ## Add worksheet entry in several xml files ## === Read xl/_rels/workbook.xml.rels === rid = fopen ([xls.workbook filesep "xl" filesep "_rels" filesep "workbook.xml.rels"], "r+"); rxml = fread (rid, Inf, "char=>char").'; fclose (rid); ## Get rId's ((worksheet number in stack, needed in [Content_Types].xml) rId = str2double (cell2mat (regexp (rxml, 'Id="rId(\d+)"', "tokens"))); ## === Read xl/workbook.xml === wid = fopen ([xls.workbook filesep "xl" filesep "workbook.xml"], "r+"); wxml = fread (wid, Inf, "char=>char").'; fclose (wid); ## Get sheetId's [sheets, is, ie] = getxmlnode (wxml, "sheets"); sheetids = str2double (cell2mat (regexp (sheets, ' sheetId="(\d+?)"', "tokens"))); ## new rId must be nr of sheets + 1. rId's (>nwrId) are bumped +1 below nwrId = numel (sheetids) + 1; xls.sheets.rid(nwrId) = nwrId; if (xls.changed == 3) ## New file from template. No new sheet, just update Sheet1 name shnum = 1; sheets = strrep (sheets, 'name="Sheet1"', ['name="' wsh_string '"']); else ## Add a new sheet entry shnum = max (sheetids) + 1; wshtag = sprintf ('', ... wsh_string, shnum, nwrId); sheets = regexprep (sheets, '/>\s*', ["/>" wshtag ""]); xls.sheets.sheetid(end+1) = shnum; endif ## Re(/over-)write workbook.xml; start at sheets node wid = fopen ([xls.workbook filesep "xl" filesep "workbook.xml"], "w+"); fprintf (wid, "%s", wxml(1:is-1)); fprintf (wid, "%s", sheets); fprintf (wid, "%s", wxml(ie+1:end)); fclose (wid); ## === End of xl/workbook.xml & wxml === ## Write xl/_rels/workbook.xml.rels & [Content_Types].xml ## Only needed for new sheets in existing files if (xls.changed != 3) ## Find highest worksheet nr in nodes, add one and shift all the rest up is = iel = 0; for ii=1:numel (rId) ## Get next Relationship node. Worksheets usually come first [relshp, is, ie] = getxmlnode (rxml, "Relationship", is+1); if (rId(ii) >= shnum) ## rId needs to be bumped relshp = regexprep (relshp, 'Id="rId(\d+)"', ... ['Id="rId' sprintf("%d", rId(ii)+1) '"']); ## Insert new node back into rxml rxml = [rxml(1:is-1) relshp rxml(ie+1:end)]; else ## Remember end pos of last worksheet node iel = ie; endif if (rId(ii) == shnum) ## Insert new node entry = sprintf ('', nwrId, shnum); endif endfor rxml = [rxml(1:iel) entry rxml(iel+1:end)]; ## Rewrite xl/_rels/workbook.xml.rels rid = fopen ([xls.workbook filesep "xl" filesep "_rels" filesep "workbook.xml.rels"], "w"); fprintf (rid, "%s", rxml); fclose (rid); ## === End of xl/_rels/worksbook.xml.rels & rxml === ## === [Content_Types].xml. === ## Merely insert a worksheet #n entry (#n = nwrId) tid = fopen ([xls.workbook filesep "[Content_Types].xml"], "r+"); txml = fread (tid, Inf, "char=>char").'; fclose (tid); ## Prepare new partname node. Its stack pos = nwrId partname = ['' ]; partname = sprintf (partname, nwrId); ## Find last worksheet node & insert new node srchstr = 'worksheet+xml"/>'; ipos = strfind (txml, srchstr)(end) + length (srchstr); tid = fopen ([xls.workbook filesep "[Content_Types].xml"], "w"); fprintf (tid, "%s", txml(1:ipos-1)); fprintf (tid, partname); fprintf (tid, txml(ipos:end)); fclose (tid); endif ## === End of [Content_Types].xml & txml === ## === === aid = fopen ([xls.workbook filesep "docProps" filesep "app.xml"], "r+"); axml = fread (aid, Inf, "char=>char").'; fclose (aid); wshnode = sprintf ('%s', wsh_string); if (xls.changed == 3) [vt, is, ie] = getxmlnode (axml, "TitlesOfParts"); ## Just replace Sheet1 entry by new name vt = strrep (vt, '>Sheet1<', ['>' wsh_string '<']); else ## 1. Update HeadingPairs node [vt1, is, ie] = getxmlnode (axml, "HeadingPairs"); ## Bump number of entries nshts = str2double (getxmlnode (vt1, "vt:i4", [], 1)) + 1; vt1 = regexprep (vt1, '(\d+)', ["" sprintf("%d", nshts) ""]); ## 2. Update TitlesOfParts node [vt2, ~, ie] = getxmlnode (axml, "TitlesOfParts", ie); ## Bump number of entries nshts = str2double (getxmlattv (vt2, "size")) + 1; vt2 = regexprep (vt2, 'size="(\d+)"', ['size="' sprintf("%d", nshts) '"']); ## Add new worksheet entry vt2 = regexprep (vt2, "\s*", ["" wshnode ""]); vt = [vt1 vt2]; endif ## Re(/over-)write apps.xml aid = fopen ([xls.workbook filesep "docProps" filesep "app.xml"], "w+"); fprintf (aid, "%s", axml(1:is-1)); fprintf (aid, "%s", vt); fprintf (aid, "%s", axml(ie+1:end)); fclose (aid); endif ## === End of docProps/app.xml & axml === ## If needed update sharedStrings entries xml descriptor files if (status > 1) ## workbook_rels.xml rid = fopen ([xls.workbook filesep "xl" filesep "_rels" filesep "workbook.xml.rels"], "r+"); rxml = fread (rid, Inf, "char=>char").'; fclose (rid); if (isempty (strfind (rxml, "sharedStrings"))) ## Add sharedStrings.xml entry. First find unique rId rId = str2double (cell2mat (regexp (rxml, 'Id="rId(\d+)"', "tokens"))); nwrId = sort (rId)(end) + 1; entry = sprintf ('', nwrId); rxml = regexprep (rxml, '/>\s*', ["/>" entry ""]); rid = fopen ([xls.workbook filesep "xl" filesep "_rels" filesep "workbook.xml.rels"], "w"); fprintf (rid, "%s", rxml); fclose (rid); endif endif if (status > 1) ## Check [Content_Types].xml for SharedStrings entry tid = fopen ([xls.workbook filesep "[Content_Types].xml"], "r+"); txml = fread (tid, Inf, "char=>char").'; fclose (tid); if (isempty (strfind (txml, "sharedStrings"))) ## Add sharedStrings.xml entry after styles.xml node. First find that one [~, ~, ipos] = regexp (txml, '(?:styles\+xml)(?:.+)(>' ... txml(ipos+1:end)]; tid = fopen ([xls.workbook filesep "[Content_Types].xml"], "w"); fprintf (tid, "%s", txml); fclose (tid); endif endif ## === /docProps/core.xml (user/modifier info & date/time) === cid = fopen ([xls.workbook filesep "docProps" filesep "core.xml"], "r+"); cxml = fread (cid, Inf, "char=>char").'; fclose (cid); cxml = regexprep (cxml, 'dBy>(\w+)GNU Octave"); cxml = [ cxml(1:ia-1) '2015-09-10T19:53:40Z<' cxml(ib+1:end) ]; [modf, ia, ib] = getxmlnode (cxml, "dcterms:modified", [], 1); endif cxml = [cxml(1:ia-1) strrep(cxml(ia:ib), modf, modtime) cxml(ib+1:end)]; cid = fopen ([xls.workbook filesep "docProps" filesep "core.xml"], "w+"); fprintf (cid, "%s", cxml); fclose (cid); ## === End of docProps/core.xml & cxml === ## Update status xls.changed = max (xls.changed-1, 1); rstatus = 1; endfunction function [ xls, rstatus ] = __OCT_oct2xlsx_sh__ (xls, wsh_number, arrdat, lims, onc, onr, spsh_opts) ## Open sheet file (new or old), will be overwritten fid = fopen ([xls.workbook filesep "xl" filesep "worksheets" filesep ... sprintf("sheet%d.xml", wsh_number)], "r+"); if (fid < 0) ## Apparently a new sheet. Fill in default xml contents xml = ''; xml = [ xml "\n" ]; xml = [ xml '' ]; xml = [ xml '' ]; xml = [ xml '' ]; xml = [ xml '']; xml = [ xml '']; xml = [ xml '' ]; else ## Read complete contents xml = fread (fid, Inf, "char=>char").'; fclose (fid); endif ## Update "dimension" (=range) node [dimnode, is1, ie1] = getxmlnode (xml, "dimension"); ## Compute new limits rng = sprintf ("%s:%s", calccelladdress (lims(2, 1), lims(1, 1)), ... calccelladdress (lims(2, 2), lims(1, 2))); ## Open sheet file (new or old) in reset mode, write first part of worksheet fid = fopen ([xls.workbook filesep "xl" filesep "worksheets" filesep ... sprintf("sheet%d.xml", wsh_number)], "w+"); fprintf (fid, "%s", xml(1:is1-1)); ## Write updated dimension node fprintf (fid, '', rng); ## Get Sheetdata node [shtdata, is2, ie2] = getxmlnode (xml, "sheetData"); ## Write second block of xml until start of sheetData fprintf (fid, "%s", [xml(ie1+1:is2-1) ""]); ## Explore data types in arrdat typearr = spsh_prstype (arrdat, onr, onc, [1:5], spsh_opts); if (all (typearr(:) == 1)) ## Numeric for r=1:rows (arrdat) fprintf (fid, '', ... r+lims(2, 1)-1, ... lims(1, 1), lims(1, 2)); for c = 1:columns (arrdat) if (0 == isnan (arrdat{r, c})) fprintf (fid, sprintf ('%0.15g', ... num2col (c+lims(1, 1)-1), r+lims(2, 1)-1, arrdat{r, c})); endif endfor fprintf (fid, ''); endfor else ## Heterogeneous array. Write cell nodes depending on content i_tatt = []; strings = {}; str_cnt = uniq_str_cnt = 0; ## Check if there are any strings if (any (typearr(:) == 3)) ## Yep. Read sharedStrings.xml try sid = fopen (sprintf ("%s/xl/sharedStrings.xml", xls.workbook), "r+"); if (sid > 0) ## File exists => there are already some strings in the sheet shstr = fread (sid, "char=>char").'; fclose (sid); ## Extract string values. May be much more than present in current sheet. ## A two-step procedure is required to preserve empty strings ("") strings = cell2mat (regexp (shstr, ']*>(.*?)', "tokens")); strings = regexprep (strings, '(^|^|$)', ""); ## Take care of strings with ', "tokens"))); ## Watch out for a rare corner case: just one empty string... (avoid []) if (isempty (strings)) strings = {""}; endif sst = getxmlnode (shstr, "sst", 1); uniq_str_cnt = str2double (getxmlattv (sst, "uniqueCount")); clear sst; ## Make shstr a numeric value shstr = 1; else ## File didn't exist yet shstr = 0; endif catch ## No sharedStrings.xml; implies no "fixed" strings (computed strings can still be there) strings = {}; str_cnt = uniq_str_cnt = 0; end_try_catch endif ## Process data row by row for ii=1:rows (arrdat) ## Row node opening tag fprintf (fid, '', ii+lims(2, 1)-1, lims(1, 1), lims(1, 2)); for jj=1:columns (arrdat) ## Ignore empty values if (! isempty (arrdat{ii, jj})) ## Init required attributes. Note leading space addr = sprintf (' r="%s"', calccelladdress (ii+lims(2, 1)-1, jj+lims(1, 1)-1)); ## Init optional atttributes stag = ttag = form = ""; ## t: e = error, b = boolean, s/str = string ## n = numeric switch typearr(ii, jj) case 1 ## Numeric ## t tag ("type") is omitted for numeric data ??? ttag = ' t="n"'; val = ["" (sprintf ("%0.15g", arrdat{ii, jj})) ""]; case 2 ## Boolean ttag = ' t="b"'; if (arrdat{ii, jj}) val = ["1"]; else val = ["0"]; endif case 3 ## String ttag = ' t="s"'; ## FIXME s value provisionally set to 0 sptr = find (strcmp (arrdat{ii, jj}, strings)); if (isempty (sptr)) ## Add new string strings = [strings arrdat{ii, jj}]; ++uniq_str_cnt; ## New pointer into sharedStrings (0-based) sptr = uniq_str_cnt; endif ## Val must be pointer (0-based) into sharedStrings.xml val = sprintf ("%d", sptr - 1); ++str_cnt; case 4 ## Formula form = sprintf ("%s", arrdat{ii, jj}(2:end)); #val = "?"; val = " "; otherwise ## (includes "case 5" ## Empty value. Clear address addr = ''; endswitch ## Append node to file, include tags if (! isempty (addr)) fprintf (fid, '', addr, stag, ttag); if (! isempty (val)) fprintf (fid, "%s%s", form, val); endif fprintf (fid, ""); endif endif endfor fprintf (fid, ''); endfor endif ## Closing tag fprintf (fid, ""); ## Append rest of original xml to file and close it fprintf (fid, "%s", xml(ie2+1:end)); fclose (fid); rstatus = 1; ## Rewrite sharedStrings.xml, if required if (any (typearr(:) == 3) && ! isempty (strings)) ## Apparently something to write if (uniq_str_cnt == 1 && isempty (strings{1})) ## Avoid writing sharedStrings file for just one empty string entry return endif ## (Re-)write xl/sharedStrings.xml sid = fopen (sprintf ("%s/xl/sharedStrings.xml", xls.workbook), "w+"); fprintf (sid, '\n'); fprintf (sid, '', ... str_cnt, uniq_str_cnt); for ii=1:uniq_str_cnt if (ismember (ii, i_tatt)) ## Invoke original %s", strings{ii}); else fprintf (sid, "%s", strings{ii}); endif endfor fprintf (sid, ""); fclose (sid); ## Check if new sharedStrings file entries are required if (isnumeric (shstr) && (! shstr)) rstatus = 2; return; endif endif ## Return endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OXS_getusedrange__.m0000644000000000000000000000013213226215407020502 xustar0030 mtime=1515789063.584155165 30 atime=1515789063.584155165 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OXS_getusedrange__.m0000644000175000017500000000243613226215407020747 0ustar00olafolaf00000000000000## Copyright (C) 2010-2017 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 . ## __OXS_getusedrange__ ## Author: Philip ## Created: 2011-06-13 function [ trow, brow, lcol, rcol ] = __OXS_getusedrange__ (xls, wsh) sh = xls.workbook.getWorkSheet (wsh - 1); try ## Intriguing: sh.getFirst<> is off by one, sh.getLast<> = OK.... 8-Z trow = sh.getFirstRow () + 1; brow = sh.getLastRow (); lcol = sh.getFirstCol () + 1; rcol = sh.getLastCol (); catch ## Might be an empty sheet trow = brow = lcol = rcol = 0; end_try_catch ## Check for empty sheet if ((trow > brow) || (lcol > rcol)) trow = brow = lcol = rcol = 0; endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OTK_getusedrange__.m0000644000000000000000000000013213226215407020466 xustar0030 mtime=1515789063.580155087 30 atime=1515789063.580155087 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OTK_getusedrange__.m0000644000175000017500000000744513226215407020740 0ustar00olafolaf00000000000000## Copyright (C) 2010-2017 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 . ## __OTK_getusedrange__ - get used range from ODS spreadsheet using ODF Toolkit ## Author: Philip Nienhuis ## Created: 2010-03-18 (First usable version) function [ trow, lrow, lcol, rcol ] = __OTK_getusedrange__ (ods, ii) odfcont = ods.workbook; ## Local copy just in case if (isfield (ods, "odfvsn")) if (strcmp (ods.odfvsn, "0.8.6") || strcmp (ods.odfvsn, "0.7.5")) xpath = ods.app.getXPath; else ## API changed in odfdom-0.8.7 xpath = ods.workbook.getXPath; endif else error ("ODS file ptr struct for OTK interface seems broken."); endif ## Create an instance of type NODESET for use in subsequent statement NODESET = __java_get__ ("javax.xml.xpath.XPathConstants", "NODESET"); ## Get table-rows in sheet no. wsh. Sheet count = 1-based (!) str = sprintf ("//table:table[%d]/table:table-row", ii); sh = xpath.evaluate (str, odfcont, NODESET); nr_of_trows = sh.getLength(); jj = 0; ## Table row counter trow = 0; drows = 0; ## Top data row, actual data row range nrows = 0; reprows = 0; ## Scratch counter rcol = 0; lcol = 1024; ## Rightmost and leftmost data column while jj < nr_of_trows row = sh.item(jj); ## Check for data rows rw_char = char (row) (1:min(500, length (char (row)))); if (findstr ("office:value-type", rw_char) || findstr (" attribute when writing strings ##if (isempty (findstr ("office:value-type", cl_char)) ... ## || isempty (findstr (". ## __OTK_spsh2oct__: internal function for reading odf files using odfdom-0.8.6+ ## Author: Philip Nienhuis ## Created: 2010-08-24. First workable version Aug 27, 2010 function [ rawarr, ods, rstatus ] = __OTK_spsh2oct__ (ods, wsh, crange, spsh_opts) rstatus = 0; ## Get contents and table stuff from the workbook odfcont = ods.workbook; ## Use a local copy just to be sure. octave ## makes physical copies only when needed (?) ## Parse sheets ("tables") from ODS file sheets = ods.app.getTableList(); nr_of_sheets = sheets.size (); ## Check user input & find sheet pointer (1-based) if (! isnumeric (wsh)) try sh = ods.app.getTableByName (wsh); sh_err = isempty (sh); catch sh_err = 1; end_try_catch if (sh_err) error (sprintf ("oct2ods/xls: sheet %s not found in file %s\n", wsh, ods.filename)); endif elseif (wsh > nr_of_sheets || wsh < 1) ## We already have a numeric sheet pointer. If it's not in range: error (sprintf ("oct2ods/xls: worksheet no. %d out of range (1 - %d)", wsh, nr_of_sheets)); else sh = sheets.get (wsh - 1); endif ## Either parse (given cell range) or prepare (unknown range) help variables if (isempty (crange)) if (! isnumeric (wsh)) ## Get sheet index jj = nr_of_sheets; while (jj-- >= 0) if (strcmp (wsh, sheets.get(jj).getTableName()) == 1) wsh = jj +1; jj = -1; endif endwhile endif [ trow, brow, lcol, rcol ] = getusedrange (ods, wsh); nrows = brow - trow + 1; ## Number of rows to be read ncols = rcol - lcol + 1; ## Number of columns to be read else [dummy, nrows, ncols, trow, lcol] = parse_sp_range (crange); ## Check ODS row/column limits if (lcol > 1024 || trow > 65536) error ("ods2oct/xls: invalid range; max 1024 columns & 65536 rows\n"); endif ## Truncate range silently if needed rcol = min (lcol + ncols - 1, 1024); ncols = min (ncols, 1024 - lcol + 1); nrows = min (nrows, 65536 - trow + 1); brow = trow + nrows - 1; endif ## Create storage for data content rawarr = cell (nrows, ncols); ## Read from worksheet row by row. Row numbers are 0-based for ii=trow:nrows+trow-1 row = sh.getRowByIndex (ii-1); for jj=lcol:ncols+lcol-1; ocell = row.getCellByIndex (jj-1); if (! isempty (ocell)) ## A little workaround as OTK doesn't recognize formula cells if (spsh_opts.formulas_as_text && ! isempty (ocell.getFormula ())) otype = "formula"; else otype = ocell.getValueType (); endif if (! isempty (otype)) otype = deblank (tolower (otype)); ## At last, read the data switch otype case {"float", "currency", "percentage"} rawarr(ii-trow+1, jj-lcol+1) = ocell.getDoubleValue (); case "date" ## Dive into TableTable API tvalue = ocell.getOdfElement ().getOfficeDateValueAttribute (); ## Dates are returned as octave datenums, i.e. 0-0-0000 based yr = str2num (tvalue(1:4)); mo = str2num (tvalue(6:7)); dy = str2num (tvalue(9:10)); if (index (tvalue, "T")) hh = str2num (tvalue(12:13)); mm = str2num (tvalue(15:16)); ss = str2num (tvalue(18:19)); rawarr(ii-trow+1, jj-lcol+1) = datenum (yr, mo, dy, hh, mm, ss); else rawarr(ii-trow+1, jj-lcol+1) = datenum (yr, mo, dy); endif case "time" ## Dive into TableTable API tvalue = ocell.getOdfElement ().getOfficeTimeValueAttribute (); if (index (tvalue, "PT")) hh = str2num (tvalue(3:4)); mm = str2num (tvalue(6:7)); ss = str2num (tvalue(9:10)); rawarr(ii-trow+1, jj-lcol+1) = datenum (0, 0, 0, hh, mm, ss); endif case "boolean" rawarr(ii-trow+1, jj-lcol+1) = ocell.getBooleanValue (); case "string" rawarr(ii-trow+1, jj-lcol+1) = ocell.getStringValue (); case "formula" form = ocell.getFormula (); ## If form doesn't start with "=", pimp ranges in formulas if (form(1) != "=") form = regexprep (form(4:end), '\[\.(\w+)\]', '$1'); form = regexprep (form, '\[\.(\w+):', '$1:'); form = regexprep (form, ':\.(\w+)\]', ':$1'); endif rawarr(ii-trow+1, jj-lcol+1) = form; otherwise ## Nothing. endswitch endif endif endfor endfor ## Keep track of data rectangle limits ods.limits = [lcol, rcol; trow, brow]; rstatus = 1; endfunction io-2.4.10/inst/private/PaxHeaders.5973/__POI_spsh_close__.m0000644000000000000000000000013213226215407020145 xustar0030 mtime=1515789063.588155243 30 atime=1515789063.588155243 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__POI_spsh_close__.m0000644000175000017500000000277013226215407020413 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## __POI_spsh_close__ - internal function: close a spreadsheet file using POI ## Author: Philip Nienhuis ## Created: 2012-10-12 function [ xls ] = __POI_spsh_close__ (xls) # Tric to detect xlsout as a Java object xlsout = 1.5; if (xls.changed > 0 && xls.changed < 3) if (isfield (xls, "nfilename")) fname = xls.nfilename; else fname = xls.filename; endif try xlsout = javaObject ("java.io.FileOutputStream", fname); bufout = javaObject ("java.io.BufferedOutputStream", xlsout); xls.workbook.write (bufout); bufout.flush (); bufout.close (); xlsout.close (); xls.changed = 0; catch if (! strcmp (class (xlsout), "double")) xlsout.close (); endif end_try_catch endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__JOD_getusedrange__.m0000644000000000000000000000013213226215407020445 xustar0030 mtime=1515789063.568154851 30 atime=1515789063.568154851 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__JOD_getusedrange__.m0000644000175000017500000000401213226215407020702 0ustar00olafolaf00000000000000## Copyright (C) 2010-2017 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 . ## __JOD_getusedrange__ ## Author: Philip ## Created: 2010-05-25 function [ trow, brow, lcol, rcol ] = __JOD_getusedrange__ (ods, wsh) ## This function works for older jOpendocument (<= 1.2) by virtue of sheets ## in JOD actually being a Java string. ## It works outside of the Java memory/heap space which is an added benefit... ## (Read: it is one big dirty hack... prone to crash Java on BIG spreadsheets) ## For newer jOpenDocument 1.3b1+ there's a newer and much faster method. if (isnumeric (wsh)) sh = char (ods.workbook.getSheet (wsh - 1)); else sh = char (ods.workbook.getSheet (wsh)); endif try ## Let's see if we have JOD v. 1.3x. If not, next call fails & we'll fall ## back to the old hack sh_rng = char (sh.getUsedRange ()); if (isempty (sh_rng)) ## Empty sheet trow = brow = lcol = rcol = 0; else ## Strip sheet name sh_rng = sh_rng(length (sh.getName) + 2 : end); ## Get rid of period sh_rng = strrep (sh_rng, ".", ""); [~, nr, nc, trow, lcol] = parse_sp_range (sh_rng); brow = trow + nr - 1; rcol = lcol + nc - 1; endif catch ## Fall back to the old hack :-( (now in private/ function) sh = char (sh); [trow, brow, lcol, rcol ] = __ods_get_sheet_dims__ (sh); end_try_catch endfunction io-2.4.10/inst/private/PaxHeaders.5973/__JXL_oct2spsh__.m0000644000000000000000000000013213226215407017556 xustar0030 mtime=1515789063.572154929 30 atime=1515789063.572154929 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__JXL_oct2spsh__.m0000644000175000017500000001373013226215407020022 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [ @var{xlso}, @var{rstatus} ] = __JXL_oct2spsh__ ( @var{arr}, @var{xlsi}) ## @deftypefnx {Function File} [ @var{xlso}, @var{rstatus} ] = __JXL_oct2spsh__ (@var{arr}, @var{xlsi}, @var{wsh}) ## @deftypefnx {Function File} [ @var{xlso}, @var{rstatus} ] = __JXL_oct2spsh__ (@var{arr}, @var{xlsi}, @var{wsh}, @var{range}) ## @deftypefnx {Function File} [ @var{xlso}, @var{rstatus} ] = __JXL_oct2spsh__ (@var{arr}, @var{xlsi}, @var{wsh}, @var{range}, @var{options}) ## ## Add data in 1D/2D CELL array @var{arr} into spreadsheet cell range @var{range} ## in worksheet @var{wsh} in an Excel spreadsheet file pointed to in structure ## @var{range}. ## Return argument @var{xlso} equals supplied argument @var{xlsi} and is ## updated by __JXL_oct2spsh__. ## ## __JXL_oct2spsh__ should not be invoked directly but rather through oct2xls. ## ## Example: ## ## @example ## [xlso, status] = __JXL_oct2spsh__ ('arr', xlsi, 'Third_sheet', 'AA31'); ## @end example ## ## @seealso {oct2xls, xls2oct, xlsopen, xlsclose, xlsread, xlswrite, xls2jxla2oct} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-12-04 function [ xls, rstatus ] = __JXL_oct2spsh__ (obj, xls, wsh, crange, spsh_opts) ## Preliminary sanity checks if (strcmpi (xls.filename(end-4:end-1), ".xls")) ## No OOXML in JXL error ("JXL interface can only process Excel .xls files") endif persistent ctype; if (isempty (ctype)) ctype = [1, 2, 3, 4, 5]; ## Number, Boolean, String, Formula, Empty endif ## scratch vars rstatus = 0; f_errs = 0; ## Prepare workbook pointer if needed if (xls.changed == 0) ## Only for 1st call of octxls after xlsopen ## Create writable copy of workbook. If >2 a writable wb was made in xlsopen xlsout = javaObject ("java.io.File", xls.filename); wb = javaMethod ("createWorkbook", "jxl.Workbook", xlsout, xls.workbook); ## Catch JExcelAPI bug/"feature": when switching to write mode, the file on disk ## is affected and the memory file MUST be written to disk to save earlier data xls.changed = 1; xls.workbook = wb; else wb = xls.workbook; endif ## Check if requested worksheet exists in the file & if so, get pointer nr_of_sheets = xls.workbook.getNumberOfSheets (); ## 1 based !! if (isnumeric (wsh)) if (wsh > nr_of_sheets) ## Watch out as a sheet called Sheet%d can exist with a lower index... strng = sprintf ("Sheet%d", wsh); ii = 1; while (~isempty (wb.getSheet (strng)) && (ii < 5)) strng = ["_" strng]; ++ii; endwhile if (ii >= 5) error (sprintf( " > 5 sheets named [_]Sheet%d already present!", wsh)); endif sh = wb.createSheet (strng, nr_of_sheets); ++nr_of_sheets; xls.changed = min (xls.changed, 2); ## Keep a 2 in case of new file else sh = wb.getSheet (wsh - 1); ## JXL sheet count 0-based endif shnames = char (wb.getSheetNames ()); printf ("(Writing to worksheet %s)\n", shnames {nr_of_sheets, 1}); else sh = wb.getSheet (wsh); if (isempty(sh)) ## Sheet not found, just create it sh = wb.createSheet (wsh, nr_of_sheets); ++nr_of_sheets; xls.changed = min (xls.changed, 2); ## Keep a 2 for new file endif endif ## Parse date ranges [nr, nc] = size (obj); [topleft, nrows, ncols, trow, lcol] = ... spsh_chkrange (crange, nr, nc, xls.xtype, xls.filename); if (nrows < nr || ncols < nc) warning ("Array truncated to fit in range\n"); obj = obj(1:nrows, 1:ncols); endif ## Prepare type array typearr = spsh_prstype (obj, nrows, ncols, ctype, spsh_opts); if (! spsh_opts.formulas_as_text) ## Remove leading '=' from formula strings fptr = ! (4 * (ones (size (typearr))) .- typearr); obj(fptr) = cellfun (@(x) x(2:end), obj(fptr), "Uniformoutput", false); endif clear fptr ## Write date to worksheet for ii=1:nrows ll = ii + trow - 2; ## Java JExcelAPI's row count = 0-based for jj=1:ncols kk = jj + lcol - 2; ## JExcelAPI's column count is also 0-based switch typearr(ii, jj) case 1 ## Numerical tmp = javaObject ("jxl.write.Number", kk, ll, obj{ii, jj}); sh.addCell (tmp); case 2 ## Boolean tmp = javaObject ("jxl.write.Boolean", kk, ll, obj{ii, jj}); sh.addCell (tmp); case 3 ## String tmp = javaObject ("jxl.write.Label", kk, ll, obj{ii, jj}); sh.addCell (tmp); case 4 ## Formula ## First make sure formula functions are all uppercase obj{ii, jj} = toupper (obj{ii, jj}); ## There's no guarantee for formula correctness, so.... try ## Actually JExcelAPI flags formula errors as mere warnings :-( tmp = javaObject ("jxl.write.Formula", kk, ll, obj{ii, jj}); ## ... while errors are actually detected in addCell(), so ## that should be within the try-catch sh.addCell (tmp); catch ++f_errs; ## Formula error. Enter formula as text string instead tmp = javaObject ("jxl.write.Label", kk, ll, obj{ii, jj}); sh.addCell (tmp); end_try_catch case 5 ## Empty or NaN tmp = javaObject ("jxl.write.Blank", kk, ll); sh.addCell (tmp); otherwise ## Just skip endswitch endfor endfor if (f_errs) printf ("%d formula errors encountered - please check input array\n", f_errs); endif xls.changed = max (xls.changed, 1); ## Preserve 2 for new files rstatus = 1; endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OXS_spsh_open__.m0000644000000000000000000000013213226215407020023 xustar0030 mtime=1515789063.588155243 30 atime=1515789063.588155243 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OXS_spsh_open__.m0000644000175000017500000000450513226215407020267 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## __OXS_xlsopen__ - internal function for opening an xls file using Java / OpenXLS ## Author: Philip Nienhuis ## Created: 2012-10-07 function [ xls, xlssupport, lastintf ] = __OXS_spsh_open__ (xls, xwrite, filename, xlssupport, ftype) if (ftype != 1 && ftype != 2) error ("The OXS interface only supports .xls (Excel'97-2003) files") endif ## Trick to detect Java file handle existence xlsin = 1.5; try if (xwrite > 2) if (ftype == 1) ## Create BIFF 8 file (.xls) wb = javaObject ("com.extentech.ExtenXLS.WorkBookHandle", false); else ## Create OOXML file (.xlsx) wb = javaObject ("com.extentech.ExtenXLS.WorkBookHandle", true); endif ## This new workbook has 3 empty sheets - get rid of the last two. ## Renaming, if needed, of Sheet1 is handled in __OXS_oct2spsh__.m for ii=2:wb.getNumWorkSheets ## Remarkable = sheet index = 0-based! wb.getWorkSheet (1).remove; endfor ## Workbook now has only one sheet ("Sheet1"). Rename it wb.getWorkSheet(0).setSheetName (")_]_}_ Dummy sheet made by Octave_{_[_("); else xlsin = javaObject ("java.io.FileInputStream", filename); wb = javaObject ("com.extentech.ExtenXLS.WorkBookHandle", xlsin); xlsin.close (); endif xls.xtype = "OXS"; xls.app = "void - OpenXLS"; xls.workbook = wb; xls.filename = filename; xlssupport += 8; lastintf = "OXS"; catch if (! strcmp (class (xlsin), "double")) xlsin.close (); endif printf ("Unsupported file format for OpenXLS - %s\n"); end_try_catch endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OXS_spsh2oct__.m0000644000000000000000000000013213226215407017572 xustar0030 mtime=1515789063.588155243 30 atime=1515789063.588155243 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OXS_spsh2oct__.m0000644000175000017500000001162513226215407020037 0ustar00olafolaf00000000000000## Copyright (C) 2011-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = __OXS_spsh2oct__ (@var{xls}) ## @deftypefnx {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = __OXS_spsh2oct__ (@var{xls}, @var{wsh}) ## @deftypefnx {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = __OXS_spsh2oct__ (@var{xls}, @var{wsh}, @var{range}) ## Get cell contents in @var{range} in worksheet @var{wsh} in an Excel ## file pointed to in struct @var{xls} into the cell array @var{obj}. ## @var{range} can be a range or just the top left cell of the range. ## ## __OXS_spsh2oct__ should not be invoked directly but rather through xls2oct. ## ## Author: Philip Nienhuis ## Created: 2011-03-26 function [ rawarr, xls, rstatus ] = __OXS_spsh2oct__ (xls, wsh, cellrange, spsh_opts) persistent ctype; if (isempty (ctype)) ctype = zeros (6, 1); ## Get enumerated cell types. Beware as they start at 0 not 1 ctype( 1) = (__java_get__ ("com.extentech.ExtenXLS.CellHandle", "TYPE_STRING")); ## 0 ctype( 2) = (__java_get__ ("com.extentech.ExtenXLS.CellHandle", "TYPE_FP")); ## 1 ctype( 3) = (__java_get__ ("com.extentech.ExtenXLS.CellHandle", "TYPE_INT")); ## 2 ctype( 4) = (__java_get__ ("com.extentech.ExtenXLS.CellHandle", "TYPE_FORMULA")); ## 3 ctype( 5) = (__java_get__ ("com.extentech.ExtenXLS.CellHandle", "TYPE_BOOLEAN")); ## 4 ctype( 6) = (__java_get__ ("com.extentech.ExtenXLS.CellHandle", "TYPE_DOUBLE")); ## 5 endif rstatus = 0; wb = xls.workbook; ## Check if requested worksheet exists in the file & if so, get pointer nr_of_sheets = wb.getNumWorkSheets (); if (isnumeric (wsh)) if (wsh > nr_of_sheets) error (sprintf ... ("Worksheet ## %d bigger than nr. of sheets (%d) in file %s",... wsh, nr_of_sheets, xls.filename)); endif sh = wb.getWorkSheet (wsh - 1); ## OXS sheet count 0-based else try sh = wb.getWorkSheet (wsh); catch error (sprintf ("Worksheet %s not found in file %s", wsh, xls.filename)); end_try_catch end if (isempty (cellrange)) ## Get numeric sheet pointer (0-based) wsh = sh.getTabIndex (); ## Get data rectangle row & column numbers (1-based) [firstrow, lastrow, lcol, rcol] = getusedrange (xls, wsh+1); if (firstrow == 0 && lastrow == 0) ## Empty sheet rawarr = {}; printf ("Worksheet '%s' contains no data\n", shnames {wsh}); rstatus = 1; return; else nrows = lastrow - firstrow + 1; ncols = rcol - lcol + 1; endif else ## Translate range to row & column numbers (1-based) [dummy, nrows, ncols, firstrow, lcol] = parse_sp_range (cellrange); ## Check for too large requested range against actually present range lastrow = min (firstrow + nrows - 1, sh.getLastRow + 1 ()); nrows = min (nrows, sh.getLastRow () - firstrow + 1); ncols = min (ncols, sh.getLastCol () - lcol + 1); rcol = lcol + ncols - 1; endif ## Read contents into rawarr rawarr = cell (nrows, ncols); ## create placeholder for jj = lcol:rcol for ii = firstrow:lastrow try scell = sh.getCell (ii-1, jj-1); sctype = scell.getCellType (); switch sctype case {ctype(2), ctype(3), ctype(6)} ## Float / double rawarr{ii+1-firstrow, jj+1-lcol} = scell.getDoubleVal (); case ctype(4) ## Formula cell if (spsh_opts.formulas_as_text) tmp = char (sh.getFormula (scell.getCellAddress)); rawarr{ii+1-firstrow, jj+1-lcol} = tmp(index (tmp, ":=") + 1 : end); else ## FIXME - may still be a string; usually OpenXLS gets it right rawarr{ii+1-firstrow, jj+1-lcol} = scell.getVal (); endif case ctype(5) rawarr{ii+1-firstrow, jj+1-lcol} = scell.getVal () == 1; case ctype(1) rawarr{ii+1-firstrow, jj+1-lcol} = scell.getVal (); otherwise # rawarr{ii+1-firstrow, jj+1-lcol} = scell.getVal (); endswitch catch ## Empty or non-existing cell end_try_catch endfor endfor rstatus = 1; xls.limits = [lcol, rcol; firstrow, lastrow]; endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OXS_oct2spsh__.m0000644000000000000000000000013213226215407017572 xustar0030 mtime=1515789063.584155165 30 atime=1515789063.584155165 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OXS_oct2spsh__.m0000644000175000017500000001277313226215407020044 0ustar00olafolaf00000000000000## Copyright (C) 2011-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [ @var{xlso}, @var{rstatus} ] = __OXS_oct2spsh__ ( @var{arr}, @var{xlsi}) ## @deftypefnx {Function File} [ @var{xlso}, @var{rstatus} ] = __OXS_oct2spsh__ (@var{arr}, @var{xlsi}, @var{wsh}) ## @deftypefnx {Function File} [ @var{xlso}, @var{rstatus} ] = __OXS_oct2spsh__ (@var{arr}, @var{xlsi}, @var{wsh}, @var{range}) ## @deftypefnx {Function File} [ @var{xlso}, @var{rstatus} ] = __OXS_oct2spsh__ (@var{arr}, @var{xlsi}, @var{wsh}, @var{range}, @var{options}) ## ## Add data in 1D/2D CELL array @var{arr} into spreadsheet cell range @var{range} ## in worksheet @var{wsh} in an Excel spreadsheet file pointed to in structure ## @var{range}. ## Return argument @var{xlso} equals supplied argument @var{xlsi} and is ## updated by __OXS_oct2spsh__. ## ## __OXS_oct2spsh__ should not be invoked directly but rather through oct2xls. ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2011-03-29 function [ xls, rstatus ] = __OXS_oct2spsh__ (obj, xls, wsh, crange, spsh_opts) changed = 0; persistent ctype; if (isempty (ctype)) ## Number, Boolean, String, Formula, Empty ctype = [1, 2, 3, 4, 5]; endif ## scratch vars rstatus = 0; f_errs = 0; ## Prepare workbook pointer if needed wb = xls.workbook; ## Check if requested worksheet exists in the file & if so, get pointer nr_of_sheets = wb.getNumWorkSheets (); ## 1 based !! if (isnumeric (wsh)) if (wsh > nr_of_sheets) ## Watch out as a sheet called Sheet%d can exist with a lower index... strng = sprintf ("Sheet%d", wsh); ii = 1; try ## While loop should be inside try-catch while (ii < 5) sh = wb.getWorkSheet (strng) strng = ['_' strng]; ++ii; endwhile catch ## No worksheet named found => we can proceed end_try_catch if (ii >= 5) error (sprintf( " > 5 sheets named [_]Sheet%d already present!", wsh)); endif ## OpenXLS v.10 has some idiosyncrasies. Might be related to the empty workbook... try sh = wb.createWorkSheet (strng); ++nr_of_sheets; catch if (wb.getNumWorkSheets () > nr_of_sheets) ## Adding a sheet did work out, in spite of Java exception ## lasterr should be something like "org/json/JSONException" ++nr_of_sheets; else error ("Couldn't add worksheet. Error message =\n%s", lasterr); endif end_try_catch xls.changed = min (xls.changed, 2); ## Keep a 2 in case of new file else sh = wb.getWorkSheet (wsh - 1); ## OXS sheet index 0-based endif printf ("(Writing to worksheet %s)\n", sh.getSheetName ()); else try sh = wb.getWorkSheet (wsh); catch ## Sheet not found, just create it. Mind OpenXLS v.10 idiosyncrasies if (xls.changed == 3 || strcmpi (wb.getWorkSheet (0).getSheetName, ")_]_}_ Dummy sheet made by Octave_{_[_(")) ## Workbook was just created, still has one empty worksheet. Rename it sh = wb.getWorkSheet (0); ## Index = 0-based sh.setSheetName (wsh); else try sh = wb.createWorkSheet (wsh); ++nr_of_sheets; catch if (wb.getNumWorkSheets () > nr_of_sheets) ## Adding a sheet did work out, in spite of Java exception ## lasterr should be something like "org/json/JSONException" ++nr_of_sheets; else error ("Couldn't add worksheet. Error message =\n%s", lasterr); endif end_try_catch endif xls.changed = min (xls.changed, 2); ## Keep a 2 for new file end_try_catch endif ## Parse date ranges [nr, nc] = size (obj); [topleft, nrows, ncols, trow, lcol] = ... spsh_chkrange (crange, nr, nc, xls.xtype, xls.filename); if (nrows < nr || ncols < nc) warning ("Array truncated to fit in range\n"); obj = obj(1:nrows, 1:ncols); endif ## Prepare type array typearr = spsh_prstype (obj, nrows, ncols, ctype, spsh_opts); if (! spsh_opts.formulas_as_text) ## Remove leading '=' from formula strings //FIXME needs updating fptr = (! (4 * (ones (size (typearr))) .- typearr)); # obj(fptr) = cellfun (@(x) x(2:end), obj(fptr), "Uniformoutput", false); endif clear fptr for ii=1:ncols for jj=1:nrows try ## Set value sh.getCell(jj+trow-2, ii+lcol-2).setVal (obj{jj, ii}); ## Addr.cnt = 0-based changed = 1; catch ## Cell not existent. Add cell if (typearr(jj, ii) != 5) sh.add (obj{jj, ii}, jj+trow-2, ii+lcol-2); changed = 1; endif end_try_catch endfor endfor if (changed) ## Preserve 2 for new files xls.changed = max (xls.changed, 1); endif rstatus = 1; endfunction io-2.4.10/inst/private/PaxHeaders.5973/__UNO_getnmranges__.m0000644000000000000000000000013213226215407020327 xustar0030 mtime=1515789063.592155322 30 atime=1515789063.592155322 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__UNO_getnmranges__.m0000644000175000017500000000515013226215407020570 0ustar00olafolaf00000000000000## Copyright (C) 2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} __UNO_getnmranges__ (@var{input1}, @var{input2}) ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2015-09-20 function [nmr] = __UNO_getnmranges__ (xls) nmr = cell (0, 3); ## Entire workbook unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.beans.XPropertySet"); docProps = xls.workbook.queryInterface (unotmp); urng = docProps.getPropertyValue ("NamedRanges"); rnms = urng.getObject.getElementNames (); ## FIXME get ranges for ii = 1:numel (rnms) rng = urng.getObject.getByName (rnms(ii)); nm = strrep (rng.getObject ().getContent (), "$", ""); ## -> $3rdSheet.$D$2:$I$4 nmr{end+1, 1} = rnms(ii); nmr{end, 2} = nm(1:index(nm, ".")-1); nmr{end, 3} = nm(index(nm, ".")+1:end); endfor ## Per sheet. First some preparations sheets = xls.workbook.getSheets (); sh_names = sheets.getElementNames (); if (! iscell (sh_names)) ## Java array (LibreOffice 3.4.+), convert to cellstr sh_names = char (sh_names); else sh_names = {sh_names}; endif ## For each sheet get named ranges for jj = 1:numel (sh_names) unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.sheet.XSpreadsheet"); sh = sheets.getByName(sh_names{jj}).getObject.queryInterface (unotmp); unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.beans.XPropertySet"); shProps = sh.queryInterface (unotmp); urng = shProps.getPropertyValue ("NamedRanges"); rnms = urng.getObject.getElementNames (); for ii=1:numel (rnms) rng = urng.getObject.getByName (rnms(ii)); nm = strrep (rng.getObject ().getContent (), "$", ""); ## -> $3rdSheet.$D$2:$I$4 nmr{end+1, 1} = rnms(ii); nmr{end, 2} = nm(1:index(nm, ".")-1); nmr{end, 3} = nm(index(nm, ".")+1:end); endfor endfor endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OXS_getnmranges__.m0000644000000000000000000000013213226215407020337 xustar0030 mtime=1515789063.584155165 30 atime=1515789063.584155165 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OXS_getnmranges__.m0000644000175000017500000000244413226215407020603 0ustar00olafolaf00000000000000## Copyright (C) 2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} __OXS_getnmranges__ (@var{input1}, @var{input2}) ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2015-09-20 function [nmr] = __OXS_getnmranges__ (xls) rnms = xls.workbook.getNamedRanges (); nmr = cell (numel (rnms), 3); for ii=1:numel (rnms) nmr{ii, 1} = char (rnms(ii)); rng = char ((rnms(ii).getCellRanges ())(1)); nmr{ii, 2} = rng(1:index (rng, "!") - 1); nmr{ii, 3} = strrep (rng(index (rng, "!") + 1 : end), "$", ""); endfor endfunction io-2.4.10/inst/private/PaxHeaders.5973/__COM_getnmranges__.m0000644000000000000000000000013213226215407020304 xustar0030 mtime=1515789063.564154773 30 atime=1515789063.564154773 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__COM_getnmranges__.m0000644000175000017500000000301713226215407020545 0ustar00olafolaf00000000000000## Copyright (C) 2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} __COM_getnmranges__ (@var{input1}, @var{input2}) ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2015-09-21 function [nmr] = __COM_getnmranges__ (xls) wb = xls.workbook; names = wb.Names (); nmr = cell (0, 3); for ii=1:names.Count try ## Only add Ranges rng = strrep (wb.Names(ii).RefersTo, "$", ""); nmr{end+1, 3} = rng(index (rng, "!")+1:end); name = wb.Names(ii).Name; nmr{end, 2} = name(1:index (name, "!")-1); if (isempty (nmr{end, 2})) ## Get sheet name from Range nmr{end, 2} = rng(2:index (rng, "!")-1); endif nmr{end, 1} = name(index(name, "!")+1:end); catch end_try_catch endfor endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OXS_spsh_info__.m0000644000000000000000000000013213226215407020015 xustar0030 mtime=1515789063.588155243 30 atime=1515789063.588155243 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OXS_spsh_info__.m0000644000175000017500000000266013226215407020261 0ustar00olafolaf00000000000000## Copyright (C) 2013-2017 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 Octave; see the file COPYING. If not, see ## . ## __OXS_spsh_info__ ## Author: Philip Nienhuis ## Created: 2012-10-12 function [sh_names] = __OXS_spsh_info__ (xls) sh_cnt = xls.workbook.getNumWorkSheets (); sh_names = cell (sh_cnt, 2); nsrows = zeros (sh_cnt, 1); for ii=1:sh_cnt sh = xls.workbook.getWorkSheet (ii-1); ## OpenXLS starts counting at 0 sh_names(ii, 1) = char (sh.getSheetName()); ## OpenXLS doesn't offer methods to distinguish between worksheets ## and graph sheets [tr, lr, lc, rc] = getusedrange (xls, ii); if (tr) sh_names(ii, 2) = ... sprintf ("%s:%s", calccelladdress (tr, lc), calccelladdress (lr, rc)); else sh_names(ii, 2) = "Empty or Chart"; endif endfor endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OXS_chk_sprt__.m0000644000000000000000000000013213226215407017642 xustar0030 mtime=1515789063.584155165 30 atime=1515789063.584155165 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OXS_chk_sprt__.m0000644000175000017500000000402513226215407020103 0ustar00olafolaf00000000000000## Copyright (C) 2014-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{varargout} =} __OXS_chk_sprt__ (@var{varargin}) ## Undocumented internal function ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2014-10-31 function [chk, missing4] = __OXS_chk_sprt__ (jcp, dbug=0) chk = 0; if (dbug > 1) printf ("\nOpenXLS (.xls - BIFF8 & .xlsx - OOXML) :\n"); endif entries4 = {"OpenXLS", "gwt-servlet-deps"}; [jpchk, missing4] = chk_jar_entries (jcp, entries4, dbug); missing4 = entries4 (find (missing4)); if (jpchk >= numel (entries4)) ## Check OpenXLS.jar version chk = 1; try ## ...a method that is first introduced in OpenXLS v.10 oxsvsn = javaMethod ("getVersion", "com.extentech.ExtenXLS.GetInfo"); ## If we get here, we do have v. 10 if (dbug > 2) printf (" OpenXLS version: %s\n", oxsvsn); endif if (dbug > 1) if (jpchk >= numel (entries4)) printf (" => Java/OpenXLS (OXS) OK.\n"); else printf (" => Not all required classes (.jar) for OXS in classpath\n"); endif endif catch ## Wrong OpenXLS.jar version (probably <= 6.08). v. 10 is required now chk = -1; warning ("OpenXLS.jar version is outdated; please upgrade to v.10\n"); end_try_catch endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__JXL_spsh_open__.m0000644000000000000000000000013213226215407020007 xustar0030 mtime=1515789063.572154929 30 atime=1515789063.572154929 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__JXL_spsh_open__.m0000644000175000017500000000334513226215407020254 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## __JXL_xlsopen__ - Internal function for opening an xls file using Java / JExcelAPI ## Author: Philip Nienhuis ## Created: 2012-10-07 function [ xls, xlssupport, lastintf ] = __JXL_spsh_open__ (xls, xwrite, filename, xlssupport, ftype, xlsinterfaces) if (ftype != 1) error ("xlsopen: JXL can only read .xls (BIFF5 - Excel95 or BIFF8 - Excel97-2003) files") endif try xlsin = javaObject ("java.io.File", filename); if (xwrite > 2) ## Get handle to new xls-file wb = javaMethod ("createWorkbook", "jxl.Workbook", xlsin); else ## Open existing file wb = javaMethod ("getWorkbook", "jxl.Workbook", xlsin); endif xls.xtype = "JXL"; xls.app = xlsin; xls.workbook = wb; xls.filename = filename; xlssupport += 4; lastintf = "JXL"; catch if (xlsinterfaces.POI) ## Fall back to UNO only when that is stable (= closing soffice) printf ("... No luck with JXL, unsupported file format.\n", filename); endif end_try_catch endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OCT_oct2gnm__.m0000644000000000000000000000013213226215407017352 xustar0030 mtime=1515789063.576155008 30 atime=1515789063.576155008 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OCT_oct2gnm__.m0000644000175000017500000001636213226215407017622 0ustar00olafolaf00000000000000## Copyright (C) 2014-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} __OCT_oct2gnm__ (@var{input1}, @var{input2}) ## Internal OF io package function. ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2014-04-20 function [xls, status] = __OCT_oct2gnm__ (obj, xls, wsh, crange, spsh_opts=0, obj_dims) ## A. Find out if we write to existing or new sheet new_sh = 0; if (isnumeric (wsh)) if (wsh < 1) error ("oct2ods/xls: sheet number (%d) should be > 0\n", wsh); elseif (wsh > numel (xls.sheets.sh_names)) ## New sheet ## FIXME check for existing/duplicate names xls.sheets.sh_names(wsh) = sprintf ("Sheet%d", wsh); new_sh = 1; wsh = numel (xls.sheets.sh_names) + 1; endif elseif (ischar (wsh)) idx = find (strcmp (wsh, xls.sheets.sh_names)); if (isempty (idx)) ## New sheet xls.sheets.sh_names(end+1) = wsh; new_sh = 1; idx = numel (xls.sheets.sh_names); endif wsh = idx; endif ## Check if we made a new file from template, add a new sheet, or add data to a sheet if (strcmpi (xls.sheets.sh_names{1}, " ") && numel (xls.sheets.sh_names) == 2 && new_sh) ## Completely new file. Clean up and copy a few things xls.sheets.sh_names(1) = []; wsh = 1; idx_s = xls.sheets.shtidx(1); idx_e = xls.sheets.shtidx(2) - 1; xls.changed = 2; lims = [obj_dims.tr, obj_dims.br; obj_dims.lc, obj_dims.rc]; rawarr = obj; elseif (new_sh) ## New sheet. Provisionally update sheet info in file pointer struct wsh = numel (xls.sheets.sh_names); idx_s = xls.sheets.shtidx(wsh) ; ## First position after last sheet idx_e = idx_s - 1; xls.changed = 1; lims = [obj_dims.tr, obj_dims.br; obj_dims.lc, obj_dims.rc]; rawarr = obj; else ## Just write new data into an existing sheet idx_s = xls.sheets.shtidx(wsh); idx_e = xls.sheets.shtidx(wsh+1) - 1; ## Get all current data in sheet and current row/column limits [rawarr, xls] = __OCT_gnm2oct__ (xls, wsh, "", struct ("formulas_as_text", 1)); lims = xls.limits; ## C. Merge old and new data. Provisionally allow empty new data to wipe old data [rawarr, lims] = __OCT_merge_data__ (rawarr, lims, obj, obj_dims); endif ## C. Create a temporary file to hold the new sheet xml ## Open sheet file (new or old) tmpfil = tmpnam; fid = fopen (tmpfil, "w+"); if (fid < 0) error ("oct2ods/xls: unable to write to tmp file %s\n", tmpfil); endif ## Write data to sheet status = __OCT__oct2gnm_sh__ (fid, rawarr, xls.sheets.sh_names{wsh}, lims); ## E. Merge new/updated sheet into gnumeric file ## Read first chunk until sht_idx fidc = fopen (xls.workbook, "r+"); ## Read and concatenate just adapted/created sheet/table:table gnm_xml = fread (fidc, idx_s - 1, "char=>char")'; ## F. Optionally update SheetName Index node if (new_sh) if (wsh == 1) ## New file, existing sheet. Find then (only) gnm:SheetName node [shtnmnode, ss, ee] = getxmlnode (gnm_xml, "gnm:SheetName"); ipos = index (shtnmnode, "> "); shtnmnode = [ shtnmnode(1:ipos) xls.sheets.sh_names{1} shtnmnode(ipos+2:end) ]; ## Replace SheetName node gnm_xml = [ gnm_xml(1:ss-1) shtnmnode gnm_xml(ee+1:end) ]; else ## Existing file, append new SheetName node to end of SheetName nodes list [shtidxnode, ss, ee] = getxmlnode (gnm_xml, "gnm:SheetNameIndex"); sh_node = sprintf('>%s', xls.sheets.sh_names{wsh}); ## Add close tag to ease up next strrep sh_node = [ sh_node "" ]; shtidxnode = strrep (shtidxnode, "", sh_node); ## Replace SheetNameIndex node gnm_xml = [ gnm_xml(1:ss-1) shtidxnode gnm_xml(ee+1:end) ]; endif endif ## Rewind tmp sheet and read it behind gnm_xml fseek (fid, 0, "bof"); sheet = fread (fid, Inf, "char=>char")'; lsheet = length (sheet); ## Close & delete sheet file fclose (fid); delete (tmpfil); gnm_xml = [ gnm_xml sheet] ; ## Read rest of gnumeric file, optionally delete overwritten sheet/table:table fseek (fidc, idx_e, 'bof'); gnm_xml = [ gnm_xml fread(fidc, Inf, "char=>char")' ]; ## Write updated gnumeric file back to disk. fclose (fidc); fidc = fopen (xls.workbook, "w+"); fprintf (fidc, "%s", gnm_xml); fclose (fidc); ## G. Update sheet pointers in ods/xls file pointer if (new_sh) xls.sheets.shtidx(wsh+1) = idx_s + lsheet; xls.changed = 2; else offset = lsheet - (idx_e - idx_s) - 1; xls.sheets.shtidx(wsh+1 : end) += offset; endif xls.changed = max (xls.changed, 1); endfunction function [ status ] = __OCT__oct2gnm_sh__ (fid, raw, wsh, lims) ## Write out the lot to requested sheet ## 1. Sheet open tags tag = '' ]; fprintf (fid, "%s", tag); fprintf (fid, "%s", wsh); fprintf (fid, "%d%d", ... lims(1, 2) - 1, lims(2, 2) - 1); fprintf (fid, ""); ## 2. Spreadsheet cells for ii=1:size (raw, 1) # lims(##, ##):lims(##, ##) ## Row # in gnumeric = 0-based irow = lims(1, 1) - 2 + ii; for jj=1:size (raw, 2) # lims(##, ##):lims(##, ##) ## Column # in gnumeric = 0-based icol = lims(2, 1) - 2 + jj; if (isempty (raw{ii, jj})) ## Do nothing elseif (islogical (raw{ii, jj})) ## BOOLEAN. Convert to acceptable format for gnumeric val = "FALSE"; if (raw{ii, jj}) val = "TRUE"; endif fprintf (fid, '%s', ... irow, icol, val) elseif (isnumeric (raw{ii, jj})) ## Any numeric value; gnumeric only has FLOAT type fprintf (fid, '%0.15g', ... irow, icol, raw{ii, jj}); elseif (ischar (raw{ii, jj})) ## STRING fprintf (fid, '%s', ... irow, icol, raw{ii, jj}); else ## Do nothing, just skip endif endfor endfor ## 3. Closing tag fprintf (fid, ""); status = 1; endfunction io-2.4.10/inst/private/PaxHeaders.5973/__UNO_spsh_close__.m0000644000000000000000000000013213226215407020157 xustar0030 mtime=1515789063.592155322 30 atime=1515789063.592155322 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__UNO_spsh_close__.m0000644000175000017500000001124613226215407020423 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## __UNO_spsh_close__ - internal function: close a spreadsheet file using UNO ## Author: Philip Nienhuis ## Created: 2012-10-12 function [ xls ] = __UNO_spsh_close__ (xls, force) if (isfield (xls, "nfilename")) ## New filename specified if (strcmp (xls.xtype, 'UNO')) ## For UNO, turn filename into URL nfilename = xls.nfilename; if (! isempty (strfind (nfilename, "file:///"))... || ! isempty (strfind (nfilename, "http://" ))... || ! isempty (strfind (nfilename, "ftp://" ))... || ! isempty (strfind (nfilename, "www://" ))) ## Seems in proper shape for OOo (at first sight) else ## Transform into URL form if (ispc) fname = canonicalize_file_name (strsplit (nfilename, filesep){end}); if (isempty (fname)) ## File doesn't exist yet? try make_absolute_filename() fname = make_absolute_filename (strsplit (filename, filesep){end}); endif else fname = make_absolute_filename (strsplit (nfilename, filesep){end}); endif ## On Windows, change backslash file separator into forward slash if (strcmp (filesep, "\\")) tmp = strsplit (fname, filesep); flen = numel (tmp); tmp(2:2:2*flen) = tmp; tmp(1:2:2*flen) = "/"; filename = [ "file://" tmp{:} ]; endif endif endif else filename = xls.filename; endif try if (xls.changed > 0 && xls.changed < 3) ## Workaround: unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.frame.XModel"); xModel = xls.workbook.queryInterface (unotmp); unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.util.XModifiable"); xModified = xModel.queryInterface (unotmp); if (xModified.isModified ()) unotmp = ... javaObject ("com.sun.star.uno.Type", "com.sun.star.frame.XStorable"); # isReadonly() ? xStore = xls.app.xComp.queryInterface (unotmp); if (xls.changed == 2) ## Some trickery as Octave Java cannot create non-numeric arrays lProps = javaArray ("com.sun.star.beans.PropertyValue", 2); ## Set file type property [ftype, filtnam] = __get_ftype__ (filename); if (isempty (filtnam)) filtnam = "calc8"; endif lProp = javaObject ... ("com.sun.star.beans.PropertyValue", "FilterName", 0, filtnam, []); lProps(1) = lProp; ## Set "Overwrite" property lProp = ... javaObject ("com.sun.star.beans.PropertyValue", "Overwrite", 0, true, []); lProps(2) = lProp; ## OK, store file # if (isfield (xls, "nfilename")) ## Store in another file ## FIXME check if we need to close the old file # xStore.storeAsURL (xls.nfilename, lProps); # else # xStore.storeAsURL (xls.filename, lProps); xStore.storeAsURL (filename, lProps); # endif else xStore.store (); endif endif endif xls.changed = -1; ## Needed for check on properly shutting down OOo ## Workaround: unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.frame.XModel"); xModel = xls.app.xComp.queryInterface (unotmp); unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.util.XCloseable"); xClosbl = xModel.queryInterface (unotmp); xClosbl.close (true); unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.frame.XDesktop"); xDesk = xls.app.aLoader.queryInterface (unotmp); pause (0.25); xDesk.terminate(); xls.changed = 0; catch if (force) ## Force closing OOo unotmp = javaObject ("com.sun.star.uno.Type", "com.sun.star.frame.XDesktop"); xDesk = xls.app.aLoader.queryInterface (unotmp); xDesk.terminate(); else warning ("Error closing xls pointer (UNO)"); endif return end_try_catch endfunction io-2.4.10/inst/private/PaxHeaders.5973/__JXL_getusedrange__.m0000644000000000000000000000013213226215407020466 xustar0030 mtime=1515789063.572154929 30 atime=1515789063.572154929 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__JXL_getusedrange__.m0000644000175000017500000000341013226215407020724 0ustar00olafolaf00000000000000## Copyright (C) 2010-2017 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 . ## __JXL_getusedrange__ - get occupied data cell range from Excel sheet ## using java/JExcelAPI ## Author: Philip Nienhuis ## Created: 2010-03-20 function [ trow, brow, lcol, rcol ] = __JXL_getusedrange__ (xls, wsh) persistent emptycell = (__java_get__ ("jxl.CellType", "EMPTY")).toString (); sh = xls.workbook.getSheet (wsh - 1); ## JXL sheet count 0-based brow = sh.getRows (); rcol = sh.getColumns (); if (brow == 0 || rcol == 0) ## Empty sheet trow = 0; lcol = 0; brow = 0; rcol = 0; else trow = brow + 1; lcol = rcol + 1; ## For loop coz we must check ALL rows for leftmost column for ii=0:brow-1 emptyrow = 1; jj = 0; ## While loop => only til first non-empty cell while (jj < rcol && emptyrow) cell = sh.getCell (jj, ii); if (! strcmp (char (cell.getType ()), emptycell)) lcol = min (lcol, jj + 1); emptyrow = 0; endif ++jj; endwhile if (! emptyrow) trow = min (trow, ii + 1); endif endfor endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OCT_oct2ods__.m0000644000000000000000000000013213226215407017356 xustar0030 mtime=1515789063.576155008 30 atime=1515789063.576155008 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OCT_oct2ods__.m0000644000175000017500000002452513226215407017626 0ustar00olafolaf00000000000000## Copyright (C) 2014-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{ods}, @var{status} =} __OCT_oct2ods__ (@var{obj}, @var{ods}, @var{wsh}, @var{crange}, @var{spsh_opts}) ## Internal function for writing to ODS sheet ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2014-01-18 function [ ods, status ] = __OCT_oct2ods__ (obj, ods, wsh, crange, spsh_opts=0, obj_dims) ## Find out if we write to existing or new sheet new_sh = 0; if (isnumeric (wsh)) if (wsh < 1) error ("oct2xls/ods: sheet number (%d) should be > 0", wsh); elseif (ods.changed == 3) ## New sheet name in new file. Ignore sheet# other than to name sheet ods.sheets.sh_names(1) = sprintf ("Sheet%d" , wsh); wsh = 1; elseif (wsh > numel (ods.sheets.sh_names)) ## New sheet ods.sheets.sh_names(wsh) = sprintf ("Sheet%d", wsh); new_sh = 1; wsh = numel (ods.sheets.sh_names) + 1; endif elseif (ischar (wsh)) idx = find (strcmp (wsh, ods.sheets.sh_names)); if (isempty (idx)) if (ods.changed == 3) ## New sheet name in new file ods.sheets.sh_names(1) = wsh; idx = 1; else ## New sheet ods.sheets.sh_names(end+1) = wsh; new_sh = 1; idx = numel (ods.sheets.sh_names); endif endif wsh = idx; endif ## Check if we made a new file from template if (ods.changed == 3) ods.changed = 2; endif if (new_sh) wsh = numel (ods.sheets.sh_names); idx_s = ods.sheets.shtidx(wsh) ; ## First position after last sheet idx_e = idx_s - 1; rawarr = {}; lims = []; elseif (ods.changed < 2) idx_s = ods.sheets.shtidx(wsh); idx_e = ods.sheets.shtidx(wsh+1) - 1; ## Get all data in sheet and row/column limits [rawarr, ods] = __OCT_ods2oct__ (ods, wsh, "", struct ("formulas_as_text", 1)); lims = ods.limits; elseif (ods.changed >= 2) idx_s = ods.sheets.shtidx(wsh); idx_e = ods.sheets.shtidx(wsh+1) - 1; rawarr = {}; lims = []; endif ## Merge old and new data. Provisionally allow empty new data to wipe old data [rawarr, lims, onr, onc] = __OCT_merge_data__ (rawarr, lims, obj, obj_dims); ## D. Get default table/row/column styles ## Open file content.xml fids = fopen (sprintf ("%s/content.xml", ods.workbook), "r"); ## Get first part, til first sheet contnt = fread (fids, ods.sheets.shtidx(1)-1, "char=>char").'; fclose (fids); ## Get default styles stuff contnt = getxmlnode (contnt, "office:automatic-styles"); is = 1; stylenode = " "; ## Any non-empty value ## Usual default style names styles = struct ("tbl", "ta1", "row", "ro1", "col", "co1"); ## Get actual default styles while (! isempty (stylenode)) [stylenode, ~, is] = getxmlnode (contnt, "style:style", is, 1); stylefam = getxmlattv (stylenode, "style:family"); if (strcmpi (stylefam, "table-column")) style.col = stylefam; elseif (strcmpi (stylefam, "table")) styles.tbl = stylefam; elseif (strcmpi (stylefam, "table-row")) styles.row = stylefam; endif endwhile ## E. Create a temporary file to hold the new sheet xml ## Open sheet file (new or old) tmpfil = tmpnam; fid = fopen (tmpfil, "w+"); if (fid < 0) error ("oct2xls/ods: unable to write to file %s", tmpfil); endif ## Write data to sheet (actually table:table section in content.xml) status = __OCT__oct2ods_sh__ (fid, rawarr, wsh, lims, onc, onr, ... ods.sheets.sh_names{wsh}, styles); ## F. Merge new/updated sheet into content.xml ## Read first chunk of content.xml until sht_idx fidc = fopen (sprintf ("%s/content.xml", ods.workbook), "r+"); ## Go to start of requested sheet fseek (fidc, 0, "bof"); ## Read and concatenate just adapted/created sheet/table:table content_xml = fread (fidc, idx_s - 1, "char=>char").'; ## Rewind sheet and read it behind content_xml fseek (fid, 0, "bof"); sheet = fread (fid, Inf, "char=>char").'; lsheet = length (sheet); ## Close & delete sheet file fclose (fid); delete (tmpfil); content_xml = [ content_xml sheet] ; ## Read rest of content.xml, optionally delete overwritten sheet/table:table fseek (fidc, idx_e, "bof"); content_xml = [ content_xml fread(fidc, Inf, "char=>char").' ]; ## Write updated content.xml back to disk. fseek (fidc, 0, "bof"); fprintf (fidc, "%s", content_xml); fclose (fidc); ## F. Update sheet pointers in ods file pointer if (new_sh) ods.sheets.shtidx(wsh+1) = idx_s + lsheet; ods.changed = 2; else offset = lsheet - (idx_e - idx_s) - 1; ods.sheets.shtidx(wsh+1 : end) += offset; endif ods.changed = max (ods.changed, 1); ## FIXME: Perhaps we'd need to update the metadata in meta.xml endfunction ## =========================================================================== function [ status ] = __OCT__oct2ods_sh__ (fid, rawarr, wsh, lims, onc, onr, tname, styles) ## Write out the lot to requested sheet ## 1. Sheet open tag fprintf (fid, '', tname, styles.tbl); ## 2. Default column styles. If required add columns repeated tag if (lims(1, 2) > 1) tncr = sprintf (' table:number-columns-repeated="%d"', lims(1, 2)); else tncr = ""; endif fprintf (fid, '', ... styles.col, tncr); ## 3. Spreadsheet rows ii = 1; while (ii <= onr) ## 3.1 Check for empty rows if (ii == 1) tnrr = lims(2, 1) - 1; else tnrr = 0; endif ## Check for consecutive empty rows while (ii <= onr && all (cellfun ("isempty", rawarr(ii, :)))) ++tnrr; ++ii; endwhile if (tnrr > 1) tnrrt = sprintf (' table:number-rows-repeated="%d"', tnrr); else tnrrt = ""; endif if (tnrr) ## Write empty row, optionally with row repeat tag if (lims (1, 2) > 1) ## Add number of empty columns repeat tag tcell = sprintf ('', ... lims(1, 2)); else tcell = ""; endif fprintf (fid, '%s', tnrrt, tcell); endif if (ii <= onr) ## Write table row opening tag fprintf (fid, '', styles.row); ## 3.2 Value cells jj = 1; while (jj <= onc) ## 3.2.1 Check if empty. Include empty columns left of rawarr if (jj == 1) tncr = lims(1, 1) - 1; else tncr = 0; endif ## Check consecutive empty cells & adapt ncr attr, write empty cells while (jj <= onc && isempty (rawarr{ii, jj})) ++tncr; ++jj; endwhile if (tncr > 1) fprintf (fid, '', tncr); elseif (tncr == 1) fprintf (fid, ""); endif ## Process non-empty data cells if (jj <= onc) ## 3.2.2 Non-empty cell. Determine value type. Set formula attr = empty of = ""; switch class (rawarr{ii, jj}) case {"double", "single"} ovt = ' office:value-type="float"'; val = sprintf ("%.4f", rawarr{ii, jj}); txt = sprintf ("%s", val); ## Convert to attribute val = sprintf (' office:value="%0.15g"', rawarr{ii, jj}); case {"int64", "int32", "int16", "int8", "uint64", "uint32", "uint16", "uint8"} ovt = ' office:value-type="integer"'; val = strtrim (sprintf ("%d15", rawarr{ii, jj})); txt = sprintf ("%s", val); ## Convert to attribute val = sprintf (' office:value="%s"', val); case "logical" ovt = ' office:value-type="boolean"'; val = "false"; if (rawarr{ii, jj}) val = "true"; endif txt = sprintf ("%s", upper (val)); ## Convert to attribute val = sprintf (' office:boolean-value="%s"', val); case "char" if (rawarr{ii, jj}(1) == "=") ## We guess a formula. Prepare formula attribute ovt = ""; txt = ""; val = ""; of = sprintf (' table:formula="of:%s"', rawarr{ii, jj}); ## FIXME We'd need to parse cell types in formula = may be formulas as well ## We cannot know, or parse, the resulting cell type, omit type info & text else ## Plain text ovt = ' office:value-type="string">'; val = strsplit (rawarr{ii, jj}, "\n"); txt = ""; for kk=1:numel (val) txt = [txt sprintf('%s', val{kk})]; endfor ## Convert to attribute val = sprintf (" office:string-value=%s", txt); txt = ""; endif otherwise ## Unknown, illegal or otherwise unrecognized value ovt = ""; val = ""; txt = ""; endswitch # write out table-cell w office-value-type / office:value fprintf (fid, "%s", of, ovt, val, txt); endif ++jj; endwhile ## Write table row closing tag fprintf (fid, ""); endif ++ii; endwhile ## 4. Closing tag fprintf (fid, ""); status = 1; endfunction io-2.4.10/inst/private/PaxHeaders.5973/__POI_spsh2oct__.m0000644000000000000000000000013213226215407017550 xustar0030 mtime=1515789063.588155243 30 atime=1515789063.588155243 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__POI_spsh2oct__.m0000644000175000017500000001564413226215407020022 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = __POI_spsh2oct__ (@var{xls}) ## @deftypefnx {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = __POI_spsh2oct__ (@var{xls}, @var{wsh}) ## @deftypefnx {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = __POI_spsh2oct__ (@var{xls}, @var{wsh}, @var{range}) ## Get cell contents in @var{range} in worksheet @var{wsh} in an Excel ## file pointed to in struct @var{xls} into the cell array @var{obj}. ## @var{range} can be a range or just the top left cell of the range. ## ## __POI_spsh2oct__ should not be invoked directly but rather through xls2oct. ## ## Examples: ## ## @example ## [Arr, status, xls] = __POI_spsh2oct__ (xls, 'Second_sheet', 'B3:AY41'); ## B = __POI_spsh2oct__ (xls, 'Second_sheet', 'B3'); ## @end example ## ## @seealso {xls2oct, oct2xls, xlsopen, xlsclose, xlsread, xlswrite, oct2jpoi2xls} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-11-23 function [ rawarr, xls, rstatus ] = __POI_spsh2oct__ (xls, wsh, cellrange, spsh_opts) persistent ctype; if (isempty (ctype)) ## Get enumerated cell types. Beware as they start at 0 not 1 ctype(1) = __java_get__ ("org.apache.poi.ss.usermodel.Cell", "CELL_TYPE_NUMERIC"); ctype(2) = __java_get__ ("org.apache.poi.ss.usermodel.Cell", "CELL_TYPE_STRING"); ctype(3) = __java_get__ ("org.apache.poi.ss.usermodel.Cell", "CELL_TYPE_FORMULA"); ctype(4) = __java_get__ ("org.apache.poi.ss.usermodel.Cell", "CELL_TYPE_BLANK"); ctype(5) = __java_get__ ("org.apache.poi.ss.usermodel.Cell", "CELL_TYPE_BOOLEAN"); ctype(6) = __java_get__ ("org.apache.poi.ss.usermodel.Cell", "CELL_TYPE_ERROR"); endif rstatus = 0; jerror = 0; wb = xls.workbook; ## Check if requested worksheet exists in the file & if so, get pointer nr_of_sheets = wb.getNumberOfSheets (); if (isnumeric (wsh)) if (wsh > nr_of_sheets) error (sprintf ("Worksheet ## %d bigger than nr. of sheets (%d) in file %s",... wsh, nr_of_sheets, xls.filename)); endif sh = wb.getSheetAt (wsh - 1); ## POI sheet count 0-based else sh = wb.getSheet (wsh); if (isempty (sh)) error (sprintf ("Worksheet %s not found in file %s", wsh, xls.filename)); endif end ## Check ranges firstrow = sh.getFirstRowNum (); ## 0-based lastrow = sh.getLastRowNum (); ## 0-based if (isempty (cellrange)) if (ischar (wsh)) ## get numeric sheet index ii = wb.getSheetIndex (sh) + 1; else ii = wsh; endif [ firstrow, lastrow, lcol, rcol ] = getusedrange (xls, ii); if (firstrow == 0 && lastrow == 0) ## Empty sheet rawarr = {}; printf ("Worksheet '%s' contains no data\n", sh.getSheetName ()); rstatus = 1; return; else nrows = lastrow - firstrow + 1; ncols = rcol - lcol + 1; endif else ## Translate range to HSSF POI row & column numbers [topleft, nrows, ncols, firstrow, lcol] = parse_sp_range (cellrange); lastrow = firstrow + nrows - 1; rcol = lcol + ncols - 1; endif ## Create formula evaluator (needed to infer proper cell type into rawarr) frm_eval = wb.getCreationHelper().createFormulaEvaluator (); ## Read contents into rawarr rawarr = cell (nrows, ncols); ## create placeholder for ii = firstrow:lastrow irow = sh.getRow (ii-1); if (! isempty (irow)) scol = irow.getFirstCellNum; ecol = irow.getLastCellNum - 1; for jj = lcol:rcol scell = irow.getCell (jj-1); if (! isempty (scell)) ## Explore cell contents type_of_cell = scell.getCellType (); if (type_of_cell == ctype(3)) ## Formula if (! spsh_opts.formulas_as_text) try ## Because not al Excel formulas have been implemented in POI cvalue = frm_eval.evaluate (scell); type_of_cell = cvalue.getCellType(); ## Separate switch because form.eval. yields different type switch type_of_cell case ctype (1) ## Numeric rawarr {ii+1-firstrow, jj+1-lcol} = cvalue.getNumberValue (); case ctype(2) ## String rawarr {ii+1-firstrow, jj+1-lcol} = ... char (cvalue.getStringValue ()); case ctype (5) ## Boolean rawarr {ii+1-firstrow, jj+1-lcol} = cvalue.BooleanValue (); otherwise ## Nothing to do here endswitch ## Set cell type to blank to skip switch below type_of_cell = ctype(4); catch ## In case of formula errors we take the cached results type_of_cell = scell.getCachedFormulaResultType (); ## We only need one warning even for multiple errors ++jerror; end_try_catch endif endif ## Preparations done, get data values into data array switch type_of_cell case ctype(1) ## 0 Numeric rawarr {ii+1-firstrow, jj+1-lcol} = scell.getNumericCellValue (); case ctype(2) ## 1 String rawarr {ii+1-firstrow, jj+1-lcol} = ... char (scell.getRichStringCellValue ()); case ctype(3) if (spsh_opts.formulas_as_text) tmp = char (scell.getCellFormula ()); rawarr {ii+1-firstrow, jj+1-lcol} = ["=" tmp]; endif case ctype(4) ## 3 Blank ## Blank; ignore until further notice case ctype(5) ## 4 Boolean rawarr {ii+1-firstrow, jj+1-lcol} = scell.getBooleanCellValue (); otherwise ## 5 Error ## Ignore endswitch endif endfor endif endfor if (jerror > 0) warning (sprintf ("%d cached values instead of formula evaluations read.\n",... jerror)); endif rstatus = 1; xls.limits = [lcol, rcol; firstrow, lastrow]; endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OTK_oct2spsh__.m0000644000000000000000000000013213226215407017556 xustar0030 mtime=1515789063.584155165 30 atime=1515789063.584155165 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OTK_oct2spsh__.m0000644000175000017500000001466013226215407020025 0ustar00olafolaf00000000000000## Copyright (C) 2010-2017 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 . ## __OTK_oct2spsh__ - read ODS spreadsheet data using Java & odftoolkit v 0.8.6+. ## You need proper java-for-octave & odfdom.jar 0.8.6+ & xercesImpl.jar 2.9.1 ## in your javaclasspath. ## ## Author: Philip Nenhuis ## Created: 2010-03-16, after oct2jotk2ods() function [ ods, rstatus ] = __OTK_oct2spsh__ (c_arr, ods, wsh, crange, spsh_opts) persistent ctype; if (isempty (ctype)) ## Number, Boolean, String, Formula, Empty; Date, Time - last two aren't used ctype = [1, 2, 3, 4, 5, 6, 7]; endif rstatus = 0; changed = 0; newsh = 0; ## Get contents and table stuff from the workbook odfcont = ods.workbook; ## Use a local copy just to be sure. octave ## makes physical copies only when needed (?) odfroot = odfcont.getRootElement (); offsprdsh = ods.app.getContentRoot(); if (strcmp (ods.odfvsn, "0.8.7") || strfind (ods.odfvsn, "0.8.8")) spsh = odfcont.getDocument (); else spsh = odfcont.getOdfDocument (); endif ## Get some basic spreadsheet data from the pointer using ODFtoolkit autostyles = odfcont.getOrCreateAutomaticStyles(); officestyles = ods.app.getOrCreateDocumentStyles(); ## Parse sheets ("tables") from ODS file sheets = ods.app.getTableList(); nr_of_sheets = sheets.size (); ## Check user input & find sheet pointer if (! isnumeric (wsh)) try sh = ods.app.getTableByName (wsh); ## We do need a sheet index number... ii = 0; while (ischar (wsh) && ii < nr_of_sheets) sh_nm = sh.getTableName (); if (strcmp (sh_nm, wsh)) wsh = ii + 1; else ++ii; endif endwhile catch newsh = 1; end_try_catch if (isempty (sh)) newsh = 1; endif elseif (wsh < 1) ## Negative sheet number: error (sprintf ("Illegal worksheet nr. %d\n", wsh)); elseif (wsh > nr_of_sheets) newsh = 1; else sh = sheets.get (wsh - 1); endif ## Check size of data array & range / capacity of worksheet & prepare vars [nr, nc] = size (c_arr); [topleft, nrows, ncols, trow, lcol] = ... spsh_chkrange (crange, nr, nc, ods.xtype, ods.filename); --trow; --lcol; ## Zero-based row ## & col ## if (nrows < nr || ncols < nc) warning ("Array truncated to fit in range\n"); c_arr = c_arr(1:nrows, 1:ncols); endif ## Parse data array, setup typarr and throw out NaNs to speed up writing; typearr = spsh_prstype (c_arr, nrows, ncols, ctype, spsh_opts); if (! spsh_opts.formulas_as_text) ## Find formulas (designated by a string starting with "=" and ending in ")") fptr = cellfun (@(x) ischar (x) && strncmp (x, "=", 1) ... && strncmp (x(end:end), ")", 1), c_arr); typearr(fptr) = ctype(4); ## FORMULA endif ## Prepare spreadsheet for writing (size, etc.). If needed create new sheet if (newsh) if (ods.changed > 2) ## New spreadsheet, use default first sheet sh = sheets.get (0); else ## Create a new sheet using DOM API. This part works OK. sh = sheets.get (nr_of_sheets - 1).newTable (spsh, nrows, ncols); endif changed = 1; if (isnumeric (wsh)) ## Give sheet a name str = sprintf ("Sheet%d", wsh); sh.setTableName (str); wsh = str; else ## Assign name to sheet and change wsh into numeric pointer sh.setTableName (wsh); endif ## printf ("Sheet %s added to spreadsheet.\n", wsh); else ## Add "physical" rows & columns. Spreadsheet max. capacity checks have been done above ## Add spreadsheet data columns if needed. Compute nr of extra columns & rows. curr_ncols = sh.getColumnCount (); ii = max (0, lcol + ncols - curr_ncols); if (ii == 1) nwcols = sh.appendColumn (); else nwcols = sh.appendColumns (ii); endif ## Add spreadsheet rows if needed curr_nrows = sh.getRowCount (); ii = max (0, trow + nrows - curr_nrows); if (ii == 1) nwrows = sh.appendRow (); else nwrows = sh.appendRows (ii); endif endif ## Transfer array data to sheet for ii=1:nrows for jj=1:ncols ocell = sh.getCellByPosition (jj+lcol-1, ii+trow-1); if (! isempty (ocell )) ## Might be spanned (merged), hidden, .... ## Number, String, Boolean, Date, Time try switch typearr (ii, jj) case {1, 6, 7} ## Numeric, Date, Time ocell.setDoubleValue (c_arr{ii, jj}); case 2 ## Logical / Boolean ## ocell.setBooleanValue (c_arr{ii, jj}); ## Doesn't work, bug in odfdom 0.8.6 ## Bug workaround: 1. Remove all cell contents ocell.removeContent (); ## 2. Switch to TableTableElement API tocell = ocell.getOdfElement (); tocell.setAttributeNS ("office", "office:value-type", "boolean"); ## 3. Add boolean-value attribute. ## This is only accepted in TTE API with a NS tag (actual bug, IMO) if (c_arr {ii,jj}) tocell.setAttributeNS ("office", "office:boolean-value", "true"); else tocell.setAttributeNS ("office", "office:boolean-value", "false"); endif case 3 ## String ocell.setStringValue (c_arr{ii, jj}); case 4 ## Formula ocell.setFormula (c_arr{ii, jj}); otherwise ## 5, empty and catch-all ## The above is all octave has to offer & java can accept... endswitch changed = 1; catch printf ("\n"); end_try_catch endif endfor endfor if (changed) ods.changed = max (min (ods.changed, 2), changed); ## Preserve 2 (new file), 1 (existing) rstatus = 1; endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__JXL_chk_sprt__.m0000644000000000000000000000013213226215407017626 xustar0030 mtime=1515789063.572154929 30 atime=1515789063.572154929 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__JXL_chk_sprt__.m0000644000175000017500000000267513226215407020100 0ustar00olafolaf00000000000000## Copyright (C) 2014-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{varagout} =} __JXL_chk_sprt__ (@var{varargin}) ## Undocumented internal function ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2014-10-31 function [chk, missing3] = __JXL_chk_sprt__ (jcp, dbug=0) chk = 0; if (dbug > 1) printf ("\nJExcelAPI (.xls (incl. BIFF5 read)) :\n"); endif entries3 = {"jxl"}; [jpchk, missing3] = chk_jar_entries (jcp, entries3, dbug); missing3 = entries3 (find (missing3)); if (jpchk >= numel (entries3)) chk = 1; if (dbug > 1) printf (" => Java/JExcelAPI (JXL) OK.\n"); endif elseif (dbug > 1) printf (" => Not all required classes (.jar) for JXL in classpath\n"); endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OCT_spsh_info__.m0000644000000000000000000000013213226215407017771 xustar0030 mtime=1515789063.580155087 30 atime=1515789063.580155087 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OCT_spsh_info__.m0000644000175000017500000000246613226215407020241 0ustar00olafolaf00000000000000## Copyright (C) 2013-2017 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 Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} __OCT_spsh_info__ (@var{x} @var{y}) ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2013-09-10 ## Updates: ## function [ sh_names ] = __OCT_spsh_info__ (ods) sh_names(:, 1) = ods.sheets.sh_names; for ii=1:numel (ods.sheets.sh_names) [ tr, lr, lc, rc ] = getusedrange (ods, ii); if (tr) sh_names(ii, 2) = sprintf ("%s:%s", calccelladdress (tr, lc),... calccelladdress (lr, rc)); else sh_names(ii, 2) = "Empty"; endif endfor endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OCT_gnm2oct__.m0000644000000000000000000000013213226215407017352 xustar0030 mtime=1515789063.576155008 30 atime=1515789063.576155008 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OCT_gnm2oct__.m0000644000175000017500000001312613226215407017615 0ustar00olafolaf00000000000000## Copyright (C) 2013-2017 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 Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## @deftypefn {Function File} [@var{raw}, @var{ods}, @var{rstatus} = __OCT_gnm2oct__ (@var{ods}, @var{wsh}, @var{range}, @var{opts}) ## Internal function for reading data from a Gnumeric worksheet ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2013-10-01 function [ rawarr, xls, rstatus] = __OCT_gnm2oct__ (xls, wsh, cellrange='', spsh_opts) rstatus = 0; ## Check if requested worksheet exists in the file & if so, get sheet if (isnumeric (wsh)) if (wsh > numel (xls.sheets.sh_names) || wsh < 1) error ("xls2oct: sheet number (%d) out of range (1 - %d)", wsh, numel (xls.sheets.sh_names)); endif elseif (ischar (wsh)) idx = find (strcmp (wsh, xls.sheets.sh_names)); if (isempty (idx)) error ("xls2oct: sheet '%s' not found in file %s", wsh, xls.filename); endif wsh = idx; endif ## Get requested sheet from info in file struct pointer. Open file fid = fopen (xls.workbook, "r"); ## Go to start of requested sheet. This requires reading from start, not ## from after 1st xml id line fseek (fid, xls.sheets.shtidx(wsh), 'bof'); ## Compute size of requested chunk nchars = xls.sheets.shtidx(wsh+1) - xls.sheets.shtidx(wsh); ## Get the sheet xml = fread (fid, nchars, "char=>char").'; fclose (fid); ## Add xml to struct pointer to avoid __OCT_getusedrange__ to read it again xls.xml = xml; ## Check ranges [ firstrow, lastrow, leftcol, rightcol ] = getusedrange (xls, wsh); ## Remove xml field xls.xml = []; xls = rmfield (xls, "xml"); if (isempty (cellrange)) if (firstrow == 0 && lastrow == 0) ## Empty sheet rawarr = {}; printf ("Worksheet '%s' contains no data\n", xls.sheets.sh_names{wsh}); rstatus = 1; return; else nrows = lastrow - firstrow + 1; ncols = rightcol - leftcol + 1; endif else [~, nr, nc, tr, lc] = parse_sp_range (cellrange); ## Check if requested range exists if (tr > lastrow || lc > rightcol) ## Out of occupied range warning ("xls2oct: requested range outside occupied range\n"); rawarr = {}; xls.limits = []; return endif lastrow = min (lastrow, firstrow + nr - 1); rightcol = min (rightcol, leftcol + nc - 1); endif ## Get cell nodes cells = getxmlnode (xml, "gnm:Cells"); ## Pattern gets most required tokens in one fell swoop pattrn = '(.*?)'; allvals = cell2mat (regexp (cells, pattrn, "tokens")); if (! isempty (allvals)) ## Reshape into 4 x ... cell array allvals = reshape (allvals, 4, numel (allvals) / 4); else allvals= cell(4, 0); endif ## For those cells w/o ValueType | ExprId tags pattrn = '(.*?)'; smevals = cell2mat (regexp (cells, pattrn, "tokens")); ## Reshape these into 3 X ... cell array, expand to 4 X ... if (! isempty (smevals)) smevals = reshape (smevals, 3, numel (smevals) / 3); smevals(4, :) = smevals(3, :); smevals(3, :) = 0; else smevals= cell(4, 0); endif ## Try to concatenate both allvals = [ allvals smevals ]; ## Convert 0-based rw/column indices to 1-based numeric allvals(1:2, :) = num2cell (str2double (allvals(1:2, :)) + 1); ## Convert cell type values to double allvals(3, :) = num2cell (str2double (allvals(3, :))); ## Convert numeric cell values to double in = find ([allvals{3,:}] == 40); allvals(4, in) = num2cell (str2double(allvals(4, in))'); ## Convert boolean values to logical il = find ([allvals{3,:}] == 20); allvals(4, il) = num2cell (cellfun (@(x) strcmpi (x, "true"), allvals(4, il))); ## Get limits of data rectangle trow = min (cell2mat (allvals(1, :))); brow = max (cell2mat (allvals(1, :))); rcol = max (cell2mat (allvals(2, :))); lcol = min (cell2mat (allvals(2, :))); xls.limits = [lcol rcol; trow brow]; ## Create data array rawarr = cell (brow-trow+1, rcol-lcol+1); ## Compute linear indices into data array from 1-based row/col indices idx = sub2ind (size (rawarr), [allvals{1, :}] - trow + 1, [allvals{2,:}] - lcol + 1); ## And assign cell values to data array rawarr(idx) = allvals(4, :); ## FIXME maybe reading parts of the data can be done faster above by better regexps ## or sorting on row & truncating followed by sorting on columns and truncating if (! isempty (cellrange)) ## We'll do it the easy way: just read all data, then return only the requested part xls.limits = [max(lcol, lc), min(rcol, lc+nc-1); max(trow, tr), min(brow, tr+nr-1)]; ## Correct spreadsheet locations for lower right shift or raw rc = trow - 1; cc = lcol - 1; rawarr = rawarr(xls.limits(2, 1)-rc : xls.limits(2, 2)-rc, xls.limits(1, 1)-cc : xls.limits(1, 2)-cc); endif if (! isempty (allvals)) rstatus = 1; endif endfunction io-2.4.10/inst/private/PaxHeaders.5973/spsh_prstype.m0000644000000000000000000000013213226215407017243 xustar0030 mtime=1515789063.600155479 30 atime=1515789063.600155479 30 ctime=1515789065.028183488 io-2.4.10/inst/private/spsh_prstype.m0000644000175000017500000000660013226215407017505 0ustar00olafolaf00000000000000## Copyright (C) 2010-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [ @var{type-array} ] = spsh_prstype ( @var{iarray}, @var{rowsize}, @var{colsize}, @var{celltypes}, @var{options}) ## (Internal function) Return rectangular array with codes for cell types in rectangular input cell array @var{iarray}. ## Codes are contained in input vector in order of Numeric, Boolean, Text, Formula and Empty, resp. ## ## spsh_prstype should not be invoked directly but rather through oct2xls or oct2ods. ## ## Example: ## ## @example ## typarr = spsh_chkrange (cellarray, nr, nc, ctypes, options); ## @end example ## ## @end deftypefn ## Author: Philip Nienhuis, ## Created: 2010-08-02 function [ typearr ] = spsh_prstype (obj, nrows, ncols, ctype, spsh_opts) ## ctype index: ## 1 = numeric ## 2 = boolean ## 3 = text ## 4 = formula ## 5 = error / NaN / empty typearr = ctype(5) * ones (nrows, ncols); ## type "EMPTY", provisionally obj2 = cell (size (obj)); ## Temporary storage for strings txtptr = cellfun ('isclass', obj, 'char'); ## type "STRING" replaced by "NUMERIC" obj2(txtptr) = obj(txtptr); obj(txtptr) = ctype(3); ## Save strings in a safe place emptr = cellfun ("isempty", obj); obj(emptr) = ctype(5); ## Set empty cells to NUMERIC lptr = cellfun ("islogical" , obj); ## Find logicals... obj2(lptr) = obj(lptr); ## .. and set them to BOOLEAN ptr = cellfun ("isnan", obj); ## Find NaNs & set to BLANK typearr(ptr) = ctype(5); typearr(! ptr) = ctype(1); ## All other cells are now numeric obj(txtptr) = obj2(txtptr); ## Copy strings back into place obj(lptr) = obj2(lptr); ## Same for logicals obj(emptr) = -1; ## Add in a filler value for empty cells typearr(txtptr) = ctype(3); ## ...and clean up typearr(emptr) = ctype(5); ## EMPTY typearr(lptr) = ctype(2); ## BOOLEAN if (! spsh_opts.formulas_as_text) ## Find formulas (designated by a string starting with "=") fptr = cellfun (@(x) ischar (x) && strncmp (x, "=", 1), obj); typearr(fptr) = ctype(4); ## FORMULA endif endfunction ## FIXME -- reinstate these tests one there if a way is found to test private ## functions directly ##%!test ##%! tstobj = {1.5, true, []; 'Text1', '=A1+B1', '=SQRT(A1)'; NaN, {}, 0}; ##%! typarr = spsh_prstype (tstobj, 3, 3, [1 2 3 4 5], struct ("formulas_as_text", 0)); ##%! assert (typarr, [1 2 5; 3 4 4; 5 5 1]); ##%!test ##%! tstobj = {1.5, true, []; 'Text1', '=A1+B1', '=SQRT(A1)'; NaN, {}, 0}; ##%! typarr = spsh_prstype (tstobj, 3, 3, [1 2 3 4 5], struct ("formulas_as_text", 1)); ##%! assert (typarr, [1 2 5; 3 3 3; 5 5 1]); io-2.4.10/inst/private/PaxHeaders.5973/__UNO_spsh_info__.m0000644000000000000000000000013213226215407020005 xustar0030 mtime=1515789063.592155322 30 atime=1515789063.592155322 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__UNO_spsh_info__.m0000644000175000017500000000250613226215407020250 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## __UNO_spsh_info__ ## Author: Philip Nienhuis ## Created: 2012-10-12 function [sh_names] = __UNO_spsh_info__ (xls) sheets = xls.workbook.getSheets (); sheetnames = sheets.getElementNames (); ## A Java object, NOT a cell array sh_cnt = numel (sheetnames); sh_names = cell (sh_cnt, 2); for ii=1:sh_cnt sh_names(ii, 1) = sheetnames(ii); [ tr, lr, lc, rc ] = getusedrange (xls, ii); if (tr) sh_names(ii, 2) = ... sprintf ("%s:%s", calccelladdress (tr, lc), calccelladdress (lr, rc)); else sh_names(ii, 2) = "Empty or Chart"; endif endfor endfunction io-2.4.10/inst/private/PaxHeaders.5973/__POI_oct2spsh__.m0000644000000000000000000000013213226215407017550 xustar0030 mtime=1515789063.588155243 30 atime=1515789063.588155243 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__POI_oct2spsh__.m0000644000175000017500000001345713226215407020022 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [ @var{xlso}, @var{rstatus} ] = __POI_oct2spsh__ ( @var{arr}, @var{xlsi}) ## @deftypefnx {Function File} [ @var{xlso}, @var{rstatus} ] = __POI_oct2spsh__ (@var{arr}, @var{xlsi}, @var{wsh}) ## @deftypefnx {Function File} [ @var{xlso}, @var{rstatus} ] = __POI_oct2spsh__ (@var{arr}, @var{xlsi}, @var{wsh}, @var{range}) ## @deftypefnx {Function File} [ @var{xlso}, @var{rstatus} ] = __POI_oct2spsh__ (@var{arr}, @var{xlsi}, @var{wsh}, @var{range}, @var{options}) ## ## Add data in 1D/2D CELL array @var{arr} into a range with upper left ## cell equal to @var{topleft} in worksheet @var{wsh} in an Excel ## spreadsheet file pointed to in structure @var{range}. ## Return argument @var{xlso} equals supplied argument @var{xlsi} and is ## updated by __POI_oct2spsh__. ## ## __POI_oct2spsh__ should not be invoked directly but rather through oct2xls. ## ## Example: ## ## @example ## [xlso, status] = __POI_oct2spsh__ ("arr", xlsi, "Third_sheet", "AA31"); ## @end example ## ## @seealso {oct2xls, xls2oct, xlsopen, xlsclose, xlsread, xlswrite} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-11-26 function [ xls, rstatus ] = __POI_oct2spsh__ (obj, xls, wsh, crange, spsh_opts) ## Preliminary sanity checks if (isempty (strcmpi (xls.filename(end-3:end), ".xls"))) error ("POI interface can only write to Excel .xls or .xlsx files") endif persistent ctype; if (isempty (ctype)) ## Get cell types. Beware as they start at 0 not 1 ctype(1) = __java_get__ ("org.apache.poi.ss.usermodel.Cell", "CELL_TYPE_NUMERIC"); ## 0 ctype(2) = __java_get__ ("org.apache.poi.ss.usermodel.Cell", "CELL_TYPE_BOOLEAN"); ## 4 ctype(3) = __java_get__ ("org.apache.poi.ss.usermodel.Cell", "CELL_TYPE_STRING"); ## 1 ctype(4) = __java_get__ ("org.apache.poi.ss.usermodel.Cell", "CELL_TYPE_FORMULA"); ## 2 ctype(5) = __java_get__ ("org.apache.poi.ss.usermodel.Cell", "CELL_TYPE_BLANK"); ## 3 endif ## scratch vars rstatus = 0; f_errs = 0; ## Check if requested worksheet exists in the file & if so, get pointer try nr_of_sheets = xls.workbook.getNumWorkSheets (); catch nr_of_sheets = xls.workbook.getNumberOfSheets (); end_try_catch if (isnumeric (wsh)) if (wsh > nr_of_sheets) ## Watch out as a sheet called Sheet%d can exist with a lower index... strng = sprintf ("Sheet%d", wsh); ii = 1; while (! isempty (xls.workbook.getSheet (strng)) && (ii < 5)) strng = ["_" strng]; ++ii; endwhile if (ii >= 5) error (sprintf( " > 5 sheets named [_]Sheet%d already present!", wsh)); endif sh = xls.workbook.createSheet (strng); xls.changed = min (xls.changed, 2); ## Keep 2 for new files else sh = xls.workbook.getSheetAt (wsh - 1); ## POI sheet count 0-based endif printf ("(Writing to worksheet %s)\n", sh.getSheetName ()); else sh = xls.workbook.getSheet (wsh); if (isempty (sh)) ## Sheet not found, just create it sh = xls.workbook.createSheet (wsh); xls.changed = min (xls.changed, 2); ## Keep 2 or 3 f. new files endif endif ## Parse date ranges [nr, nc] = size (obj); [topleft, nrows, ncols, trow, lcol] = ... spsh_chkrange (crange, nr, nc, xls.xtype, xls.filename); if (nrows < nr || ncols < nc) warning ("Array truncated to fit in range\n"); obj = obj(1:nrows, 1:ncols); endif ## Prepare type array typearr = spsh_prstype (obj, nrows, ncols, ctype, spsh_opts); if (! spsh_opts.formulas_as_text) ## Remove leading "=" from formula strings ## FIXME should be easier using typearr<4> info fptr = (! (2 * (ones (size (typearr))) .- typearr)); obj(fptr) = cellfun (@(x) x(2:end), obj(fptr), "Uniformoutput", false); endif ## Create formula evaluator frm_eval = xls.workbook.getCreationHelper ().createFormulaEvaluator (); for ii=1:nrows ll = ii + trow - 2; ## Java POI's row count 0-based row = sh.getRow (ll); if (isempty (row)) row = sh.createRow (ll); endif for jj=1:ncols kk = jj + lcol - 2; ## POI's column count is 0-based if (typearr(ii, jj) == ctype(5)) ## Empty cells cell = row.createCell (kk, ctype(5)); elseif (typearr(ii, jj) == ctype(4)) ## Formulas ## Try-catch needed as there's no guarantee for formula correctness try cell = row.createCell (kk, ctype(4)); cell.setCellFormula (obj{ii,jj}); catch ++f_errs; cell.setCellType (ctype (3)); ## Enter formula as text cell.setCellValue (obj{ii, jj}); end_try_catch else cell = row.createCell (kk, typearr(ii,jj)); if (isnumeric (obj{ii, jj})) cell.setCellValue (obj{ii, jj}); else cell.setCellValue (obj{ii, jj}); endif endif endfor endfor if (f_errs) printf ("%d formula errors encountered - please check input array\n", f_errs); endif xls.changed = max (xls.changed, 1); ## Preserve a "2" rstatus = 1; endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OCT_getnmranges__.m0000644000000000000000000000013213226215407020313 xustar0030 mtime=1515789063.572154929 30 atime=1515789063.572154929 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OCT_getnmranges__.m0000644000175000017500000000253013226215407020553 0ustar00olafolaf00000000000000## Copyright (C) 2015-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{retval} =} __OCT_getnmranges__ (@var{input1}, @var{input2}) ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2015-09-18 function [nmranges] = __OCT_getnmranges__ (xls) [~, ~, ext] = fileparts (xls.filename); switch ext case ".xlsx" nmranges = __OCT_xlsx_getnmranges__ (xls); case ".ods" nmranges = __OCT_ods_getnmranges__ (xls); case ".gnumeric" nmranges = __OCT_gnm_getnmranges__ (xls); otherwise error ("This should not happen - pls file bug report"); endswitch endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OTK_getnmranges__.m0000644000000000000000000000013213226215407020323 xustar0030 mtime=1515789063.580155087 30 atime=1515789063.580155087 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OTK_getnmranges__.m0000644000175000017500000000211713226215407020564 0ustar00olafolaf00000000000000## Copyright (C) 2015-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{nmr} =} __OTK_getnmranges__ (@var{ptr) ## Internal function. ## ## @seealso{} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2015-09-20 function [nmr] = __OTK_getnmranges__ (ods) ## Currently just a stub. Named ranges do not work in ODF Toolkit nmr = cell (0, 3); endfunction io-2.4.10/inst/private/PaxHeaders.5973/__OXS_spsh_close__.m0000644000000000000000000000013213226215407020167 xustar0030 mtime=1515789063.588155243 30 atime=1515789063.588155243 30 ctime=1515789065.028183488 io-2.4.10/inst/private/__OXS_spsh_close__.m0000644000175000017500000000272513226215407020435 0ustar00olafolaf00000000000000## Copyright (C) 2012-2017 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 Octave; see the file COPYING. If not, see ## . ## __OXS_spsh_close__ - internal function: close a spreadsheet file using JXL ## Author: Philip Nienhuis ## Created: 2012-10-12 function [ xls ] = __OXS_spsh_close__ (xls) ofile = 1.5; if (xls.changed > 0 && xls.changed < 3) if (isfield (xls, "nfilename")) fname = xls.nfilename; else fname = xls.filename; endif try xlsout = javaObject ("java.io.FileOutputStream", fname); xls.workbook.write (xlsout); xlsout.close (); xls.changed = 0; catch if (! strcmp (class (ofile), "double")) ofile.close (); endif warning ("__OXS_spsh_close__: error trying to close OXS file ptr"); end_try_catch endif xls.workbook.close (); endfunction io-2.4.10/inst/PaxHeaders.5973/getxmlnode.m0000644000000000000000000000013213226215407015174 xustar0030 mtime=1515789063.556154616 30 atime=1515789063.556154616 30 ctime=1515789065.028183488 io-2.4.10/inst/getxmlnode.m0000644000175000017500000000633413226215407015442 0ustar00olafolaf00000000000000## Copyright (C) 2013-2017 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 Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## @deftypefn {Function File} [ @var{node}, @var{s}, @var{e} ] = getxmlnode (@var{xml}, @var{tag}) ## @deftypefnx {Function File} [ @var{node}, @var{s}, @var{e} ] = getxmlnode (@var{xml}, @var{tag}, @var{is}) ## @deftypefnx {Function File} [ @var{node}, @var{s}, @var{e} ] = getxmlnode (@var{xml}, @var{tag}, @var{is}, @var{contnt}) ## Get a string representing the first xml @var{tag} node starting at position ## @var{is} in xml text string @var{xml}, and return start and end indices. If ## @var{is} is omitted it defaults to 1 (start of @var{xml}). If @var{contnt} ## is TRUE, return the portion of the node between the outer tags. ## ## @seealso{getxmlattv} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2013-09-08 function [ node, spos, epos ] = getxmlnode (xml, tag, is=1, contnt=0) if (nargin < 2) print_usage; endif if (nargin >= 3 && isempty (is)) is = 1; endif ## Input validation if (! ischar (xml) || ! ischar (tag)) error ("getxmlnode: text strings expected for first two args\n"); elseif (nargin==3 && (! islogical (is) && ! isnumeric (is))) error ("getxmlnode: logical or numerical value expected for arg #3\n"); elseif (nargin==4 && (! islogical (contnt) && ! isnumeric (contnt))) error ("getxmlnode: logical or numerical value expected for arg #3\n"); endif is = max (is, 1); node = ''; ## Start tag must end with either />, a space preceding an attribute, or > ## Search order is vital as /> (single node) is otherwise easily missed spos = regexp (xml(is:end), sprintf ("<%s(/>| |>)", tag), "once"); if (! isempty (spos)) ## Apparently a node exists. Get its end. Maybe it is a single node ## ending in "/>" spos = spos(1); [~, epos] = regexp (xml(is+spos:end), sprintf ("(|%s[^><]*/>)", tag, tag), "once"); if (! isempty (epos)) epos = epos(1); node = xml(is+spos-1 : is+spos+epos(1)-1); if (contnt) if (strcmp (node(end-1:end), "/>")) ## Single node tag. Return empty string node = ''; else ## Get contents between end of opening tag en start of end tag node = node(index (node, ">", "first")+1 : index (node, "<", "last")-1); endif endif else error ("getxmlnode: couldn't find matching end tag for %s", tag); endif ## Update position pointers relative to input string epos += is + spos - 1; spos += is - 1; else ## No node found; reset pointers spos = 0; epos = 0; endif endfunction io-2.4.10/inst/PaxHeaders.5973/calccelladdress.m0000644000000000000000000000013213226215407016136 xustar0030 mtime=1515789063.556154616 30 atime=1515789063.556154616 30 ctime=1515789065.028183488 io-2.4.10/inst/calccelladdress.m0000644000175000017500000000376613226215407016412 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## calccelladdress (R, C) - compute spreadsheet style cell address from ## row & column index (both 1-based). ## ## Max column index currently set to 18278 (max ODS: 1024, OOXML: 16384). ## Row limits for ODF and OOXML are 65536 and 1048576, resp. ## Author: Philip Nienhuis ## Created: 2009-12-12 function [ celladdress ] = calccelladdress (row, column) if (nargin < 2) error ("calccelladdress: Two arguments needed"); endif if (column > 18278 || column < 1) error ("Specified column out of range (1..18278)"); endif if (row > 1048576 || row < 1) error ("Specified row out of range (1..1048576)"); endif celladdress = sprintf ("%s%d", num2col (column), row); endfunction %!test %! a = calccelladdress (1, 1); %! assert (a, "A1"); %!test %! a = calccelladdress (378, 28); %! assert (a, "AB378"); %!test %! a = calccelladdress (65536, 1024); %! assert (a, "AMJ65536"); %!test %! a = calccelladdress (1048576, 16384); %! assert (a, "XFD1048576"); %!test %! a = calccelladdress (378, 26); %! assert (a, "Z378"); %!test %! a = calccelladdress (378, 702); %! assert (a, "ZZ378"); %!test %! a = calccelladdress (378, 701); %! assert (a, "ZY378"); %!test %! a = calccelladdress (378, 703); %! assert (a, "AAA378"); %!test %! a = calccelladdress (378, 676); %! assert (a, "YZ378"); io-2.4.10/inst/PaxHeaders.5973/parsecell.m0000644000000000000000000000013213226215407015000 xustar0030 mtime=1515789063.564154773 30 atime=1515789063.564154773 30 ctime=1515789065.028183488 io-2.4.10/inst/parsecell.m0000644000175000017500000001340113226215407015237 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [ @var{numarr}, @var{txtarr}, @var{lim} ] = parsecell (@var{rawarr}) ## @deftypefnx {Function File} [ @var{numarr}, @var{txtarr}, @var{lim} ] = parsecell (@var{rawarr}, @var{limits}) ## ## Divide a heterogeneous 2D cell array into a 2D numeric array and a ## 2D cell array containing only strings. Both returned arrays are ## trimmed from empty outer rows and columns. ## This function is particularly useful for parsing cell arrays returned ## by functions reading spreadsheets (e.g., xlsread, odsread). ## ## Optional return argument @var{lim} contains two field with the outer ## column and row numbers of @var{numarr} and @var{txtarr} in the ## original array @var{rawarr}. ## Optional input argument @var{limits} can either be the spreadsheet ## data limits returned in the spreadsheet file pointer struct ## (field xls.limits or ods.limits), or the file ptr struct itself. ## If one of these is specified, optional return argument @var{lim} ## will contain the real spreadsheet row & column numbers enclosing ## the origins of the numerical and text data returned in @var{numarr} ## and @var{txtarr}. ## ## Examples: ## ## @example ## [An, Tn] = parsecell (Rn); ## (which returns the numeric contents of Rn into array An and the ## text data into array Tn) ## @end example ## ## @example ## [An, Tn, lims] = parsecell (Rn, xls.limits); ## (which returns the numeric contents of Rn into array An and the ## text data into array Tn.) ## @end example ## ## @seealso {xlsread, odsread, xls2oct, ods2oct} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-12-13 function [ numarr, txtarr, lim ] = parsecell (rawarr, arg2=[]) if (isstruct (arg2)) ## Assume a file ptr has been supplied if (isfield (arg2, "limits")) rawlimits = arg2.limits; else warning ("Invalid file ptr supplied to parsecell() - limits ignored.\n"); endif else rawlimits = arg2; endif lim = struct ( "numlimits", [], "txtlimits", []); numarr = []; txtarr = {}; if (! isempty (rawarr)) ## Valid data returned. Divide into numeric & text arrays no_txt = 0; no_num = 0; if (all (all (cellfun (@isnumeric, rawarr)))) numarr = num2cell (rawarr); no_txt = 1; elseif (iscellstr (rawarr)) txtarr = cellstr (rawarr); no_num = 1; endif ## Prepare parsing [nrows, ncols] = size (rawarr); ## Find text entries in raw data cell array txtptr = cellfun ("isclass", rawarr, "char"); if (~no_txt) ## Prepare text array. Create placeholder for text cells txtarr = cell (size (rawarr)); txtarr(:) = {""}; if (any (any (txtptr))) ## Copy any text cells found into place holder txtarr(txtptr) = rawarr(txtptr); ## Clean up text array (find leading / trailing empty ## rows & columns) irowt = 1; while (! any (txtptr(irowt, :))); irowt++; endwhile irowb = nrows; while (! any (txtptr(irowb, :))); irowb--; endwhile icoll = 1; while (! any (txtptr(:, icoll))); icoll++; endwhile icolr = ncols; while (! any (txtptr(:, icolr))); icolr--; endwhile ## Crop textarray txtarr = txtarr(irowt:irowb, icoll:icolr); lim.txtlimits = [icoll, icolr; irowt, irowb]; if (! isempty (rawlimits)) correction = [1; 1]; lim.txtlimits(:,1) = lim.txtlimits(:,1) + rawlimits(:,1) - correction; lim.txtlimits(:,2) = lim.txtlimits(:,2) + rawlimits(:,1) - correction; endif else ## If no text cells found return empty text array txtarr = {}; endif endif if (! no_num) ## Prepare numeric array. Set all text & empty cells to NaN. ## First get their locations emptr = cellfun ("isempty", rawarr); emptr(find (txtptr)) = 1; if (all (all (emptr))) numarr= []; else ## Find leading & trailing empty rows irowt = 1; while (all(emptr(irowt, :))); irowt++; endwhile irowb = nrows; while (all(emptr(irowb, :))); irowb--; endwhile icoll = 1; while (all(emptr(:, icoll))); icoll++; endwhile icolr = ncols; while (all(emptr(:, icolr))); icolr--; endwhile ## Pre-crop rawarr rawarr = rawarr (irowt:irowb, icoll:icolr); ## Build numerical array numarr = zeros (irowb-irowt+1, icolr-icoll+1); ## Watch out for scalar (non-empty) numarr where emptr = 0 if (sum (emptr(:)) > 0) numarr(emptr(irowt:irowb, icoll:icolr)) = NaN; endif numarr(! emptr(irowt:irowb, icoll:icolr)) = ... cell2mat (rawarr(~emptr(irowt:irowb, icoll:icolr))); ## Save limits lim.numlimits = [icoll, icolr; irowt, irowb]; if (! isempty (rawlimits)) correction = [1; 1]; lim.numlimits(:,1) = lim.numlimits(:,1) + rawlimits(:,1) - correction(:); lim.numlimits(:,2) = lim.numlimits(:,2) + rawlimits(:,1) - correction(:); endif endif endif lim.rawlimits = rawlimits; endif endfunction io-2.4.10/inst/PaxHeaders.5973/unicode2utf8.m0000644000000000000000000000013213226215407015345 xustar0030 mtime=1515789063.600155479 30 atime=1515789063.600155479 30 ctime=1515789065.028183488 io-2.4.10/inst/unicode2utf8.m0000644000175000017500000000324013226215407015604 0ustar00olafolaf00000000000000## Copyright (C) 2016-2017 Markus Mützel ## ## 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 . ## -*- texinfo -*- ## @deftypefn {} {[@var{ostr}, @var{error_flag}] =} unicode2utf8 (@var{ustr}) ## Encode (1-byte) Unicode string @var{ustr} into UTF-8 @var{ostr}. ## ## UTF-8 characters with more than 2 bytes are dropped since Octave does not ## support characters >255. ## If an error occured @var{error_flag} is set to true. ## @end deftypefn ## Author: Markus Mützel ## Created: 2016-10-12 function [ostr, error_flag] = unicode2utf8 (ustr="") error_flag = false; ustr = uint8 (ustr); # convert char to uint8 ichar = 1; ostr = uint8 ([]); for (ichar = 1:numel (ustr)) if (ustr(ichar) < 128) ## single byte character ostr(end+1) = ustr(ichar); elseif (ustr(ichar) < 2048) ## double byte character ostr(end+1) = 192 + bitshift (bitand (192, ustr(ichar)), -6); ostr(end+1) = 128 + bitand (63, ustr(ichar)); else ## Should never reach here because ustr is cast to uint8 error_flag = true; endif endfor io-2.4.10/inst/PaxHeaders.5973/rfsearch.m0000644000000000000000000000013213226215407014623 xustar0030 mtime=1515789063.600155479 30 atime=1515789063.600155479 30 ctime=1515789065.028183488 io-2.4.10/inst/rfsearch.m0000644000175000017500000001023013226215407015057 0ustar00olafolaf00000000000000## Copyright (C) 2013-2017 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 Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## @deftypefn {Function File} @var{filename} = rsearchfile (@var{dname}, @var{fname}) ## @deftypefnx {Function File} @var{filename} = rsearchfile (@var{dname}, @var{fname}, @var{maxdepth}) ## Recursively search for file or filename pattern FNAME starting in directory ## DNAME and return the first match. ## ## @var{dname} and @var{fname} must be character strings and should conform ## to the directory name and filename requirements of your operating system. ## Optional argument @var{maxdepth} can be specified to limit the maximum search ## depth; the default value is 1 (search only in @var{dname} and subdirs of ## @var{dname}). Setting maxdepth to 0 limits the search to @var{dname}. ## Be careful with setting @var{maxdepth} to values > 3 or 4 as this can ## provoke excessive search times in densely populated directory trees. ## Keep in mind that rfsearch is a recursive function itself. ## ## Output argument @var{filename} returns the relative file path of the ## first match, relative to @var{DNAME}, or an empty character string if ## no match was found. ## ## Examples: ## ## @example ## filename = rfsearch ("/home/guest/octave", "test.fil") ## Look for file test.fil and start the search in /home/guest/octave ## @end example ## ## @example ## filename = rfsearch ("/home", "test.fil", 2) ## Look for file test.fil, start the search in /home, and if needed ## search subdirs of subdirs of /home ## @end example ## ## @seealso {dir, glob} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2013-08-20 function [ fpath ] = rfsearch (dname, fname, mxdpth=1, depth=0) ## Input validation if (nargin < 2) print_usage () elseif ((! ischar (dname)) || (! ischar (fname))) error ("rsearchfile: character arguments expected for DNAME and FNAME\n"); elseif (! isnumeric (mxdpth)) error ("Numeric value >= 0 expected for MAXDEPTH\n"); elseif (mxdpth < 0) warning ("rsearchfile: negative value for MAXDEPTH (%d) set to 0\n", mxdpth); mxdpth = 0; elseif (! isnumeric (depth)) print_usage ("too many or illegal arguments"); endif ## If present strip trailing filesep of dname (doesn't hurt though). ## Preserve root / if (length (dname) > 1 && strcmp (dname(min(2, end)), filesep)) dname(end:end) = ''; endif sbdir = ''; fpath = dir ([dname filesep fname '*']); if (isempty (fpath) && depth < mxdpth) ## Bump search depth ++depth; ## Get list of subdirs in current level dirlist = dir (dname); if (! isempty (dirlist)) dirlist = dirlist(find ([dirlist.isdir])); ii = 0; if (strcmp (dirlist(1).name, '.')) ## Not a root dir; discard entries '.' & '..' ii = 2; endif fpath = ''; ## Search all subdirs in current level while (++ii <= numel (dirlist) && isempty (fpath)) sbdir = [filesep dirlist(ii).name]; fpath = dir ([dname sbdir filesep fname '*']); if (isempty (fpath) && depth < mxdpth) ## Try a level deeper, if allowed. Be sure to convey current depth ## as 'find_in_subdir' is called recursively here fpath = rfsearch ([dname sbdir], fname, mxdpth, depth); endif endwhile endif endif ## Final parts if (isempty (fpath)) fpath = ''; else if (isstruct (fpath)) fpath = fpath.name; endif ## Combine and strip leading filesep fpath = [sbdir filesep fpath](2:end); endif endfunction ## rfsearch io-2.4.10/inst/PaxHeaders.5973/xmlwrite.m0000644000000000000000000000013213226215407014701 xustar0030 mtime=1515789063.608155636 30 atime=1515789063.608155636 30 ctime=1515789065.028183488 io-2.4.10/inst/xmlwrite.m0000644000175000017500000001136213226215407015144 0ustar00olafolaf00000000000000## Copyright (C) 2015,2017 Pantxo Diribarne ## ## 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 . ## -*- texinfo -*- ## @deftypefn {Function File} {} xmlwrite (@var{fname}, @var{dom}) ## @deftypefnx {Function File} {@var{str} =} xmlwrite (@var{dom}) ## ## Write an xml DOM document to file @var{fname} or to ouput string ## @var{str}. ## ## The @var{dom} argument must be a DOM document object as returned by ## @code{xmlread} function. ## ## Octave does not ship with the necessary Xerces library so you ## should take care of adding the required .jar files to your ## javaclasspath, e.g: ## ## @example ## @code{javaaddpath ("/path/to/xerces-2_11_0/xercesImpl.jar");} ## @code{javaaddpath ("/path/to/xerces-2_11_0/xml-apis.jar");} ## @end example ## ## xmlwrite will check for Java support and proper xerces Java libraries ## in the javaclasspath until the check passes, or if it is called without ## arguments. In the latter case it will also return the found xerces ## javaclasspath entries and xerces version to standard output. ## ## @seealso{xmlread} ## @end deftypefn function str = xmlwrite (varargin) persistent java_ok = []; if (nargin < 1) ## Reset Java support check results java_ok = []; endif ## Check Java support and support files if (isempty (java_ok)) if (! __have_feature__ ("JAVA")) error ("xmlwrite: Octave was built without Java support, exiting"); elseif (! usejava ("jvm")) error ("xmlwrite: no Java JRE or JDK detected, exiting"); endif ## Default verbosity level for Java libs check vrbs = 0; if (nargin < 1) vrbs = 3; endif ## Check if required Java class libs are in the javaclasspath chk = __XMLrw_chk_sprt__ (javaclasspath ("-all"), vrbs); if (chk) java_ok = 1; ## If xmlwrite was called w/o args, return if (nargin < 1) str = []; return endif else java_ok = 0; error ("xmlwrite: no xercesImpl.jar and/or xml-apis.jar > v2.11.0 in \ javaclasspath"); endif endif ## Java checks OK; process arguments if (nargin == 1) dom = varargin{1}; jos = javaObject ("java.io.StringWriter"); elseif (nargin == 2) dom = varargin{2}; fname = varargin{1}; if (! ischar (fname)) print_usage (); endif jfile = javaObject ("java.io.File", fname); jos = javaObject ("java.io.FileOutputStream", jfile); else print_usage (); endif ## Check the validity of the DOM document unwind_protect doc_classes = {"org.apache.xerces.dom.DeferredDocumentImpl", ... "org.apache.xerces.dom.DocumentImpl"}; if (! any (strcmp (class (dom), doc_classes))) error ("xmlwrite: DOM must be a java DOM document object") endif try jfmt = javaObject ("org.apache.xml.serialize.OutputFormat", dom); jfmt.setIndenting (1); serializer = javaObject ("org.apache.xml.serialize.XMLSerializer", ... jos, jfmt); catch disp (lasterr ()); error ("xmlwrite: couldn't load Xerces serializer object") end_try_catch try serializer.serialize (dom); catch disp (lasterr ()); error ("xmlwrite: couldn't serialize document") end_try_catch if (nargout > 0 && strcmp (class (jos), "java.io.StringWriter")) str = char (jos.toString ()); else str = 1; endif unwind_protect_cleanup jos.close (); end_unwind_protect endfunction %!demo %! ## Create a java representation of a DOM document. The document %! ## object features all the necessary methods to create subelements. %! doc = javaObject ("org.apache.xerces.dom.DocumentImpl"); %! %! ## Create a root node and add it to the document %! root = doc.createElement ("RootNode"); %! root.setAttribute ("created", datestr (date ())); %! doc.appendChild (root); %! %! ## Create a child node, append it text data and add it to the %! ## root children %! child = doc.createElement ("TextChild"); %! child.setAttribute ("verbose", "yes"); %! child.setAttribute ("useful", "no"); %! txt = doc.createTextNode ("These are text data"); %! child.appendChild (txt); %! root.appendChild (child); %! %! ## Serialize DOM document to string %! str = xmlwrite (doc) io-2.4.10/inst/PaxHeaders.5973/oct2xls.m0000644000000000000000000000013213226215407014424 xustar0030 mtime=1515789063.560154694 30 atime=1515789063.560154694 30 ctime=1515789065.028183488 io-2.4.10/inst/oct2xls.m0000644000175000017500000002161113226215407014665 0ustar00olafolaf00000000000000## Copyright (C) 2009-2017 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 . ## -*- texinfo -*- ## @deftypefn {Function File} [ @var{xls}, @var{rstatus} ] = oct2xls (@var{arr}, @var{xls}) ## @deftypefnx {Function File} [ @var{xls}, @var{rstatus} ] = oct2xls (@var{arr}, @var{xls}, @var{wsh}) ## @deftypefnx {Function File} [ @var{xls}, @var{rstatus} ] = oct2xls (@var{arr}, @var{xls}, @var{wsh}, @var{range}) ## @deftypefnx {Function File} [ @var{xls}, @var{rstatus} ] = oct2xls (@var{arr}, @var{xls}, @var{wsh}, @var{range}, @var{options}) ## ## Add data in 1D/2D CELL array @var{arr} into a cell range @var{range} ## in worksheet @var{wsh} in an Excel (or gnumeric) spreadsheet file ## pointed to in structure @var{xls}. ## Return argument @var{xls} equals supplied argument @var{xls} and is ## updated by oct2xls. ## ## A subsequent call to xlsclose is needed to write the updated spreadsheet ## to disk (and -if needed- close the Excel or Java invocation). ## ## @var{arr} can be any 1D or 2D array containing numerical, logical and/or ## character data (cellstr) except complex. Mixed type arrays can ## only be cell arrays. ## ## @var{xls} must be a valid pointer struct created earlier by xlsopen. ## ## @var{wsh} can be a number or string (max. 31 chars). ## In case of a yet non-existing Excel file, the first worksheet will be ## used & named according to @var{wsh} - extra empty worksheets that Excel ## creates by default are deleted. ## In case of existing files, some checks are made for existing worksheet ## names or numbers, or whether @var{wsh} refers to an existing sheet with ## a type other than worksheet (e.g., chart). ## When new worksheets are to be added to the Excel file, they are ## inserted to the right of all existing worksheets. The pointer to the ## "active" sheet (shown when Excel opens the file) remains untouched. ## ## If @var{range} is omitted or just the top left cell of the range is ## specified, the actual range to be used is determined by the size of ## @var{arr}. If nothing is specified for @var{range} the top left cell ## is assumed to be 'A1'. If defined in the spreadsheet file, a "Named ## range" can also be specified. In that case @var{wsh} will be ignored ## and the worksheet associated with the specified Named range will be ## used. ## ## Data are added to the worksheet, ignoring other data already present; ## existing data in the range to be used will be overwritten. ## ## If @var{range} contains merged cells, only the elements of @var{arr} ## corresponding to the top or left Excel cells of those merged cells ## will be written, other array cells corresponding to that cell will be ## ignored. ## ## Optional argument @var{options}, a structure, can be used to specify ## various write modes. ## @table @asis ## @item "formulas_as_text" ## If set to 1 or TRUE formula strings ( i.e., text strings (assumed to ## start with "=" and end in a ")" ) are to be written as litteral ## text strings rather than as spreadsheet formulas (the latter is the ## default). ## ## @item 'convert_utf' ## If set to 1 or TRUE, oct2xls converts one-byte characters outside the ## range [32:127] to UTF-8 so that they are properly entered as UTF-8 ## encoded text in spreadsheets. The default value is 0. ## This setting has no effect for the COM interface as that does the ## encoding automatically using libraries outside Octave. ## @end table ## ## Beware that -if invoked- Excel invocations may be left running silently ## in case of COM errors. Invoke xlsclose with proper pointer struct to ## close them. ## When using Java, note that large data array sizes elements may exhaust ## the Java shared memory space for the default java memory settings. ## For larger arrays, appropriate memory settings are needed in the file ## java.opts; then the maximum array size for the Java-based spreadsheet ## options may be in the order of 10^6 elements. In caso of UNO this ## limit is not applicable and spreadsheets may be much larger. ## ## Examples: ## ## @example ## [xlso, status] = oct2xls ('arr', xlsi, 'Third_sheet', 'AA31:AB278'); ## @end example ## ## @seealso {xls2oct, xlsopen, xlsclose, xlsread, xlswrite, xlsfinfo} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-12-01 function [ xls, rstatus ] = oct2xls (obj, xls, wsh=1, crange="", spsh_opts=[]) if (nargin < 2) error ("oct2xls needs a minimum of 2 arguments."); endif ## Validate input array, make sure it is a cell array if (isempty (obj)) warning ("oct2xls: request to write empty matrix - ignored."); rstatus = 1; return; elseif (isnumeric (obj)) obj = num2cell (obj); elseif (ischar (obj)) obj = {obj}; printf ("(oct2xls: input character array converted to 1x1 cell)\n"); elseif (! iscell (obj)) error ("oct2xls: input array neither cell nor numeric array\n"); endif if (ndims (obj) > 2) error ("oct2xls: only 2-dimensional arrays can be written to spreadsheet\n"); endif ## Cast all numerical values to double as spreadsheets only have double/boolean/text type idx = cellfun (@isnumeric, obj, "UniformOutput", true); obj(idx) = cellfun (@double, obj(idx), "UniformOutput", false); ## Check xls file pointer struct test1 = ! isfield (xls, "xtype"); test1 = test1 || ! isfield (xls, "workbook"); test1 = test1 || isempty (xls.workbook); test1 = test1 || isempty (xls.app); test1 = test1 || ! ischar (xls.xtype); if (test1) error ("oct2xls: invalid xls file pointer struct\n"); endif ## Check worksheet ptr if (! (ischar (wsh) || isnumeric (wsh))) error ("Integer (index) or text (wsh name) expected for arg # 3\n"); elseif (isempty (wsh)) wsh = 1; endif ## Check range if (! isempty (crange) && ! ischar (crange)) error ("oct2xls: character string expected for arg # 4 (range)\n"); elseif (isempty (crange)) crange = ""; elseif (! isempty (crange)) ## Check for range name and convert it to range & optionally sheet ## 1. Check if it matches a range [crange, wsh, xls] = chknmrange (xls, crange, wsh); endif ## Various options if (isempty (spsh_opts)) spsh_opts.formulas_as_text = 0; spsh_opts.convert_utf = 0; ## other options to be implemented here elseif (isstruct (spsh_opts)) if (! isfield (spsh_opts, "formulas_as_text")) spsh_opts.formulas_as_text = 0; endif if (! isfield (spsh_opts, "convert_utf")) spsh_opts.convert_utf = 0; endif ## other options to be implemented here else error ("oct2xls: structure expected for arg # 5\n"); endif if (nargout < 1) printf ("oct2xls: warning: no output spreadsheet file pointer specified.\n"); endif ## Convert to UTF-8 if (! strcmp (xls.xtype, "COM") && (spsh_opts.convert_utf)) if (exist ("native2unicode", "file")) conv_fcn = @(str) unicode2native (native2unicode (uint8 (str)), "UTF-8"); else conv_fcn = @unicode2utf8; endif obj = tidyxml (obj, conv_fcn); endif ## Select interface to be used if (strcmpi (xls.xtype, "COM")) ## ActiveX / COM [xls, rstatus] = __COM_oct2spsh__ (obj, xls, wsh, crange, spsh_opts); elseif (strcmpi (xls.xtype, "POI")) ## Invoke Java and Apache POI [xls, rstatus] = __POI_oct2spsh__ (obj, xls, wsh, crange, spsh_opts); elseif (strcmpi (xls.xtype, "JXL")) ## Invoke Java and JExcelAPI [xls, rstatus] = __JXL_oct2spsh__ (obj, xls, wsh, crange, spsh_opts); elseif (strcmpi (xls.xtype, "OXS")) ## Invoke Java and OpenXLS [xls, rstatus] = __OXS_oct2spsh__ (obj, xls, wsh, crange, spsh_opts); elseif (strcmpi (xls.xtype, "UNO")) ## Invoke Java and UNO bridge (OpenOffice.org) [xls, rstatus] = __UNO_oct2spsh__ (obj, xls, wsh, crange, spsh_opts); elseif (strcmpi (xls.xtype, "OCT")) ## Replace illegal XML characters by XML escape sequences idx = cellfun (@ischar, obj); obj(idx) = strrep (obj(idx), "&", "&" ); obj(idx) = strrep (obj(idx), "<", "<" ); obj(idx) = strrep (obj(idx), ">", ">" ); obj(idx) = strrep (obj(idx), "'", "'"); obj(idx) = strrep (obj(idx), '"', """ ); ## Invoke native Octave code (only ods/xlsx/gnumeric) [xls, rstatus] = __OCT_oct2spsh__ (obj, xls, wsh, crange, spsh_opts); ##elseif (strcmpi (xls.xtype, "")) ## else error (sprintf ("oct2xls: unknown Excel .xls interface - %s.\n", xls.xtype)); endif endfunction io-2.4.10/inst/PaxHeaders.5973/utf82unicode.m0000644000000000000000000000013213226215407015345 xustar0030 mtime=1515789063.604155557 30 atime=1515789063.600155479 30 ctime=1515789065.028183488 io-2.4.10/inst/utf82unicode.m0000644000175000017500000000443613226215407015614 0ustar00olafolaf00000000000000## Copyright (C) 2017 Markus Mützel ## ## 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 . ## -*- texinfo -*- ## @deftypefn {} {[@var{ustr}, @var{error_flag}] =} utf82unicode (@var{istr}) ## Convert UTF-8 encoded strings @var{istr} to (1-byte) Unicode @var{ustr}. ## ## UTF-8 characters with more than 2 bytes are dropped since Octave does not ## support characters >255. ## If an error occured @var{error_flag} is set to true. ## @end deftypefn ## Author: Markus Mützel ## Created: 2016-10-12 function [ustr, error_flag] = utf82unicode (istr="") error_flag = false; istr = uint8 (istr); ibyte = 1; ustr = uint8 ([]); while (true) if (isequal (bitget (istr(ibyte), 8), 0)) ## Single byte character ustr(end+1) = istr(ibyte); ibyte += 1; elseif (isequal (bitget (istr(ibyte), 6:8), [0 1 1])) ## Start of double-byte char if (isequal (bitget (istr(ibyte+1), 7:8), [0 1])) ## Decode byte if it is valid UTF-8 ustr(end+1) = bitand (31, istr(ibyte))*64 + bitand (63, istr(ibyte+1)); else error_flag = true; endif ibyte += 2; elseif (isequal (bitget (istr(ibyte), 6:8), [1 1 1])) ## Drop this character (Octave does not support chars > 255). error_flag = true; ## Detect how many bytes to drop ibyte += find (bitget (istr(ibyte), 8:-1:1) == 0, 1, "first") - 1; elseif (isequal (bitget (istr(ibyte), 7:8), [0 1])) ## Drop this character (must follow a start byte) error_flag = true; ibyte += 1; else ## Should not reach here but maybe for safety? error_flag = true; ibyte += 1; endif if (ibyte > numel (istr)) break endif endwhile io-2.4.10/PaxHeaders.5973/DESCRIPTION0000644000000000000000000000013213226215407013401 xustar0030 mtime=1515789063.548154458 30 atime=1515789063.548154458 30 ctime=1515789065.028183488 io-2.4.10/DESCRIPTION0000644000175000017500000000073513226215407013646 0ustar00olafolaf00000000000000Name: io Version: 2.4.10 Date: 2018-01-09 Author: various authors Maintainer: Philip Nienhuis 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) Suggested: windows (>= 1.2.1); Java JRE (> 1.6) Autoload: no License: GPLv3+, simplified BSD Url: http://octave.sf.net io-2.4.10/PaxHeaders.5973/COPYING0000644000000000000000000000013213226215407012726 xustar0030 mtime=1515789063.548154458 30 atime=1515789063.548154458 30 ctime=1515789065.028183488 io-2.4.10/COPYING0000644000175000017500000010451313226215407013172 0ustar00olafolaf00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . io-2.4.10/PaxHeaders.5973/NEWS0000644000000000000000000000013213226215407012372 xustar0030 mtime=1515789063.552154538 30 atime=1515789063.552154538 30 ctime=1515789065.028183488 io-2.4.10/NEWS0000644000175000017500000013536113226215407012643 0ustar00olafolaf00000000000000Summary of important user-visible changes for releases of the io package =============================================================================== io-2.4.10 Release Date: 2018-01-09 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: - Remove leftover stanza in configure.ac (bug #52830) - col2num: make input argument case-insensitive *** Code improvements: - csv2cell: now reads files with varying number of fields per line. The number of fields in the first line (assumed to contain column titles) is assumed to be the nr. of columns in the file. Thus csv2cell is supposed to correctly read most csv files w/o any additional parameters (only the separator needs to be specified if it isn't a comma) =============================================================================== io-2.4.9 Release Date: 2018-01-03 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: - read_namelist.m: character sequences may contain a '/' character (bug #52310, fix by Brice Davier) - chk_spreadsheet_support: adapt to core cset 516437d2194d (don't allow func parameters to be persistent) - csv2cell: fix erroneous column header to column-number conversion *** Code improvements: =============================================================================== io-2.4.8 Release Date: 2017-10-21 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: - csv2cell(): * Improve ignoring CR (char (13)) in csv files (bugs #50979 and #50297) - OCT interface: * More robust identification of worksheets (spreadsheets written with POI interface were misinterpreted) * Overhauled reading .xlsx files; catches more types: inlineString, Boolean, ... (with lot of assistance from Markus Muetzel, thx) - read_namelist.m: improve reading when ending char is not fist on line (bug #52242, fix by Brice Davier) *** Code improvements: - Replace utf82unicode with native2unicode v.v. in Octave 4.4+ (thanks to Markus Mützel) - If no filename extension is given, default to .xlsx rather than .xls - xlsread.m and odsread.m now accept a function handle, an output options struct and interface as arguments after the third (range) argument, in any order. See "help xlsread" or "help odsread" for more info. - all spreadsheet I/O functions now accept an empty string as worksheet name, implying the first worksheet. =============================================================================== io-2.4.6, io-2.4.7 Release Date: 2017-03-03 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: - OCT interface: * fix erroneous empty cell assignment to cellstr array bug 49579) * correct XML double-quote translation * reading multi-line text cells in .ods files (bug #50200) * properly write multi-line cells in .ods files - xlsread: initialize r_extnd (bug #49656) - xlsfinfo, odsfinfo: error when no named range exists in .ods file (bug #49922) - JOD interface: * avoid NPE when opening empty file * Remove "A" & "B" column headers in new sheets - UNO interface: * avoid NPE when writing to new sheet - csv2cell(): * warn that multi-line text fields (containing newline characters) are not allowed (bug #50224) * ignore CR (char (13)) in csv files (bug #50297) *** Code improvements: - POI interface: * update support to POI 3.16a (add new java .jar) * better distinguish .xls and .xlsx support **** New features: - csv2cell() now accepts a spreadsheet-style range argument. That option allows reading .csv files with heterogeneous number of fields per line =============================================================================== io-2.4.5 Release Date: 2016-11-08 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: - OCT interface: various fixes related to XML handling (bug 49510) - Correctly handle sheet names containing spaces and quotes (bug 49558) *** Code improvements: - xlswrite.m: arrays arent truncated to 1x1 if a range of only one cell is specified. It'll be now interpreted as topleft cell - odswrite has always worked like above; it is now explicitly documented =============================================================================== io-2.4.4 Release Date: 2016-10-23 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: - xmlread.m, xmlwrite.m: fix typo (bug 49095; credits to Andreas Weber) - xmlwrite.m: properly close I/O stream (bug 49197; credits to Pantxo Diribarne) - POI, OXS interfaces: close I/O streams in case of errors (bug 49197) - POI: fix fallback to JXl/UNO for BIFF5 files (Excel '95) - (named ranges) pick first sheet in case of multiple matches with named range (bug 49286) - tidyxml.m: also preserve char(127) - xl2oct.m, ods2oct.m, octls.m, oct2ods.m, tidyxml.m: supply an option to convert UTF-8 characters to one-byte characters and back (thanks to Markus Muetzel; bug 49222). - Fix writing to another spreadheet file upon closing speadsheet pointer *** New features: - New functions utf82unicode.m and unicode2utf8.m. These convert double- byte UTF-8 strings into single-byte char strings and back, resp. - When reading from / writing to spreadsheet files, text strings can be converted from/to UTF8 encoding by specifying an option flag "convert_utf" in calls to xls2oct.m / ods2oct.m / oct2xls.m / oct2ods.m. This is probably *only* useful for systems where the Octave terminal cannot support UTF-8 display (e.g., Windows 7 and below) =============================================================================== io-2.4.3 Release Date: 2016-09-03 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: - COM interface: return proper used range in case of just 1 column of data - JOD interface: temporary fix for reading numeric values (bug #48013) til bug #48591 has been fixed *** Code improvements: - io_xls_testscript.m, io_ods_testscript.m: return results rather than bail out when hitting errors - cell2csv: increase precision when writing double values (credits to Martin Kunz) =============================================================================== 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: - OCT interface: avoid reading/writing double-byte characters. Excel and LibreOffice convert characters < 32 or > 126 to double-byte. Octave cannot handle double-byte (unicode) characters (yet). The 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. =============================================================================== io-2.4.0 Release Date: 2015-12-23 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: - UNO interface: flag mismatching 64bit/32bit builds of Octave and LO/OOo. - xlsopen.m/odsopen.m: avoid too many empty lines; improve output of interface detection. - OTK interface: more reliable formula reading. - Fix unneeded empty lines while detecting interfaces. *** Improvements - Panxto Dixbarne has supplied xmlread.m and xmlwrite.m to replace the undocumented, unsupported and unusable binary code by Laurent Mazet. xmlread.m and xmlwrite.m depend on the Java Xerces library > 2.11.0 These functions are now Matlab-compatible. *** Various: - Remove duplicate code (checks on javaclasspath entries). - Do not allow code to remove non-supported .jars from javaclasspath. - Prepare for a 2.4.0 release now that xmlread/-write work properly. =============================================================================== io-2.2.11 Release Date: 2015-10-22 Release Manager: Philip Nienhuis =============================================================================== Primarily a bug fix release *** Bug fixes: - More robust Named range code processing & code simplifications - odsfinfo.m / gnumeric: fix errors when sheet has no Named ranges - xlsopen.m: don't allow .xlsx to be opened by OXS interface (OpenXLS .xlsx processing is immature while it works fine for plain .xls/BIFF8) - odsfinfo.m: implement fformat and nmranges output arguments - some cosmetic issues and spelling =============================================================================== io-2.2.10 Release Date: 2015-09-24 Release Manager: Philip Nienhuis =============================================================================== *** New features: - Support for Named Ranges. If present in a spreadsheet file, a Named Range can be entered instead of a spreadsheet-style range for xlsread, xls2oct, odswrite, etc. odsfinfo.m and xlsfinfo.m can be used to explore Named ranges in spreadsheet files. Due to bugs in JExcelApi, jOpenDocument and ODF Toolkit, Named Ranges do not work for the JXL, JOD and OTK interfaces. Currently LibreOffice invoked through the UNO interface can only use Named Ranges for .xls / .xlsx files, not .ods files *** Bug fixes: - Allow UNO to work with 64-bit LibreOffice - Adapt UNO jar search to new Java class lib locations in LibreOffice 5+ - Improve PKG_ADD Libre-/OpenOffice search - Two OCT .xlsx write bugs (#45915, #45916). The former is a workaround for a (possible) LibreOffice incompatibility - PKG_ADD: avoid uninstalled previous LO/OOo installations when searching for LO/OOo on Windows - Allow .ods to be read with xls2oct.m - xls2oct.m: catch unsupported file formats for OCT interface *** Various: Improve formula support and reading/writing logicals (BOOLEANS) with JOD interface (jOpenDocument versions 1.3 and 1.4beta) =============================================================================== io-2.2.9 Release Date: 2015-07-10 Release Manager: Philip Nienhuis =============================================================================== This is a bug fix release. *** Bug fixes: - Fix typo in duplicate sheet names check code (bug #45498) - For the OCT interface, increase numeric write precision to 15 digits (used to be just 6) and ensure that very large and small numbers can be written (bug #45498) - Fix wrong indexing when writing a new gnumeric file with wsh pointer > 1 - xlsopen.m (xlswrite): fix type preventing writing to ods *** Reminder: This will be (one of) the last io package release(s) before the spreadsheet I/O is moved into core Octave, so this version will only install in Octave < 4.2.x (override using the -nodeps option with pkg.m) =============================================================================== io-2.2.8 Release Date: 2015-06-21 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: - xlsread: properly fall back to dlmread when reading .csv files (don't bother with COM (Excel) or UNO (LibreOffice) interfaces) - private/__COM_spsh_open__.m: use entire given pathname to convert to full path, not just filename proper (bug #44642) - Same for private/__UNO_spsh_open__.m - xlsread.m/xls2oct.m using OCT interface: fix wrong worksheet reference (bug #45303) *** This will be (one of) the last io package release(s) before the spreadsheet I/O is moved into core Octave, so this version will only install in Octave < 4.2.x (override using the -nodeps option with pkg.m) =============================================================================== io-2.2.7 Release Date: 2015-03-07 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: - dbfread: catch really empty (= spaces rather than zeros) date entries. - xlsopen.m: Clarify error message about missing I/O with file extension. - xlswrite.m: clarify supported file types/interfaces in texinfo header. - private/getxlsinterfaces.m: make COM interface detection more robust. - csv2cell, cell2csv: fix SEP/PROT argument processing for 64-bit indexing Octave - num2col.cc: fix uninitialized variable bug that crashed Octave-3.9.1+ (wasn't exposed in earlier versions) *** Various: - NEWS file scrutinized (formatting, typos) by Armin Mueller (thanks!) - Replaced all occurrences of deprecated core function strmatch() with find (strcmp ()) or strfind() - Silently create new spreadsheet files (there used to be a "Creating file ..." message) - Checked all Java-based interface support SW for newer versions. Results are mentioned in the doc/...html files. =============================================================================== io-2.2.6 Release Date: 2015-01-03 Release Manager: Philip Nienhuis =============================================================================== *** New features: - dbfwrite.m: can write cell arrays to a .dbf file (provisionally v.III+) For the time being dbfwrite (and dbfread) are considered experimental. *** Bug fixes: - xlswrite: provide sheet name if empty string was supplied for sheet name - dbfread: fix wrong indexing of logical values in output array. Properly implement selecting data columns with cellstr headers. Better dbf file version checks and memo field checks. =============================================================================== io-2.2.5 Release Date: 2014-11-22 Release Manager: Philip Nienhuis =============================================================================== *** New features: - On Windows, try to avoid using 32-bit UNO interface for 64-bit Octave. - Added a first dbfread.m, to read dbase files. Needed a.o., for reading shapefiles etc. dbfread.m is considered experimental for the time being. *** Bug fixes: - Enable writing formulas to OOXML (.xlsx) in OCT interface(bug #43321a). - Fix creating new .ods file in OCT(bug #43321b). - xlswrite: supply default data cellrange if no or empty cellrange argument is supplied. - OCT interface: make sure requested worksheet names are matched exactly (bug #43353) - OCT interface: make sure writing to relative paths works. Creating the intermediate subdir tree won't work (a zip / gzip limitation) - Fix reading from sheets with some special names (bug #43331) - Fix worksheet bookkeeping when adding new sheets (bug #43354) - More robust code to read SharedStrings.xml (bug #43399) - Oct2xls (OCT) fails when sheet names are being used (bug #43400) - Invoke SaveCopyAs rather than SaveAs for new Excel files in COM interface *** Other changes - First throw at restructuring to eliminate duplicate code: . chk_spreadsheet_support.m: singled out checks for java class libs per interface - Checked odfdom-incubating 6.1 (odfdom-0.8.10): doesn't work properly - Added checks for unsupported jar versions in chk_spreadsheet_support. This function won't load unsupported .jar versions anymore and will even remove them from the javaclasspath if it finds them. The only way that unsupported .jar versions (spreadsheet Java class libs) can get in the javaclasspath is if users manually add them. =============================================================================== io-2.2.4 Release Date: 2014-09-11 Release Manager: Philip Nienhuis =============================================================================== *** New features: - Add 'headerlines' parameter to csv2cell, to allow skipping a first number of lines before reading actual data. See "help csv2cell". *** Bug fixes: - Replace __num2char__ / __char2num__ (.mex files) by .oct versions num2col & col2num as 64-bitOctave cannot compile mex files with int64_t. - Add some delays (0.25 s) in OCT and UNO file open/close functions to give zip and unpack some time to finish I/O operations (lazy write) on fast systems. =============================================================================== io-2.2.3 Release Date: 2014-08-14 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: - Replace canonicalize_file_name calls by make_absolute_filename to avoid ActiveX/COM errors (due to changed canonicalize_file_name in 3.9.0+) - More robust strrep code in OCT/xlsx write code (modifying access time) - Fix handling empty cell range argument when writing .ods with OCT interface (bug #43783) - Better string detection when reading .xlsx with OCT interface - Properly return a value of 0 after xlswrite/odswrite write errors =============================================================================== io-2.2.2 Release Date: 2014-05-12 Release Manager: Philip Nienhuis =============================================================================== *** New features: - Write support for gnumeric An updated overview of which interface can be used for what types of files (extensions): Interface File extension COM POI POI/OOXML JXL OXS UNO OTK JOD OCT -------------------------------------------------------------- .xls (Excel95) R R R .xls (Excel97-2003) + + + + + + .xlsx (Excel2007+) ~ + (+) R + .xlsb, .xlsm ~ ? R R? .wk1 + R .wks + R .dbf + + .ods ~ + + + + .sxc + + .fods + .uos + .dif + .csv + R .gnumeric + -------------------------------------------------------------- (~ = dependent on Excel/LO/OOo version; + = read/write; R = only reading) (+) unfortunately OOXML support in the OpenXLS Java library itself is too buggy, so OOXML support for OXS has been disabled (but it is implemented) *** Docs (html) & texinfo help texts updated *** Bug fixes: - UNO open/close: catch changed behavior of canonicalize_file_name in Octave-3.9.0+ - odsfinfo.m, xlsfinfo.m: also check for leading period in file extension switch statement - Replace java_get (deprecated in Octave > 4.1.0) by __java_get__ - Catch rare Java exception in OTK interface under Octave-4.1.0+ =============================================================================== io-2.2.1 Release Date: 2014-04-26 Release Manager: Philip Nienhuis =============================================================================== Bug fix release: *** Bug fixes: - First check built-in Java support before further testing Java-based interfaces (bug #42192) - Invoke __char2num__/__num2char__ rather than __OCT_cc__ for spreadsheet cell address translation in OCT interface funcs as well - Fix wrong file handle refs. when updating app.xml in OOXML files =============================================================================== io-2.2.0 Release Date: 2014-04-13 Release Manager: Philip Nienhuis =============================================================================== *** New features: - Experimental write support w/o Java or ActiveX, just native Octave, for ODS 1.2 (LibreOffice native format) and OOXML (Excel 2007+ .xlsx) - (write support for gnumeric pending) An updated overview of which interface can be used for what types of files (extensions): (~ = dependent on Excel/LO/OOo version; + = read/write; R = only reading) Interface File extension COM POI POI/OOXML JXL OXS UNO OTK JOD OCT -------------------------------------------------------------- .xls (Excel95) R R R .xls (Excel97-2003) + + + + + + .xlsx ~ + (+) R + .xlsb, .xlsm ~ ? R .wk1 + R .wks + R .dbf + + .ods ~ + + + + .sxc + + .fods + .uos + .dif + .csv + R .gnumeric R -------------------------------------------------------------- *** Docs (html) & texinfo help texts updated *** Bug fixes: - (gnumeric reading): Properly handle ValueFormat tags Fix older formats w/o Value* tags - Restored UNO interface option in ods2oct.m - (xlswrite) when truncating an array (sheet capacity, too small a range), convey truncated range rather than topleft cell - PKG_ADD: Fix case-sensitivity when searching for Libre/OpenOffice loc. Do not automatically load Java class libs on *nix - OCT: delete tmp dirs after closing spreadsheet files - POI: return complete cell range for a.o., xlsfinfo =============================================================================== io-2.1.x Release Date: TBA Release Manager: Philip Nienhuis =============================================================================== (unstable version) For changes see 2.2.0 (above) =============================================================================== io-2.0.2 Release Date: 2014-01-09 Release Manager: Philip Nienhuis =============================================================================== Another bug fix release *** Bug fixes: - PKG_ADD, PKG_DEL: move into script dir to be sure they can be invoked while loading / unloading io package *** New features: - chk_spreadsheet_support: Remembers which javaclasspath entries it loaded, can remove them too - PKG_DEL: Removes all javaclasspath entries added by chk_spreadsheet-support when unloading the io package - PKG_ADD: Searches for OpenOffice.org / LibreOffice in some conventional places to allow silent automatic loading of Java class libs & directories required for OOo / LO =============================================================================== io-2.0.1 Release Date: 2014-01-01 Release Manager: Philip Nienhuis =============================================================================== Bug fix release *** Bug fixes: - Fixed rfsearch error (empty subdirs) when loading package *** PKG_ADD: Also search user (%USERPROFILE%\Java or ~/Java) for Java spreadsheet support .jar files; also add conventional Linux place in search (usually /usr/share/java) =============================================================================== io-2.0.0 Release Date: 2014-01-01 Release Manager: Philip Nienhuis =============================================================================== *** Some code simplifications & style fixes An updated overview of which interface can be used for what types of files (extension): (~ = dependent on Excel/LO/OOo version; + = read/write; R = only reading) Interface File extension COM POI POI/OOXML JXL OXS UNO OTK JOD OCT -------------------------------------------------------------- .xls (Excel95) R R R .xls (Excel97-2003) + + + + + + .xlsx ~ + (+) R R .xlsb, .xlsm ~ ? R .wk1 + R .wks + R .dbf + + .ods ~ + + + R .sxc + + .fods + .uos + .dif + .csv + R .gnumeric R -------------------------------------------------------------- For unsupported file types, UNO will write .ods whatever the actual file extension. *** Bug fixes: - Fixed texinfo headers for the test scripts - The UNO interface no longer writes ODS for all file extensions. An updated list is shown above. *** Known issues: - OOXML write/read support in OpenXLS (OXS) is a bit wonky. Doesn't pass Octave OF-io's test script. Upstream has been informed of one example bug. - OpenXLS' OOXML depends on another .jar file (gwt-servlet-deps.jar). Rip it from this archive (108+ MB download): gwt-2.5.1.zip, available at: http://www.gwtproject.org/download.html ("Download GWT SDK") - LibreOffice/OpenOffice.org (UNO interface) doesn't write .csv - OTK interface (.ods) sometimes writes ridiculously wide columns. =============================================================================== io-1.3.6 Release Date: 2013-TBA Release Manager: Philip Nienhuis =============================================================================== *** OXS (OpenXLS) now has read/write support. AFAICS it is the fastest Java- based interface. Provisionally .xls (BIFF8, Excel'97-2003) works fairly reliably. OOXML works too but is unstable (see below, "Known issues"). *** Some code simplifications & style fixes *** xlsread may fall back to csvread for .csv files when no Excel (COM) or LibreOffice/OOo (UNO) interface is supported (bug #40993) An updated overview of which interface can be used for what types of files (extension): (~ = dependent on Excel version; + = read/write; R = only reading) Interface File extension COM POI POI/OOXML JXL OXS UNO OTK JOD OCT -------------------------------------------------------------- .xls (Excel95) R R R .xls (Excel97-2003) + + + + + + .xlxx/xlsm + + (+) + R .wk1 + + .wks + + .dbf + + .ods ~ + + + R .sxc + + .fods + .uos + .dif + .csv + + .gnumeric R -------------------------------------------------------------- *** Bug fixes: - post_install.m: seems unneeded, provisionally commented out all commands - PKG_ADD: dropped all references to Java package, now just checks octave_config_info("features").JAVA *** Known issues: - OOXML write/read support in OpenXLS (OXS) is a bit wonky. Doesn't pass Octave OF-io's test script. Upstream has been informed of one example bug. - OpenXLS' OOXML depends on another .jar file (gwt-servlet-deps.jar). Rip it from this archive (108+ MB download): gwt-2.5.1.zip, available at: http://www.gwtproject.org/download.html ("Download GWT SDK") =============================================================================== io-1.3.5 Release Date: 2013-TBA Release Manager: Philip Nienhuis =============================================================================== *** Merged in changes from io-1.2.5 (OCT interface) *** New spreadsheet test routine; improved existing routines to write with one and read with some other interface (helped to uncover many concealed bugs) *** (pending) Cleaning up chk_spreadsheet_support.m *** Bug fixes: - OCT: Replace fgetl calls by fread Improved regexp's - JOD: Wipe "A" and "B" in A1/B1 in new empty spreadsheets (a very old bug) - POI: File extension checks improved =============================================================================== io-1.3.4 Release Date: None (internal) =============================================================================== *** chk_spreadsheet_support restyled from Matlab into Octave style " , introduced recursive subdir search for Java class libs (nice for Fedora) Added rfsearch.m, function to find files in subdirs =============================================================================== io-1.3.3 Release Date: 2013-08-15 Release Manager: Philip Nienhuis =============================================================================== Intermediate unofficial development version for Octave 3.7.x. Only released on patch tracker Changes: see section for version 1.2.3 =============================================================================== io-1.3.2 Release Date: 2013-06-18 Release Manager: Philip Nienhuis =============================================================================== Intermediate unofficial development version for Octave 3.7.x. Only released on patch tracker ** Bug fixes --- chk_spredsheet_support: better Java detection (bug #38725) --- xlsopen.m: .xlsx files are properly recognized --- Re-enabled OXS (only reading) and UNO ** Created test_spsh.m test script --- This will find all supported spreadsheet interfaces and tests them one by one =============================================================================== io-1.3.0, io-1.3.1 Release Date: -internal- Release Manager: Philip Nienhuis =============================================================================== Version 1.3.0 - 1.3.1 are intermediate development versions for Octave > 3.7.1 with built-in Java support. They are largely untested; the built-in test scripts work for all tested interfaces except UNO and OXS (which consequently are disabled). =============================================================================== io-1.2.5 Release Date: 2013-11-14 Release Manager: Philip Nienhuis =============================================================================== *** - Added string/formula read support to xlsx/OCT. There's now full read support for .xlsx (OOXML) files w/o requiring Java or COM - Added requested range for .xlsx/OCT reading *** Bug fixes: - Better filetype / file extension detection (bug #40490) - Added unpack.m from dev core Octave as private/__unpack.m to avoid unzip errors for .xlsx and .gnumeric - Removed harmless but annoying error messages from Java detection - Fix tablerow repeat counter bugs (affected reading ODS w. OCT interface) =============================================================================== io-1.2.4 Release Date: 2013-11-05 Release Manager: Philip Nienhuis =============================================================================== *** Added !experimental! OCT (native Octave) interface for reading .ods, gnumeric, and xlsx. OCT doesn't need Java or COM/ActiveX; it works without any support software. That independence does come at a price however: - reading .ods is fully flexible like the other interfaces but a bit slow - reading .xlsx is FAST but it only gives numeric data (no strings yet) - reading gnumeric only reads "hard" data, no formula results. I'm afraid this isn't gonna change (it's a gnumeric developer issue) Markus Bergholz supplied the code for very fast reading of OOXML (at present only numeric data) - Thanks very much Markus! An overview of what interface can be used for which types of files (extension) (~ = dependent on Excel version; + = read/write; R = only reading) Interface File extension COM POI POI/OOXML JXL OXS UNO OTK JOD OCT -------------------------------------------------------------- .xls (Excel95) R R R .xls (Excel97-2003) + + + + R + .xlxx/xlsm + + + R .wk1 + + .wks + + .dbf + + .ods ~ + + + R .sxc + + .fods + .uos + .dif + .csv + + .gnumeric R -------------------------------------------------------------- *** getxmlattv.m, getxmlnode.m: new functions (for support of OCT interface) *** xlsopen.m: suffixes for Excel filenames (.xls, .xlsx) need not be specified. (But the files on disk do need these suffixes!) *** odsread.m, xlsread.m: No output arg required (output is sent to terminal if not output args specified) '' '' Check if filename is a text string *** odsopen: Relax requirement of lower case filename extension ** Bug fixes: --- xlsopen.m: Undue fallback to JXL for OOXML files hopefully fixed now '' Misinformation in error message about unsupported OXS & UNO fixed --- private/__POI_getusedrange__.m: Check return value of XSSF getFirstCellNum method =============================================================================== io-1.2.3 Release Date: 2013-08-15 Release Manager: Philip Nienhuis =============================================================================== ** Bug fixes: --- private/chk_jar_entries.m: trim multiple entries to avoid padded spaces *** private/getxlsinterfaces.m: add multiple jar entries for POI cf. Fedora naming (actually a Fedora packaging complication) *** chk_spreadsheet_support.m: same as getxlsinterfaces.m *** Added logical types to object2json (by Keith Sheppard, bug #39429) *** Tested odfdom-0.6-incubator (odfdom-0.8.9): too buggy to support :-( Updated doc/READ-ODS.html and added checks to chk_spreadsheet_support.m and private/getodsinterfaces.m =============================================================================== io-1.2.2 Release Date: 2013-05-21 Release Manager: Philip Nienhuis =============================================================================== ** Bug fixes: --- xlsopen.m: avoid fallback to JXL for OOXML files in some cases --- xlsopen.m, odsopen.m (actually silently fixed in 1.2.1): always re-read javaclasspath when a Java spreadsheet interface is requested explicitly (because between calls to xls-/odsopen new classes could be added to the javaclasspath, this wasn't picked up properly) --- csv2cell(): Fix hanging when it encountered EOF w/o preceding EOL (#143 in former OctDev bug tracker) csv2cell(): Fix inconsistent behavior when first field on a line is a string protected by "" (see http://octave.1599824.n4.nabble.com/csv2cell-inconsistent-tc4635817.html) --- __UNO_oct2spsh__.m: wrong assignment in code finding existing sheetnames --- Fix checks on xls or xls? suffix (due to Vermylen) --- Temporarily commented out tests in private subdir (bug #38755) ** csv2cell(): Tests added for above bugs and proper SEP and PROT args ** cell2csv(): Tests added incl. for proper SEP and PROT args ** Added read_namelist.m and write_namelist.m, kindly contributed by Darien Pardinas Diaz and Terry Duel =============================================================================== io-1.2.1 Release Date: 2013-03-01 Release Manager: Philip Nienhuis =============================================================================== ** Bug fixes: --- post_install.m: fixed wrong format specifier in error message --- chk_spreadsheet_support: Java call to return JVM memory size returns varying type dependent on Java version. Made this part of code more robust. Also prepared for Octave-3.8 built-in Java support --- xlsopen.m, odsopen.m: improved matching file type to specific interfaces (e.g., .sxc can only be read by JOD and UNO; .xlsx only by COM, POI-OOXML and UNO) ** moved common Java detection code from getods/getxlsinterfaces to separate function ** post_install: if PKG_ADD couldn't be removed from .oct file dir, inform user to add spreadsheet Java class libs manually to the javaclasspath ** Replaced all calls to to-be-deprecated java_new & java_invoke calls by javaObject and javaMethod =============================================================================== io-1.2.0 Release Date: 2012-12-27 Release Manager: Philip Nienhuis =============================================================================== This will be the last major version that is "depending" on the separate Java package for most of the spreadsheet I/O. In a next major version this will be based on Octave's built-in Java support. Some of the spreadsheet support files in io-1.2.0 are expected not to work anymore in Octave-3.8+ ** Bug fixes: --- xls2oct(POI)/__POI_spsh2oct__: now correctly evaluates formulas (as far as POI can handle cell formulas) --- Fixed sheet selection code for UNO and COM interfaces ** Moved all interface-specific subfunctions and code into ./private subdir. This allowed for elimination of a lot of duplicate code. ** Moved functions parse_sp_range.m, spsh_chkrange.m & spsh_prstype.m into ./private subdir ** Support for POI 3.9 added =============================================================================== io-1.0.20 Release Date: 2012-09-07 Release Manager: Philip Nienhuis =============================================================================== ** Bug fixes: --- xlsopen, xlsclose, odsopen, odsclose: replaced canonicalize_file_name call with make_absolute_filename for non-windows systems (canonicalize_file_name doesn't work with non-existent (new) files on *nix) (bug #36677); Web addresses (URLs) only need two rather than three slashes; --- xlsopen: matching .jar names to javaclasspath entries worked the wrong way --- io_xls_testscript / io_ods_testscript: added small delay for UNO calls to avoid lock-ups with recent LibreOffice (3.6.x) ** The annoying flashing LibreOffice splash screens have been fixed upstream; with LibreOffice 3.6.1 I didn't see them anymore ** Extended file rename section in odsclose similar to that in xlsclose =============================================================================== io-1.0.19 Release Date: 2012-06-08 Release Manager: Philip Nienhuis =============================================================================== ** Bug fixes: --- getusedrange subfunc getusedrange_jod: str2num applied to indices rather than the substring. Must have been there for > 2 years, only surfaced with jopendocument v 1.3b1 --- oct2xls, oct2ods: cast all numeric types in input array to double as spreadsheets have only double, boolean or character string type. This bug has been there from the very beginning of the spreadsheet functions >8-O --- Support for reading back formulas from .xls spreadsheets using ActiveX/COM ** Compatible with jOpenDocument version 1.3b1 getUsedRange() method added (MUCH faster than the old hack) ** Compatible with odfdom-java-0.8.8-incubator.jar (ODF Toolkit 0.5-incubating) ** Compatible with Apache POI 3.8 final =============================================================================== io-1.0.18 Release Date: 2012-03-22 Release Manager: Philip Nienhuis =============================================================================== ** The following functions have been imported from the miscellaneous package: cell2csv csvconcat xmlread csv2cell csvexplode xmlwrite Their error messages and help messages have been cleaned up a bit. ** Bug fixes: --- odsfinfo: fixed "wrong type argument `cell'" bug when run interactively. --- xlsopen, odsopen: fixed messed up screen output due to UNO usage warning. --- csv2cell: checks if file is empty and if so, return an empty cell. --- xlsopen: better Java detection logic, more informative error messages ** Adapted to internal LibreOffice-3.5-final changes. Some bugs (flashing LO screens) still have to be fixed upstream - see here: https://bugs.freedesktop.org/show_bug.cgi?id=42470 ** Tried OpenXLS-6.0.7.jar. Reads OK, still unusable for writing .xls files. =============================================================================== io-1.0.17 Release Date: 2012-02-27 Release Manager: Philip Nienhuis =============================================================================== ** Bug fixes: --- oct2ods, oct2xls, odswrite default range input arg. These functions may not have worked properly for two years (!) ** Fixed support for odfdom v.0.8.7 (ODS). Note: the OTK interface only works well with xercesImpl.jar 2.9.1 (Sep 14, 2009) ** Many small bug fixes & documentation updated to actual functionality. ** Fixed "seealso" texinfo header string in almost all functions. ** Added formal test scripts to "internal functions" section. =============================================================================== io-1.0.16 Release Date: 2012-01-19 Release Manager: Philip Nienhuis =============================================================================== ** Bug fixing release ** PKG_ADD now expects Java spreadsheet class libs (.jars) in /lib/java (for MinGW) =============================================================================== io-1.0.15 Release Date: 2011-10-02 Release Manager: Philip Nienhuis =============================================================================== io-1.0.15 is primarily a bug fix release and a snapshot / wrap-up of current development status (some still a bit experimental). It mainly comprises: ** A number of bug fixes (incl. some serious ones, notably with .ods/OOo Calc); ** Some mainly cosmetic improvements to existing code; less verbosity; ** pch2mat (reading & transforming Nastran PCH files, contributed by B. Oytun Peksel); ** object2json.m (creating a json description string of objects, contributed by Daniel Torre). This was already silently introduced in io-1.0.14; ** A scripted troubleshooting / classpath setup tool for spreadsheet I/O support (chk_spreadsheet_support.m); ** Experimental OXS support (OpenXLS) for reading Excel xls (BIFF8). OpenXLS is -let's say- a little bit lacking: For reading it is faster than JXL. However, while OXS write support has been coded (and works) I had to disable it as the OXS Java classes won't release the file handle so Octave will hang upon closing :-( I'm stuck with this so I just release it as-is; ** Experimental UNO support, i.e. invoking OpenOffice.org (or clones like LibreOffice) behind the scenes to read spreadsheet files, much like ActiveX/COM for MS-Excel. This is also based on Java. The first time you use UNO, OOo has to be loaded and you'll have to be patient, but once loaded (and in the OS cache) you'll see the pros: --* Very fast; --* Much lower Java memory usage as OOo loads the spreadsheet in its own memory chunk (not Octave's) => much bigger spreadsheet capacity; --* You can read *all* formats supported by OOo: .ods, .xls, .csv, .xlsx, .sxc, .dbf, Lotus wk1, Quattro Pro, ......; and it doesn't really matter whether xlsopen of odsopen is used. Of course all this wonderful stuff comes at a prize: --* After closing the spreadsheet file (odsclose, xlsclose) ALL OOo invocations will be closed, also those started outside Octave. This is due to "the way OpenOffice works" (quoted from OOo dev forum), especially through Java. There are other ways to close OOo but they'll hang Octave; --* The Java UNO classes supplied with e.g. LibreOffice aren't kept quite up-to-date with the main program. As a consequence, with e.g., LibreOffice 3.4 the main LO window will pop up (it can't be hidden). I filed a bug report for this (https://bugs.freedesktop.org/show_bug.cgi?id=40991) but I haven't seen it being picked up yet. Another example: while LO 3.3.1's row capacity was already > 10^6, it took until LO 3.4 before this capacity was implemented in the Java UNO classes. Like with OXS, I'm a bit stuck here - all this has to be fixed upstream. Hint: for older Octave versions (< 3.4.0) you can install io-1.0.15 using the -nodeps flag. You'll then loose the old and buggy textread and csv/dlm-read/write functions but I'd consider that as no big loss. io-2.4.10/PaxHeaders.5973/src0000644000000000000000000000013213226215411012400 xustar0030 mtime=1515789065.028183488 30 atime=1515789065.028183488 30 ctime=1515789065.028183488 io-2.4.10/src/0000755000175000017500000000000013226215411012715 5ustar00olafolaf00000000000000io-2.4.10/src/PaxHeaders.5973/m40000644000000000000000000000013213226215407012725 xustar0030 mtime=1515789063.608155636 30 atime=1515789065.028183488 30 ctime=1515789065.028183488 io-2.4.10/src/m4/0000755000175000017500000000000013226215407013242 5ustar00olafolaf00000000000000io-2.4.10/src/m4/PaxHeaders.5973/octave-forge.m40000644000000000000000000000013213226215407015625 xustar0030 mtime=1515789063.608155636 30 atime=1515789063.980162933 30 ctime=1515789065.028183488 io-2.4.10/src/m4/octave-forge.m40000644000175000017500000000575313226215407016077 0ustar00olafolaf00000000000000# Copyright (C) 2017 Olaf Till # Modifications to print what is searching for by JohnD # # 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 . # arguments of OF_OCTAVE_ALT_SYMS (see also description of # OF_OCTAVE_LIST_ALT_SYMS below): # # $1: symbol version 1 # $2: symbol version 2 # $3: test for symbol version 2 # $4: macro name to access alternative symbols # $5: include directives for symbol version 1 # $6: include directives for symbol version 2 # (a list of lists of args 1--6 is $1 of OF_OCTAVE_LIST_ALT_SYMS) # $7: name of generated include file with alternatives of Octave headers # (arg7 is $2 of OF_OCTAVE_LIST_ALT_SYMS) AC_DEFUN([OF_OCTAVE_ALT_SYMS], [ AC_MSG_CHECKING([$1 or $2]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[#include ] $6], [$3])], [AC_DEFINE($4, [[$2]], [macro for alternative Octave symbols]) AC_MSG_RESULT([$2]) echo '$6' >> $7], [AC_DEFINE($4, [[$1]], [macro for alternative Octave symbols]) AC_MSG_RESULT([$1]) echo '$5' >> $7] ) ]) # OF_OCTAVE_LIST_ALT_SYMS is called in the following way: # # OF_OCTAVE_LIST_ALT_SYMS([ # [dnl # [old_octave_symbol], # [new_octave_symbol], # [[compilation test] # [for new_octave_symbol]], # [NAME_OF_GENERATED_MACRO____WILL_EXPAND_TO_OLD_OR_NEW_SYMBOL], # [[include directives] # [except #include ] # [necessary to compile with old_octave_symbol]], # [[include directives] # [except #include ] # [nessary to compile with new_octave_symbol] # [and to compile the test]] # ], # # ... further such lists as the above # # ], # # [name-of-header-file-for-alternative-octave-iclude-directives.h]) # # # This file should be put into src/m4/, and the line # # AC_CONFIG_MACRO_DIRS([m4]) # # should be put into src/configure.ac. The package should use # autoheader to generate config.h.in (src/bootstrap should contain the # lines 'aclocal', 'autoconf', and 'autoheader -f'). Package code # should include config.h and use the generated macros to access the # alternative symbols of Octave. An example of a call to # OF_OCTAVE_LIST_ALT_SYMS in src/configure.ac is available together # with this file. AC_DEFUN([OF_OCTAVE_LIST_ALT_SYMS], [ echo '/* generated by configure */' > $2 m4_foreach([it], [$1], [m4_apply([OF_OCTAVE_ALT_SYMS], [it, $2])]) AH_BOTTOM([#include "$2"]) ]) io-2.4.10/src/PaxHeaders.5973/csv2cell.cc0000644000000000000000000000013213226215407014506 xustar0030 mtime=1515789063.608155636 30 atime=1515789063.608155636 30 ctime=1515789065.028183488 io-2.4.10/src/csv2cell.cc0000644000175000017500000003741713226215407014762 0ustar00olafolaf00000000000000// Copyright (C) 2004 Laurent Mazet // Copyright (C) 2014-2018 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 . /* %% Check EOF w/o preceding EOL & text fields in 1st column disguised as numeric str %!test %! f = tmpnam (); %! fid = fopen (f, 'w+'); %! fprintf (fid, "\"1\""); %! fclose (fid); %! s = csv2cell (f){1}; %! unlink (f); %! assert (s, "1"); %!test %! f = tmpnam (); %! csvwrite(f, "\"1\",2", "DELIMITER", ""); %! s = csv2cell(f); %! unlink (f); %! assert (s{1}, "1"); %! assert (s{2}, 2); %!test %! f = tmpnam (); %! csvwrite(f, "3,\"1\"", "DELIMITER", ""); %! s = csv2cell(f); %! unlink (f); %! assert (s{1}, 3); %! assert (s{2}, "1"); %% Check proper string protection %!test %! f = tmpnam (); %! fid = fopen (f, 'w+'); %! str = ['01/03/2012,"H (Mar, 12)",26.750000,2584' "\n"]; %! str = [str '"01/04/2012",H (Mar, 12),2330' "\n"]; %! str = [str '"01/05/2012","H (Mar 12)",26.000000,3198' "\n"]; %! str = [str '01/06/2012,H (Mar 12),25.500000,3045' "\n"]; %! fprintf (fid, str); %! fclose (fid); %! s = csv2cell (f); %! unlink (f); %! assert (isnumeric ([s{1:4, 4}]), true); %! ddd = datenum (s{2,1}, "dd/mm/yyyy") - datenum (s{1,1}, "dd/mm/yyyy"); %! assert (ddd, 31.0, 1e-5); %! assert (iscellstr (s(1:4, 2)), true); %! assert (isnumeric ([s{1, 3} s{3:4, 3}]), true); %! assert (ischar (s{2, 3}), true); %% Check separator and string protection arguments %!test %! f = tmpnam (); %! fid = fopen (f, 'w+'); %! str = ['01/03/2012;$H (Mar; 12)$;26.750000;2584' "\n"]; %! str = [str '$01/04/2012$;H (Mar; 12);2330' "\n"]; %! str = [str '$01/05/2012$;$H (Mar 12)$;26.000000;3198' "\n"]; %! str = [str '01/06/2012;H (Mar 12);25.500000;3045' "\n"]; %! fprintf (fid, str); %! fclose (fid); %! s = csv2cell (f, ";", "$"); %! unlink (f); %! assert (isnumeric ([s{1:4, 4}]), true); %! ddd = datenum (s{2,1}, "dd/mm/yyyy") - datenum (s{1,1}, "dd/mm/yyyy"); %! assert (ddd, 31.0, 1e-5); %! assert (iscellstr (s(1:4, 2)), true); %! assert (isnumeric ([s{1, 3} s{3:4, 3}]), true); %! assert (ischar (s{2, 3}), true); %% Check headerlines, %!test %! f = tmpnam (); %! fid = fopen (f, 'w+'); %! fprintf (fid, "A, B\n 1, 2\n 3, 4\n 5, 6\n"); %! fclose (fid); %! s = csv2cell (f); %! assert (iscellstr (s(1, :)), true); %! assert (cell2mat (s(2:end, :)), [1 2; 3 4; 5 6], 1e-10); %! s = csv2cell (f, 1); %! assert (cell2mat (s), [1 2; 3 4; 5 6], 1e-10); %! s = csv2cell (f, 3); %! assert (cell2mat (s), [5 6], 1e-10); %! s = csv2cell (f, -3); %! assert (iscellstr (s(1, :)), true); %! assert (cell2mat (s(2:end, :)), [1 2; 3 4; 5 6], 1e-10); %! s = csv2cell (f, 5); %! assert (iscell (s) && isempty (s)); %! unlink (f); %% Check surplus headerlines w EOF before final EOL %!test %! f = tmpnam (); %! fid = fopen (f, 'w+'); %! fprintf (fid, "A, B\n 1, 2\n 3, 4\n 5, 6"); %! fclose (fid); %! s = csv2cell (f, 10); %! unlink (f); %! assert (iscell (s) && isempty (s)); %% Check if csv2cell ignores trailing CR's in cells %!test %! f = tmpnam (); %! fid = fopen (f, 'w+'); %! fprintf (fid, "a\r\n1\r\nc\n4\n"); %! fclose (fid); %! s = csv2cell (f); %! unlink (f); %! assert (uint16 ([s{1} s{3}]), uint16([97 99])); %! assert ([s{2} s{4}], [1 4]); %% Check spreadsheet style range arg %!test %! f = tmpnam (); %! fid = fopen (f, 'w+'); %! fprintf (fid, '1,2,3\n11,12,13,"14",15,16\n,22\n31,32,"33",34\n41,"42",,44,45\n51,52,53'); %! fclose (fid); %! s = csv2cell (f, "b2:e5"); %! unlink (f); %! assert (cell2mat(s([1; 2; 3; 5; 11; 13])), [12; 22; 32; 13; 34; 15], eps); %! assert (s([7; 9]), {"33"; "14"}); %! assert (all (cellfun (@isempty, s([6, 8, 10, 14:15])))); %% Check files with uneven line length w/o range arg %!test %! f = tmpnam (); %! fid = fopen (f, 'w+'); %! fprintf (fid, 'a,b,c,d,e,f\n11,12,13,"14",15,16\n,22\n31,32,"33",34\n41,"42",,44,45\n51,52,53'); %! fclose (fid); %! s = csv2cell (f); %! unlink (f); %! assert (size (s), [6 6]); %! assert (cell2mat(s([2, 4:6, 8:10, 12, 14, 18, 22:23, 26, 29, 32])), ... %! [11, 31, 41, 51, 12, 22, 32, 52, 13, 53, 34, 44, 15, 45, 16], eps); %! assert ([s(1,:), s(11), s(16), s(20)], {"a", "b", "c", "d", "e", "f", ... %! "42", "33", "14"}); %! assert (all (cellfun (@isempty, s([3, 15, 17, 21, 24, 27:28, 30, 33:36])))); %% Check ":" separator %!test %! f = tmpnam (); %! fid = fopen (f, 'w+'); %! fprintf (fid, "1:2\n3:4\n5:6"); %! fclose (fid); %! s = csv2cell (f, ":"); %! unlink (f); %! assert (cell2mat(s), [1, 2; 3, 4; 5, 6], eps); %% Check ":" separator and spreadsheet style range combi %!test %! f = tmpnam (); %! fid = fopen (f, 'w+'); %! fprintf (fid, "1:2:3\n4:5:6\n7:8:9\n"); %! fclose (fid); %! s = csv2cell (f, "b2:c3", ":"); %! unlink (f); %! assert (cell2mat(s), [5, 6; 8,9], eps); %% Errors %!error csv2cell (); %!error csv2cell ("___.csv"); %!error csv2cell ("file.csv", "a&:f3"); %!error csv2cell ("file.csv", "b2:a1"); %!error csv2cell ("f.csv", ",,"); %!error csv2cell ("f.csv", ",", "[]"); */ #include #include #include #include #include #include #include "config.h" #define MAXSTRINGLENGTH 4096 DEFUN_DLD (csv2cell, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{c} = } csv2cell (@var{file})\n\ @deftypefnx {Loadable Function} {@var{c} = } csv2cell (@var{file}, @var{sep})\n\ @deftypefnx {Loadable Function} {@var{c} = } csv2cell (@var{file}, @var{sep}, @var{prot})\n\ @deftypefnx {Loadable Function} {@var{c} = } csv2cell (@var{file}, @var{hl}, ...)\n\ @deftypefnx {Loadable Function} {@var{c} = } csv2cell (@var{file}, @var{range}, ...)\n\ \n\ Read a CSV (Comma Separated Values) file and convert it into a cell \ array.\n\ \n\ @var{sep} (a character value) changes the character used to separate \ two fields. The default value is a comma (@code{,}).\n\ \n\ @var{prot} (a character value) changes the character used to protect \ a string. The default is a double quote (@code{\"}).\n\ \n\ Optional argument @var{hl} (a numeric value >= 0) is the number of \ headerlines to skip; negative values are ignored. If @var{hl} is \ equal to or larger than the total number of lines in the file, no \ data are read and an empty cell array is returned.\n\ \n\ Alternatively, optional argument @var{range} can be specified as a \ spreadsheet-style cell range to specify a block of fields to be \ returned in @var{c}. If the specified column range reaches beyond \ the number of fields on a line, the output cell array is padded with \ empty string values. If the specified row range exceeds the number \ of lines in the \ file, the range is silently truncated to match the number of lines \ per file.\n\ \n\ If no range argument is supplied, csv2cell assumes the first line \ contains column headers and the number of fields in the first line is \ supposed to be the number of columns in the output array. A warning \ is emitted then if any data line contains more fields than the header \ line.\n\ \n\ Note: newline characters in fields (i.e., multi-line text fields) are not \ allowed.\n\ \n\ The maximum line width of the csv file is set to 4096 characters.\n\ (This is also the theoretical maximum number of columns in the data \n\ if all fields are empty, i.e., a line containing just 4096 consecutive \n\ separators.)\n\ @end deftypefn") { /* Get arguments */ const int nargin = args.length (); octave_value_list retval; if (nargin == 0) { error ("csv2cell: not enough input arguments"); return retval; } const std::string file = args (0).string_value (); /* Look if first arg after filename = numeric. If yes => headerlines */ long hlines = (nargin > 1 && args(1).OV_ISNUMERIC () ? args(1).long_value() : 0); int arg_sh = (nargin > 1 && args(1).OV_ISNUMERIC () ? 1 : 0); bool lr = false; int lcol = 1; int rcol = 0; // int ipos = 1; int icol = 0; long irow = 0; long brow = 0; if (nargin > 1 && ! arg_sh) { std::string addr = args(1).string_value (); std::transform (addr.begin (), addr.end (), addr.begin (), ::toupper); size_t smcln = addr.find (":"); if (addr.size () > 1 && smcln != std::string::npos) { // Seems to be an address arg_sh = 1; size_t addr_len = addr.size (); size_t ii = 0; int dc; long dr; while (ii < addr_len) { switch (addr[ii]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { irow = irow * 10; dr = (long) (addr[ii] - 48); irow = irow + dr; break; } case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': { icol = icol * 26; dc = (int) (addr[ii] - 64); icol = icol + dc; break; } case ':': { lcol = icol; icol = 0; // ipos = 1; hlines = irow - 1; irow = 0; lr = true; break; } default: { // Assume it's a plain letter a-z error ("csv2cell: illegal character in address argument"); break; } } ++ii; } if (lcol < 1) lcol = 1; rcol = icol; brow = irow; if (rcol < lcol || brow < hlines + 1 || lcol < 1 || hlines < 0) error ("csv2cell: illegal cell range specified"); if (rcol > MAXSTRINGLENGTH + 1) error ("csv2cell: nr. of columns too large for buffer size"); } } const std::string _sep = (nargin > arg_sh + 1) ? args(arg_sh + 1).string_value () : ","; if (_sep.length() != 1) { error ("csv2cell: separator value can only be one character\n"); return retval; } char sep = _sep[0]; const std::string _prot = (nargin > arg_sh + 2) ? args(arg_sh + 2).string_value () : "\""; if (_prot.length() != 1) { error ("csv2cell: protector value can be only one character\n"); return retval; } char prot = _prot[0]; /* Open file */ std::ifstream fd (file.c_str ()); if (!fd.is_open ()) { error ("csv2cell: cannot open file %s for reading\n", file.c_str()); return retval; } fd.seekg (0, std::ios::end); long fdend = fd.tellg (); fd.seekg (0, std::ios::beg); if (fd.tellg () >= fdend) return octave_value (Cell (0, 0)); /* Buffers */ char line [MAXSTRINGLENGTH]; std::string str, word; bool inside = false; /* Read headerlines */ for (long ii=0; ii < hlines; ii++) { fd.getline (line, MAXSTRINGLENGTH); if (fd.tellg () >= fdend || fd.fail ()) return octave_value (Cell (0, 0)); } /* Read a first data line */ str = ""; fd.getline (line, MAXSTRINGLENGTH); while (fd.fail ()) { fd.clear (); str += line; fd.getline (line, MAXSTRINGLENGTH); } str += line; /* Parse first line to get number of columns */ int nbcolumns = 0; for (int i = 0, len = str.length (); i <= len; i++) if (i == len || ((str[i] == sep || str[i] == 10) && ! inside)) nbcolumns++; else if ((inside) && (str[i] == prot) && ((i < len) && (str[i+1] == prot))) ++i; else if (str[i] == prot) inside = !inside; /* Read all the file to get number of rows */ long nbrows = 1; while (fd.tellg () <= fdend && fd.peek () != EOF) { fd.getline (line, MAXSTRINGLENGTH); while (fd.fail () && fd.peek() != EOF) { fd.clear (); fd.getline (line, MAXSTRINGLENGTH); } nbrows++; } fd.clear(); /* In case of address range, fix up nbrows */ if (lr && nbrows + hlines > brow) nbrows = brow - hlines; /* Rewind */ fd.seekg (0, std::ios::beg); if (!fd.good ()) { error ("csv2cell: cannot reread %s\n", file.c_str ()); return retval; } /* Again, read headerlines */ for (long ii = 0; ii < hlines; ii++) { fd.getline (line, MAXSTRINGLENGTH); } /* Read all the file until the end */ int ncols; if (lr) ncols = rcol - lcol + 1; else { rcol = nbcolumns; ncols = nbcolumns; } Cell c (nbrows, ncols); // Initialize c to be able to cope with heterogeneous line length csv's for (long i = 0; i < ncols; i++) for (long j = 0; j < nbrows; j++) c(j, i) = ""; // c(j, i) = octave::numeric_limits::NaN (); bool line_too_long = false; for (long i = 0; i < nbrows; i++) { /* Read a line */ str = ""; fd.getline (line, MAXSTRINGLENGTH); while (fd.fail ()) { fd.clear (); str += line; fd.getline (line, MAXSTRINGLENGTH); } str += line; /* Explode a line into a sub cell */ word = ""; // inside = (str[0] == prot); inside = false; int j = 0; // Keep track of when just read, but not yet copied field, was inside (text) bool oinside = false; int len = str.length (); for (int k = 0; k <= len; k++) { if (((k == len) || (str[k] == sep)) && (!inside)) { /* Check number of columns */ if (!lr && !line_too_long && j == nbcolumns) { line_too_long = true; warning ("csv2cell: line(s) found with more fields than in headerline"); break; } /* Check for last char to be 13 (CR) and remove if found */ if (word[word.length ()-1] == char(13)) word.resize (word.size () - 1); /* Check if scalar */ const char *word_str = word.c_str (); char *err; double val = strtod (word_str, &err); /* Store into the cell; check if it is in address argument range*/ if ((j+1 >= lcol && j < rcol)) { c(i, j-lcol+1) = ((word == "") || oinside || (err != word_str+word.length())) ? octave_value (word) : octave_value (val); } j++; word = ""; oinside = false; } else if ((inside) && (str[k] == prot) && ((k < len) && (str[k+1] == prot))) { /* Inside a string */ word += prot; ++k; } else if (str[k] == prot) { /* Changing */ oinside = inside; inside = !inside; } else word += str[k]; } } /* Close file */ fd.close (); retval (0) = c; return retval; } io-2.4.10/src/PaxHeaders.5973/csvexplode.cc0000644000000000000000000000013213226215407015145 xustar0030 mtime=1515789063.608155636 30 atime=1515789063.608155636 30 ctime=1515789065.028183488 io-2.4.10/src/csvexplode.cc0000644000175000017500000000616713226215407015417 0ustar00olafolaf00000000000000// Copyright (C) 2004 Laurent Mazet // // 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 . #include #include #include "config.h" DEFUN_DLD (csvexplode, args, nargout, "-*- texinfo -*-\n" "@deftypefn {Loadable Function} {@var{c} =} csvexplode (@var{str})\n" "@deftypefnx {Loadable Function} {@var{c} =} csvexplode (@var{str}, @var{sep})\n" "@deftypefnx {Loadable Function} {@var{c} =} csvexplode (@var{str}, @var{sep}, @var{prot})\n" "\n" "Explode a CSV string into a cell. " "@var{sep} (character value) changes the character used to separate two fields. " "The default value is a comma (@code{,}). @var{prot} (character value) changes " "the character used to protect a string. The default is a double quote (@code{\"}).\n" "@end deftypefn") { /* Check argument */ if ((args.length() < 1) || (args.length() > 3)) { print_usage (); return octave_value(); } /* Get arguments */ if (! args(0).is_string ()) { if (args(0).OV_ISCELL ()) return octave_value (args(0)); else return octave_value (Cell(args(0))); } std::string str = args(0).string_value(); std::string _sep = (args.length() > 1) ? args(1).string_value() : ","; if (_sep.length() != 1) { error("csvexplode: separator can only be one character\n"); return octave_value(); } char sep = _sep[0]; std::string _prot = (args.length() > 2) ? args(2).string_value() : "\""; if (_prot.length() != 1) { error("csvexplode: protector can only be one character\n"); return octave_value(); } char prot = _prot[0]; /* Explode a line into a cell */ Cell retval; std::string word; bool inside = false; for (int i=0, len=str.length(); i<=len; i++) { if (((i==len) || (str[i] == sep)) && (!inside)) { /* Extand cell */ retval.resize(dim_vector(1, retval.columns()+1)); /* Check if scalar */ const char *word_str=word.c_str(); char *err; double val = strtod (word_str, &err); /* Store into the cell */ retval(0, retval.columns()-1) = ((word == "") || (err != word_str+word.length())) ? octave_value(word) : octave_value(val); word = ""; } else if ((inside) && (str[i]==prot) && ((i>. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and Philip Nienhuis $0: about your system, including $0: any error possibly output before this message. Then $0: install a modern shell, or manually run the script $0: under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='io' PACKAGE_TARNAME='io' PACKAGE_VERSION='2.4.10' PACKAGE_STRING='io 2.4.10' PACKAGE_BUGREPORT='Philip Nienhuis ' PACKAGE_URL='' ac_unique_file="csv2cell.cc" ac_subst_vars='LTLIBOBJS LIBOBJS CXXCPP OBJEXT EXEEXT ac_ct_CXX CPPFLAGS LDFLAGS CXXFLAGS CXX OCTAVE_CONFIG MKOCTFILE target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking ' ac_precious_vars='build_alias host_alias target_alias CXX CXXFLAGS LDFLAGS LIBS CPPFLAGS CCC CXXCPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures io 2.4.10 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/io] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of io 2.4.10:";; esac cat <<\_ACEOF Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CXXCPP C++ preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to >. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF io configure 2.4.10 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by io $as_me 2.4.10, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" # Avoid warnings for redefining AH-generated preprocessor symbols of # Octave. # Checks for programs. # Extract the first word of "mkoctfile", so it can be a program name with args. set dummy mkoctfile; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MKOCTFILE+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MKOCTFILE"; then ac_cv_prog_MKOCTFILE="$MKOCTFILE" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MKOCTFILE="mkoctfile" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MKOCTFILE=$ac_cv_prog_MKOCTFILE if test -n "$MKOCTFILE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKOCTFILE" >&5 $as_echo "$MKOCTFILE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$MKOCTFILE"; then as_fn_error 1 "mkoctfile not found" "$LINENO" 5; fi # Extract the first word of "octave-config", so it can be a program name with args. set dummy octave-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OCTAVE_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OCTAVE_CONFIG"; then ac_cv_prog_OCTAVE_CONFIG="$OCTAVE_CONFIG" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OCTAVE_CONFIG="octave-config" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OCTAVE_CONFIG=$ac_cv_prog_OCTAVE_CONFIG if test -n "$OCTAVE_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCTAVE_CONFIG" >&5 $as_echo "$OCTAVE_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$OCTAVE_CONFIG"; then as_fn_error 1 "octave-config not found" "$LINENO" 5; fi # The same value of CXX as Octave was compiled with is supposed to be used. CXX=${CXX:-`${MKOCTFILE} -p CXX`} ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 $as_echo_n "checking whether the C++ compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C++ compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 $as_echo_n "checking for C++ compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Checks for libraries. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. # Start of checks for Octave features, preparations for checks. OCTLIBDIR=${OCTLIBDIR:-`$OCTAVE_CONFIG -p OCTLIBDIR`} ## We need Octaves include path both with and without '/octave' ## appended. The path without '/octave' is needed to selectively test ## for Octave headers, like octave/....h. The path with '/octave' is ## needed since some Octave headers contain include directives for ## other Octave headers with <> instead of "". OCTINCLUDEDIR=${OCTINCLUDEDIR:-`$MKOCTFILE -p INCFLAGS`} ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu TCXXFLAGS=$CXXFLAGS TLDFLAGS=$LDFLAGS TLIBS=$LIBS TCPPFLAGS=$CPPFLAGS LDFLAGS="-L$OCTLIBDIR $LDFLAGS" LIBS="-loctinterp $LIBS" # CXXFLAGS= CPPFLAGS="$OCTINCLUDEDIR $CPPFLAGS" ## Simple symbol alternatives of different Octave versions. echo '/* generated by configure */' > oct-alt-includes.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking is_numeric_type or isnumeric" >&5 $as_echo_n "checking is_numeric_type or isnumeric... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { octave_value ().isnumeric (); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : $as_echo "#define OV_ISNUMERIC isnumeric" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: isnumeric" >&5 $as_echo "isnumeric" >&6; } echo ' ' >> oct-alt-includes.h else $as_echo "#define OV_ISNUMERIC is_numeric_type" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: is_numeric_type" >&5 $as_echo " is_numeric_type" >&6; } echo '' >> oct-alt-includes.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking is_cell or iscell" >&5 $as_echo_n "checking is_cell or iscell... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { octave_value ().iscell (); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : $as_echo "#define OV_ISCELL iscell" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: iscell" >&5 $as_echo "iscell" >&6; } echo ' ' >> oct-alt-includes.h else $as_echo "#define OV_ISCELL is_cell" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: is_cell" >&5 $as_echo " is_cell" >&6; } echo '' >> oct-alt-includes.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking is_empty or isempty" >&5 $as_echo_n "checking is_empty or isempty... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { octave_value ().isempty (); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : $as_echo "#define OV_ISEMPTY isempty" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: isempty" >&5 $as_echo "isempty" >&6; } echo ' ' >> oct-alt-includes.h else $as_echo "#define OV_ISEMPTY is_empty" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: is_empty" >&5 $as_echo " is_empty" >&6; } echo '' >> oct-alt-includes.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext LIBS=$TLIBS LDFLAGS=$TLDFLAGS CXXFLAGS=$TCXXFLAGS CPPFLAGS=$TCPPFLAGS ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # End of checks for Octave features. cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by io $as_me 2.4.10, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration headers: $config_headers Report bugs to >." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ io config.status 2.4.10 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi io-2.4.10/src/PaxHeaders.5973/config.h.in0000644000000000000000000000013013226215411014476 xustar0029 mtime=1515789065.02418341 29 atime=1515789065.02418341 30 ctime=1515789065.028183488 io-2.4.10/src/config.h.in0000644000175000017500000000142313226215411014740 0ustar00olafolaf00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ #include "undef-ah-octave.h" /* macro for alternative Octave symbols */ #undef OV_ISCELL /* macro for alternative Octave symbols */ #undef OV_ISEMPTY /* macro for alternative Octave symbols */ #undef OV_ISNUMERIC /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION #include "oct-alt-includes.h" io-2.4.10/src/PaxHeaders.5973/Makefile0000644000000000000000000000013213226215407014122 xustar0030 mtime=1515789063.608155636 30 atime=1515789063.608155636 30 ctime=1515789065.028183488 io-2.4.10/src/Makefile0000644000175000017500000000027713226215407014370 0ustar00olafolaf00000000000000all: csvexplode.oct csv2cell.oct csvconcat.oct cell2csv.oct col2num.oct num2col.oct MKOCTFILE ?= mkoctfile %.oct: %.cc $(MKOCTFILE) $< clean: rm -f *.o octave-core core *.oct *.mex *~ io-2.4.10/src/PaxHeaders.5973/bootstrap0000644000000000000000000000013213226215407014422 xustar0030 mtime=1515789063.608155636 30 atime=1515789063.620155871 30 ctime=1515789065.028183488 io-2.4.10/src/bootstrap0000755000175000017500000000005513226215407014665 0ustar00olafolaf00000000000000#! /bin/sh aclocal autoconf autoheader -f io-2.4.10/src/PaxHeaders.5973/undef-ah-octave.h0000644000000000000000000000013213226215407015601 xustar0030 mtime=1515789063.612155714 30 atime=1515789063.612155714 30 ctime=1515789065.028183488 io-2.4.10/src/undef-ah-octave.h0000644000175000017500000000070613226215407016044 0ustar00olafolaf00000000000000/* To be included at the top of config.h (by autoheader). Avoid warnings for redefining AH-generated preprocessor symbols of Octave. */ #ifdef PACKAGE_BUGREPORT #undef PACKAGE_BUGREPORT #endif #ifdef PACKAGE_NAME #undef PACKAGE_NAME #endif #ifdef PACKAGE_STRING #undef PACKAGE_STRING #endif #ifdef PACKAGE_TARNAME #undef PACKAGE_TARNAME #endif #ifdef PACKAGE_URL #undef PACKAGE_URL #endif #ifdef PACKAGE_VERSION #undef PACKAGE_VERSION #endif io-2.4.10/src/PaxHeaders.5973/num2col.cc0000644000000000000000000000013213226215407014350 xustar0030 mtime=1515789063.608155636 30 atime=1515789063.608155636 30 ctime=1515789065.028183488 io-2.4.10/src/num2col.cc0000644000175000017500000000274313226215407014616 0ustar00olafolaf00000000000000// Copyright (C) 2014-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 . #include DEFUN_DLD (num2col, args, nargout, "-*- texinfo -*-\n" "@deftypefn {Loadable Function} {@var{CIDX} = } num2col (@var{N})\n" "\n" "Convert a numerical column number into a spreadsheet column Id. " "@end deftypefn") { /* Get arguments */ const int nargin = args.length (); octave_value_list retval; std::string val = ""; // Input check if (nargin != 1) { error ("num2col: exactly one input argument expected"); return retval; } int nn = args (0).int_value (); int rmd; while (nn > 0) { rmd = nn % 26; if (rmd == 0) { rmd = 26; } val = std::string (1, rmd+64).append (val); nn = nn - rmd; nn = nn / 26; } return octave_value (val, '\''); }io-2.4.10/src/PaxHeaders.5973/col2num.cc0000644000000000000000000000013213226215407014350 xustar0030 mtime=1515789063.608155636 30 atime=1515789063.608155636 30 ctime=1515789065.028183488 io-2.4.10/src/col2num.cc0000644000175000017500000000272413226215407014615 0ustar00olafolaf00000000000000// Copyright (C) 2014-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 . #include DEFUN_DLD (col2num, args, nargout, "-*- texinfo -*-\n" "@deftypefn {Loadable Function} {@var{N} = } col2num (@var{CIDX})\n" "\n" "Convert a spreadsheet column Id into a numerical column number. " "@end deftypefn") { /* Get arguments */ const int nargin = args.length (); octave_value retval = -1; // Input check if (nargin != 1) { error ("col2num: exactly one input argument expected"); return retval; } std::string cidx = args (0).string_value (); std::transform (cidx.begin (), cidx.end (), cidx.begin (), ::toupper); retval = 0; int dd; for (int ii=0, len = cidx.length (); ii < len; ii++) { dd = (int) (cidx[ii] - 64); retval = retval*26 + dd; } return retval; }io-2.4.10/src/PaxHeaders.5973/cell2csv.cc0000644000000000000000000000013213226215407014506 xustar0030 mtime=1515789063.608155636 30 atime=1515789063.608155636 30 ctime=1515789065.028183488 io-2.4.10/src/cell2csv.cc0000644000175000017500000001072213226215407014750 0ustar00olafolaf00000000000000// Copyright (C) 2004 Laurent Mazet // Copyright (C) 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 . /* %% Straightforward performance %!test %! arr = arr1 = num2cell (randn (3, 3)); %! for ii=1:size (arr, 1) %! arr1(ii, ii) = sprintf ("\"Val = %f\"", arr{ii, ii}); %! endfor %! f = tmpnam(); %! cell2csv (f, arr1); %! arr2 = csv2cell (f); %! unlink (f); %! idx = find (cellfun ("ischar", arr2)); %! arr2(idx) = cellfun (@(x) str2double(strrep(x, "Val = ", "")), arr2(idx), "Uni", false); %! assert (arr, arr2, 1e-5); %% Test with SEP and PROT args %!test %! arr = arr1 = num2cell (randn (3, 3)); %! for ii=1:size (arr, 1) %! arr1(ii, ii) = sprintf ("Val = %f", arr{ii, ii}); %! endfor %! arr1(2, 2) = [arr1{2, 2} ";"]; %! f = tmpnam(); %! cell2csv (f, arr1, ";", "&"); %! arr2 = csv2cell (f, ";", "&"); %! unlink (f); %! assert (arr2{2, 2}(end), ";"); %! arr2(2, 2) = strrep (arr2{2, 2}, ";", ""); %! idx = find (cellfun ("ischar", arr2)); %! arr2(idx) = cellfun (@(x) str2double(strrep(x, "Val = ", "")), arr2(idx), "Uni", false); %! assert (arr, arr2, 1e-5); */ #include #include #include #include #include "config.h" DEFUN_DLD (cell2csv, args, nargout, "-*- texinfo -*-\n" "@deftypefn {Loadable Function} {} cell2csv (@var{file}, @var{c})\n" "@deftypefnx {Loadable Function} {} cell2csv (@var{file}, @var{c}, @var{sep})\n" "@deftypefnx {Loadable Function} {} cell2csv (@var{file}, @var{c}, @var{sep}, @var{prot})\n" "\n" "Create a CSV file from a cell array. " "@var{sep} (character value) changes the character used to separate two fields. " "The default value is a comma " "(@code{,}). @var{prot} (character value) changes the character used to protect a string. " "Default value is a double quote (@code{\"}).\n" "@end deftypefn") { /* Check argument */ if ((args.length() < 2) || (args.length() > 4)) { print_usage (); return octave_value(); } /* Get arguments */ std::string file = args(0).string_value(); Cell c = args(1).cell_value(); std::string sep = (args.length() > 2) ? args(2).string_value() : ","; if (sep.length() != 1) { error("cell2csv: separator can only be one character\n"); return octave_value(); } std::string prot = (args.length() > 3) ? args(3).string_value() : "\""; if (prot.length() != 1) { error("cell2csv: protector can only be one character\n"); return octave_value(); } /* Open file */ std::ofstream fd(file.c_str()); if (!fd.is_open()) { error("cell2csv: cannot open file %s for writing\n", file.c_str()); return octave_value(); } /* Concat a cell into a string */ std::string word; /* For each element */ for (int i=0, il=c.rows(); i // // 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 . #include #include DEFUN_DLD (csvconcat, args, nargout, "-*- texinfo -*-\n" "@deftypefn {Loadable Function} {@var{str} = } csvconcat (@var{c})\n" "@deftypefnx {Loadable Function} {@var{str} = } csvconcat (@var{c}, @var{sep})\n" "@deftypefnx {Loadable Function} {@var{str} = } csvconcat (@var{c}, @var{sep}, @var{prot})\n" "\n" "Concatenate a cell into a CSV string or array of strings. " "@var{sep} (character value) changes the character used to separate two fields. " "The default value is a comma " "(@code{,}). @var{prot} (character value) changes the character used to protect a string. " "The default is a double quote (@code{\"}).\n" "@end deftypefn") { /* Check argument */ if ((args.length() < 1) || (args.length() > 3)) { print_usage (); return octave_value(); } /* Get arguments */ Cell c = args(0).cell_value(); std::string sep = (args.length() > 1) ? args(1).string_value() : ","; if (sep.length() != 1) { error("csvconcat: separator can only be one character\n"); return octave_value(); } std::string prot = (args.length() > 2) ? args(2).string_value() : "\""; if (prot.length() != 1) { error("csvconcat: protector can only be one character\n"); return octave_value(); } /* Concat a cell into a string */ string_vector vec(c.rows()); std::string word; /* For each element */ for (int i=0, il=c.rows(); i ### ### 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 ### . AC_PREREQ([2.67]) AC_INIT([io], [2.4.10], [Philip Nienhuis ]) AC_CONFIG_SRCDIR([csv2cell.cc]) AC_CONFIG_HEADERS([config.h]) # Avoid warnings for redefining AH-generated preprocessor symbols of # Octave. AH_TOP([#include "undef-ah-octave.h"]) AC_CONFIG_MACRO_DIRS([m4]) # Checks for programs. AC_CHECK_PROG(MKOCTFILE, mkoctfile, mkoctfile) if test -z "$MKOCTFILE"; then AC_MSG_ERROR([mkoctfile not found], 1); fi AC_CHECK_PROG(OCTAVE_CONFIG, octave-config, octave-config) if test -z "$OCTAVE_CONFIG"; then AC_MSG_ERROR([octave-config not found], 1); fi # The same value of CXX as Octave was compiled with is supposed to be used. CXX=${CXX:-`${MKOCTFILE} -p CXX`} AC_PROG_CXX AC_PROG_CXXCPP # Checks for libraries. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. # Start of checks for Octave features, preparations for checks. OCTLIBDIR=${OCTLIBDIR:-`$OCTAVE_CONFIG -p OCTLIBDIR`} ## We need Octaves include path both with and without '/octave' ## appended. The path without '/octave' is needed to selectively test ## for Octave headers, like octave/....h. The path with '/octave' is ## needed since some Octave headers contain include directives for ## other Octave headers with <> instead of "". OCTINCLUDEDIR=${OCTINCLUDEDIR:-`$MKOCTFILE -p INCFLAGS`} AC_LANG_PUSH([C++]) TCXXFLAGS=$CXXFLAGS TLDFLAGS=$LDFLAGS TLIBS=$LIBS TCPPFLAGS=$CPPFLAGS LDFLAGS="-L$OCTLIBDIR $LDFLAGS" LIBS="-loctinterp $LIBS" # CXXFLAGS= CPPFLAGS="$OCTINCLUDEDIR $CPPFLAGS" ## Simple symbol alternatives of different Octave versions. OF_OCTAVE_LIST_ALT_SYMS([ [dnl [is_numeric_type], [isnumeric], [[octave_value ().isnumeric ();]], [OV_ISNUMERIC], [], [] ], [dnl [is_cell], [iscell], [[octave_value ().iscell ();]], [OV_ISCELL], [], [] ], [dnl [is_empty], [isempty], [[octave_value ().isempty ();]], [OV_ISEMPTY], [], [] ] ], [oct-alt-includes.h]) LIBS=$TLIBS LDFLAGS=$TLDFLAGS CXXFLAGS=$TCXXFLAGS CPPFLAGS=$TCPPFLAGS AC_LANG_POP([C++]) # End of checks for Octave features. AC_OUTPUT io-2.4.10/src/PaxHeaders.5973/aclocal.m40000644000000000000000000000013213226215410014314 xustar0030 mtime=1515789064.328169758 30 atime=1515789064.580174701 30 ctime=1515789065.028183488 io-2.4.10/src/aclocal.m40000644000175000017500000000127313226215410014557 0ustar00olafolaf00000000000000# generated automatically by aclocal 1.14.1 -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_include([m4/octave-forge.m4]) io-2.4.10/PaxHeaders.5973/doc0000644000000000000000000000013213226215407012363 xustar0030 mtime=1515789063.552154538 30 atime=1515789065.028183488 30 ctime=1515789065.028183488 io-2.4.10/doc/0000755000175000017500000000000013226215407012700 5ustar00olafolaf00000000000000io-2.4.10/doc/PaxHeaders.5973/READ-XLS.html0000644000000000000000000000013213226215407014505 xustar0030 mtime=1515789063.552154538 30 atime=1515789063.552154538 30 ctime=1515789065.028183488 io-2.4.10/doc/READ-XLS.html0000644000175000017500000011460713226215407014756 0ustar00olafolaf00000000000000

README for Excel spreadsheet file r/w access scripts for octave (> 3.8.x)

Copyright (C) 2009 - 2017 Philip Nienhuis <prnienhuis at users.sf.net>

February 4, 2017

EXCEL .XLS SUPPORT FILES


doc/README-XLS.html
This file.

xlsread.m
All-in-one function for reading data from one specific worksheet in an Excel spreadsheet file. This script has Matlab-compatible functionality.

xlswrite.m
All-in-one function for writing data to one specific worksheet in an Excel spreadsheet file. This script has Matlab-compatible functionality.

xlsfinfo.m
All-in-one function for exploring basic properties of an Excel spreadsheet file. This script has Matlab-compatible functionality.

xlsopen.m
Function for "opening" (= providing a handle to) an Excel spreadsheet file ("workbook"). This function sorts out which interface to use for .xls access (i.e.,COM; Java & Apache POI; JexcelAPI; OpenXLS; etc.), but it's choice can be overridden.

xls2oct.m
Function for reading data from a specific worksheet pointed to in a struct created by xlsopen.m. xls2oct can be called multiple times consecutively using the same pointer struct, each time allowing to read data from different ranges and/or worksheets. Data are returned in the form of a 2D heterogeneous cell array that can be parsed by parsecell.m. xls2oct is a mere wrapper for interface-dependent scripts that do the actual low-level reading.

oct2xls.m
Function for writing data to a specific worksheet pointed to in a struct created by xlsopen.m. octxls can be called multiple times consecutively using the same pointer struct, each time allowing to write data to different ranges and/or worksheets. oct2xls is a mere wrapper for interface-dependent scripts that do the actual low-level writing.

xlsclose.m
Function for closing (the handle to) an Excel workbook. When data have been written to the workbook oct2xls will write the workbook to disk. Otherwise, the file pointer is simply closed and possibly used interfaces for Excel access (COM/ActiveX/Excel.exe) will be shut down properly.

parsecell.m
Function for separating the data in raw arrays returned by xls2oct, into numerical/logical and text (cell) arrays.

chk_spreadsheet_support.m
Internal function for (1) checking, (2) setting up, (3) debugging spreadsheet support. While not specifically meant for direct invocation from the Octave prompt (it is more useful during initialization of Octave itself) it can be very helpful when hunting down issues with spreadsheet support in Octave.
calccelladdress.m,
Support function called by the script functions; calculates spreadsheet type row/column address based on 1-based row/column numbers.

test_spsh.m, io_xls_testscript.m
Undocumented scripts for testing basic features of the spreadsheet scripts. Meant for testers and developers, but I don't mind ordinary users to give it a try.


REQUIRED SUPPORT SOFTWARE


For the native Octave interface (OCT)

(read/write support for OOXML (Excel 2007+), ODS 1.2 (LibreOffice/OpenOffice.org Calc), and Gnumeric)
NO external support software is required!

For the Excel/COM interface:
  • A windows computer with Excel installed
  • Octave-forge Windows-1.2.1 (Windows-1.2.2 for Octave 4.0+)

For the Java / Apache POI / JExcelAPI / OpenXLS / LibreOffice | OpenOffice.org interfaces (general):

  • Octave 3.7.2 or later with Java support compiled in
  • Java JRE or JDK > 1.6.0 (hasn't been tested with earlier versions)
Apache POI specific:

and here:

  • for OOXML support with Apache POI:

poi-ooxml-schemas-<version>.jar, + either xbean.jar or xmlbeans.jar, + dom4j-1.6.1.jar in javaclasspath.

Get them here:

http://poi.apache.org/download.html ("xmlbeans" and poi-ooxml-schemas)

http://sourceforge.net/projects/dom4j/files (dom4j-<version>)

Starting with POI-3.15, another Java class lib is required: commons-collections4-.jar
    Recent releases of Apache POI provide zipped / tar.gz'd archives with all required files inside.
JExcelAPI specific:
OpenXLS specific:
These class libs must be referenced with full pathnames in your javaclasspath.
When the io package gets loaded, a utility function (PKG_ADD) invokes an initiaization function that tries to automatically find the Java class libs and adds the ones it found to the javaclasspath; When the io package gets unloaded, these same class libs will be removed from the javaclasspath.

On MinGW the required Java class libs had best be put in /<libdir>/java (where <libdir> on MinGW is usually /lib); on Linux system supplied Java class libs usually reside in /usr/share/java. Alternatively, you can put them in your HOME directory in a subdirectory java (mind case!) - on *nix that would be ~./java, on Windows %USERPROFILE%/java (same level as My Documents). The PKG_ADD routine, that gets run each time the io package is loaded, expects the class libs there; if they are elsewhere, add them in ./share/octave/<version>/m/startup/octaverc using appropriate javaaddpath statements or a chk_spreadsheet_support() call.
In addition, you can specify a subdirectory using the environment variable OCTAVE_IO_JAVALIBS.
Once a particular Java class lib has been added to the javaclasspath, it won't be searched anymore nor reloaded from the next search location. The search order is:
  1. Specified by the environment variable OCTAVE_IO_JAVALIBS
  2. <HOME_DIR>/java
  3. /usr/share/java (*nix) or /lib/java (MinGW)
If you do not want PKG_ADD to load the Java class libs, specify a value of "no", "false" or "0" for the OCTAVE_IO_JAVALIBS environment variable before starting Octave.
UNO specific (invoking OpenOffice.org (or clones) behind the scenes):
NOTE: EXPERIMENTAL!! A working OpenOffice.org installation. The utility function chk_spreadsheet_support can be used to add the needed entries to the javaclasspath. Be aware that OpenOffice.org/LibreOffice arch type (32-bit or 64-bit) must match Octave's arch type.


USAGE


xlsread and xlswrite are mere wrappers for xlsopen-xls2oct-xlsclose-parsecell and xlsopen-oct2xls-xlsclose sequences, resp. They exist for the sake of Matlab compatibility.

xlsfinfo can be used for finding out what worksheet names exist in the file. For OOXML files you either need MS-Excel 2007 for Windows (or later version) installed, and/or the input parameter REQINTF should be specified with a value of 'poi', 'oxs' or 'uno' (case-insensitive) and -obviously- either the complete POI interface must have been installed, and/or OpenXLS, and/or LibreOffice/OpenOffice.org.

Invoking xlsopen/..../xlsclose directly provides for much more flexibility, speed, and robustness than xlsread / xlswrite. Indeed, using the same file handle (pointer struct) you can mix reading & writing before writing the workbook out to disk using xlsclose.
And: xlsopen / xlsclose hide the gory interface details from the user.
Currently only .xls files (BIFF8) can be read/written; using JExcelAPI BIFF5 can be read as well. For OOXML files either Excel 2007 for Windows (or higher) and/or the complete Apache POI interface, and/or OpenXLS v 10, or LibreOffice must be installed (and probably the REQINTF parameter specified with a value of 'poi', 'oxs', or 'uno').

When using xlsopen....xlsclose be sure to keep track of the file handle struct.

A possible scenario:

xlh = xlsopen (<excel_filename> , [rw], [<requested interface>])
# Set rw to 1 if you want to write to a workbook immediately.
# In that case the check for file existence is skipped and
# -if needed- a new workbook created.
# If you really want an other interface than auto-selected
# by xlsopen you can request that. But xlsopen still checks
# proper support for your choice.


# Read some data
[ rawarr1, xlh ] = xls2oct (xlh, <SomeWorksheet>, <Range>)
# Be sure to specify xlh as output argument as xls2oct keeps
# track of changes and the need to write the workbook to disk
# in the xlhstruct. And the origin range is conveyed through
# the xlh pointer struct.


# Separate data into numeric and text data
[ numarr1, txtarr1, lim1 ] = parsecell (rawarr1)

# Get more data from another worksheet in the same workbook
[ rawarr2, xlh ] = xls2oct (xlh, <SomeOtherWorksheet>, <Range>)
[ numarr2, txtarr2, lim2 ] = parsecell (rawarr2)

# <... Analysis and preparation of new data in cell array Newdata....>

# Add new data to spreadsheet
xlh = oct2xls (Newdata, xlh, <AnotherWorksheet>, <Range>)

# Close the workbook and write it to disk; then clear the handle
xlh = xlsclose (xlh)
clear xlh
When not using the COM interface, specify a value of 'POI' for parameter REQINTF when accessing OOXML files in xlsread, xlswrite, xlsopen, xlsfinfo (and be sure the complete Apache POI interface is installed). If you haven't got ActiveX installed (i.e., not having MS-Excel under Windows) specifying 'POI' may not be needed as in such cases Apache POI is the next default interface.
When using JExcelAPI (JXL), after writing into a worksheet you MUST save the file adding data to the same or another worksheet is no more possible after the first call to oct2xls(). This is a limitation of JExcelAPI.

SPREADSHEET FORMULA SUPPORT, STRIPPING AND ENCODING


When using the COM, POI, JXL, OXS, UNO and OCT interfaces you can:
  • (When reading, xls2oct) either read evaluated spreadsheet formula results, or the literal formula text strings;
  • (When writing, oct2xls) either enter text strings in the form of spreadsheet formulas in the worksheet as formulas, or enter them as literal text strings.

In short, you can enter spreadsheet formulas and in a later stage read them back, change them and re-enter them in the worksheet. 

The behaviour is controlled by an option structure options which has some fields ("flags") that can be set to TRUE or FALSE:
  • options.formulas_as_text = 0 (the default) implies enter formulas as formulas and read back formula results
    options.formulas_as_text =1 (or any positive integer) means enter formulas as text strings and read them back as text strings.
    Be aware that there's no formula evaluator in JExcelAPI (JXL). So if you create formulas in your spreadsheet using oct2xls or xlswrite with 'JXL', do not expect meaningful results when reading those files later on unless you open them in Excel and write them back to disk.
    While both Apache POI and JExcelAPI feature a formula validator, not all spreadsheet functions present in Excel have been implemented (yet).
    Worse, older Excel versions feature less functions than newer versions. So be wary as this may make for interesting confusion.
  • options.strip_array = 1 (the default) instructs Octave to strip the output arrays resulting from reading a spreadsheet from empty outer rows and columns.
    options.strip_array = 0 will return the complete requested output range.
  • options.convert_utf = 0 (the default) leave UTF-8 encoded text strings read from a spreadsheet untouched. Usually this works well as the Octave terminal usually knows how to display UTF-8 encoded strings - but note that Octve itself has limited support for processing multibyte-character strings. Windows 10 has proper support for UTF-8 in the cmd.exe terminal (used by Octave); but older Windows versions may need a conversion step:
    options.convert_utf = 1 currently invokes conversion functions utf82unicode.m (when reading from spreadsheet) or unicode2utf8 (when writing to spreadsheet). This can be useful when the strings in Octave that are intended to be written to spreadsheet file contain characters outside the range [32:127]; Excel and LibreOffice cannot process spreadsheets containing single characters outside that range.

Note that when invoking xlsread.m and xlswrite.m, these options are not available. To use these options you need to invoke xls2oct.m / oct2xls.m as outlined above under USAGE

MATLAB COMPATIBILITY


xlsread, xlswrite and xlsfinfo are for the most part Matlab-compatible. Some small differences are mentioned below. When using the Java interfaces octave supplies some formula manipulation support.

xlsread
Matlab's xlsread supports invoking extra functions while reading ("passing function handle"); octave not. But this can be simulated outside xlsread.

Matlab's xlsread flags some spreadsheet errors, octave-forge just returns blank cells.

Octave's xlsread (and for that matter, xlsfinfo as well) returns info about the actual (rather than the requested) cell range where the data came from. Personally I find it very useful to know from what part of a worksheet the data originate so I've put quite some effort in it :-)
Matlab can't, due to Excel automatically trimming returned arrays from empty outer columns and rows. Octave is more clever but the Visual Basic call used for determining the actually used range has some limitations: (1) it relies on cached range values and thus may be out-of-date, and (2) it counts empty formatted cells too. When using ActiveX/COM, if octave's xlsfinfo.m returns wrong data ranges it is most often an overestimation.
Matlab's xlsread ignores all non-numeric data values outside the smallest rectangle encompassing all numerical values. Octave's xlsread doesn't. This means that Matlab ignores all row/column headers, not very user-friendly IMO.

When using the Java interface, reading and writing xls-files by octave's xlsread is platform-independent. On systems w/o installed Excel, Matlab can only read Excel 95 formatted .xls files (written using ML xlswrite's 'Basic" option) and then differently than under Windows.....
Matlab's xlsread returns strings for cells containing date values. This makes for endless if-then-elseif-else-end constructs to catch all expected date formates. Octave returns numerical data (where 0 = 1/1/1900 you can easily transfer them into proper octave date values yourself using e.g. datestr(), see bottom of this document for more info).

xlswrite
Octave's xlswrite works on systems w/o Excel support, Matlab's doesn't (properly).
When specifying a sheet number larger than the number of existing sheets in an .xls file, Matlab's xlswrite adds empty sheets until the new sheet number is created; Octave's xlswrite only adds one sheet called "Sheet<number>" where <number> is the specified sheet number.
Even better (IMO) while M's xlswrite always creates Sheet1/Sheet2/Sheet3 when creating a new spreadsheet, octave's xlswrite only creates the requested worksheet. (Did you know that you can instruct Excel to create spreadsheets with just one, or any number of, worksheets? Look in Tools | Options, General tab.)
Oh and octave doesn't touch the "active sheet" - but that's not automatically an advantage.
If the specified write range is larger than the actual data array, Matlab's xlswrite adds #N/A cells to fill up the lowermost rows and rightmost columns; octave-forge's xlswrite doesn't.

xlsfinfo
When invoking Excel/COM interface, Octave's xlsfinfo also echoes the type of sheet (worksheet, chart), not just the sheet names. Using Java I haven't found similar functionality (yet).
Octave's xlsfinfo also shows (and returns) the range of the smallest rectangle encompassing all occupied data ranges in each sheet.

COMPARISON OF INTERFACES & USAGE

Using Excel itself (through COM / ActiveX on Windows systems) is probably the most robust and versatile and especially FAST option (though for OOXML the OCT interface is probably faster). There's one gotcha: in case of some type of COM errors Excel will keep running invisibly; you can only end it through Task Manager.
A tiny problem is that one cannot find out easily through COM what file types are supported; xls, wks, wk1, xlsx, etc.
Another -obvious- limitation is that COM Excel access only works on Windows systems where Excel is installed.

JExcelAPI (Java-based and therefore platform-independent) is proven technology but switching between reading and writing is quite involved and memory-hungry when processing large spreadsheets. As the docs state, JExcelAPI is optimized for reading and it does do that well - but still slower than Excel/COM. The fact that upon a switch from reading to writing the existing spreadsheet is overwritten in place by a blank one and that you can only get the contents back wen writing out all of the changes is worrying - and any change after the first write() is lost as a next write() doesn't seem to work, worse yet, you may completely loose the spreadsheet in question. The first is by JExcelAPI design, the second is probably a bug (in octave-forge/Java or JExcelAPI ? I don't know). Adding data to existing spreadsheets does work, but IMO undue user confidence is needed.
JExcelAPI supports BIFF5 (only reading) and BIFF8 (Excel 95 and Excel 97-2003, respectively). Upon overwriting, BIFF5 spreadsheets are converted silently to BIFF8.
JexcelAPI, unlike ApachePOI, doesn't evaluate functions while reading but instead relies on cached results (i.e. results computed by Excel itself). Depending on Excel settings ("Automatic calculation" ON or OFF) this may or may not yield incorrect (or expected) results.

Apache POI (Java-based and platform-independent too) is based on the OpenOffice.org I/O Excel r/w routines. It is a more versatile than JExcelAPI, while it doesn't support BIFF5 it does support BIFF8 (Excel 97 2003) and OOXML (Excel 2007).
It is slower than native JXL let alone Excel & COM but it features active formula evaluation, although at the moment (early 2015, v. 3.11) still not *all* Excel functions have been implemented (a daunting task for the POI devs, as it is hard to keep up with MS here). I've made the relevant subfunction (xls2jpoi2oct) fall back to cached formula results (and yield a suitable warning) for non-implemented Excel functions while reading Excel files.

OpenXLS (an open source version of Extentech's commercial Java-xls product) is still a bit experimental. It seems to work faster than JExcelAPI, but it has other issues - i.e., processing of OOXML files is still unreliable. In addition OpenXLS scatters Extentech.tmp files here and there. For .xls (BIFF8) it works OK.

UNO (invoking OpenOffice.org (OOo) or LibreOffice (LO) or clones behind the scenes, a la ActiveX) is experimental. It works FAST (i.e., once OOo itself is loaded and initialized which can take some time) and can process much larger spreadsheets than the other Java-based interfaces because the data are not entered in the JVM but in OOo's memory.
A big stumbling block is that odsclose() on a UNO xls struct will kill ALL OpenOffice.org invocations, also those that were not related to Octave! This is due to UNO-Java limitations.
The underlying issue is that when Octave starts an OpenOffice.org invocation, OpenOffice.org must be closed for Octave to be able to exit; otherwise Octave will wait for OOo to shut down before it can terminate itself. So Octave must kill OOo to be able to terminate.
A way out hasn't been found yet.

All in all, of the three Java options I'd prefer Apache POI rather than OpenXLS or JexcelAPI. But the latter is indispensable for BIFF5 formats. Once UNO is stable it is to be preferred as it can read ALL file formats supported by OOo (viz. wk1, ods, xlsx, sxc, ...). If you need to process really large spreadsheets, UNO is by far the fastest option (behind COM on Windows systems), but for smaller spreadsheets you'll find that the other interfaces are more efficient.

The OCT interface (native Octave calls) is by far the fastest for OOXML, the only Octave option for gnumeric, but for ODS it is still slower than COM/ActiveX or UNO. Experimental OCT write support is available for OOXML, ODS 1.2 and gnumeric but not extensively tested yet.

Some notes on the choice for Java:
  1. It saves a LOT of development time to use ready-baked Java classes rather than developing your own routines and thus effectively reinvent the wheel.
  2. A BIG advantage is that a Java-based solution is platform-independent ("portable").
  3. The Java classes offer much more options than just reading and writing. Formatting, recalculation options, hiding/merging cell ranges, etc.
  4. But Java is known to be not very conservative with resources, especially not when processing XML-based formats.
So Java is a compromise between portability and rapid development time versus capacity (and speed).
But IMO data sets larger than 5.105 cells should not be kept in spreadsheets anyway. Better use real databases for such data sets.

A NOTE ON JAVA MEMORY USAGE

Java memory pool allocation size

The Java virtual machine (JVM), when initialized by octave, reserves one big chunk of your computer's RAM in which all java classes and methods etc. are to be loaded: the java memory pool. It does this because java has a very sophisticated "garbage collection" system. At least on Windows, the initial size is 2MB and the maximum size is 16 MB. On Linux this allocated size might differ (e.g., my Mandriva box with openJDK has a 512 MB default max setting). This part of memory is where the Java-based XLS/ODS octave routines live and keep their variables etc.
For transferring large pieces of information to and from spreadsheets you might hit the limits of this pool. E.g. to be able to handle I/O of an array of around 500,000 cells I needed a memory pool size of 512 MB.
The memory size can be increased by inserting a file called "java.opts" (without quotes) in the directory ./share/octave//java (where the script file javaclasspath.m is located; try "which javaclasspath" in an Octave terminal to get the proper location), containing just the following lines:
-Xms16m
-Xmx512m
(where 16 = initial size, 512 = maximum size (in this example), m stands for Megabyte. This maximum is system-dependent. E.g., I have a 1 GB setting).
For further details consult the Octave manual, "Java Interface", "FAQ", "How can I handle memory limitations?"


After processing a large chunk of spreadsheet information you might notice that octave's memory footprint does not shrink so it looks like Java's memory pool does not shrink back; but rest assured, the memory footprint is the allocated (reserved) memory size, not the actual used size. After the JVM has done its garbage collection, only the so-called "working set" of the memory allocation is really in use and that is a trimmed-down part of the memory allocation pool. On Windows systems it often suffices to minimize the octave terminal for a few seconds to get a more reasonable memory footprint.

TROUBLESHOOTING

Some hints for troubleshooting Excel support are contained in this thread:
http://sourceforge.net/mailarchive/forum.php?thread_name=4C61B649.9090802%40hccnet.nl&forum_name=octave-dev
dated August 10, 2010.
A more structured approach is below.

Since April 2011 a special purpose setup file has been included in the io package (chk_spreadsheet_support.m). Large parts of the approach below (starting at Step 2) have been automated in this script. When running it with the second input argument (debug level) set to 3 a lot of useful diagnostic output will be printed to screen.
  1. Check if COM / ActiveXworks (only under Windows OS). Do a pkg list and see
  2. a. If there's a windows package mentioned (then it's installed). If not, install it.

    b. If there's an asterisk on the windows package line (then the package is loaded). If not, do a pkg load windows

  3. Check if the ActiveX server works. Do:
  4. exl = actxserver ('Excel.Application') ## Note the period between "Excel" and "Application"

    If a COM object is returned, ActiveX / COM / Excel works. Do: exl.Quit(); delete (exl) to shut down the (hidden) Excel invocation.

    If you get an error message, your last resort is re-installing the windows package, or trying the Java-based interfaces.

  5. Check if java works.
    As of Octave-3.8, Java is usually built-in and step 3 does not apply anymore
    Do a
    pkg list and see

a. If there's a java package mentioned (then it's installed). If not, install it. Don't do this in Octave 3.8 and higher!!

b. If there's an asterisk on the java package line (then the package is loaded). If not, do a pkg rebuild -auto java Don't do this in Octave 3.8 and higher!!

  1. Check Java memory settings. Try javamem
  2. a. If it works, check if it reports sufficiently large max memory (had better be 200 MiB, the bigger the better)

    b. If it doesn't work, do:

    rt = java_invoke ('java.lang.Runtime', 'getRuntime')
    rt.gc
    rt.maxMemory ().doubleValue () / 1024 / 1024

    The last command will show MaxMemory in MiB.

    c. In case you have insufficient memory, see in "GOTCHAS", "Java memory pool allocation size", how to increase java's memory pre-reservation.

  3. Check if all classes (.jarfiles) are in class path. Do a 'javaclasspath' (under unix/linux, do 'tmp = javaclasspath; strsplit (tmp,":")' (w/o quotes). See above under "REQUIRED SUPPORT SOFTWARE" what classes should be mentioned.

If classes (.jar files) are missing, download and put them somewhere and add them to the javaclass path with their fully qualified pathname (in quotes) using javaaddpath().

Once all classes are present and in the javaclasspath, the xls interfaces should just work. The only remaining showstoppers are insufficient write privileges for the working directory, a wrecked up octave or some other problem outside octave.

  1. Try opening an xls file:

xls1 = xlsopen ('test.xls', 1, 'poi'). If this works and xls1 is a struct with various fields containing objects, the Apache POI interface (POI) works. Do an xls1 = xlsclose (xls1) to close the file.

xls2 = xlsopen ('test.xls', 1, 'jxl'). If this works and xls2 is a struct with various fields containing objects, the JExcelAPI interface (JXL) works as well. Don't forget to do xls2 = xlsclose (xls2) to close the file.

DEVELOPMENT

xlsopen/xlsclose and friends have been written so that adding other interfaces (Perl? native octave? ...?) should be very easily accomplished. xlsopen.m merely needs two stanzas, xlsfinfo.m, xls2oct.m, oct2xls.m and getusedrange.m each need an additional elseif stanza, and xlsclose.m needs a small stanza for closing the pointer struct and writing to disk.
The real work lies in creating the relevant __<INTF>_spsh_open__.m & __<INTF>_spsh_close__.m, __<INTF>_spsh2oct__.m & __<INTF>_oct2spsh__.m, __<INTF>_spsh_info__.m, and __<INTF>_getusedrange__.m subfunction scripts in ./private subdir, but that shouldn't be really hard, depending on the interface support libraries' quality and documentation. The function scripts in the ./private subdir provide for ample examples.
Separating the file access functions and the actual reading/writing from/to the workbook in memory has made developer's life (I mean: my time developing this stuff) much easier.

Some other options for development (who?):
  • Speeding up, especially Java worksheet/cell access. For cracks, not me.
  • Automatic conversion of Excel date/time values into octave ones and vice versa (adding or subtracting 636960). But then again Excel's dates are 01-01-1900 based (octave's 0-0-0000) and buggy (Excel thinks 1900 is a leap year), and I sometimes have to use dates from before 1900. Maybe as an option?
  • Creating Excel graphs (a significant enterprise to write from scratch).
  • Support for "passing function handle" in xlsread.

Enjoy!

Philip Nienhuis, February 4, 2017
io-2.4.10/doc/PaxHeaders.5973/READ-ODS.html0000644000000000000000000000013213226215407014464 xustar0030 mtime=1515789063.552154538 30 atime=1515789063.552154538 30 ctime=1515789065.028183488 io-2.4.10/doc/READ-ODS.html0000644000175000017500000012334713226215407014736 0ustar00olafolaf00000000000000

ODS support for Octave

Copyright 2009 - 2016 Philip Nienhuis <prnienhuis at users.sf.net>

This version October 23, 2016

(ODS = Open Document Format spreadsheet data format, used by e.g., OpenOffice.org.)

Files content

odsread.m
No-hassle read script for reading from an ODS file and parsing the numeric and text data into separate arrays.

odswrite.m
No-hassle write script for writing to an ODS file.

odsopen.m 
Get a file pointer to an ODS spreadsheet file.

ods2oct.m
Read raw data from an ODS spreadsheet file using the file pointer handed by odsopen.

oct2ods.m
Write data to an ODS spreadsheet file using the file pointer handed by odsopen.

odsclose.m
Close file handle made by odsopen and -if data have been transfered to a spreadsheet- save data.

odsfinfo.m
Explore sheet names and optionally estimated data size of ods files with unknown content.

calccelladdress.m
Utility function, can be used to compute a spreadsheet-type cell adress from 1-based row and column numbers.

parsecell.m
(contained in Excel xlsread scripts, but works also for ods support) parse raw data (cell array) into separate numeric array and text (cell) array.)

chk_spreadsheet_support.m
Internal function for (1) checking, (2) setting up, (3) debugging spreadsheet support. While not specifically meant for direct invocation from the Octave prompt (it is more useful during initialization of Octave itself) it can be very helpful when hunting down issues with spreadsheet support in Octave.

test_spsh.m, io_ods_testscript.m
Undocumented scripts for testing basic operation of ODS spreadsheet functions. Meant for testers and developers, but I don't mind if mere mortal users give it a try as well ;-)


REQUIRED SUPPORT SOFTWARE

For the native Octave interface (OCT)

(read/write support for ODS 1.2 (LibreOffice/OpenOffice.org Calc), OOXML (Excel 2007+), and Gnumeric)
NO external support software is required!

Octave >= 3.8.0 will do just fine but maybe a bit slow. If you want faster I/O, Java support need to be compiled in, a Java JRE > 1.6.0 must be installed, and one or more of the following is required:

  • odfdom.jar (for the OTK interface, currently the preferred option)

  • and/or

  • jopendocument<version>.jar (for the JOD interface)


  • and/or

  • OpenOffice.org (or clones like LibreOffice, Go-Office, ...) (for the UNO interface)

      Get it from http://www.openoffice.org. The relevant Java class libs are unoil.jar, unoloader.jar, jurt.jar, juh.jar and ridl.jar (which are scattered around the OOo installation directory), while also the <OOo>/program/ directory needs to be in the classpath.
      NOTE: OOo's / LO's arch type (32-bit or 64-bit) must match Octave's arch. In other words, 64-bit Octave won't work with 32-bit LibreOffice, and vice versa.

    Whatever Java option, these class libs must be referenced with full pathnames in your javaclasspath.
    When the io package gets loaded, a utility function (PKG_ADD) tries to automatically find the Java class libs and adds the ones it found to the javaclasspath; When the io package gets unloaded, these same class libs will be removed from the javaclasspath.

    Except for the UNO (OOo) classes, on MinGW the jar files had best be put in /<libdir>/java where <libdir> on MinGW it is usually /lib; on Linux system supplied Java class libs usually reside in /usr/share/java. Alternatively, you can put them in your HOME directory in a subdirectory java (mind case!) - on *nix that would be ~./java, on Windows %USERPROFILE%/java (same level as My Documents). The PKG_ADD routine, that gets run each time the io package is loaded, expects the class libs there; if they are elsewhere, add them in ./share/octave/<version>/m/startup/octaverc using appropriate javaaddpath statements or a chk_spreadsheet_support() call.
    In addition, you can specify a subdirectory using the environment variable OCTAVE_IO_JAVALIBS.
    Once a particular Java class lib has been added to the javaclasspath, it won't be searched anymore nor reloaded from the next search location. The search order is:

    1. Specified by the environment variable OCTAVE_IO_JAVALIBS
    2. <HOME_DIR>/java
    3. /usr/share/java (*nix) or /lib/java (MinGW)
    If you do not want PKG_ADD to load the Java class libs, specify a value of "no", "false" or "0" for the OCTAVE_IO_JAVALIBS environment variable before starting Octave.


    USAGE

    (see help ods<function_filename> in octave terminal.)

    odsread is a sort of analog to xlsread and works more or less the same. odsread is a mere wrapper for the functions odsopen, ods2oct, and odsclose that do file access and the actual reading, plus parsecell for post-processing.

    odswrite works similar to xlswrite. It too is a wrapper for scripts which do the actual work and invoke other scripts, a.o. oct2ods.

    odsfinfo can be used to explore odsfiles with unknown content for sheet names and to get an impression of the data content sizes.

    When you need data from just one sheet, odsread is for you. But when you need data from multiple sheets in the same spreadsheet file, or if you want to process spreadsheet data by limited-size chunks at a time, odsopen / ods2oct [/parsecell] / / odsclose sequences provides for much more speed and flexibility as the spreadsheet needs to be read just once rather than repeatedly for each call to odsread.

    Same reasoning goes for odswrite.

    Also, if you use odsopen / ../, you can process multiple spreadsheets simultaneously just use odsopen repeatedly to get multiple spreadsheet file pointers.

    Moreover, after adding data to an existing spreadsheet file, you can fiddle with the filename in the ods file pointer struct to save the data into another, possibly new spreadsheet file.

    If you use odsopen / ods2oct / / oct2ods / . / odsclose, DO NOT FORGET to invoke odsclose in the end. The file pointers can contain an enormous amount of data and may needlessly keep precious memory allocated. In case of the UNO interface, the hidden OpenOffice.org invocation (soffice.bin) can even block proper closing of Octave.


    SPREADSHEET FORMULA SUPPORT, STRIPPING AND ENCODING

    When using the OTK, UNO, and/or OCT interface you can:
    • (When reading, ods2oct) either read spreadsheet formula results, or the literal formula text strings;
    • (When writing, oct2ods) either enter formulas in the worksheet as formulas, or enter them as literal text strings.
    In short, you can enter spreadsheet formulas and in a later stage read them back, change them and re-enter them in the worksheet.
    The behaviour is controlled by an option structure options which has some fields ("flags") that can be set to TRUE or FALSE:
    • options.formulas_as_text = 0 (the default) implies enter formulas as formulas and read back formula results
      options.formulas_as_text =1 (or any positive integer) means enter formulas as text strings and read them back as text strings.
      Be aware that there's no formula evaluator in ODS java, not even a formula validator. So if you create formulas in your spreadsheet using oct2ods or odswrite, do not expect meaningful results when reading those files later on unless you open them in OpenOffice.org Calc and write them back to disk.
      You can write all kind of junk as a formula into a spreadsheet cell. There's not much validity checking built into odfdom.jar. I didn't bother to try OpenOffice.org Calc to read such faulty spreadsheets, so I don't know what will happen with spreadsheets containing invalid formulas. But using the above options, you can at least repair them using octave....
      The only exception is if you select the UNO interface, as that invokes OpenOffice.org behind the scenes, and OOo obviously has a validator and evaluator built-in.
    • options.strip_array = 1 (the default) instructs Octave to strip the output arrays resulting from reading a spreadsheet from empty outer rows and columns.
      options.strip_array = 0 will return the complete requested output range.
    • options.convert_utf = 0 (the default) leave UTF-8 encoded text strings read from a spreadsheet untouched. Usually this works well as the Octave terminal usually knows how to display UTF-8 encoded strings - but note that Octve itself has limited support for processing multibyte-character strings. Windows 10 has proper support for UTF-8 in the cmd.exe terminal (used by Octave); but older Windows versions may need a conversion step:
      options.convert_utf = 1 currently invokes conversion functions utf82unicode.m (when reading from spreadsheet) or unicode2utf8 (when writing to spreadsheet). This can be useful when the strings in Octave that are intended to be written to spreadsheet file contain characters outside the range [32:127]; e.g., LibreOffice cannot process spreadsheets containing single characters outside that range.

    Note that when invoking odsread.m and odswrite.m, these options are not available. To use these options you need to invoke ods2oct.m / oct2ods.m as outlined above under USAGE

    GOTCHAS

    I know of one big gotcha: i.e. reading dates (& time). A less obvious one is Java memory pool allocation size.

    Date and time in ODS

    Octave (as does Matlab) stores dates as a number representing the number of days since January 1, 0 (and as an aside ignores a.o. Pope Gregorius' intervention in 1582 when 10 days were simply skipped).

    OpenOffice.org stores dates as text strings like yyyy-mm-dd.

    MS-Excel stores dates as a number representing the number of days since January 1, 1900 (and as an aside, erroneously assumes 1900 to be a leap year).

    Now, converting OpenOffice.org date cell values (actually, character strings flagged by date attributes) into Octave looks pretty straightforward. But when the ODS spreadsheet was originally an Excel spreadsheet converted by OpenOffice.org, the date cells can either be OOo date values (i.e.,strings) OR old numerical values from the Excel spreadsheet.

    So: you should carefully check what happens to date cells.

    As octave has no date or time data type, octave date values (usually numerical data) are simply transferred as floats to ODS spreadsheets. You'll have to convert the values into dates yourself from within OpenOffice.org.

    While adding data and time values has been implemented in the write scripts, the wait is for clever solutions to distinguish dates from floats in octave cell arrays.

    Java memory pool allocation size

    The Java virtual machine (JVM) initializes one big chunk of your computer's RAM in which all Java classes and methods etc. are to be loaded: the Java memory pool. It does this because Java has a very sophisticated garbage collection system. At least on Windows, the initial size is 2MB and the maximum size is 64MB. On Linux this allocated size is much bigger. This part of memory is where the Java-based ODS octave routines (and the Java-based ods routines) live and keep their variables etc.

    For transferring large pieces of information to and from spreadsheets you might hit the limits of this pool. E.g. to be able to handle I/O of an array of around 50,000 cells I needed a memory pool size of 512 MB.

    The memory size can be increased by inserting a file called java.opts (without quotes) in the directory ./share/octave/packages/java-<version> (where the script file javaclasspath.m is located), containing just the following lines:

    -Xms16m
    -Xmx512m

    (where 16 = initial size, 512 = maximum size (in this example), m stands for Megabyte. This number is system-dependent).

    After processing a large chunk of spreadsheet information you might notice that octave's memory footprint does not shrink so it looks like Java's memory pool does not shrink back; but rest assured, the memory footprint is the allocated (reserved) memory size, not the actual used size. After the JVM has done its garbage collection, only the so-called working set of the memory allocation is really in use and that is a trimmed-down part of the memory allocation pool. On Windows systems it often suffices to minimize the octave terminal for a few seconds to get a more reasonable memory footprint.

    Reading cells containing errors

    Spreadsheet cells containing erroneous stuff are transferred to Octave as NaNs. But not all errors can be catched. Cells showing #Value# in OpenOffice.org Calc often contain invalid formulas but may have a 0 (null) value stored in the value fields. It is impossible to catch this as there is no run-time formula evaluator (yet) in ODF Toolkit nor jOpenDocument (like there is in Apache POI for Excel).

    Smaller gotcha's (only with jOpenDocument 1.2b2, fixed in 1.2b3+ and 1.2 final):

    • While reading, empty cells are sometimes not skipped but interpreted with numerical value 0 (zero).

    • A valid range MUST be specified, I haven't found a way to discover the actual occupied rows and columns (jOpenDocument can give the physical ones (= capacity) but that doesn't help).

    NOT fixed in version 1.2 final nor 1.3b1:

    • jOpenDocument doesn't set the so-called <office:value-type='string'> attribute in cells containing text; as a consequence ODF Toolkit will treat them as empty cells. Ooo will read them OK.


    MATLAB COMPATIBILITY

    Depending on the MS-Excel version on the same computer, Matlab may read/write ODS files using xlsread/xlswrite. Note that decent ODS 1.2 support only started with Excel 2013.
    odsread is fairly function-compatible to xlsread, however.

    Same goes for odswrite, odsfinfo and xlsfinfo however odsfinfo has better functionality IMO.


    COMPARISON OF INTERFACES

    The ODFtoolkit is the one that gives the best (but slow) results at present. However, parsing xml trees into rectangular arrays is not quite straightforward and the other way round is a real nightmare; odftoolkit up til 0.7.5. did little to hide the gory details for the developers.

    While reading ODS is still OK, writing implies checking whether cells already exist explicitly (in table:table-cells) or implicitly (in number-columns-repeated or number-rows-repeated nodes) or not at all yet in which case you'll need to add various types of parent nodes. Inserting new cells (nodes) or deleting nodes implies rebuilding possibly large parts of the tree in memory - nothing for the faint-of-heart. Only with ODFToolkit (odfdom) 0.8.6, 0.8.7 and 0.8.8 things have been simplified for developers.
    Unfortunately, with odftoolkit-0.6.0-incubating and odftoolkit-0.6.1-incubating (corresponding to odfdom-0.8.9 and 0.8.10) unresolved dependencies ("jenasin") have been introduced that break their functionality for Octave.

    The jOpenDocument interface is more promising, as it does shield the xml tree details and presents developers something which looks like a spreadsheet model.
    However, unfortunately the developers decided to shield essential methods by making them 'protected' (e.g. the vital getCellType). JopenDocument does support writing. But OTOH many obvious methods are still lacking and formula support is absent (although announced for future version 1.4).
    And last (but not least) the jOpenDocument developers state that their development is primarily driven by requests from customers who pay for support. I do sympathize with this business model but for Octave needs this may hamper progress for a while.
    In addition, jOpenDocument 1.2 and 1.3b1 still have bugs here and there. For one, it doesn't write appropriate OfficeValueType attributes to the cells, so there's no way to reliably read and distinguish boolean, string and integer values.

    The (still experimental) UNO interface, based on a Java/UNO bridge linking a hidden OpenOffice.org invocation to Octave, is the most promising:

    • Admittedly OOo needs some tens of seconds to start for the first time, but once OOo is in the operating system's disk cache, it operates much faster than ODF or JOD;
    • It has built-in formula validator and evaluator;
    • It has a much more reliable data parser;
    • It can read much more spreadsheet formats than just ODS; .sxc (older OOo and StarOffice), but also .xls, .xlsx (Excel), .wk1 (Lotus 123), dbf, etc.
    • It consumes only a fraction of the JVM heap memory that the other Java ODS spreadsheet solutions need because OOo reads the spreadsheet in its own memory chunk in RAM. The other solutions read, expand, parse and manipulate all data in the JVM. In addition, OOo's code is outside the JVM (and Octave) while the ODF Toolkit and jOpenDocument classes also reside in the JVM.
    However, UNO is not stable yet (see below). As stated above, the arch type (32-bit or 64-bit) must match that of Octave..

    The OCT (native Octave) interface is also promising as it is completely under control of Octave (-Forge) developers. Currently it only offers read and -experimental- write support for ODS (relatively slow), gnumeric (faster) and OOXML (very fast). An immense advantage is that no other external software is required. Write support has not extensively tested yet, however.

    TROUBLESHOOTING

    Some hints for troubleshooting ODS support are given here.
    Since April 2011 the function chk_spreadsheet_support() has been included in the io package. Calling it with arguments ('', 3) (empty string and debug level 3) will echo a lot of diagnostics to the screen. Large parts of the steps outlined below have been automated in this script.
    Problems with UNO are too complicated to treat them here; most of the troubleshooting has been implemented in chk_spreadsheet_support.m, only some general guidelines are given below.

    1. Check if Java works.
      NOTE: As of Octave 3.8, Java support is usually built-in in Octave and the below description of the Java package does not apply anymore!
      Do a pkg list and see

      a. If there's a Java package mentioned (then it's installed). If not, install it. Don't do this in Octave 3.8 and higher!!

      b. If there's an asterisk on the java package line (then the package is loaded). If not, do a pkg rebuild-auto java Don't do this in Octave 3.8 and higher!!

    1. Check Java memory settings. Try javamem

      a. If it works, check if it reports sufficiently large max memory (had better be 200 MiB, the bigger the better)

      b. If it doesn't work, do:

        rt = java_invoke ('java.lang.Runtime', 'getRuntime')

        rt.gc

        rt.maxMemory ().doubleValue () / 1024 / 1024

        The last command will show MaxMemory in MiB.

      c. In case you have insufficient memory, see in GOTCHAS, Java memory pool allocation size, how to increase java's memory pre-reservation.

    2. Check if all classes (.jarfiles) are in class path. Do a 'jcp = javaclasspath (-all)'  (under unix/linux, do 'jcp = javaclasspath; strsplit (jcp,:)' (w/o quotes). See above under REQUIRED SUPPORT SOFTWARE what classes should be mentioned.

      If classes (.jar files) are missing, download and put them somewhere and add them to the javaclass path with their fully qualified pathname (in quotes) using javaaddpath().

    Once all classes are present and in the javaclasspath, the ods interfaces should just work. The only remaining showstoppers are insufficient write privileges for the working directory, a wrecked up octave or some other problems outside octave.

    1. Try opening an ods file:

      ods1 = odsopen ('test.ods', 1, 'otk'). If this works and ods1 is a struct with various fields containing objects, ODF toolkit interface (OTK) works. Do an ods1 = odsclose (ods1) to close the file.

      ods2 = odsopen ('test.ods', 1, 'jod'). If this works and ods2 is a struct with various fields containing objects, jOpenDocument interface (JOD) works as well. Do ods2 = odsclose (ods2) to close the file.

    2. For the UNO interface, at least version 1.2.8 of the Java package is needed plus the following Java class libs (jars) and directory:
      * unoil.jar (usually found in subdirectory Basis<version>/program/classes/ or the like of the OpenOffice.org (<OOo>) installation directory;
      * juh.jar, jurt.jar, unoloader.jar and ridl.jar, usually found in the subdirectory URE/share/java/ (or the like) of OOo's installation directory;
      * The subdirectory program/ (where soffice[.exe] (or ooffice) resides).
      The exact case (URE or ure, Basis or basis), name ("Basis3.2" or just "basis") and subdirectory tree (URE/java or URE/share/java) varies across OOo versions and -clones, so chk_spreadsheet_support.m can have a hard time finding all needed classes. In particularly bad cases, when chk_spreadsheet_support cannot find them, you might need to add one or more of these these classes manually to the javaclasspath.


    DEVELOPMENT

    As with the Excel r/w stuff, adding new interfaces should be easy and straightforward. Add relevant stanzas for your new interface INTF in odsopen, odsclose, odsfinfo, oct2ods, ods2oct, getusedrange and add new subfunctions (for the real work) in subdir ./private; you'll need a total of six interface-dependent private functions (see the various examples for each interface in subdir ./private).

    Suggestions for future development:

    • Speeding up (ODS is 10 X slower than e.g. OOXML !!!). jOpenDocument is much faster but still immature.
      For large spreadsheets, UNO *is* MUCH faster than jOpenDocument but starting up OpenOffice.org for the first time can take tens of seconds...
      Note that UNO is still experimental. The issue is that odsclose() will simply kill ALL other OpenOffice.org invocations, also those that were not opened through Octave! This is related to UNO-Java limitations.
      The underlying issue is that when Octave starts an OpenOffice.org invocation, OpenOffice.org must be closed for Octave to be able to exit; otherwise Octave will wait for OOo to shut down before it can terminate itself. So Octave must kill OOo to be able to terminate.
      A way out hasn't been found yet.

    • Passing function handle a la Matlab's xlsread

    • Adding styles (borders, cell lay-out, font, etc.)

    Some notes on the choice for Java (becoming less relevant as the OCT interface gets more mature):
    1. It saves a LOT of development time to use ready-baked Java classes rather than developing your own routines and thus effectively reinvent the wheel.
    2. A BIG advantage is that a Java-based solution is platform-independent (portable).
    3. The Java classes offer much more options than just reading and writing. Formatting, recalculation options, hiding/merging cell ranges, etc.
    4. But Java is known to be not very conservative with resources, especially not when processing XML-based formats.
    So Java is a compromise between portability and rapid development time versus capacity (and speed).
    But IMO data sets larger than 5.105 cells should not be kept in spreadsheets anyway. Use real databases for such data sets.

    ODFDOM versions

    I have tried various odfdom versions. As to 0.8 & 0.8.5, while the API has been simplified enormously (finally one can address cells by spreadsheet address rather than find out yourself by parsing the table-column/-row/-cell structure), many irrecoverable bugs have been introduced :-((
    In addition processing ODS files became significantly slower (up to 7 times!).

    End of August 2010 there's implemented support for odfdom-0.8.6.jar that version is at last sufficiently reliable to use. The few remaining bugs and limitations could easily be worked around by diving in the older TableTable API. Later on (early 2011) version 0.8.7 has been tested too - this needed a few adjustments. Early 2012 odfdom-0.8.8 (from odfdom-0.5-incubator) was accepted. In March 2015 odfdom-0.8.10 (odfdom-0.6.1-incubator) was tested but alas, it doesn't work (needs extraneous dependencies); clearly the odfdom API (currently at main version 0) is not stable yet.
    So at the moment (August 2012 = last I looked) only odfdom versions 0.7.5, 0.8.6, 0.8.7 and 0.8.8(-incubator) are supported. 0.7.5 is deprecated, however.

    If you want to experiment with odfdom 0.8 & 0.8.5, you can try:
    • odsopen.m (revision 7157)
    • ods2oct.m (revision 7158)
    • oct2ods.m (revision 7159)

    Enjoy!

    Philip Nienhuis, October 23, 2016