// Reconcile DEP-5 debian/copyright to licensecheck report on source tree
//
// Copyright : 2024 P Blackman
// License   : BSD-2-clause
//
// Exclude files and folders likely to lead to false positives

unit exclude;
{$mode delphi}

interface

function IgnoreFile (Fname : AnsiString) : Boolean;
procedure LoadExcludes;


implementation uses Classes, StrUtils, SysUtils, Support;
{$warn 6058 off} // Don't need to hear about inlining issues

const GenExcludes : String = '/usr/share/lrc/lrc.excludes';  // General exclisions
      LocExcludes : String = 'debian/lrc.excludes';          // Specific to package

var
    ExcludedFiles,
    ExcludedDirs : tStringList;


procedure LoadFile (var Files, Dirs : tStringList; var MyFile : text);
var Line : String;
begin
    while NOT EOF (MyFile) do
    begin
        ReadLn (MyFile, Line);

        If length (Line) = 0 then
            // Empty line
        else
        if Line[1] < Chr(20) then
            // Blank line
        else
        if Line[1]  = '#' then
            // Comment
        else
        begin
            if Line[Length(Line)] = '/' then
                Dirs.Add (Line)
            else
                Files.Add (Line);
        end;
    end;
end;

procedure LoadExcludes;
var MyFile : text;
begin
    ExcludedFiles := tStringList.Create;
    ExcludedDirs  := tStringList.Create;

    if OpenFile (GenExcludes, MyFile) then
    begin
        LoadFile (ExcludedFiles, ExcludedDirs, MyFile);
        Close (MyFile);
    end;

    if OpenFile (LocExcludes, MyFile) then
    begin
        LoadFile (ExcludedFiles, ExcludedDirs, MyFile);
        Close (MyFile);
    end;
end;

// Check if the end of the path name matches an exclusion
function CheckDirs (Path : AnsiString) : Boolean;
var I : integer;
begin
    I := 0;
    result := False;

    While NOT result and (I < ExcludedDirs.Count) do
    begin
        result := EndsText (ExcludedDirs[I], Path);
        I := I+1;
    end;
end;

// Check if beginning of file name matches an exclusion
function CheckFiles (FullName : AnsiString) : Boolean;
var I : integer;
begin
    I := 0;
    result := False;

    While NOT result and (I < ExcludedFiles.Count) do
    begin
        result := StartsText (ExcludedFiles[I], FullName);

        if ContainsStr (Fullname, '/') then
            // Maybe a sub-directory
            result := result or EndsText (ExcludedFiles[I], FullName);

        I := I+1;
    end;
end;


function IgnoreFile (Fname : AnsiString) : Boolean;
var FullName, Path : AnsiString;
begin
    FullName := ExtractFileName(Fname);
    Path     := ExtractFilePath(Fname);

    // Check files with or without the path
    result := CheckDirs (Path) or CheckFiles (FullName) or CheckFiles (FName);
end;

end.
