/usr/share/psychtoolbox-3/PsychFiles/ReadStructsFromText.m is in psychtoolbox-3-common 3.0.11.20140816.dfsg1-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 | function theStructs = ReadStructsFromText(filename)
% theStructs = ReadStructsFromText(filename)
%
% Open a tab delimited text file. The first row should
% contain the field names for a structure. Each following
% row contains the data for one instance of that structure.
%
% This routine reads each row and returns an array of structures,
% one struct for each row, with the data filled in. Data
% can be numeric or string for each field.
%
% Not a lot of checking is done for cases where the read file
% fails to conform to the necessary format.
%
% See Also: WriteStructsToText
% 6/15/03 dhb Wrote it.
% 07/01/03 dhb Support string as well as numeric data.
% 07/02/03 dhb, jg Handle white space in column headers.
% 07/03/03 dhb More little tweaks.
% 08/06/03 dhb Handle fgetl returns empty string.
% 08/22/07 dhb This was modified on disk but not commented our uploaded to SVN repository.
% 4/26/12 dhb Squeeze '/' out of field names too.
% 5/31/12 dhb Squeeze '*' out of field names too.
% 6/7/13 dhb Suppress uninteresting warning on str2num.
% 4/3/14 dhb Try to handle NaN in text files. Worked for at least one case.
% Open the file
fid = fopen(filename);
if fid == -1
error('Cannot open file %s', filename);
end
% Read first line to get field names for returned structure
theFields = {};
firstLine = fgetl(fid);
theIndex = 1;
i = 1;
while (1)
wholeField = [];
while (1)
readString = firstLine(theIndex:end);
[field,count,nil,nextIndex] = sscanf(readString,'%s',1);
if (count == 0)
break;
end
wholeField = [wholeField field];
theIndex = theIndex+nextIndex-1;
if (nextIndex <= length(readString) && abs(readString(nextIndex)) == 9)
break;
else
wholeField = [wholeField ' '];
end
end
if (count == 0)
if (~isempty(wholeField))
theFields{i} = wholeField;
i = i+1;
end
break;
end
theFields{i} = wholeField;
wholeField = [];
i = i+1;
end
nFields = length(theFields);
% Squeeze white space out of each field
for i = 1:nFields
newField = [];
oldField = theFields{i};
for j = 1:length(oldField)
if (~isspace(oldField(j)) && oldField(j) ~= '.' && oldField(j) ~= '/' && oldField(j) ~= '*')
newField = [newField oldField(j)];
end
end
theFields{i} = newField;
end
% Octave doesn't support the textscan function, so we use the old method
% of extracting data for Octave users. The new method allows spaces in
% strings.
if ~IsOctave
% Read out all the data from the text file delimited by newline
% characters.
data = textscan(fid, '%s', 'delimiter', '\n');
data = data{1};
% Read the values from each line of the text and convert them to
% doubles if possible.
f = 1;
for i = 1:size(data, 1)
values = textscan(data{i}, '%s', 'delimiter', '\t');
values = values{1};
for j = 1:size(values, 1)
convertedValue = [];
% Convert the entry from a string to a number if possible. We
% first check to see if the value is on the path as a function
% because the str2num function calls eval on its input which
% will cause it to execute.
if (strcmp(lower(values{j}),'nan'))
convertedValue = NaN;
elseif isempty(which(values{j})) && isempty(which(strtok(values{j})))
oldWarn = warning('off','MATLAB:namelengthmaxexceeded');
convertedValue = str2num(values{j}); %#ok<ST2NM>
warning(oldWarn.state,'MATLAB:namelengthmaxexceeded');
end
% If the value successfully converted, overwrite what was
% already in the cell array.
if ~isempty(convertedValue)
values{j} = convertedValue;
end
end
theStructs(f) = cell2struct(values, theFields, 1); %#ok<AGROW>
f = f + 1;
end
else
% Now read lines and pull out structure elements
f = 1;
while (1)
theLine = fgetl(fid);
if (isempty(theLine) || theLine == -1)
break;
end
theIndex = 1;
theData = cell(nFields,1);
for i = 1:nFields
readString = theLine(theIndex:end);
[field,count,nil,nextIndex] = sscanf(readString,'%g',1);
if (count == 0)
[field,count,nil,nextIndex] = sscanf(readString,'%s',1);
if (count == 0)
error('Cannot parse input');
end
end
theIndex = theIndex+nextIndex-1;
theData{i} = field;
end
theStruct = cell2struct(theData,theFields,1);
theStructs(f) = theStruct;
f = f+1;
end
end
% If there was no data in the file, return an empty matrix.
if ~exist('theStructs', 'var')
theStructs = [];
end
% Close the file.
fclose(fid);
|