image thumbnail

gettok: a pedestrian matlab constructs decoder

by

 

16 Feb 2002 (Updated )

a decoder/tokenizer for MATLAB constructs

[out1,out2,out3]=gettok(s,varargin)
% [o1,o2,o3] = gettok(in[,'opt1',par,'opt2',par,...])
%			to tokenize/decode ML constructs <in>
%			ver:	25-Apr-2005 09:06:44
%
%    in	: opt,par	output 1	output 2	output 3
%---------------------------------------------------------------------------------
%  char	:		cell(*)		procpar		[]
%  cell	:		char/token	procpar		[]
% struc	:  -f,0		cell(*)		procpar		[]
%			- fieldnames
% struc	:  -f,1		string		procpar		[]
%			- fieldnames
% struc	:  -f,-1|-2|-3	struc tree
%			- entries	values		procpar
%					-  char >xxx<
%					- other @id(inf)
%   int	:		char range	procpar		[]
%     1	:  -f,1		cells: 'a':'z'
%     2	:  -f,1		cells: 'A':'Z'
%     3	:  -f,1		cells: 'A':'z'
%
%   opt :	par	processing
%---------------------------------------------------------------------------------
%    -f	:      mode	main processing flag		[see above]
%		 -1	make <in> a <struct>		[see NOTE]
%	         -2	= -f,-1,-b,-r,-t,-z
%	         -3	= -f,-2,-l
%    -r	:		recover <struc(*)> in <cell(*)>
%    -t	:		test field constructors		[-f,-1|-2|-3]
%    -l	:		create <in2> from result	[-t : add isequal(in,in2)]
%    -n	:    'name'	redefine input name		[def: inputname(1)]
%    -p	:    'pref'	add <prefix>TOKEN
%    -s	:    'suff'	add TOKEN<suffix>
%   -sd	:   'X','Y'	redefine XstringY del		[def: >string<]
%    -b	:		show cell  brackets {}
%    -c	:		show token contents @id/index
%    -z	:		show token size			[def: bytes]
%    -h	:		show example file		[def: gettokh1.m]
%    -q	:		suppress runtime output/test
%    -Q	:		suppress runtime output
%
% NOTE	:
%	-f,-1|-2|-3
%	default <struct>-name if <in> is not a <struct>:
%		- Astruct.  CONSTRUCTOR	= TOKEN		for struct.field
%		- Acell.    CONSTRUCTOR	= TOKEN		for cells
%		- Anr.  val.CONSTRUCTOR	= TOKEN		for numbers
%		- Aobj. val.CONSTRUCTOR	= TOKEN		for other objects
%
%	procpar.field:	constructors			eg: in.x{3,2,3}.y(1,2).z
%			show the ML syntax to retrieve
%			the contents of the construct
%			at the command prompt
%	procpar.desc :	contents descriptors		eg: @N.1(2,2,3:uint8)
%			a brief summary of the
%			constructor's contents
%			STRING		>string< [b]	[change del: <-sd>]
%			OTHER		@type.nri(size:class) [b]
%			-type :		@C	cell
%					@E	valid  empty constructor
%						cannot evaluate contents
%					@N	numerical
%					@O	object
%					@S	struct
%					@T	char array
%			-nri  :		nr	of instance of type
%			-size :		size	of contents
%			-class:		class	of contents
%			-b    :		bytes
%	procpar.val  :	contents			[if <-l>]

% created:
%	us	10-Jun-2001
% modified:
%	us	16-Feb-2002		/ released to CSSM and TMW
%	us	23-Apr-2005		/ dynamic fields R13+
%	us	25-Apr-2005 09:06:44

function	[out1,out2,out3]=gettok(s,varargin)

		ver='25-Apr-2005 09:06:44';
	if	nargout
		out1=ver;		% def: return current version
		out2=[];
		out3=[];
	end

	if	nargin < 1
		help gettok;
		return;
	end
	if	nargin == 1 & strcmp(s,'-h');
	if	exist('gettokh1.m')
		type gettokh1.m;
	else
		disp('gettok> help file(s) not available');
	end
		return;
	end

		[s,par]=ini_par(ver,inputname(1),s,varargin);

		t=[];
	if	ischar(s)
		[t,par]=get_string(s,par,0);
	else
		[t,par]=RUN_gettok(s,par);
	end
		par.n=par.n-1;

	if	nargout
	if	~isempty(par.opt.f) & (par.opt.f < 0 & ~isempty(par.field))
		out1=par.field;
		out2=par.desc;
		out3=update(par,-1);
		par=run_test(s,par,0);
	else
		out1=t;
	if	ischar(t)
	if	t(1) == ' '
		t=t(2:end);
	end
		out1=strrep(t,'  ',' ');
	end
		out2=update(par,-1);
		out3=[];
	end
	else
		out1=t;
	end
		return;
%--------------------------------------------------------------------------------
function	[t,par]=RUN_gettok(s,par);

		par.cv=s;
	if	ischar(s)
		par.cmod{par.level}='C';
		[t,par]=get_string(s,par,1);
	elseif	iscell(s)
		par.cmod{par.level}='X';
		[t,par]=get_cell(s,par,0);
	elseif	isstruct(s)
		par.cmod{par.level}='S';
		[t,par]=get_struct(s,par,0);
	elseif	isnumeric(s) & par.opt.f > 0
		par.cmod{par.level}='N';
		par.tc=par.tc+1;
		[t,par]=get_char(s,par,0);
	elseif	isnumeric(s)
		par.cmod{par.level}='N';
		par.tc=par.tc+1;
		[t,par]=get_obj(s,par,1);
	else
		par=update(par,'O');
		[t,par]=get_obj(s,par,1);
	end
		return;
%--------------------------------------------------------------------------------
% STRING
%--------------------------------------------------------------------------------
function	[t,par]=get_string(s,par,mode)

		par.cv=s;
% R12.1		t={};
		t=[];
		par.tc=par.tc+1;
		[nr,nc]=size(s);

% TEXT BLOCK:	r x c
	if	par.level > 1 | (nr > 1 & nc > 1)
		[tok,par]=get_obj(s,par,1);
	if	mode == 1
		t=[t [par.opt.pval tok par.opt.sval]];
	else
		t=[t;{[par.opt.pval tok par.opt.sval]}];
	end
		par.cv=s;
		return;
	end

% TEXT LINE:	r x 1 | 1 x c
		tail=s;
	while	1
		[tok,tail]=strtok(tail);
		tok=tok(:)';
	if	isempty(tok)
		break;
	end
	if	mode == 1
		t=[t [par.opt.sdval{1} par.opt.pval tok par.opt.sval par.opt.sdval{2}]];
	if	par.opt.z
		t=t(1:end-1);
		sb=get_whos(par,tok);
		t=sprintf('%s [%-1d]',t,sb.bytes);
	end
	else
		t=[t;{[par.opt.sdval{1} par.opt.pval tok par.opt.sval par.opt.sdval{2}]}];
	end
	end
		par=update(par,'c');
		par.cv=s;
		return
%--------------------------------------------------------------------------------
% CELL
%--------------------------------------------------------------------------------
function	[t,par]=get_cell(s,par,mode)

		par.cv=s;

% R12.1		t={};
		t=[];

		nc=prod(size(s));
	if	~nc | (par.opt.b & par.tc >= 0)
		par.tc=par.tc+1;
		[tmp,par]=get_obj(s,par);
		t=[tmp '{ ' t];
	end

		nc=prod(size(s));
		nd=size(s);
	for	i=1:nc
		six=get_index(i,nd);
		v=s{i};
		orlevel=par.rlevel;
% recover cell contents
	if	ischar(v)
		par.tc=par.tc+1;
		par.clevel(par.level)=par.clevel(par.level)+1;
		par.cindex(par.clevel(par.level),par.level)={six};
		[tmp,par]=get_obj(v,par,0);
		par.cindex(par.clevel(par.level),par.level)={[]};
		par.clevel(par.level)=par.clevel(par.level)-1;
		t=[t tmp ' '];
	elseif	iscell(v)
		par.tc=par.tc+1;
		par.clevel(par.level)=par.clevel(par.level)+1;
		par.cindex(par.clevel(par.level),par.level)={six};
		[tmp,par]=get_cell(v,par,1);
	if	isempty(v)
		sname=get_sref('X',par,0);
		par=print_token(sname,tmp,par,1);
	end
		par.cindex(par.clevel(par.level),par.level)={[]};
		par.clevel(par.level)=par.clevel(par.level)-1;
		t=[t tmp ' '];
	else	
		par.tc=par.tc+1;
		par.clevel(par.level)=par.clevel(par.level)+1;
		par.cindex(par.clevel(par.level),par.level)={six};
		par.rlevel(par.level)=0;
		par.rindex(par.level)={[]};
		[tmp,par]=get_obj(v,par,0,'{}');
		par.cindex(par.clevel(par.level),par.level)={[]};
		par.clevel(par.level)=par.clevel(par.level)-1;
		t=[t tmp ' '];
	end
		par.rlevel=orlevel;
	end

	if	~isempty(t)
		t(end)=[];
	end
	if	~nc | (par.opt.b & par.tc >= 0)
		t=[t ' }'];
	end
		par.cv=s;
		return
%--------------------------------------------------------------------------------
% STRUCTURE
%--------------------------------------------------------------------------------
function	[t,par]=get_struct(s,par,mode)

		par.cv=s;
		par=get_level([],par,0);

% R12.1		t={};
		t=[];
		st=dbstack;
		sn=size(st,1);
		fn=fieldnames(s);
		fs=prod(size(fn));
		ss=s(:);

%		disp(sprintf('GET STRUCTURE from [%5d:%5d<%5d] %5d <%s>',sn,st(2).line,st(3).line,par.level,[par.ctok{:}]));
		[nr,nc]=size(ss);
		nd=size(s);

% REMOVED 23-Apr-2005:
% TERRIBLE KLUDGE for anomalous cases of the form:
% s.a=struct([]) | s.a=struct('b',{},'c',{})
% MUST use temp var <ans>!

	if	~(nr*nc) | ~fs
		fs=size(fn,1);
	if	~fs
		par.level=par.level-1;
		sname=get_sref('S',par,0);
	try
% keep this <eval>!
		com=sprintf('%s=struct([]);',sname(1:end-1));
		eval(com);
	catch
%		disp('warning');
	end
		[t,par]=get_obj(s,par,1);
		par.flag(par.n)=1;
		par=print_token(sname,t,par,1);
		par.level=par.level+1;
	else
	for	i=1:fs
		par.ctok(par.level)={[fn{i} '.']};
		par.cmod(par.level)={'?'};
		par.pmod(par.level)=0;
		nans=get_whos(par,s);
		nans=prod(nans.size);
% R12.1 ori	com=sprintf('deal(s.%s);',fn{i});
% ...		eval(com);
% ...	if	isempty(ans) & iscell(ans)
% ...		[t,par]=get_cell({},par,1);
	if	~nans
		[t,par]=get_obj([],par,1);
		sname=get_sref('X',par,1);
		t=strrep(t,'@N','@E');
		t=strrep(t,'0:double','0:?????');
		par.flag(par.n)=1;
		par=print_token(sname,t,par,1);
	else
		[t,par]=get_obj(s,par,0);
	end
	end
	end
	end

	if	par.opt.f >= 0
		nr=1;
	end
	for	j=1:nr
		s=ss(j);
		par.tc=par.tc+1;
	if	fs
		par.ctok=par.ctok(1:par.level-1);
		par.cmod=par.cmod(1:par.level-1);
		par.pmod=par.pmod(1:par.level-1);
	end

	if	nr > 1
		six=get_index(j,nd);
		par.rindex(par.level-1)={six};
		par.rlevel(par.level-1)=1;
	else
		par.rindex(par.level-1)={[]};
		par.rlevel(par.level-1)=0;
	end

	if	~fs & ~isempty(fn)
		par.level=par.level-1;
		[t,par]=get_obj(s,par,0);
		par.level=par.level+1;
	else
	for	i=1:fs
		tok=fn{i};
		par.ctok(par.level)={[tok '.']};
		par.cmod(par.level)={'?'};
		par.pmod(par.level)=0;
		par.index(par.level)=0;
		par.clevel(par.level)=0;
		par.cindex(:,par.level)={[]};
		par.rlevel(par.level)=0;
		par.rindex(par.level)={[]};

	if	par.opt.f == 1
		t=[t [par.opt.pval tok par.opt.sval] ' '];
	else
		t=[t;{[par.opt.pval tok par.opt.sval]}];
	end

	if	par.opt.f < 0
% continuing <@S> enumeration
%		os=par.tx.s;
%		par=update(par,-2);
%		par.tx.s=os;
		par=update(par,-2);

%		disp(sprintf('>>> STRUCT %5d <%s>',is,tok));
	if	par.mver < 6.5
		com=sprintf('isstruct(s.%s);',tok);
		is=eval(com);
		com=sprintf('RUN_gettok(s.%s,par);',tok);
		[a,par]=eval(com);
	else
		is=isstruct(s.(tok));
		[a,par]=RUN_gettok(s.(tok),par);
	end
%		disp(sprintf('<<< STRUCT %5d <%s>',is,tok));

	if	~is
		sname=get_sref('X',par,1);
		par.fsf=0;
		par=print_token(sname,a,par,0);
		par.pmod(par.level)=0;
	else
%		disp(sprintf('skipping token %5d/%5d <%s> %5d: %s',j,i,tok,par.level));
	end

	end
	end
	end
	end

		par=get_level([],par,-1);
		par.cname=[];
		par.ctok=par.ctok(1:par.level);
		par.cmod=par.cmod(1:par.level);
		par.pmod=par.pmod(1:par.level);
		par.cv=s;
%		disp(sprintf('END STRUCTURE from [%5d<%5d] %5d: %s',st(2).line,st(3).line,par.level));
		return;
%--------------------------------------------------------------------------------
% OBJECT
%--------------------------------------------------------------------------------
function	[t,par]=get_obj(v,par,mode,br)

% mode:		par.index(par.level)
%    0		update
%   ~0		do not update

		par.cv=v;
		sb=get_whos(par,v);
	if	prod(sb.size) == 0
		sbs='0';
	else
		sbs=sprintf('%-1d,',sb.size);
		sbs=sbs(1:end-1);
		sbs=sb.tsize;
	end

	if	isnumeric(v)
%		disp('GET NUMBER');
		ix=par.tx.n(end)+1;
%		sb=get_whos(par,v);
		t=sprintf('@N.%-1d(%s:%s)',ix,sbs,sb.class);
		par=update(par,'n');
	if	par.opt.z
		t=sprintf('%s [%-1d]',t,sb.bytes);
	end
	if	~mode & par.opt.r
		par=get_level('N',par,2);
		cname=get_sref('N',par,0);
		par=print_token(cname,t,par,1);
	end
	elseif	ischar(v)
%		disp(sprintf('GET CHAR BLOCK <%s>',v));
	if	sb.size == 0 | sb.size(1) == 1 | sb.size(2) == 1
		t=[par.opt.sdval{1} v(:)' par.opt.sdval{2}];
		par=update(par,'c');
	else
		ix=par.tx.t(end)+1;
		t=sprintf('@T.%-1d(%s)',ix,sbs);
		par=update(par,'t');
	end
	if	par.opt.z
		t=sprintf('%s [%-1d]',t,sb.bytes);
	end
	if	~mode & par.opt.r
		par=get_level('T',par,2);
		cname=get_sref('T',par,0);
		par=print_token(cname,t,par,1);
	end
	elseif	isstruct(v)
%		disp('GET STRUCT');

		ssf=length(fieldnames(v));
		ix=par.tx.s(end)+1;
		t=sprintf('@S.%-1d(%s:%-1d)',ix,sbs,ssf);
		par=update(par,'s');
	if	par.opt.z
		t=sprintf('%s [%-1d]',t,sb.bytes);
	end
	if	mode
		return;
	end
		par=get_level('S',par,2);
		cname=get_sref('S',par,0);

% RECURSION
	if	par.opt.r
	if	par.fsf
		par.fsf=par.fsf+1;
		par.fs=par.fs+1;
		par.cname=cname;
%		disp(sprintf('>> recursion %5d %5d <%s>',par.fsf,par.fs,par.cname));
		[tt,par]=RUN_gettok(v,par);
		par.fsf=par.fsf-1;
		par.fs=par.fs-1;
%		disp(sprintf('<< recursion %5d %5d <%s>',par.fsf,par.fs,par.cname));
	if	par.fs
		return
	end
	end
		par.cname=cname;
		par.fs=par.fs+1;
		par.fsf=1;
		orlevel=par.rlevel;
%		disp(sprintf('---------> floating structure <--------- %5d/%-1d <%s>',par.fs,par.fsf,class(v)));
		[tt,par]=RUN_gettok(v,par);
		par.fsf=0;
		par.fs=par.fs-1;
%		disp(sprintf('---------< floating structure >--------- %5d/%-1d',par.fs,par.fsf));
		par.rlevel=orlevel;
	end
	elseif	iscell(v)
%		disp('GET CELL');
		ix=par.tx.x(end)+1;
		t=sprintf('@C.%-1d(%s)',ix,sbs);
		par=update(par,'x');
	if	par.opt.z
		t=sprintf('%s [%-1d]: ',t,sb.bytes);
	end
	else
%		disp('GET OBJECT');
		ix=par.tx.o(end)+1;
		t=sprintf('@O.%-1d(%s:%s)',ix,sbs,sb.class);
		par=update(par,'o');
	if	par.opt.z
		t=sprintf('%s [%-1d]',t,sb.bytes);
	end
	if	~mode & par.opt.r
		par=get_level('O',par,2);
		cname=get_sref('O',par,0);
		par=print_token(cname,t,par,1);
	end
	end
		return;
%--------------------------------------------------------------------------------
% CHAR RANGE
%--------------------------------------------------------------------------------
function	[t,par]=get_char(s,par,mode)

% R12.1		t={};
		t=[]'
		par=update(par,0);
	switch	s(1)
	case	{1}
		t=char([double('a'):double('z')]');
	case	{2}
		t=char([double('A'):double('Z')]');
	case	{3}
		t=char([double('A'):double('Z')]');
		t=[t;char([double('a'):double('z')]')];
	otherwise
%		[t,par]=get_obj(s,par,0);
	end
	if	~isempty(par.opt.pval)
		par.opt.pval=repmat(par.opt.pval,size(t,1),1);
		t=[par.opt.pval t];
	end
	if	~isempty(par.opt.sval)
		par.opt.sval=repmat(par.opt.sval,size(t,1),1);
		t=[t par.opt.sval];
	end
		t=cellstr(t);
	if	~isempty(t)
		par.tx.c=[0 1:length(t)];
	end
		return;
%--------------------------------------------------------------------------------
% TEST
%--------------------------------------------------------------------------------
function	par=run_test(s,par,mode)

% keep these <eval>s!

	if	mode
	if	par.opt.q | ~par.opt.t | par.opt.f >= 0 | par.opt.c
		return;
	end
		pflg=par.flag(par.n-1);
		tok=sprintf('par.v%s;',s(length(par.iname)+1:end));
	try
		eval(tok);
%		disp(sprintf('%5d> %s CHECK field <%s>',par.n-1,par.iname,par.field{par.n-1}));
		par.flag(par.n-1)=0;
	catch
		disp(sprintf('%5d! %s ERROR field <%s>',par.n-1,par.iname,tok));
		par.flag(par.n-1)=-1;
	end
	if	par.opt.l
		par.val{par.n-1}=par.cv;
		tok=sprintf('par.vv%s=par.cv;',s(length(par.iname)+1:end));
		eval(tok);
	if	isnumeric(par.cv) & strcmp(class(par.cv),'double')
	if	~isempty(find(isnan(par.cv)))
		par.flag(par.n-1)=-2;
	end
	end
	if	pflg == 1
		par.flag(par.n-1)=-3;
	end
	end
		return;
	end

	if	par.opt.q | par.opt.Q
		return;
	elseif	par.opt.c
		disp(sprintf('gettok> cannot test input with flag <-c>'));
		return;
	elseif	~par.n
		disp(sprintf('gettok> output not a struc'));
		return;
	end

		res=isempty(find(par.flag==-1));
	if	res
		disp(sprintf(' TEST: %s OK    field(s)',par.iname));
	else
		disp(sprintf(' TEST: %s ERROR field(s)',par.iname));
	end
	if	par.opt.l
		ress=isequal(par.v,par.vv);
	if	ress
		disp(sprintf(' TEST: %s OK    struct',par.iname));
	else
		disp(sprintf(' TEST: %s ERROR struct',par.iname));
		res=find(par.flag==-2);
	for	i=1:length(res)
		disp(sprintf('%5d! %s error NaN:       <%s>',res(i),par.iname,par.field{res(i)}));
	end
		res=find(par.flag==-3);
	for	i=1:length(res)
		disp(sprintf('%5d! %s error struct().x <%s>',res(i),par.iname,par.field{res(i)}));
	end
	end
	end
		return;
%--------------------------------------------------------------------------------
% UTILITIES
%--------------------------------------------------------------------------------
function	[s,par]=ini_par(pver,iname,s,var)

		cflg=0;
		tmps=s;
		suff=[];
	if	~isstruct(s)
		cflg=1;
	if	iscell(s)
		cflg=0;
	end
	if	isnumeric(s)
		suff='.val';
	end
	end
	if	isempty(iname)
	if	isnumeric(s)
		iname=['A' 'nr'];
	else
	switch	class(s)
	case	{ 'struct' 'cell' 'char' }
		iname=['A' class(s)];
		cflg=0;
	otherwise
		iname=['A' 'obj'];
	end
	end
	end

		par=[];
		ipar=parse(par,var{:});
	if	ipar.opt.n
		iname=ipar.opt.nval;
	else
		ipar.opt.nval=iname;
	end
		par.version=pver;
		par.mrel=version;
% NOT in R12.1!	par.mver=version('-release');
% TEST		par.mrel='6.5.0.180913a';
		par.mver=sum(sscanf(par.mrel,'%d.%d').*[1 .1].');
		par.runtime=datestr(now);
		par.v=s;
		par.vv=[];
		par.cv=[];
		par.n=1;
		par.level=1;
		par.field={};
		par.desc={};
		par.val={};
		par.flag=[];
		par.iname=iname;
		par.suffx=suff;
		par.cname=[];
		par.index=[0];
		par.ctok={[iname '.']};
		par.cmod={};
		par.pmod=[0];
		par.clevel=[0];
		par.cindex={};
		par.rlevel=[];
		par.rindex={};
		par.tag=[];
		par.fs=0;
		par.fsf=0;
		par.tx=[];
		par=update(par,-2);
		par=update(par,1);
		par.opt=ipar.opt;
		par.opt.class=class(s);
		par.opt.hasval=0;

	if	par.opt.f < 0 & cflg
		par.opt.hasval=1;
		clear s;
		s.val=tmps;
		par.v=s;
	end
		return;
%--------------------------------------------------------------------------------
function	par=parse(par,varargin)

%			flg	arg	def	type	% contents
%				=flg
%				=flgval
		opt={
			'-b'	0	0	[]	% show cell brackets
			'-c'	0	0	[]	% show cell indexing
			'-f'	-1	0	[]	% proc mode
			'-l'	0	0	[]	% load/recreate IN by result
			'-n'	1	''	[]	% input name
			'-p'	1	''	[]	% prefix
			'-q'	0	0	[]	% quiet mode discard vals
			'-Q'	0	0	[]	% quiet mode save    vals
			'-r'	0	0	[]	% recursion
			'-s'	1	''	[]	% suffix
			'-sd'	2	''	{}	% char delimiters
			'-t'	0	0	[]	% test output
			'-z'	0	0	[]	% show token size
		};

% keep these <eval>s... (we know it's bad!)
	for	i=1:size(opt,1)
		op=opt{i,1};
		na=opt{i,2};
		r=find(strcmp(op,varargin));
		com=sprintf('par.opt.%s=0;',op(2:end));
		eval(com);
		com=sprintf('par.opt.%sval=opt{i,3};',op(2:end));
		eval(com);
	if	~isempty(r) & nargin-abs(na) > r
		com=sprintf('par.opt.%s=1;',op(2:end));
		eval(com);
	if	na
	for	j=1:abs(na)
	if	na > 0
	if	iscell(opt{i,4})
		com=sprintf('par.opt.%sval{%-1d}=varargin{r+%-1d};',op(2:end),j,j);
	else
		com=sprintf('par.opt.%sval=varargin{r+%-1d};',op(2:end),j);
	end
	else
		com=sprintf('par.opt.%s=varargin{r+%-1d};',op(2:end),j);
	end
		eval(com);
	end
	else
		com=sprintf('par.opt.%sval=opt{i,3};',op(2:end));
		eval(com);
	end
	end
	end

		fopt=par.opt.f;
	if	fopt == -3
		fopt=-2;
		par.opt.l=1;
	end
	if	fopt == -2
		par.opt.b=1;
		par.opt.r=1;
		par.opt.t=1;
		par.opt.z=1;
	end
	if	par.opt.f < 0 & ~par.opt.sd
		par.opt.sdval{1}='>';
		par.opt.sdval{2}='<';
	elseif	~par.opt.sd
		par.opt.sdval{1}='';
		par.opt.sdval{2}='';
	end
		return
%--------------------------------------------------------------------------------
function	par=update(par,mode)

	if	isempty(par) | mode == -2
		par.tx.c=0;	% char/string
		par.tx.t=0;	% char block
		par.tx.n=0;	% numeric
		par.tx.s=0;	% struct
		par.tx.x=0;	% cell
		par.tx.o=0;	% objects
		par.ix=1;	% object index
		par.tc=0;	% cell index
		return;
	end
	if	mode == -1
		opar=par;
	if	length(par.tx.c) > 1
		opar.tx.c=par.tx.c(2:end);
	end
	if	length(par.tx.t) > 1
		opar.tx.t=par.tx.t(2:end);
	end
	if	length(par.tx.s) > 1
		opar.tx.s=par.tx.s(2:end);
	end
	if	length(par.tx.n) > 1
		opar.tx.n=par.tx.n(2:end);
	end
	if	length(par.tx.x) > 1
		opar.tx.x=par.tx.x(2:end);
	end
	if	length(par.tx.o) > 1
		opar.tx.o=par.tx.o(2:end);
	end
		par=[];
		par.version=opar.version;
		par.mrel=opar.mrel;
		par.mver=opar.mver;
		par.runtime=opar.runtime;
		par.n=opar.n;
		par.field=opar.field;
		par.desc=opar.desc;
		par.val=opar.val';
%		par.v=opar.v;
%		par.vv=opar.vv;
		par.flag=opar.flag(1:par.n)';
		par.tx=opar.tx;
		par.opt=opar.opt;
		return;
	end
	if	ischar(mode)
	switch	mode
	case	{'c'}
		par.tx.c(end+1)=par.tx.c(end)+1;
		par.ix=par.ix+1;
	case	{'t'}
		par.tx.t(end+1)=par.tx.t(end)+1;
		par.ix=par.ix+1;
	case	{'s'}
		par.tx.s(end+1)=par.tx.s(end)+1;
		par.ix=par.ix+1;
	case	{'n'}
		par.tx.n(end+1)=par.tx.n(end)+1;
		par.ix=par.ix+1;
	case	{'x'}
		par.tx.x(end+1)=par.tx.x(end)+1;
		par.ix=par.ix+1;
	otherwise
		par.tx.o(end+1)=par.tx.o(end)+1;
		par.ix=par.ix+1;
	end
	end
		return;
%--------------------------------------------------------------------------------
function	par=get_level(tag,par,mode)

	switch	mode
	case	-1
		par.level=par.level-1;
		par.index=par.index(1:end-1);
		par.tag=par.tag(1:end-1);
		par.cindex=par.cindex(:,1:par.level);
		par.clevel=par.clevel(1:par.level);
		par.rindex=par.rindex(1:par.level);
		par.rlevel=par.rlevel(1:par.level);
	case	0
		par.level=par.level+1;
		par.index=[par.index 0];
		par.tag=[par.tag ' '];
		par.cindex(:,par.level)={[]};
		par.clevel(par.level)=0;
		par.rindex(par.level)={[]};
		par.rlevel(par.level)=0;
	case	1
	if	par.fsf
		par.index(par.level)=par.index(par.level)+1;
		par.tag(par.level)=tag;
	end
	case	2
		par.index(par.level)=par.index(par.level)+1;
		par.tag(par.level)=tag;
	end
		return;
%--------------------------------------------------------------------------------
function	six=get_index(ndx,nd)

% to reduce (1,x) | (x,1) -> (x)
	if	0
	if	length(nd) == 2
	if	nd(1) == 1 | nd(2) == 1
		nd=prod(nd);
	end
	end
	end
% from <sub2ind.m>
		nd=[nd(1:end-1) prod(nd(1:end))];
		n=length(nd);
		k=[1 cumprod(nd(1:end-1))];
		six='';
		ndx=ndx-1;
		six='';
	for i=n:-1:1
		kk=floor(ndx/k(i))+1;
		ndx=rem(ndx,k(i));
		six=sprintf('%-1d,%s',kk,six);
	end
		six=six(1:end-1);
		return;
%--------------------------------------------------------------------------------
function	cname=get_sref(tag,par,oflg)

		index=par.index;
	if	oflg
		index(end)=0;
	end
		cname='';
		sname=par.ctok;
	for	i=1:par.level
		cname=[cname sname{i}(1:end-1)];
% add {}
	for	j=1:par.clevel(i)
		cname=[cname '{' par.cindex{j,i} '}'];
	end
% add ()
	if	~isempty(par.rlevel)
	if	par.rlevel(i)
		cname=[cname '(' par.rindex{i} ')'];
	end
	end
	if	par.opt.c
% add cell contents/index
	if	index(i)
		cname=[cname sprintf('<@%s%-1d>',par.tag(i),index(i))];
	end
	end
		cname=[cname '.'];
	end
		return;
%--------------------------------------------------------------------------------
		function	t=get_whos(par,var)

		t=whos('var');
		t.tsize=sprintf('%-1d:%s',numel(t.size),num2str(t.size,'%-1d,'));
		t.tsize(end)='';

	if	par.mver < 7
		return;
	end

		ext='';
	if	t.global
		ext=[ext 'global.'];	% this should NEVER happen!
	end
	if	t.sparse
		ext=[ext 'sparse.'];
	end
	if	t.complex
		ext=[ext 'complex.'];
	end
	if	~isempty(ext)
		t.class=sprintf('%s%s',ext,t.class);
	end
		return
%--------------------------------------------------------------------------------
function	par=print_token(sname,a,par,mode)

	if	mode
		par.pmod(1:par.level)=mode;
	elseif	par.pmod(par.level)
%		disp('skipping next entry ...');
		return;
	end
		sname(end)='';
		par.field=[par.field;{sname}];
		par.desc=[par.desc;{a}];
	if	~par.opt.q && ~par.opt.Q
		disp(sprintf('%5d: %s = %s',par.n,sname,a));
	end
		par.n=par.n+1;
		par.flag(par.n)=0;
		par.pmod(1:par.level-1)=1;
		par=run_test(sname,par,par.opt.f);
		return;
%--------------------------------------------------------------------------------

Contact us