📄 bffparse.m
字号:
% reject too short arrays
if length(rcont) < length(rhead)
continue;
end
% deal into struct
rstruct = hstruct;
for hfc = 1:nfields
hfield = hfields{hfc};
rstruct.(hfield) = deblank(rcont{hstruct.(hfield)});
end
% deal with empty lines
rstrtype = lower(rstruct.type);
if isempty(rstrtype)
continue;
elseif ~strcmp(rstrtype, 'skipn') && ...
isempty(rstruct.varname)
warning( ...
'BVQXtools:AmbiguousBFFSpec', ...
'Empty variable only allowed for SKIPN toked.' ...
);
continue;
end
% put non-empty type/varname rules into actrules
rstruct.disksize = 0;
actrules(end + 1) = rstruct;
end
% init loop checking variables
looplist = {};
loopused = {};
% parse rules (using for; if any rules fail, error out!)
for slc = 1:length(actrules)
% get rstruct from actrules
rstruct = actrules(slc);
% check syntax of fields, type
rstrtype = lower(rstruct.type);
if ~any(strcmp(rstrtype, ...
{'bloop', 'eloop', 'expre', 'field', 'skipn', 'xloop'}))
error( ...
'BVQXtools:BadBFFSpec', ...
'Invalid ListOfFields.type token: ''%s''.', ...
rstruct.type ...
);
end
% ... cond
if ~isempty(rstruct.cond)
try
eval([ ...
'if 1==0,if ' ...
mstrrep(rstruct.cond, ...
{'(\@\@|\$\$)', '(\@|\$)'}, ...
{'tvar', 'tvar.'}, 1) ...
',disp(1);end,end']);
catch
error( ...
'BVQXtools:BadBFFSpec', ...
'Invalid ListOfFields.cond content: ''%s''.', ...
rstruct.cond ...
);
end
end
% ... disktype
if strcmp(rstrtype, 'field')
% get shortcut
rtype = rstruct.disktype;
% check type syntax
if isempty(regexpi(rtype, '^[a-z][a-z_0-9]+$'))
error( ...
'BVQXtools:BadBFFSpec', ...
'Invalid ListOfFields.disktype tag: ''%s''.', ...
rtype ...
);
end
% check disktype
switch lower(rtype)
% disktype is built in
case { ...
'char', 'int8', 'int16', 'int32', ...
'uchar', 'uint8', 'uint16', 'uint32', ...
'int64', 'uint64','single', 'double'}
rtype = lower(rtype);
% disktype string, cstring, char*
case {'char*', 'cstring', 'string'}
rtype = 'cstring';
% unsupported disktype
otherwise
error( ...
'BVQXtools:BadBFFSpec', ...
'Invalid disktype in FIELD(%d).disktype', ...
slc ...
);
end
% put back into actrules(slc)
actrules(slc).disktype = rtype;
if isfield(bff_dtsize, lower(rtype))
actrules(slc).disksize = bff_dtsize.(lower(rtype));
else
actrules(slc).disksize = 0;
end
end
% ... datatype
if ...
strcmp(rstrtype, 'field') && ...
isempty(regexpi(rstruct.datatype, '^[a-z][a-z_0-9]+$'))
error( ...
'BVQXtools:BadBFFSpec', ...
'Invalid ListOfFields.datatype tag: ''%s''.', ...
rstruct.datatype ...
);
end
% ... dim (loops)
if strcmp(rstrtype, 'bloop')
% only single number OR variable
if isempty(regexpi(rstruct.dim, ...
'^(\d+|[\$\@][a-z][a-z_0-9\.]*(\((\d+|[\$\@][a-z][a-z_0-9\.]*)\))?)$'))
error( ...
'BVQXtools:BadBFFSpec', ...
'Invalid LOOP.DIM given: ''%s''.', ...
rstruct.dim ...
);
end
% ... dim (fields)
elseif strcmp(rstrtype, 'field')
% multiple numbers AND/OR variables
if isempty(regexpi(rstruct.dim, ...
['^((\d+|[\$\@][a-z][a-z_0-9]*)(\((\d+|[\$\@][a-z][a-z_0-9]*)\))?' ...
'(\.[a-z][a-z_0-9]*(\((\d+|[\$\@][a-z][a-z_0-9]*)\))?)*\,\s*)*' ...
'((\d+|[\$\@][a-z][a-z_0-9]*)(\((\d+|[\$\@][a-z][a-z_0-9]*)\))?)$']))
error( ...
'BVQXtools:BadBFFSpec', ...
'Invalid ListOfFields.dim given: ''%s''.', ...
rstruct.dim ...
);
end
% ... dim (skipX)
elseif strcmp(rstrtype(1:4), 'skip')
% only a 1-D numeric value accepted
if ~all(rstruct.dim > 47 & rstruct.dim < 58)
error( ...
'BVQXtools:BadBFFSpec', ...
'Invalid SKIPx.dim given: ''%s''.', ...
rstruct.dim ...
);
end
end
% ... default (if non-empty)
if ~isempty(rstruct.default)
try
eval(['if 1==0,' ...
mstrrep(rstruct.default, ...
{'(\@\@|\$\$)', '(\@|\$)'}, ...
{'tvar', 'tvar.'}, 1) ...
',end']);
catch
error( ...
'BVQXtools:BadBFFSpec', ...
'Invalid ListOfFields.default value: ''%s''.', ...
rstruct.default ...
);
end
end
% ... varname (loops, fields)
if any(strcmp(rstrtype, ...
{'bloop', 'eloop', 'field', 'xloop'}))
% fields can be complex
if strcmp(rstrtype, 'field')
if isempty(regexpi(rstruct.varname, ...
['^([a-z][a-z_0-9]*(\((\d+|[\$\@][a-z][a-z_0-9]*)\))?\.)*' ...
'[a-z][a-z_0-9]*(\((\d+|[\$\@][a-z][a-z_0-9]*)\))?$']))
error( ...
'BVQXtools:BadBFFSpec', ...
'Invalid ListOfFields.varname: ''%s''.', ...
rstruct.varname ...
);
end
% loop variables MUST be simple
else
if isempty(regexpi(rstruct.varname, ...
'^[a-z][a-z_0-9]*(\(\d+\))?$'))
error ( ...
'BVQXtools:BadBFFSpec', ...
'Invalid ListOfFields.varname: ''%s''.', ...
rstruct.varname ...
);
end
end
% ... varname (expressions)
else
try
eval(['if 1==0,' ...
mstrrep(rstruct.varname, ...
{'(\@\@|\$\$)', '(\@|\$)'}, ...
{'tvar', 'tvar.'}, 1) ...
',end']);
catch
error( ...
'BVQXtools:BadBFFSpec', ...
'Invalid EXPRE in ListOfFields.varname: ''%s''.', ...
rstruct.varname ...
);
end
end
% look at loop details
if strcmp(rstrtype, 'bloop')
% varname might not be part of current looplist
if any(strcmp(rstruct.varname, loopused))
error( ...
'BVQXtools:BadBFFSpec', ...
'LOOP variable name reused: ''%s''.', ...
rstruct.varname ...
);
end
% put varname at the end of looplist
lvname = rstruct.varname;
looplist{end + 1} = lvname;
loopused{end + 1} = lvname;
slooplist = looplist;
% scan for loop end
eloopfound = false;
subloops = 1;
for sslc = (slc+1):length(actrules)
% get another shortcut
tstruct = actrules(sslc);
% subloops (BLOOP)
tstrtype = lower(tstruct.type);
if strcmp(tstrtype, 'bloop')
subloops = subloops + 1;
slooplist{end + 1} = tstruct.varname;
% end-of-loop (ELOOP)
elseif strcmp(tstrtype, 'eloop')
subloops = subloops - 1;
try
if ~strcmp(slooplist{end}, tstruct.varname)
error('ILLEGALLOOP');
end
slooplist(end) = [];
catch
error( ...
'BVQXtools:BadBFFSpec', ...
'Illegal loop nesting found.' ...
);
end
% checking loop names for xloop
elseif strcmp(tstrtype, 'xloop')
% must be found in slooplist !
if ~any(strcmp(slooplist, tstruct.varname))
error( ...
'BVQXtools:BadBFFSpec', ...
'Unknown XLOOP token: ''%s''.', ...
tstruct.varname ...
);
end
end
% type must be ELOOP and varname match
if numel(actrules(sslc).type) == 5 && ...
all(lower(actrules(sslc).type) == 'eloop') && ...
strcmp(actrules(sslc).varname, lvname)
eloopfound = true;
elooprule = sslc;
break;
end
end
% if no end of loop found...
if ~eloopfound
error( ...
'BVQXtools:BadBFFSpec', ...
'Missing closing tag for LOOP %s.', ...
lvname ...
);
end
% subloops MUST be zero now
if subloops ~= 0
error( ...
'BVQXtools:BadBFFSpec', ...
'Invalid LOOP nesting in BFF spec.' ...
);
end
% build special loop struct
lstruct = struct( ...
'loopvar', lvname, ...
'firstrule', slc, ...
'lastrule', elooprule, ...
'cond', rstruct.cond, ...
'dim', rstruct.dim);
% split dim from varname
ldim = 1;
fname = rstruct.varname;
[ldimmatcht{1:3}] = regexpi( ...
fname, '^[a-z][a-z_0-9]*\((\d+)\)$');
ldimmatcht = ldimmatcht{3};
if ~isempty(ldimmatcht) && ...
~isempty(ldimmatcht{1})
ldim = str2double( ...
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -