## Copyright (C) 2025 Dmitri A. Sergatskov <dasergatskov@gmail.com>
##
## This program is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License as
## published by the Free Software Foundation; either version 3 of the
## License, or (at your option) any later version.
##
## This program is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, see
## <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn  {Function File} {} run_pkg_add ()
## @deftypefnx {Function File} {} run_pkg_add (@var{dirs})
## Process PKG_ADD directives in source files.
##
## This function searches for PKG_ADD directives in .m and .cc files
## in the specified directories and evaluates them.
##
## If no @var{dirs} are provided, it searches in "inst" and "src" directories.
##
## @end deftypefn

function run_pkg_add (dirs)
  # If no directories are provided, use "inst" and "src"
  if (nargin < 1)
    dirs = {"inst", "src"};
  endif

  # Process each directory
  for i = 1:length (dirs)
    d = dirs{i};
    if (exist (d, "dir"))
      # Process .m files
      mfiles = dir (fullfile (d, "*.m"));
      for j = 1:length (mfiles)
        if (! mfiles(j).isdir)
          process_file (fullfile (d, mfiles(j).name));
        endif
      endfor

      # Process .cc files
      ccfiles = dir (fullfile (d, "*.cc"));
      for j = 1:length (ccfiles)
        if (! ccfiles(j).isdir)
          process_file (fullfile (d, ccfiles(j).name));
        endif
      endfor # *.cc files
    endif
  endfor # dirs
endfunction

function process_file (filename)
  # Open the file
  fid = fopen (filename, "r");
  if (fid < 0)
    return;
  endif

  unwind_protect
    # Read line by line, looking for PKG_ADD directives
    while (! feof (fid))
      line = fgetl (fid);
      if (! ischar (line))
        break;
      endif

      # Check for PKG_ADD lines using string functions
      if (strncmp (line, "// PKG_ADD:", 11))
        # Extract the directive
        pkg_cmd = line(12:end);
      elseif (strncmp (line, "## PKG_ADD:", 11))
        # Extract the directive
        pkg_cmd = line(12:end);
      else
        continue;
      endif

      # Trim leading/trailing whitespace
      pkg_cmd = strtrim (pkg_cmd);

      # Evaluate the directive
      if (! isempty (pkg_cmd))
        try
          eval (pkg_cmd);
        catch err
          warning (["Error evaluating PKG_ADD directive from ", ...
                    filename, ": ", err.message]);
        end_try_catch
      endif
    endwhile

  unwind_protect_cleanup
    # Close the file
    fclose (fid);
  end_unwind_protect
endfunction
