This file is indexed.

/usr/share/octave/packages/io-2.4.5/private/__OCT_gnm2oct__.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
## Copyright (C) 2013-2016 Philip Nienhuis
## 
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
## 
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR 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
## <http://www.gnu.org/licenses/>.

## -*- 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 <prnienhuis at users.sf.net>
## 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 = '<gnm:Cell Row="(\d*?)" Col="(\d*?)"(?: (?:ValueType|ExprID)="(\d*?)")(?: ValueFormat="\w+")?>(.*?)</gnm:Cell>';
  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 = '<gnm:Cell Row="(\d*?)" Col="(\d*?)">(.*?)</gnm:Cell>';
  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