./PaxHeaders/io-2.7.00000644000000000000000000000013215004726004011263 xustar0030 mtime=1746119684.348811128 30 atime=1746119684.376810916 30 ctime=1746119684.376810916 io-2.7.0/0000755000175000017500000000000015004726004011521 5ustar00philipphilipio-2.7.0/PaxHeaders/io.sourceforge.octave.io.metainfo.xml0000644000000000000000000000006215004725440020352 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/io.sourceforge.octave.io.metainfo.xml0000644000175000017500000000226015004725440020666 0ustar00philipphilip io.sourceforge.octave.io org.octave.Octave IO File I/O in various formats

Provides functions for reading and writing various file formats, especially spreadsheets, and mixed-type csv-files.

file input/output file I/O spreadsheet .csv http://octave.sourceforge.net/io https://savannah.gnu.org/bugs/?func=additem&group=octave various Octave-Forge Community octave-maintainers@gnu.org FSFAP
io-2.7.0/PaxHeaders/inst0000644000000000000000000000013215004726004012103 xustar0030 mtime=1746119684.347811135 30 atime=1746119684.376810916 30 ctime=1746119684.376810916 io-2.7.0/inst/0000755000175000017500000000000015004726004012476 5ustar00philipphilipio-2.7.0/inst/PaxHeaders/__exit_io__.m0000644000000000000000000000006215004725440014577 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/__exit_io__.m0000644000175000017500000000405515004725440015117 0ustar00philipphilip## Copyright (C) 2016-2025 Carnë Draug ## Copyright (C) 2011-2025 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. ## ## Deregister Qt help files for GUI doc browser. ## Remove io java jars loaded by io package functions from javaclasspath. ## ## @end deftypefn ## PKG_DEL: __exit_io__ () function __exit_io__ () ## Package documentation ## On package unload, attempt to unload docs try pkg_dir = fileparts (fullfile (mfilename ("fullpath"))); doc_file = fullfile (pkg_dir, "doc", "io.qch"); doc_file = strrep (doc_file, '\', '/'); if exist(doc_file, "file") if exist("__event_manager_unregister_documentation__") __event_manager_unregister_documentation__ (doc_file); elseif exist("__event_manager_unregister_doc__") __event_manager_unregister_doc__ (doc_file); endif endif catch # do nothing end_try_catch ## Java spreadsheet I/O jars. ## 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 ## .. followed by clearing binary modules. clear -f cell2csv csv2cell col2num num2col csvconcat csvexplode endfunction io-2.7.0/inst/PaxHeaders/tidyxml.m0000644000000000000000000000006215004725440014035 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/tidyxml.m0000644000175000017500000000450015004725440014350 0ustar00philipphilip## Copyright (C) 2016-2025 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.7.0/inst/PaxHeaders/xlsopen.m0000644000000000000000000000006215004725440014033 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/xlsopen.m0000644000175000017500000004456315004725440014363 0ustar00philipphilip## Copyright (C) 2009-2025 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 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Octave; see the file COPYING. If not, see ## .7 ## -*- 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}) ## @deftypefnx {Function File} @var{xls} = xlsopen (@var{filename}, @var{readwrite}, @var{reqintf}, @var{verb}) ## Get a pointer to a spreadsheet in memory in the form of return argument ## (file pointer struct) @var{xls}. ## ## Calling xlsopen without specifying a return argument is fairly useless ## and considered an error! After processing the spreadsheet, the file ## pointer must be explicitly closed by calling xlsclose() to release possibly ## large amounts of RAM. ## ## @var{filename} should be a valid spreadsheet file name (including ## extension); see "help xlsread" for an overview of supported spreadsheet file ## formats. ## ## 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 ## spreadsheet I/O interface (see below) that otherwise would automatically ## be selected by xlsopen. In most situations this parameter is unneeded as ## xlsopen automatically selects the most useful interface present, depending ## on installed external support software and requested file type. A ## user-specified interface selection can be reset to default by entering ## a numeric value of -1. ## ## If a value of 1 or true is entered for @var{verb}, xlsopen returns info about ## the spreadsheet I/O interfaces that were found and/or are requested and ## active. The default value is false (no info on interfaces is shown). ## ## Spreadsheet I/O Interfaces ## ========================== ## xlsopen works with interfaces, which are links to support software, mostly ## external. @* ## The built-in 'OCT' interface needs no external software and allows ## I/O from/to OOXML (Excel 2007 and up), ODS 1.2 and Gnumeric. @* For all other ## spreadsheet formats, or if you want more speed and/or more flexibility, ## additional external software is required. See "help xlsread" for more info. @* ## Currently implemented interfaces to external SW are (in order of preference) ## 'COM' (Excel/COM), 'POI' (Java/Apache POI), 'JXL' (Java/JExcelAPI), 'OXS' ## (Java/OpenXLS), 'UNO' (Java/OpenOffice.org - EXPERIMENTAL!), 'OTK' ## (ODF Toolkit), 'JOD' (jOpendocument); see below: ## ## @table @asis ## @item xls and .xlsx: ## One or more of (1) 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, or (2 - Windows only) OF-windows package and ## MS-Excel. These interfaces are referred to as POI, JXL, OXS, UNO and COM, ## resp., and are preferred in that order by default (depending on presence of ## the pertinent support SW). Currently the OCT interface has the lowest ## priority. @* ## Excel'95 spreadsheets (BIFF5) can only be read using the JXL (JExcelAPI), ## UNO (Open-/LibreOffice), and COM (Excel-ActiveX) interfaces. ## ## @item .ods, .sxc: ## A Java JRE 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 presence of support SW). The OCT interface has ## lowest priority). @* ## The old OpenOffice.org .sxc format can be read using the UNO interface and ## older versions of the JOD interface. ## ## @item Other formats: ## By invoking the UNO interface one can read any format that the installed ## LibreOffice version supports; see below. The same goes (on Windows systems) ## for the COM interface (invoking MS-Excel). However, writing to other file ## formats than .xlsx, .ods and .xls is not implemented for COM. ## ## Depending on the installed LibreOffice release, in addition to .xls, .xlsx, ## .ods and .sxc, the following file formats may be read/written (untested!) ## when using the UNO interface. The pertinent import/export filters are ## inferred from the filename extension. ## ## @verbatim ## File format filename extension(s) ## ==================================== ===================== ## "Gnumeric" .gnumeric, .gnm ## "Text CSV" .csv ## "UOF spreadsheet" .uos ## "OpenDocument Spreadsheet Flat XML" .fods ## "dBase" .dbf ## "Digital Interchange Format" .dif ## "Lotus 1-2-3" .wk1 .wk2 .123 ## "WPS Lotus Calc" .wk3 .wk4 ## "MS Works Calc" .wks, .wdb ## "ClarisWorks Calc" .cwk ## "Mac Works Calc" .wps ## "Quattro Pro 6.0" .wb2 ## "WPS QPro Calc" .wb1 .wq1 .wq2 ## "Rich Text Format (StarCalc)" .rtf ## "SYLK" .slk .sylk ## "Apple Numbers" .numbers ## "Microsoft Multiplan" .mp ## @end verbatim ## @end table ## ## The utility function chk_spreadsheet_support.m can be useful to set the ## javaclasspath for the Java-based interfaces. ## ## Beware: 'zombie' Excel invocations may be left running invisibly in case ## of COM errors or after forgetting to close the file pointer. Similarly for ## LibreOffice, which may even prevent Octave from being closed (the reason ## the UNO interface is still experimental). ## ## 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, ## chk_spreadsheet_support} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-11-29 function [ xls ] = xlsopen (filename, xwrite=0, reqinterface=[], verbose=false) persistent interfaces; persistent chkintf; persistent lastintf; ## interfaces. = [] (not yet checked), ## 0 (found to be unsupported or unwanted), or ## 1 (checked and OK) ## Define preferred order of (default) file extensions for if no extension ## was specified persistent prefext = {".xls", ".xlsx", ".xlsm", ".ods", ".gnumeric", ... ".gnm", ".csv"}; if (isempty (chkintf) || (isnumeric (reqinterface) && reqinterface == -1)) ## Either not yet checked, or selection to be reset to default chkintf = 1; interfaces = struct ("COM", [], "JXL", [], "JOD", [], "OCT", 1, ... "OTK", [], "OXS", [], "POI", [], "UNO", []); if (isnumeric (reqinterface)) reqinterface = ""; endif endif if (isempty (lastintf)) lastintf = "---"; endif xlsintf_cnt = 1; ## Bit mask keeping track of detected/supported interfaces xlssupport = 0; ## Input checks if (nargout < 1) error (["xlsopen: no return argument specified!\n", ... "usage: XLS = xlsopen (Xlfile [, Rw] [, reqintf])\n"]); endif if (! (islogical (xwrite) || isnumeric (xwrite))) error (["xlsopen: numerical or logical value expected for arg ## 2 ", ... "(readwrite)\n"]); endif if (ischar (filename)) [pth, fnam, ext] = fileparts (filename); if (isempty (fnam)) error ("xlsopen: no filename or empty filename specified"); endif if (xwrite && ! isempty (pth)) apth = make_absolute_filename (pth); if (exist (apth) != 7) error ("xlsopen: cannot write into non-existent directory:\n'%s'\n", ... apth); endif endif else error ("xlsopen: filename expected for argument #1"); endif ## Check available interfaces if none was specified now or in earlier call if (! isempty (reqinterface)) intfmsg = "requested"; if (! (ischar (reqinterface) || iscell (reqinterface))) error (["xlsopen: arg. #3 (interface) not recognized - ", ... "character value required\n"]); endif ## Turn arg3 into cell array if needed if (! iscell (reqinterface)) reqinterface = {reqinterface}; endif reqinterface = cellfun (@upper, reqinterface, "uni", 0); ## Check if previously used interface matches a requested interface if (isempty (regexpi (reqinterface, lastintf, "once"){1}) || ... ! interfaces.(reqinterface{1})) ## New interface requested. Provisionally disable all interfaces interfaces.COM = 0; interfaces.JOD = 0; interfaces.JXL = 0; interfaces.OCT = 0; interfaces.OTK = 0; interfaces.OXS = 0; interfaces.POI = 0; interfaces.UNO = 0; for ii=1:numel (reqinterface) ## Try to invoke requested interface(s) for this call. Check if it ## is supported anyway by emptying the corresponding var. try interfaces.(reqinterface{ii}) = []; catch error (sprintf (["xlsopen: unknown interface \"%s\" requested.\n" "Only COM, JOD, JXL, OCT, OTK, OXS, POI or UNO) supported\n"], ... reqinterface{})); end_try_catch endfor if (verbose) printf ("\nChecking requested interface(s): "); endif interfaces = getinterfaces (interfaces, verbose); ## Well, is/are the requested interface(s) supported on the system? xlsintf_cnt = 0; for ii=1:numel (reqinterface) if (! interfaces.(toupper (reqinterface{ii}))) ## No it aint if (verbose) printf ("%s is not supported.\n", upper (reqinterface{ii})); endif 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 spreadsheet file exists. First check (supported) file name suffix: ## FIXME: invoke subfunct mtchext() rather than repeat below code several times ftype = 0; has_suffix = 1; [ftype, ~, ext] = __get_ftype__ (filename); if (! isempty (ext)) ext = lower (ext); else has_suffix = 0; endif ## Adapt file open mode for readwrite argument. ## 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 an existing file with a recognized file extension filnm = mtchext (filename, prefext); if (! isempty (filnm)) ## Simply choose the first one if (isstruct (filnm)) filename = filnm(1).name; else filename = filnm; endif endif endif endif ## Explore for filename in relevant rw mode. stat() can't see if file is locked 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 error error ( sprintf ("xlsopen: 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: 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 interfaces. No problem if they've already been ## checked, getinterfaces (far below) just returns immediately then. interfaces = getinterfaces (interfaces, verbose); ## If no external interface was detected and no suffix was given, use .xlsx if (! has_suffix && ! (interfaces.COM + interfaces.POI + ... interfaces.JXL + interfaces.OXS + ... interfaces.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 -> OTK -> JOD -> UNO -> OCT ## ftype (file type) is conveyed depending on interface capabilities if ((! xlssupport) && interfaces.COM && (ftype != 5)) ## Excel functioning has been tested above & file exists, so we just invoke it. if (verbose) printf (" Invoking COM ..."); endif [ xls, xlssupport, lastintf ] = __COM_spsh_open__ (xls, xwrite, filename, xlssupport); elseif ((! xlssupport) && ((interfaces.POI >= 2 && ftype <= 2) || ... (interfaces.POI == 1 && ftype == 1))) if (verbose) printf (" Invoking POI ..."); endif [ xls, xlssupport, lastintf ] = __POI_spsh_open__ (xls, xwrite, filename, xlssupport, ftype, interfaces); elseif ((! xlssupport) && interfaces.JXL && ftype == 1) if (verbose) printf (" Invoking JXL ..."); endif [ xls, xlssupport, lastintf ] = __JXL_spsh_open__ (xls, xwrite, filename, xlssupport, ftype); elseif ((! xlssupport) && interfaces.OXS && ftype == 1) if (verbose) printf (" Invoking OXS ..."); endif [ xls, xlssupport, lastintf ] = __OXS_spsh_open__ (xls, xwrite, filename, xlssupport, ftype); elseif (interfaces.OTK && ! xlssupport && ftype == 3) if (verbose) printf (" Invoking OTK ..."); endif [ xls, xlssupport, lastintf ] = ... __OTK_spsh_open__ (xls, xwrite, filename, xlssupport); elseif (interfaces.JOD && ! xlssupport && (ftype == 3 || ftype == 4)) if (verbose) printf (" Invoking JOD ..."); endif [ xls, xlssupport, lastintf ] = ... __JOD_spsh_open__ (xls, xwrite, filename, xlssupport); elseif ((! xlssupport) && interfaces.UNO && (ftype != 5)) if (verbose) printf (" Invoking UNO ..."); endif ## Part 1 of kludge to avoid lengthy delays while LO searches for printers ## during aLoader.loadComponentFromURL (..., "_blank", ...) call below, only ## req/d for .ods files unwind_protect if (ftype == 3) SDDP = getenv ("SAL_DISABLE_DEFAULTPRINTER"); setenv ("SAL_DISABLE_DEFAULTPRINTER", "1"); ## Proceed with the JAVA-UNO bridge stuff endif [ xls, xlssupport, lastintf ] = __UNO_spsh_open__ (xls, xwrite, filename, xlssupport); unwind_protect_cleanup ## Part 2: set env.var. to original value (or wipe it if it was empty) if (ftype == 3) setenv ("SAL_DISABLE_DEFAULTPRINTER", SDDP); endif end_unwind_protect elseif ((! xlssupport) && interfaces.OCT && ... (ftype == 2 || ftype == 3 || ftype == 5)) if (verbose) printf (" Invoking OCT ..."); endif [ xls, xlssupport, lastintf ] = __OCT_spsh_open__ (xls, xwrite, filename, xlssupport, ftype); endif ## Get Named Ranges, if any try xls.nmranges = getnmranges (xls); catch end_try_catch ## Rounding up. If none of the interfaces 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 getinterfaces() if (verbose) printf ("None.\n"); endif warning ("xlsopen: no'%s' spreadsheet I/O support with %s interfaces.\n", ... ext, intfmsg); endif else ## No match between file type & interface found warning ("xlsopen: file type not supported by %s %s %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 function fname = mtchext (fname, prefext) ## In case of multiple files with same name, pick the one with preferred ext. flist = {dir([fname ".*"]).name}; exts = cell2mat (cell2mat (regexpi (flist, '.*(\.\w+$)', "tokens"))); ## Get first matching file extension. ismember() arg order = vital! extm = find (ismember (prefext, exts)); if (! isempty (extm)) fname = flist(extm); else fname = [fname prefext{1}]; endif endfunction io-2.7.0/inst/PaxHeaders/unicode2utf8.m0000644000000000000000000000006215004725440014662 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/unicode2utf8.m0000644000175000017500000000347415004725440015206 0ustar00philipphilip## Copyright (C) 2016-2025 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}) ## Convert from Unicode code points @var{ustr} to UTF-8 encoded string @var{ostr}. ## ## It is not possible to convert Unicode characters with a codepoint higher ## than 255 because Octave's @code{char} type is 8-bit wide. This means that ## only the ISO 8859-1 (Latin-1) subset of Unicode can be mapped correctly. ## ## 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 endfunction io-2.7.0/inst/PaxHeaders/odsread.m0000644000000000000000000000006215004725440013764 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/odsread.m0000644000175000017500000000317115004725440014302 0ustar00philipphilip## Copyright (C) 2009-2025 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 from a spreadsheet file. ## ## For more info see the help for xlsread.m. ## ## odsread.m is deprecated. Currently it is a mere wrapper for xlsread.m. ## ## @seealso{xlsread} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-12-12 function [a, b, c, d, e] = odsread (varargin) [a, b, c, d, e] = xlsread (varargin{:}); endfunction io-2.7.0/inst/PaxHeaders/write_namelist.m0000644000000000000000000000006215004725440015371 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/write_namelist.m0000644000175000017500000000705115004725440015710 0ustar00philipphilip## Copyright (C) 2011-2025 Darien Pardinas Diaz ## Copyright (C) 2025 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{ret} = weite_namelist (@var{s}) ## ## WRITE_NAMELIST(S, FILENAME) writes a namelist data structure S to a ## file FILENAME. S should follow the following structure: ## ## @verbatim ## |--VAR1 ## |--VAR2 ## |-- NMLST_A--|... ## | |--VARNa ## | ## | |--VAR1 ## |-- NMLST_B--|--VAR2 ## | |... ## S --| ... |--VARNb ## | ## | |--VAR1 ## |-- NMLST_M--|--VAR2 ## |... ## |--VARNm ## @end verbatim ## ## 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"); ## ## @end deftypefn ## 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.7.0/inst/PaxHeaders/ods2oct.m0000644000000000000000000000006215004725440013720 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/ods2oct.m0000644000175000017500000000307015004725440014234 0ustar00philipphilip## Copyright (C) 2009-2025 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 from a spreadsheet file pointed to in file pointer struct @var{ods}. ## ## For more info see the help for xls2oct.m. ## ## ods2oct.m is deprecated. Currently it is a mere wrapper for xls2oct.m ## ## @seealso{xls2oct} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-12-13 function [a, b, c] = ods2oct (varargin) [a, b, c] = xls2oct (varargin{:}); endfunction io-2.7.0/inst/PaxHeaders/odsclose.m0000644000000000000000000000006215004725440014156 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/odsclose.m0000644000175000017500000000245515004725440014500 0ustar00philipphilip## Copyright (C) 2009-2025 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 a spreadsheet file pointer and if needed write the contents to disk. ## ## For more info see the help for xlsclose.m. ## ## odsclose.m is deprecated. Currently it is a mere wrapper for xlsclose.m ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-12-13 function [ ods ] = odsclose (varargin) ods = xlsclose (varargin{:}); endfunction io-2.7.0/inst/PaxHeaders/parsecell.m0000644000000000000000000000006215004725440014315 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/parsecell.m0000644000175000017500000001341415004725440014634 0ustar00philipphilip## Copyright (C) 2009-2025 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 fields 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 ("parsecell: 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 placeholder 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.7.0/inst/PaxHeaders/pch2mat.m0000644000000000000000000000006215004725440013701 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/pch2mat.m0000644000175000017500000001022015004725440014210 0ustar00philipphilip## Copyright (C) 2011-2025 Bilen Oytun Peksel ## Copyright (C) 2025 Philip Nienhuis ## 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. E.g. 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.7.0/inst/PaxHeaders/calccelladdress.m0000644000000000000000000000006215004725440015453 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/calccelladdress.m0000644000175000017500000000423715004725440015775 0ustar00philipphilip## Copyright (C) 2009-2025 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{celladdr} = calccelladdress (@var{row}, @var{column}) ## ## calccelladdress (row, column) - 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. ## ## @end deftypefn ## 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 ("calccelladdress: specified column out of range (1..18278)"); endif if (row > 1048576 || row < 1) error ("calccelladdress: 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.7.0/inst/PaxHeaders/private0000644000000000000000000000013215004726004013555 xustar0030 mtime=1746119684.331811256 30 atime=1746119684.376810916 30 ctime=1746119684.376810916 io-2.7.0/inst/private/0000755000175000017500000000000015004726004014150 5ustar00philipphilipio-2.7.0/inst/private/PaxHeaders/__POI_spsh_close__.m0000644000000000000000000000006215004725440017462 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__POI_spsh_close__.m0000644000175000017500000000276515004725440020010 0ustar00philipphilip## Copyright (C) 2012-2025 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.7.0/inst/private/PaxHeaders/__JXL_spsh_close__.m0000644000000000000000000000006215004725440017470 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__JXL_spsh_close__.m0000644000175000017500000000253215004725440020006 0ustar00philipphilip## Copyright (C) 2012-2025 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_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.7.0/inst/private/PaxHeaders/__OCT_oct2spsh__.m0000644000000000000000000000006215004725440017063 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__OCT_oct2spsh__.m0000644000175000017500000000454015004725440017402 0ustar00philipphilip## Copyright (C) 2014-2025 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 ("oct2xls: writing to file type %s not supported by OCT", xls.app); endif endfunction io-2.7.0/inst/private/PaxHeaders/__OTK_getnmranges__.m0000644000000000000000000000006215004725440017640 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__OTK_getnmranges__.m0000644000175000017500000000205415004725440020155 0ustar00philipphilip## Copyright (C) 2015-2025 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.7.0/inst/private/PaxHeaders/__POI_spsh_info__.m0000644000000000000000000000006215004725440017310 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__POI_spsh_info__.m0000644000175000017500000000262315004725440017627 0ustar00philipphilip## Copyright (C) 2012-2025 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) 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.7.0/inst/private/PaxHeaders/__OCT_getnmranges__.m0000644000000000000000000000006215004725440017630 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__OCT_getnmranges__.m0000644000175000017500000000245515004725440020152 0ustar00philipphilip## Copyright (C) 2015-2025 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.7.0/inst/private/PaxHeaders/__JOD_oct2spsh__.m0000644000000000000000000000006215004725440017052 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__JOD_oct2spsh__.m0000644000175000017500000001336715004725440017400 0ustar00philipphilip## Copyright (C) 2009-2025 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 ("oct2xls: sheet number out of range of ODS specification (>1024)"); elseif (wsh > sh_cnt) error ("oct2xls: 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 (["oct2xls: 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 ("oct2xls: 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 ("oct2xls: 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.7.0/inst/private/PaxHeaders/__OXS_spsh_info__.m0000644000000000000000000000006215004725440017332 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__OXS_spsh_info__.m0000644000175000017500000000266015004725440017652 0ustar00philipphilip## Copyright (C) 2013-2025 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.7.0/inst/private/PaxHeaders/__OTK_spsh_open__.m0000644000000000000000000000006215004725440017324 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__OTK_spsh_open__.m0000644000175000017500000000417615004725440017650 0ustar00philipphilip## Copyright (C) 2012-2025 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 ("xlsopen: couldn't open file %s using OTK", filename); lastintf = ""; end_try_catch endfunction io-2.7.0/inst/private/PaxHeaders/__JXL_chk_sprt__.m0000644000000000000000000000006215004725440017143 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__JXL_chk_sprt__.m0000644000175000017500000000267515004725440017471 0ustar00philipphilip## Copyright (C) 2014-2025 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.7.0/inst/private/PaxHeaders/__get_ftype__.m0000644000000000000000000000006215004725440016577 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__get_ftype__.m0000644000175000017500000001104415004725440017113 0ustar00philipphilip## Copyright (C) 2014-2025 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. ## ## @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, ext] = __get_ftype__ (fname) persistent filtnams; filtnams = {"MS Excel 97", ## 1 .xls "Calc MS Excel 2007 XML", ## 2 .xlsx "calc8", ## 3 .ods "StarOffice XML (Calc)", ## 4 .sxc "Gnumeric Spreadsheet", ## 5 .gnumeric, .gnm "Text CSV", ## 6 .csv "UOF spreadsheet", ## 7 .uos "OpenDocument Spreadsheet Flat XML", ## 8 .fods "dBase", ## 9 .dbf "DIF", ## 10 .dif "Lotus", ## 11 .wk1 .wk2 .123 "WPS_Lotus_Calc", ## 12 .wk3 .wk4 "MS_Works_Calc", ## 12 .wks, .wdb "ClarisWorks_Calc", ## 14.cwk "Mac_Works_Calc", ## 15 .wps "Quattro Pro 6.0", ## 16 .wb2 "WPS_QPro_Calc", ## 17 .wb1 .wq1 .wq2 "Rich Text Format (StarCalc)", ## 18 .rtf "SYLK", ## 19 .slk .sylk "Apple Numbers", ## 20 .numbers "Microsoft Multiplan"}; ## 21 .mp [~, ~, ext] = fileparts (fname); if (! isempty (ext)) switch lower (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", ".gnm"} ## 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; case {".wk1", ".wk2", ".123"} ## Lotus ftype = 11; case {".wk3", ".wk4"} ## WPS_Lotus_Calc ftype = 12; case {".wks", ".wdb"} ## MS_Works_Calc ftype = 13; case ".cwk" ## ClarisWorks_Calc ftype = 14; case ".wps" ## Mac_Works_Calc ftype = 15; case ".wb2" ## Quattro Pro 6.0 ftype = 16; case {".wb1", ".wq1", ".wq2"} ## WPS_QPro_Calc ftype = 17; case ".rtf" ## Rich Text Format (StarCalc) ftype = 18; case {".slk", ".sylk"} ## SYLK ftype = 19; case ".numbers" ## Apple Numbers ftype = 20; case ".mp" ## Microsoft Multiplan ftype = 21; otherwise ## Any other type = non-supported ftype = 0; endswitch else ftype = ""; endif if (ftype > 0) filtnam = filtnams{ftype}; else filtnam = ""; endif endfunction io-2.7.0/inst/private/PaxHeaders/__OCT_gnm2oct__.m0000644000000000000000000000006215004725440016667 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__OCT_gnm2oct__.m0000644000175000017500000001312615004725440017206 0ustar00philipphilip## Copyright (C) 2013-2025 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.7.0/inst/private/PaxHeaders/__COM_getusedrange__.m0000644000000000000000000000006215004725440017764 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__COM_getusedrange__.m0000644000175000017500000000332615004725440020304 0ustar00philipphilip## Copyright (C) 2010-2025 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.7.0/inst/private/PaxHeaders/__JOD_spsh2oct__.m0000644000000000000000000000006215004725440017052 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__JOD_spsh2oct__.m0000644000175000017500000002026215004725440017370 0ustar00philipphilip## Copyright (C) 2009-2025 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 (strfind (char (scell), ". ## -*- 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.7.0/inst/private/PaxHeaders/__XMLrw_chk_sprt__.m0000644000000000000000000000006215004725440017517 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__XMLrw_chk_sprt__.m0000644000175000017500000000327615004725440020043 0ustar00philipphilip## Copyright (C) 2015-2025 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.7.0/inst/private/PaxHeaders/__JXL_spsh_info__.m0000644000000000000000000000006215004725440017316 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__JXL_spsh_info__.m0000644000175000017500000000254015004725440017633 0ustar00philipphilip## Copyright (C) 2012-2025 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.7.0/inst/private/PaxHeaders/__UNO_oct2spsh__.m0000644000000000000000000000006215004725440017077 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__UNO_oct2spsh__.m0000644000175000017500000001351515004725440017420 0ustar00philipphilip## Copyright (C) 2011-2025 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 ("oct2xls: 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 ("oct2xls: couldn't 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 ("oct2xls: 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), 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 ("oct2xls: 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.7.0/inst/private/PaxHeaders/__POI_spsh2oct__.m0000644000000000000000000000006215004725440017065 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__POI_spsh2oct__.m0000644000175000017500000001775315004725440017416 0ustar00philipphilip## Copyright (C) 2009-2025 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 poiv4 p4ctype; if (isempty (ctype)) ## Get enumerated cell types. Beware as they start at 0 not 1 try ## POI < 4 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_BOOLEAN"); ctype(3) = __java_get__ ("org.apache.poi.ss.usermodel.Cell", "CELL_TYPE_STRING"); ctype(4) = __java_get__ ("org.apache.poi.ss.usermodel.Cell", "CELL_TYPE_FORMULA"); ctype(5) = __java_get__ ("org.apache.poi.ss.usermodel.Cell", "CELL_TYPE_BLANK"); poiv4 = false; catch ## POI >= 4 p4ctype.enum = __java_get__ ("org.apache.poi.ss.usermodel.CellType", "NUMERIC"); ctype(1) = p4ctype.enum.ordinal; p4ctype.name = "numeric"; p4ctype(2).enum = __java_get__ ("org.apache.poi.ss.usermodel.CellType", "BOOLEAN"); ctype(2) = p4ctype(2).enum.ordinal; p4ctype(2).name = "boolean"; p4ctype(3).enum = __java_get__ ("org.apache.poi.ss.usermodel.CellType", "STRING"); ctype(3) = p4ctype(3).enum.ordinal; p4ctype(3).name = "string"; p4ctype(4).enum = __java_get__ ("org.apache.poi.ss.usermodel.CellType", "FORMULA"); ctype(4) = p4ctype(4).enum.ordinal; p4ctype(4).name = "formula"; p4ctype(5).enum = __java_get__ ("org.apache.poi.ss.usermodel.CellType", "BLANK"); ctype(5) = p4ctype(5).enum.ordinal; p4ctype(5).name = "blank"; poiv4 = true; end_try_catch 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 ("xls2oct: 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 ("xls2oct: 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 (poiv4) type_of_cell = type_of_cell.ordinal (); endif if (type_of_cell == ctype(4)) ## 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(); if (poiv4) type_of_cell = type_of_cell.ordinal (); endif ## 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) ## 1 Numeric rawarr {ii+1-firstrow, jj+1-lcol} = scell.getNumericCellValue (); case ctype(2) ## 2 Boolean rawarr {ii+1-firstrow, jj+1-lcol} = scell.getBooleanCellValue (); case ctype(3) ## 3 String rawarr {ii+1-firstrow, jj+1-lcol} = ... char (scell.getRichStringCellValue ()); case ctype(4) if (spsh_opts.formulas_as_text) tmp = char (scell.getCellFormula ()); rawarr {ii+1-firstrow, jj+1-lcol} = ["=" tmp]; endif case ctype(5) ## 4 Blank ## Blank; ignore until further notice otherwise ## 5 Error ## Ignore endswitch endif endfor endif endfor if (jerror > 0) warning (sprintf ("xls2oct: %d cached values instead of formula evaluations read.\n",... jerror)); endif rstatus = 1; xls.limits = [lcol, rcol; firstrow, lastrow]; endfunction io-2.7.0/inst/private/PaxHeaders/__OTK_getusedrange__.m0000644000000000000000000000006215004725440020003 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__OTK_getusedrange__.m0000644000175000017500000000744315004725440020327 0ustar00philipphilip## Copyright (C) 2010-2025 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 (strfind (rw_char, "office:value-type") || strfind (rw_char, " attribute when writing strings ##if (isempty (strfind (cl_char, "office:value-type")) ... ## || isempty (strfind (cl_char, ". ## -*- 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, force="") 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 ## This doesn't seem to work well since v. 6.2.0 ...: [mvst, msg] = movefile (["." filesep fname ".zip"], filename, "f"); if (! mvst) ## ... but removing ".\" (or ("./") seems to work: [mvst, msg] = movefile ([fname ".zip"], filename, "f"); endif if (! mvst) ## Still no luck 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 or move files in %s to %s\n\n", ... fcn, xls.workbook, filename); warning (err.message) 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 ## If we get here, all is done for .gnumeric cd (opwd); return endif ## Delete tmp file and return to work dir cd (opwd); if (! xls.changed || ! isempty (force)) ## Below is needed for a silent delete of our tmpdir confirm_recursive_rmdir (0, "local"); rmdir (xls.workbook, "s"); endif endfunction io-2.7.0/inst/private/PaxHeaders/__JXL_spsh_open__.m0000644000000000000000000000006215004725440017324 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__JXL_spsh_open__.m0000644000175000017500000000337015004725440017643 0ustar00philipphilip## Copyright (C) 2012-2025 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 lastintf = ""; end_try_catch endfunction io-2.7.0/inst/private/PaxHeaders/__UNO_getusedrange__.m0000644000000000000000000000006215004725440020007 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__UNO_getusedrange__.m0000644000175000017500000000437515004725440020334 0ustar00philipphilip## Copyright (C) 2011-2025 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 adrblks = cell2mat (regexp (addrs, '.*?([A-Z]+\d+:[A-Z]+\d+|[A-Z]+\d+)', "tokens")); nblks = numel (adrblks); ## 2. First try with "," separator... 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) [dummy, nrows, ncols, trow, lcol] = parse_sp_range (adrblks{ii}); 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.7.0/inst/private/PaxHeaders/__OXS_chk_sprt__.m0000644000000000000000000000006215004725440017157 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__OXS_chk_sprt__.m0000644000175000017500000000402515004725440017474 0ustar00philipphilip## Copyright (C) 2014-2025 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.7.0/inst/private/PaxHeaders/__OCT_oct2xlsx__.m0000644000000000000000000000006215004725440017104 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__OCT_oct2xlsx__.m0000644000175000017500000005441515004725440017431 0ustar00philipphilip## Copyright (C) 2013-2025 Markus Bergholz ## Parts Copyright (C) 2014-2025 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, 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 ("oct2xls: 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; xls.sheets.sh_names(end+1) = wsh; wsh_number = numel (xls.sheets.sh_names); ## Update shId & get proper new worksheet number that fits in shId category wid = find (xls.sheets.type == 1); xls.sheets.type = [ xls.sheets.type 1 ]; xls.sheets.shId = [xls.sheets.shId (max (xls.sheets.shId(wid)) + 1) ]; ## -1? endif wsh_string = wsh; wsh = wsh_number; wsh_number = xls.sheets.shId(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 ## Make wsh internally now the newest/next higher sheet number, not any no. wsh = numel (xls.sheets.sh_names) + 1; xls.sheets.sh_names(end+1) = wsh_string; ## Update shId & get proper new worksheet number that fits in shId category wid = find (xls.sheets.type == 1); xls.sheets.type = [ xls.sheets.type 1 ]; xls.sheets.shId = [xls.sheets.shId (max (xls.sheets.shId(wid)) + 1) ]; else if (xls.sheets.type(wsh) != 1) warning ("oct2xls: sheet %d is not a worksheet\n", wsh); return endif endif ## Make sure wsh_number refers to a worksheet, not any sheet wsh_number = xls.sheets.shId(wsh); endif if (new_sh) rawarr = {}; lims = []; else ## Get all data in sheet and row/column limits. If wsh is numeric, ## __OCT_xlsx2oct__ will turn it into a valid worksheet no. o_spsh_opts = spsh_opts; spsh_opts.formulas_as_text = true; [rawarr, xls] = __OCT_xlsx2oct__ (xls, wsh, "", spsh_opts); spsh_opts = o_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) >= nwrId) ## 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) == nwrId) ## Insert new node with nwrId and higher *work*sheet no. entry = sprintf ('', nwrId, wsh_number); 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, wsh_number); ## Find last worksheet node & insert new node srchstr = 'worksheet+xml"/>'; [~, ipos] = regexp (txml, '(worksheet\+xml".*?/>)'); ipos = ipos(end) + 1; # 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+"); if (aid > 0) ## Apparently a docProps/ subdir in .xlsx file. Isn't always written by Excel 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); ## === End of docProps/app.xml & axml === endif else ## when writing data to existing worksheets, MS-Excel might complain about ## xl/calcChain.xml. As MS-Excel will regenerate it and only MS-Excel ever ## uses it, the easiest thing is to just delete the file from the archive. try unlink ([xls.workbook filesep "xl" filesep "calcChain.xml"]); catch end_try_catch endif ## 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+"); if (cid > 0) ## Apparently a docProps/ subdir in .xlsx file. Isn't always written by Excel 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 === endif ## 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.7.0/inst/private/PaxHeaders/getusedrange.m0000644000000000000000000000006215004725440016472 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/getusedrange.m0000644000175000017500000000716615004725440017020 0ustar00philipphilip## Copyright (C) 2010-2025 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 ("getusedrange: 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 ... ("getusedrange: unknown interface - only OTK, JOD, COM, POI, JXL, OXS, UNO and OCT implemented"); endif endfunction io-2.7.0/inst/private/PaxHeaders/__OCT_ods_getnmranges__.m0000644000000000000000000000006215004725440020475 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__OCT_ods_getnmranges__.m0000644000175000017500000000432115004725440021011 0ustar00philipphilip## Copyright (C) 2015-2025 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"); xml = fread (fid, Inf, "char=>char").'; fclose (fid); rxml = getxmlnode (xml, "table:database-ranges", 1, 1); fmt = 'table:named-range table:name="(.*?)" .*?range-address="(.*?)"'; if (! isempty (rxml)) ## Older ODS version 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 elseif (! isempty (rxml = cell2mat (regexp (xml, fmt, "tokens")))) ## Newer ODS version rxml = reshape (rxml, 2, [])'; rxml(:, 2) = cellfun (@(x) strrep (x, "$", ""), rxml(:, 2), "uni", 0); rxml(:, 2) = cellfun (@(x) strrep (x, ":.", ":"), rxml(:, 2), "uni", 0); nmr = cell (size (rxml, 1), 3); nmr(:, 1) = rxml(:, 1); for ii=1:size (rxml, 1) nmr(ii, 2:3) = strsplit (rxml{ii, 2}, '.'); endfor else nmr = cell (0, 3); return endif endfunction io-2.7.0/inst/private/PaxHeaders/__COM_oct2spsh__.m0000644000000000000000000000006215004725440017054 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__COM_oct2spsh__.m0000644000175000017500000002172415004725440017376 0ustar00philipphilip## Copyright (C) 2009-2025 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 ("oct2xls: COM interface can only write to Excel .xls or .xlsx files\n") endif if (isnumeric (wsh)) if (wsh < 1) error ("oct2xls: illegal worksheet number: %i\n", wsh); endif elseif (size (wsh, 2) > 31) error ("oct2xls: illegal worksheet name - too long\n") endif ## Check to see if ActiveX is still alive try wb_cnt = xls.workbook.Worksheets.count; catch error ("oct2xls: ActiveX invocation in file ptr struct seems non-functional\n"); end_try_catch ## define some constants not yet in __COM__.cc xlWorksheet = -4167; ## xlChart= 3 or 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 ("oct2xls: 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 = [1 2 3 4 5]; ## Numeric Boolean Text Formula Empty typearr = spsh_prstype (obj, nrows, ncols, ctype, spsh_opts); ## Make cells now indicated to be empty, empty fptr = ! (5 * (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 ... ("oct2xls: > 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 ("oct2xls: existing sheet '%s' is not type worksheet.\n", wsh)); else ## Simply point to the relevant sheet sh = xls.workbook.Sheets (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 ("oct2xls: can't 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.Sheets.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.Sheets(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.Sheets(ii).Move (before = xls.workbook.Sheets(ws_cnt)); ## ....then move the last one before the new sheet. xls.workbook.Sheets (ws_cnt).Move (before = xls.workbook.Sheets(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.Sheets(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 if (spsh_opts.convert_utf) ... && (compare_versions (ver ("windows").Version, "1.5.0", "<=")) ## The COM interface in of-windows until version 1.5.0 expected strings ## that were encoded in the system locale. Not all Unicode characters can ## be encoded in a non-Unicode locale. Try to convert as much as possible. if (isempty (which ("unicode2native"))) ## Not available before Octave 4.4 ## Use fallback function. (Assumes the locale is ISO 8859-1.) conv_fcn = @utf82unicode; else if (isempty (which ("__locale_charset__"))) ## Not available before Octave 6 ## Assume ISO 8859-1 enc = "iso8859-1"; else enc = __locale_charset__ (); endif conv_fcn = @(str) char (unicode2native (str, enc)); endif obj = cellfun (conv_fcn, obj, "uniformoutput", false); 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 ("oct2xls: can't 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.7.0/inst/private/PaxHeaders/__JXL_getnmranges__.m0000644000000000000000000000006215004725440017640 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__JXL_getnmranges__.m0000644000175000017500000000205115004725440020152 0ustar00philipphilip## Copyright (C) 2015-2025 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.7.0/inst/private/PaxHeaders/__OTK_ods2oct__.m0000644000000000000000000000006215004725440016703 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__OTK_ods2oct__.m0000644000175000017500000002006315004725440017220 0ustar00philipphilip## Copyright (C) 2009-2025 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 = strfind (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.7.0/inst/private/PaxHeaders/__POI_chk_sprt__.m0000644000000000000000000000006215004725440017135 xustar0020 atime=1746119456 30 ctime=1746119684.376810916 io-2.7.0/inst/private/__POI_chk_sprt__.m0000644000175000017500000001171515004725440017456 0ustar00philipphilip## Copyright (C) 2014-2025 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 as each POI version needs additional jars entries1 = {{"apache-poi.", "poi-3", "poi-4", "poi-5"}, ... {"apache-poi-ooxml.", "poi-ooxml-3", "poi-ooxml-4", "poi-ooxml-5"}, ... "commons-math"}; ## 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, missing] = chk_jar_entries (jcp, entries1, dbug); missing1 = entries1 (find (missing)); try ## POI >= 4.0 needs another jar here poiv = javaObject ("org.apache.poi.Version").getVersion(); if (compare_versions (poiv, "4.0.0", "<")) ic = find (cellfun ("ischar", missing1)); id = find (strncmpi ("commons-math", missing1(ic), 1)); missing1(ic(id)) = []; jpchk1++; if (dbug > 1) printf (" commons-math not needed for POI <= 5.0\n"); endif endif end_try_catch 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) /< commons...>:\n"); endif ## Each next POI version needs more jars, so order below is vital entries2 = {{"xbean", "xmlbean"}, {"apache-poi-ooxml-schemas", ... "poi-ooxml-schemas", "poi-ooxml-lite"}, "commons-collections", ... "commons-compress", "commons-io", "log4j"}; [jpchk2, missing] = chk_jar_entries (jcp, entries2, dbug); missing2 = entries2 (find (missing)); ## 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(); ## Stuff required only for POI-3.15+ if (compare_versions (poiv, "3.14", "<=")) ## Remove commons-collections from missing2 ic = find (cellfun (@ischar, missing2)); id = find (strncmpi ("commons-collections", missing2(ic), 19)); missing2(ic(id)) = []; jpchk2++; if (dbug > 2) printf (" commons-collections4 not needed for POI <= 3.14\n"); endif endif ## Stuff required only for POI-4 and up if (compare_versions (poiv, "4.0", "<") && ... any (strncmpi (missing2, "commons-compress", 16))) ## Remove commons-compress from missing2 ic = find (cellfun (@ischar, missing2)); id = find (strncmpi ("commons-compress", missing2(ic), 16)); missing2(ic(id)) = []; jpchk2++; if (dbug > 2) printf (" commons-compress not needed for POI <= 4.0\n"); endif endif ## Stuff needed only for POI-5.1+ if (compare_versions (poiv, "5.1", "<") && ... any (strncmpi (missing2(:), "commons-io", 16))) ## Remove commons-io from missing2 ic = find (cellfun (@ischar, missing2)); id = find (strncmpi ("commons-io", missing2(ic), 16)); missing2(ic(id)) = []; jpchk2++; if (dbug > 2) printf (" commons-io not needed for POI <= 5.0\n"); endif ## Remove log4j from missing2 ic = find (cellfun (@ischar, missing2)); id = find (strncmpi ("log4j", missing2(ic), 5)); missing2(ic(id)) = []; jpchk2++; if (dbug > 2) printf (" log4j not needed for POI <= 5.0\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.7.0/inst/private/PaxHeaders/__UNO_chk_sprt__.m0000644000000000000000000000006215004725440017147 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__UNO_chk_sprt__.m0000644000175000017500000000314115004725440017462 0ustar00philipphilip## Copyright (C) 2014-2025 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.7.0/inst/private/PaxHeaders/__JOD_getnmranges__.m0000644000000000000000000000006215004725440017617 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__JOD_getnmranges__.m0000644000175000017500000000270415004725440020136 0ustar00philipphilip## Copyright (C) 2017-2025 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) try ## Works only in jOpenDocument 1.5+ nmrs = ods.workbook.getRangesNames (); nnmr = nmrs.size (); anmr = nmrs.toArray (); nmr = cell (nnmr, 3); for inmr=1 : nnmr rg = ods.workbook.getRange (anmr(inmr)).toString (); rg = strsplit (rg,"."); nmr{inmr, 3} = [rg{2:3}]; nmr{inmr, 2} = rg{1}; nmr{inmr, 1} = anmr(inmr); endfor catch ## Just a stub. Named ranges do not work in earlier jOpenDocument nmr = cell (0, 3); end_try_catch endfunction io-2.7.0/inst/private/PaxHeaders/__OXS_getusedrange__.m0000644000000000000000000000006215004725440020017 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OXS_getusedrange__.m0000644000175000017500000000243615004725440020340 0ustar00philipphilip## Copyright (C) 2010-2025 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.7.0/inst/private/PaxHeaders/__OCT_xlsx_getnmranges__.m0000644000000000000000000000006215004725440020706 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OCT_xlsx_getnmranges__.m0000644000175000017500000000343115004725440021223 0ustar00philipphilip## Copyright (C) 2015-2025 Andreas Weber ## Copyright (C) 2015-2025 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.7.0/inst/private/PaxHeaders/chk_jar_entries.m0000644000000000000000000000006215004725440017147 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/chk_jar_entries.m0000644000175000017500000000470615004725440017472 0ustar00philipphilip## Copyright (C) 2012-2025 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.7.0/inst/private/PaxHeaders/__UNO_spsh_info__.m0000644000000000000000000000006215004725440017322 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__UNO_spsh_info__.m0000644000175000017500000000250615004725440017641 0ustar00philipphilip## Copyright (C) 2012-2025 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.7.0/inst/private/PaxHeaders/__OTK_spsh2oct__.m0000644000000000000000000000006215004725440017073 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OTK_spsh2oct__.m0000644000175000017500000001336315004725440017415 0ustar00philipphilip## Copyright (C) 2010-2025 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_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 if (brow - trow == 0 || rcol - lcol == 0) rawarr = {}; return endif 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" rawarr(ii-trow+1, jj-lcol+1) = ocell.getDoubleValue (); case "currency" rawarr(ii-trow+1, jj-lcol+1) = ocell.getCurrencyValue (); case "percentage" rawarr(ii-trow+1, jj-lcol+1) = ocell.getPercentageValue (); 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.7.0/inst/private/PaxHeaders/__UNO_spsh_close__.m0000644000000000000000000000006215004725440017474 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__UNO_spsh_close__.m0000644000175000017500000001126015004725440020010 0ustar00philipphilip## Copyright (C) 2012-2025 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 ("xlsclose: error closing xls pointer (UNO)"); endif return end_try_catch endfunction io-2.7.0/inst/private/PaxHeaders/spsh_prstype.m0000644000000000000000000000006215004725440016560 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/spsh_prstype.m0000644000175000017500000000703215004725440017076 0ustar00philipphilip## Copyright (C) 2010-2025 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) = 3; ; ## Save strings in a safe place emptr = cellfun ("isempty", obj); obj(emptr) = 5; ## Set empty cells to EMPTY lptr = cellfun ("islogical" , obj); ## Find logicals... obj2(lptr) = obj(lptr); ## .. and set them to BOOLEAN ptr = ! cellfun ("isfinite", obj); ## Find NaNs,Infs & set to BLANK typearr(ptr) = 5; ## FIXME: do we need isfinite ()? typearr(! ptr) = 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) = 3; ## ...and clean up typearr(emptr) = 5; ## EMPTY typearr(lptr) = 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) = 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.7.0/inst/private/PaxHeaders/__POI_spsh_open__.m0000644000000000000000000000006215004725440017316 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__POI_spsh_open__.m0000644000175000017500000000375715004725440017646 0ustar00philipphilip## Copyright (C) 2012-2025 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 else xlsin = javaObject ("java.io.FileInputStream", filename); wb = javaMethod ("create", ... "org.apache.poi.ss.usermodel.WorkbookFactory",... xlsin); xlsin.close (); endif xls.app = "POI"; 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 lastintf = ""; end_try_catch endfunction io-2.7.0/inst/private/PaxHeaders/__OTK_spsh_close__.m0000644000000000000000000000006215004725440017470 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OTK_spsh_close__.m0000644000175000017500000000237215004725440020010 0ustar00philipphilip## Copyright (C) 2012-2025 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.7.0/inst/private/PaxHeaders/__chk_java_sprt__.m0000644000000000000000000000006215004725440017427 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__chk_java_sprt__.m0000644000175000017500000000460515004725440017750 0ustar00philipphilip## Copyright (C) 2013-2025 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; if (! isempty (javachk ("jvm"))) ## No Java support built in => any further checks are moot return endif try jcp = javaclasspath ("-all"); ## 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, "."); ## Before Java 9 the numbering scheme is "1.ver.x_y". ## For Java 9 it is "ver.x.y". ## For Java 10 and 11 it is just "ver". java_ver = []; if (numel (cjver) > 1 && (sscanf (cjver{1}, "%d") == 1)) java_ver = sscanf (cjver{2}, "%d"); elseif (! isempty (cjver)) java_ver = sscanf (cjver{1}, "%d"); endif if (isempty (java_ver) || java_ver < 6) warning (["Java version too old (%s). ", ... "You need at least Java 6 (v. 1.6.x.x).\n"], jver); 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. 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.7.0/inst/private/PaxHeaders/getinterfaces.m0000644000000000000000000000006215004725440016640 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/getinterfaces.m0000644000175000017500000001763515004725440017170 0ustar00philipphilip## Copyright (C) 2009-2025 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 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## @deftypefn {Function File} @var{interfaces} = getinterfaces (@var{interfaces}) ## 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{interfaces} it is possible to specify which ## interface(s) should be checked. ## ## Currently implemented interfaces comprise: ## - ActiveX / COM (native Excel in the background) ## - Java & JExcelAPI (.xls) ## - Java & jOpendocument (.ods, .sxc) ## - Java & ODFtoolkit (.ods) ## - Java & OpenXLS (only JRE >= 1.4 needed) (.xls) ## - Java & Apache POI (.xls, .xlsx) ## - Java & UNO bridge (native OpenOffice.org in background) - EXPERIMENTAL!! ## - native Octave, only for .xlsx (OOXML), .ODS1.2, . gnumeric ## ## Examples: ## ## @example ## interfaces = getinterfaces (interfaces); ## @end example ## Author: Philip Nienhuis ## Created: 2009-11-29 function [interfaces] = getinterfaces (interfaces, verbose=true) ## 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 (interfaces.COM) && isempty (interfaces.JXL) ... && isempty (interfaces.JOD) && isempty (interfaces.POI) ... && isempty (interfaces.OTK) && isempty (interfaces.OXS) ... && isempty (interfaces.UNO)) ## Looks like first call to xlsopen. Check Java support if (verbose) printf ("Detected interfaces: "); endif tmp1 = []; elseif (isempty (interfaces.COM) || isempty (interfaces.JXL) ... || isempty (interfaces.JOD) || isempty (interfaces.POI) ... || isempty (interfaces.OTK) || isempty (interfaces.OXS) ... || isempty (interfaces.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"); if (isunix && ! iscell (jcp)); jcp = strsplit (char (jcp), pathsep ()); endif endif endif ## Check if MS-Excel COM ActiveX server runs (only on Windows!) if (ispc && isempty (interfaces.COM)) interfaces.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); if (verbose) printf ("COM; "); endif ## If we get here, the call succeeded & COM works. interfaces.COM = 1; catch ## COM non-existent. Only print message if COM is explicitly requested (tmp1==[]) if (! isempty (tmp1) && verbose) 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 (interfaces.JXL) || isempty (interfaces.JOD)... || isempty (interfaces.OTK) || isempty (interfaces.OXS)... || isempty (interfaces.POI) || isempty (interfaces.UNO)) ## Some or all Java-based interface(s) explicitly requested but no Java support if (verbose) printf (" no Java support found (no Java JRE or JDK ?)"); endif endif ## Set Java-based interfaces to 0 anyway as there's no Java support interfaces.JOD = 0; interfaces.JXL = 0; interfaces.OTK = 0; interfaces.OXS = 0; interfaces.POI = 0; interfaces.UNO = 0; if (verbose) printf ("\n"); endif ## No more need to try any Java interface return endif endif ## Try Java & Apache POI if (isempty (interfaces.POI)) interfaces.POI = 0; ## Check basic .xls (BIFF8) support [chk, ~, missing2] = __POI_chk_sprt__ (jcp); if (chk > 0) interfaces.POI = chk; if (verbose) printf ("POI"); if (isempty (missing2)) printf (" (& OOXML)"); endif printf ("; "); endif endif endif ## Try Java & JExcelAPI if (isempty (interfaces.JXL)) interfaces.JXL = 0; chk = __JXL_chk_sprt__ (jcp); if (chk) interfaces.JXL = 1; if (verbose) printf ("JXL; "); endif endif endif ## Try Java & OpenXLS if (isempty (interfaces.OXS)) interfaces.OXS = 0; chk = __OXS_chk_sprt__ (jcp); ## Beware of unsupported openxls jar versions (chk must be > 0) if (chk >= 1) interfaces.OXS = 1; if (verbose) printf ("OXS; "); endif endif endif ## Try Java & jOpenDocument if (isempty (interfaces.JOD)) interfaces.JOD = 0; chk = __JOD_chk_sprt__ (jcp); if (chk) interfaces.JOD = 1; if (verbose) printf ("JOD; "); endif endif endif ## Try Java & ODF toolkit if (isempty (interfaces.OTK)) interfaces.OTK = 0; [chk, missing5] = __OTK_chk_sprt__ (jcp); ## Beware of unsupported odfdom jar versions if (chk >= 1) interfaces.OTK = 1; if (verbose) printf ("OTK; "); endif endif endif ## Try Java & UNO if (isempty (interfaces.UNO)) interfaces.UNO = 0; chk = __UNO_chk_sprt__ (jcp); if (chk) interfaces.UNO = 1; if (verbose) printf ("UNO; "); endif if (verbose) 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 interfaces.JOD = 0; interfaces.JXL = 0; interfaces.OTK = 0; interfaces.OXS = 0; interfaces.POI = 0; interfaces.UNO = 0; endif ## Native Octave. Nothing to check, always supported if (isempty (interfaces.OCT)) interfaces.OCT = 1; if (verbose) printf ("OCT"); endif endif if (verbose) printf ("\n"); endif ## ---- Other interfaces here, similar to the ones above. ## Java interfaces should be in the has-java if-block ## FIXME the below stanza should be dropped once UNO is stable. # Echo a suitable warning about experimental status: if (uno_1st_time == 1 && verbose) ++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.7.0/inst/private/PaxHeaders/__OCT_getusedrange__.m0000644000000000000000000000006215004725440017773 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OCT_getusedrange__.m0000644000175000017500000001404115004725440020307 0ustar00philipphilip## Copyright (C) 2013-2025 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)); node= ""; if (fid > 0) do xml = fread (fid, 512, "char=>char").'; if (isempty (xml)) error ("getusedrange: couldn't read \"dimension\" node.\n"); endif node = getxmlnode (xml, "dimension"); ## Seek a little back to be sure to be able to read a complete dimension node fseek (fid, ftell (fid) - 50, "bof"); until (numel (node) > 20); 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.7.0/inst/private/PaxHeaders/__UNO_spsh2oct__.m0000644000000000000000000000006215004725440017077 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__UNO_spsh2oct__.m0000644000175000017500000001151015004725440017411 0ustar00philipphilip## Copyright (C) 2011-2025 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 ("xls2oct: sheet index %d out of range 1-%d", wsh, numel (sh_names)); endif else ii = find (strcmp (wsh, sh_names)); if (isempty (ii)) error ("xls2oct: 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 = cell2mat (regexp (addrs, '.*?([A-Z]+\d+:[A-Z]+\d+|[A-Z]+\d+)', "tokens")); if (isempty (adrblks)) warning ("xls2oct: 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.7.0/inst/private/PaxHeaders/__COM_spsh_close__.m0000644000000000000000000000006215004725440017451 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__COM_spsh_close__.m0000644000175000017500000001057415004725440017774 0ustar00philipphilip## Copyright (C) 2012-2025 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 ## or xlFileFormat (see below switch stmt): ## (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. Get proper format [~, ~, ext] = fileparts (fname); ## https://docs.microsoft.com/en-us/office/vba/api/excel.xlfileformat switch ext case ".txt" ## Current Platform Text xlFileFormat = -4158; case {".wks"} ## Lotus 1-2-3 format (general) / MS Works xlFileFormat = 4; case {".wk1"} ## Lotus 1-2-3 format (general) xlFileFormat = 5; case ".csv" ## CSV (general, not platform-specific) xlFileFormat = 6; case ".dbf" ## dBase 3 format (xDbf3). Note; xlDBf2 = 7, xlDBF4 = 11 xlFileFormat = 8; case ".dif" ## Data Interchange format xlFileFormat = 9; case ".wk3" ## Lotus-1-2-3 xlFileFormat = 15; case ".wq1" ## Quattro Pro format xlFileFormat = 34; case ".prn" ## Printer Text xlFileFormat = 36; case ".wk4" ## Lotus 1-2-3 xlFileFormat = 38; case {".htm", ".html"} ## HTML format xlFileFormat = 44; case {".mht", ".mhtml"} ## Web Archive xlFileFormat = 45; case ".xml" ## XML spreadsheet 2003 xlFileFormat = 46; case "xlsb" ## Excel Binary Workbook xlFileFormat = 50; case ".xlsx" ## Open XML Workbook xlFileFormat = 51; case ".xlsm" ## Open XML Workbook Macro Enabled xlFileFormat = 52; case ".xls" ## Excel 97-2003 Workbook xlFileFormat = 56; case ".pdf" ## Printer Text xlFileFormat = 57; case ".ods" ## Open Document Format xlFileFormat = 60; otherwise ## Fall back to OpenXML .xlsx xlFileFormat = 51; endswitch xls.workbook.SaveAs (fname, xlFileFormat); 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.7.0/inst/private/PaxHeaders/__OCT_xlsx2oct__.m0000644000000000000000000000006215004725440017104 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OCT_xlsx2oct__.m0000644000175000017500000002357115004725440017430 0ustar00philipphilip## Copyright (C) 2013-2025 Markus Bergholz ## Parts Copyright (C) 2013-2025 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) rstatus = 0; ## 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\n", 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)\n", wsh, numel (xls.sheets.sh_names)); elseif (wsh < 1) error ("xls2oct: illegal worksheet number (%d)\n", wsh); endif ## Check if it's a worksheet and translate wsh to shId if (xls.sheets.type(wsh) != 1) warning ("xls2oct: sheet %d is not a worksheet\n", wsh); raw = {}; return else wsh = xls.sheets.shId(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 ("xls2oct; couldn't open worksheet xml file sheet%d.xml\n", wsh); endif else ## Get data rawdata = fread (rawsheet, "char=>char").'; fclose (rawsheet); ## Shared strings of entire worksheet 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 ## 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, ']*?(?:\st="(\w+)"[^>]*>|(>))(?:|/>))?(?:]*)>([^<]*)|([^<]*)|([^<]*))', "tokens"); ## : (.*?) ## formula: .. if (any (cellfun (@length, val) != 3)) warning ("xls2oct: error reading data from sheet %d", wsh); val = cell (0, 3); elseif (! isempty (val)) val = cat (1, val{:}); warning ("off", "legacy-function", "local"); ## Booleans idx = find (strncmp ("b", val(:, 2), 1)); if (! isempty (idx)) id = find (str2double (val(idx, 3))); val(idx, 3) = false; val(idx(id), 3) = true; endif ## Numeric data idx = find (strncmp (">", val(:, 2), 1)); idx = [ idx; find(strncmp ("n", val(:, 2), 1)) ]; if (! isempty (idx)) val(idx, 3) = num2cell (str2double (val(idx, 3))); endif ## Date / time idx = find (strncmp ("d", val(:, 2), 1)); ## 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 = find (strcmp ("str", val(:, 2))); val(idx, :) = []; endif ## 2.B. Shared strings ## Don't mix with t="str" entries => "exact" option idx = find (strcmp ("s", val(:, 2))); 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), 1); if (! isempty (strings)) ctext = regexp (strings, ']*>(.*?)', "tokens"); ## Watch out for empty cells ( in sharedStrings) ctext(cellfun ("isempty", ctext)) = {{{""}}}; ## Find cells with mixed-style contents, these have another ## XML node level and need separate treatment. jdx = find (cellfun ("numel", ctext, "uni", 0) > 1); for ii=1:numel (jdx) ctext{jdx(ii)}{1}{1} = cell2mat (cell2mat (ctext{jdx(ii)})); ctext{jdx(ii)}(2:end) = []; end ctext = cell2mat (cell2mat (ctext))'; ## Copy string values into place. Watch out for empty strings val(idx, 3) = ctext(str2double (val(idx, 3)) + 1, 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 ("xls2oct: error reading formula data from sheet %d", wsh); valf = cell (0, 3); 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 idx.all = val(:, 1); if (numel (idx.all) > 0) ## 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")); ## 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 (vi.col); idx.minrow = min (vi.row); idx.maxrow = max (vi.row); idx.maxcol = max (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 doesn't begin in first column if (idx.mincol > 1) vi.col = vi.col - (idx.mincol - 1); endif ## Row adjustment when first number or formula doesn't begin in first row if (idx.minrow > 1) 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 indices 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 else ## To prevent warnings or errors while calculating corresponding NaN matrix idx.num = idx.alph = vi.col = vi.row = raw = xls.limits = []; end if (! isempty (val)) rstatus = 1; endif endfunction io-2.7.0/inst/private/PaxHeaders/__POI_getusedrange__.m0000644000000000000000000000006215004725440017775 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__POI_getusedrange__.m0000644000175000017500000000453515004725440020320 0ustar00philipphilip## Copyright (C) 2010-2025 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 poiv4; try cblnk = __java_get__ ("org.apache.poi.ss.usermodel.Cell", "CELL_TYPE_BLANK"); poiv4 = false; catch cblnk = __java_get__ ("org.apache.poi.ss.usermodel.CellType", "BLANK").ordinal (); poiv4 = true; end_try_catch 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 cst = irow.getCell(scol).getCellType (); cet = irow.getCell(ecol).getCellType (); if (poiv4) cst = cst.ordinal (); cet = cet.ordinal (); endif if (! (cst == cblnk && cet == 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.7.0/inst/private/PaxHeaders/__JXL_getusedrange__.m0000644000000000000000000000006215004725440020003 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__JXL_getusedrange__.m0000644000175000017500000000341015004725440020315 0ustar00philipphilip## Copyright (C) 2010-2025 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.7.0/inst/private/PaxHeaders/__OXS_spsh_open__.m0000644000000000000000000000006215004725440017340 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OXS_spsh_open__.m0000644000175000017500000000454015004725440017657 0ustar00philipphilip## Copyright (C) 2012-2025 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 ("xlsopen: 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"); lastintf = ""; end_try_catch endfunction io-2.7.0/inst/private/PaxHeaders/__OTK_oct2ods__.m0000644000000000000000000000006215004725440016703 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OTK_oct2ods__.m0000644000175000017500000004244315004725440017226 0ustar00philipphilip## Copyright (C) 2010-2025 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); 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 ## 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 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.7.0/inst/private/PaxHeaders/__OCT_oct2gnm__.m0000644000000000000000000000006215004725440016667 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OCT_oct2gnm__.m0000644000175000017500000001647315004725440017216 0ustar00philipphilip## Copyright (C) 2014-2025 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 = tempname; 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}) || ... (isnumeric (raw{ii, jj}) && ! isfinite (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.7.0/inst/private/PaxHeaders/__COM_spsh_open__.m0000644000000000000000000000006215004725440017305 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__COM_spsh_open__.m0000644000175000017500000000400515004725440017620 0ustar00philipphilip## Copyright (C) 2012-2025 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 ("xlsopen: ActiveX error trying to open or create file %s\n",... filename)); app.Application.DisplayAlerts = 1; app.Quit (); delete (app); lastintf = ""; end_try_catch endfunction io-2.7.0/inst/private/PaxHeaders/__JOD_getusedrange__.m0000644000000000000000000000006215004725440017762 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__JOD_getusedrange__.m0000644000175000017500000000401215004725440020273 0ustar00philipphilip## Copyright (C) 2010-2025 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.7.0/inst/private/PaxHeaders/__COM_spsh_info__.m0000644000000000000000000000006215004725440017277 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__COM_spsh_info__.m0000644000175000017500000000315015004725440017612 0ustar00philipphilip## Copyright (C) 2012-2025 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 = [3, 4, -4169]; ## 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; stype = xls.workbook.Sheets(ii).Type; if (stype == 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 (any (ismember (stype, xlChart))) sh_names(ii, 2) = sprintf ("Chart"); ++ch_cnt; else sh_names(ii, 2) = "Other_type"; ++o_cnt; endif endfor endfunction io-2.7.0/inst/private/PaxHeaders/__OXS_oct2spsh__.m0000644000000000000000000000006215004725440017107 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OXS_oct2spsh__.m0000644000175000017500000001302115004725440017420 0ustar00philipphilip## Copyright (C) 2011-2025 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 ("oct2xls: > 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 ("oct2xls: 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 ("oct2xls: 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 ("oct2xls: 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.7.0/inst/private/PaxHeaders/__JOD_spsh_info__.m0000644000000000000000000000006215004725440017275 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__JOD_spsh_info__.m0000644000175000017500000000240715004725440017614 0ustar00philipphilip## Copyright (C) 2012-2025 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.7.0/inst/private/PaxHeaders/__POI_oct2spsh__.m0000644000000000000000000000006215004725440017065 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__POI_oct2spsh__.m0000644000175000017500000001611415004725440017404 0ustar00philipphilip## Copyright (C) 2009-2025 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 ("oct2xls: POI interface can only write to Excel .xls or .xlsx files") endif persistent ctype poiv4 p4ctype; if (isempty (ctype)) ## Get enumerated cell types. Beware as they start at 0 not 1 try ## POI < 4 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 poiv4 = false; catch ## POI >= 4 p4ctype.enum = __java_get__ ("org.apache.poi.ss.usermodel.CellType", "NUMERIC"); ctype(1) = p4ctype.enum.ordinal; p4ctype.name = "numeric"; p4ctype(2).enum = __java_get__ ("org.apache.poi.ss.usermodel.CellType", "BOOLEAN"); ctype(2) = p4ctype(2).enum.ordinal; p4ctype(2).name = "boolean"; p4ctype(3).enum = __java_get__ ("org.apache.poi.ss.usermodel.CellType", "STRING"); ctype(3) = p4ctype(3).enum.ordinal; p4ctype(3).name = "string"; p4ctype(4).enum = __java_get__ ("org.apache.poi.ss.usermodel.CellType", "FORMULA"); ctype(4) = p4ctype(4).enum.ordinal; p4ctype(4).name = "formula"; p4ctype(5).enum = __java_get__ ("org.apache.poi.ss.usermodel.CellType", "BLANK"); ctype(5) = p4ctype(5).enum.ordinal; p4ctype(5).name = "blank"; poiv4 = true; end_try_catch 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 ("oct2xls: > 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 ("oct2xls: 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); ## Remove leading "=" from formula strings fptr = (typearr == 4); obj(fptr) = cellfun (@(x) x(2:end), obj(fptr), "Uniformoutput", false); ## 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) == 5) ## Empty cells if (poiv4) cell = row.createCell (kk, p4ctype(5).enum); else cell = row.createCell (kk, ctype(5)); endif elseif (typearr(ii, jj) == 4) ## Formulas ## Try-catch needed as there's no guarantee for formula correctness try if (poiv4) cell = row.createCell (kk, p4ctype(4).enum); else cell = row.createCell (kk, ctype(4)); endif cell.setCellFormula (obj{ii,jj}); catch ++f_errs; ## Enter formula as text if (poiv4) cell.setCellType (p4ctype(3).enum); else cell.setCellType (ctype (3)); endif cell.setCellValue (obj{ii, jj}); end_try_catch else if (poiv4) cell = row.createCell (kk, p4ctype(typearr(ii,jj)).enum); else cell = row.createCell (kk, ctype(typearr(ii,jj))); endif 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.7.0/inst/private/PaxHeaders/__OTK_spsh_info__.m0000644000000000000000000000006215004725440017316 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OTK_spsh_info__.m0000644000175000017500000000345415004725440017640 0ustar00philipphilip## Copyright (C) 2012-2025 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 (compare_versions (ods.odfvsn, "0.8.7", ">=")) 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.7.0/inst/private/PaxHeaders/spsh_chkrange.m0000644000000000000000000000006215004725440016634 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/spsh_chkrange.m0000644000175000017500000000646515004725440017163 0ustar00philipphilip## Copyright (C) 2010-2025 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.7.0/inst/private/PaxHeaders/__COM_spsh2oct__.m0000644000000000000000000000006215004725440017054 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__COM_spsh2oct__.m0000644000175000017500000001312715004725440017374 0ustar00philipphilip## Copyright (C) 2009-2025 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 ("xls2oct: 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 ("xls2oct: ActiveX invocation in file ptr struct seems non-functional"); end_try_catch ## Check & get handle to requested worksheet. Take ""Sheets as the total ## user-visible count may include chartsheets and macrosheets wb_cnt = wb.Sheets.count; old_sh = 0; if (isnumeric (wsh)) if (wsh < 1 || wsh > wb_cnt) errstr = sprintf ("xls2oct: sheet 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 ("xls2oct: worksheet name \"%s\" not present", wsh); error (errstr) else wsh = old_sh; endif endif ## Finally get pointer to requested worksheet sh = wb.Sheets (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 (spsh_opts.convert_utf) ... && (compare_versions (ver ("windows").Version, "1.5.0", "<=")) ## The COM interface in of-windows until version 1.5.0 returns strings ## that are encoded in the system locale. All character values not ## contained in the locale encoding are mapped to codepoint 32 (space ## character). Try to recover the remainder. if (isempty (which ("native2unicode"))) ## Not available before Octave 4.4 ## Use fallback function. (Assumes the locale is ISO 8859-1.) conv_fcn = @unicode2utf8; else if (isempty (which ("__locale_charset__"))) ## Not available before Octave 6 ## Assume ISO 8859-1 (Latin-1) enc = "iso8859-1"; else enc = __locale_charset__ (); endif conv_fcn = @(str) native2unicode (uint8 (str), enc); endif idx = cellfun (@ischar, rawarr); rawarr(idx) = cellfun (conv_fcn, rawarr(idx), "uniformoutput", false); 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 warning ("xls2oct: no data read from spreadsheet file"); rstatus = 0; endif endfunction io-2.7.0/inst/private/PaxHeaders/__OXS_getnmranges__.m0000644000000000000000000000006215004725440017654 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OXS_getnmranges__.m0000644000175000017500000000240115004725440020165 0ustar00philipphilip## Copyright (C) 2017-2025 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.7.0/inst/private/PaxHeaders/__JXL_spsh2oct__.m0000644000000000000000000000006215004725440017073 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__JXL_spsh2oct__.m0000644000175000017500000002053615004725440017415 0ustar00philipphilip## Copyright (C) 2009-2025 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 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 ("xls2oct: 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 ("xls2oct; 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.7.0/inst/private/PaxHeaders/__COM_getnmranges__.m0000644000000000000000000000006215004725440017621 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__COM_getnmranges__.m0000644000175000017500000000273715004725440020146 0ustar00philipphilip## Copyright (C) 2017-2025 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.7.0/inst/private/PaxHeaders/__JOD_chk_sprt__.m0000644000000000000000000000006215004725440017122 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__JOD_chk_sprt__.m0000644000175000017500000000273615004725440017446 0ustar00philipphilip## Copyright (C) 2014-2025 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.7.0/inst/private/PaxHeaders/chknmrange.m0000644000000000000000000000006215004725440016132 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/chknmrange.m0000644000175000017500000000527615004725440016460 0ustar00philipphilip## Copyright (C) 2015-2025 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) idx = find (strcmpi (datrange, xls.nmranges(:, 1))); if (! isempty (idx)) 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 = find (strncmpi (wsh, xls.nmranges(idx, 2), numel (wsh))); 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 else mtch = cell2mat (regexp (datrange, ... '(^[A-Za-z]{1,3}[0-9]+){1}(:[A-Za-z]{1,3}[0-9]+$)?', "tokens")); if (isempty (mtch) || ! strcmp ([mtch{:}], datrange)) error ("Unknown Named Range or unrecognizable cell range") endif endif endfunction io-2.7.0/inst/private/PaxHeaders/__OCT_spsh_open__.m0000644000000000000000000000006215004725440017314 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OCT_spsh_open__.m0000644000175000017500000001755515004725440017645 0ustar00philipphilip## Copyright (C) 2013-2025 Philip Nienhuis ## Copyright (C) 2013-2025 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 = tempname; ## 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 ("xlsopen: 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 ("xlsopen: 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. rId# is the position in the worksheet stack. sheets = getxmlnode (xml, "sheets", [], 1); xls.sheets.sh_names = cell2mat (regexp (sheets, ' 0) str = fread (fid, "char=>char").'; fclose (fid); ee = 1; numrels = numel (strfind (str, 'Relationship ')); relids = cell (numrels, 3); for ii=1:numrels [node, ~, ee] = getxmlnode (str, "Relationship", ee); relids{ii, 1} = getxmlattv (node, "Id"); relids{ii, 2} = getxmlattv (node, "Target"); relids(ii, 3) = "0"; endfor id = find (strncmpi ("worksheets", relids(:, 2), 10)); relids(id, 3) = "1"; rels = str2double (cell2mat (cell2mat ( ... regexp (relids(id, :), '(\d+)', "tokens")))); id = find (strncmp ("chartsheets", relids(:, 2), 11)); if (! isempty (id)) relids(id, 3) = "2"; rels = [rels; (str2double (cell2mat (cell2mat ( ... regexp (relids(id, :), '(\d+)', "tokens")))))]; endif rels = sortrows (rels, 1); xls.sheets.shId = rels(:, 2)'; xls.sheets.type = rels(:, 3)'; else error ("xlsopen: couldn't read xl/_rels/workbook.xml.rels"); 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, ""); else sht_end = sht_end(end) + 14; 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.sheets.type = repmat (1, 1, nsheets); # Dummy sheet type for ods xls.sheets.shId = [1 : nsheets]; # Dummy sheet nr enumeration 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)); nsheets = numel (xls.sheets.sh_names); xls.sheets.type = repmat (1, 1, nsheets); xls.sheets.shId = [1 : nsheets]; 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.7.0/inst/private/PaxHeaders/__JXL_oct2spsh__.m0000644000000000000000000000006215004725440017073 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__JXL_oct2spsh__.m0000644000175000017500000001446215004725440017416 0ustar00philipphilip## Copyright (C) 2009-2025 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 ("oct2xls: 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( "oct2xls: > 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 ("oct2xls: 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.7.0/inst/private/PaxHeaders/__OCT_oct2ods__.m0000644000000000000000000000006215004725440016673 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OCT_oct2ods__.m0000644000175000017500000002555515004725440017223 0ustar00philipphilip## Copyright (C) 2014-2025 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 ## ... but first get original file size cxfs = dir ([ods.workbook filesep "content.xml"]); cxfs = cxfs.bytes; 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 = tempname; 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); cxbs = ftell (fidc); if (cxbs < cxfs) ## New content.xml shorter than original ==> overwrite trailing junk fprintf (fidc, "%s", repmat (" ", 1, cxfs - cxbs)); endif 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. FIXME check for finite values as well 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}) || ... (isnumeric (rawarr{ii, jj}) && ! isfinite (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"} if (isfinite (rawarr{ii, jj})) 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}); else ovt = ""; val = ""; txt = ""; endif 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 = ""; 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.7.0/inst/private/PaxHeaders/__OCT_spsh_info__.m0000644000000000000000000000006215004725440017306 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OCT_spsh_info__.m0000644000175000017500000000352415004725440017626 0ustar00philipphilip## Copyright (C) 2013-2025 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) if (ods.sheets.type(ii) == 1) [ tr, lr, lc, rc ] = getusedrange (ods, ods.sheets.shId(ii)); if (tr) sh_names(ii, 2) = sprintf ("%s:%s", calccelladdress (tr, lc),... calccelladdress (lr, rc)); else sh_names(ii, 2) = "Empty"; endif elseif (ods.sheets.type(ii) == 2) sh_names(ii, 2) = "Chart"; else sh_names(ii, 2) = "Other type"; endif endfor ## Replace XML escape sequences by regular characters sh_names(:, 1) = strrep (sh_names(:, 1), "&", "&"); sh_names(:, 1) = strrep (sh_names(:, 1), "<", "<"); sh_names(:, 1) = strrep (sh_names(:, 1), ">", ">"); sh_names(:, 1) = strrep (sh_names(:, 1), "'", "'"); sh_names(:, 1) = strrep (sh_names(:, 1), """, '"'); endfunction io-2.7.0/inst/private/PaxHeaders/__OTK_oct2spsh__.m0000644000000000000000000000006215004725440017073 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OTK_oct2spsh__.m0000644000175000017500000001464415004725440017420 0ustar00philipphilip## Copyright (C) 2010-2025 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 (compare_versions (ods.odfvsn, "0.8.7", ">=")) 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 ("oct2xls: 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 ("oct2xls: 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.7.0/inst/private/PaxHeaders/__POI_getnmranges__.m0000644000000000000000000000006215004725440017632 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__POI_getnmranges__.m0000644000175000017500000000504115004725440020146 0ustar00philipphilip## Copyright (C) 2015-2025 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); poiv = javaObject ("org.apache.poi.Version").getVersion(); if (compare_versions (poiv, "5.0.0", "<")) ## Because there's no POI call to get all named ranges, 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 end_try_catch else ## POI > 5.0.0 finally has a method to request Named Ranges nmrs = xls.workbook.getAllNames (); nnmr = nmrs.size (); nmr = cell (nnmr, 3); for inmr=1 : nnmr nm = nmrs.get (inmr-1); 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 nmr{inmr, 3} = rg; nmr{inmr, 1} = nm.getNameName (); nmr{inmr, 2} = nm.getSheetName (); endif endfor endif endfunction io-2.7.0/inst/private/PaxHeaders/getnmranges.m0000644000000000000000000000006215004725440016327 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/getnmranges.m0000644000175000017500000000332615004725440016647 0ustar00philipphilip## Copyright (C) 2015-2025 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} =} 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.7.0/inst/private/PaxHeaders/__OCT_gnm_getnmranges__.m0000644000000000000000000000006215004725440020471 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OCT_gnm_getnmranges__.m0000644000175000017500000000361715004725440021014 0ustar00philipphilip## Copyright (C) 2015-2025 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.7.0/inst/private/PaxHeaders/__OXS_spsh2oct__.m0000644000000000000000000000006215004725440017107 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OXS_spsh2oct__.m0000644000175000017500000001164715004725440017434 0ustar00philipphilip## Copyright (C) 2011-2025 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 ... ("xls2oct: 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 ("xls2oct: 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.7.0/inst/private/PaxHeaders/__UNO_spsh_open__.m0000644000000000000000000000006215004725440017330 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__UNO_spsh_open__.m0000644000175000017500000001163615004725440017653 0ustar00philipphilip## Copyright (C) 2012-2025 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 [~, maxsize] = computer (); amd64y = maxsize > 2^31 - 1; 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 lastintf = ""; error ("xlsopen: couldn't open file %s using UNO\n", filename); end_try_catch endfunction io-2.7.0/inst/private/PaxHeaders/parse_sp_range.m0000644000000000000000000000006215004725440017005 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/parse_sp_range.m0000644000175000017500000000535015004725440017324 0ustar00philipphilip## Copyright (C) 2009-2025 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.7.0/inst/private/PaxHeaders/__OCT_ods2oct__.m0000644000000000000000000000006215004725440016673 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OCT_ods2oct__.m0000644000175000017500000002367615004725440017225 0ustar00philipphilip## Copyright (C) 2013-2025 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", "percentage", "currency"} ## Simply get value from main cell tag. In case of error ## values (#VALUE, #DIV/0, etc.) the cell type is string. rawarr{irow, icol} = str2double (getxmlattv (tcell, "office:value")); 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); ## 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.7.0/inst/private/PaxHeaders/__JOD_spsh_close__.m0000644000000000000000000000006215004725440017447 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__JOD_spsh_close__.m0000644000175000017500000000233715004725440017770 0ustar00philipphilip## Copyright (C) 2012-2025 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.7.0/inst/private/PaxHeaders/__UNO_getnmranges__.m0000644000000000000000000000006215004725440017644 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__UNO_getnmranges__.m0000644000175000017500000000504415004725440020163 0ustar00philipphilip## Copyright (C) 2017-2025 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.7.0/inst/private/PaxHeaders/__OXS_spsh_close__.m0000644000000000000000000000006215004725440017504 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OXS_spsh_close__.m0000644000175000017500000000271315004725440020023 0ustar00philipphilip## Copyright (C) 2012-2025 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 ("xlsclose: error trying to close OXS file ptr"); end_try_catch endif xls.workbook.close (); endfunction io-2.7.0/inst/private/PaxHeaders/__JOD_spsh_open__.m0000644000000000000000000000006215004725440017303 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__JOD_spsh_open__.m0000644000175000017500000000457315004725440017630 0ustar00philipphilip## Copyright (C) 2012-2025 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 ("xlsopen: couldn't open file %s using JOD", filename); lastintf = ""; end_try_catch endfunction io-2.7.0/inst/private/PaxHeaders/__ods_get_sheet_dims__.m0000644000000000000000000000006215004725440020441 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__ods_get_sheet_dims__.m0000644000175000017500000001317415004725440020763 0ustar00philipphilip## Copyright (C) 2013-2025 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{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.7.0/inst/private/PaxHeaders/__OTK_chk_sprt__.m0000644000000000000000000000006215004725440017143 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/private/__OTK_chk_sprt__.m0000644000175000017500000000640615004725440017465 0ustar00philipphilip## Copyright (C) 2014-2025 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 ## ODF Toolkit is an unstable project AFAICS ... supp_vsns = {"0.7.5", "0.8.6", "0.8.8", "0.10.0", "0.11.0", "0.12.0"}; 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 ## A kludge for odfdom 0.11.x up: end_try_catch try ## New since 0.8.6 odfvsn = javaMethod ("getOdfdomVersion", "org.odftoolkit.odfdom.JarManifest"); ## For odfdom 0.10.0 and up, throw out some unneeded jars in the check if (compare_versions (odfvsn, "0.10.0", ">=")) missing5 = {}; jpchk += 2; endif 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 and > 0.10.0 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 (! any (ismember (odfvsn, supp_vsns))) chk = -1; if (dbug > 1) printf (" *** odfdom version (%s) is not supported - use any of\n %s\n", ... odfvsn, strjoin (supp_vsns, ", ")); 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.7.0/inst/PaxHeaders/odswrite.m0000644000000000000000000000006215004725440014203 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/odswrite.m0000644000175000017500000000274015004725440014522 0ustar00philipphilip## Copyright (C) 2009-2025 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}) ## Write data to a spreadsheet file. ## ## For more info see the help for xlswrite.m. ## ## odsread.m is deprecated. Currently it is a mere wrapper for xlswrite.m ## ## @seealso{xlswrite} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-12-14 function [ rstatus ] = odswrite (varargin) rstatus = xlswrite (varargin{:}); endfunction io-2.7.0/inst/PaxHeaders/xmlwrite.m0000644000000000000000000000006215004725440014216 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/xmlwrite.m0000644000175000017500000001141115004725440014530 0ustar00philipphilip## Copyright (C) 2015-2025 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 output 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.7.0/inst/PaxHeaders/test_spsh.m0000644000000000000000000000006215004725440014357 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/test_spsh.m0000644000175000017500000001136415004725440014700 0ustar00philipphilip## Copyright (C) 2013-2025 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 () ## @deftypefnx {Function File} [ @var{void} ] = test_sprdsh (@var{verbose}) ## 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 function io_testscript.m for the actual testing. ## ## As it is meant to be used interactively, no output arguments ## are returned. ## ## @seealso{io_testscript} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2013-04-21 function [] = test_spsh (verbose = false) persistent intfs = {"com", "poi", "oox", "jxl", "oxs", "otk", "jod", "uno"}; page_screen_output (0, "local"); ## Get available interfaces avail_intf = uint16 (chk_spreadsheet_support ()); rslts = cell (0, 11); ## Check all interfaces intf2 = ""; for ii = 1:numel (intfs) 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 32 ## OTK (ODF Toolkit) intf = intf2 = "otk"; fname = "io-test.ods"; case 64 ## JOD (jOpenDocument) intf = intf2 = "jod"; fname = "io-test.ods"; case 128 ## UNO (LibreOffice Java-UNO bridge) intf = intf2 = "uno"; ## .xls otherwise endswitch ## If present, test selected interfaces if (! isempty (intf)) printf ("\nInterface \"%s\" found.\n", upper (intf)); rslts = [rslts ; io_testscript(intf, fname, "", verbose)]; if (intfchk == 128) ## Check UNO also for .xlsx and .ods intf = intf2 = "uno"; fname = "io-test.xlsx"; rslts = [rslts ; io_testscript(intf, fname, "", verbose)]; intf = intf2 = "uno"; fname = "io-test.ods"; rslts = [rslts ; io_testscript(intf, fname, "", verbose)]; endif 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 for xlsx rslts = [rslts; io_testscript("OCT", "io-test.xlsx", "", verbose)]; ## Test OCT interface for ods rslts = [rslts; io_testscript("OCT", "io-test.ods", "", verbose)]; ## Test OCT interface for gnumeric rslts = [rslts; io_testscript("OCT", "io-test.gnumeric", "", verbose)]; 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.7.0/inst/PaxHeaders/oct2xls.m0000644000000000000000000000006215004725440013741 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/oct2xls.m0000644000175000017500000002351715004725440014265 0ustar00philipphilip## Copyright (C) 2009-2025 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 a 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 LibreOffice (OOo) or Excel 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 for .xlsx/.xls files). ## If it is numeric it refers to the position in the total sheet stack incl. ## e.g., chartsheets. ## ## 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 spreadsheet file, they are ## inserted to the right of all existing worksheets. The pointer to the ## "active" sheet (shown when opened in a spreadsheet program) 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 spreadsheet 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 literal ## 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- LibreOffice or Excel invocations may be left ## running silently in case of Java or COM errors. Invoke xlsclose with a ## proper pointer struct to try 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 ("oct2xls: 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 alfnm = "[abcdefghijklmnopqrstuvwxyz]+[0123456789]+"; rlims = cell2mat (cell2mat (regexp (lower (deblank (crange)), ... ["(^" alfnm ":" alfnm "$|^" alfnm "$)"], "tokens"))); if (isempty (rlims)) ## Apparently no cell range - check for Named range [crange, wsh, xls] = chknmrange (xls, crange, wsh); else if (isempty (strfind (rlims, ":"))) if (strcmpi (xls.filename(end-4:end-1), ".xls")) crange = [rlims ":XFD1048576"]; ## OOXML has ridiculously large limits elseif (strcmpi (xls.filename(end-3:end), ".ods")) crange = [rlims ":AMJ1048576"]; ## LO max. 1024 columns else ## FIXME .gnumeric and other formats unknown crange = [rlims ":IV65536"]; ## Regular xls limits endif endif endif 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 ## Select interface to be used switch upper (xls.xtype) case, "COM" ## ActiveX / COM [xls, rstatus] = __COM_oct2spsh__ (obj, xls, wsh, crange, spsh_opts); case, "JOD" ## Write ods file tru Java & jOpenDocument. API still leaves lots to be wished... [ xls, rstatus ] = __JOD_oct2spsh__ (obj, xls, wsh, crange); case, "JXL" ## Invoke Java and JExcelAPI [xls, rstatus] = __JXL_oct2spsh__ (obj, xls, wsh, crange, spsh_opts); case, "OXS" ## Invoke Java and OpenXLS [xls, rstatus] = __OXS_oct2spsh__ (obj, xls, wsh, crange, spsh_opts); case, "OTK" ## Write ods file thru Java & ODF toolkit. switch xls.odfvsn case "0.7.5" [ xls, rstatus ] = __OTK_oct2ods__ (obj, xls, wsh, crange, spsh_opts); case {"0.8.6", "0.8.7", "0.8.8", "0.10.0", "0.11.0", "0.12.0"} [ xls, rstatus ] = __OTK_oct2spsh__ (obj, xls, wsh, crange, spsh_opts); otherwise error ("oct2ods: unsupported odfdom version\n"); endswitch case, "POI" ## Invoke Java and Apache POI [xls, rstatus] = __POI_oct2spsh__ (obj, xls, wsh, crange, spsh_opts); case, "UNO" ## Invoke Java and UNO bridge (OpenOffice.org) [xls, rstatus] = __UNO_oct2spsh__ (obj, xls, wsh, crange, spsh_opts); case, "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); otherwise error (sprintf ("oct2xls: unknown Excel .xls interface - %s.\n", xls.xtype)); endswitch endfunction io-2.7.0/inst/PaxHeaders/odsfinfo.m0000644000000000000000000000006215004725440014152 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/odsfinfo.m0000644000175000017500000000307515004725440014473 0ustar00philipphilip## Copyright (C) 2009-2025 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 a spreadsheet file for some info about its contents. ## ## For more info see the help for xlsfinfo.m. ## ## odsfinfo.m is deprecated. Currently it is a mere wrapper for xlsfinfo.m ## ## @seealso{xlsfinfo} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-12-17 function [a, b, c, d] = odsfinfo (varargin) [a, b, c, d] = xlsfinfo (varargin{:}); endfunction io-2.7.0/inst/PaxHeaders/append_save.m0000644000000000000000000000006215004725440014630 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/append_save.m0000644000175000017500000001101115004725440015136 0ustar00philipphilip## Copyright (C) 2003-2025 Tomer Altman ## Copyright (C) 2025 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{rval} = append_save (@var{filename}, @var{option}, @var{var_val_cell}, @var{varargin}) ## Add variables to existing save files. Works for all the types of save files ## that "save" supports. ## ## Input: ## ## @itemize ## @item ## @var{filename}, a string which specifies the existing save file. ## ## @item ## @var{option}, the options you need to pass to the 'save' function to save ## to the file type that you want. ## ## @item ## @var{var_val_cell}, 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. ## ## @item ## @var{varargin}, any number of additional 1x2 cells, following the same ## format as the 3rd argument specified immediately before this one. ## @end itemize ## ## 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 @} ) ## @end example ## ## @end deftypefn function [ retval ] = append_save ( filename, option, var_val_cell, varargin ) retval = 0 ## 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.7.0/inst/PaxHeaders/oct2ods.m0000644000000000000000000000006215004725440013720 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/oct2ods.m0000644000175000017500000000301415004725440014232 0ustar00philipphilip## Copyright (C) 2009-2025 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 spreadsheet file pointer @var{ods}. ## ## For more info see the help for oct2xls.m. ## ## oct2ods.m is deprecated. Currently it is a mere wrapper for oct2xls.m ## ## @seealso{oct2xls} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-12-13 function [a, b] = oct2ods (varargin) [a, b] = oct2xls (varargin{:}); endfunction io-2.7.0/inst/PaxHeaders/read_namelist.m0000644000000000000000000000006215004725440015152 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/read_namelist.m0000644000175000017500000002613415004725440015474 0ustar00philipphilip## Copyright (C) 2013-2025 Darien Pardinas Diaz ## Copyright (C) 2025 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{s} = read_namelist (@var{filename}) ## ## S = READ_NAMELIST (FILENAME) returns the struct S containing namelists and ## variables in the file FILENAME organised in hierachical way: ## ## @verbatim ## |--VAR1 ## |--VAR2 ## |-- NMLST_A--|... ## | |--VARNa ## | ## | |--VAR1 ## |-- NMLST_B--|--VAR2 ## | |... ## S --| ... |--VARNb ## | ## | |--VAR1 ## |-- NMLST_M--|--VAR2 ## |... ## |--VARNm ## @end verbatim ## ## 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"); ## @end example ## ## @end deftypefn ## 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:ii+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.7.0/inst/PaxHeaders/getxmlattv.m0000644000000000000000000000006215004725440014542 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/getxmlattv.m0000644000175000017500000000304215004725440015055 0ustar00philipphilip## Copyright (C) 2013-2025 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), '"[ >/]', "once"); if (! isempty (vale)) retval = xmlnode(vals:vals+vale-2); endif endif endfunction io-2.7.0/inst/PaxHeaders/__init_io__.m0000644000000000000000000000006215004725440014571 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/__init_io__.m0000644000175000017500000001311715004725440015110 0ustar00philipphilip## Copyright (C) 2016-2025 Carnë Draug ## Copyright (C) 2011-2025 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. ## ## Register Qt help files for GUI doc browser. ## Search io pkg java jars and add found ones to javaclasspath. ## ## @end deftypefn ## PKG_ADD: __init_io__ () function __init_io__ () ## Package documentation ## On package load, attempt to load docs try pkg_dir = fileparts (fullfile (mfilename ("fullpath"))); doc_file = fullfile (pkg_dir, "doc", "io.qch"); doc_file = strrep (doc_file, '\', '/'); if exist(doc_file, "file") if exist("__event_manager_register_documentation__") __event_manager_register_documentation__ (doc_file); elseif exist("__event_manager_register_doc__") __event_manager_register_doc__ (doc_file); endif endif catch # do nothing end_try_catch ## Java spreadsheet I/O jars. ## First check if Java support is available HAVE_JAVA = isempty (javachk ("jvm")); 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 = fullfile (OCTAVE_HOME, "lib"); # 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 have a 64-bit indexing Octave at hand? ## (thanks to Markus Muetzel for the suggestion to try MAXSIZE) [~, maxsize] = computer (); amd64y = maxsize > 2^31 - 1; ## 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.7.0/inst/PaxHeaders/toJSON.m0000644000000000000000000000006215004725440013457 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/toJSON.m0000644000175000017500000004315515004725440014003 0ustar00philipphilip## Copyright (C) 2019-2025 Ketan M. Patel ## Copyright (C) 2025 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{str} =} toJSON (@var{obj}) ## @deftypefnx {} {@var{str} =} toJSON (@var{obj}, @var{prec}) ## @deftypefnx {} {@var{str} =} toJSON (@var{obj}, @var{compact}) ## @deftypefnx {} {@var{str} =} toJSON (@var{obj}, @var{prec}, @var{compact}) ## Convert any Octave @var{obj} into a compact JSON string. ## ## toJSON strives to convert Octave vectors, matrices and/or ND arrays to ## equivalent JSON arrays. Special provisions are made to handle +/-Inf and ## complex numbers, which are conventionally not permitted is JSON string. ## ## Input arguments: ## ## @itemize ## @item ## @var{obj}, any Octave object: double, float, int, logical, complex, char, etc. ## There are no limitations on the class accepted, but classes not ## permitted in JSON are merely referenced by classname, along the lines of ## @code{"[octave_com_object]"}, and the contents are lost. ## ## @item ## @var{prec}, a numeric value, specifies number of significant digits for ## number-to-string conversion. The default value of @var{prec} is 15. ## ## @item ## @var{compact} (logical; default value is FALSE) specifies whether to return ## Octave struct arrays as arrays of JSON objects or JSON objects of arrays. ## Consider an Octave struct array with fields 'x' and 'y': ## ## @itemize ## Leaving as FALSE returns a JSON array of objects, i.e.: ## ## @w{ '[@{"x": ..., "y": ...@}, @{"x": ..., "y": ...@}]' } ## ## @item ## Changing to TRUE returns a JSON object of arrays, i.e.: ## ## @w{ '@{"x": [...], "y": [...]@}' } ## @end itemize ## @end itemize ## ## Special cases: ## ## The specification for JSON does not allow +/-Inf or complex numbers; ## nevertheless, provisions are made here to enable these important numbers: ## ## @itemize ## @item ## Octave numbers +/-Inf return as numeric string '+/-1e999' which ## should automatically revert to +/-Inf when parsed. ## ## @item ## Complex numbers return as JSON object @code{@{"re":..., "im":...@}} ## @end itemize ## ## Apparent JSON strings are left unquoted. This allows recursive use of toJSON. ## To prevent this, append a whitespace to the string. ## ## The bodies of Octave inline functions are stored as string; however, reference to ## values external to inline function will be lost. e.g. ## ## @w{ @@(x) a*x => "@@@@(x) a*x" } ## ## @seealso{fromJSON} ## @end deftypefn ## Author: Ketan M. Patel ## Created: 2019-06-01 function str = toJSON ( obj='', PREC=[], COMPACT=[] ); if( isbool(PREC) ); [PREC,COMPACT] = {[],PREC}{:}; elseif ~(isempty(PREC) || isnumeric(PREC)); warning ("toJSON.m: invalid PREC\n"); PREC = []; elseif ~(isempty(COMPACT) || isbool(COMPACT)); warning ("toJSSON.m: invalid COMPACT\n"); COMPACT = []; endif # set defaults isempty(PREC) && (PREC=15); isempty(COMPACT) && (COMPACT=false); fmt = sprintf('%%.%dg,',fix(abs(PREC))); opt = struct('fmt',fmt,'prec',PREC,'compact',COMPACT); if( nargin == 0 ); str = ''; else str = _tojson_(obj,opt); endif endfunction ## convert any object into some kind of JSON string function [str] = _tojson_ ( obj, opt ); ND = ndims(obj); if( iscomplex(obj) ); obj = {real(obj) imag(obj)}; if( ~opt.compact ); obj = _map_(@num2cell,obj); endif str = _tojson_(struct('re',obj{1},'im',obj{2}),opt); ## end iscomplex elseif( isstruct(obj) && (ND == 2 || opt.compact) ); keys = __fieldnames__(obj); vals = struct2cell(obj); if( isempty(vals) ); str = '{}'; elseif( isscalar(obj) || opt.compact ); if( ~isscalar(obj) ); vals = _nestdim_(vals,1); endif str = _map_(@(k,v)['"',k,'":',_tojson_(v,opt)], keys(:),vals(:)); str = _csv_('{',str,'}'); elseif( ~isvector(obj) ); # 2D or ND struct array str = _tojson_(_nestdim_(obj,1),opt); else # 1D struct array ## NOTE: str = _tojson_(num2cell(obj,opt)) is a simpler but very slow alternative for i = 1:rows(vals); # join key value pairs kv(i,:) = _map_(@(k,v)['"',k,'":',_tojson_(v,opt)], keys(i), vals(i,:)); endfor for i = 1:columns(kv); # assemble key-value into struct str{i} = _csv_('{',kv(:,i),'}'); endfor str = _csv_('[',str,']'); endif ## end isstruct elseif( ND > 2 ); # nest ND array, c-style str = _tojson_(_nestdim_(obj,ND),opt); elseif( iscell(obj) ); try # try as matrix first ~cellfun(@ischar,obj) || error('no'); str = _tojson_(reshape([obj{:}],size(obj)),opt); catch; if( isempty(obj) ); str = '[]'; elseif( ~isvector(obj) ); str = _tojson_(_nestdim_(obj,1),opt); else str = _csv_('[', _map_(@(o) _tojson_(o,opt),obj), ']'); endif; end_try_catch; ## end iscell elseif( isnumeric(obj) || isbool(obj) ); ## stringify if( isbool(obj) ); str = _csv_('',{'false','true'}(obj.'+1),''); else obj( nans=isnan(obj) ) = NaN; # standardize NaN,nan,NA str = sprintf(opt.fmt,obj.')(1:end-1); ## GRRR! JSON is not IEEE754 complain; hacks to transmit Inf and NaN any(isinf(obj)) && (str = _rep_(str,'Inf','1e999')); any(nans) && (str = _rep_(str,'NaN','null' )); endif ## bracket string if( all (size(obj) > 1) ); idx = strfind(str,','); c = columns(obj); str(idx(c:c:end)) = ';'; # replace end of row ',' with ';' str = ['[[' _rep_(str,';','],[') ']]']; elseif( numel(obj) ~= 1 ); # NOTE: either empty or vector str = ['[' str ']']; endif ## end isnumeric || isbool elseif( ischar(obj) ); ## 2D array of chars, make it a column vector of strings if( rows(obj)>1 ); str = _tojson_(mat2cell(obj,ones(1,rows(obj)),columns(obj)),opt); ## else quote it, if not already JSON string (i.e. object/struct/quoted string) elseif( ~(numel(str=obj) && strfind('{}[]""',obj([1,end]))) ); str = ['"' _rep_(obj,'"','\"') '"']; end ## end ischar elseif( is_function_handle(obj) ); str = func2str(obj); str(1) == "@" || (str = ['@(x) ' str '(x)']); str = ['"@' str '"']; else str = ['"[' class(obj) ']"']; endif endfunction ## _tojson() ##========================= helpers ======================= function str1 = _rep_ ( str, pat, rep ); str1 = strrep(str,pat,rep,'overlaps',false); endfunction function obj = _map_ ( fn, varargin ); obj = cellfun(fn,varargin{:},'UniformOutput',false); endfunction function C = _nestdim_ ( obj, D ); index.type = '()'; index.subs(1:ndims(obj)) = {':'}; for i = 1:size(obj,D); index.subs(D) = i; C{i} = squeeze(subsref(obj,index)); # allow rows => columns endfor endfunction function str = _csv_ ( a, c, b ); c = c(:).'; c(2,:) = ','; str = [a c{1:end-1} b]; endfunction %!test ## invalid args %!warning toJSON(0,struct); %!warning toJSON(0,:,struct); %!test ## no args %! assert(toJSON(),''); %!test ## empty string %! assert(toJSON(''),'""'); %!test ## empty array %! assert(toJSON([]),'[]'); %!test ## zero %! assert(toJSON(0),"0") %!test ## false %! assert(toJSON(false),'false') %!test ## float %! assert(toJSON(pi),'3.14159265358979') %!test ## PREC input arg test %! assert(toJSON(pi, 0),'3') %! assert(toJSON(pi, 5),'3.1416') %! assert(toJSON(pi, -5),'3.1416') %! assert(toJSON(pi, 25),'3.141592653589793115997963') %! assert(toJSON(pi, :),'3.14159265358979') %! assert(toJSON(pi, []),'3.14159265358979') %! assert(toJSON(pi, false),'3.14159265358979'); %! assert(toJSON(pi, {}),'3.14159265358979'); %!test ## number single %! assert(toJSON(single(pi)),'3.14159274101257') %!test ## number int8 %! assert(toJSON(int8(pi)),'3') %!test ## number int32 %! assert(toJSON(int32(pi)),'3') %!test ## number string %! assert(toJSON("3"),'"3"') %!test ## string %! assert(toJSON("abcdefg"), '"abcdefg"'); %# unknown class %!testif HAVE_JAVA %! if (usejava ("jvm")) %! obj = javaObject ("java.math.BigDecimal", 1.0); %! assert(toJSON(obj), '"[java.math.BigDecimal]"'); %! endif %!test ## apparent JSON string, do not quote %! assert(toJSON('[]'),'[]'); %! assert(toJSON('[1,2, 3]'),'[1,2, 3]'); %! assert(toJSON('{}'),'{}'); %! assert(toJSON('{"a":4}'),'{"a":4}'); %! assert(toJSON('""'),'""'); %!test ## apparent JSON string blocked, quote it %! assert(toJSON('"abc def" '),'"\"abc def\" "'); %!test ## vectors %! assert(toJSON([1,2,3]),'[1,2,3]') %! assert(toJSON([1;2;3]),'[1,2,3]') %!test ## vector with PREC %! assert(toJSON(pi*(1:4),3),'[3.14,6.28,9.42,12.6]') %!test ## matrix %! assert(toJSON([1,2,3;13,14,15]),'[[1,2,3],[13,14,15]]') %!test ## boolean 2D array %! assert(toJSON(![1 1;0 1]),'[[false,false],[true,false]]') %!test ## ND array %! assert(toJSON(reshape(1:8,2,2,2)),'[[[1,3],[2,4]],[[5,7],[6,8]]]') %!test ## more N ND array %! ndmat = ones(2,2,2,3); %! ndmat([4,9,21]) = [4,9,21]; %! json = toJSON(ndmat); %! assert(json,'[[[[1,1],[1,4]],[[1,1],[1,1]]],[[[9,1],[1,1]],[[1,1],[1,1]]],[[[1,1],[1,1]],[[21,1],[1,1]]]]') %!test ## string array %! assert(toJSON(["a";"bc";"defg"]), '["a ","bc ","defg"]'); %!test ## string array %! assert(toJSON(["a";"bc";"defg"]'), '["abd"," ce"," f"," g"]'); %!test ## cell vector %! assert(toJSON({1,2,3}),'[1,2,3]') %! assert(toJSON({1;2;3}),'[1,2,3]') %!test ## mixed cell vector %! assert(toJSON({1,2,3,"a"}),'[1,2,3,"a"]') %!test ## cell array of numerical vectors %! assert(toJSON({[1,2,3];[3,4,5]}),'[[1,2,3],[3,4,5]]') %!test ## numerical ND cell array (look just like ND numerical array) %! json = toJSON(num2cell(reshape(1:8,2,2,2))); %! assert(json,'[[[1,3],[2,4]],[[5,7],[6,8]]]') %!test ## numerical ND cell array, with PREC %! c = num2cell(reshape(1:8,2,2,2)); c{5} = pi; %! assert(toJSON(c,5),'[[[1,3],[2,4]],[[3.1416,7],[6,8]]]') %!test ## mixed ND cell array %! c = num2cell(reshape(1:8,2,2,2)); c{5} = "a"; %! assert(toJSON(c),'[[[1,3],[2,4]],[["a",7],[6,8]]]') %!test ## structure numbers %! assert(toJSON(struct(), true),'{}') %!test ## structure numbers %! assert(toJSON(struct("a",3,"b",5), true),'{"a":3,"b":5}') %!test ## structure string %! s = struct("a","hello","b",4); %! assert(toJSON(s, true),'{"a":"hello","b":4}') %!test ## structure string array %! s = struct("a","","b",4); s.a = {"hello","bye"}; %! assert(toJSON(s, true),'{"a":["hello","bye"],"b":4}') %!test ## structure array COMPACT=false %! assert(toJSON(struct("a",{3.125;3.125}), false),'[{"a":3.125},{"a":3.125}]') %!test ## structure array COMPACT=true %! assert(toJSON(struct("a",{3.125;3.125}), true),'{"a":[3.125,3.125]}') %! assert(toJSON(struct("a",{pi;pi}), 5, true),'{"a":[3.1416,3.1416]}') %!test ## structure array 2D %! s = struct("a",{1 3;2 4},"b",{11 13;12 14}); %! assert(toJSON(s, true),'{"a":[[1,3],[2,4]],"b":[[11,13],[12,14]]}') %!test ## structure array 2D COMPACT=false %! s = struct("a",{1 3;2 4},"b",{11 13;12 14}); %! assert(toJSON(s, false),'[[{"a":1,"b":11},{"a":3,"b":13}],[{"a":2,"b":12},{"a":4,"b":14}]]') %!test ## mixed cell array %! assert(toJSON({1,2,3,"a",struct("a",3)}, true),'[1,2,3,"a",{"a":3}]') %!test ## complex number %! assert(toJSON(i, true),'{"re":0,"im":1}'); %!test ## complex number 1D array %! assert(toJSON([i,1], true),'{"re":[0,1],"im":[1,0]}'); %!test ## complex number COMPACT=false, %! assert(toJSON([i,1], false),'[{"re":0,"im":1},{"re":1,"im":0}]'); %!test ## test complex number 2D array %! assert(toJSON([i 1;2 i*3],true),'{"re":[[0,1],[2,0]],"im":[[1,0],[0,3]]}'); %!test ## struct with complex number %! assert(toJSON(struct('a',1+i,'b',3),true), '{"a":{"re":1,"im":1},"b":3}'); %!test ## struct ARRAY with complex number %! json = toJSON(struct('a',{1;i},'b',{5;2}),true); %! assert(json, '{"a":{"re":[1,0],"im":[0,1]},"b":[5,2]}'); %!test ## struct ARRAY with complex number COMPACT=false, %! json = toJSON(struct('a',{1;i},'b',{5;2}),false); %! assert(json, '[{"a":1,"b":5},{"a":{"re":0,"im":1},"b":2}]'); %!test ## struct ARRAY with complex number COMPACT=false, %! json = toJSON(struct('a',{[1 2i];[3 i]},'b',{5;2}),false); %! assert(json, '[{"a":[{"re":1,"im":0},{"re":0,"im":2}],"b":5},{"a":[{"re":3,"im":0},{"re":0,"im":1}],"b":2}]'); %!test ## ND struct array %! json=toJSON(struct('a',num2cell(reshape(1:8,2,2,2))),true); %! assert(json, '{"a":[[[1,3],[2,4]],[[5,7],[6,8]]]}'); %!test ## ND struct array COMPACT=false, %! json=toJSON(struct('a',num2cell(reshape(1:8,2,2,2))),false); %! assert(json, '[[[{"a":1},{"a":3}],[{"a":2},{"a":4}]],[[{"a":5},{"a":7}],[{"a":6},{"a":8}]]]'); %!test ## inline function %! assert(toJSON(@sin),'"@@(x) sin(x)"') %! assert(toJSON(@(a,b)a+b+c),'"@@(a, b) a + b + c"') %# struct with java object %!testif HAVE_JAVA %! if (usejava ("jvm")) %! obj = javaObject ("java.math.BigDecimal", 1.0); %! assert(toJSON(struct('a',obj)), '{"a":"[java.math.BigDecimal]"}'); %! endif %!test ## structure array DEFAULT COMPACT %! s = struct("a",{3.125;3.125}); %! assert(toJSON(s),'[{"a":3.125},{"a":3.125}]') %!test %% jsondecode's a big test %! var1 = struct ('para', ['A meta-markup language, used to create ' ... %! 'markup languages such as DocBook.'], ... %! 'GlossSeeAlso', {{'GML'; 'XML'}}); %! var2 = struct ('ID', 'SGML', 'SortAs', 'SGML', ... %! 'GlossTerm', 'Standard Generalized Markup Language', ... %! 'Acronym', 'SGML', 'Abbrev', 'ISO 8879:1986', ... %! 'GlossDef', var1, 'GlossSee', 'markup'); %! data = struct ('glossary', ... %! struct ('title', 'example glossary', ... %! 'GlossDiv', struct ('title', 'S', ... %! 'GlossList', ... %! struct ('GlossEntry', var2)))); %! exp = ['{' , ... %! '"glossary":{', ... %! '"title":"example glossary",', ... %! '"GlossDiv":{', ... %! '"title":"S",', ... %! '"GlossList":{', ... %! '"GlossEntry":{', ... %! '"ID":"SGML",', ... %! '"SortAs":"SGML",', ... %! '"GlossTerm":"Standard Generalized Markup Language",', ... %! '"Acronym":"SGML",', ... %! '"Abbrev":"ISO 8879:1986",', ... %! '"GlossDef":{', ... %! '"para":"A meta-markup language, ', ... %! 'used to create markup languages such as DocBook.",', ... %! '"GlossSeeAlso":["GML","XML"]', ... %! '},', ... %! '"GlossSee":"markup"', ... %! '}', ... %! '}', ... %! '}', ... %! '}', ... %! '}']; %! assert (toJSON (data), exp); %!test %% jsondecode's another big Test %! var1 = struct ('id', {0; 1; 2}, 'name', {'Collins'; 'Hays'; 'Griffin'}); %! var2 = struct ('id', {0; 1; 2}, 'name', {'Osborn'; 'Mcdowell'; 'Jewel'}); %! var3 = struct ('id', {0; 1; 2}, 'name', {'Socorro'; 'Darla'; 'Leanne'}); %! data = struct (... %! 'x_id', {'5ee28980fc9ab3'; '5ee28980dd7250'; '5ee289802422ac'}, ... %! 'index', {0; 1; 2}, ... %! 'guid', {'b229d1de-f94a'; '39cee338-01fb'; '3db8d55a-663e'}, ... %! 'latitude', {-17.124067; 13.205994; -35.453456}, ... %! 'longitude', {-61.161831; -37.276231; 14.080287}, ... %! 'friends', {var1; var2; var3}); %! exp = ['[', ... %! '{', ... %! '"x_id":"5ee28980fc9ab3",', ... %! '"index":0,', ... %! '"guid":"b229d1de-f94a",', ... %! '"latitude":-17.124067,', ... %! '"longitude":-61.161831,', ... %! '"friends":[', ... %! '{', ... %! '"id":0,', ... %! '"name":"Collins"', ... %! '},', ... %! '{', ... %! '"id":1,', ... %! '"name":"Hays"', ... %! '},', ... %! '{', ... %! '"id":2,', ... %! '"name":"Griffin"', ... %! '}', ... %! ']', ... %! '},', ... %! '{', ... %! '"x_id":"5ee28980dd7250",', ... %! '"index":1,', ... %! '"guid":"39cee338-01fb",', ... %! '"latitude":13.205994,', ... %! '"longitude":-37.276231,', ... %! '"friends":[', ... %! '{', ... %! '"id":0,', ... %! '"name":"Osborn"', ... %! '},', ... %! '{', ... %! '"id":1,', ... %! '"name":"Mcdowell"', ... %! '},', ... %! '{', ... %! '"id":2,', ... %! '"name":"Jewel"', ... %! '}', ... %! ']', ... %! '},', ... %! '{', ... %! '"x_id":"5ee289802422ac",', ... %! '"index":2,', ... %! '"guid":"3db8d55a-663e",', ... %! '"latitude":-35.453456,', ... %! '"longitude":14.080287,', ... %! '"friends":[', ... %! '{', ... %! '"id":0,', ... %! '"name":"Socorro"', ... %! '},', ... %! '{', ... %! '"id":1,', ... %! '"name":"Darla"', ... %! '},', ... %! '{', ... %! '"id":2,', ... %! '"name":"Leanne"', ... %! '}', ... %! ']', ... %! '}', ... %! ']']; %! assert (toJSON (data), exp); io-2.7.0/inst/PaxHeaders/dbfwrite.m0000644000000000000000000000006215004725440014151 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/dbfwrite.m0000644000175000017500000002017515004725440014472 0ustar00philipphilip## Copyright (C) 2015-2025 Philip Nienhuis ## Copyright (C) 2018-2025 Matthew Parkan ## ## 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 max. 10 characters; longer column names will ## be truncated). Each column must contain only one class of data, except of ## course the top entry (the column header). Integers interspersed in double ## type colums will be written as doubles. Data types that can be written are ## character (text string), numeric (integer and float, the latter with 6 ## decimal places), and logical. ## ## Output argument @var{status} is 1 if the file was written successfully, -1 if ## one or more data columns were skipped, 0 otherwise. If 0 the incomplete file ## will be deleted as well. ## ## Provisionally only dBase v. III+ files without memos can be written. ## ## @seealso{dbfread} ## @end deftypefn ## Authors: Philip Nienhuis ,whos ## Matthew Parkan ## 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("%d ", 1, numel (toolong))]; printf ("Applies to column(s): %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", "ieee-le"); if (fid < 0) error ("dbfwrite: could not open file %s\n", fname); endif unwind_protect ## Start writing header ## Provisionally assume dbase III+ w/o memos fwrite (fid, 3, "uint8"); ## Date of last update (YYMMDD), with YY the number of years since 1900 t = now; upd = datevec(t) - [1900, 0, 0, 0, 0, 0]; fwrite (fid, uint8(upd(1:3)), "uint8"); ## Number of records in the table 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"); RR = zeros (32, nfields, "uint8"); colskipped = 0; 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 ## Be strict on mixing char and numeric; this implies logicals ## interspersed in numeric type column won't be accepted either if (all (cellfun (@isnumeric, data(tr:end, ii), "uni", 1))) ## We're lax on interspersed integers, they'll be cast to double 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 (all (cellfun (@ischar, data(tr:end, ii), "uni", 1))) ftype = "C"; fldlng = max (cellfun (@(x) length(x), data(tr:end, ii))); elseif (all (cellfun (@islogical, (data(tr:end, ii)), "uni", 1))) ftype = "L"; fldlng = 1; else warning (["dbfwrite: heterogeneous data types in column %d ('%s'), ", ... "skipped.\n"], ii, data{1, ii}); RR(:, end) = []; nfields--; colskipped = 1; continue ; ## unwind_protect_cleanup takes care of closing & wiping file 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 RR(:, ii) = recdesc'; reclen += fldlng; fldlngs = [ fldlngs; sprintf("%d", fldlng) ]; endfor fwrite (fid, RR, "char"); ## 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"); ## Determine data record format. "Erased byte" is first char of format fmt = "\0"; for j = 1:nfields switch fldtyp(j) case "C" ## character txt = ["%", fldlngs{j}, "s"]; case "N" ## numeric txt = ["%" fldlngs{j} "d"]; case "L" ## logical txt = ["%", fldlngs{j}, "c"]; case "F" ## float txt = ["%" fldlngs{j} "f"]; case "D" ## date; currently inactive ## txt = sprintf (["%" fldlngs{jj} "s"], data{ii, jj}); otherwise end fmt = [fmt, txt]; ## append format end ## Convert boolean attributes to Y/N characters str_logical = {"N", "Y"}; for jj = find (fldtyp == "L") data(2:end, jj) = str_logical (double ([data{2:end, jj}] + 1))'; end ## Write data in ~100 MB chunks to avoid overflow. First find an optimal ## chunk size as max. nr. of records in a chunk= (= nr.of rows in data) chunk_sz = floor (1e8 / reclen); for ii=1 : chunk_sz : nrecs ## Reshape chunk of data matrix T = [data(ii+1:min (ii+chunk_sz, nrecs+1), :)'(:)]; blob = sprintf (fmt, T{:}); ## Write blob to file fwrite (fid, blob, "char"); endfor status = 1; unwind_protect_cleanup fclose (fid); if (! status) printf ("dbfwrite: removing incomplete file %s.\n", fname); unlink (fname); elseif (colskipped) status = -1; endif end_unwind_protect endfunction io-2.7.0/inst/PaxHeaders/fexist.m0000644000000000000000000000006215004725440013645 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/fexist.m0000644000175000017500000000501715004725440014164 0ustar00philipphilip## Copyright (C) 2008-2025 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 specified 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 ("fexist: 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 ("fexist: invalid access type spec: %s", c) endswitch endfor ex &= at; endif endif io-2.7.0/inst/PaxHeaders/xlsread.m0000644000000000000000000000006215004725440014005 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/xlsread.m0000644000175000017500000004636115004725440014333 0ustar00philipphilip## Copyright (C) 2009-2025 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}] = xlsread (@var{filename}, @var{wsh}, @var{range}, @var{interface}, @dots{}) ## @deftypefnx {Function File} [@var{numarr}, @var{txtarr}, @var{rawarr}, @var{limits}] = xlsread (@var{filename}, @var{wsh}, @var{range}, @var{options}, @dots{}) ## @deftypefnx {Function File} [@var{numarr}, @var{txtarr}, @var{rawarr}, @var{limits}] = xlsread (@var{filename}, @var{wsh}, @var{range}, @var{verbose}, @dots{}) ## @deftypefnx {Function File} [@var{numarr}, @var{txtarr}, @var{rawarr}, @var{extout}, @var{limits}] = xlsread (@var{filename}, @var{wsh}, @var{range}, @var{func_handle}, @dots{}) ## Read data from a spreadsheet file. ## ## Out of the box, xlsread can read data from .xlsx, .ods and .gnumeric ## spreadsheet files. For .xlsx it is relatively fast (when reading an ## entire sheet), for .ods quite slow and for .gnumeric it's the only ## choice. @* ## For reading from other file formats or for faster I/O, see below under ## "Spreadsheet I/O interfaces". ## ## @indentedblock ## ==========@ Input arguments@ ============= ## @end indentedblock ## ## Required parameter: ## ## @var{filename}: the spreadsheet file to read data from. If it does ## not contain any directory (i.e., full or relative path), the file is ## assumed to be in the current directory. The filename extension ## (e.g., .ods, .xlsx or .gnumeric) must be included in the file name; ## when using the UNO interface all file formats can be read that are ## supported by the locally installed OpenOffice.org or LibreOffice ## version (e.g., wk1, csv, dbf, .xlsm, etc.). The same holds for COM ## (MS-Excel) on Windows when the windows package is loaded. ## ## Optional parameters: ## ## @var{wsh} is either numerical or text; in the latter case it is ## case-sensitive and it may be max. 31 characters long for .xls and ## .xlsx formats; for .ods the limit is much larger (> 2000 chars). ## Note that in case of a numerical @var{wsh} this number refers to the ## position in the visible sheet stack, counted from the left in a ## spreadsheet program window. The default is numerical 1, i.e. ## corresponding to the leftmost sheet tab in the spreadsheet file. @* ## Note: xlsread ignores the concept of "active worksheet" (i.e., the ## worksheet shown if the file is opened in a spreadheet program). ## ## @var{range} is expected to be a regular spreadsheet range format, ## or "" (empty string, indicating all data in a worksheet). ## If no explicit range is specified the occupied cell range will have ## to be determined behind the scenes first; this can take some time for ## the native OCT and Java-based interfaces (but the results may be more ## reliable than that of UNO/LibreOffice or 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. ## ## @indentedblock ## If only the first argument @var{filename} 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 leftmost worksheet (not necessarily ## Sheet1). @* ## However, if only two arguments are specified and the second argument ## is either 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. ## @end indentedblock ## ## After these "regular" input arguments a number of optional arguments ## can be supplied in any desired order, but just one of each optional ## argument type: ## ## @table @asis ## @item @var{interface} (character or cellstr value) ## (see also further below under "Spreadsheet I/O interfaces".) ## @var{Interface} (often a three-character case-insensitive text string) ## can be used to override the automatic interface selection by xlsread ## out of the locally supported ones. ## ## For .ods I/O select one or more of "jod", "otk", "uno" or "oct" for ## @var{reqintf} (see help for xlsopen). @* ## For I/O to/from .xlsx files a value of 'com', 'poi', 'uno', or 'oct' ## can be specified. 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. If no interface was explicitly ## selected, Octave will select one automatically based on available ## external support software. Octave will keep using a selected ## interface during an Octave ession as long as no other interface is ## specified, even if in the mean time other support software becomes ## available (e.g., by loading a package). The other way round, ## removing external support software while the interface it is based ## on was selected, is not advised and might lead to unpredictable ## behavior. ## ## @item @var{func_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 4th output ## argument @var{extout} of xlsread; output argument @var{limits} ## becomes the 5th argument then (see below). ## ## @item @var{options} (struct value) ## xlsread's data output can be influenced to some extent by a number of ## other options. See OPTIONS in "help xls2oct" for an overview. ## ## @item @var{verbose} (logical value) ## To show which spreadsheet I/O interfaces have been found or which one ## is requested and active, enter true or a numeric 1 for @var{verbose}. ## The default value is false (no info about found interfaces). ## @end table ## ## @indentedblock ## ==========@ Output arguments@ ============= ## @end indentedblock ## ## 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). @* ## In case a function handle was specified (see above), @var{extout} ## will be the 4th output argument and @var{limits} the 5th, to be ## Matlab compatible with regard to function handle output. ## ## 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 the COM interface does the same for ## @var{rawarr}, so any returned array may turn out to be smaller than ## requested in @var{range}. Use the last return argument @var{LIMITS} ## for info on the cell ranges your data came from. ## If you don't want the output to be trimmed, specify an Options struct ## containing a field "strip_array" with contents 0 or false as extra ## input argument (see above). ## ## Remarks: @* ## -------- ## ## 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. ## ## xlsread is just a wrapper for a collection of scripts that find out ## the interface to be used (COM, Java/POI, Java/JOD, Java/OXS, Java/UNO, ## etc.), select one, and then do the actual reading. Function ## parsecell() is invoked to separate the numerical and text data from ## the raw output array. @* ## For each call to xlsread (1) the selected interface must be started, ## (2) the spreadsheet file read into memory, (3) the data read from the ## requested worksheet, and (4) the file closed, interface closed and ## memory released. When reading multiple ranges from the same file (in ## optionally multiple, separate worksheets) a significant speed boost ## can be obtained by invoking those scripts directly as in: @* ## ## xlsopen / xls2oct [/ parsecell] / ... / xlsclose @* ## ## That way it is also possible to mix reading and writing (or vice ## versa) - (except for the JXL interface): @* ## ## xlsopen / xls2oct [/ parsecell] / oct2xls / ... / xlsclose @* ## ## Beware: @* ## When using the COM interface, hidden Excel invocations may be kept ## running silently ("zombie invocations") if the spreadsheet file isn't ## closed correctly or in case of unexpected errors. For the UNO interface ## it can be worse - hidden LibreOffice invocations may even prevent Octave ## from closing. ## ## @indentedblock ## ==========@ Spreadheet I/O interfaces@ ============= ## @end indentedblock ## ## To be able to read from other file formats or for faster reading, ## external software is required. The connection to such external ## software is called an "interface". Below is an overview of the ## supported interfaces with the pertinent required external software ## together with a speed indication: ## @multitable {1} {12} {123567890123456789012345678901234567890} {1234567890} ## @item * @tab OCT @tab built-in, no external SW required @tab see above ## @item * @tab JOD @tab Java JRE and jOpendocument @tab fastest ## @item * @tab OTK @tab Java JRE and ODF Toolkit @tab slow ## @item * @tab UNO @tab Java JRE and LibreOffice or OpenOffice.org @tab ** ## @item * @tab COM @tab (Windows only) octave-forge windows package and MS-Excel @tab ** ## @item * @tab POI @tab Java JRE and Apache POI @tab intermediate ## @item * @tab JXL @tab Java JRE and JExcelAPI @tab intermediate ## @item * @tab OXS @tab Java JRE and OpenXLS @tab fastest ## @end multitable ## @indentedblock ## ** UNO needs to start up LibreOffice (or OpenOffice.org) behind the scenes ## which takes time. But once LibreOffice is loaded, reading is very fast, so ## for large .ods spreadsheet files it may be the fastest option. Similar ## holds for the COM interface, Excel and .xls/.xlsx files. ## @end indentedblock ## ## The table below offers an overview of the file formats currently ## supported by each interface. For each file format, xlsread ## automatically first tries the leftmost installed interface in the table. ## ## @multitable {1234567890123456789} {1} {1} {1234567} {1} {1} {1} {1} {1} {1} ## @item @tab -----------------------@ Interfaces@ ------------------- ## @headitem File extension @tab COM @tab POI @tab POI+OOXML @tab JXL @tab OXS @tab UNO @tab OTK @tab JOD @tab OCT ## @item .ods @tab @ ~ @tab @tab @tab @tab @tab @ + @tab @ + @tab @ + @tab @ + ## @item .sxc @tab @tab @tab @tab @tab @tab @ + @tab @tab @ R @tab ## @item .xls (Excel95) @tab @ R @tab @tab @tab @ R @tab @tab @ R @tab @tab @tab ## @item .xls (Excel97-2003) @tab @ + @tab @ + @tab @ + @tab @ + @tab @ + @tab @ + @tab @tab @tab ## @item .xlsx (Excel2007+) @tab @ ~ @tab @tab @ + @tab @tab (+) @tab @ + @tab @tab @tab @ + ## @item .xlsb, xlsm @tab @ ~ @tab @tab @tab @tab @ ? @tab @ + @tab @tab @tab @ R? ## @item .wk1 @tab @ + @tab @tab @tab @tab @tab @ R @tab @tab @tab ## @item .wks @tab @ + @tab @tab @tab @tab @tab @ R @tab @tab @tab ## @item .dbf @tab @tab @tab @tab @tab @tab @ + @tab @tab @tab ## @item .fods @tab @tab @tab @tab @tab @tab @ + @tab @tab @tab ## @item .uos @tab @tab @tab @tab @tab @tab @ + @tab @tab @tab ## @item .dif @tab @tab @tab @tab @tab @tab @ + @tab @tab @tab ## @item .csv @tab @ + @tab @tab @tab @tab @tab @ R @tab @tab @tab ## @item .gnumeric @tab @tab @tab @tab @tab @tab @tab @tab @tab @ + ## @end multitable ## ## ~ = dependent on LO/OOo/Excel version; @* + = read/write; @* R = only reading. @* ## (+) unfortunately OOXML support in the OpenXLS Java library itself is ## buggy, so OOXML support for OXS has been disabled (but it is implemented) ## ## The utility function chk_spreadsheet_support.m is useful for ## checking and setting up external support SW (e.g., adding relevant ## Java .jar libraries to the javaclasspath). ## ## @indentedblock ## ==============@ Examples@ ================= ## @end indentedblock ## ## Basic usage to get numerical data from a spreadsheet: ## ## @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 ## ## A little more involved: ## ## @example ## [An, Tn, Ra, limits] = xlsread ('Sales2009.ods', 'Third_sheet'); ## (which returns all data in worksheet 'Third_sheet' in file 'Sales2009.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 ## ## How to select an interface; in this example two: ## ## @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, OXS, UNO and OCT interfaces). ## @end example ## ## @seealso{xlswrite, xlsopen, xls2oct, parsecell, xlsclose, xlsfinfo, oct2xls} ## ## @end deftypefn ## Author. Philip Nienhuis ## Created. 2009-10-16 function [ numarr, txtarr, rawarr, varargout ] = xlsread (fn, wsh, datrange, varargin) rstatus = 0; if (nargin < 1) error ("xlsread: no input arguments specified\n") elseif (! ischar (fn)) error (["xlsread: 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 (strfind (wsh, ":" )) && ! isempty (wsh))) ## Apparently a worksheet specified datrange = ""; else ## Range specified datrange = wsh; wsh = 1; endif endif reqintf = hndl = opts = extout = []; ## Process additional input arguments beyond #3 verbose = false; 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})) ## Options struct. It will be validated in xls2oct, just convey here. opts = varargin{ii}; elseif ((isnumeric (varargin{ii}) && isreal (varargin{ii}) && ... isfinite (varargin{ii})) || islogical (varargin{ii})) ## Show spreadsheet I/O interfaces at first start verbose = logical (varargin{ii}); else error ("xlsread: illegal input arg. #%d", ii); endif endfor endif rawarr = txtarr = {}; numarr = varagout{1} = varargout{2} = []; ## 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") warning ("xlsread: invoking dlmread to read .csv file ..."); if (isempty (datrange)) numarr = dlmread (fn, ","); else numarr = dlmread (fn, ",", datrange); endif 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 & to be able ## to close stray Excel invocations ## Get pointer array to spreadsheet file xls_ok = 0; xls = xlsopen (fn, 0, reqintf, verbose); 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 varargout{1} = feval (hndl, numarr); catch warning (["xlsread: applying specified function handle ", ... "failed with error:\n'%s'\n"], lasterr); varargout{1} = []; end_try_catch varargout{2} = lims; else varargout{1} = lims; endif endif endif unwind_protect_cleanup ## Close spreadsheet file if (xls_ok) xls = xlsclose (xls); endif end_unwind_protect endif endfunction io-2.7.0/inst/PaxHeaders/xls2oct.m0000644000000000000000000000006215004725440013741 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/xls2oct.m0000644000175000017500000002635415004725440014267 0ustar00philipphilip## Copyright (C) 2009-2025 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 a spreadsheet file pointed to in struct @var{xls}. ## ## Spreadsheet file pointer @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; for .xlsx and .xls formats it may be max. 31 characters ## long. Note that in case of a numerical @var{wsh} this number refers to ## the position in the total sheet stack, counted from the left in a ## spreadsheet program window. The default is numerical 1, i.e. corresponding ## to the leftmost sheet tab in the spreadsheet 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 or is specified as an empty string ## 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 inferred 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 latter ## if at all present in th spreadsheet). 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 utility function parsecell() to separate numeric and text values from ## @var{rawarr}. ## ## Optional return argument @var{xls} contains the pointer struct. If any ## data were 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 xlsx/.xls files 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 depend on ## interface and version of the support SW. ## Be aware that the COM interface trims @var{rawarr} from empty outer rows & ## columns, so a 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 "Automatic calculation" settings when the spreadsheet was saved. ## ## When reading from merged cells, all array elements NOT corresponding ## to the leftmost or upper spreadsheet cell will be treated as if the ## "corresponding" spreadsheet cells are empty. ## ## 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 ("xls2oct: file ptr struct expected for argument #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 ("xls2oct: invalid xls file pointer struct\n"); endif ## Check worksheet ptr if (! (ischar (wsh) || isnumeric (wsh))) error ("xls2oct: 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 ("xls2oct: 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 ("xls2oct: structure expected for arg #4 (options)\n"); endif ## Select the proper interfaces switch upper (xls.xtype) case "COM" ## Call Excel thru COM / ActiveX server [rawarr, xls, rstatus] = __COM_spsh2oct__ (xls, wsh, datrange, spsh_opts); case "JOD" ## Read ods file tru Java & jOpenDocument. First check for formula support if ((xls.odfvsn < 4) && spsh_opts.formulas_as_text) ## Not supported in jOpenDucument < 1.3 warning (["xls2oct: option 'formulas_as_text' not supported\n", ... "in jOpenDocument < 1.3; please upgrade. Option ignored.\n"]); spsh_opts.formulas_as_text = 0; endif [rawarr, xls, rstatus] = __JOD_spsh2oct__ (xls, wsh, datrange, spsh_opts); case "JXL" ## Read xls file thru JExcelAPI [rawarr, xls, rstatus] = __JXL_spsh2oct__ (xls, wsh, datrange, spsh_opts); case "OTK" ## Read ods file tru Java & ODF toolkit switch xls.odfvsn case "0.7.5" [rawarr, xls, rstatus] = __OTK_ods2oct__ (xls, wsh, datrange, spsh_opts); case {"0.8.6", "0.8.7", "0.8.8", "0.10.0", "0.11.0", "0.12.0"} [rawarr, xls, rstatus] = __OTK_spsh2oct__ (xls, wsh, datrange, spsh_opts); otherwise error ("xls2oct: unsupported odfdom version or invalid ods file pointer.\n"); endswitch [rawarr, xls, rstatus] = __OTK_spsh2oct__ (xls, wsh, datrange, spsh_opts); case "OXS" ## Read xls file thru OpenXLS [rawarr, xls, rstatus] = __OXS_spsh2oct__ (xls, wsh, datrange, spsh_opts); case "POI" ## Read xls file thru Java POI [rawarr, xls, rstatus] = __POI_spsh2oct__ (xls, wsh, datrange, spsh_opts); case "UNO" ## Read xls file thru OpenOffice.org UNO (Java) bridge [rawarr, xls, rstatus] = __UNO_spsh2oct__ (xls, wsh, datrange, spsh_opts); case "OCT" ## Read xls file thru 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: 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), """, '"'); otherwise error (sprintf ("xls2oct: unknown Excel .xls interface - %s.\n", xls.xtype)); endswitch ## 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.7.0/inst/PaxHeaders/io_testscript.m0000644000000000000000000000006215004725440015236 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/io_testscript.m0000644000175000017500000002122115004725440015550 0ustar00philipphilip## Copyright (C) 2012-2025 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{rslts}] =} io_testscript (@var{intf1}) ## @deftypefnx {Function File} {@var{rslts}] =} io_testscript (@var{intf1}, @var{fname}) ## @deftypefnx {Function File} {@var{rslts}] =} io_testscript (@var{intf1}, @var{fname}, @var{intf2}) ## @deftypefnx {Function File} {@var{rslts}] =} io_testscript (@var{intf1}, @var{fname}, @var{intf2}, @var{verbose}) ## Try to check proper operation of spreadsheet I/O scripts using interface ## @var{intf1}. ## ## @var{intf1} can be one of COM, JOD, JXL, OCT, OTK, OXS, POI, or UNO. 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 ## depending on @var{intf1} one of "io-test.xlsx", "io-test.xls" or ## "io-test.ods" 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. ## ## If @var{verbose} is supplied with a value of true or 1 the used interface ## is written to the screen. ## ## The tests are primarily meant to be run interactively. For automated tests ## (e.g., test_spsh.m) optional output argument @var{rslts} is supplied. The ## results of all test steps are printed on the terminal. ## ## @seealso{test_spsh} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2012-02-25 function rslts = io_testscript (intf, fname="io-test.xlsx", intf2=[], verbose=false) printf ("\nTesting interface %s using file %s...", upper (intf), fname); isuno = false; dly = 0.01; ## If no intf2 is supplied, write with intf1 if (isempty (intf2)) intf2 = intf; endif ## .xlsx is default filename extension except JOD/OTK (.ods) and JXL/POI (.xls) if (strcmpi (intf, "jod") || strcmpi (intf, "otk")) fname = "io_test.ods"; elseif (strcmpi (intf, "jxl") || strcmpi (intf, "oxs")) fname = "io-test.xls"; 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\n 1. Initialize arrays..."); arr1 = [NA 1 2; NaN 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..."); xlswrite (fname, {""}, "EmptySheet", "b4", intf2, verbose); if (isuno) pause (dly); endif ## 3. Add data to test sheet printf ("\n 3. Add data to test sheet..."); xlswrite (fname, arr1, "Testsheet", "b2:d3", intf2, verbose); if (isuno) pause (dly); endif xlswrite (fname, arr2, "Testsheet", "d4:z20", intf2, verbose); 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..."); xlswrite (fname, [1], "JustOne", "A1", intf2, verbose); if (isuno) pause (dly); endif ## 5. Get sheet info & find sheet with data and data range printf ("\n 5. Explore sheet info..."); [~, shts] = xlsfinfo (fname, intf2, verbose); if (isuno) pause (dly); endif shnr = find (strcmp ("Testsheet", shts(:, 1))); ## Note case! if (isempty (shnr)) printf ("\nWorksheet 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..."); [num, txt, raw, lims] = xlsread (fname, shnr, crange, intf2, verbose); if (isuno) pause (dly); endif ## First check: has anything been read at all? if (isempty (raw)) printf ("\nNo data at all have been read... test failed.\n"); return elseif (isempty (num)) printf ("\nNo numeric data have been read... test failed.\n"); return elseif (isempty (txt)) printf ("\nNo 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..."); 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..."); opts.formulas_as_text = 1; xls = xlsopen (fname, 0, intf2, verbose); 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):"); 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 ("\n ...OK, formula recovered ('%s').", 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.7.0/inst/PaxHeaders/odsopen.m0000644000000000000000000000006215004725440014012 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/odsopen.m0000644000175000017500000000250715004725440014332 0ustar00philipphilip## Copyright (C) 2009-2025 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} = 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 contents of a spreadsheet file. ## ## For more info see the help for xlsopen.m. ## ## odsopen.m is deprecated. Currently it is a mere wrapper for xlsopen.m ## ## @seealso{xlsopen} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-12-13 function [ ods ] = odsopen (varargin) ods = xlsopen (varargin{:}); endfunction io-2.7.0/inst/PaxHeaders/xmlread.m0000644000000000000000000000006215004725440013777 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/xmlread.m0000644000175000017500000000675115004725440014324 0ustar00philipphilip## Copyright (C) 2015-2025 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.7.0/inst/PaxHeaders/utf82unicode.m0000644000000000000000000000006215004725440014662 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/utf82unicode.m0000644000175000017500000000462715004725440015207 0ustar00philipphilip## Copyright (C) 2018-2025 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 from UTF-8 encoded strings @var{istr} to Unicode codepoints @var{ustr}. ## ## UTF-8 characters with more than 2 bytes are dropped since Octave does not ## support characters >255. This means that only the ISO 8859-1 (Latin-1) ## subset of Unicode can be mapped correctly. ## ## 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 endfunction io-2.7.0/inst/PaxHeaders/chk_spreadsheet_support.m0000644000000000000000000000006215004725440017273 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/chk_spreadsheet_support.m0000644000175000017500000005676715004725440017634 0ustar00philipphilip## Copyright (C) 2009-2025 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 ## @item 'Windows': C:/Program Files/OpenOffice.org or
## C:/Program Files (X86)/LibreOffice ## ## @item '*nix': /usr/lib/ooo or /opt/libreoffice ## ## @item '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 javaclasspath entries; if @var{debug_level} < 2 report each ## individual removed entry. ## @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 ## FIXME Only the first if clause can be retained and the rest of the elseif dropped ## once io depends on Octave >= 6.0.0. See bug #47480, comments #22 and #25 if (compare_versions (OCTAVE_VERSION, "6.0.0", ">=")) tmp = javachk ("jvm"); HAVE_JAVA = isempty (tmp) || ... isempty (strfind (lower (tmp.identifier), "java-not-supported")); else HAVE_JAVA = __have_feature__ ("JAVA"); endif 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, maybe Java's bitness doesn't match Octave's.\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 ("\nAll Java-based interfaces (save UNO) fully supported.\n\n"); else printf ("\nSome 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 thru 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 ("\nSome 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 ("chk_spreadsheet_support:\nWrong 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.7.0/inst/PaxHeaders/dbfread.m0000644000000000000000000000006215004725440013732 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/dbfread.m0000644000175000017500000003377715004725440014267 0ustar00philipphilip## Copyright (C) 2014-2025 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} entries can be supplied in any ## order, yet the returned data column order matches that of the columns order ## in the dbase file. Requested column names that don't exist in the .dbf ## file are simply ignored. For dbase files containing multiple columns with ## the same name, specify a numeric or logical array to select columns to be ## returned. If @var{cols} is omitted or empty, 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. The ## default value of @var{re} is false. ## ## @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 comprise 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 recs = sort (recs); 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 (max (cols) < 2) ## Input as 0 or 1 ("logicals") cols = find (cols); if (isempty (cols)) cols = -1; endif endif elseif (islogical (cols)) cols = find (cols); elseif (ischar (cols)) cols = cellstr (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", "ieee-le"); 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 (isempty (recs)) txt = fread (fid, [recl, nrecs], "char=>char")'; else txt = fread (fid, [recl, recs(end)], "char=>char")'; 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 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 = sum ([dbf.fldlng]) + 1; ## Init output array column pointer scol = 0; for ii=numel (dbf) : -1 : 1 ## 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 = ismember (dbf(ii).fldnam, cols); 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 fld = txt(:, txtp-dbf(ii).fldlng+1 : txtp); switch (dbf(ii).fldtyp) case {"B", "G"} ## Block number into .dbt file, other than memo data(2:end, ii) = num2cell (str2double (fld)); case "C" ## Text data(2:end, ii) = 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, ii) = num2cell (dlf); case "L" ## Logical / boolean data(2:end, ii) = false; data(regexpi (fld, "[yt]")+1, ii) = true; case {"F", "N"} ## Numeric data(2:end, ii) = 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, ii) = 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(:, ii) = []; 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.data = dbf; endif endfunction io-2.7.0/inst/PaxHeaders/xlswrite.m0000644000000000000000000000006215004725440014224 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/xlswrite.m0000644000175000017500000002506415004725440014547 0ustar00philipphilip## Copyright (C) 2009-2025 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{range}) ## @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}, @dots{}) ## @deftypefnx {Function File} @var{rstatus} = xlswrite (@var{filename}, @var{arr}, @var{wsh}, @var{range}, @var{verbose}, @dots{}) ## Add data in 1D/2D array @var{arr} to a spreadsheet file. ## ## Out of the box, xlswrite can write data to .xlsx, .ods and .gnumeric ## spreadsheet files. For .xlsx it is relatively fast, for .ods quite ## slow and for .gnumeric it's the only choice. @* ## For writing to other file formats or for faster I/O, see the help for ## xlsread (under "Spreadsheet I/O interfaces"). ## ## Required parameters: @* ## -------------------- ## ## @var{filename} must be a valid spreadsheet 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. ## ## Optional parameters: @* ## -------------------- ## ## @var{wsh} can be a number or string (max. 31 chars for .xls and .xlsx, ## unlimited for .ods). In case of a not yet existing spreadsheet file, only ## one sheet will be created, used & named according to @var{wsh}. ## 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 worksheet (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 the file is opened in an external spreadsheet ## program) 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. @* ## 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 existing 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 determined from the data. ## ## @indentedblock ## 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:AMJ1048576 for .ods, 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 ":". ## To enter a range of just one cell specify e.g., "F3:F3". ## ## If @var{range} contains merged cells, only the elements of @var{arr} ## corresponding to the top or left spreadsheet 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". ## ## 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. ## @end indentedblock ## ## After @var{range} some optional arguments can be specified: ## ## @table @asis ## @item @var{reqintf} (character value) ## 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. The value of @var{reqintf} ## is case-insensitive. For an overview of interfaces and external ## support software, see the help for xlsread. @* ## 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. ## ## @item @var{verbose} (numerical or logical value) ## If a value of true (logical) or 1 (numerical) is specified, xlswrite ## will echo the found spreadsheet I/O interfaces when it is started for ## the first time in an Octave session or when @var{reqintf} was ## specified. If @var{verbose} is omitted or a value of false or 0 ## (zero) is specified (the default) no interface info is shown. ## @end table ## ## @var{rstatus} returns 1 if writing succeeded, 0 otherwise. ## ## xlswrite is a mere wrapper for various functions which find out what ## spreadsheet interface to use (COM, POI, JOD, etc), followed by ## separate functions for opening, writing to, and closing a spreadsheet ## file. For each call to xlswrite such an interface must be started ## and a spreadsheet file loaded and written. When writing to multiple ## ranges and/or sheets in the same spreadsheet file, or reading from ## and writing to the same spreadsheet file, a significant 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) ## ## or (mixing reading and writing in any desired order) ## ## (xlsopen / xls2oct / .... / octxls / .... / xlsclose) ## ## Example: ## ## @example ## status = xlswrite ... ## ('test4.xls', 'arr', 'Third_sheet', 'C3:AB40'); ## (which adds the contents of array arr (any type) to ## range C3: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, ## chk_spreadsheet_support} ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2009-10-16 function [ rstatus ] = xlswrite (filename, arr, arg3, arg4, varargin) rstatus = r_extnd = 0; ## Sanity checks if (nargin < 2) error ("xlswrite: 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; crange = setrange (filename, "A1"); elseif (nargin == 3) ## Find out whether 3rd argument = worksheet or range if (isnumeric (arg3) || (isempty (strfind (arg3, ":")) && ! isempty (arg3))) ## Apparently a worksheet specified wsh = arg3; crange = setrange (filename, "A1"); 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 reqintf = []; verbose = false; for ii=1:numel (varargin) if (ischar (varargin{ii})) reqintf = varargin{ii}; elseif ((isnumeric (varargin{ii}) && isreal (varargin{ii}) && ... isfinite (varargin{ii})) || islogical (varargin{ii})) verbose = varargin{ii}; else error ("xlswrite: unrecognized argument nr %d", ii); endif endfor if (isempty (wsh)) wsh = 1; endif if (isempty (crange) || r_extnd) if (r_extnd) tlcl = crange; else tlcl = "A1"; endif crange = setrange (filename, tlcl); 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 LibreOffice/Excel can be closed ## i.c.o. errors xls_ok = 0; xls = xlsopen (filename, 1, reqintf, verbose); if (! isempty (xls)) xls_ok = 1; [xls, rstatus] = oct2xls (arr(1:nr, 1:nc), xls, wsh, crange); endif unwind_protect_cleanup ## Use "force" flag to wipe pointer and scratch files if (xls_ok && ! isempty (xls)) xls = xlsclose (xls, "force"); endif end_unwind_protect if (! isempty (xls)) ## Apparently the file pointer couldn't be cleared, usually due to errors rstatus = 0; endif endfunction function crange = setrange (filename, tlcl) if (numel (filename) >= 6 && strcmpi (filename(end-4:end-1), ".xls")) ## OOXML has ridiculously large limits crange = ":XFD1048576"; elseif (numel (filename) >= 5 && strcmpi (filename(end-3:end), ".ods")) ## .ods limits as of LO > 3.3 crange = ":AMJ1048576"; else ## Regular xls limits crange = ":IV65536"; endif crange = [tlcl crange]; endfunction io-2.7.0/inst/PaxHeaders/getxmlnode.m0000644000000000000000000000006215004725440014511 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/getxmlnode.m0000644000175000017500000000633415004725440015033 0ustar00philipphilip## Copyright (C) 2013-2025 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.7.0/inst/PaxHeaders/templates0000644000000000000000000000013215004726004014101 xustar0030 mtime=1746119684.334811233 30 atime=1746119684.377810908 30 ctime=1746119684.377810908 io-2.7.0/inst/templates/0000755000175000017500000000000015004726004014474 5ustar00philipphilipio-2.7.0/inst/templates/PaxHeaders/template.ods0000644000000000000000000000006215004725440016505 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/templates/template.ods0000644000175000017500000001522315004725440017024 0ustar00philipphilipPKk6D'Configurations2/accelerator/current.xmlPKPKk6DConfigurations2/images/Bitmaps/PKw6DERz content.xmlWˮ0Uع$n-BB[v ?"iڿg켹MlRsxf>(: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.7.0/inst/templates/PaxHeaders/template.gnumeric0000644000000000000000000000006215004725440017531 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/templates/template.gnumeric0000644000175000017500000000104115004725440020041 0ustar00philipphilipΣ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.7.0/inst/templates/PaxHeaders/template.xlsx0000644000000000000000000000006215004725440016716 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/templates/template.xlsx0000644000175000017500000001630715004725440017241 0ustar00philipphilipPK!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~. ## -*- texinfo -*- ## @deftypefn {} {@var{obj} =} fromJSON (@var{str}) ## @deftypefnx {} {@var{obj} =} fromJSON (@var{str}, @var{sarray}) ## Convert a JSON string into a native Octave object. ## ## fromJSON especially strives to convert numerical JSON arrays into Octave ## vector, matrix or ND array. Special provisions are made to recognize ## +/-Inf, NaN and complex numbers, which are conventionally not permited in ## JSON strings. ## ## Input arguments: ## ## @itemize ## @item ## @var{str} is a JSON string. ## ## @item ## @var{sarray}, (default TRUE) logical value that determines how JSON member ## arrays are parsed. Setting it to FALSE is recommended for safer parsing of ## non-numerical, mixed-class or mixed-size arrays JSON payloads. ## ## Leave @var{sarray} set to TRUE for fast parsing of numerical JSON arrays and ## objects. Octave vectors, matrices, ND arrays and struct arrays are returned ## as much as possible, otherwise returned as a combination of vectors/matrices ## and cell arrays. ## ## Set @var{sarray} to FALSE if, with fast parsing, output does not match ## expections, particularly if @var{str} mainly comprises JSON objects/arrays ## with strings. All JSON member arrays are returned as (nested) Octave cell ## arrays. ## @end itemize ## ## Output: ## ## @itemize ## @item ## @var{obj} is a native Octave object. JSON number, logical, array, and ## object strings are converted to Octave numbers, logicals, vectors and ## structs, respectively. Quoted or unrecognizable JSON fragments are returned ## as NaN values. ## @end itemize ## ## Special numbers: ## ## The specification for JSON does not allow +/-Inf, NaN or complex numbers; ## nevertheless, provisions are made here to enable these important numbers: ## ## @itemize ## @item ## JSON number strings '+/-1e308' are rounded to +/-Inf. ## ## @item ## Unquoted JSON string 'null' is converted to NaN. ## ## @item ## JSON objects, or arrays thereof, with exclusive members "real" and "imag" ## (or "re" and "im") will be converted to Octave complex numbers, vectors or ## matrices, respectively. ## ## @example ## @w{e.g. '@{"re":3,"im":1@}' => 3 + 1i } ## @w{ '[1,@{"re":3,"im":1@}]' => [ 1 + 0i, 3 + 1i ] } ## @end example ## @end itemize ## ## @seealso{toJSON} ## @end deftypefn ## Author: Ketan M. Patel ## Created: 2019-06-01 function [obj] = fromJSON ( str=' ', SARRAY=[] ); ## Check if bytecode interpreter is implemented if (exist ("__vm_enable__", "builtin") == 5) ## FIXME The following statement invoking 'class' is a fragile trick to call ## __vm_enable__ from within a function. But it works ... class (vm = __vm_enable__ ()); if (vm) ## Yep, active. Bail out with a printf, not a warning. printf ("\n *****************************************************************\n"); printf ( [" | fromJSON.m is incompatible with the bytecode interpreter. |\n", ... " | To use fromJSON, disable bytecode interpreter with command: |\n", ... " | __vm_enable__ (0) |\n", ... " | ...and try again. |\n"]); printf ( " *****************************************************************\n\n"); return endif endif if ~( isnumeric(SARRAY) || isbool(SARRAY) ); _warn_("invalid SARRAY"); SARRAY = []; endif ## set defaults ischar(str) && str || (str=' '); ~isempty(SARRAY) || (SARRAY=true); ischar (str) && uint8(str(1)) > 126 && (str = str( find(str<127,1) : end )); # drop leading encoding chars wstate = warning('off',"Octave:num-to-str"); obj = _fromjson_(str,SARRAY); warning(wstate); endfunction function [obj, remain] = _fromjson_ ( str, SARRAY ); [btag, block, remain] = _get_block_(str); switch( btag ); case '['; obj = _to_array_ (block, SARRAY); case '{'; obj = _to_struct_ (block, SARRAY); case '"'; obj = _to_string_ (block, SARRAY); otherwise; obj = _to_number_ (block, SARRAY); endswitch remain = regexprep(remain,'^[\s,]*',''); #!!! keep this HERE, not in _get_block_ endfunction ## gets block quoted-string/array/object block from string ## this will work with single-quoted strings, but only double-quoted strings are safe function [btag, block, remain] = _get_block_ (str); [open, btag] = regexp(str,'[^\s,]','once','start','match'); switch( btag ); # find ALL bracket tag (open/close) positions case '['; idx = [strfind(str,'[') -strfind(str,']')]; # strfind is 100x faster than regexp case '{'; idx = [strfind(str,'{') -strfind(str,'}')]; case {'"',"'"}; idx = -strfind(str,btag); idx(1) *= -1; # all but first are closers btag = '"'; # regard single-quote as double-quote (lazy JSON) otherwise; [block,remain] = strtok(str(open:end),','); return; endswitch idx( '\' == str([1 abs(idx(2:end))-1]) ) = []; # exclude escaped-tags (e.g.'\[', '\{', '\"', etc) ## filter out double-quoted (exclusively) block tags ( btag ~= '"' && (q = strfind(str,'"') ) # find all double-quote marks && (q = q(str(q-1) ~= '\')) > 1 # discard \", stop if only single " remains && (idx = _bfilter_(idx, q)) ); # filter out quoted btags if ~( numel(idx) > 1 && ( close=-idx(2) ) > 0 ); # unless simple (non-nested) block... idx = idx([~,i] = sort(abs(idx))); # sort idx by abs(idx) if( ( ci=find(0 == cumsum(sign(idx)), 1) ) ); close = -idx(ci); else close = numel(str)+1; _warn_(btag,str); endif end block = str( open+1 : close-1 ); remain = str( close+1 : end ); endfunction function [arr] = _to_array_ ( str, SARRAY ); ok = SARRAY && ~( regexp(str,'\[\s*\[','once') # no ND array || regexp(str,':\s*[''"]','once') # no struct array with strings || strfind(str,'=') ); # no apparent assignment op if( ok ); arr = regexprep( _rep_(str, Inf), ',(?=\s*\[)',';'); # JSON to Octave array syntax if( strfind(str,'{') ); # JSON object arr = [ _lazyJSON_ "; arr=_deep_complex_([" _rep_(arr, struct) "])" ]; else # JSON numerical? array arr = [ "arr=[" arr "]" ]; endif eval([ arr "; ok = isnumeric(arr) || isstruct(arr);" ], "ok=false;"); endif if( ~ok ); # this can be slow, avoid getting here if possible arr = {}; while( str ); # grind thru string, one array element at a time [arr{end+1} str] = _fromjson_(str,SARRAY); endwhile; if( SARRAY ); switch numel(arr); case 0; arr = []; case 1; arr = arr{1}; otherwise; arr = _ndarray_(arr); endswitch endif endif endfunction function [obj] = _to_struct_ ( str, SARRAY ); obj = struct(); ## we're making this harder than needed in order to permit lazy JSON ## i.e. unquoted and single quote keys (but! start/end quote chars must match) while( ( q=regexp(str, '[^\s,:]', 'once','match') ) # detect key quote-char or empty str && ( m=regexp(str, _qrgx_(q), 'once','names') ).k ); # get key,val or fail [obj.(m.k) str] = _fromjson_(m.v, SARRAY); endwhile regexp(str,'[^\s]','once') && _warn_('}', str); obj = _complex_( obj ); # _deep_complex_ not necessary here endfunction function [str] = _to_string_ ( str, SARRAY ); if( SARRAY && (numel(str) > 2 && str(1:2) == '@') ); try str = str2func(str(2:end)); catch _warn_('@', str); end_try_catch; endif endfunction function [num] = _to_number_( str, SARRAY ); if( strfind(str,'=') ); # guard against assignment expr num = 'error()'; else num = ['num=[' _rep_(str,Inf) '];']; endif eval(num, ['_warn_("invalid frag",str); num=NaN;']); endfunction ##========================= helpers ======================= ## filter out quoted block tags function [idx] = _bfilter_(idx,q); qo = q(1:2:end-1)'; # open quote (ignore unclosed quote) qc = q(2:2:end)'; # close quote ai = abs(idx); idx( any(qo < ai & ai < qc,1) ) = []; # purge quoted block tags endfunction ## replace string frags according to set pattern function [str] = _rep_ ( str, pat ); if isstruct(pat); pat = {'{','struct(',':',',','}',')'}; else pat = {'null','NaN ','e308','e999','Infinity','Inf ',"\n",' '}; # keep empty spaces endif do str = strrep(str,pat{1:2},'overlaps',false); pat(1:2) = []; until isempty(pat); endfunction ## try to make ND array (either mat or cell) function [c] = _ndarray_ ( c ); sz = size(e = c{1}); t = class(e); if ~( ~ischar(e) && sz && cellfun(@(v)isa(v,t)&&size(v)==sz, c) ); return; elseif( isscalar(e) ); # try matrix conversion, ok to fail if not uniform class try c = [c{:}]; end; elseif( isvector(e) ); # cell array of mat or cell array c = reshape([c{:}], numel(e), numel(c)).'; else # make ND array index.type = "()"; index.subs = repmat({':'},1,ndims(e)+1); i = numel(c); do index.subs{end} = i; e = subsasgn(e,index,c{i}); until (--i) == 1; c = e; endif endfunction ## convert complex number struct DEEP WITHIN structure to complex number function [s] = _deep_complex_(s); if( isstruct(s) && isstruct( s=_complex_(s) ) ); vals = cellfun(@_deep_complex_, struct2cell(s), 'uniformoutput', false); s = cell2struct(vals, __fieldnames__(s)); endif endfunction ## convert complex number struct to complex number function [s] = _complex_ ( s ); if( numel( keys=__fieldnames__(s) ) == 2 && ( ismember( k={'real','imag'}, keys) || ismember( k={'re','im'}, keys) ) && isnumeric( re=[s.(k{1})] ) && isnumeric( im=[s.(k{2})] ) && size_equal(re,im) ); s = reshape( complex(re,im), ifelse(isscalar(s), size(re), size(s)) ); endif endfunction ## for max conversion speeed, gaurd against common lazy JSON (unquoted keys) function [str] = _lazyJSON_ ( ); str = 'x="x";y="y";z="z";real=re="re";imag=im="im";r="r";rho="rho";theta="theta";phi="phi";'; endfunction ## compute regexp pattern for JSON object key (quoted or unquoted) function [rgx] = _qrgx_(q); sum(q=="\"'") || (q=''); rgx = ['[\s,]*' q '(?.+?)' q '\s*:\s*(?[^\s].*)' ]; endfunction function [out] = _warn_ ( msg, frag='' ); if( numel(msg) == 1 ); switch(msg); case '{'; msg = "unclosed object"; case '['; msg = "unclosed array"; case '"'; msg = "unclosed quote"; case '}'; msg = "malformed structure"; regexp(lastwarn,'unclosed') || ( frag=[frag '}'] ); case '@'; msg = "invalid inline func string"; otherwise endswitch endif frag && ( frag=["`" frag "`"] ); numel(frag)>40 && (frag = [frag(1:27) ' ... ' frag(end-27:end)]); out = warning("fromJSON: %s %s\n",msg,frag); endfunction ################################################################################ ############################### BIST ####################################### ################################################################################ ##%!test ## input validation ##%! assert( fromJSON(),[]); % ok, reference ##%!warning fromJSON('',struct); ##%! ## ##%!test ## invalid input validation ##%! bad = {4,{},@sin,struct(),'',false,0,[1,2,3]}; ##%! assert(fromJSON(4), []); ##%! assert(fromJSON({}), []); ##%! assert(fromJSON(@sin), []); ##%! assert(fromJSON(struct), []); ##%! assert(fromJSON(false), []); ##%! assert(fromJSON([1,2,3]),[]); ## ################# JSON number BIST ##################### ## ##%!test ## number ##%! assert( fromJSON('4'),4) ## ##%!test ## number string ##%! assert( fromJSON('"string"'),"string") ## ##%!test ## bool ##%! assert( fromJSON('true'),true) ## ##%!test ## round up to Inf ##%! assert( fromJSON('1e308'), Inf) ##%! assert( fromJSON('-1e308'), -Inf) ## ##%!test ## do NOT round up to Inf ##%! assert( fromJSON('1e307'), 1e307) ##%! assert( fromJSON('-1e307'), -1e307) ## ##%!test ## automatically parse as Inf ##%! assert( fromJSON('1e309'), Inf) ##%! assert( fromJSON('-1e309') -Inf) ##%! assert( fromJSON('1e999'), Inf) ##%! assert( fromJSON('-1e999'), -Inf) ## ##%!test ## null ##%! assert( fromJSON( 'null' ),NaN) ## ##%!test ## in case JSON spec commitee gets head out of ass ##%! assert( fromJSON('Inf'), Inf) ##%! assert( fromJSON('-Inf'), -Inf) ##%! assert( fromJSON('Infinity'), Inf) ##%! assert( fromJSON('-Infinity'), -Inf) ##%! assert( fromJSON('NaN'), NaN) ##%! assert( fromJSON('nan'), NaN) ## ##%!test ## quoted null,Inf,etc (guard against false-positive, leave alone) ##%! assert( fromJSON('"null"'),"null") ##%! assert( fromJSON('"Inf"'),"Inf") ##%! assert( fromJSON('"1e308"'),"1e308") ## ##%!test ## all of the above in array form ##%! assert( fromJSON('[1,1e308,Inf,-Infinity,NaN,nan,null]'), ##%! [1 Inf Inf -Inf NaN NaN,NaN]) ## ##%!test ## garbage (non-quoted, meaningless string) ##%!warning assert( fromJSON('garbage'), NaN) ## ################# JSON aray BIST ##################### ## ##%!test ## empty array ##%! assert( fromJSON('[]',true),[]); ## ##%!test ## empty cell array ##%! assert( fromJSON('[]',false),{}); ## ##%!test ## single element array ##%! assert( fromJSON('[1]',true),1); ##%! assert( fromJSON('[1]',false),{1}); ## ##%!test ## JSON array to Octave vector ##%! assert( fromJSON('[1,2,3,4]', true), ##%! [1 2 3 4]) ## ##%!test ## JSON array to Octave vector ##%! assert( fromJSON('[[1],[2],[3],[4]]', true), ##%! [1;2;3;4]) ## ##%!test ## JSON array to Octave cell array ##%! assert( fromJSON('[1,2,3,4]', false), ##%! {1 2 3 4}) ## ##%!test ## JSON array to Octave vector ##%! assert( fromJSON('[[1],[2],[3],[4]]', false), ##%! {{1},{2},{3},{4}}) ## ##%!test ## JSON nested array to Octave matrix ##%! assert( fromJSON('[[1,2],[3,4]]', true), ##%! [1 2;3 4]) ## ##%!test ## JSON nested array to nested Octave cell array ##%! assert( fromJSON('[[1,2],[3,4]]', false), ##%! {{1 2},{3 4}}) ## ##%!test ## JSON nested array to Octave ND array ##%! assert( fromJSON('[[[1,3,5],[2,4,6]],[[7,9,11],[8,10,12]]]', true), ##%! reshape(1:12,2,3,2)); ## ##%!test ## numerical ND cell array ##%! assert( fromJSON('[[[1,3,5],[2,4,6]],[[7,9,11],[8,10,12]]]', false), ##%! {{{1,3,5},{2,4,6}},{{7,9,11},{8,10,12}}}); ## ##%!test ## test default SARRAY ##%! assert( fromJSON('[[1,2],[3,4]]'), ##%! fromJSON('[[1,2],[3,4]]',true)) ## ##%!test ## bool array ##%! assert( fromJSON('[true,false,false,true]'), ##%! !![1 0 0 1]) ## ##%!test ## mixed bool and number array ##%! assert( fromJSON("[[true,3],[false,1]]"), ##%! [1 3;0 1]) ## ##%!test ## more N numerical ND array ##%! json = "[[[[[1,3],[2,4]],[[5,7],[6,8]]],[[[11,13],[12,14]],[[15,17],[16,18]]]],[[[[21,23],[22,24]],[[25,27],[26,28]]],[[[31,33],[32,34]],[[35,37],[36,38]]]]]"; ##%! assert( fromJSON(json), ##%! reshape([1:8 11:18 21:28 31:38],2,2,2,2,2)); ## ##%!test ## mismatch nested array (mix of scalar and cell array) ##%! assert( fromJSON('[[1,2,3,4,5],[1,2]]', true), ##%! {[1 2 3 4 5] [1 2]}) ## ##%!test ## more mismatched nested array ##%! assert( fromJSON('[1,2,3,[2,3]]'), ##%! {1,2,3,[2,3]}) ## ##%!test ## array of numerical array and mixed-class array ##%! assert( fromJSON('[[1,2,3,"a"],[2,3,4,4]]', true), ##%! {{1 2 3 "a"},[2 3 4 4]}) ## ##%!test ## mixed-class array ##%! assert( fromJSON('[["a",2,3],[4,"b",5]]', true), ##%! {'a' 2 3; 4 'b' 5}); ## ##%!test ## mismatch nested array, safe parsing to cell array ##%! assert( fromJSON('[[1,2,3,4,5],[1,2]]', false), ##%! {{1 2 3 4 5},{1 2}}) ## ##%!test ## mixed-class array, safe parsing to cell array ##%! assert( fromJSON('[["a",2,3],[4,"b",5]]', false), ##%! {{'a' 2 3},{4 'b' 5}} ); ## ##%!test ## more N numerical ND array ##%! json = "[[[[[1,3],[2,4]],[[5,7],[6,8]]],[[[11,13],[12,14]],[[15,17],[16,18]]]],[[[[21,23],[22,24]],[[25,27],[26,28]]],[[[31,33],[32,34]],[[35,37],[36,38]]]]]"; ##%! json = regexprep(json,'(\d+)','"$1"'); % turn it input JSON array of strings ##%! c = cellfun(@num2str,num2cell(reshape([1:8 11:18 21:28 31:38],2,2,2,2,2)), 'uniformoutput', false); ##%! assert( fromJSON(json),c); ## ##%!test ## JSON-like: with non-JSON, Octave, numerical notation (bonus feature) ##%! assert( fromJSON('[Inf,-Inf,NaN,2i,pi,e]'), ##%! [Inf,-Inf,NaN,2*i,pi,e],1e-15); ## ## ##%!test ## beautified JSON vector ##%! assert( fromJSON("\n[1,\n2\n]\n",true), ##%! [1,2]) ## ##%! assert( fromJSON("\n[1,\n2\n]\n",false), ##%! {1,2}) ## ##%!test ## beautified JSON array ##%! assert( fromJSON("[\n [\n 1,\n 2\n ],\n [\n 3,\n 4\n ]\n]",true), ##%! [[1 2];[3 4]]) ## ##%!test ## beautified JSON array ##%! assert( fromJSON("[\n [\n 1,\n 2\n ],\n [\n 3,\n 4\n ]\n]",false), ##%! {{1,2},{3,4}}) ## ##%!test ## incomplete array ##%! warning('off','all'); ##%! assert( fromJSON("[1,2,3 "), ##%! [1,2,3]); ## ##%!test ## more incomplete array ##%! warning('off','all'); ##%! assert( fromJSON("[[1,2,3],[3"), ##%! {[1,2,3],[3]}); ## ##%!test ## string with whitespaces ##%! assert( fromJSON("\"te\nss df\t t\""), ##%! "te\nss df\t t") ## ##%!test ## char array ##%! assert( fromJSON('["a","b","c"]'), ##%! {'a','b','c'}) ## ##%!test ## array of string ##%! assert( fromJSON('["test","list","more"]'), ##%! {'test',"list","more"}) ## ##%!test ## escaped quote ##%! assert( fromJSON ('"tes\"t"'), ##%! 'tes\"t'); ## ##%!test ## escaped quote in array ##%! assert( fromJSON('["te\"t","list","more"]'), ##%! {'te\"t' 'list' 'more'}) ## ##%!test ## garbage in array ##%! warning('off','all'); ##%! assert( fromJSON('[1,garbage]'), [1,NaN]) ## ################# JSON object BIST ##################### ## ##%!test ## empty object to empty struct ##%! assert( fromJSON('{}',true), struct()) ##%! assert( fromJSON('{}',false),struct()) ##%! assert( fromJSON('{ }',false),struct()) ## ##%!test ## struct to object ##%! assert( fromJSON('{"a":3,"b":5}',true), ##%! struct("a",3,"b",5)) ## ##%!test ## unclosed object ##%!warning assert(fromJSON('{a:3,b:4'),struct("a",3,"b",4)); ## ##%!test ## string with colons (guards against JSON object false postive) ##%! assert( fromJSON('["2012-11-12T10:35:32Z","2012-11-13T08:35:12Z"]'), ##%! {"2012-11-12T10:35:32Z", "2012-11-13T08:35:12Z"}); ## ##%!test ## string with {} (guards against JSON object false postive) ##%! assert( fromJSON('["some text {hello:3}","more text \"{hello:3}\""]'), ##%! {'some text {hello:3}', 'more text \"{hello:3}\"'}); ## ##%!test ## lazy JSON object (unquoted and single-quote keys) ##%! assert( fromJSON("{a:3,'b':5}",true), ##%! struct("a",3,"b",5)) ## ##%!test ## bad (but passable) lazy JSON object, unquoted-key with quote char at end ##%! assert( fromJSON("{a':3,b\":5}",true), ##%! struct("a'",3,'b"',5)) ## ##%!test ## bad (failing) JSON object (mismatched or unclosed quoted-keys) ##%!warning assert( fromJSON("{'a :3}"), struct()); ##%!warning assert( fromJSON("{'a\":3}"), struct()); ##%!warning assert( fromJSON("{\"a :3}"), struct()); ##%!warning assert( fromJSON("{\"a':3}"), struct()); ## ##%!test ## keys (quoted and unquoted) with whitespace ##%! assert( fromJSON('{"a":3," key with space ": 4, more white space : 40}'), ##%! struct("a",3," key with space ",4,"more white space",40)) ## ##%!test ## object with duplicate key ##%! assert( fromJSON('{"a":3,"a":5}'), ##%! struct("a",5)) ## ##%!test ## empty object key-val ##%! assert( fromJSON('{a:3,,, , b :5}'), ##%! struct("a",3,"b",5)) ## ##%!test ## object with object ##%! assert( fromJSON('{a:{b:2}}', true), ##%! struct('a',struct('b',2))); ## ##%!test ## object with object with object ##%! assert( fromJSON('{a:{b:{c:3,d:4},e:5}}', true), ##%! struct('a',struct('b',struct('c',3,'d',4),'e',5))); ## ##%!test ## object with array to struct with array ##%! assert( fromJSON('{a:[1,2,3,4]}', true), ##%! struct('a',[1 2 3 4])); ## ##%!test ## object with array to struct with cell array ##%! assert( fromJSON('{a:[1,2,3,4]}', false), ##%! struct('a',{{1 2 3 4}})); ## ##%!test ## array of objects to struct array ##%! assert( fromJSON('[{a:1},{a:2},{a:3},{a:4}]',true), ##%! struct('a',{1 2 3 4})); ## ##%!test ## array of objects to cell array ##%! assert( fromJSON('[{a:1},{a:2},{a:3},{a:4}]',false), ##%! num2cell(struct('a',{1 2 3 4}))); ## ##%!test ## object with 2x2 array to struct with 2x2 array ##%! assert( fromJSON('{a:[[1,3],[2,4]]}', true), ##%! struct('a',[1 3;2 4])); ## ##%!test ## object with 2x2 array to struct with cell array ##%! assert( fromJSON('{a:[[1,3],[2,4]]}', false), ##%! struct('a',{{{1,3},{2,4}}})); ## ##%!test ## 2x2 array of object to struct array ##%! assert( fromJSON('[[{a:1},{a:2}],[{a:3},{a:4}]]',true), ##%! struct('a',{1 2;3 4})); ## ##%!test ## 2x2 array of object to cell array ##%! assert( fromJSON('[[{a:1},{a:2}],[{a:3},{a:4}]]',false), ##%! { num2cell(struct('a',{1 2})), num2cell(struct('a',{3 4}))} ); ## ##%!test ## **nested** object with array to struct array ##%! assert( fromJSON('{"a":{"b":[1,2,3]}}',true ), ##%! struct("a",num2cell(struct("b",[1,2,3])))) % <== struct array ## ##%!test ## **nested** object with array to cell array ##%! assert( fromJSON('{"a":{"b":[1,2,3]}}',false), ##%! struct("a",struct("b",{{1,2,3}}))) % <== struct with array b ## ##%!test ## object with mixed-size arrays (will not honor SARRAY=true) ##%! assert( fromJSON('{"a":[1,2],"b":[3,4,5]}',true), ##%! struct("a",[1,2],"b",[3,4,5])) ## ##%!test ## object with number and string (guard against turing string into char array) ##%! assert( fromJSON('{"a":1,"b":"hello"}',true), ##%! struct("a",1,"b","hello")) ## ##%!test ## object with empty array (gaurd against returning empty struct array) ##%! assert( fromJSON('{"a":3,"b":[]}',true), ##%! struct("a",3,"b",[])) ## ##%!test ## object with colon value ##%! assert( fromJSON('{"time": "10:35:00"}'), ##%! struct("time", "10:35:00")); ## ##%!test ## object with colon key ##%! assert( fromJSON('{"ti:me": "10:35:00", ":tricky:" : 4}'), ##%! struct("ti:me", "10:35:00",":tricky:",4)); ## ##%!test ## array of structure with value with colons ##%! assert( fromJSON('[{"time": "10:35"},{"time": "10:54"}]', true), ##%! struct("time", {"10:35","10:54"})); ## ##%!test ## array of structure with value with keys ##%! assert( fromJSON('[{"ti:me": "10:35"},{"ti:me": "10:54"}]', true), ##%! struct("ti:me", {"10:35","10:54"})); ## ##%!test ## incomplete struct ##%!warning assert( fromJSON('{a:3,b }', true), ##%! struct('a',3)); ## ##%!test ## incomplete struct ##%!warning assert( fromJSON('{a:3,b: }', true), ##%! struct('a',3)); ## ## ##%!test ## struct with mixed class array SARRAY=true ##%! assert( fromJSON('{"b":[1,2,{c:4}]}',true), ##%! struct('b',{{1,2,struct('c',4)}})); ## ##%!test ## struct with mixed class array SARRAY=false ##%! assert( fromJSON('{"b":[1,2,{c:4}]}',false), ##%! struct('b',{{1,2,struct('c',4)}})); ## ##%!test ## 2x2 array of struct ##%! assert( fromJSON('[[{a:1},{a:3}],[{a:2},{a:4}]]'), ##%! struct('a',{1 3;2 4})); ## ##%!test ## ND array of struct to ND struct array ##%! assert( fromJSON('[[[{a:1},{a:3}],[{a:2},{a:4}]],[[{a:11},{a:13}],[{a:12},{a:14}]]]'), ##%! struct('a',num2cell(reshape([1:4 11:14],2,2,2)))); ## ##%!test ## mixed array with struct ##%! assert( fromJSON('[2,{a:3,"b":5}]'), ##%! {2,struct("a",3,"b",5)}) ## ##%!test ## more mixed array with struct ##%! assert( fromJSON('[{a:3,"b":5},{a:3}]'), ##%! {struct("a",3,"b",5),struct("a",3)}) ## ##%!test ## garbage in struct ##%! warning('off','all'); ##%! assert( fromJSON('{a:garbage}'), struct('a', NaN)); ## ########### complex number JSON object BIST ################ ## ##%!test ## complex number object ##%! assert( fromJSON('{"re":3,"im":5}'), 3+5i); ##%! assert( fromJSON('{"real":3,"imag":5}'), 3+5i); ## ##%!test ## complex number lazy notation object ##%! assert( fromJSON('{re:3,im:5}'), 3+5i); ##%! assert( fromJSON('{real:3,imag:5}'), 3+5i); ## ##%!test ## fake complex number object ##%! assert( fromJSON('{"re": "hello","im":5}'), ##%! struct('re',"hello",'im',5)); ## ##%!test ## complex number in reverse order ##%! assert( fromJSON('{im:3,re:5}'), 5+3i); ## ##%!test ## complex with excess members ##%! assert( fromJSON('{im:3,re:5,re:7,im:10}'),7+10i); ## ##%!test ## complex number object with mismatch re/im and real/imag ##%! assert( fromJSON('{real:3,im:5}'), ##%! struct('real',3,'im',5)); ## ##%!test ## apparent complex number object with extra member ##%! assert( fromJSON('{re:3,im:5,t:3}'), ##%! struct('re',3,'im',5,'t',3)); ## ##%!test ## array of complex number object to scalar array of complex number ##%! assert( fromJSON('[{re:4,im:6},{re:5,im:7}]}',true), ##%! [4+6i,5+7i] ); ## ##%!test ## array of complex number object to cell array of complex number ##%! assert( fromJSON('[{re:4,im:6},{re:5,im:7}]}',false), ##%! {4+6i,5+7i} ); ## ##%!test ## complex number object with array to scalar array of complex number ##%! assert( fromJSON('{re:[4,5],im:[6,7]}',true), ##%! [4+6i,5+7i] ); ## ##%!test ## complex number object with array to struct with cell array ##%! assert( fromJSON('{re:[4,5],im:[6,7]}',false), ##%! struct("re",{{4,5}},"im",{{6,7}})); ## ##%!test ## complex number object with mismatch array sizes ##%! assert( fromJSON('{re:[4,5],im:[6]}',true), ##%! struct('re',[4,5],'im',6)); ## ##%!test ## complex number object with mismatch array sizes ##%! assert( fromJSON('{re:[4,5],im:[6]}',true), ##%! struct('re',[4,5],'im',6)); ## ##%!test ## bogus complex number object with mixed classed array ##%! assert( fromJSON('{re:[4,5],im:[6,"a"]}',true), ##%! struct('re',[4,5],'im',{{6,'a'}})); ## ##%!test ## array of bogus complex number object ##%! assert( fromJSON('[{re:4,im:6},{re:5,im:"a"}]',true), ##%! {4+6i,struct('re',5,'im','a')}); ## ##%!test ## complex number object with matrix ##%! assert( fromJSON('[{re:[4,5;0 2],im:[6,7;3 0]}]'), ##%! [4+6i,5+7i;3i 2]); ## ##%!test ## array of complex number object ##%! assert( fromJSON('[[{re:4,im:6},{re:1,im:0}],[{re:0,im:2}, {re:2,im:4}]]'), ##%! [4+6i 1;2i 2+4i]); ## ##%!test ## complex number object with ND array ##%! assert( fromJSON('{re:[[[1,1],[2,2]],[[3,3],[4,4]]],im:[[[1,1],[2,2]],[[3,3],[4,4]]]}', true), ##%! reshape( (1+i)*[1 2 1 2 3 4 3 4], 2,2,2)); ## ##%!test ## ND array of complex number objects ##%! assert( fromJSON('[[[{"re":1,"im":1},{"re":1,"im":1}],[{"re":2,"im":2},{"re":2,"im":2}]],[[{"re":3,"im":3},{"re":3,"im":3}],[{"re":4,"im":4},{"re":4,"im":4}]]]'), ##%! reshape( (1+i)*[1 2 1 2 3 4 3 4], 2,2,2)); ## ##%!test ## array of objects with complex number member ##%! assert( fromJSON('[{"a": {re:4, im:6}},{"a": {re:5,im:7}}]'), ##%! struct('a',{4+6i,5+7i}) ); ## ##%!test ## ND array objects with complex number members ##%! obj = struct('a',{4+6i,5+7i;4+6i,5+7i}); ##%! obj(:,:,2) = obj; ##%! assert( fromJSON('[[[{"a": {re:4, im:6}},{"a": {re:5,im:7}}],[{"a": {re:4, im:6}},{"a": {re:5,im:7}}]],[[{"a": {re:4, im:6}},{"a": {re:5,im:7}}],[{"a": {re:4, im:6}},{"a": {re:5,im:7}}]]]'), ##%! obj ); ## ##%!test ## array of objects with DEEP complex number member ##%! assert( fromJSON('[{"a": {"b": {re:4, im:6}}},{"a": {re:5,im:7}}]'), ##%! [struct('a',struct('b',4+6i)),struct('a',5+7i)] ); ## ##%!test ## mismatch array (to cell array) of objects with DEEP complex number member ##%! assert( fromJSON('[{"a":{"b":{re:4, im:6}}}, {"c":{"d":{"e":{re:5,im:7}}}}]'), ##%! {struct('a',struct('b',4+6i)),struct('c',struct('d',struct('e',5+7i)))} ); ## ##%!test # array of complex number in algebraic format (extracircular parsing) ##%! assert( fromJSON('[[4+6i, 1+0i], [2i, 4i + 2]]'), ##%! [4+6i 1;2i 2+4i]); ## ##%!test ## complex number object mixed with number within array (test array parsing) ##%! assert( fromJSON('[[4,{re:1,im:0}],[{re:0,im:2}, {re:4,im:6}]]'), ##%! [4 1;2i 4+6i]); ## ##%!test ## complex number object within a structure (nested) ##%! assert( fromJSON('{"a": {re:1,im:5}}'), ##%! struct('a',1+5i)); ## ##%!test ## complex number object with structure array (nested) ##%! assert( fromJSON('[{"a":{re:1,im:5}},{"a":{re:2,im:5}}]'), ##%! struct('a',{1+5i,2+5i})); ## ##%!test ## complex number object deeply nested in object ##%! assert( fromJSON('{a:1,b:{c:2,d:{e:3,f:{re:3,im:5}}}}'), ##%! struct('a',1,'b',struct('c',2,'d',struct('e',3,'f',3+5i)))); ## ################ file encoding error ###################### ######## simulate parsing with non-ASCII character######### ## ##%!test ## leading file-encoding bytes (simulated with emoji) ##%! assert( fromJSON('😊4'), 4); % just ignore it, likely some file encoding taken in by fread ## ##%!test ## inside arrray ##%!warning assert( fromJSON('[😊,4]'), [NaN, 4]); % convert to NaN ## ##%!test ## inside struct ##%!warning assert( fromJSON('{"a":😊4}'), struct('a',NaN)); % convert to NaN ## ##%!test ## inside quotes ##%! assert( fromJSON('"😊"'), '😊'); % SMILE! not invalid ## ################# exotic JSON BIST ##################### ## ##%!test ## test octave inline fn (convert to inline) ##%! assert(fromJSON('"@@sin"'),@sin); ##%! assert(func2str(fromJSON('"@@(x)3*x"')),func2str(@(x)3*x)); ## ##%!test ## test apparent octave inline fn (do NOT convert to inline) ##%! assert(fromJSON('"@sin"'), '@sin'); ##%! assert(fromJSON('"@(x)3*x"'),'@(x)3*x'); ## ##%!test ## test octave inline fn with SARRAY=false (do NOT convert otherwise valid inline) ##%! assert(fromJSON('"@@sin"', false), '@@sin'); ##%! assert(fromJSON('"@@(x)3*x"', false),'@@(x)3*x'); ## ##%# exotic object in structure ##%!testif HAVE_JAVA ##%! if (usejava ("jvm")) ##%! assert(fromJSON('{"a":"[java.math.BigDecimal]"}'),struct('a','[java.math.BigDecimal]')); ##%! endif ## ##%# exotic object (placeholder of class name) ##%!testif HAVE_JAVA ##%! if (usejava ("jvm")) ##%! assert(fromJSON('"[java.math.BigDecimal]"'),'[java.math.BigDecimal]'); ##%! endif ## ################# beautified or confusing JSON BIST ##################### ## ##%!test ## JSON with confusing '[]{},' AND missing quotes (hard string parse test) ##%! warning('off','all'); ##%! obj=fromJSON('[{a:"tes, {}: [ ] t"},"lkj{} sdf",im mi{}ing quotes]'); ##%! assert(obj,{struct('a',"tes, {}: [ ] t"), 'lkj{} sdf',NaN}) ## ##%!test ## beautified JSON object (extraneous whitespace/newline) ##%! assert( fromJSON("\n { \n\t\"a\"\t\n\n\n :\t\n\n\n 3\n\t} \n \n"), ##%! struct("a",3)) ## ##%!test ## beautified JSON string with array (test parse with extraneous whitespace) ##%! pretty_json ="{\n \"data\": [\n {\n \"vendor\": \"0x10de\",\n \"details\": {\n \"created\": \"2012-11-12T10:35:32Z\"\n },\n \"_status\": \"synced\"\n }\n ]\n}"; ##%! ##%! obj = struct('data', ... ##%! struct('vendor','0x10de', ... ##%! 'details', struct('created','2012-11-12T10:35:32Z'), ... ##%! '_status', 'synced' ##%! ) ##%! ); ##%! ##%! assert( fromJSON(pretty_json),obj,true); ## ##%!test ## garbage string with whitespace ##%!warning assert( fromJSON("[1, gar bage]"),[1,NaN]) ## ##%!test ## garbage string with newline ##%!warning assert( fromJSON("[1, \n gar \n bage]"),[1,NaN]) ## ##%!test ## garbage string with quotes ##%!warning assert( fromJSON('[1,gar""bage]'),[1,NaN]) ## ##%!test ## garbage string with array brackets ##%!warning assert( fromJSON('[1,gar[]bage]'),[1,NaN]) ## ##%!test ## garbage string with object brackets ##%!warning assert( fromJSON('[1,{"a":gar{}bage}]'),{1,struct('a',NaN)}) ## ##%!test ## looks like fn, but is UNQUOTED string ##%!warning assert(fromJSON('@@nofunc'),NaN); ## ############ complex (non-numerical) JSON BIST ################ ## ##%!test ## a JSON string stored inside JSON string object ##%! json = "[ \n { \n \"plot\": [ \n { \n \"line1\": { \n \"x\": [ \n 1, \n 3 \n ], \n \"y\": [ \n 12, \n 32 \n ] \n } \n } \n ] \n } \n]"; ##%! assert( fromJSON(json,true), ##%! struct('plot',struct('line1',struct('x',[1,3],'y',[12,32])))); ## ##%!test ## jsondecode's Arrays with the same field names in the same order. ##%! json = '[{"x_id":"5ee28980fc9ab3","index":0,"guid":"b229d1de-f94a","latitude":-17.124067,"longitude":-61.161831,"friends":[{"id":0,"name":"Collins"},{"id":1,"name":"Hays"},{"id":2,"name":"Griffin"}]},{"x_id":"5ee28980dd7250","index":1,"guid":"39cee338-01fb","latitude":13.205994,"longitude":-37.276231,"friends":[{"id":0,"name":"Osborn"},{"id":1,"name":"Mcdowell"},{"id":2,"name":"Jewel"}]},{"x_id":"5ee289802422ac","index":2,"guid":"3db8d55a-663e","latitude":-35.453456,"longitude":14.080287,"friends":[{"id":0,"name":"Socorro"},{"id":1,"name":"Darla"},{"id":2,"name":"Leanne"}]}]'; ##%! ##%! f1 = num2cell(struct ('id', {0 1 2}, 'name', {'Collins' 'Hays' 'Griffin'})); ##%! f2 = num2cell(struct ('id', {0 1 2}, 'name', {'Osborn' 'Mcdowell' 'Jewel'})); ##%! f3 = num2cell(struct ('id', {0 1 2}, 'name', {'Socorro' 'Darla' 'Leanne'})); ##%! ##%! keys = {'x_id','index','guid','latitude','longitude','friends'}; ##%! val1 = {'5ee28980fc9ab3', 0, 'b229d1de-f94a', -17.124067, -61.161831, f1}; ##%! val2 = {'5ee28980dd7250', 1, '39cee338-01fb', 13.205994, -37.276231, f2}; ##%! val3 = {'5ee289802422ac', 2, '3db8d55a-663e', -35.453456, 14.080287, f3}; ##%! ##%! exp = cell2struct({val1{:};val2{:};val3{:}}',keys)'; ##%! fromJSON(json); # this may be confusing mix of array and non-cell array, but NO fail allowed ##%! assert (fromJSON(json, false), num2cell(exp)); ## ## ##%!test ## from firefox active-stream.discovery_stream.json (UGH! url link as object key) ##%! ##%! json = '[{"feeds":{"https://getpocket.cdn.mozilla.net/v3/firefox/global-recs?version=3&consumer_key=$apiKey&locale_lang=$locale®ion=$region&count=30":{"lastUpdated":1640020188467,"data":{"settings":{"domainAffinityParameterSets":{"default":{"recencyFactor":0.5,"frequencyFactor":0.5,"combinedDomainFactor":0.5,"perfectFrequencyVisits":10,"perfectCombinedDomainScore":2,"multiDomainBoost":0,"itemScoreFactor":1}}}}}}}]'; ##%! exp = struct("feeds", ##%! struct('https://getpocket.cdn.mozilla.net/v3/firefox/global-recs?version=3&consumer_key=$apiKey&locale_lang=$locale®ion=$region&count=30', ##%! struct("lastUpdated",1640020188467, ##%! "data", ##%! struct("settings", ##%! struct("domainAffinityParameterSets", ##%! struct("default", ##%! struct("recencyFactor",0.5, ##%! "frequencyFactor",0.5, ##%! "combinedDomainFactor",0.5, ##%! "perfectFrequencyVisits",10, ##%! "perfectCombinedDomainScore",2, ##%! "multiDomainBoost",0, ##%! "itemScoreFactor",1 ##%! ) ##%! ) ##%! ) ##%! ) ##%! ) ##%! ) ##%! ); ##%! assert (fromJSON(json, true), exp ); ##%! assert (fromJSON(json, false), {exp}); io-2.7.0/inst/PaxHeaders/xlsclose.m0000644000000000000000000000006215004725440014177 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/xlsclose.m0000644000175000017500000001432415004725440014517 0ustar00philipphilip## Copyright (C) 2009-2025 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 a spreadsheet file pointed to in struct @var{xls}, and if needed ## write file to disk. ## ## xlsclose will determine if the file should be written to disk based ## on information contained in @var{xls}. If no errors occured during ## writing, the xls file pointer struct will be reset to empty and -if ## the UNO or COM interface was used- LibreOffice (or OpenOffice.org) or ## 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 LibreOffice.org (UNO) ## invocations may live on, possibly even impeding proper shutdown of ## Octave. ## ## @var{filename} can be used to write changed spreadsheet files to ## a file other than that opened with xlsopen(); unfortunately this doesn't ## work with JXL (JExcelAPI) interface. ## ## For other file formats than OOXML, ODS or gnumeric, you need a Java JRE ## plus Apache POI > 3.5 and/or JExcelAPI, OpenXLS, jOpenDocument, ODF Toolkit ## and/or LibreOffice or clones, and/or the OF windows package + MS-Excel ## installed on your computer + proper javaclasspath set, to make this ## function work at all. ## ## @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 if (nargout < 1) warning ("xlsclose: return argument missing - spreadsheet pointer not reset.\n"); endif force = 0; if (nargin > 1) for ii=1:nargin-1 if (strcmpi (varargin{ii}, "force")) ## Close pointer 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 (cell2mat (cell2mat (regexp (lower (varargin{ii}), ... '.*?(\.xls[xm]{0,1}$|\.ods$|\.gnumeric$)', "tokens")))) && ... (! (strcmp (xls.xtype, "COM") || strcmp (xls.xtype, "UNO")))) ## Excel/ActiveX && OOo (UNO bridge) will write any valid filetype; ## POI/JXL/OXS need .xls[x], JOD/OTK need .ods, OCT nees ods/xlsx/gnumeric error ("xlsclose: proper 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 unwind_protect switch upper (xls.xtype) case "COM" ## COM / ActiveX xls = __COM_spsh_close__ (xls); case "JOD" ## Java & jOpenDocument xls = __JOD_spsh_close__ (xls); case "JXL" ## Java and jExcelAPI xls = __JXL_spsh_close__ (xls); case "OTK" ## Java & ODF toolkit xls = __OTK_spsh_close__ (xls, force); case "OXS" ## Java and OpenXLS xls = __OXS_spsh_close__ (xls); case "POI" ## Java and Apache POI xls = __POI_spsh_close__ (xls); case "UNO" ## Java and LibreOffice / OOo xls = __UNO_spsh_close__ (xls, force); case "OCT" ## Native Octave xls = __OCT_spsh_close__ (xls, "xlsclose", force); otherwise ## Cannot happen theoretically error ("xlsclose: unknown interface - %s", xls.xtype); endswitch unwind_protect_cleanup if (xls.changed && xls.changed < 3) warning (sprintf (['xlsclose: file %s could not be saved.\n', ... "No write permission? unsupported file format? in use elsewhere?\n"], ... xls.filename)); if (force) xls = []; else printf (["(File pointer preserved.\n Try saving again later, or ", ... "with different file name, or as different file type.)\n"]); endif else xls = []; endif end_unwind_protect endfunction io-2.7.0/inst/PaxHeaders/xlsfinfo.m0000644000000000000000000000006215004725440014173 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/xlsfinfo.m0000644000175000017500000002144115004725440014511 0ustar00philipphilip## Copyright (C) 2009-2025 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}]) ## @deftypefnx {Function File} [@dots{}] = xlsfinfo (@dots{}, @var{verbose}) ## Query a spreadsheet file for some info about its contents. ## ## Inputs: ## @itemize ## @item ## @var{filename} is the name, or relative or absolute filename, of a ## spreadsheet file. ## ## @item ## If multiple spreadsheet I/O interfaces have been installed, ## @var{reqintf} can be specified to request a specific interface. If ## omitted xlsfinfo selects a suitable interface; see the help for xlsread ## for more information. ## ## @item ## If optional argument @var{verbose} (numerical or logical; always the ## last argument) is specified as logical 'true' or numerical 1, xlsfinfo ## echoes info about the spreadsheet I/O interface it uses. ## @end itemize ## ## Outputs: ## @itemize ## @item ## Return argument @var{filetype} returns a string containing a general ## description of the spreadsheet file type: "Microsoft Excel Spreadsheet" ## for Excel spreadsheets, "OpenOffice.org Calc spreadsheet" for .ods ## spreadsheets, "Gnumeric spreadsheet" for Gnumeric spreeadsheets, or ## @"" (empty string) for other or unrecognized spreadsheet formats. ## ## @item ## If @var{filename} is a recognized Excel, OpenOffice.org Calc or ## Gnumeric spreadsheet file, optional return argument @var{sh_names} ## contains an 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. ## ## @item ## Optional return value @var{fformat} currently returns "xlWorkbookNormal" ## for .xls formats, "xlOpenXMLWorkbook" for .xlsx, "xlCSV" for .csv, ## "GnumericWorkbook" for .gnumeric, "ODSWorkbook" for .ods, ## "StarOfficeWorkbook" for .sxc, or @"" (empty) for other file formats. ## ## @item ## 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 with the COM, POI, OXS and OCT interfaces, and ## with the UNO interface only properly for Excel files. ## @end itemize ## ## If no return arguments are specified the sheet names are echoed to the ## terminal screen plus for each sheet the actual occupied data range. ## The occupied cell range will have to be determined behind the scenes ## first; this can take some time for some of the Java based interfaces. ## Any Named ranges defined in the spreadsheet file will be listed on ## screen as well. ## ## For OOXML spreadsheets no external SW is required but full POI and/or ## UNO and/or COM support (see xlsopen) may work better or faster; to use ## those specify "poi", "uno" or "com" for @var{reqintf}. For Excel '95 ## files use "com" (windows only), "jxl", "oxs" or "uno". Gnumeric and ## ODS files can be explored with the built-in OCT interface (no need to ## specify @var{reqintf} then) although again the COM, JOD, OTK or UNO ## interfaces may work faster, depending on a.o., the size of the file. ## Note that the JXL, OXS, OTK and JOD interfaces don't support Named ## ranges so when using these interfaces no information about Named ranges ## is returned. ## ## Examples: ## ## @example ## exist = xlsfinfo ('test4.xls'); ## (Just checks if file test4.xls is a readable Excel file) ## @end example ## ## @example ## [exist, names] = xlsfinfo ('test4.ods'); ## (Checks if file test4.ods is a readable LibreOffice Calc file and ## returns 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, ... varargin) persistent str2; str2 = " "; ## 33 spaces persistent lstr2; lstr2 = length (str2); verbose = false; reqintf = ""; if (nargin < 1 || nargin > 3) print_usage (); elseif (nargin == 2) if (isnumeric (varargin{1}) || islogical (varargin{1})) verbose = varargin{1}; else reqintf = varargin{1}; endif elseif (nargin == 3) reqintf = varargin{1}; verbose = varargin{2}; endif xls = xlsopen (filename, 0, reqintf, verbose); if (isempty (xls)) return; endif toscreen = nargout < 1; ## If any valid spreadsheet 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, "JOD")) [sh_names] = __JOD_spsh_info__ (xls); elseif (strcmp (xls.xtype, "JXL")) [sh_names] = __JXL_spsh_info__ (xls); elseif (strcmp (xls.xtype, "OCT")) [sh_names] = __OCT_spsh_info__ (xls); elseif (strcmp (xls.xtype, "OXS")) [sh_names] = __OXS_spsh_info__ (xls); elseif (strcmp (xls.xtype, "OTK")) [sh_names] = __OTK_spsh_info__ (xls); elseif (strcmp (xls.xtype, "POI")) [sh_names] = __POI_spsh_info__ (xls); elseif (strcmp (xls.xtype, "UNO")) [sh_names] = __UNO_spsh_info__ (xls); ##elseif else error (sprintf ("xlsfinfo: unknown spreadsheet I/O 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 elseif (strfind (lower (xls.filename(end-2:end)), 'ods')) fformat = "ODSWorkbook" elseif (strfind (lower (xls.filename(end-7:end)), 'gnumeric')) fformat = "GnumericWorkbook" else fformat = ""; endif endif if (nargout > 3) ## Echo named ranges nmranges = getnmranges (xls); endif endif xls = xlsclose (xls); endfunction io-2.7.0/inst/PaxHeaders/rfsearch.m0000644000000000000000000000006215004725440014140 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/inst/rfsearch.m0000644000175000017500000001034715004725440014461 0ustar00philipphilip## Copyright (C) 2013-2025 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} = rfsearch (@var{dname}, @var{fnpattern}) ## @deftypefnx {Function File} @var{filename} = rfsearch (@var{dname}, @var{fnpattern}, @var{maxdepth}) ## Recursive File Search - search for file or filename pattern FNPATTERN starting ## in directory DNAME and return the first match. ## ## @itemize ## @item @var{dname}, @var{fnpattern} ## Must be character strings and should conform ## to the directory name and filename requirements of your operating system. ## ## @item @var{maxdepth} (optional) 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. ## @end itemize ## ## 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 ("rfsearch: character arguments expected for DNAME and FNPATTERN\n"); elseif (! isnumeric (mxdpth)) error ("rfsearch: numeric value >= 0 expected for MAXDEPTH\n"); elseif (mxdpth < 0) warning ("rfsearch: 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 ((fpath.isdir || 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.7.0/PaxHeaders/Makefile0000644000000000000000000000006215004725440012650 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/Makefile0000644000175000017500000002067615004725440013177 0ustar00philipphilip## Copyright 2015-2025 Carnë Draug ## Copyright 2015-2025 Oliver Heimlich ## Copyright 2017-2025 Julien Bect ## Copyright 2017-2025 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.7.0/PaxHeaders/DESCRIPTION0000644000000000000000000000006215004725440012716 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/DESCRIPTION0000644000175000017500000000073415004725440013236 0ustar00philipphilipName: io Version: 2.7.0 Date: 2025-05-01 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 (>= 4.2.0) Suggested: windows (>= 1.2.1); Java JRE (> 1.8) Autoload: no License: GPLv3+, simplified BSD Url: http://octave.sf.net io-2.7.0/PaxHeaders/COPYING0000644000000000000000000000006215004725440012243 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/COPYING0000644000175000017500000010451315004725440012563 0ustar00philipphilip 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.7.0/PaxHeaders/NEWS0000644000000000000000000000006215004725440011707 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/NEWS0000644000175000017500000016551715004725440012242 0ustar00philipphilipSummary of important user-visible changes for releases of the io package =============================================================================== io-2.7.0 Release Date: 2025-05-01 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: - dbfread.m: rewrite code for attribute (column) selection (bug #61757) - fromJSON.m, toJSON.m: improve Java-based BIST (re-apply bug #60040); Adapt to more stringent code checks required by (experimental) bytecode interpreter (bug #66790) - TexInfo header fixes (bug #62075) - UNO interface: properly process .xlsx files with commas in sheet names (bug #62169) - xlswrite: Improve xlswrite messages in case of write errors and make sure to clean up (in course of bug #64366) - OCT interface: properly process dcterms:created and dcterms:modified nodes (bug #64349) - OCT interface: copy formulas rather than values when writing into an existing sheet (bug #65624) - rfsearch.m: make sure rfsearch only finds real files, rather than also subdirectories - Fix reading data with Named Ranges (properly distinguish Named Range from ordinary spreadsheet range) (bug #66288) - Fix bug when invoking odsfinfo (errored out with "not enough arguments") - Fix indexing error in xlswrite.m in case of very short file names - Avoid long delay with newer LibreOffice (UNO interface) when that is waiting for printer connection. *** Code improvements - JOD interface: now also supports jOpenDocument-1.5. Named Ranges have been implemented, worked also in 1.4-rc2. - POI interface: overhauled .jar detection in Java classpath, POI is now supported up to release 5.2.3. - OTK interface (ODF Toolkit): update support up to 0.10.0, 0.11.0 and 0.12.0. Only one jar is required: odfdom-java--jar-with-dependencies.jar. - Help files for the GUI doc browser have been added. These are loaded/ unloaded automatically when loading/unloading the io package. - Texinfo help headers for several functions have been udpated and improved for use with the GUI doc browser. *** Other changes The UNO interface in some Linux distros and in macOS may take very long to load. On Windows and other Linux distros there deosn't seem to be any issue. As this appears to be an upstream issue no further attempts have been made to avoid these delays in the io package. =============================================================================== io-2.6.4 Release Date: 2021-12-30 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: - fromJSON.m, toJSON.m: some improvements for Java-based BIST - make saving .ods/.xlsx files work again with OCT interface - fix opening .xlsx files made using Google docs (bug #60830) - allow other file extensions than .xls/.xlsx when saving to a different file - fix writing text strings in .ods files (bug (#60825) - improve file extension processing *** Code improvements - toJSON.m, fromJSON.m: made much more robust (credits to K.M. Patel) *** Deprecated function: - object2json (superseded by toJSON) =============================================================================== io-2.6.3 Release Date: 2020-11-02 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: - xlsopen.m: don't wipe user selected reqinterface upon first call to xlsopen after loading io package (bug #59273, bug #59277) - Improve handling of POI interface, esp. OOXML support (bug #59273) - Make reading .ods using OCT interface more reliable (bug #59273) *** Code improvements: - Spreadsheet I/O interfaces echoed to screen when invoking test scripts with "verbose flag. - Significant speed improvements when reading .xlsx files with OCT interface, thanks to Dennis Zeilstra (bug #59277) *** New functions - toJSON and fromJSON: convert Octave objects into a JSON string and vice versa, contributed by Ketan M. Patel (patch #9980). Once Octave-7.x is released these functions will be superseded by core jsonencode and jsondecode. Until then, and/or for users who can't or won't upgrade to Octave-7.x (yet), tojSON and fromJSON will provide JSON functionality. Note: these functions are not fully Matlab-compatible; be careful with ND-arrays. =============================================================================== io-2.6.2 Release Date: 2020-10-10 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: - Fix Named range read errors for .ods files with OCT interface. - dbfread.m: open files in little-endian mode (fix by Rafael Laboissière). - xlsopen.m: improve filename extension checking (.xlsm, .xlsb and .sxc were not recognized). - xlsclose (private/__COM_spsh_close__.m): add missing output formats for COM interface (esp. .ods; also .wk3 and .wk4). - xlsread.m: implement options argument (it *was* mentioned in the help but didn't work) - Improve character encoding for COM interface (bug #59203); credits to Markus Mützel *** Code improvements: - xlsfinfo.m: implement 'verbose' flag to echo used interface info. - io_testscript.m: minimize delay, improve texinfo. - csv2cell's maximum line length has been increased to 32768 characters (bug #58618). - Remove autotools (bootstrap, configure). Avoids potential problems and makes code easier to maintain. Kudos to Kai Torben Ohlhus (bug 357081). - Reintroduce xmlread and xmlwrite functions. NOTE: xmlread may provoke Octave crashes on some Linux systems (see bug #58004) =============================================================================== io-2.6.1 Release Date: 2020-04-15 Release Manager: Philip Nienhuis =============================================================================== *** io-2.6.1 is meant to polish a few prominent bugs introduced unfortunately in the coarse of code overhaul for io-2.6.0. *** Bug fixes: - xlsopen: reinstate default OCT interface (reason that on systems w/o Java or with non-matching Java bit width "no spreadsheet I/O support was found" for .ods and .xlsx). - ods*.m wrapper functions: properly implement output args (bug #58045). - Wrong concatenation of indices when reading .xlsx with OCT interface. Still no fix for the XML functions :-( =============================================================================== io-2.6.0 Release Date: 2020-02-25 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: - Fixed some concealed bugs in getxmlattv.m & __OXS_spsh2oct__.m. - dbfwrite.m: made more robust as regards heterogeneous data columns, just skip them rather than abort. Also fixed writing just one data row (bug #57669) - read_namelist.m: fixed a minor typo. - OCT interface: properly return negative values formatted as "()" (bug #57812). - The XML functions xmlread.m and xmlwrite.m have been (temporarily) removed (see bug #58004). Once that bug is fixed these functions will be reinstated. *** Code improvements: - Most user-visible spreadsheet I/O functions have been adapted such that: * All supported spreadsheet formats / file types can be read and written with the xls*.m functions. So it isn't required anymore to read .xlsx/.xls with xlsread, and .ods with odsread, etc. * The ods*.m functions still exist but now are mere wrappers for the corresponding xls*.m functions. They are (softly) deprecated but will be retained for a while (to at least somewhere in 2022 ?). As they are mere wrappers they have all the functionality of the corresponding xls*.m and previous ods*.m functions. This has been done to cut down on code maintenance; it wasn't really manageable to keep two separate function sets in sync that behind the scenes provided close to 95 % overlapping internal functionality. The choice for keeping xls*.m rather than ods*.m functions was made for Matlab compatibility - that has no ods*.m functions. - The xlsread.m help text now contains an extensive explanation of spreadsheet I/O interfaces. - The message indicating which interfaces were found is now silenced but can be shown by adding an argument "verbose" to xlsread / xlsopen / xlswrite. See the help for xlsread, xlsopen and xlswrite. *** Other changes The previously separate READ-ODS.html and READ-XLS.html docs in the doc/ subdirectory have been replaced by a new combined html background document rewritten from scratch: Spreadsheet-IO-in-Octave.html =============================================================================== io-2.4.13 Release Date: 2019-10-15 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: - COM interface: restore writing formulas to spreadsheet - OCT interface: ignore NA and NaN values when writing .ods and .gnumeric (bug #56375) - OCT interface: don't truncate arrays when using single cell-range input with oct2ods and oct2xls functions (bug #56444) - csv2cell: properly process leading tilde in file name (bug #53591) *** Code improvements: - COM interface: better support for creating file formats other than .xlsx - ditto for UNO interface - Remove references to legacy Java package, as io depends on Octave >= 4.0 where core Octave should have built-in Java support anyway - Replace calls to strmatch() with calls to str(n)cmp(i)() - Replace calls to __octave_config_info__() and __have_feature__() by javachk() (bug #47480) *** Various: - The io package now needs Octave >= 4.0.0, due to dependence on javachk =============================================================================== io-2.4.12 Release Date: 2018-10-28 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: - dbfwrite.m: avoid crash and vectorize writing data to file (bug #53899) by Matthew Parkan - dbfwrite.m: add unwind_protect block to be able to avoid dangling file handles in case of errors; better checks on data column homogeneity; texinfo (help) header fixes - A little more robust Java check - csv2cell: improper string indexing (bug #54407), fix by Orion Paplowski - " process leading '~' in file names (bug #53591) *** Code improvements: - POI interface: adapt to POI-4.0.0 (new getCelltype enums) - POI: overhaul cell type handling when reading and writing - dbfread.m: improve speed when reading a subset of data =============================================================================== io-2.4.11 Release Date: 2018-04-18 Release Manager: Philip Nienhuis =============================================================================== *** Bug fixes: - OCT interface: fix reading shared formula results (bug #52875) credits to Radekivv - OCT interface: fix a rare case of nested text cell XML with special formatting attributes (bug # 53298) - OCT interface: don't over-allocate memory when reading text cells in xlsx (bug 533910, credits to Peter Giles - OCT interface: return correct date values for .ods file (bug #53401) - dbfwrite.m: don't prepend space before string values - bug #53510: fix detection of Java version for Java > 8 - OCT interface: (part of) bug #53459, i.e. reading .xlsx files with a more complex mix of chartsheets, macrosheets and worksheets, and exploring such files with xlsfinfo. Writing to such files however isn't guaranteed to be bug free. However, other interfaces (POI, UNO) provide a workaround. - COM interface: clearly distinguish between worksheets and e.g., chartsheets when referencing sheets by number. =============================================================================== 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 aren't 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 spreadsheet file upon closing spreadsheet 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: (hmm a bit moot as of early 2018) 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.7.0/PaxHeaders/src0000644000000000000000000000013215004726004011715 xustar0030 mtime=1746119684.352811097 30 atime=1746119684.377810908 30 ctime=1746119684.377810908 io-2.7.0/src/0000755000175000017500000000000015004726004012310 5ustar00philipphilipio-2.7.0/src/PaxHeaders/col2num.cc0000644000000000000000000000006215004725440013665 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/src/col2num.cc0000644000175000017500000000413015004725440014177 0ustar00philipphilip// Copyright (C) 2014-2025 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 . /* %% Test simple case %!test %! assert (col2num ("a"), 1, 1e-16); %!test %! assert (col2num ("z"), 26, 1e-16); %% Test more complicated string %!test %! assert (col2num ("aa"), 27, 1e-16); %!test assert (col2num ("ydf"), 17010, 1e-16); %% Test case insensitivity %!test %! assert (col2num ("A"), 1, 1e-16); %!test assert (col2num ("Ydf"), 17010, 1e-16); %!test assert (col2num ("yDf"), 17010, 1e-16); %!test assert (col2num ("ydF"), 17010, 1e-16); %!test assert (col2num ("YDf"), 17010, 1e-16); %!test assert (col2num ("yDF"), 17010, 1e-16); %!test assert (col2num ("YdF"), 17010, 1e-16); %!test assert (col2num ("YDF"), 17010, 1e-16); */ #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.7.0/src/PaxHeaders/Makefile0000644000000000000000000000006215004725440013437 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/src/Makefile0000644000175000017500000000037115004725440013754 0ustar00philipphilip## Copyright (C) 2021-2025 The Octave Project Developers all: 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.7.0/src/PaxHeaders/num2col.cc0000644000000000000000000000006215004725440013665 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/src/num2col.cc0000644000175000017500000000320315004725440014177 0ustar00philipphilip// Copyright (C) 2014-2025 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 . /* %% Simple case %!test assert (num2col (1), "A"); %!test assert (num2col (27), "AA"); %% More complicated case %!test assert (num2col (17010), "YDF"); */ #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.7.0/src/PaxHeaders/csv2cell.cc0000644000000000000000000000006215004725440014023 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/src/csv2cell.cc0000644000175000017500000003764515004725440014356 0ustar00philipphilip// Copyright (C) 2004-2025 Laurent Mazet // Copyright (C) 2014-2025 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 = tempname (); %! fid = fopen (f, 'w+'); %! fprintf (fid, "\"1\""); %! fclose (fid); %! s = csv2cell (f){1}; %! unlink (f); %! assert (s, "1"); %!test %! f = tempname (); %! csvwrite(f, "\"1\",2", "DELIMITER", ""); %! s = csv2cell(f); %! unlink (f); %! assert (s{1}, "1"); %! assert (s{2}, 2); %!test %! f = tempname (); %! csvwrite(f, "3,\"1\"", "DELIMITER", ""); %! s = csv2cell(f); %! unlink (f); %! assert (s{1}, 3); %! assert (s{2}, "1"); %% Check proper string protection %!test %! f = tempname (); %! 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 = tempname (); %! 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 = tempname (); %! 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 = tempname (); %! 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 = tempname (); %! 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 = tempname (); %! 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 = tempname (); %! 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 = tempname (); %! 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 = tempname (); %! 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 #include "octave_4_2_compatibility.h" #define MAXSTRINGLENGTH 32768 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 is 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 32768 characters.\n\ (This is also the theoretical maximum number of columns - 1 in the data \n\ if all fields are empty, i.e., a line containing just 32768 consecutive \n\ separators will yield 32769 empty values.)\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 = octave::sys::file_ops::tilde_expand (args (0).string_value ()); /* Look if first arg after filename = numeric. If yes => headerlines */ long hlines = (nargin > 1 && args(1).isnumeric () ? args(1).long_value() : 0); int arg_sh = (nargin > 1 && args(1).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+1 < 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.length () && 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+1 < 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.7.0/src/PaxHeaders/octave_4_2_compatibility.h0000644000000000000000000000006215004725440017026 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/src/octave_4_2_compatibility.h0000644000175000017500000000052215004725440017341 0ustar00philipphilip// Copyright (C) 2020 - 2025 The Octave Project Developers #if ! defined (OCTAVE_4_2_COMPATIBILITY_H_) #define OCTAVE_4_2_COMPATIBILITY_H_ 1 #include #if OCTAVE_MAJOR_VERSION == 4 && OCTAVE_MINOR_VERSION < 4 #define iscell is_cell #define isempty is_empty #define isnumeric is_numeric_type #endif #endif io-2.7.0/src/PaxHeaders/csvconcat.cc0000644000000000000000000000006215004725440014271 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/src/csvconcat.cc0000644000175000017500000000561415004725440014613 0ustar00philipphilip// Copyright (C) 2004-2025 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 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.\n\n\ @var{sep} (character value) changes the character used to separate two fields.\n\ The default value is a comma (@code{,}).\n\n\ @var{prot} (character value) changes the character used to protect a string.\n\ 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 . #include #include #include "octave_4_2_compatibility.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.\n\ \n\ @var{sep} (character value) changes the character used to separate two fields.\ The default value is a comma (@code{,}).\n\ \n\ @var{prot} (character value) changes the character used to protect a string.\n\ 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).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) 2016-2025 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 = tempname(); %! 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 = tempname(); %! 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 "octave_4_2_compatibility.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.\n\ @var{sep} (character value) changes the character used to separate two fields.\n\ The default value is a comma (@code{,}).\n\ @var{prot} (character value) changes the character used to protect a string.\n\ 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/dev/null),) QHELPGENERATOR = qhelpgenerator-qt5 else ifneq ($(shell qcollectiongenerator-qt5 -v 2>/dev/null),) QHELPGENERATOR = qcollectiongenerator-qt5 #else ifneq ($(shell qhelpgenerator -qt5 -v 2>/dev/null),) # v4 doesnt work # QHELPGENERATOR = qhelpgenerator -qt5 else ifneq ($(shell qcollectiongenerator -qt5 -v 2>/dev/null),) QHELPGENERATOR = qcollectiongenerator -qt5 else QHELPGENERATOR = true endif endif PACKAGE := $(shell $(SED) -n -e 's/^Name: *\(\w\+\)/\1/p' ../DESCRIPTION) VERSION := $(shell $(SED) -n -e 's/^Version: *\(\w\+\)/\1/p' ../DESCRIPTION) DATE := $(shell $(SED) -n -e 's/^Date: *\(\w\+\)/\1/p' ../DESCRIPTION) DEPENDS := $(shell $(SED) -n -e 's/^Depends[^,]*, *\(.*\)/\1/p' ../DESCRIPTION | $(SED) 's/ *([^()]*)//g; s/ *, */ /g') BASEDIR ?= $(realpath $(CURDIR)) HG := hg HG_CMD = $(HG) --config alias.$(1)=$(1) --config defaults.$(1)= $(1) HG_ID := $(shell $(call HG_CMD,identify) --id | sed -e 's/+//' ) HG_TIMESTAMP := $(firstword $(shell $(call HG_CMD,log) --rev $(HG_ID) --template '{date|hgdate}')) TAR_REPRODUCIBLE_OPTIONS := --sort=name --mtime="@$(HG_TIMESTAMP)" --owner=0 --group=0 --numeric-owner TAR_OPTIONS := --format=ustar $(TAR_REPRODUCIBLE_OPTIONS) RELEASE_DIR := $(PACKAGE)-$(VERSION) RELEASE_TARBALL := $(PACKAGE)-$(VERSION).tar.gz HTML_DIR := $(PACKAGE)-html HTML_TARBALL := $(PACKAGE)-html.tar.gz .PHONY: doc clean maintainer-clean .PHONY: build-docs cleandocs help: @echo "Targets:" @echo " doc - Build Texinfo package manual" @echo @echo " clean - Remove releases, html documentation, and oct files" @echo " maintainer-clean - Additionally remove all generated files" doc: build-docs version.texi: $(BASEDIR)/../.hg/dirstate @echo Generating $@ @echo "@c autogenerated from Makefile" > $@ @echo "@set VERSION $(VERSION)" >> $@ @echo "@set PACKAGE $(PACKAGE)" >> $@ @echo "@set DATE $(DATE)" >> $@ functions.texi: $(BASEDIR)/../.hg/dirstate ./mkfuncdocs.py --src-dir=../inst/ --src-dir=../src/ ../INDEX | $(SED) 's/@seealso/@xseealso/g' > functions.texi $(PACKAGE).qhc: $(PACKAGE).texi functions.texi version.texi # extract html SOURCE_DATE_EPOCH=$(HG_TIMESTAMP) $(MAKEINFO) --html --css-ref=$(PACKAGE).css $(MAKEINFO_HTML_OPTIONS) $(PACKAGE).texi ifeq ($(QHELPGENERATOR),true) $(warning No QHELPGENERATOR ... skipping QT doc build) else # try also create qch file if can ./mkqhcp.py $(PACKAGE) && $(QHELPGENERATOR) $(PACKAGE).qhcp -o $(PACKAGE).qhc $(RM) -f $(PACKAGE).qhcp $(PACKAGE).qhp $(PACKAGE).html endif $(PACKAGE).info: $(PACKAGE).texi functions.texi version.texi $(MAKEINFO) $(PACKAGE).texi build-docs: $(PACKAGE).qhc $(PACKAGE).info clean-docs: $(RM) -f $(PACKAGE).html $(RM) -f $(PACKAGE).qhc $(RM) -f $(PACKAGE).qch $(RM) -f $(PACKAGE).info $(RM) -f functions.texi $(RM) -f version.texi clean: clean-docs -rm -rf $(RELEASE_DIR) $(RELEASE_TARBALL) $(HTML_TARBALL) $(HTML_DIR) cd src && $(MAKE) $@ maintainer-clean: clean io-2.7.0/doc/PaxHeaders/io.texi0000644000000000000000000000006215004725440013257 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/doc/io.texi0000644000175000017500000000727415004725440013605 0ustar00philipphilip% Copyright (C) 1996-2024 The Octave Project Developers % % This file is part of Octave. % % Octave is free software: you can redistribute it and/or modify it % under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % Octave is distributed in the hope that it will be useful, but % WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with Octave; see the file COPYING. If not, see % . \input texinfo @c Octave io - io package for GNU octave. @c For manually generating the documentation use @c LANGUAGE=en makeinfo --html --no-split io.texi @c %*** Start of HEADER @documentencoding UTF-8 @setfilename io.info @settitle Octave io - io package for GNU octave @afourpaper @paragraphindent 0 @finalout @c @afourwide @c %*** End of the HEADER @dircategory Math @direntry * Octave io: (io). io package for Octave @end direntry @include version.texi @include macros.texi @c ------------------------------------------------------------------------- @c @contents @c ------------------------------------------------------------------------- @ifnottex @node Top @top Octave io package Copyright © The Octave Project Developers Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions. @end ifnottex @c ------------------------------------------------------------------------- @node Overview @chapter Overview @cindex Overview The io package contains functions for reading and writing various type of data files. @c ------------------------------------------------------------------------- @node Installing and loading @chapter Installing and loading @cindex Installing and loading The io package must be installed and then loaded to be used. It can be installed in @acronym{GNU} Octave directly from octave-forge, @section Windows install @cindex Windows install If running in Windows, the package may already be installed, to check run: @example pkg list io @end example @section Installing @cindex Installing With an internet connection available, the io package can be installed from octave-forge using the following command within @acronym{GNU} Octave: @example pkg install io @end example The latest released version of the package will be downloaded and installed. Otherwise, if the package file has already been downloaded it can be installed using the follwoing command in @acronym{GNU} Octave: @example pkg install io-@value{VERSION}.tar.gz @end example @section Loading @cindex Loading Regardless of the method of installing the package, in order to use its functions, the package must be loaded using the pkg load command: @example pkg load io @end example The package must be loaded on each @acronym{GNU} Octave session. @c ------------------------------------------------------------------------- @node Function Reference @chapter Function Reference @cindex Function Reference @include functions.texi @c ------------------------------------------------------------------------- @bye io-2.7.0/doc/PaxHeaders/Spreadsheet-IO-in-Octave.html0000644000000000000000000000006215004725440017242 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/doc/Spreadsheet-IO-in-Octave.html0000644000175000017500000013053715004725440017567 0ustar00philipphilip

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

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

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.

February 22, 2020

SPREADSHEET I/O SUPPORT FOR OCTAVE



> > > > AN IMPORTANT THING TO KEEP IN MIND < < < <
The spreadsheet I/O functions merely serve for data I/O, or in other words, just transferring data from or to spreadsheet files.
More sophisticated stuff like formatting or overhauling worksheet setup is simply out of scope.

General overview of functions and files
As of io-2.6.0, the separate functions for .ods and .xls(x) formats have been unified into the xls* functions. The ods* functions still live on as wrappers for their xls* siblings, although they are now formally deprecated. This means that from now on all spreadsheet formats that used to be divided over the ods* and xls* functions can be read / written with either ods* or xls* functions. In the overview below the ods* siblings are indicated between parentheses after their xls* counterparts.

This move was badly needed to be able to cut down on maintenance, as the various ods* functions did largely the same as their xls* siblings (think of input validation, preprocessing, input argument handling, file handling, etc.).
The choice for keeping xls* functions and deprecating the ods* functions is a logical consequence of Octave striving to be Matlab-compatible: Matlab doesn't have ods* functions, only xls* functions.

doc/Spreadsheet-IO-in-Octave.html
This file.

xlsread.m (odsread.m)
All-in-one functions for reading data from one specific worksheet in a spreadsheet file. This script has Matlab-compatible functionality.

xlswrite.m (odswrite.m)
All-in-one function for writing data to one specific worksheet in a spreadsheet file. This script has Matlab-compatible functionality.

xlsfinfo.m (odsfinfo.m)
All-in-one function for exploring basic properties of a spreadsheet file. This script has Matlab-compatible functionality.

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

xls2oct.m (ods2oct.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 (hidden, "private") interface-dependent scripts that do the actual low-level reading.

oct2xls.m (oct2ods.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 (hidden, "private") interface-dependent scripts that do the actual low-level writing.

xlsclose.m (odsclose.m)
Function for closing (the handle to) a spreadsheet file. When data have been written to the workbook in memory, xlsclose will write the workbook to disk. Otherwise, the file pointer is simply closed and possibly used interfaces for spreadsheet access (LibreOffice, 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_testscript.m
Undocumented scripts for testing basic features of the spreadsheet scripts. Meant for testers and developers.

Private utility functions
Most of the above functions delegate actual file and data handling to "interface"-specific functions that are "private" (= hidden from the user and not directly callable by users).

Templates
The io package installation directory contains a "template" subdirectory. This contains empty spreadsheet "frameworks" that are only used as templates for writing data to new spreadsheet files. I do not think they can be read as-is by spreadsheet programs, so don't try that.


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 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.8.0 (hasn't been tested with earlier versions);

.ods file format

ODF Toolkit / ODFDOM specific:

jOpendocument specific:

.xls / .xlsx / .xlsm file formats

Apache POI specific:
  • Basic support for .xls:
    class .jars: poi-3.5-FINAL-<date>.jar & poi-ooxml-3.5-<date>.jar (or later versions) in javaclasspath.
    Get them here:
    http://poi.apache.org/download.html
  • OOXML (.xlsx, .xlsm) support with Apache POI:
    poi-ooxml-schemas-<version>.jar, + either xbean.jar or xmlbeans.jar and 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 (just .xls):

OpenXLS specific (just .xls):

These class libs must be referenced with full pathnames in your javaclasspath.
When the io package gets loaded, a utility function (__init_io__.m) 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 to automatically load the Java class libs, specify a value of "no", "false" or "0" for the OCTAVE_IO_JAVALIBS environment variable before starting Octave.

.ods, .xls, .xlsx, .xlsm, .sxc + several other file formats

UNO specific (invoking OpenOffice.org (or clones) behind the scenes):
    NOTE: EXPERIMENTAL!!
  • A working OpenOffice.org installation.
    Be aware that OpenOffice.org/LibreOffice arch type (32-bit or 64-bit) must match Octave's arch type.
    The utility function chk_spreadsheet_support had best be used to add the needed entries to the javaclasspath. 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.

For the Excel/COM interface:
  • A windows computer with MS-Excel installed;
  • Octave-forge Windows package, version > 1.2.1. Don't forget to load the package.


USAGE


xlsread (odsread) and xlswrite (odswrite) are mere wrappers for xlsopen (odsopen) - xls2oct (ods2oct) - xlsclose (odsclose) - parsecell and xlsopen (odsopen) - oct2xls (oct2ods) - xlsclose (odsclose) sequences, resp. They exist for the sake of Matlab compatibility.

xlsfinfo (odsfinfo) can be used for finding out what worksheet names exist in the file.

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.

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

A possible scenario:

xlh = xlsopen (<spreadsheet_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 result
    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), OpenXLS, Odf Toolkit or jOpendocument. So if you create formulas in your spreadsheet using oct2xls or xlswrite with e.g., 'JXL', do not expect meaningful results when reading those files later on unless you first open them in LibreOffice, Excel or Apache POI 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.


MATLAB COMPATIBILITY AND SOME GOTCHAS


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 flags some spreadsheet errors, Octave's just returns blank cells.
Individual spreadsheet cells containing erroneous stuff are transferred to Octave as NaNs. But not all errors can be catched. E.g., spreadsheet cells showing #Value# in LibreOffice Calc often contain invalid formulas but may have a 0 (null) value stored in the value fields. It is rarely possible 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).

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.

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 formats. Internally date are stored as doubles with an epoch of 31 Dec. 1899. Octave's xlsread and xls2oct just return those numerical data (where 0 = 1/1/1900 you can easily transfer them into proper Octave date values yourself by adding 693960. Note that only dates after March 1, 1900 make proper sense because Excel erroneously assumes 1900 to be a leap year.

In .ods file dates are stored as text strings rather than numerical values. Octave reads them into datenums with an epoch of Jan. 1, 0000.
Note that you can get an interesting confusing with regard to dates when reading .ods files and then writing them to disk s .xls or .xlsx files, or vice versa.

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.

When writing datenums to disk, xlswrite (and oct2xls) doesn't morph them into proper Excel date values. The reason is that neither Octave nor Matlab have date types and conversely, Excel only has double, logical or text types and distinguishes dates from double values solely through formatting. And writing formatting isn't implemented for xlswrite.
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


The OCT or native Octave interface is completely under control of Octave (-Forge) developers. Currently it only offers support for .ods (relatively slow), .gnumeric (faster) and OOXML (relatively fast). An immense advantage is that no other external software is required.
However, all this comes at a price. Parsing xml trees into rectangular arrays is not quite straightforward and the other way round can be a real nightmare.

  • OOXML (.xlx, .xlsm) files are merely g-zipped directory trees containing XML files. But that's the easy part. Internally all these XML files are cross-linked by various XML tags and especially the XML files that contain the data are extremely complicated. Octave reads those XML files using regular expressions; XML gurus will frown here but using regexps is extremely fast. OTOH it is also fragile as the order of XML tags and subnodes may differ from file to file. However, until now we've seen no problems.

  • .ods files which are also (zipped) archives are different yet equally complicated. Unlike OOXML or gnumeric, .ods spreadsheet cells internally have no cell address tags so developers have to set up their own cell address bookkeeping; regular expressions are of little use here. While reading ODS is doable, 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. This is the reason that I/O to/from .ods with the OCT interface is quite slow.

  • Gnumeric files are the easiest to read and write and like OOXML regular expressions work well and fast. A particular gotcha with gnumeric is that no cached data values are stored in the file. That means that Octave can't read formula results as hey just don't exist in the file; you really need Gnumeric itself for that. The reason is (as far as I could deduce from their support mailing lists) that the Gnumeric developers figured that files might be 30 % larger and they deemed that too much at the time.

So, after reading the above you might appreciate that the io package can also invoke pre-baked libraries that simply shield away the gory details. Most if not all open-source ones are Java based and therefore platform-independent. Read on:

ODF Toolkit (ODFDOM) is the one that gives the best (but slow) results at present for .ods. ODF Toolkit up til 0.7.5 did little to hide the gory details for the developers. 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 for .ods is more promising (and currently the fastest for not too big spreadsheets), as it does shield the XML tree details and presents to 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. The last (and recommended) release was 1.4-rc2 from 2014.

Apache POI is based on the OpenOffice.org I/O Excel r/w routines. It is more versatile than JExcelAPI (below); 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 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.

JExcelAPI (for .xls) 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 e.g., OpenXLS.
The fact that upon a switch from reading to writing the existing spreadsheet on disk 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.

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; in fact it is the fastest Java-based option for not too big .xls (BIFF8) file I/O.

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 own memory.
A big stumbling block is that odsclose() on a UNO xls or ods struct will kill ALL OpenOffice.org invocations, also those that were not related to Octave! This is due to UNO-Java limitations. In fact this is the reason UNO is still considered experimental
The underlying issue is that after Octave started an Libreoffice invocation, Libreoffice must be closed for Octave to be able to exit; otherwise Octave will wait for LO to shut down before it can terminate itself. So Octave must kill LO to be able to terminate.
A way out hasn't been found yet and may even not exist.

Using Excel itself (through COM / ActiveX on Windows systems) is probably the most robust and versatile and especially FAST option. There's one gotcha: in case of some type of COM errors Excel will keep running invisibly and turn into a hidden "zombie" process; 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.; modern Excel versions can read .ods.
Another -obvious- limitation is that COM Excel access only works on Windows systems where Excel is installed.

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. OCT write support is available for OOXML, ODS 1.2 and gnumeric.
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.106 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. 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 a memory pool size of 512 MB is needed.
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 spreadsheet support are contained in this thread (for Excel): http://sourceforge.net/mailarchive/forum.php?thread_name=4C61B649.9090802%40hccnet.nl&forum_name=octave-dev dated August 10, 2010. Since that time a lot has changed.

As of April 2011 a special purpose setup file has been included in the io package (chk_spreadsheet_support.m) in which error checking and troubleshooting have been automated; it has evolved over time with core Octave itself.
When running it with the second input argument (debug level) set to 3 a lot of useful, hopefully self-explanatory diagnostic output will be printed to screen.


DEVELOPMENT

xlsopen / xlsclose and friends have been written so that adding other interfaces (Perl? ...?) 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 the ./private subdir, but that need not 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. Presently each spreadheet cell is read or written individually; maybe there's a way to treat several cells at once. But the problem is undoubtedly how to translate possibly heterogeneous Java array structures into Octave heterogeneous cell arrays.
    Using ActiveX/COM an entire array is handed as an object from Excel to Octave and parsed in the Octave world; using OCT a worksheet is scanned using a regular expression for each data type in one fell swoop, and spreadsheets usually only have a limited number of data types (just double, text, logical, and some derived types).
  • Automatic conversion of spreadsheet date/time values into Octave ones and vice versa (adding or subtracting 636960 in case of ActiveX/COM). But then again Excel's dates are 01-01-1900 based ("epoch"; Octave's epoch is 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?
    The again each spreadsheet interface support SW has its own date representation and epoch which makes Matlab compatibility over all interfaces an elusive goal.
  • Creating spreadsheet graphs (a significant enterprise to write from scratch).

Enjoy!

Philip Nienhuis, February 22, 2020

io-2.7.0/doc/PaxHeaders/gpl.texi0000644000000000000000000000006215004725440013432 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/doc/gpl.texi0000644000175000017500000010433015004725440013747 0ustar00philipphilip@node Copying @appendix GNU General Public License @cindex warranty @cindex copyright @center Version 3, 29 June 2007 @display Copyright @copyright{} 2007 Free Software Foundation, Inc. @url{http://fsf.org/} Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @end display @heading 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. @heading TERMS AND CONDITIONS @enumerate 0 @item 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. @item 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. @item 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. @item 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. @item 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. @item 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: @enumerate a @item The work must carry prominent notices stating that you modified it, and giving a relevant date. @item 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''. @item 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. @item 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. @end enumerate 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. @item 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: @enumerate a @item 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. @item 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. @item 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. @item 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. @item 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. @end enumerate 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. @item 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: @enumerate a @item Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or @item 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 @item 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 @item Limiting the use for publicity purposes of names of licensors or authors of the material; or @item Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or @item 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. @end enumerate 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. @item 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. @item 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. @item 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. @item 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. @item 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. @item 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. @item 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. @item 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. @item 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. @item 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 enumerate @heading END OF TERMS AND CONDITIONS @heading 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. @smallexample @var{one line to give the program's name and a brief idea of what it does.} Copyright (C) @var{year} @var{name of author} 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 @url{http://www.gnu.org/licenses/}. @end smallexample 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: @smallexample @var{program} Copyright (C) @var{year} @var{name of author} This program comes with ABSOLUTELY NO WARRANTY; for details type @samp{show w}. This is free software, and you are welcome to redistribute it under certain conditions; type @samp{show c} for details. @end smallexample The hypothetical commands @samp{show w} and @samp{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 @url{http://www.gnu.org/licenses/}. 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 @url{http://www.gnu.org/philosophy/why-not-lgpl.html}. io-2.7.0/doc/PaxHeaders/version.texi0000644000000000000000000000006215004725440014335 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/doc/version.texi0000644000175000017500000000012715004725440014651 0ustar00philipphilip@c autogenerated from Makefile @set VERSION 2.7.0 @set PACKAGE io @set DATE 2025-05-01 io-2.7.0/doc/PaxHeaders/mkqhcp.py0000644000000000000000000000006215004725440013612 xustar0020 atime=1746119456 30 ctime=1746119684.377810908 io-2.7.0/doc/mkqhcp.py0000755000175000017500000001331315004725440014132 0ustar00philipphilip#!/usr/bin/python3 ## mkqhcp.py ## Version 1.0.4 ## Copyright 2022-2023 John Donoghue ## ## 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 ## . import sys import os import re def process(name): with open(name + ".qhcp", 'wt') as f: f.write ('\n') f.write ('\n') f.write (' \n') f.write (' \n') f.write (' \n') f.write (' {0}.qhp\n'.format(name)) f.write (' {0}.qch\n'.format(name)) f.write (' \n') f.write (' \n') f.write (' \n') f.write (' {0}.qch\n'.format(name)) f.write (' \n') f.write (' \n') f.write ('\n') title = name pat_match = re.compile(r".*(?P<title>[^<]+).*") with open(name + ".html", 'rt') as fin: # find html for line in fin: line = line.strip() e = pat_match.match(line) if e: title = e.group("title") break # section h2_match = re.compile(r'.*

]*>(?P[^<]+)</h2>.*') # appendix h2a_match = re.compile(r'.*<h2 class="appendix"[^>]*>(?P<title>[^<]+)</h2>.*') # index h2i_match = re.compile(r'.*<h2 class="unnumbered"[^>]*>(?P<title>[^<]+)</h2>.*') h3_match = re.compile(r'.*<h3 class="section"[^>]*>(?P<title>[^<]+)</h3>.*') h4_match = re.compile(r'.*<h4 class="subsection"[^>]*>(?P<title>[^<]+)</h4>.*') tag_match1 = re.compile(r'.*<span id="(?P<tag>[^"]+)"[^>]*></span>.*') #tag_match2 = re.compile(r'.*<div class="[sub]*section" id="(?P<tag>[^"]+)"[^>]*>.*') tag_match2 = re.compile(r'.*<div class="[sub]*section[^"]*" id="(?P<tag>[^"]+)"[^>]*>.*') tag_match3 = re.compile(r'.*<div class="chapter-level-extent" id="(?P<tag>[^"]+)"[^>]*>.*') tag_match4 = re.compile(r'.*<div class="appendix-level-extent" id="(?P<tag>[^"]+)"[^>]*>.*') tag_match5 = re.compile(r'.*<div class="unnumbered-level-extent" id="(?P<tag>[^"]+)"[^>]*>.*') index_match = re.compile(r'.*<h4 class="subsection"[^>]*>[\d\.\s]*(?P<name>[^<]+)</h4>.*') tag = "top" has_h2 = False has_h3 = False #pat_match = re.compile(r'.*<span id="(?P<tag>[^"])"></span>(?P<title>[.]+)$') with open(name + ".html", 'rt') as fin: with open(name + ".qhp", 'wt') as f: f.write('<?xml version="1.0" encoding="UTF-8"?>\n') f.write('<QtHelpProject version="1.0">\n') f.write(' <namespace>octave.community.{}</namespace>\n'.format(name)) f.write(' <virtualFolder>doc</virtualFolder>\n') f.write(' <filterSection>\n') f.write(' <toc>\n') f.write(' <section title="{} Manual" ref="{}.html">\n'.format(title, name)) # chapters here for line in fin: line = line.strip() e = tag_match1.match(line) if not e: e = tag_match2.match(line) if not e: e = tag_match3.match(line) if not e: e = tag_match4.match(line) if not e: e = tag_match5.match(line) if e: tag = e.group("tag") e = h2_match.match(line) if not e: e = h2a_match.match(line) if not e: e = h2i_match.match(line) if e: if has_h3: f.write(' </section>\n') has_h3 = False if has_h2: f.write(' </section>\n') has_h2 = True f.write(' <section title="{}" ref="{}.html#{}">\n'.format(e.group("title"), name, tag)) e = h3_match.match(line) if e: if has_h3: f.write(' </section>\n') has_h3 = True f.write(' <section title="{}" ref="{}.html#{}">\n'.format(e.group("title"), name, tag)) e = h4_match.match(line) if e: f.write(' <section title="{}" ref="{}.html#{}"></section>\n'.format(e.group("title"), name, tag)) if has_h3: f.write(' </section>\n') if has_h2: f.write(' </section>\n') f.write(' </section>\n') f.write(' </toc>\n') f.write(' <keywords>\n') fin.seek(0) for line in fin: line = line.strip() e = tag_match1.match(line) if not e: e = tag_match2.match(line) if e: tag = e.group("tag") e = index_match.match(line) if e: f.write(' <keyword name="{}" ref="{}.html#{}"></keyword>\n'.format(e.group("name"), name, tag)) f.write(' </keywords>\n') f.write(' <files>\n') f.write(' <file>{}.html</file>\n'.format(name)) f.write(' <file>{}.css</file>\n'.format(name)) f.write(' </files>\n') f.write(' </filterSection>\n') f.write('</QtHelpProject>\n') def show_usage(): print (sys.argv[0], "projname") if __name__ == "__main__": if len(sys.argv) > 1: status = process(sys.argv[1]) sys.exit(status) else: show_usage() ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������io-2.7.0/doc/PaxHeaders/io.qhc����������������������������������������������������������������������0000644�0000000�0000000�00000000062�15004725440�013061� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������20 atime=1746119456 30 ctime=1746119684.377810908 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������io-2.7.0/doc/io.qhc���������������������������������������������������������������������������������0000644�0001750�0001750�00000300000�15004725440�013366� 0����������������������������������������������������������������������������������������������������ustar�00philip��������������������������philip�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������SQLite format 3���@ ���#���������������������������������������������������������������#�.zq ��$  w h z H"f| ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������b''tableVersionFilterVersionFilterCREATE TABLE VersionFilter (Version TEXT, FilterId INTEGER)n++tableComponentFilterComponentFilterCREATE TABLE ComponentFilter (ComponentName TEXT, FilterId INTEGER)u--tableComponentMappingComponentMappingCREATE TABLE ComponentMapping (ComponentId INTEGER, NamespaceId INTEGER)q))tableComponentTableComponentTableCREATE TABLE ComponentTable (ComponentId INTEGER PRIMARY KEY, Name TEXT)VtableFilterFilterCREATE TABLE Filter (FilterId INTEGER PRIMARY KEY, Name TEXT)b%%tableVersionTableVersionTableCREATE TABLE VersionTable (NamespaceId INTEGER, Version TEXT)))mtableTimeStampTableTimeStampTableCREATE TABLE TimeStampTable (NamespaceId INTEGER, FolderId INTEGER, FilePath TEXT, Size INTEGER, TimeStamp TEXT)551tableOptimizedFilterTableOptimizedFilterTableCREATE TABLE OptimizedFilterTable (NamespaceId INTEGER, FilterAttributeId INTEGER)(77otableFileAttributeSetTableFileAttributeSetTableCREATE TABLE FileAttributeSetTable (NamespaceId INTEGER, FilterAttributeSetId INTEGER, FilterAttributeId INTEGER) 33/tableContentsFilterTableContentsFilterTableCREATE TABLE ContentsFilterTable (FilterAttributeId INTEGER, ContentsId INTEGER )w --!tableIndexFilterTableIndexFilterTable CREATE TABLE IndexFilterTable (FilterAttributeId INTEGER, IndexId INTEGER)s ++tableFileFilterTableFileFilterTable CREATE TABLE FileFilterTable (FilterAttributeId INTEGER, FileId INTEGER)z ''3tableContentsTableContentsTable CREATE TABLE ContentsTable (Id INTEGER PRIMARY KEY, NamespaceId INTEGER, Data BLOB) !! tableIndexTableIndexTable CREATE TABLE IndexTable (Id INTEGER PRIMARY KEY, Name TEXT, Identifier TEXT, NamespaceId INTEGER, FileId INTEGER, Anchor TEXT)''MtableFileNameTableFileNameTable CREATE TABLE FileNameTable (FolderId INTEGER, Name TEXT, FileId INTEGER PRIMARY KEY, Title TEXT)e'' tableSettingsTableSettingsTableCREATE TABLE SettingsTable (Key TEXT PRIMARY KEY, Value BLOB )9M'�indexsqlite_autoindex_SettingsTable_1SettingsTable�������h##tableFilterTableFilterTableCREATE TABLE FilterTable (NameId INTEGER, FilterAttributeId INTEGER )l++tableFilterNameTableFilterNameTableCREATE TABLE FilterNameTable (Id INTEGER PRIMARY KEY, Name TEXT ){55tableFilterAttributeTableFilterAttributeTableCREATE TABLE FilterAttributeTable (Id INTEGER PRIMARY KEY, Name TEXT )u##1tableFolderTableFolderTableCREATE TABLE FolderTable (Id INTEGER PRIMARY KEY, NamespaceId INTEGER, Name TEXT )x))+tableNamespaceTableNamespaceTableCREATE TABLE NamespaceTable (Id INTEGER PRIMARY KEY, Name TEXT, FilePath TEXT ) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������3octave.community.ioio.qch �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� doc �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ���#�{fS>#�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������9FullTextSearchFallback%CreationTimeh) HideAddressBar- EnableAddressBarA EnableDocumentationManager; HideFilterFunctionality? EnableFilterFunctionality*-;LastRegisterTime2025-04-28T21:12:29.330 ���?�Z~?k���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������9FullTextSearchFallback%CreationTime)HideAddressBar-EnableAddressBarAEnableDocumentationManager;HideFilterFunctionality?EnableFilterFunctionality- LastRegisterTime ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �io.cssio.css1 �Wio.htmlOctave io - io package for GNU octave ���( �XC"nW>! v ] F /  o H ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(�� 'test_spshtest_005fspsh%'�'� /io_testscriptio_005ftestscript&�� parsecellparsecell=%�;� Kchk_spreadsheet_supportchk_005fspreadsheet_005fsupport%$�+� +calccelladdresscalccelladdress#�� odswriteodswrite"�� odsreadodsread!�� odsopenodsopen �� odsfinfoodsfinfo�� odscloseodsclose�� ods2octods2oct�� oct2odsoct2ods�� xlswritexlswrite�� xlsreadxlsread�� xlsopenxlsopen�� xlsfinfoxlsfinfo�� xlsclosexlsclose�� xls2octxls2oct�� oct2xlsoct2xls�� xmlwritexmlwrite�� xmlreadxmlread�� tidyxmltidyxml�!� !getxmlnodegetxmlnode�!� !getxmlattvgetxmlattv�� dbfwritedbfwrite�� dbfreaddbfread�!� !csvexplodecsvexplode �� csvconcatcsvconcat �� csv2cellcsv2cell �� cell2csvcell2csv' �)� 1write_namelistwrite_005fnamelist �%� %utf82unicodeutf82unicode�%� %unicode2utf8unicode2utf8�� toJSONtoJSON%�'� /read_namelistread_005fnamelist�� pch2matpch2mat�� fromJSONfromJSON�� rfsearchrfsearch�� fexistfexist!�#� +append_saveappend_005fsave ��� V� V����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� @��������i�o�.�h�t�m�l���X�O�c�t�a�v�e� �i�o� �-� �i�o� �p�a�c�k�a�g�e� �f�o�r� �G�N�U� �o�c�t�a�v�e� �M�a�n�u�a�l������ �i�o�.�h�t�m�l�#�O�v�e�r�v�i�e�w����1� �O�v�e�r�v�i�e�w������<�i�o�.�h�t�m�l�#�I�n�s�t�a�l�l�i�n�g�-�a�n�d�-�l�o�a�d�i�n�g���0�2� �I�n�s�t�a�l�l�i�n�g� �a�n�d� �l�o�a�d�i�n�g������.�i�o�.�h�t�m�l�#�W�i�n�d�o�w�s�-�i�n�s�t�a�l�l���&�2�.�1� �W�i�n�d�o�w�s� �i�n�s�t�a�l�l������$�i�o�.�h�t�m�l�#�I�n�s�t�a�l�l�i�n�g����2�.�2� �I�n�s�t�a�l�l�i�n�g�������i�o�.�h�t�m�l�#�L�o�a�d�i�n�g����2�.�3� �L�o�a�d�i�n�g������4�i�o�.�h�t�m�l�#�F�u�n�c�t�i�o�n�-�R�e�f�e�r�e�n�c�e���(�3� �F�u�n�c�t�i�o�n� �R�e�f�e�r�e�n�c�e������.�i�o�.�h�t�m�l�#�F�i�l�e�-�O�p�e�r�a�t�i�o�n�s���&�3�.�1� �F�i�l�e� �O�p�e�r�a�t�i�o�n�s������.�i�o�.�h�t�m�l�#�a�p�p�e�n�d�_�0�0�5�f�s�a�v�e���"�3�.�1�.�1� �a�p�p�e�n�d�_�s�a�v�e�������i�o�.�h�t�m�l�#�f�e�x�i�s�t����3�.�1�.�2� �f�e�x�i�s�t������ �i�o�.�h�t�m�l�#�r�f�s�e�a�r��� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������" 3io.qch`�2025-04-28T21:12:29 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� � �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������doc ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������c�h����3�.�1�.�3� �r�f�s�e�a�r�c�h������T�i�o�.�h�t�m�l�#�M�i�s�c�e�l�l�a�n�e�o�u�s�-�C�o�n�v�e�r�s�i�o�n�-�F�u�n�c�t�i�o�n�s���L�3�.�2� �M�i�s�c�e�l�l�a�n�e�o�u�s� �C�o�n�v�e�r�s�i�o�n� �F�u�n�c�t�i�o�n�s������ �i�o�.�h�t�m�l�#�f�r�o�m�J�S�O�N����3�.�2�.�1� �f�r�o�m�J�S�O�N�������i�o�.�h�t�m�l�#�p�c�h�2�m�a�t����3�.�2�.�2� �p�c�h�2�m�a�t������2�i�o�.�h�t�m�l�#�r�e�a�d�_�0�0�5�f�n�a�m�e�l�i�s�t���&�3�.�2�.�3� �r�e�a�d�_�n�a�m�e�l�i�s�t�������i�o�.�h�t�m�l�#�t�o�J�S�O�N����3�.�2�.�4� �t�o�J�S�O�N������(�i�o�.�h�t�m�l�#�u�n�i�c�o�d�e�2�u�t�f�8���$�3�.�2�.�5� �u�n�i�c�o�d�e�2�u�t�f�8������(�i�o�.�h�t�m�l�#�u�t�f�8�2�u�n�i�c�o�d�e���$�3�.�2�.�6� �u�t�f�8�2�u�n�i�c�o�d�e������4�i�o�.�h�t�m�l�#�w�r�i�t�e�_�0�0�5�f�n�a�m�e�l�i�s�t���(�3�.�2�.�7� �w�r�i�t�e�_�n�a�m�e�l�i�s�t������4�i�o�.�h�t�m�l�#�C�S�V�-�F�i�l�e�-�F�u�n�c�t�i�o�n�s���,�3�.�3� �C�S�V� �F�i�l�e� �F�u�n�c�t�i�o�n�s������ �i�o�.�h�t�m�l�#�c�e�l�l�2�c�s�v����3�.�3�.�1� �c�e�l�l�2�c�s�v������ �i�o�.�h�t�m�l�#�c�s�v�2�c�e�l�l����3�.�3�.�2� �c�s�v�2�c�e�l�l������"�i�o�.�h�t�m�l�#�c�s�v�c�o�n�c�a�t����3�.�3�.�3� �c�s�v�c�o�n�c�a�t������$�i�o�.�h�t�m�l�#�c�s�v�e�x�p�l�o�d�e��� �3�.�3�.�4� �c�s�v�e�x�p�l�o�d�e������&�i�o�.�h�t�m�l�#�D�B�F�-�I�_�0�0�2�f�O����3�.�4� �D�B�F� �I�/�O�������i�o�.�h�t�m�l�#�d�b�f�r�e�a�d����3�.�4�.�1� �d�b�f�r�e�a�d������ �i�o�.�h�t�m�l�#�d�b�f�w�r�i�t�e����3�.�4�.�2� �d�b�f�w�r�i�t�e������&�i�o�.�h�t�m�l�#�X�M�L�-�I�_�0�0�2�f�O����3�.�5� �X�M�L� �I�/�O������$�i�o�.�h�t�m�l�#�g�e�t�x�m�l�a�t�t�v��� �3�.�5�.�1� �g�e�t�x�m�l�a�t�t�v������$�i�o�.�h�t�m�l�#�g�e�t�x�m�l�n�o�d�e��� �3�.�5�.�2� �g�e�t�x�m�l�n�o�d�e�������i�o�.�h�t�m�l�#�t�i�d�y�x�m�l����3�.�5�.�3� �t�i�d�y�x�m�l�������i�o�.�h�t�m�l�#�x�m�l�r�e�a�d����3�.�5�.�4� �x�m�l�r�e�a�d������ �i�o�.�h�t�m�l�#�x�m�l�w�r�i�t�e����3�.�5�.�5� �x�m�l�w�r�i�t�e�������i�o�.�h�t�m�l�#�S�p�r�e�a�d�s�h�e�e�t�-�I�_�0�0�2�f�O�-�U�s�e�r�-�F�u�n�c�t�i�o�n�s�-�F�o�r�-�_�0�0�2�e�x�l�s�_�0�0�2�f�_�0�0�2�e�x�l�s�x���b�3�.�6� �S�p�r�e�a�d�s�h�e�e�t� �I�/�O� �U�s�e�r� �F�u�n�c�t�i�o�n�s� �F�o�r� �.�x�l�s�/�.�x�l�s�x�������i�o�.�h�t�m�l�#�o�c�t�2�x�l�s����3�.�6�.�1� �o�c�t�2�x�l�s�������i�o�.�h�t�m�l�#�x�l�s�2�o�c�t����3�.�6�.�2� �x�l�s�2�o�c�t������ �i�o�.�h�t�m�l�#�x�l�s�c�l�o�s�e����3�.�6�.�3� �x�l�s�c�l�o�s�e������ �i�o�.�h�t�m�l�#�x�l�s�f�i�n�f�o����3�.�6�.�4� �x�l�s�f�i�n�f�o�������i�o�.�h�t�m�l�#�x�l�s�o�p�e�n����3�.�6�.�5� �x�l�s�o�p�e�n�������i�o�.�h�t�m�l�#�x�l�s�r�e�a�d����3�.�6�.�6� �x�l�s�r�e�a�d������ �i�o�.�h�t�m�l�#�x�l�s�w�r�i�t�e����3�.�6�.�7� �x�l�s�w�r�i�t�e������n�i�o�.�h�t�m�l�#�S�p�r�e�a�d�s�h�e�e�t�-�I�_�0�0�2�f�O�-�U�S�e�r�-�F�u�n�c�t�i�o�n�s�-�F�o�r�-�_�0�0�2�e�o�d�s���V�3�.�7� �S�p�r�e�a�d�s�h�e�e�t� �I�/�O� �U�S�e�r� �F�u�n�c�t�i�o�n�s� �F�o�r� �.�o�d�s�������i�o�.�h�t�m�l�#�o�c�t�2�o�d�s����3�.�7�.�1� �o�c�t�2�o�d�s�������i�o�.�h�t�m�l�#�o�d�s�2�o�c�t����3�.�7�.�2� �o�d�s�2�o�c�t������ �i�o�.�h�t�m�l�#�o�d�s�c�l�o�s�e����3�.�7�.�3� �o�d�s�c�l�o�s�e������ �i�o�.�h�t�m�l�#�o�d�s�f�i�n�f�o����3�.�7�.�4� �o�d�s�f�i�n�f�o�������i�o�.�h�t�m�l�#�o�d�s�o�p�e�n����3�.�7�.�5� �o�d�s�o�p�e�n�������i�o�.�h�t�m�l�#�o�d�s�r�e�a�d����3�.�7�.�6� �o�d�s�r�e�a�d������ �i�o�.�h�t�m�l�#�o�d�s�w�r�i�t�e����3�.�7�.�7� �o�d�s�w�r�i�t�e������J�i�o�.�h�t�m�l�#�S�p�r�e�a�d�s�h�e�e�t�-�U�t�i�l�i�t�y�-�F�u�n�c�t�i�o�n�s���B�3�.�8� �S�p�r�e�a�d�s�h�e�e�t� �U�t�i�l�i�t�y� �F�u�n�c�t�i�o�n�s������.�i�o�.�h�t�m�l�#�c�a�l�c�c�e�l�l�a�d�d�r�e�s�s���*�3�.�8�.�1� �c�a�l�c�c�e�l�l�a�d�d�r�e�s�s������N�i�o�.�h�t�m�l�#�c�h�k�_�0�0�5�f�s�p�r�e�a�d�s�h�e�e�t�_�0�0�5�f�s�u�p�p�o�r�t���:�3�.�8�.�2� �c�h�k�_�s�p�r�e�a�d�s�h�e�e�t�_�s�u�p�p�o�r�t������"�i�o�.�h�t�m�l�#�p�a�r�s�e�c�e�l�l����3�.�8�.�3� �p�a�r�s�e�c�e�l�l������H�i�o�.�h�t�m�l�#�S�p�r�e�a�d�s�h�e�e�t�-�F�u�n�c�t�i�o�n�-�T�e�s�t�i�n�g���@�3�.�9� �S�p�r�e�a�d�s�h�e�e�t� �F�u�n�c�t�i�o�n� �T�e�s�t�i�n�g������2�i�o�.�h�t�m�l�#�i�o�_�0�0�5�f�t�e�s�t�s�c�r�i�p�t���&�3�.�9�.�1� �i�o�_�t�e�s�t�s�c�r�i�p�t������*�i�o�.�h�t�m�l�#�t�e�s�t�_�0�0�5�f�s�p�s�h����3�.�9�.�2� �t�e�s�t�_�s�p�s�hio-2.7.0/doc/PaxHeaders/macros.texi�����������������������������������������������������������������0000644�0000000�0000000�00000000062�15004725440�014134� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������20 atime=1746119456 30 ctime=1746119684.377810908 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������io-2.7.0/doc/macros.texi����������������������������������������������������������������������������0000644�0001750�0001750�00000006241�15004725440�014453� 0����������������������������������������������������������������������������������������������������ustar�00philip��������������������������philip�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@c Copyright (C) 2012-2019 John W. Eaton @c @c This file is part of Octave. @c @c Octave is free software: you can redistribute it and/or modify it @c under the terms of the GNU General Public License as published by @c the Free Software Foundation, either version 3 of the License, or @c (at your option) any later version. @c @c Octave is distributed in the hope that it will be useful, but @c WITHOUT ANY WARRANTY; without even the implied warranty of @c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @c GNU General Public License for more details. @c @c You should have received a copy of the GNU General Public License @c along with Octave; see the file COPYING. If not, see @c <https://www.gnu.org/licenses/>. @c The following macro marks words that aspell should ignore during @c spellchecking. Within Texinfo it has no effect as it merely replaces @c the macro call with the argument itself. @macro nospell {arg} \arg\ @end macro @c The following macro works around the Info/plain text expansion of @code{XXX} @c which is `XXX'. This looks particularly bad when the macro body is @c single or double-quoted text, such as a property value `"position"' @ifinfo @macro qcode{arg} \arg\ @end macro @end ifinfo @ifnotinfo @macro qcode{arg} @code{\arg\} @end macro @end ifnotinfo @c The following macro is used for the on-line help system, but we don't @c want lots of `See also: foo, bar, and baz' strings cluttering the @c printed manual (that information should be in the supporting text for @c each group of functions and variables). @c @c Implementation Note: @c For TeX, @vskip produces a nice separation. @c For Texinfo, '@sp 1' should work, but in practice produces ugly results @c for HTML. We use a simple blank line to produce the correct @c behavior. @c @c We use @xseealso now because Texinfo introduced its own @seealso @c command. But instead of modifying all source files, we'll have the @c munge-texi script convert @seealso to @xseealso. @macro xseealso {args} @iftex @vskip 2pt @end iftex @ifnottex @end ifnottex @ifnotinfo @noindent @strong{See also:} \args\. @end ifnotinfo @ifinfo @noindent See also: \args\. @end ifinfo @end macro @c The following macro works around a situation where the Info/plain text @c expansion of the @code{XXX} macro is `XXX'. The use of the apostrophe @c can be confusing if the code segment itself ends with a transpose operator. @ifinfo @macro tcode{arg} \arg\ @end macro @end ifinfo @ifnotinfo @macro tcode{arg} @code{\arg\} @end macro @end ifnotinfo @c FIXME: someday, when Texinfo 5.X is standard, we might replace this with @c @backslashchar, which is a new addition to Texinfo. @macro xbackslashchar \\ @end macro @c These may be useful for all, not just for octave.texi. @tex \ifx\rgbDarkRed\thisisundefined \def\rgbDarkRed{0.50 0.09 0.12} \fi \ifx\linkcolor\thisisundefined \relax \else \global\def\linkcolor{\rgbDarkRed} \fi \ifx\urlcolor\thisisundefined \relax \else \global\def\urlcolor{\rgbDarkRed} \fi \ifx\urefurlonlylinktrue\thisisundefined \relax \else \global\urefurlonlylinktrue \fi @end tex @c Make the apostrophe in code examples cut-and-paste friendly. @codequoteundirected on ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������io-2.7.0/doc/PaxHeaders/io.info���������������������������������������������������������������������0000644�0000000�0000000�00000000062�15004725440�013241� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������20 atime=1746119456 30 ctime=1746119684.377810908 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������io-2.7.0/doc/io.info��������������������������������������������������������������������������������0000644�0001750�0001750�00000241411�15004725440�013560� 0����������������������������������������������������������������������������������������������������ustar�00philip��������������������������philip�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is io.info, produced by makeinfo version 7.1.1 from io.texi. INFO-DIR-SECTION Math START-INFO-DIR-ENTRY * Octave io: (io). io package for Octave END-INFO-DIR-ENTRY  File: io.info, Node: Top, Next: Overview, Up: (dir) Octave io package ***************** Copyright © The Octave Project Developers Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions. * Menu: * Overview:: * Installing and loading:: * Function Reference:: -- The Detailed Node Listing -- Function Reference * File Operations:: * Miscellaneous Conversion Functions:: * CSV File Functions:: * DBF I/O:: * XML I/O:: * Spreadsheet I/O User Functions For .xls/.xlsx:: * Spreadsheet I/O USer Functions For .ods:: * Spreadsheet Utility Functions:: * Spreadsheet Function Testing::  File: io.info, Node: Overview, Next: Installing and loading, Prev: Top, Up: Top 1 Overview ********** The io package contains functions for reading and writing various type of data files.  File: io.info, Node: Installing and loading, Next: Function Reference, Prev: Overview, Up: Top 2 Installing and loading ************************ The io package must be installed and then loaded to be used. It can be installed in GNU Octave directly from octave-forge, 2.1 Windows install =================== If running in Windows, the package may already be installed, to check run: pkg list io 2.2 Installing ============== With an internet connection available, the io package can be installed from octave-forge using the following command within GNU Octave: pkg install io The latest released version of the package will be downloaded and installed. Otherwise, if the package file has already been downloaded it can be installed using the follwoing command in GNU Octave: pkg install io-2.7.0.tar.gz 2.3 Loading =========== Regardless of the method of installing the package, in order to use its functions, the package must be loaded using the pkg load command: pkg load io The package must be loaded on each GNU Octave session.  File: io.info, Node: Function Reference, Prev: Installing and loading, Up: Top 3 Function Reference ******************** * Menu: * File Operations:: * Miscellaneous Conversion Functions:: * CSV File Functions:: * DBF I/O:: * XML I/O:: * Spreadsheet I/O User Functions For .xls/.xlsx:: * Spreadsheet I/O USer Functions For .ods:: * Spreadsheet Utility Functions:: * Spreadsheet Function Testing::  File: io.info, Node: File Operations, Next: Miscellaneous Conversion Functions, Up: Function Reference 3.1 File Operations =================== 3.1.1 append_save ----------------- -- Function File: RVAL = append_save (FILENAME, OPTION, VAR_VAL_CELL, VARARGIN) Add variables to existing save files. Works for all the types of save files that "save" supports. Input: • FILENAME, a string which specifies the existing save file. • OPTION, the options you need to pass to the 'save' function to save to the file type that you want. • VAR_VAL_CELL, 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. • VARARGIN, 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. octave> B = ones(2,2); octave> append_save( "test.txt", "-binary", {"B", B } ) 3.1.2 fexist ------------ -- Function File: ex = fexist (file, tspec, aspec) Checks whether a file exists. FILE is the queried file path. TSPEC is a combination of letters f,d,p,S, corresponding to file types: • f: regular file • d: directory • p: named pipe (FIFO special file) • S: socket The query is true if the actual file type matches any of the specified options. 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 specified types of access, either through "user", "group" or "other" specs. See also: stat, lstat. 3.1.3 rfsearch -------------- -- Function File: FILENAME = rfsearch (DNAME, FNPATTERN) -- Function File: FILENAME = rfsearch (DNAME, FNPATTERN, MAXDEPTH) Recursive File Search - search for file or filename pattern FNPATTERN starting in directory DNAME and return the first match. • DNAME, FNPATTERN Must be character strings and should conform to the directory name and filename requirements of your operating system. • MAXDEPTH (optional) can be specified to limit the maximum search depth; the default value is 1 (search only in DNAME and subdirs of DNAME). Setting maxdepth to 0 limits the search to DNAME. Be careful with setting 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 FILENAME returns the relative file path of the first match, relative to DNAME, or an empty character string if no match was found. Examples: filename = rfsearch ("/home/guest/octave", "test.fil") Look for file test.fil and start the search in /home/guest/octave 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 See also: dir, glob.  File: io.info, Node: Miscellaneous Conversion Functions, Next: CSV File Functions, Prev: File Operations, Up: Function Reference 3.2 Miscellaneous Conversion Functions ====================================== 3.2.1 fromJSON -------------- -- : OBJ = fromJSON (STR) -- : OBJ = fromJSON (STR, SARRAY) Convert a JSON string into a native Octave object. fromJSON especially strives to convert numerical JSON arrays into Octave vector, matrix or ND array. Special provisions are made to recognize +/-Inf, NaN and complex numbers, which are conventionally not permited in JSON strings. Input arguments: • STR is a JSON string. • SARRAY, (default TRUE) logical value that determines how JSON member arrays are parsed. Setting it to FALSE is recommended for safer parsing of non-numerical, mixed-class or mixed-size arrays JSON payloads. Leave SARRAY set to TRUE for fast parsing of numerical JSON arrays and objects. Octave vectors, matrices, ND arrays and struct arrays are returned as much as possible, otherwise returned as a combination of vectors/matrices and cell arrays. Set SARRAY to FALSE if, with fast parsing, output does not match expections, particularly if STR mainly comprises JSON objects/arrays with strings. All JSON member arrays are returned as (nested) Octave cell arrays. Output: • OBJ is a native Octave object. JSON number, logical, array, and object strings are converted to Octave numbers, logicals, vectors and structs, respectively. Quoted or unrecognizable JSON fragments are returned as NaN values. Special numbers: The specification for JSON does not allow +/-Inf, NaN or complex numbers; nevertheless, provisions are made here to enable these important numbers: • JSON number strings '+/-1e308' are rounded to +/-Inf. • Unquoted JSON string 'null' is converted to NaN. • JSON objects, or arrays thereof, with exclusive members "real" and "imag" (or "re" and "im") will be converted to Octave complex numbers, vectors or matrices, respectively. e.g. '{"re":3,"im":1}' => 3 + 1i '[1,{"re":3,"im":1}]' => [ 1 + 0i, 3 + 1i ] See also: toJSON. 3.2.2 pch2mat ------------- -- Function File: DATA = pch2mat (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. E.g. data.S1.p254686.x and they are n x 2. 3.2.3 read_namelist ------------------- -- function file: S = read_namelist (FILENAME) 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. NMLST = read_namelist ("OPTIONS.nam"); NMLST.NAM_FRAC.XUNIF_NATURE = 0.1; write_namelist(NMlST, "MOD_OPTIONS.nam"); 3.2.4 toJSON ------------ -- : STR = toJSON (OBJ) -- : STR = toJSON (OBJ, PREC) -- : STR = toJSON (OBJ, COMPACT) -- : STR = toJSON (OBJ, PREC, COMPACT) Convert any Octave OBJ into a compact JSON string. toJSON strives to convert Octave vectors, matrices and/or ND arrays to equivalent JSON arrays. Special provisions are made to handle +/-Inf and complex numbers, which are conventionally not permitted is JSON string. Input arguments: • OBJ, any Octave object: double, float, int, logical, complex, char, etc. There are no limitations on the class accepted, but classes not permitted in JSON are merely referenced by classname, along the lines of ‘"[octave_com_object]"’, and the contents are lost. • PREC, a numeric value, specifies number of significant digits for number-to-string conversion. The default value of PREC is 15. • COMPACT (logical; default value is FALSE) specifies whether to return Octave struct arrays as arrays of JSON objects or JSON objects of arrays. Consider an Octave struct array with fields 'x' and 'y': Leaving as FALSE returns a JSON array of objects, i.e.: '[{"x": ..., "y": ...}, {"x": ..., "y": ...}]' • Changing to TRUE returns a JSON object of arrays, i.e.: '{"x": [...], "y": [...]}' Special cases: The specification for JSON does not allow +/-Inf or complex numbers; nevertheless, provisions are made here to enable these important numbers: • Octave numbers +/-Inf return as numeric string '+/-1e999' which should automatically revert to +/-Inf when parsed. • Complex numbers return as JSON object ‘{"re":..., "im":...}’ Apparent JSON strings are left unquoted. This allows recursive use of toJSON. To prevent this, append a whitespace to the string. The bodies of Octave inline functions are stored as string; however, reference to values external to inline function will be lost. e.g. @(x) a*x => "@@(x) a*x" See also: fromJSON. 3.2.5 unicode2utf8 ------------------ -- : [OSTR, ERROR_FLAG] = unicode2utf8 (USTR) Convert from Unicode code points USTR to UTF-8 encoded string OSTR. It is not possible to convert Unicode characters with a codepoint higher than 255 because Octave's ‘char’ type is 8-bit wide. This means that only the ISO 8859-1 (Latin-1) subset of Unicode can be mapped correctly. If an error occured ERROR_FLAG is set to true. 3.2.6 utf82unicode ------------------ -- : [USTR, ERROR_FLAG] = utf82unicode (ISTR) Convert from UTF-8 encoded strings ISTR to Unicode codepoints USTR. UTF-8 characters with more than 2 bytes are dropped since Octave does not support characters >255. This means that only the ISO 8859-1 (Latin-1) subset of Unicode can be mapped correctly. If an error occured ERROR_FLAG is set to true. 3.2.7 write_namelist -------------------- -- function file: RET = weite_namelist (S) 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");  File: io.info, Node: CSV File Functions, Next: DBF I/O, Prev: Miscellaneous Conversion Functions, Up: Function Reference 3.3 CSV File Functions ====================== 3.3.1 cell2csv -------------- -- Loadable Function: cell2csv (FILE, C) -- Loadable Function: cell2csv (FILE, C, SEP) -- Loadable Function: cell2csv (FILE, C, SEP, PROT) Create a CSV file from a cell array. SEP (character value) changes the character used to separate two fields. The default value is a comma (‘,’). PROT (character value) changes the character used to protect a string. Default value is a double quote (‘"’). 3.3.2 csv2cell -------------- -- Loadable Function: C = csv2cell (FILE) -- Loadable Function: C = csv2cell (FILE, SEP) -- Loadable Function: C = csv2cell (FILE, SEP, PROT) -- Loadable Function: C = csv2cell (FILE, HL, ...) -- Loadable Function: C = csv2cell (FILE, RANGE, ...) Read a CSV (Comma Separated Values) file and convert it into a cell array. SEP (a character value) changes the character used to separate two fields. The default value is a comma (‘,’). PROT (a character value) changes the character used to protect a string. The default is a double quote (‘"’). Optional argument HL (a numeric value >= 0) is the number of headerlines to skip; negative values are ignored. If HL is equal to or larger than the total number of lines in the file, no data is read and an empty cell array is returned. Alternatively, optional argument RANGE can be specified as a spreadsheet-style cell range to specify a block of fields to be returned in 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. 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. Note: newline characters in fields (i.e., multi-line text fields) are not allowed. The maximum line width of the csv file is set to 32768 characters. (This is also the theoretical maximum number of columns - 1 in the data if all fields are empty, i.e., a line containing just 32768 consecutive separators will yield 32769 empty values.) 3.3.3 csvconcat --------------- -- Loadable Function: STR = csvconcat (C) -- Loadable Function: STR = csvconcat (C, SEP) -- Loadable Function: STR = csvconcat (C, SEP, PROT) Concatenate a cell into a CSV string or array of strings. SEP (character value) changes the character used to separate two fields. The default value is a comma (‘,’). PROT (character value) changes the character used to protect a string. The default is a double quote (‘"’). 3.3.4 csvexplode ---------------- -- Loadable Function: C = csvexplode (STR) -- Loadable Function: C = csvexplode (STR, SEP) -- Loadable Function: C = csvexplode (STR, SEP, PROT) Explode a CSV string into a cell. SEP (character value) changes the character used to separate two fields. The default value is a comma (‘,’). PROT (character value) changes the character used to protect a string. The default is a double quote (‘"’).  File: io.info, Node: DBF I/O, Next: XML I/O, Prev: CSV File Functions, Up: Function Reference 3.4 DBF I/O =========== 3.4.1 dbfread ------------- -- Function File: [DATA, DATINFO] = dbfread (FNAME) -- Function File: [DATA, DATINFO] = dbfread (FNAME, RECS) -- Function File: [DATA, DATINFO] = dbfread (FNAME, RECS, COLS) -- Function File: [DATA, DATINFO] = dbfread (FNAME, RECS, COLS, RE) Read contents of a dbase (dbf) file, provisionally dbase III+, IV or V. • FNAME should be the name of a valid dbase file; the file extension isn't required. • 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 RECS can be specified in any order, but the returned data are sorted in order of records in the file. • 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. COLS entries can be supplied in any order, yet the returned data column order matches that of the columns order in the dbase file. Requested column names that don't exist in the .dbf file are simply ignored. For dbase files containing multiple columns with the same name, specify a numeric or logical array to select columns to be returned. If COLS is omitted or empty, data from all file columns are returned. • If a value of 1 or true is entered for 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. The default value of RE is false. • Return value DATA is a N+1 x M cellstr array where the uppermost row contains the column names and the rest of the rows comprise the record data. • Optional return argument DATINFO is a struct array containing various information of the dbase file and record build-up. Arguments RECS and 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 RECS or COLS (if supplied) is exhausted. Sometimes dbase files contain records indicated as being erased. The data in such records is silently skipped, unless the RE flag is set and/or RECS is supplied and erased records happen to be present in the requested record numbers. Examples: A = dbfread ("file.dbf"); (returns all data in file.dbf in array A) [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) 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) A = dbfread ("file", [0 1 0 0 1 0]); (returns data from record numbers 2 and 5 in file.dbf in array A) [~, B] = dbfread ("file.dbf", 0); (to returns info on column names and number of records, plus more info) [A] = dbfread ("file", [], {"Header1", "Col5"}); (returns data from columns with names (headers) Header1 and Col5, resp.) See also: xlsread. 3.4.2 dbfwrite -------------- -- Function File: [STATUS] = dbfwrite (FNAME, DATA) Write data in a cell array to a dbf (xBase) file, provisionally dBase III+. FNAME must be a valid file name, optionally with '.dbf' suffix. DATA should be a cell array of which the top row contains column names (character strings, each max. 10 characters; longer column names will be truncated). Each column must contain only one class of data, except of course the top entry (the column header). Integers interspersed in double type colums will be written as doubles. Data types that can be written are character (text string), numeric (integer and float, the latter with 6 decimal places), and logical. Output argument STATUS is 1 if the file was written successfully, -1 if one or more data columns were skipped, 0 otherwise. If 0 the incomplete file will be deleted as well. Provisionally only dBase v. III+ files without memos can be written. See also: dbfread.  File: io.info, Node: XML I/O, Next: Spreadsheet I/O User Functions For .xls/.xlsx, Prev: DBF I/O, Up: Function Reference 3.5 XML I/O =========== 3.5.1 getxmlattv ---------------- -- Function File: [RETVAL] = getxmlattv (XMLNODE, ATT) Get value of attribute ATT in xml node (char string) XMLNODE, return empty if attribute isn't present. See also: getxmlnode. 3.5.2 getxmlnode ---------------- -- Function File: [ NODE, S, E ] = getxmlnode (XML, TAG) -- Function File: [ NODE, S, E ] = getxmlnode (XML, TAG, IS) -- Function File: [ NODE, S, E ] = getxmlnode (XML, TAG, IS, CONTNT) Get a string representing the first xml TAG node starting at position IS in xml text string XML, and return start and end indices. If IS is omitted it defaults to 1 (start of XML). If CONTNT is TRUE, return the portion of the node between the outer tags. See also: getxmlattv. 3.5.3 tidyxml ------------- -- : OSTR = tidyxml (ISTR, CONV_FCN) Optionally convert character using the function handle in CONV_FCN, remove characters (<32 >255) from text string or cell array ISTR and return the result in 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. 3.5.4 xmlread ------------- -- Function File: NODE = xmlread (FNAME) Parse an xml file 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: javaaddpath ("/path/to/xerces-2_11_0/xercesImpl.jar"); javaaddpath ("/path/to/xerces-2_11_0/xml-apis.jar"); 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. See also: xmlwrite. 3.5.5 xmlwrite -------------- -- Function File: xmlwrite (FNAME, DOM) -- Function File: STR = xmlwrite (DOM) Write an XML DOM document to file FNAME or to output string STR. The DOM argument must be a DOM document object as returned by ‘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: javaaddpath ("/path/to/xerces-2_11_0/xercesImpl.jar"); javaaddpath ("/path/to/xerces-2_11_0/xml-apis.jar"); 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. See also: xmlread.  File: io.info, Node: Spreadsheet I/O User Functions For .xls/.xlsx, Next: Spreadsheet I/O USer Functions For .ods, Prev: XML I/O, Up: Function Reference 3.6 Spreadsheet I/O User Functions For .xls/.xlsx ================================================= 3.6.1 oct2xls ------------- -- Function File: [ XLS, RSTATUS ] = oct2xls (ARR, XLS) -- Function File: [ XLS, RSTATUS ] = oct2xls (ARR, XLS, WSH) -- Function File: [ XLS, RSTATUS ] = oct2xls (ARR, XLS, WSH, RANGE) -- Function File: [ XLS, RSTATUS ] = oct2xls (ARR, XLS, WSH, RANGE, OPTIONS) Add data in 1D/2D CELL array ARR into a cell range RANGE in worksheet WSH in a spreadsheet file pointed to in structure XLS. Return argument XLS equals supplied argument 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 LibreOffice (OOo) or Excel invocation). 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. XLS must be a valid pointer struct created earlier by xlsopen. WSH can be a number or string (max. 31 chars for .xlsx/.xls files). If it is numeric it refers to the position in the total sheet stack incl. e.g., chartsheets. In case of existing files, some checks are made for existing worksheet names or numbers, or whether WSH refers to an existing sheet with a type other than worksheet (e.g., chart). When new worksheets are to be added to the spreadsheet file, they are inserted to the right of all existing worksheets. The pointer to the "active" sheet (shown when opened in a spreadsheet program) remains untouched. If 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 ARR. If nothing is specified for 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 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 RANGE contains merged cells, only the elements of ARR corresponding to the top or left spreadsheet cells of those merged cells will be written, other array cells corresponding to that cell will be ignored. Optional argument OPTIONS, a structure, can be used to specify various write modes. "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 literal text strings rather than as spreadsheet formulas. (The latter is the default). '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. Beware that -if invoked- LibreOffice or Excel invocations may be left running silently in case of Java or COM errors. Invoke xlsclose with a proper pointer struct to try 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: [xlso, status] = oct2xls ('arr', xlsi, 'Third_sheet', 'AA31:AB278'); See also: xls2oct, xlsopen, xlsclose, xlsread, xlswrite, xlsfinfo. 3.6.2 xls2oct ------------- -- Function File: [ RAWARR, XLS, RSTATUS ] = xls2oct (XLS) -- Function File: [ RAWARR, XLS, RSTATUS ] = xls2oct (XLS, WSH) -- Function File: [ RAWARR, XLS, RSTATUS ] = xls2oct (XLS, WSH, RANGE) -- Function File: [ RAWARR, XLS, RSTATUS ] = xls2oct (XLS, WSH, RANGE, OPTIONS) Read data contained within cell range RANGE from worksheet WSH in a spreadsheet file pointed to in struct XLS. Spreadsheet file pointer XLS is supposed to have been created earlier by xlsopen in the same octave session. WSH is either numerical or text, in the latter case it is case-sensitive; for .xlsx and .xls formats it may be max. 31 characters long. Note that in case of a numerical WSH this number refers to the position in the total sheet stack, counted from the left in a spreadsheet program window. The default is numerical 1, i.e. corresponding to the leftmost sheet tab in the spreadsheet file. 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 WSH. If no range is specified or is specified as an empty string 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 inferred range can be outdated. The Java-based interfaces are more reliable in this respect albeit much slower. Optional argument 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: "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 latter if at all present in th spreadsheet). The default value is 0 (FALSE). "strip_array" Set the value of this field set to TRUE or 1 to strip the returned output array 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. "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. If only the first argument 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 WSH. In that case xls2oct will try to read all data contained in that worksheet. Return argument RAWARR contains the raw spreadsheet cell data. Use utility function parsecell() to separate numeric and text values from RAWARR. Optional return argument XLS contains the pointer struct. If any data were read, field XLS.limits contains the outermost column and row numbers of the actually returned cell range. Optional return argument 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 RAWARR. Date/time values in xlsx/.xls files 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 depend on interface and version of the support SW. Be aware that the COM interface trims RAWARR from empty outer rows & columns, so a returned cell array may turn out to be smaller than requested in RANGE, independent of field 'formulas_as_text' in 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 "Automatic calculation" settings when the spreadsheet was saved. When reading from merged cells, all array elements NOT corresponding to the leftmost or upper spreadsheet cell will be treated as if the "corresponding" spreadsheet cells are empty. Examples: 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) [An, xls2, status] = xls2oct (xls2, 'Third_sheet'); See also: oct2xls, xlsopen, xlsclose, parsecell, xlsread, xlsfinfo, xlswrite. 3.6.3 xlsclose -------------- -- Function File: [XLS] = xlsclose (XLS) -- Function File: [XLS] = xlsclose (XLS, FILENAME) -- Function File: [XLS] = xlsclose (XLS, "FORCE") Close a spreadsheet file pointed to in struct XLS, and if needed write file to disk. xlsclose will determine if the file should be written to disk based on information contained in XLS. If no errors occured during writing, the xls file pointer struct will be reset to empty and -if the UNO or COM interface was used- LibreOffice (or OpenOffice.org) or 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 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 LibreOffice.org (UNO) invocations may live on, possibly even impeding proper shutdown of Octave. FILENAME can be used to write changed spreadsheet files to a file other than that opened with xlsopen(); unfortunately this doesn't work with JXL (JExcelAPI) interface. For other file formats than OOXML, ODS or gnumeric, you need a Java JRE plus Apache POI > 3.5 and/or JExcelAPI, OpenXLS, jOpenDocument, ODF Toolkit and/or LibreOffice or clones, and/or the OF windows package + MS-Excel installed on your computer + proper javaclasspath set, to make this function work at all. XLS must be a valid pointer struct made by xlsopen() in the same octave session. Examples: xls1 = xlsclose (xls1); (Close spreadsheet file pointed to in pointer struct xls1; xls1 is reset) See also: xlsopen, xlsread, xlswrite, xls2oct, oct2xls, xlsfinfo. 3.6.4 xlsfinfo -------------- -- Function File: [FILETYPE] = xlsfinfo (FILENAME [, REQINTF]) -- Function File: [FILETYPE, SH_NAMES] = xlsfinfo (FILENAME [, REQINTF]) -- Function File: [FILETYPE, SH_NAMES, FFORMAT] = xlsfinfo (FILENAME [, REQINTF]) -- Function File: [FILETYPE, SH_NAMES, FFORMAT, NMRANGES] = xlsfinfo (FILENAME [, REQINTF]) -- Function File: [...] = xlsfinfo (..., VERBOSE) Query a spreadsheet file for some info about its contents. Inputs: • FILENAME is the name, or relative or absolute filename, of a spreadsheet file. • If multiple spreadsheet I/O interfaces have been installed, REQINTF can be specified to request a specific interface. If omitted xlsfinfo selects a suitable interface; see the help for xlsread for more information. • If optional argument VERBOSE (numerical or logical; always the last argument) is specified as logical 'true' or numerical 1, xlsfinfo echoes info about the spreadsheet I/O interface it uses. Outputs: • Return argument FILETYPE returns a string containing a general description of the spreadsheet file type: "Microsoft Excel Spreadsheet" for Excel spreadsheets, "OpenOffice.org Calc spreadsheet" for .ods spreadsheets, "Gnumeric spreadsheet" for Gnumeric spreeadsheets, or "̈ (empty string) for other or unrecognized spreadsheet formats. • If FILENAME is a recognized Excel, OpenOffice.org Calc or Gnumeric spreadsheet file, optional return argument SH_NAMES contains an Nx2 list (cell array) of sheet names contained in 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 return value FFORMAT currently returns "xlWorkbookNormal" for .xls formats, "xlOpenXMLWorkbook" for .xlsx, "xlCSV" for .csv, "GnumericWorkbook" for .gnumeric, "ODSWorkbook" for .ods, "StarOfficeWorkbook" for .sxc, or "̈ (empty) for other file formats. • Optional return argument 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 with the COM, POI, OXS and OCT interfaces, and with the UNO interface only properly for Excel files. If no return arguments are specified the sheet names are echoed to the terminal screen plus for each sheet the actual occupied data range. The occupied cell range will have to be determined behind the scenes first; this can take some time for some of the Java based interfaces. Any Named ranges defined in the spreadsheet file will be listed on screen as well. For OOXML spreadsheets no external SW is required but full POI and/or UNO and/or COM support (see xlsopen) may work better or faster; to use those specify "poi", "uno" or "com" for REQINTF. For Excel '95 files use "com" (windows only), "jxl", "oxs" or "uno". Gnumeric and ODS files can be explored with the built-in OCT interface (no need to specify REQINTF then) although again the COM, JOD, OTK or UNO interfaces may work faster, depending on a.o., the size of the file. Note that the JXL, OXS, OTK and JOD interfaces don't support Named ranges so when using these interfaces no information about Named ranges is returned. Examples: exist = xlsfinfo ('test4.xls'); (Just checks if file test4.xls is a readable Excel file) [exist, names] = xlsfinfo ('test4.ods'); (Checks if file test4.ods is a readable LibreOffice Calc file and returns a list of sheet names and types) See also: oct2xls, xlsread, xls2oct, xlswrite. 3.6.5 xlsopen ------------- -- Function File: XLS = xlsopen (FILENAME) -- Function File: XLS = xlsopen (FILENAME, READWRITE) -- Function File: XLS = xlsopen (FILENAME, READWRITE, REQINTF) -- Function File: XLS = xlsopen (FILENAME, READWRITE, REQINTF, VERB) Get a pointer to a spreadsheet in memory in the form of return argument (file pointer struct) XLS. Calling xlsopen without specifying a return argument is fairly useless and considered an error! After processing the spreadsheet, the file pointer must be explicitly closed by calling xlsclose() to release possibly large amounts of RAM. FILENAME should be a valid spreadsheet file name (including extension); see "help xlsread" for an overview of supported spreadsheet file formats. If READWRITE is set to 0 (default value) or omitted, the spreadsheet file is opened for reading. If READWRITE is set to true or 1, a spreadsheet file is opened (or created) for reading & writing. Optional input argument REQINTF can be used to override the spreadsheet I/O interface (see below) that otherwise would automatically be selected by xlsopen. In most situations this parameter is unneeded as xlsopen automatically selects the most useful interface present, depending on installed external support software and requested file type. A user-specified interface selection can be reset to default by entering a numeric value of -1. If a value of 1 or true is entered for VERB, xlsopen returns info about the spreadsheet I/O interfaces that were found and/or are requested and active. The default value is false (no info on interfaces is shown). Spreadsheet I/O Interfaces ========================== xlsopen works with interfaces, which are links to support software, mostly external. The built-in 'OCT' interface needs no external software and allows I/O from/to OOXML (Excel 2007 and up), ODS 1.2 and Gnumeric. For all other spreadsheet formats, or if you want more speed and/or more flexibility, additional external software is required. See "help xlsread" for more info. Currently implemented interfaces to external SW are (in order of preference) 'COM' (Excel/COM), 'POI' (Java/Apache POI), 'JXL' (Java/JExcelAPI), 'OXS' (Java/OpenXLS), 'UNO' (Java/OpenOffice.org - EXPERIMENTAL!), 'OTK' (ODF Toolkit), 'JOD' (jOpendocument); see below: xls and .xlsx: One or more of (1) 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, or (2 - Windows only) OF-windows package and MS-Excel. These interfaces are referred to as POI, JXL, OXS, UNO and COM, resp., and are preferred in that order by default (depending on presence of the pertinent support SW). Currently the OCT interface has the lowest priority. Excel'95 spreadsheets (BIFF5) can only be read using the JXL (JExcelAPI), UNO (Open-/LibreOffice), and COM (Excel-ActiveX) interfaces. .ods, .sxc: A Java JRE 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 presence of support SW). The OCT interface has lowest priority). The old OpenOffice.org .sxc format can be read using the UNO interface and older versions of the JOD interface. Other formats: By invoking the UNO interface one can read any format that the installed LibreOffice version supports; see below. The same goes (on Windows systems) for the COM interface (invoking MS-Excel). However, writing to other file formats than .xlsx, .ods and .xls is not implemented for COM. Depending on the installed LibreOffice release, in addition to .xls, .xlsx, .ods and .sxc, the following file formats may be read/written (untested!) when using the UNO interface. The pertinent import/export filters are inferred from the filename extension. File format filename extension(s) ==================================== ===================== "Gnumeric" .gnumeric, .gnm "Text CSV" .csv "UOF spreadsheet" .uos "OpenDocument Spreadsheet Flat XML" .fods "dBase" .dbf "Digital Interchange Format" .dif "Lotus 1-2-3" .wk1 .wk2 .123 "WPS Lotus Calc" .wk3 .wk4 "MS Works Calc" .wks, .wdb "ClarisWorks Calc" .cwk "Mac Works Calc" .wps "Quattro Pro 6.0" .wb2 "WPS QPro Calc" .wb1 .wq1 .wq2 "Rich Text Format (StarCalc)" .rtf "SYLK" .slk .sylk "Apple Numbers" .numbers "Microsoft Multiplan" .mp The utility function chk_spreadsheet_support.m can be useful to set the javaclasspath for the Java-based interfaces. Beware: 'zombie' Excel invocations may be left running invisibly in case of COM errors or after forgetting to close the file pointer. Similarly for LibreOffice, which may even prevent Octave from being closed (the reason the UNO interface is still experimental). Examples: 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) See also: xlsclose, xlsread, xlswrite, xls2oct, oct2xls, xlsfinfo, chk_spreadsheet_support. 3.6.6 xlsread ------------- -- Function File: [NUMARR, TXTARR, RAWARR, LIMITS] = xlsread (FILENAME) -- Function File: [NUMARR, TXTARR, RAWARR, LIMITS] = xlsread (FILENAME, WSH) -- Function File: [NUMARR, TXTARR, RAWARR, LIMITS] = xlsread (FILENAME, RANGE) -- Function File: [NUMARR, TXTARR, RAWARR, LIMITS] = xlsread (FILENAME, WSH, RANGE) -- Function File: [NUMARR, TXTARR, RAWARR, LIMITS] = xlsread (FILENAME, WSH, RANGE, INTERFACE, ...) -- Function File: [NUMARR, TXTARR, RAWARR, LIMITS] = xlsread (FILENAME, WSH, RANGE, OPTIONS, ...) -- Function File: [NUMARR, TXTARR, RAWARR, LIMITS] = xlsread (FILENAME, WSH, RANGE, VERBOSE, ...) -- Function File: [NUMARR, TXTARR, RAWARR, EXTOUT, LIMITS] = xlsread (FILENAME, WSH, RANGE, FUNC_HANDLE, ...) Read data from a spreadsheet file. Out of the box, xlsread can read data from .xlsx, .ods and .gnumeric spreadsheet files. For .xlsx it is relatively fast (when reading an entire sheet), for .ods quite slow and for .gnumeric it's the only choice. For reading from other file formats or for faster I/O, see below under "Spreadsheet I/O interfaces". ========== Input arguments ============= Required parameter: FILENAME: the spreadsheet file to read data from. If it does not contain any directory (i.e., full or relative path), the file is assumed to be in the current directory. The filename extension (e.g., .ods, .xlsx or .gnumeric) must be included in the file name; when using the UNO interface all file formats can be read that are supported by the locally installed OpenOffice.org or LibreOffice version (e.g., wk1, csv, dbf, .xlsm, etc.). The same holds for COM (MS-Excel) on Windows when the windows package is loaded. Optional parameters: WSH is either numerical or text; in the latter case it is case-sensitive and it may be max. 31 characters long for .xls and .xlsx formats; for .ods the limit is much larger (> 2000 chars). Note that in case of a numerical WSH this number refers to the position in the visible sheet stack, counted from the left in a spreadsheet program window. The default is numerical 1, i.e. corresponding to the leftmost sheet tab in the spreadsheet file. Note: xlsread ignores the concept of "active worksheet" (i.e., the worksheet shown if the file is opened in a spreadheet program). RANGE is expected to be a regular spreadsheet range format, or "" (empty string, indicating all data in a worksheet). If no explicit range is specified the occupied cell range will have to be determined behind the scenes first; this can take some time for the native OCT and Java-based interfaces (but the results may be more reliable than that of UNO/LibreOffice or 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 WSH doesn't matter as the worksheet associated with the specified Named range will be used. If only the first argument FILENAME 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 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 leftmost worksheet (not necessarily Sheet1). However, if only two arguments are specified and the second argument is either numeric or a text string that does not contain a ".", it is assumed to be 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 "regular" input arguments a number of optional arguments can be supplied in any desired order, but just one of each optional argument type: INTERFACE (character or cellstr value) (see also further below under "Spreadsheet I/O interfaces".) INTERFACE (often a three-character case-insensitive text string) can be used to override the automatic interface selection by xlsread out of the locally supported ones. For .ods I/O select one or more of "jod", "otk", "uno" or "oct" for REQINTF (see help for xlsopen). For I/O to/from .xlsx files a value of 'com', 'poi', 'uno', or 'oct' can be specified. 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 REQINTF can also be a cell array of strings, one can select or exclude one or more interfaces. If no interface was explicitly selected, Octave will select one automatically based on available external support software. Octave will keep using a selected interface during an Octave ession as long as no other interface is specified, even if in the mean time other support software becomes available (e.g., by loading a package). The other way round, removing external support software while the interface it is based on was selected, is not advised and might lead to unpredictable behavior. FUNC_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 4th output argument EXTOUT of xlsread; output argument LIMITS becomes the 5th argument then (see below). OPTIONS (struct value) xlsread's data output can be influenced to some extent by a number of other options. See OPTIONS in "help xls2oct" for an overview. VERBOSE (logical value) To show which spreadsheet I/O interfaces have been found or which one is requested and active, enter true or a numeric 1 for VERBOSE. The default value is false (no info about found interfaces). ========== Output arguments ============= Return argument NUMARR contains the numeric data, optional return arguments TXTARR and RAWARR contain text strings and the raw spreadsheet cell data, respectively. Return argument LIMITS contains the outer column/row numbers of the read spreadsheet range where NUMARR, TXTARR and RAWARR have come from (remember, xlsread trims outer rows and columns). In case a function handle was specified (see above), EXTOUT will be the 4th output argument and LIMITS the 5th, to be Matlab compatible with regard to function handle output. Erroneous data and empty cells are set to NaN in NUMARR and turn up empty in TXTARR and RAWARR. Date/time values in Excel are returned as numerical values in 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. NUMARR and TXTARR are trimmed from empty outer rows and columns. Be aware that the COM interface does the same for RAWARR, so any returned array may turn out to be smaller than requested in RANGE. Use the last return argument LIMITS for info on the cell ranges your data came from. If you don't want the output to be trimmed, specify an Options struct containing a field "strip_array" with contents 0 or false as extra input argument (see above). Remarks: ----- 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. xlsread is just a wrapper for a collection of scripts that find out the interface to be used (COM, Java/POI, Java/JOD, Java/OXS, Java/UNO, etc.), select one, and then do the actual reading. Function parsecell() is invoked to separate the numerical and text data from the raw output array. For each call to xlsread (1) the selected interface must be started, (2) the spreadsheet file read into memory, (3) the data read from the requested worksheet, and (4) the file closed, interface closed and memory released. When reading multiple ranges from the same file (in optionally multiple, separate worksheets) a significant speed boost can be obtained by invoking those scripts directly as in: xlsopen / xls2oct [/ parsecell] / ... / xlsclose That way it is also possible to mix reading and writing (or vice versa) - (except for the JXL interface): xlsopen / xls2oct [/ parsecell] / oct2xls / ... / xlsclose Beware: When using the COM interface, hidden Excel invocations may be kept running silently ("zombie invocations") if the spreadsheet file isn't closed correctly or in case of unexpected errors. For the UNO interface it can be worse - hidden LibreOffice invocations may even prevent Octave from closing. ========== Spreadheet I/O interfaces ============= To be able to read from other file formats or for faster reading, external software is required. The connection to such external software is called an "interface". Below is an overview of the supported interfaces with the pertinent required external software together with a speed indication: * OCT built-in, no external SW required see above * JOD Java JRE and jOpendocument fastest * OTK Java JRE and ODF Toolkit slow * UNO Java JRE and LibreOffice or ** OpenOffice.org * COM (Windows only) octave-forge windows ** package and MS-Excel * POI Java JRE and Apache POI intermediate * JXL Java JRE and JExcelAPI intermediate * OXS Java JRE and OpenXLS fastest ** UNO needs to start up LibreOffice (or OpenOffice.org) behind the scenes which takes time. But once LibreOffice is loaded, reading is very fast, so for large .ods spreadsheet files it may be the fastest option. Similar holds for the COM interface, Excel and .xls/.xlsx files. The table below offers an overview of the file formats currently supported by each interface. For each file format, xlsread automatically first tries the leftmost installed interface in the table. --------------- Interfaces ------------- File extension COM POI POI+OOXML JXL OXS UNO OTK JOD OCT ---------------------------------------------------------------- .ods ~ + + + + .sxc + R .xls (Excel95) R R R .xls (Excel97-2003) + + + + + + .xlsx (Excel2007+) ~ + (+) + + .xlsb, xlsm ~ ? + R? .wk1 + R .wks + R .dbf + .fods + .uos + .dif + .csv + R .gnumeric + ~ = dependent on LO/OOo/Excel version; + = read/write; R = only reading. (+) unfortunately OOXML support in the OpenXLS Java library itself is buggy, so OOXML support for OXS has been disabled (but it is implemented) The utility function chk_spreadsheet_support.m is useful for checking and setting up external support SW (e.g., adding relevant Java .jar libraries to the javaclasspath). ============== Examples ================= Basic usage to get numerical data from a spreadsheet: 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) A little more involved: [An, Tn, Ra, limits] = xlsread ('Sales2009.ods', 'Third_sheet'); (which returns all data in worksheet 'Third_sheet' in file 'Sales2009.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) How to select an interface; in this example two: 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, OXS, UNO and OCT interfaces). See also: xlswrite, xlsopen, xls2oct, parsecell, xlsclose, xlsfinfo, oct2xls. 3.6.7 xlswrite -------------- -- Function File: RSTATUS = xlswrite (FILENAME, ARR) -- Function File: RSTATUS = xlswrite (FILENAME, ARR, WSH) -- Function File: RSTATUS = xlswrite (FILENAME, ARR, RANGE) -- Function File: RSTATUS = xlswrite (FILENAME, ARR, WSH, RANGE) -- Function File: RSTATUS = xlswrite (FILENAME, ARR, WSH, RANGE, REQINTF, ...) -- Function File: RSTATUS = xlswrite (FILENAME, ARR, WSH, RANGE, VERBOSE, ...) Add data in 1D/2D array ARR to a spreadsheet file. Out of the box, xlswrite can write data to .xlsx, .ods and .gnumeric spreadsheet files. For .xlsx it is relatively fast, for .ods quite slow and for .gnumeric it's the only choice. For writing to other file formats or for faster I/O, see the help for xlsread (under "Spreadsheet I/O interfaces"). Required parameters: ------------- FILENAME must be a valid spreadsheet file name (including file name extension). If 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. 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. Optional parameters: ------------- WSH can be a number or string (max. 31 chars for .xls and .xlsx, unlimited for .ods). In case of a not yet existing spreadsheet file, only one sheet will be created, used & named according to WSH. In case of existing files, some checks are made for existing sheet names or numbers, or whether WSH refers to an existing sheet with a type other than worksheet (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 the file is opened in an external spreadsheet program) remains untouched. RANGE is expected to be a regular spreadsheet range. Data is added to the worksheet; existing data in the requested range will be overwritten. Array ARR will be clipped at the right and/or bottom if its size is bigger than can be accommodated in RANGE. If ARR is smaller than the RANGE allows, it is placed in the top left rectangle of RANGE and existing cell values outside the rectangle will be retained. If the third argument is a sheet name and RANGE is specified as just one cell, it is taken as the topleft cell and the bottomright cell range address is determined from the data. 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:AMJ1048576 for .ods, 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 ":". To enter a range of just one cell specify e.g., "F3:F3". If RANGE contains merged cells, only the elements of ARR corresponding to the top or left spreadsheet 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". 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 WSH doesn't matter as the worksheet associated with the specified Named range will be used. After RANGE some optional arguments can be specified: REQINTF (character value) 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 REQINTF can be used to override that automatic selection by xlswrite. The value of REQINTF is case-insensitive. For an overview of interfaces and external support software, see the help for xlsread. 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. VERBOSE (numerical or logical value) If a value of true (logical) or 1 (numerical) is specified, xlswrite will echo the found spreadsheet I/O interfaces when it is started for the first time in an Octave session or when REQINTF was specified. If VERBOSE is omitted or a value of false or 0 (zero) is specified (the default) no interface info is shown. RSTATUS returns 1 if writing succeeded, 0 otherwise. xlswrite is a mere wrapper for various functions which find out what spreadsheet interface to use (COM, POI, JOD, etc), followed by separate functions for opening, writing to, and closing a spreadsheet file. For each call to xlswrite such an interface must be started and a spreadsheet file loaded and written. When writing to multiple ranges and/or sheets in the same spreadsheet file, or reading from and writing to the same spreadsheet file, a significant 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) or (mixing reading and writing in any desired order) (xlsopen / xls2oct / .... / octxls / .... / xlsclose) Example: status = xlswrite ... ('test4.xls', 'arr', 'Third_sheet', 'C3:AB40'); (which adds the contents of array arr (any type) to range C3:AB40 in worksheet 'Third_sheet' in file test4.xls and returns a logical True (= numerical 1) in 'status' if all went well) See also: xlsread, oct2xls, xls2oct, xlsopen, xlsclose, xlsfinfo, chk_spreadsheet_support.  File: io.info, Node: Spreadsheet I/O USer Functions For .ods, Next: Spreadsheet Utility Functions, Prev: Spreadsheet I/O User Functions For .xls/.xlsx, Up: Function Reference 3.7 Spreadsheet I/O USer Functions For .ods =========================================== 3.7.1 oct2ods ------------- -- Function File: [ ODS, RSTATUS ] = oct2ods (ARR, ODS) -- Function File: [ ODS, RSTATUS ] = oct2ods (ARR, ODS, WSH) -- Function File: [ ODS, RSTATUS ] = oct2ods (ARR, ODS, WSH, RANGE) -- Function File: [ ODS, RSTATUS ] = oct2ods (ARR, ODS, WSH, RANGE, OPTIONS) Transfer data to spreadsheet file pointer ODS. For more info see the help for oct2xls.m. oct2ods.m is deprecated. Currently it is a mere wrapper for oct2xls.m See also: oct2xls. 3.7.2 ods2oct ------------- -- Function File: [ RAWARR, ODS, RSTATUS ] = ods2oct (ODS) -- Function File: [ RAWARR, ODS, RSTATUS ] = ods2oct (ODS, WSH) -- Function File: [ RAWARR, ODS, RSTATUS ] = ods2oct (ODS, WSH, RANGE) -- Function File: [ RAWARR, ODS, RSTATUS ] = ods2oct (ODS, WSH, RANGE, OPTIONS) Read data from a spreadsheet file pointed to in file pointer struct ODS. For more info see the help for xls2oct.m. ods2oct.m is deprecated. Currently it is a mere wrapper for xls2oct.m See also: xls2oct. 3.7.3 odsclose -------------- -- Function File: [ODS] = odsclose (ODS) -- Function File: [ODS] = odsclose (ODS, FILENAME) -- Function File: [ODS] = odsclose (ODS, "FORCE") Close a spreadsheet file pointer and if needed write the contents to disk. For more info see the help for xlsclose.m. odsclose.m is deprecated. Currently it is a mere wrapper for xlsclose.m 3.7.4 odsfinfo -------------- -- Function File: [FILETYPE] = odsfinfo (FILENAME [, REQINTF]) -- Function File: [FILETYPE, SH_NAMES] = odsfinfo (FILENAME [, REQINTF]) -- Function File: [FILETYPE, SH_NAMES, NMRANGES] = odsfinfo (FILENAME [, REQINTF]) -- Function File: [FILETYPE, SH_NAMES, FFORMAT, NMRANGES] = odsfinfo (FILENAME [, REQINTF]) Query a spreadsheet file for some info about its contents. For more info see the help for xlsfinfo.m. odsfinfo.m is deprecated. Currently it is a mere wrapper for xlsfinfo.m See also: xlsfinfo. 3.7.5 odsopen ------------- -- Function File: ODS = odsopen (FILENAME) -- Function File: ODS = odsopen (FILENAME, READWRITE) -- Function File: ODS = odsopen (FILENAME, READWRITE, REQINTF) Get a pointer to contents of a spreadsheet file. For more info see the help for xlsopen.m. odsopen.m is deprecated. Currently it is a mere wrapper for xlsopen.m See also: xlsopen. 3.7.6 odsread ------------- -- Function File: [NUMARR, TXTARR, RAWARR, LIMITS] = odsread (FILENAME) -- Function File: [NUMARR, TXTARR, RAWARR, LIMITS] = odsread (FILENAME, WSH) -- Function File: [NUMARR, TXTARR, RAWARR, LIMITS] = odsread (FILENAME, WSH, RANGE) -- Function File: [NUMARR, TXTARR, RAWARR, LIMITS, EXTOUT] = odsread (FILENAME, WSH, RANGE, OPTS, ...) Read data from a spreadsheet file. For more info see the help for xlsread.m. odsread.m is deprecated. Currently it is a mere wrapper for xlsread.m. See also: xlsread. 3.7.7 odswrite -------------- -- Function File: RSTATUS = odswrite (FILENAME, ARR) -- Function File: RSTATUS = odswrite (FILENAME, ARR, WSH) -- Function File: RSTATUS = odswrite (FILENAME, ARR, WSH, RANGE) -- Function File: RSTATUS = odswrite (FILENAME, ARR, WSH, RANGE, REQINTF) Write data to a spreadsheet file. For more info see the help for xlswrite.m. odsread.m is deprecated. Currently it is a mere wrapper for xlswrite.m See also: xlswrite.  File: io.info, Node: Spreadsheet Utility Functions, Next: Spreadsheet Function Testing, Prev: Spreadsheet I/O USer Functions For .ods, Up: Function Reference 3.8 Spreadsheet Utility Functions ================================= 3.8.1 calccelladdress --------------------- -- function file: CELLADDR = calccelladdress (ROW, COLUMN) calccelladdress (row, column) - 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. 3.8.2 chk_spreadsheet_support ----------------------------- -- Function File: [ RETVAL, INTFS, LJARS ] = chk_spreadsheet_support () -- Function File: [ RETVAL, INTFS, LJARS ] = chk_spreadsheet_support ( PATH_TO_JARS ) -- Function File: [ RETVAL, INTFS, LJARS ] = chk_spreadsheet_support ( PATH_TO_JARS, DEBUG_LEVEL ) -- Function File: [ RETVAL, INTFS, LJARS ] = chk_spreadsheet_support ( PATH_TO_JARS, DEBUG_LEVEL, 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. 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. PATH_TO_JARS can be [] or " if no class libs need to be added to the javaclasspath. PATH_TO_OOO - installation directory of OpenOffice.org (again with /forward/ slashes). Usually that is something like (but no guarantees): 'Windows': C:/Program Files/OpenOffice.org or <br> C:/Program Files (X86)/LibreOffice '*nix': /usr/lib/ooo or /opt/libreoffice 'Mac OSX': ????? IMPORTANT: PATH_TO_OOO should be such that both: 1. PATH_TO_OOO/program/ and 2. PATH_TO_OOO/ure/.../ridl.jar resolve OK. (Note that LibreOffice/OOo should match the bit width (32bit or 64bit) of the Java version Octave was built with.) DEBUG_LEVEL: (integer) between [0 (no output) .. 3 (full output] 0 No debug output is generated. 1 Only proper operation of main interface groups (COM, Java) is shown. If PATH_TO_JARS and/or PATH_TO_OOO was supplied, chk_spreadsheet_support indicates whether it could find the required Java class libs for all interfaces. 2 Like 1, proper working of individual implemented Java-based interfaces is shown as well. If PATH_TO_JARS and/or PATH_TO_OOO was supplied, chk_spreadsheet_support indicates for each individual Java-based interface whether it could add the required Java class libs. 3 Like 2, also presence of individual javaclass libs in javaclasspath is indicated. If PATH_TO_JARS and/or 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. -1 (or any negative number) Remove all directories and Java class libs that chk_spreadsheet_support added to the javaclasspath. If DEBUG_LEVEL < 1 report number of removed javaclasspath entries; if DEBUG_LEVEL < 2 report each individual removed entry. Output: RETVAL = 0: only spreadsheet support for OOXML & ODS 1.2 and read support for gnumeric present through OCT interface, or 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: 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) INTFS: listing of supported spreadsheet interfaces. The OCT interface is always supported. LJARS: listing of full paths of Java class libs and directories that chk_spreadsheet_support has added to the javaclasspath. 3.8.3 parsecell --------------- -- Function File: [ NUMARR, TXTARR, LIM ] = parsecell (RAWARR) -- Function File: [ NUMARR, TXTARR, LIM ] = parsecell (RAWARR, 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 LIM contains two fields with the outer column and row numbers of NUMARR and TXTARR in the original array RAWARR. Optional input argument 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 LIM will contain the real spreadsheet row & column numbers enclosing the origins of the numerical and text data returned in NUMARR and TXTARR. Examples: [An, Tn] = parsecell (Rn); (which returns the numeric contents of Rn into array An and the text data into array Tn) [An, Tn, lims] = parsecell (Rn, xls.limits); (which returns the numeric contents of Rn into array An and the text data into array Tn.) See also: xlsread, odsread, xls2oct, ods2oct.  File: io.info, Node: Spreadsheet Function Testing, Prev: Spreadsheet Utility Functions, Up: Function Reference 3.9 Spreadsheet Function Testing ================================ 3.9.1 io_testscript ------------------- -- Function File: RSLTS] = io_testscript (INTF1) -- Function File: RSLTS] = io_testscript (INTF1, FNAME) -- Function File: RSLTS] = io_testscript (INTF1, FNAME, INTF2) -- Function File: RSLTS] = io_testscript (INTF1, FNAME, INTF2, VERBOSE) Try to check proper operation of spreadsheet I/O scripts using interface INTF1. INTF1 can be one of COM, JOD, JXL, OCT, OTK, OXS, POI, or UNO. No checks are made as to whether the requested interface is supported at all. If FNAME is supplied, that filename is used for the tests, otherwise depending on INTF1 one of "io-test.xlsx", "io-test.xls" or "io-test.ods" is chosen by default. This parameter is required to have e.g., POI distinguish between testing .xls (BIFF8) and .xlsx (OOXML) files. If INTF2 is supplied, that interface will be used for writing the spreadsheet file and INTF1 will be used for reading. If VERBOSE is supplied with a value of true or 1 the used interface is written to the screen. The tests are primarily meant to be run interactively. For automated tests (e.g., test_spsh.m) optional output argument RSLTS is supplied. The results of all test steps are printed on the terminal. See also: test_spsh. 3.9.2 test_spsh --------------- -- Function File: [ VOID ] = test_sprdsh () -- Function File: [ VOID ] = test_sprdsh (VERBOSE) 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 function io_testscript.m for the actual testing. As it is meant to be used interactively, no output arguments are returned. See also: io_testscript.  Tag Table: Node: Top180 Node: Overview1270 Node: Installing and loading1467 Node: Function Reference2542 Node: File Operations2947 Node: Miscellaneous Conversion Functions6301 Node: CSV File Functions14299 Node: DBF I/O17911 Node: XML I/O22873 Node: Spreadsheet I/O User Functions For .xls/.xlsx26164 Node: Spreadsheet I/O USer Functions For .ods69088 Node: Spreadsheet Utility Functions72914 Node: Spreadsheet Function Testing80180  End Tag Table  Local Variables: coding: utf-8 End: �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������io-2.7.0/doc/PaxHeaders/io.qch����������������������������������������������������������������������0000644�0000000�0000000�00000000062�15004725440�013061� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������20 atime=1746119456 30 ctime=1746119684.377810908 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������io-2.7.0/doc/io.qch���������������������������������������������������������������������������������0000644�0001750�0001750�00000260000�15004725440�013373� 0����������������������������������������������������������������������������������������������������ustar�00philip��������������������������philip�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������SQLite format 3���@ �������������������������������������������������������������������.zq ��� o�A $ 3 ? o�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������X''qtableMetaDataTableMetaDataTableCREATE TABLE MetaDataTable(Name Text, Value BLOB )t ##/tableFolderTableFolderTableCREATE TABLE FolderTable(Id INTEGER PRIMARY KEY, Name Text, NamespaceID INTEGER )| ''7tableFileNameTableFileNameTable CREATE TABLE FileNameTable (FolderId INTEGER, Name TEXT, FileId INTEGER, Title TEXT )t ++tableFileFilterTableFileFilterTable CREATE TABLE FileFilterTable (FilterAttributeId INTEGER, FileId INTEGER )f '' tableFileDataTableFileDataTable CREATE TABLE FileDataTable (Id INTEGER PRIMARY KEY, Data BLOB ) 77#tableFileAttributeSetTableFileAttributeSetTable CREATE TABLE FileAttributeSetTable (Id INTEGER, FilterAttributeId INTEGER )33/tableContentsFilterTableContentsFilterTable CREATE TABLE ContentsFilterTable (FilterAttributeId INTEGER, ContentsId INTEGER ){''5tableContentsTableContentsTableCREATE TABLE ContentsTable (Id INTEGER PRIMARY KEY, NamespaceId INTEGER, Data BLOB )x--#tableIndexFilterTableIndexFilterTableCREATE TABLE IndexFilterTable (FilterAttributeId INTEGER, IndexId INTEGER ) !! tableIndexTableIndexTableCREATE TABLE IndexTable (Id INTEGER PRIMARY KEY, Name TEXT, Identifier TEXT, NamespaceId INTEGER, FileId INTEGER, Anchor TEXT )h##tableFilterTableFilterTableCREATE TABLE FilterTable (NameId INTEGER, FilterAttributeId INTEGER )l++tableFilterNameTableFilterNameTableCREATE TABLE FilterNameTable (Id INTEGER PRIMARY KEY, Name TEXT ){55tableFilterAttributeTableFilterAttributeTableCREATE TABLE FilterAttributeTable (Id INTEGER PRIMARY KEY, Name TEXT )h)) tableNamespaceTableNamespaceTableCREATE TABLE NamespaceTable (Id INTEGER PRIMARY KEY,Name TEXT ) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������3octave.community.io �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ���( �zR<~`H. x ^ D ,  ~ f L $ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(�� 'test_spshtest_005fspsh&'�'� /io_testscriptio_005ftestscript&�� parsecellparsecell>%�;� Kchk_spreadsheet_supportchk_005fspreadsheet_005fsupport&$�+� +calccelladdresscalccelladdress#�� odswriteodswrite"�� odsreadodsread!�� odsopenodsopen �� odsfinfoodsfinfo�� odscloseodsclose�� ods2octods2oct�� oct2odsoct2ods�� xlswritexlswrite�� xlsreadxlsread�� xlsopenxlsopen�� xlsfinfoxlsfinfo�� xlsclosexlsclose�� xls2octxls2oct�� oct2xlsoct2xls�� xmlwritexmlwrite�� xmlreadxmlread�� tidyxmltidyxml�!� !getxmlnodegetxmlnode�!� !getxmlattvgetxmlattv�� dbfwritedbfwrite�� dbfreaddbfread�!� !csvexplodecsvexplode �� csvconcatcsvconcat �� csv2cellcsv2cell �� cell2csvcell2csv( �)� 1write_namelistwrite_005fnamelist �%� %utf82unicodeutf82unicode �%� %unicode2utf8unicode2utf8�� toJSONtoJSON&�'� /read_namelistread_005fnamelist�� pch2matpch2mat�� fromJSONfromJSON�� rfsearchrfsearch�� fexistfexist"�#� +append_saveappend_005fsave �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ��� V� V����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� @��������i�o�.�h�t�m�l���X�O�c�t�a�v�e� �i�o� �-� �i�o� �p�a�c�k�a�g�e� �f�o�r� �G�N�U� �o�c�t�a�v�e� �M�a�n�u�a�l������ �i�o�.�h�t�m�l�#�O�v�e�r�v�i�e�w����1� �O�v�e�r�v�i�e�w������<�i�o�.�h�t�m�l�#�I�n�s�t�a�l�l�i�n�g�-�a�n�d�-�l�o�a�d�i�n�g���0�2� �I�n�s�t�a�l�l�i�n�g� �a�n�d� �l�o�a�d�i�n�g������.�i�o�.�h�t�m�l�#�W�i�n�d�o�w�s�-�i�n�s�t�a�l�l���&�2�.�1� �W�i�n�d�o�w�s� �i�n�s�t�a�l�l������$�i�o�.�h�t�m�l�#�I�n�s�t�a�l�l�i�n�g����2�.�2� �I�n�s�t�a�l�l�i�n�g�������i�o�.�h�t�m�l�#�L�o�a�d�i�n�g����2�.�3� �L�o�a�d�i�n�g������4�i�o�.�h�t�m�l�#�F�u�n�c�t�i�o�n�-�R�e�f�e�r�e�n�c�e���(�3� �F�u�n�c�t�i�o�n� �R�e�f�e�r�e�n�c�e������.�i�o�.�h�t�m�l�#�F�i�l�e�-�O�p�e�r�a�t�i�o�n�s���&�3�.�1� �F�i�l�e� �O�p�e�r�a�t�i�o�n�s������.�i�o�.�h�t�m�l�#�a�p�p�e�n�d�_�0�0�5�f�s�a�v�e���"�3�.�1�.�1� �a�p�p�e�n�d�_�s�a�v�e�������i�o�.�h�t�m�l�#�f�e�x�i�s�t����3�.�1�.�2� �f�e�x�i�s�t������ �i�o�.�h�t�m�l�#�r�f�s�e�a�r��� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ���W�W�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������%�N��xMn0>œP7($A6,r'VrL ,=KOVHPJXff7󜧔z:M RI\O0 ʚ%(qBi�eU#:W$$qƀj UmPZ/O pd]p*yx3b_@tv4tAx)vW?-0u}(|=_ W2JY`Ov"MOg^|]+jl C{1 ej yC{#8O-ăs';\�:�xrG/?En &2CmsHWQ@];}F.@#fݵdeee'zyJLY,zi0/ %KѵL]D{ýXLrnwv.//b',NI�T2y=RkEz */gsuO鯧JuU8TFOd޳Izv2.JLt#z8s9SO%ʌt^:\{*-}RחH-)ыbe /f*/k')tM<#՞U!K]'KS{"Us]iRN&"yZ2ӽ{@,?i&O3=' =gJ <?>zr 蔟Օ,zbL 3ؘ{Ġ(O_R <QyJs&4<j(I/JrgjR><`BDM@ωDPt\c_*j{2?ԡdqEl8ŧheRSp6҇"I_nR x)3U R=0CE=١-=Zd2?zO[ߓ$L^L]l`4q 5 _0W v!dg,z2BϯT ~Bƥx *T1KIu.R# )J-cX_ UdXSer1Bfb^4ק L*~Pb^(  epBWtNR`y i%>3EN:p^WT^2Ls"_Ώ$ z*U1ÁȨIR:L Gsu闅M&˶yu9U2B3#}Q'K<'YS9/U桀מ>2ػlOؿLEO}@eq=Hz]<ّ3`#Z¤OP2:^).,R0(,2C^N^K7)e@ kA_� [Xt)HS=r웸q¨dM)2 ;F9.t~=/?ف_Yᕤٵzg`ss%m!iK31 j{?퓝zltt LDsX4(i嵐0uR1n&33/TP]dY޳sH54Tg̻m<mR1 6liCZNAh"W%ߜ:Behn:D!󈅁&:%5ֳ Ϣ[Xh&dL *`잋.,y'2 qdejT,j TU6sT%+r?z;,e1<mm x@uwMF[OޫsY$2.LS_:@W]A⊴ δ8Hܼ~P"hچ\(9}&zP)a5x&PXu͇>{_�n�uj9N358ÕVO۞|-qgbpԋ\8 bbf_)7ۓ?&?$=1s;N:54tc Сx>{2։ Z&ó'ұ,=+.ddBϞ+#U޳pF@h0F M84n|!28VY�>ONRՓgOώn8 H6uTq|tvx}?u T<09\LEiE±FZY͜=)5O r����� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� io.cssio.css2 Wio.htmlOctave io - io package for GNU octave �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� doc ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������!qchVersion1.0���.O.) HvڮRo +R8*Ea4gxxM^ʼQbKw/'n0P#7&M$ wDa>;z6ҙϤ5_Z$Y}SIShAKJKɪ  _|1/ ݇ej@{HБ($A+$"TRecM4y;ΓEًEQ̮c 30zDFsݎPE )c乂[Ԣ\j ״/x S2x8TPtUI`沸_><?YVy2MpvHZ,n{[YC3=.(c!VF\NBbt 0޿/T[ ߛr¿&A'Se I4c] Ҫ^VډkCQE& |Km5y:W2Ca*Ir)X2z?x :=H9 ?(Dk/6ڕ1\~Ezf\|ƌ";1IBO|mjpu l 8BЋ9k /ljU[ }T)!32,c?-U11Ji:%oy[2kUf Ѣ9'j$éX,y$,tPߛ-OUj^I/]xOi(c Fܭx}٫=(o+4\yvq"+ŗRqET6wSÓ ģ֋Bh5ڔj֩XWGdYߚiERU:[x"<\dpF/γk4;vh%isj 8U%NK%.ugH<t&I[^ERT@�>]1RdO?\zGHOTn1EQ&~BcKU9<;Ksx}G|TګU}V:DBǨ1 Uk<JqZ 5׍!I$rMK ƅE_M@SOi;S=S; e"UMҌG֟ز?c 2E&5X/J|196&h?wt_v3}-IX@e@]6?/ޥl2Wza/t^g~̻O:usߞw)mpv-^ymsol,Դ<Vz)-i$*o$-E!;JN9L#GP|Ϯ |1S8 C=PÑ<ӫH;~I8e1Q$[dgf<O"M>ű<F: jb6f8t"(؎($Fs+[5RJ;pAcѳJ_EϑФR(JseT_R73R`&@m@W0@lrpv1gD<Qnc1KT2zҟh{ő5xPO جsʠm`tJSXm2O"_3 X_5b1.C:4b�n2bI1Cۨ ް*q;߈UeYTe"I,4)VUHbW;<[c0cҡc֙Lr[Hud#BeYzmBreJE I: 7ڇ^\>lyOr$,!w29rNq#&@\ oWN`+-r+9D#n &aHJVΜy㘘Hר"ruQ#+ TehlGi) bAfyY:k,[}3S[7%Z$N(NG~;_dmr㰙pMv�ݸj-fJPo((c:)=g-T˃|rUm8,-[" d-o~R1K=eWb/0d?/1eǽxQ쉯n~7[xh;X nm.3݃�F~lk njUJrmEzvӥMq|tzX|$;=yG?a_l׼(v T"nN%@+O;u1C4EN 9+rq%Ę"qIlEfgh, NR 7dC_=^,N>z8]^c'0Ŧ&%) pCd$`g[[Y4'7R.|&!Wn5w**xG0}sz~巯~},emN\橡i 9uR^;ɟn6FjoGeGqǣC±䟖>Wo`Pvv*z86]ZHq<3VXPܱ3xY trCL~=*W1FIbSĒ!DZ` �Hd)'�7D sl2Kka4PPҠ$HL k2[ ]`ˮn=|N;{sr|:̥U Gѻ~Gg߿%?E5;~Y:Z`PR>+Zke4m+~to+mL-[X-rW C#~˴%W:[&gMiY5e"?7[FkͷĿ̞ N`͇"(2z`]m<hHM}4kـEh1dҼ <PxVSPy&6;XC༄K1Z"]?SSA|<2bMBNQ#?#'9_$.V8Ӧ;`? ɬ >ݤ9Z/R$9!zsI嬆c F<ye/fdl41챪[OzR kuO-&;5ˎTe^9)5{KŃ6@@4!ھGf;-|Wlϣȁ_?ퟸwn#|T䁾<[Vd<[p8c1Ќss^8Q'O}t|7hl\z&'΃�7N@<#C-nV/|. w>* vrL - tSlqWǜ#$PTxc3g,H' b`r8\H )uAAj1ұ?PB(9t<j܀hgO䟯]Շe`3׀s`r@ϮYp+s-/?64|di J[LACNMs6A^ +l$m\C껡�TCszbDmv&Yh0JKq&ʧ9"򃀜ysz"=z`OB``/uxHz�%l7 VCS ۸<g^E۸qַb۸B[ltmܲ'[6rZ_=Sgmmbt]*:hBn0)H{#'ɸAsCv7!꽾뚝|ӶyX܇*bt9xNcHg knStGUP+�%8 1g9' u,0FK fFt,3YTKwcJp9XV} RΔ> L:Od8y4?ϔv}9goճN^Ia#9/NF7ify"˺?6]?0|˷?&l[+48B%?- ���}?[`-lɳhiЖ ۦOJVW^jC4D<E (z>MY}Ps[?.) ,R~5b&E\-c3xp*X1l_͎Vb[ ׵m\[ꋲ'V텏%эNݖ|7ݿem$oNm@o8n݆ 8M;0®LX3D _}R=(̎i"{ j"аD$QTl,el<LN"Txs0ny%-OnwXjtoПcsTd'fb07-Q+D 뎐MHuR b1BSK$N)(C'-%BY?h;9P$ǯTEOlh G. sEP�Ylc-f9S�2buD5A8:RqP)IJL=�H;lG/yFi< !J"KW@dþ6\sn%|fhoȕ`0֠eך�Fq/RMm}gH\2FŁrX"`<vƊJv#Lp\]Rޓ涁�Ŕ0Ǡtȿ2[ 8S]pcsAw0t zq0PT6ޤ@Yj"u" U))US X_< 5^T82q -߰p=ж!5vMBAښ~ gIp`*' prGM8Ὼap%;<[ls0/e&td,н*}V­R鮏KXQ+[U?] |z# x" _7;'Tz,~ Mu> ~lɵ{)Xص-jFzxh{ɡHm ,6! c\Dݎ[=58b=h}|�I[< HzhgӾKô6͛7_[mhPpL2K؃qDjr,-ҙj}\aTJ�[,IU' &JȄ,q?7FqRa7J|V~h)(ΕGT*lƘ N]p]FN8č'pqLʍHl׃(U)0rqѭ٘=Ti* i%K?oN*Pk$C3#BؑM Nא(ǟY쯇JV_8@8Hp̯#תmyH̶plIODΰPR ԰{gq d40zt6Yub݇ΐysAxeƎ{R ]5&">c._Jc_U86` 9؃֨ȕFTh!w r:*2oZ/d!R̛B, ^xp:r&5pz"jJ! 50 zOӢp y՞a<J+*j2<=q[h ~̿a],M^ޮh4 C A/ lM N U|pXE%ż{d5cZxA1*)D<gIKZA;F)OC6 %N[vN0^:qr-T.@zLX G<(jVH"\ wov&XX:(|k@r{q#E)>B*?/(@W&6h&F1CP<' nz ǣX<ibO댫z>駎؍Ampξ9B/ x@.%QW6?=+yIB.њuC#eN@? ?]C+2|uC58(l56pdejŧ:{@tB>Γ[F @|5&!Wmh)~}aȾ-o+]8s3-!6yծ6j0Gѻz.Zbyn<r3V:']l4g�b6Ms]L&UKQ+~e:z†Scc-n0{Q<2 ު%4B󔍉xMsH"`02%ʺ^|ifA⢏NBIa`DjEmU*D %|BE9D~n6)DS�iu;i5o�1ce JzUQp R]L6 AmC;zȓEă=""@!8HCi,v}biNe%u9& Lʴw݄|@[bo@$(6eQf>϶n)r>޽ Zi37*fw{?a< U^.+OjȒe4_T` eYEru仚e$neTМMbӰЇmDtzk57Arw84hx.X {L \!<FJ KtkvC~to-ݖ'/V CH* )Kΐ+6#D1 bJj'S7Iv^dJCa6gg2hoZJ-.nteAxl:o u,@~8R#U^*r Pl-j `x jvP$z-捊o}^|-{6a9 u{M.�КY վ$Ofpん[:]26U&>촅QEW!6d oV0R+]fS 䳘?�p0OSBنGQ.3p\zuP ֢BΌuzng΍зDvWɜ=B5* 04!ΤS=$srx@[ mBjyDž7t;$Cnp4ev ~l}iڽ4VWMM\XUR;f0؇hXy4 V^@"먐u "�ƽH/OމDqI*4[Xevg k!-'�#\L'?˂-P%Z84[o[}$Ѓu;޹ ?} :{e9OMkUrgbnT�#Xy!2.^ ƈQ.28'ڝc=,NlT *F ZCK+C0, ϟ 0 %A.|QY$#%jcBs3p#5gmfC#Iz#/J ҇1"a>I4Va R3Z:Y[lwx\el|&I"Fm"֝Dj|sXP^'U5N*8E񅱫KΰR;=M; 0{(q_|D*3vvcPN@o\ë]׻7q.%pOc-4_Crnc.*^y�3Z̿XnZ%Lۥn7Hn-V*X_ X$ {Rx2벛Az]CCR4_>C -xYjIUܖ+Fys>!aw0Db1O0btm9`#*%4*(*3 0R ͋c*`SO 96d2IJNNtWWc`Oav!gu٧PCPÁw���?0# CqSFr͡+?D uF7$fը}6o`PRUb]eFUѺgN8jmaΜRmQ-Ena~MؠŴ*\{!S 0T{_'~B,-)(f u]jTu+W3*v�Wm4JhO n$LJ/z̀f?�e.#4t "R[ų&70�GܨjfY GY"c�˜jCqk?ieMiuN*n ੑOX9.]ׁώF$d|!Bnq;A.%jO <f@hjcXnY}u J͖ 2^Ätk dry DL=NQ8˓ p <'&w9:q#Q<m3==g+o'/TQ]'=֬* –SYD\Q&<Ԗ9 U#\cr"vc&bNmt&yߛgWXb{8T, l,k3(WB(S`$\d|#x-T߽X@]L23oS=#d iGAn@F1YZBfQB� )83o#q픚4}HNpEiS;V'v; x؍H0F^`po|a[,e!mb(eKCF.8:=HiPzJɶP'\ 5ŋw1!(&"vJp&;۫2dDFHեڝ%*w~-5M[R#f.ԤDQt9ȩhy]ର&YpY[:61)3hЬ/y.?oH@hXs6>Y{*a!| Xo.]L|>A_^^yJݦDNꡞ1!~"nP0\>XEeo<t3t,'X|=Y:K]f 11 v2H "]sz,^)x)ŗgӴH>оŗGG{G~%MRĎ{c0DO8 % qIzߎom&B^ʢ4-X;M S-fykĿm%򝚧u-Կc#u<<72U#6 'u/֠gfܶ5pRm* K3 Xc1.*ۘ3b4{Ckhwy`� c;2ruZ:/ҽ*,w�w`LS�}Zh)2ZϺC<0OJe'vE^=*,S7Dֺ#5[2{VjƥJQEyA˴khqbk}/,P wTM[huV;h!,۬jlM lqQkNc(k JQ9+.C/qsx6 njZ)XA],TG`E44XN\ ڱ?ptd^bVEAOTЈ)ay{Zjd*F d�fz@a4@bZ X J /EA @:�CTrWmЄ +m2Ď%Ph&jBk>əC\ůπH4:#C/_룷ZwH�#)Z(r.I 鼂8Ui^bJؔGh;0B_R!ɨa(e~)2 kɪȗD<r "`k1.|UcVXJݯЈxז$4el"i@E#YP)rXZ!�[&g:4["K ZI" K:#(SߙDF|=R쳕ia%sOy3#YTτ>ˑE (B-_#;F4o<Ӊ^y1%`$I2=5 9nXx}.6'n4j u.=I>C`2!am$77B k!/R\!&V,4Kk:1xׯ^q9X#BcZN蕐*1Q~DOW+Q2#C2Z.> xtsWn2يo' tYb?yxQ\.C\E[#picW(e T AWW"X,t2Q.@ZOOovwi*ku |`=zk1QsIQ\`NF5 E SI@(/l8 ],d<:^K\$ X; }m WhmECdػP߮*/N⻓7xOOa8u3\gժ )=)x[.q.h V? Erd}n7^d^:]vi}aXųG^~wƵ7Hrx|rꢯ n u+7JUZjDwlWًŗy"{qpx BJ`ArjEjS`Qh$aWYj_'a [="?~Y _s)҉NV'D"zVcCl#"-Gw sTbܹty�2cЈ~{[aWy oBT.=8l#DZQ+ـz6aOWtkH$BdA_F!U뇓=~j)OcЮ<5RXY \Pdd[SX/ՅŒp2G+]#+א/M=.X?|2_s *d|^rɻ@},-XʖMTs,i/(6C(Ɯc!6&eԷW"OАK yPPSZ95rMTbB" g/y†VXAˍ*M%AHދwF0p}|ҏ|Yz6AAٞt6WCs<.q:'l꺑$uM\C;7T0}˓gX,@ (f5U@9׾VEb}7 gu0NN>{@sVLcIXz}*Gs( 1@s7>d|8:,qs_N^ӈJ|%ޝ?̬(i{ _f^/ iK.md`w<Z!} t S_eSTS孫3CK!)!bKǍ {wZ~#iVС*Wl4/'<[kf Thy*UoPUL?HݲlPVs&vj췊x(f:}Yg0-gh4Ͱ/*㻒\bvP�"Te1H؉:0$I/JVnX̩q5P(_+GFg 6z�_b/jjCA97nq ,|Nd Uqpy�B|*RqX,HKwA%SqeXÈ_MՑW>J|(�<Q$doY�{*:tQO2!8hSh?0J~U:{8W9%B&ʌt7zւwFOJ6r2*këچ lFՉZuX9xYQWݔEQu@7 ¿k !}bF 0MA3+sq|/2(?>0�uE )cj3ĨgF)J�PsUK ÜA..ޒ]kF7g.ULxI%/A %mb���]|iBc<<޽l   lWom1i) b'nhtUevBt%iڮ!)slbmԅm;p $x1Y IbA+r빪!Z84Ƣ�p'15/ӂa9p;'zQn([8H N>Rˋ@aJyE/v88 8`r1SS"HD>Ҍ bUH(!.x3f>=ΰvHՕZh  11P[SU dcXѢ`VG3Dg*qlQ6ш5Rc 1Tc*"ǶZ vk5NŒ,?+4 ^dF5Y 1Fa|UǥL}\nC]3`@yp~7Amr�Ѿhh#zj }!3�=oO^TypFK$S�G S.. [#ȒoO^=%W `\e%ۨ\WܜA'"Fش#MBeLyNi3--%t:}Ȫr2 یQ$AjNh_ T'~3idt,0mo A<+>Lߙ @uXUݚQyT۶O|l[[  eۤc2n[oȇU˯uװbc$pjt2r_L05rdC|!ObW)!T! r nGزir4}$?c?dn"3o D%%gg(ޭVjlAx:C|CĤnb�H%j!eD* XVApe@]ѫd4bۼrDl~06jg6 ͧ( zƔ^Jmq @,-)Æ$ ywV i]nmM6aH\"T�"H @Ō7 HGsf9#AݗU8@1h !sp\!DJm7`ƴa 0.>3iHIDvQF LJcq>xWap$W8H˵.Tiޕu2s ([RoP,o2H :mPvt$.s &sХ=4FM Uy-c Ō8Lk֚ K,ӗ&yqHjKiyBVАbA 6-I}`+E+d*aVga!+)f'(J;/%1H* Ҫb[x}܃bEcՏ:8ygׁq7g0FзVQ)8?Ig ^}7^S_}Ad0“iuE � suX; '@A[cAB0h܈u.(4; uΨ3˗t׃z( )Bj8"YҐݛ؞9)mV6'vtabi8Dpx,*V̎SIg�Huvl9jN=~OYġlM8 K}i 8_w~*'N8L1|4|(#8db?fo*wr [8-jc T^Qgm|19Β:q`N}'܁:M+F[N*<&oƒsݡ֙ݒFc) +bP"9td6!P4;GP>{p6<N#@v92{hĥޣ{t)Ӎ[ avlT@qS?g "8`9v$-C/j,_5)xTA|<& t516O^D״ƿ J י,ki8b\zb2^)Dीp@ƘIV #/?oNFߝZ]xve2odu/?/Bew]p9گ5f9"/h=ѐiQEZ~aQ{u-nC}Cst:C1t]w)%- gsO*kꌧ>[#HY`sbd (}x C{Rى" <4d:9#ᅈCZ4R9EA!o^?3`0= .X U$YȹKx)<�;{EKǦc;~ FrDƧLDI8-0Ob:mr(}ichKh6چZ<?L\^wl[BM3=h[`W]0*Yx;svwuyN!E*DMp 2R%bKxNms<÷bx˽w[coؕ\;ZXgԋy/}TIjup`aH:uF]ս7eXv3@pzx~6Cۻ Se+['fˉ/� *A`d;ZlZuL ؒ& g@G}Hb͖Ko8Ii;|5E]/hz] _#3f˪}d|o3\DKRu(.%L]X$:b1)̻g?�-TjgO${k-䏾 ɤpjK|ˆ StMGArQLS̛Uhȹ1yJbɧ"MhnXr<>atkN5ab$zW)W3Ye/ƎL/Uڅ(dz�Y褦eiԣ* =DFŖMhRdޯ"JJ-)AI)@Cw:Pk"Xc�8t(3?! D0ckke֪ooZ1B_+96b\"6,B@DI.#bޝ>> %[^)UKmmnL h2 +"EïOE&G1#A^˛TfYMTM4/URpHzEɾqݖ` l^Ym^"D&: Xȕ;0qI:՟sH3i=Pr)+HA>\p _JWm vg=UÚ1Lj$)216뛵رĄNY<,R9&p_NiĐ&C!yj)$w֡:Q55\Sn%o%d({1#n�9FS,,N ^*0t1FԂ1sB`p_QgX*S9!gjEYpP宋).y@^g[o7 8ץ(R?<_k&G];>75pKkVĻV(PRk\^I z#BUf6!BXrcw}'1�$A\x=`ZԾۯ`m#Hk!`,ݓh(oaq[8& fq1 c,RB6& Fr [Gm%ePE J@.68 du7 w%EI ȥ6'l5wUi$Z 6F?)5 tr5{&:p!EAP{=^#amy7#{J-cnoإxajL_s.hәp���Xȭ G)"5 �KdxjJqIK1RSyڜY/)}D=VP �(VF\MXz- biT σg,L%Qɹ_NC mzٛY:|y� A f tT|LX� []9fD274d hZ02H"G}swgoNOՄ#^ LLm#ׂK];:W;swS63Y{C[kU&aШmEBod>rFUtZ -YG Un,:p%7rnXs;AaeȆawV'1? 5S08{LX-\邶{SW ,P _@4z^1J#Na,ъZXm9M򸵰Pecʊ1~XӗtU;WT\9mҙb!.pnŕ7; y;؅#b\ɢŢ \")'09< pS' ZQe8ؤz3땨,)beqTLNJjAݵ Fi�P`mdJr5J7ޜZe(M$Y4O�C>L/}u=vp+!݈!r*T4nEDb2ʙmw 1ꖫ@ʆbH3}lV]ԥPːKBbǨp[# \7&)]V@=JXGH%&H]O9|Z[%$QX=؍ ݉*SCɷۢ߁V%3_#wЊv@C.BfQİlSJ0`őۣh&;{xn~gi%jr`@u)#Wqfmb̮Eζxk~KB5~%4w3�`>FZ<�_ԣJ42QDv& sv\w<g$vp8_)ZugUƓhp\SW+vYnUo<jZ1~+GڭT �dA)ȥp{$Q( /|+aZw TP4E%1.a;w6eJ1\(1 ]dE0�FSǯ׾5V]1~ b8gАtGԽU޳E'ɡ?GWDjiu@s޾@:R]J6FA\*b8rΘrgOٓ2y';eN^E)CZۡ'@씰m{! :* 9\ESv6yr&`?L_vI{kPj@{l;W¡j̸mj�lt׺}}w}&>l8S *t߇:<pd v"FI_Ab-(\ C~[N:s0KEx؝bCw DG^dC(*Ď߽ߖyA:(!`[S%- R-H=wVA8®]q.i8x{-<k?[=ofTɄ9}`(..N9ůIgWb羡MMi3g=JY~8Ŕ`du2/{R" z竛];QKCWU non{WW A},7$=+!`+~U_ ,xk4,s M?riocߞo.?/k2lyvv7 /B%/JͱX&l l ۓC*(W[S{3M\w]LY:*$`FeYFk4W�m UT%'#P] EA"!a:Vs6$xCתǴ`d�.?w"gY9HRYДazax_ba6WjA$aFGabPK'_Gxq0<z~ׂѕƂPwLHsv6XК6ZRXv]I't5�helم.Tr{x,{S$y~y*3ewwr> uyFt B|o= PkZC0!n?٢zJ^1 bMҜIѲ/w%=SnBl[]fXo?E6>yxmWq .EQsޢl!>y8 V2$sn塳.`h9x\"<-k& |?k7֍�nbr{ӍlJY. & y9}IxULo o{hƖ7ǟCե˴EؼeZ%$#ɺ6kq!@�}~{0.uhVLU -О2IM2�+qnu$e1o?kmQlZU02g9Q /b8(`T=�Gkv-D@ & Kۺa8lGxkO/02n{1 bpN1== ]L] x^6tJ31DFnsOTqY7+ H,rp ']kURfqpLGژM.St$1ZǺ%'7±)KECL&T5UTHY6"T |⑕F�cI!|FOL ~!0H-WK`\5E?%ZkҘϩQE-0w aQ* g)_#fy0Z`[lh..ԋ40TX!{J2j84r@ìۥ:Zur;6 փ mtYFs[x<ֳN:Qq=quRJ1hgrLYds0ƥ3܎A] Ʀ,- E4CzA}eY/ a"s@v51ޥs.wJF!LB�a԰; Ŧa�IM YCV#!P:k21'zB PKJU ;Fqwx۽|1|o<B o࠽_kE)<lA}ڐ6¥V.u>ل%z\Cz@�0.u;A$pIE܀1ݪT(ԏ˟hkn/- f .u_M|t&J3>]T'8],<.u3=R^hS-Յ7.Q~~݀0r#9T~~ye3lZWi!LL _-ܤDV2ȖzNwø>}TaO_K=I=; ]&!z6кUoy-?P308)LI T$2s]جl*Pd'5kii46%'�}:&AJ[:,(`nZtP9(hnYy;bOSIuw_=!`j1a< iAqKiwKݚ1b" j,M`:yqAtRk!,`}7E|@v?Tx#LE*{AS&>N[Bb耒SR<#;85jv!soJ3RLqFQHk$zPxlW0sohdoi͆f1c \mJb' gfv^"|d8&uKLZW OIө1bYDŰg~0{rFPJ^N 4IL] c4ꉗݴ+s.%Mkl` _ffau(~Q%sК7_mϗlv0_%K)1S (", 41q{>QKJb3>g+zk\����+7]sCzhSH1p8ª 5Y+V;lF$qĥAaD=}AR.|/5 rOC8f8 |IS:#n]lJ(:(mRkoZQCe OLNߟb`fZW:1\tPkF-AݶעW\0`hgAMkYZB,z'\҉zKo_V@'өŷ:vgwu/,GVw j?fUBfb=^@X_!W9 <o0($QBmM5v&%ϵGmfm-Z'u'8;(�fumMIlٔ;C"owz & p~<[-W_Y]O6U}$MM6t+>f-o+jNky;i wz3}PHmNKO䈠/^qz} -'a{K 68Xn(WmG4[w >p䖷&ﴒ60vG X[#~\ӭ~}0ll(M6ӏ8V0k mV z>#6R|+sz2$/B~ٕ#rDc Dۣy#P; :6sLw?iNn0K0 nXU|-U."~] 06ix; WIVm*a?ҫE.L&q \z_ކztۇHRT-JVS)Nʹ+R3~b=\-ʥJlm!y.nX_UY;5npE_f[~=V[YNi;UNRiF[QJVb ~=Z6RK)x0~`[!/)xۄs"w[F*f;U)Sw*7xc޾ 穬lxRkURk!Ys1n>3rKx4/lMq;;$5ȓ-TJxٞmhЗ1 ꒀO(),FPIƨ+ z#]N�jN'*;yU}C?&�C0%87�pE[+ڐ~0m,OpmmF N̖1\/ϲpѝ|#zRnۧjsl | }H5ZD٦QjZ/YBO9B>BУLLL A)o$]1 �ސi_˥/%0H"n~]cC*GPu^(1~[t"N*E۾\5pqVTB$ 5 Rh@1u jh_BȃU.5\AqF Is9K )xezi,hhԬ 8 .79p娦-k# Y\z#Tޱ@쳣'go^:;]\"&f+OKbj*T~$ҎE5#[NMˌA} m^\iB�dQ\fQeMfqZ˲*:W?2|Q$6`Z@6Td�/ kwzRA,z _,7/ LS`,[B2/2}ގm\:/w#H_<Nm@|<*8/WtMa'\NW)vt MbGKP[q}7;yvt|v p HKVB/7dz'''; 20_}QpSI"<$TN'v WXc>,PNz&1R@NʩҲ ޣ\x*pL!+˷KCA8$sU@Ej+zPdeO]<[ac-K~йU:oU^=yAva0N?DkEfkVA0fR\fy k9rOls+PVpXbq[zH)9Lҋ4tAP�p=.N@LmQ^r5B7zФ~e'ֈ*VzBH4#')*2Stގȃ=C4ksRը\@ VS<eΆ ˴͢uA\8Ş/1Imt*κayp}lhly<Azu^|S{H-�*L'/Op?b|6Ttऴ/�Ћi`#`LQ)2%_S%ans񫳿uljFp 3SYl΋Nc>!vS$JX3 H; (SL؃g=xG[ !LFw{fS�=܆;h.S,aoׯů:^$ G)u~}t` o<AsI=V?Vs}̸z5!#'δ>mECyK=F Q_j,z:0lbmJ\l =64eZiiTɹPӅO0d..-sSf\COv[qfXK7}%rw<`kT5>O,<*f,Wqu ھS.}Z7+q|#e78-> 󯌛yzEm%s�D052D' |Y- vT{80\Vg!䟃 uXH԰UY-C%[~ }I҉ @!r(dQc(7]NddsŇ7{ct[@[RP9*Q/`e*KIG65\}iV9RjlsgzRW![ #&`/霧74rjV]/p\,2gM�_b# 3/KOFe>O,j@ze-H7jfh][3<9$h}-Ѧ T3Bddh5oxf8ps{<X5!>�{[`d9dգܖanKz1i$Xg5x׺D{,*k&_o*gnfqx'�*]7=ז~n6ݦY\+UָDSmI#mn}m1%Iл $hȽE<W_a.0lD+q]]0O٨Vw% 6sS v\H`B qcsWRTj.(354pz`  'aKؗ|80w)A|@[hצo/^jTM'7L*qtGR^ZL兊(2-R3u*#˵-zd(S/^X) 7MUԼ-Bz7 whx\/↥ۀ35ajl+an̟Y~B.Liv-f "(Xfg׶|ձ"k7>g}䈃^XSrTK,܍6c1b( ؏]l̴[5ڿJ|W54�l \NzEb[a&P&8l-k" ,Y \[1S Ⴃn停v1kTڒ˪ [LCj8spFd( 0.8pRJu#1TnCEuDykfZβgb�����c�h����3�.�1�.�3� �r�f�s�e�a�r�c�h������T�i�o�.�h�t�m�l�#�M�i�s�c�e�l�l�a�n�e�o�u�s�-�C�o�n�v�e�r�s�i�o�n�-�F�u�n�c�t�i�o�n�s���L�3�.�2� �M�i�s�c�e�l�l�a�n�e�o�u�s� �C�o�n�v�e�r�s�i�o�n� �F�u�n�c�t�i�o�n�s������ �i�o�.�h�t�m�l�#�f�r�o�m�J�S�O�N����3�.�2�.�1� �f�r�o�m�J�S�O�N�������i�o�.�h�t�m�l�#�p�c�h�2�m�a�t����3�.�2�.�2� �p�c�h�2�m�a�t������2�i�o�.�h�t�m�l�#�r�e�a�d�_�0�0�5�f�n�a�m�e�l�i�s�t���&�3�.�2�.�3� �r�e�a�d�_�n�a�m�e�l�i�s�t�������i�o�.�h�t�m�l�#�t�o�J�S�O�N����3�.�2�.�4� �t�o�J�S�O�N������(�i�o�.�h�t�m�l�#�u�n�i�c�o�d�e�2�u�t�f�8���$�3�.�2�.�5� �u�n�i�c�o�d�e�2�u�t�f�8������(�i�o�.�h�t�m�l�#�u�t�f�8�2�u�n�i�c�o�d�e���$�3�.�2�.�6� �u�t�f�8�2�u�n�i�c�o�d�e������4�i�o�.�h�t�m�l�#�w�r�i�t�e�_�0�0�5�f�n�a�m�e�l�i�s�t���(�3�.�2�.�7� �w�r�i�t�e�_�n�a�m�e�l�i�s�t������4�i�o�.�h�t�m�l�#�C�S�V�-�F�i�l�e�-�F�u�n�c�t�i�o�n�s���,�3�.�3� �C�S�V� �F�i�l�e� �F�u�n�c�t�i�o�n�s������ �i�o�.�h�t�m�l�#�c�e�l�l�2�c�s�v����3�.�3�.�1� �c�e�l�l�2�c�s�v������ �i�o�.�h�t�m�l�#�c�s�v�2�c�e�l�l����3�.�3�.�2� �c�s�v�2�c�e�l�l������"�i�o�.�h�t�m�l�#�c�s�v�c�o�n�c�a�t����3�.�3�.�3� �c�s�v�c�o�n�c�a�t������$�i�o�.�h�t�m�l�#�c�s�v�e�x�p�l�o�d�e��� �3�.�3�.�4� �c�s�v�e�x�p�l�o�d�e������&�i�o�.�h�t�m�l�#�D�B�F�-�I�_�0�0�2�f�O����3�.�4� �D�B�F� �I�/�O�������i�o�.�h�t�m�l�#�d�b�f�r�e�a�d����3�.�4�.�1� �d�b�f�r�e�a�d������ �i�o�.�h�t�m�l�#�d�b�f�w�r�i�t�e����3�.�4�.�2� �d�b�f�w�r�i�t�e������&�i�o�.�h�t�m�l�#�X�M�L�-�I�_�0�0�2�f�O����3�.�5� �X�M�L� �I�/�O������$�i�o�.�h�t�m�l�#�g�e�t�x�m�l�a�t�t�v��� �3�.�5�.�1� �g�e�t�x�m�l�a�t�t�v������$�i�o�.�h�t�m�l�#�g�e�t�x�m�l�n�o�d�e��� �3�.�5�.�2� �g�e�t�x�m�l�n�o�d�e�������i�o�.�h�t�m�l�#�t�i�d�y�x�m�l����3�.�5�.�3� �t�i�d�y�x�m�l�������i�o�.�h�t�m�l�#�x�m�l�r�e�a�d����3�.�5�.�4� �x�m�l�r�e�a�d������ �i�o�.�h�t�m�l�#�x�m�l�w�r�i�t�e����3�.�5�.�5� �x�m�l�w�r�i�t�e�������i�o�.�h�t�m�l�#�S�p�r�e�a�d�s�h�e�e�t�-�I�_�0�0�2�f�O�-�U�s�e�r�-�F�u�n�c�t�i�o�n�s�-�F�o�r�-�_�0�0�2�e�x�l�s�_�0�0�2�f�_�0�0�2�e�x�l�s�x���b�3�.�6� �S�p�r�e�a�d�s�h�e�e�t� �I�/�O� �U�s�e�r� �F�u�n�c�t�i�o�n�s� �F�o�r� �.�x�l�s�/�.�x�l�s�x�������i�o�.�h�t�m�l�#�o�c�t�2�x�l�s����3�.�6�.�1� �o�c�t�2�x�l�s�������i�o�.�h�t�m�l�#�x�l�s�2�o�c�t����3�.�6�.�2� �x�l�s�2�o�c�t������ �i�o�.�h�t�m�l�#�x�l�s�c�l�o�s�e����3�.�6�.�3� �x�l�s�c�l�o�s�e������ �i�o�.�h�t�m�l�#�x�l�s�f�i�n�f�o����3�.�6�.�4� �x�l�s�f�i�n�f�o�������i�o�.�h�t�m�l�#�x�l�s�o�p�e�n����3�.�6�.�5� �x�l�s�o�p�e�n�������i�o�.�h�t�m�l�#�x�l�s�r�e�a�d����3�.�6�.�6� �x�l�s�r�e�a�d������ �i�o�.�h�t�m�l�#�x�l�s�w�r�i�t�e����3�.�6�.�7� �x�l�s�w�r�i�t�e������n�i�o�.�h�t�m�l�#�S�p�r�e�a�d�s�h�e�e�t�-�I�_�0�0�2�f�O�-�U�S�e�r�-�F�u�n�c�t�i�o�n�s�-�F�o�r�-�_�0�0�2�e�o�d�s���V�3�.�7� �S�p�r�e�a�d�s�h�e�e�t� �I�/�O� �U�S�e�r� �F�u�n�c�t�i�o�n�s� �F�o�r� �.�o�d�s�������i�o�.�h�t�m�l�#�o�c�t�2�o�d�s����3�.�7�.�1� �o�c�t�2�o�d�s�������i�o�.�h�t�m�l�#�o�d�s�2�o�c�t����3�.�7�.�2� �o�d�s�2�o�c�t������ �i�o�.�h�t�m�l�#�o�d�s�c�l�o�s�e����3�.�7�.�3� �o�d�s�c�l�o�s�e������ �i�o�.�h�t�m�l�#�o�d�s�f�i�n�f�o����3�.�7�.�4� �o�d�s�f�i�n�f�o�������i�o�.�h�t�m�l�#�o�d�s�o�p�e�n����3�.�7�.�5� �o�d�s�o�p�e�n�������i�o�.�h�t�m�l�#�o�d�s�r�e�a�d����3�.�7�.�6� �o�d�s�r�e�a�d������ �i�o�.�h�t�m�l�#�o�d�s�w�r�i�t�e����3�.�7�.�7� �o�d�s�w�r�i�t�e������J�i�o�.�h�t�m�l�#�S�p�r�e�a�d�s�h�e�e�t�-�U�t�i�l�i�t�y�-�F�u�n�c�t�i�o�n�s���B�3�.�8� �S�p�r�e�a�d�s�h�e�e�t� �U�t�i�l�i�t�y� �F�u�n�c�t�i�o�n�s������.�i�o�.�h�t�m�l�#�c�a�l�c�c�e�l�l�a�d�d�r�e�s�s���*�3�.�8�.�1� �c�a�l�c�c�e�l�l�a�d�d�r�e�s�s������N�i�o�.�h�t�m�l�#�c�h�k�_�0�0�5�f�s�p�r�e�a�d�s�h�e�e�t�_�0�0�5�f�s�u�p�p�o�r�t���:�3�.�8�.�2� �c�h�k�_�s�p�r�e�a�d�s�h�e�e�t�_�s�u�p�p�o�r�t������"�i�o�.�h�t�m�l�#�p�a�r�s�e�c�e�l�l����3�.�8�.�3� �p�a�r�s�e�c�e�l�l������H�i�o�.�h�t�m�l�#�S�p�r�e�a�d�s�h�e�e�t�-�F�u�n�c�t�i�o�n�-�T�e�s�t�i�n�g���@�3�.�9� �S�p�r�e�a�d�s�h�e�e�t� �F�u�n�c�t�i�o�n� �T�e�s�t�i�n�g������2�i�o�.�h�t�m�l�#�i�o�_�0�0�5�f�t�e�s�t�s�c�r�i�p�t���&�3�.�9�.�1� �i�o�_�t�e�s�t�s�c�r�i�p�t������*�i�o�.�h�t�m�l�#�t�e�s�t�_�0�0�5�f�s�p�s�h����3�.�9�.�2� �t�e�s�t�_�s�p�s�hio-2.7.0/doc/PaxHeaders/io.css����������������������������������������������������������������������0000644�0000000�0000000�00000000062�15004725440�013076� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������20 atime=1746119456 30 ctime=1746119684.377810908 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������io-2.7.0/doc/io.css���������������������������������������������������������������������������������0000644�0001750�0001750�00000001337�15004725440�013416� 0����������������������������������������������������������������������������������������������������ustar�00philip��������������������������philip�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������pre.example, .header, .float-caption, hr { /* base00 ~ body text in light solarized theme */ color: #657b83; border-color: #657b83; } pre.example { /* base3 ~ background color in light solarized theme */ background-color: #fdf6e3; padding: 0.5em; } table.cartouche { border: 1px solid #948473; background-color: #FFE3C6; width: 100%; } table.cartouche td, table.cartouche th { border: 1px solid #948473; padding: 4px 4px; } /* newer texinfo generation styles */ div.example { /* base00 ~ body text in light solarized theme */ color: #657b83; border-color: #657b83; } pre.example-preformatted { /* base3 ~ background color in light solarized theme */ background-color: #fdf6e3; padding: 0.5em; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������io-2.7.0/doc/PaxHeaders/mkfuncdocs.py���������������������������������������������������������������0000644�0000000�0000000�00000000062�15004725440�014463� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������20 atime=1746119456 30 ctime=1746119684.377810908 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������io-2.7.0/doc/mkfuncdocs.py��������������������������������������������������������������������������0000755�0001750�0001750�00000027661�15004725440�015016� 0����������������������������������������������������������������������������������������������������ustar�00philip��������������������������philip�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/python3 ## Copyright 2018-2024 John Donoghue ## ## 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 ## <https://www.gnu.org/licenses/>. ## mkfuncdocs v1.0.8 ## mkfuncdocs.py will attempt to extract the help texts from functions in src ## dirs, extracting only those that are in the specifed INDEX file and output them ## to stdout in texi format ## ## It will extract from both .m and the help text for DEFUN_DLD help in .cc/.cpp ## files. ## ## It attempts to find the help text for each function in a file within the src search ## folders that match in order: [ functionname.m functionname.cc functionname.cpp ## functionname_withoutprefix.cc functionname_withoutprefix.cpp ] ## ## Usage: ## mkfundocs.py options INDEXfile ## Options can be 0 or more of: ## --verbose : Turn on verbose mode ## --src-dir=xxxxx : Add dir xxxxx to the dirs searched for the function file. ## If no directories are provided, it will default to looking in the ## 'inst' directory. ## --ignore=xxxxx : dont attempt to generate help for function xxxxx. ## --funcprefix=xxxxx : remove xxxxx from the function name when searching for matching ## source file. ## --allowscan : if can not find function, attemp to scan .cc,cpp,cxx files for match ## ## --standalone : generate a texinfo file expected to be used with being included in ## another document file. import sys import os import re import tempfile import shutil import fnmatch import subprocess import glob import calendar; import time; class Group: name = "Functions" functions = [] def __init__ (self, name=""): if name: self.name = name self.functions = [] class Index: name = "" groups = [] def texify_line(line): # convert any special chars in a line to texinfo format # currently just used for group formatting ? line = line.replace("@", "@@") line = line.replace("{", "@{") line = line.replace("}", "@}") line = line.replace(",", "@comma{}") return line def find_defun_line_in_file(filename, fnname): linecnt = 0 defun_line=re.compile(r"^DEFUN_DLD\s*\(\s*{}".format(fnname)) with open(filename, 'rt') as f: for line in f: if re.match(defun_line, line): return linecnt linecnt = linecnt + 1 return -1 def find_function_line_in_file(filename, fnname): linecnt = 0 func = False defun_line=re.compile(r"^\s*function \s*") with open(filename, 'rt') as f: for line in f: if func == True: x = line.strip() if x.startswith("## -*- texinfo -*-"): return linecnt else: func = False if re.match(defun_line, line): if line.find("=") != -1: x = line.split("=") x = x[-1] else: x = line.replace("function ", "") x = x.split("(") x = x[0].strip() if x == fnname: func = True linecnt = linecnt + 1 return -1 def read_m_file(filename, skip=0): help = [] inhelp = False havehelp = False; with open(filename, 'rt') as f: for line in f: line = line.lstrip() if skip > 0: skip = skip - 1 elif not havehelp: if havehelp == False and inhelp == False and line.startswith('##'): if "texinfo" in line: inhelp = True elif inhelp == True: if not line.startswith('##'): inhelp = False havehelp = True else: if line.startswith("## @"): line = line[3:] else: line = line[2:] help.append (line.rstrip()); return help def read_cc_file(filename, skip=0): help = [] inhelp = False havehelp = False; with open(filename, 'rt') as f: for line in f: line = line.lstrip() if skip > 0: skip = skip - 1 elif not havehelp: if havehelp == False and inhelp == False: if "texinfo" in line: inhelp = True elif inhelp == True: line = line.rstrip() if len(line) > 0 and line[-1] == '\\': line = line[:-1] line = line.rstrip() line = line.replace("\\n", "\n") line = line.replace("\\\"", "\"") if len(line) > 0 and line[-1] == '\n': line = line[:-1] # endif a texinfo line elif line.endswith('")'): line = line[:-2] if line.startswith('{'): inhelp = False havehelp = True else: help.append (line); return help def read_help (filename, skip=0): help = [] if filename[-2:] == ".m": help = read_m_file(filename, skip) else: help = read_cc_file(filename, skip) return help def read_index (filename, ignore): index = Index () with open(filename, 'rt') as f: lines = f.read().splitlines() #print ("read", lines) first = True category = Group() for l in lines: if l.startswith("#"): pass elif first: index.name = l; first = False elif l.startswith(" "): l = l.strip() # may be multiple functions here funcs = l.split() for f in funcs: if f not in ignore: category.functions.append(f); else: # new category name if len(category.functions) > 0: index.groups.append(category) category = Group(l.strip()) # left over category ? if len(category.functions) > 0: index.groups.append(category) return index; def find_class_file(fname, paths): for f in paths: # class constructor ? name = f + "/@" + fname + "/" + fname + ".m" if os.path.isfile(name): return name, 0 # perhaps classname.func format ? x = fname.split(".") if len(x) > 0: zname = x.pop() cname = ".".join(x) name = f + "/" + cname + ".m" if os.path.isfile(name): idx = find_function_line_in_file(name, zname) if idx >= 0: return name, idx name = f + "/@" + cname + "/" + zname + ".m" if os.path.isfile(name): return name, 0 return None, -1 def find_func_file(fname, paths, prefix, scanfiles=False): for f in paths: name = f + "/" + fname + ".m" if os.path.isfile(name): return name, 0 # class constructor ? name = f + "/@" + fname + "/" + fname + ".m" if os.path.isfile(name): return name, 0 name = f + "/" + fname + ".cc" if os.path.isfile(name): return name, 0 name = f + "/" + fname + ".cpp" if os.path.isfile(name): return name, 0 # if have a prefix, remove and try if prefix and fname.startswith(prefix): fname = fname[len(prefix):] name = f + "/" + fname + ".cc" if os.path.isfile(name): return name, 0 name = f + "/" + fname + ".cpp" if os.path.isfile(name): return name, 0 # if here, we still dont have a file match # if allowed to scan files, do that if scanfiles: #sys.stderr.write("Warning: Scaning for {}\n".format(fname)) for f in paths: files = list(f + "/" + a for a in os.listdir(f)) cc_files = fnmatch.filter(files, "*.cc") cpp_files = fnmatch.filter(files, "*.cpp") cxx_files = fnmatch.filter(files, "*.cxx") for fn in cc_files + cpp_files + cxx_files: line = find_defun_line_in_file(fn, fname) if line >= 0: #sys.stderr.write("Warning: Found function for {} in {} at {}\n".format(fname, fn, line)) return fn, line return None, -1 def display_standalone_header(): # make a file that doesnt need to be included in a texinfo file to # be valid print("@c mkfuncdocs output for a standalone function list") print("@include macros.texi") print("@ifnottex") print("@node Top") print("@top Function Documentation") print("Function documentation extracted from texinfo source in octave source files.") print("@contents") print("@end ifnottex") print("@node Function Reference") print("@chapter Function Reference") print("@cindex Function Reference") def display_standalone_footer(): print("@bye") def display_func(name, ref, help): print ("@c -----------------------------------------") print ("@subsection {}".format(name)) print ("@cindex {}".format(ref)) for l in help: print ("{}".format(l)) def process (args): options = { "verbose": False, "srcdir": [], "funcprefix": "", "ignore": [], "standalone": False, "allowscan": False } indexfile = "" for a in args: #print ("{}".format(a)) c=a.split("=") key=c[0] if len(c) > 1: val=c[1] else: val="" if key == "--verbose": options["verbose"] = True; if key == "--standalone": options["standalone"] = True; elif key == "--allowscan": options["allowscan"] = True; elif key == "--src-dir": if val: options["srcdir"].append(val); elif key == "--ignore": if val: options["ignore"].append(val); elif key == "--func-prefix": if val: options["funcprefix"] = val; elif val == "": if indexfile == "": indexfile = key if indexfile == "": raise Exception("No index filename") if len(options["srcdir"]) == 0: options["srcdir"].append("inst") #print "options=", options if options['standalone']: display_standalone_header() idx = read_index(indexfile, options["ignore"]) for g in idx.groups: #print ("************ {}".format(g.name)) g_name = texify_line(g.name) print ("@c ---------------------------------------------------") print ("@node {}".format(g_name)) print ("@section {}".format(g_name)) print ("@cindex {}".format(g_name)) for f in sorted(g.functions): print ("@c {} {}".format(g_name, f)) h = "" filename = "" path = "" if "@" in f: #print ("class func") path = f name = "@" + f ref = f.split("/")[-1] filename, lineno = find_func_file(path, options["srcdir"], options["funcprefix"]) elif "." in f: path = f ref = f.split(".")[-1] name = f.split(".")[-1] filename, lineno = find_class_file(path, options["srcdir"]) if not filename: parts = f.split('.') cnt = 0 path = "" for p in parts: if cnt < len(parts)-1: path = path + "/+" else: path = path + "/" path = path + p cnt = cnt + 1 name = f; ref = parts[-1] filename, lineno = find_func_file(path, options["srcdir"], options["funcprefix"]) elif "/" in f: path = f name = f ref = f.split("/")[-1] filename, lineno = find_func_file(path, options["srcdir"], options["funcprefix"]) else: path = f name = f ref = f filename, lineno = find_func_file(path, options["srcdir"], options["funcprefix"], options['allowscan']) if not filename: sys.stderr.write("Warning: Cant find source file for {}\n".format(f)) else: h = read_help (filename, lineno) if h: display_func (name, ref, h) if options['standalone']: display_standalone_footer() def show_usage(): print (sys.argv[0], "[options] indexfile") if __name__ == "__main__": if len(sys.argv) > 1: status = process(sys.argv[1:]) sys.exit(status) else: show_usage() �������������������������������������������������������������������������������io-2.7.0/PaxHeaders/INDEX���������������������������������������������������������������������������0000644�0000000�0000000�00000000062�15004725440�012002� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������20 atime=1746119456 30 ctime=1746119684.377810908 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������io-2.7.0/INDEX��������������������������������������������������������������������������������������0000644�0001750�0001750�00000001372�15004725440�012321� 0����������������������������������������������������������������������������������������������������ustar�00philip��������������������������philip�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������io >> Input from and output to external formats File Operations append_save fexist rfsearch Miscellaneous Conversion Functions fromJSON pch2mat read_namelist toJSON utf82unicode unicode2utf8 write_namelist CSV File Functions cell2csv csv2cell csvconcat csvexplode DBF I/O dbfread dbfwrite XML I/O getxmlattv getxmlnode tidyxml xmlread xmlwrite Spreadsheet I/O User Functions For .xls/.xlsx oct2xls xls2oct xlsclose xlsfinfo xlsopen xlsread xlswrite Spreadsheet I/O USer Functions For .ods oct2ods ods2oct odsclose odsfinfo odsopen odsread odswrite Spreadsheet Utility Functions calccelladdress chk_spreadsheet_support parsecell Spreadsheet Function Testing io_testscript test_spsh ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������