function pcode(varargin)
%PCODE  Create pre-parsed pseudo-code file (P-file).
%   PCODE FUN parses the M-file FUN.M into the pre-parsed pseudo-code file
%   (P-file) FUN.P and puts it into the current directory (private and
%   method directories will be created for private and object methods if
%   the directories don't already exist). The original M-file may be
%   anywhere on the MATLAB search path.
%
%   PCODE FUN1 FUN2 ... creates P-files for the listed functions.
%
%   PCODE *.m creates P-files for all the M-files in the current
%   directory.
%
%   PCODE ... -INPLACE  creates the P-files in the same directory
%   as the m-file.  An error occurs if the files can't be created.
 
%   Copyright 1984-2000 The MathWorks, Inc. 
%   $Revision: 1.25 $  $Date: 2000/06/01 01:25:38 $

inplace = 0;
flag = {};
for i=nargin:-1:1
  if ~isstr(varargin{i}) | ...
      size(varargin{i},1)~=1 | ndims(varargin{i})~=2
    error('Input arguments must be single strings.');
  end
  if strncmp(varargin{i},'-',1) % It's a flag
    if strcmp(varargin{i},'-inplace'),
      inplace = 1;
    else
      flag = [flag varargin(i)];
    end
    varargin(i) = []; % Remove flag from input list
  end
end

if length(flag)>1, error('Too many flags.'); end

for i=1:length(varargin),
  if strcmp(varargin{i},'*'), varargin{i} = '*.m'; end
  if any(varargin{i}=='*'),
    files = dir(varargin{i});
    for j=1:length(files),
      preparse(files(j).name,inplace,flag);
    end
  else
    file = varargin{i};
    [fpath,fname,fext,fver] = fileparts(file);
    % Add .m if necessary
    if isempty(fext)
       file = [file '.m'];
    elseif strcmp(fext,'.p');
       file = fullfile(fpath,[fname '.m']);
    end
    preparse(file,inplace,flag);
  end
end

%-------------------------------------------
function preparse(file,inplace,flag)
%   Preparse file

% Convert filename into full path name before calling pfile.
fn = which(file);
if isempty(fn),
  fid = fopen(file);
  if fid==-1,
     warning(sprintf('File ''%s'' not found.',file))
     return
  else
    fn = fopen(fid);
    fclose(fid);
  end
end

% Make sure filename ends with .m
if all(lower(fn(end-1:end))=='.m'),
  if inplace,
    pfile(fn,[fn(1:end-2) '.p'],flag{:});
  else
    d = pwd;
    [dum,doops,dpriv] = basename(fullfile(pwd,'dummy.m'));
    [name,oops,priv] = basename(fn);
    if ~isempty(oops) & ~isequal(doops,oops)
      if ~exist(fullfile(pwd,oops,''),'dir')
        mkdir(oops)
        if ~exist(fullfile(pwd,oops,''),'dir')
          error(sprintf('Could not create %s directory.',oops))
        end
      end
      d = fullfile(d,oops,'');
    end
    if ~isempty(priv) & ~isequal(dpriv,priv)
      if ~exist(fullfile(d,priv,''),'dir')
        mkdir(fullfile(d,''),priv)
        if ~exist(fullfile(d,priv,''),'dir')
          error(sprintf('Could not create %s directory.',priv))
        end
      end
      d = fullfile(d,priv,'');
    end
    
    pfile(fn,fullfile(d,[name(1:end-2) '.p']),flag{:});
  end
else
  warning(sprintf('Skipping "%s" since it isn''t an m-file.',file))
end

%-----------------------------
function [b,oops,priv] = basename(fn)
oops = '';
priv = '';
k = max(find(fn==filesep));
if isempty(k)
  b = fn;
else
  b = fn(k+1:end);

  % Look for private and class directory
  p = fn(1:k-1);
  if ~isempty(p)
    k = max(findstr([filesep 'private'],p));
    if ~isempty(k) & k == length(p)-7,
      priv = p(k:end); % Private directory name
      p = p(1:k-1);
    end
    if ~isempty(p)
      k = max(find(p=='@'));
      if ~isempty(k) & ~any(p(k:end)==filesep)
        oops = p(k:end); % Class directory name
      end
    end
  end 
end

