📄 tffio.m
字号:
% set current rule pointer to end of loop
rulec = loopinfo.lastrule;
end
% end of a loop
case {'eloop'}
% check name of LAST ENTERED loop
if ~strcmp(rexpr, loopx{end})
error( ...
'BVQXtools:BadBFFSpec', ...
'Invalid LOOP end token found: ''%s''.', ...
rexpr ...
);
end
% increase loop counter and check if the loop is done
try
leaveloop = false;
eval([...
'namevars.' rexpr '=namevars.' rexpr '+1;' ...
'if namevars.' rexpr '>loopi(loopc).dim,leaveloop=true;end']);
catch
error( ...
'BVQXtools:BadExpression', ...
'Couldn''t increase/check LOOP counter: ''%s''.', ...
rexpr ...
);
end
% if we're NOT leaving loop
if ~leaveloop
% set next rule to process to first loop line
rulec = loopi(loopc).firstrule;
% if we're leaving loop
else
% pop loopi/x(loopc)
loopi(loopc) = [];
loopx(loopc) = [];
loopc = loopc - 1;
end
% expression
case {'expre'}
% if no given condition is given
if isempty(rcond)
% simply execute expression
try
eval(rexpr);
catch
error( ...
'BVQXtools:BadExpression', ...
'Couldn''t evaluate EXPRE: ''%s''.', ...
rexpr ...
);
end
% with a given condition
else
% execute upon condition
try
eval(['if ' rcond ',' rexpr ';end']);
catch
error( ...
'BVQXtools:BadExpression', ...
'Couldn''t evaluate EXPRE: ''%s''.', ...
['if ' rcond ',' rexpr ';end'] ...
);
end
end
% field (read/write)
case {'field'}
% check cond
if ~isempty(rcond)
try
eval(['iofield=false;if ' rcond ',iofield=true;end']);
catch
error( ...
'BVQXtools:BadExpression', ...
'Couldn''t evaluation COND expression: ''%s''.', ...
rcond ...
);
end
if ~iofield
rulec = rulec + 1;
continue;
end
end
% reading
if ~writemode
% check number of lines/columns to come
if linec > linecount
error( ...
'BVQXtools:BadTTFCont', ...
'No more lines left to read FIELD.' ...
);
end
% get deblanked field line
fieldline = deblank(linecont{linec});
% check for name
[linema{1:3}] = regexpi(fieldline, ...
'^\s*([a-z][a-z_0-9]*)\:?\s*(.*)$');
linemt = linema{3};
if ~isempty(linemt)
fieldname = fieldline(linemt{1}(1, 1):linemt{1}(1, 2));
fieldval = fieldline(linemt{1}(2, 1):linemt{1}(2, 2));
else
fieldname = '';
fieldval = fieldline;
end
% give (only) a warning if name does NOT match
if isempty(strfind(rfldn, fieldname))
warning( ...
'BVQXtools:BadTFFSpec', ...
['Possibly reading wrong field, ' ...
'''%s'' instead of ''%s''.'], ...
fieldname, rexpr ...
);
end
% depending on datatype
switch (lower(rdata))
% built-in
case { ...
'char', 'int8', 'int16', 'int32', ...
'uint8', 'uint16', 'uint32', ...
'single', 'double', 'logical'}
% first to double then to value
try
eval(['tffcont.' rexpr '=' ...
lower(rdata) '(str2num(fieldval));']);
catch
error( ...
'BVQXtools:EvaluationError', ...
'Could not store %s field in %s.', ...
rdata, rexpr ...
);
end
% handle strings specifically
case {'cstring', 'string'}
% format with delimiter, remove it then
if ~isempty(rform) && ...
length(fieldval) > 1 && ...
rform(1) == rform(end) && ...
fieldval(1) == rform(1) && ...
fieldval(end) == rform(1)
fieldval = fieldval(2:end - 1);
end
% simply copy content
try
eval(['tffcont.' rexpr '=fieldval;']);
catch
error( ...
'BVQXtools:EvaluationError', ...
'Could not store string field in %s.', ...
rexpr ...
);
end
% special
otherwise
% try custom conversion (only once)
try
eval(['tffcont.' rexpr ...
'=string2' rdata '(fieldval);']);
catch
error( ...
'BVQXtools:ConversionError', ...
'Could not convert string=>%s field for %s.', ...
rdata, rexpr ...
);
end
end
% increase line counter
linec = linec + 1;
% writing
else
% get data to write
try
eval(['writedata=tffcont.' rexpr ';']);
catch
error( ...
'BVQXtools:EvaluationError', ...
'Data field evaluation error: ''%s''.', ...
rexpr ...
);
end
% check dim
if length(size(writedata)) ~= 2 || ...
(~ischar(writedata) && ...
length(writedata) ~= rdim(1))
error( ...
'BVQXtools:BadTFFSpec', ...
'FIELD dimension mismatch.' ...
);
end
% get line start
linestart = sprintf(['%-' mfl 's'], [rfldn ':']);
% depending on datatype
switch (lower(rdata))
% built-in but hopefully unconverted
case {'double'}
% first to double then to value
try
if ~isa(writedata, 'double')
writedata=double(writedata);
end
linevalue = deblank(sprintf([rform ' '], writedata));
catch
error( ...
'BVQXtools:ConversionFailed', ...
'Couldn''t convert from %s=>double.', ...
class(writedata) ...
);
end
% built-in but definitely converted
case { ...
'char', 'int8', 'int16', 'int32', ...
'uint8', 'uint16', 'uint32', ...
'single', 'logical'}
% first to double then to value
try
eval(['writedata=double(' ...
lower(rdata) '(writedata));']);
linevalue = deblank(sprintf([rform ' '], writedata));
catch
error( ...
'BVQXtools:ConversionFailed', ...
'Couldn''t convert from %s=>double.', ...
rdata ...
);
end
% specifically handle strings
case {'cstring', 'string'}
% format
if ~isempty(rform) && ...
any(rform == '%')
try
writedata = ...
deblank(sprintf([rform ' '], writedata));
catch
error( ...
'BVQXtools:SprintfFailed', ...
'Error using sprintf formatting.' ...
);
end
end
% simply assign value
linevalue = writedata;
% otherwise use handler function
otherwise
% try conversion
try
eval(['linevalue=double(' ...
rtype '2string(writedata));']);
catch
error( ...
'BVQXtools:ConversionFailed', ...
'Couldn''t convert %s from %s=>string.', ...
rexpr, rdata ...
);
end
end
% put line into stream
linecont{end + 1} = [linestart fds linevalue];
linecount = linecount + 1;
end
% field list (ONLY READ, write by field)
case {'flist'}
% get list of fields to come
fieldlist = {};
fieldlookup = struct;
while rulec <= rules
if ~strcmpi(rule(rulec).type, 'flist')
rulec = rulec - 1;
break;
end
% get shortcut to rule
sprule = rule(rulec);
srcond = sprule.cond;
rulec = rulec + 1;
% check condition
if ~isempty(srcond)
try
eval(['flinclude=false;if ' ...
srcond ',flinclude=true;end']);
if ~flinclude
continue;
end
catch
error( ...
'BVQXtools:EvaluationError', ...
'Error evaluating COND on FLIST ''%s''.', ...
sprule.field ...
);
end
end
fieldlist{end + 1} = lower(sprule.field);
fieldlookup.(makelabel(fieldlist{end})) = rulec - 1;
end
% don't do anything on empty fieldlist
if isempty(fieldlist)
continue;
end
% build pattern matching terms
fieldmlist = ['^\s*(' lower(gluetostring(fieldlist, '\:|')) ...
'\:)\s*(.*)$'];
% check number of lines/columns to come
if linec > linecount
error( ...
'BVQXtools:BadTTFCont', ...
'No more lines left to read FLIST.' ...
);
end
% read as long as pattern matches
fieldline = deblank(linecont{linec});
[flinea{1:3}] = ...
regexpi(fieldline, fieldmlist);
flinet = flinea{3};
while ~isempty(fieldmlist) && ...
~isempty(flinet) && ...
linec <= linecount
% get fieldname that matched (without ':')
fieldname = fieldline(flinet{1}(1, 1):flinet{1}(1, 2) - 1);
fieldval = fieldline(flinet{1}(2, 1):flinet{1}(2, 2));
% lookup rule
try
srulec = fieldlookup.(makelabel(lower(fieldname)));
catch
error( ...
'BVQXtools:LookupFailed', ...
'Field lookup from struct failed: ''%s''.', ...
fieldname ...
);
end
% remove fieldname from fieldlist and rebuild fieldmlist
fieldlist(strcmpi(fieldname, fieldlist)) = [];
fieldmlist = ['^(' lower(gluetostring(fieldlist, '\:|')) ...
'\:)\s*(.*)$'];
% get sub rule
sprule = rule(srulec);
srtype = sprule.type;
srfldn = sprule.field;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -