⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uparse.pas

📁 DelphiDoc is a program for automatic generation of documentation on a Delphi-Project. At the momen
💻 PAS
📖 第 1 页 / 共 5 页
字号:
 files and add their parsers to the list. The actual reading and parsing of the
 files of pascal code is done in ~[link ParseFile]. The files will only be read
 and the head (kind of file and the first uses-clause) will be parsed.
 Further passing must be done by calling the different methods of the parsers
 as done in ~[link DoParseFiles].
~param Files    the list of files to parse; if the objects-Property is not nil
                (that means Boolean(objects[i]) = True) and it is a
                project-file all used units will be parsed, too
~param Dirs     the list of directories whose files will be parsed;
                must be the absolute short names; that's means they're unique;
                if the objects-Property is not nil all subdirectories will also
                be parsed
~param NotFiles the list of files which will not be parsed if in Dirs or used
~param NotDirs  the list of directories whose files will not be parsed;
                must be the absolute short names; that's means they're unique;
                if the objects-Property is not nil all subdirectories will also
                not be parsed }
procedure TParserManager.ParseList(Files, Dirs, NotFiles, NotDirs: TStrings);
var       i, j          :Integer;     //general counters
          Count         :Integer;     //number of items in the lists
          //length of directory-path (for relative path)
          len           :Integer;
          List          :TStringList; //list for found files in directories
begin
 Count := Files.Count;
 if assigned(FProgress) then
  begin
   FProgress.SetWorkText('Parsing single Files...');
   FProgress.SetMaximum(Count);
  end;
 i := 0;                              //for each file to parse
 while (i < Count) and (not assigned(FProgress) or not FProgress.ShouldAbort) do
  begin
   if assigned(FProgress) then
    begin
     FProgress.SetProgressText(Format('Parsing File %d of %d', [i + 1, Count]));
     FProgress.SetProcessText(Files[i]);
    end;

   //parse the file
   ParseFile(Files[i], Boolean(Files.Objects[i]), Dirs, NotFiles, NotDirs);

   if assigned(FProgress) then
    FProgress.StepProgress;
   inc(i);
  end;

 if not assigned(FProgress) or not FProgress.ShouldAbort then
  begin
   List := TStringList.Create;   //create list for the files in the directories
   try
     List.Sorted := True;
     List.Duplicates := dupAccept;
     Count := Dirs.Count;
     if assigned(FProgress) then
      begin
       FProgress.SetWorkText('Parsing Directories...');
       FProgress.SetMaximum(Count * 5);
      end;
     j := 0;                     //for each directory
     while (j < Count) and
           (not assigned(FProgress) or not FProgress.ShouldAbort) do
      begin
       List.Clear;                 //search all files in the directory
       FindPasFiles(ExpandFileName(Dirs[j]), List, Boolean(Dirs.Objects[j]));
       //save length of absolute path (to delete it when showing the name)
       len := length(ExpandFileName(Dirs[j])) + 2;
       if assigned(FProgress) then
        FProgress.SetProgressText(Format('Found %d Files in %s',
                                        [List.Count, Dirs[j]]));
       i := 0;
       while (i < List.Count) and    //for all found pascal files
             (not assigned(FProgress) or not FProgress.ShouldAbort) do
        begin
         if assigned(FProgress) then   //show relative path
          FProgress.SetProcessText(copy(List[i], len,
                                       high(length(List[i]))));
         //if it should be parsed
         if FileDirAllowed(List[i], Dirs, NotDirs) then
          //parse the file
          ParseFile(List[i], False, Dirs, NotFiles, NotDirs);

         if assigned(FProgress) then
          FProgress.StepProgress;
         inc(i);
        end;  //for each file in the directory
       inc(j);
      end;  //for each directory
   finally
    List.Free;
   end;
 end; //if not FProgress.ShouldAbort
end;











































































{Preparses a file or files in a directory.
~param FileName  the name of the file or directory to parse
~param IsDir     if FileName points to a directory
~param Recursive if all used files/files in sub-directories should also be
                 parsed }
procedure TParserManager.PreparseOneFile(const FileName: String;
                                         IsDir, Recursive: Boolean);
var       Empty         :TStringList; //an empty list
          i             :Integer;     //general counter
          //length of directory-path (for relative path)
          len           :Integer;
          List          :TStringList; //list for found files in directories
begin
 Empty := TStringList.Create;         //create empty list
 try
   if not IsDir then
    begin
     if assigned(FProgress) then
      begin
       FProgress.SetWorkText('Parsing single File...');
       FProgress.SetMaximum(1);
       FProgress.SetProgressText('Parsing File 1 of 1');
       FProgress.SetProcessText(FileName);
      end;


     ParseFile(FileName, Recursive, Empty, Empty, Empty);  //parse the file

     if assigned(FProgress) then
      FProgress.StepProgress;
    end
   else
    begin
     List := TStringList.Create; //create list for the files in the directories
     try
       List.Sorted := True;
       List.Duplicates := dupAccept;
       if assigned(FProgress) then
        begin
         FProgress.SetWorkText('Parsing Directory...');
         FProgress.SetMaximum(1);
        end;

       //search all files in the directory
       FindPasFiles(ExpandFileName(FileName), List, Recursive);
       //save length of absolute path (to delete it when showing the name)
       if assigned(FProgress) then
        begin
         FProgress.SetMaximum(List.Count);
         FProgress.SetProgressText(Format('Found %d Files', [List.Count]));
        end;
       len := length(ExpandFileName(FileName)) + 2;
       i := 0;
       while (i < List.Count) and       //for all found pascal files
             (not assigned(FProgress) or not FProgress.ShouldAbort) do
        begin
         if assigned(FProgress) then       //show relative path
          FProgress.SetProcessText(copy(List[i], len, high(length(List[i]))));

         ParseFile(List[i], False, Empty, Empty, Empty);     //parse the file

         if assigned(FProgress) then
          FProgress.StepProgress;

         inc(i);
        end;  //for each file in the directory

     finally
      List.Free;                      //free list of files in the directory
     end;
    end;
 finally
  Empty.Free;                         //free empty list
 end;
end;




{Encapsulates the parsing of several pascal-files. This function provides a
 simple way to call the various functions and methods of different classes in
 the right sequence.
~result if the parsing wasn't aborted by the user }
function TParserManager.ParseFiles: Boolean;
var      AProgress     :TProgressAdapter;    //a dummy-object if none given
begin
 Result := True;                             //so far not aborted

 if not assigned(FProgress) then              //no FProgress-object given?
  begin
   AProgress := TProgressAdapter.Create;        //create a dummy object
   FProgress := AProgress;                      //and use it
  end
 else
  AProgress := nil;                             //nothing to free

 try
   try
     //do the actual parsing of the files
     DoParseFiles;
   except
     on E: EAbortProgress do                   //if parsing has been aborted
      Result := False;                           //simply return false
     else
      raise;
   end;
 finally
  if assigned(AProgress) then                  //if created
   begin
    FProgress := nil;
    AProgress.Free;                              //free dummy-object
   end;
 end;
end;










{Handles a message from a parser.
~param Information the information about the message
~param Parser      the parser generating the message }
procedure TParserManager.HandleMessage(const Information:
                                                      TParseMessageInformation;
                                       Parser: TFileParser);
begin
 if assigned(FOnMessage) then          //handler for message available?
  FOnMessage(Information, Self)          //handle it there
 else
  if IsDebuggerPresent then              //application is being debugged?
   asm int 3 end;                          //stop it (by a hard break point)
end;

{Handles a warning message from a parser.
~param Message the warning message
~param Parser  the parser generating the message or nil }
procedure TParserManager.AddWarning(const Message: String;
                                    Parser: TFileParser);
          //information to add the warning messsage
var       Information   :TParseMessageInformation;
begin
 //put/wrap the message in the structure for the information about it
 Information.MessageKind := pmkWarning;
 Information.MessageType := etParameters;
 Information.TheFile := nil;
 Information.ErrorPosition := UndefPosition;
 Information.EffectiveFile := nil;
 Information.EffectiveErrorPosition := UndefPosition;
 Information.Message := Message;

 HandleMessage(Information, Parser);           //handle the warning message
end;

{Handles a hint message.
~param Message the hint message }
procedure TParserManager.AddHint(const Message: String);
          //information to add the hint
var       Information   :TParseMessageInformation;
begin
 //put/wrap the message in the structure for the information about it
 Information.MessageKind := pmkHint;
 Information.MessageType := etNone;
 Information.TheFile := nil;
 Information.ErrorPosition := UndefPosition;
 Information.EffectiveFile := nil;
 Information.EffectiveErrorPosition := UndefPosition;
 Information.Message := Message;

 HandleMessage(Information, nil);           //handle the hint
end;




{Called, if an unknown unit is used by a file.
~param Sender   the sender of the event; the parser of the file that uses the
                unknown unit
~param UnitName the name of the unit
~result the parser of the unit if it could be parsed or nil }
function TParserManager.UnknownUnit(Sender: TFileParser;
                                    const UnitName: String): TPascalFile;
         //index of the file in the files to parse if used
var      Index         :Integer;
         Empty         :TStringList;               //an empty list
begin
 Result := nil;
 Index := LibFileNames.IndexOf(UnitName);          //search if it is a lib file
 if Index <> -1 then                               //is a lib file?
  begin
   Empty := TStringList.Create;
   try
     ParseFile(LibFilePaths[Index], False, Empty, Empty, Empty); //parse it
   finally
    Empty.Free;
   end;
   Result := FList[0];                             //get the newest parsed file
   assert(Result.FilePath = LibFilePaths[Index]);
  end;
end;


end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -