function [BLK,INVALIDKEY,INVALIDALLBUT] = readblk(THIS)
% READBLK  [Not a public function] Read individual blocks of theparser code.
%
% Backend IRIS function.
% No help provided.

% -IRIS Toolbox.
% -Copyright (c) 2007-2012 Jaromir Benes.

%**************************************************************************

nblk = length(THIS.blkname);

% Check all words starting with an !.
INVALIDKEY = xxchkkey(THIS);
INVALIDALLBUT = false;

% Add new line character at the end of the file.
if isempty(THIS.code) || THIS.code(end) ~= char(10)
    THIS.code(end+1) = char(10);
end

% End of block (eob) is start of another block or end of file.
index = ~cellfun(@isempty,THIS.blkname);
eob = sprintf('|%s',THIS.blkname{index});
eob = ['(?=$',eob,')'];

% Remove redundant semicolons.
THIS.code = regexprep(THIS.code,'(\s*;){2,}',';');

% Read blocks.
BLK = cell(1,nblk);
for iblk = 1 : nblk
    if isempty(THIS.blkname{iblk})
        continue
    end
    % Read a whole block.
    pattern = [THIS.blkname{iblk},'\s+(.*?)',eob];
    tokens = regexpi(THIS.code,pattern,'tokens');
    tokens = [tokens{:}];
    if ~isempty(tokens)
        % !allbut must be in all or none of log declaration blocks.
        if THIS.flagblk(iblk)
            INVALIDALLBUT = INVALIDALLBUT || xxchkallbut(tokens);
        end
        BLK{iblk} = [tokens{:}];
    else
        BLK{iblk} = '';
    end
end

end

% Subfunctions.

%**************************************************************************
function INVALIDKEY = xxchkkey(THIS)

index = ~cellfun(@isempty,THIS.blkname);
allowed = [THIS.blkname(index),THIS.otherkey,{'!allbut'}];

key = regexp(THIS.code,'!\w+','match');
nkey = length(key);
valid = true(1,nkey);
for i = 1 : nkey
    valid(i) = any(strcmp(key{i},allowed));
end
INVALIDKEY = key(~valid);

end
% xxchkkey().

%**************************************************************************
function INVALID = xxchkallbut(tokens)

% The keyword `!allbut` must be in all or none of flag blocks.
index = cellfun(@isempty,regexp(tokens,'!allbut','match','once'));
INVALID = any(index) && ~all(index);

end
% xxchkallbut().