This file is indexed.

/usr/share/octave/packages/io-2.4.5/private/__OTK_ods2oct__.m is in octave-io 2.4.5-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
## Copyright (C) 2009-2016 Philip Nienhuis
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free Software
## Foundation; either version 3 of the License, or (at your option) any later
## version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, see <http://www.gnu.org/licenses/>.

## __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 <prnienhuis at users.sf.net>
## 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:table> - table nodes, the actual worksheets;
  ## <table:table-row> - row nodes, the rows in a worksheet;
  ## <table:table-cell> - 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 ("No worksheet '%s' found in file %s", 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 ("Worksheet no. %d out of range (1 - %d)", 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 ("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);
  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 <text:p|r> </text:p|r> tags
                ist = findstr (tmp, "<text:");
                if (ist)
                  ist = ist (length (ist));
                  ist = ist + 8;
                  ien = index (tmp(ist:end), "</text") + ist - 2;
                  tmp (ist:ien);
                  cvalue = tmp(ist:ien);
                endif
              endif
              rawarr(ii-trow+2, jj-lcol+1)= cvalue;
            otherwise
              ## Nothing
          endswitch
        endif
      endif
      ++jj;            ## Next cell
    endwhile

    ## Check for repeated rows (i.e. condensed in one table-row)
    extrarows = row.getTableNumberRowsRepeatedAttribute () - 1;
    if (extrarows > 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