diff --git a/.gitattributes b/.gitattributes index 5707aeb2cf..11dcc8c3cb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -19372,6 +19372,7 @@ utils/fpdoc/fpdocclasstree.pp svneol=native#text/plain utils/fpdoc/fpdocproj.pas svneol=native#text/plain utils/fpdoc/fpdocstripper.lpi svneol=native#text/plain utils/fpdoc/fpdocstripper.pp svneol=native#text/plain +utils/fpdoc/fpdocstrs.pp svneol=native#text/plain utils/fpdoc/fpdocxmlopts.pas svneol=native#text/plain utils/fpdoc/fpmake.pp svneol=native#text/plain utils/fpdoc/images/minus.png -text svneol=unset#image/png diff --git a/utils/fpdoc/dglobals.pp b/utils/fpdoc/dglobals.pp index 2cfed6aed8..05e2c4f10b 100644 --- a/utils/fpdoc/dglobals.pp +++ b/utils/fpdoc/dglobals.pp @@ -33,203 +33,6 @@ Var LEOL : Integer; modir : string; -resourcestring - // Output strings - SDocPackageTitle = 'Reference for package ''%s'''; - SDocPackageMenuTitle = 'Package ''%s'''; - SDocPackageLinkTitle = 'Package'; - SDocPrograms = 'Programs'; - SDocUnits = 'Units'; - SDocUnitTitle = 'Reference for unit ''%s'''; - SDocUnitMenuTitle = 'Unit ''%s'''; - SDocInheritanceHierarchy = 'Inheritance Hierarchy'; - SDocInterfaceSection = 'Interface section'; - SDocImplementationSection = 'Implementation section'; - SDocUsedUnits = 'Used units'; - SDocUsedUnitsByUnitXY = 'Used units by unit ''%s'''; - SDocConstsTypesVars = 'Constants, types and variables'; - SDocResStrings = 'Resource strings'; - SDocTypes = 'Types'; - SDocType = 'Type'; - SDocConstants = 'Constants'; - SDocConstant = 'Constant'; - SDocClasses = 'Classes'; - SDocClass = 'Class'; - SDocProceduresAndFunctions = 'Procedures and functions'; - SDocProcedureOrFunction = 'Procedure/function'; - SDocVariables = 'Variables'; - SDocVariable = 'Variable'; - SDocIdentifierIndex = 'Index'; - SDocPackageClassHierarchy = 'Class hierarchy'; - SDocModuleIndex = 'Index of all identifiers in unit ''%s'''; - SDocPackageIndex = 'Index of all identifiers in package ''%s'''; - SDocUnitOverview = 'Overview of unit ''%s'''; - SDocOverview = 'Overview'; - SDocSearch = 'Search'; - SDocDeclaration = 'Declaration'; - SDocDescription = 'Description'; - SDocErrors = 'Errors'; - SDocVersion = 'Version info'; - SDocSeeAlso = 'See also'; - SDocExample = 'Example'; - SDocArguments = 'Arguments'; - SDocFunctionResult = 'Function result'; - SDocRemark = 'Remark: '; - SDocMethodOverview = 'Method overview'; - SDocPropertyOverview = 'Property overview'; - SDocEventOverview = 'Event overview'; - SDocInterfacesOverview = 'Interfaces overview'; - SDocInterface = 'Interfaces'; - SDocPage = 'Page'; - SDocMember = 'Member'; - SDocMembers = 'Members'; - SDocField = 'Field'; - SDocMethod = 'Method'; - SDocProperty = 'Property'; - SDocAccess = 'Access'; - SDocInheritance = 'Inheritance'; - SDocProperties = 'Properties'; - SDocMethods = 'Methods'; - SDocEvents = 'Events'; - SDocByName = 'by Name'; - SDocByInheritance = 'By inheritance'; - SDocValue = 'Value'; - SDocExplanation = 'Explanation'; - SDocProcedure = 'Procedure'; - SDocValuesForEnum = 'Enumeration values for type %s'; - SDocSourcePosition = 'Source position: %s line %d'; - SDocSynopsis = 'Synopsis'; - SDocVisibility = 'Visibility'; - SDocOpaque = 'Opaque type'; - SDocDateGenerated = 'Documentation generated on: %s'; - // The next line requires leading/trailing space due to XML comment layout: - SDocGeneratedByComment = ' Generated using FPDoc - (c) 2000-2012 FPC contributors and Sebastian Guenther, sg@freepascal.org '; - SDocNotes = 'Notes'; - SDocName = 'Name'; - SDocType_s = 'Type(s)'; - SDocTopic = 'Topic'; - SDocNoneAVailable = 'No members available'; - - // Topics - SDocRelatedTopics = 'Related topics'; - SDocUp = 'Up'; - SDocNext = 'Next'; - SDocPrevious = 'Previous'; - - // Various backend constants - SDocChapter = 'Chapter'; - SDocSection = 'Section'; - SDocSubSection = 'Subsection'; - SDocTable = 'Table'; - SDocListing = 'Listing'; - - // Man page usage - SManUsageManSection = 'Use ASection as the man page section'; - SManUsageNoUnitPrefix = 'Do not prefix man pages with unit name.'; - SManUsageWriterDescr = 'UNIX man page output.'; - SManUsagePackageDescription = 'Use descr as the description of man pages'; - - // HTML usage - SHTMLUsageFooter = 'Append xhtml (@filename reads from file) as footer to html page'; - SHTMLUsageNavigator = 'Append xhtml (@filename reads from file) in navigator bar'; - SHTMLUsageHeader = 'Append xhtml (@filename reads from file) as header to html page below navigation bar'; - SHTMLUsageFooterDate = 'Append footer with date. fmt is Optional format for FormatDateTime'; - SHTMLUsageCharset = 'Set the HTML character set'; - SHTMLHtmlSearch = 'Add search page with given name to the menu bar'; - SHTMLIndexColcount = 'Use N columns in the identifier index pages'; - SHTMLImageUrl = 'Prefix image URLs with url'; - SHTMLDisableMenuBrackets = 'Disable ''['' and '']'' characters around menu items at the top of the page. Useful for custom css'; - - // CHM usage - SCHMUsageTOC = 'Use [File] as the table of contents. Usually a .hhc file.'; - SCHMUsageIndex = 'Use [File] as the index. Usually a .hhk file.'; - SCHMUsageDefPage = 'Set the "Home" page relative to where it lives in the chm. i.e. "/index.html"'; - SCHMUsageOtrFiles= 'A txt file containing a list of files to be added relative to the working directory.'; - SCHMUsageCSSFile = 'Filename of a .css file to be included in the chm.'; - SCHMUsageAutoTOC = 'Automatically generate a Table of Contents. Ignores --toc-file'; - SCHMUsageAutoIDX = 'Automatically generate an Index. Ignores --index-file'; - SCHMUsageMakeSearch = 'Automatically generate a Search Index from filenames that match *.htm*'; - SCHMUsageChmTitle= 'Title of the chm. Defaults to the value from --package'; - - // MarkDown usage - SMDUsageFooter = 'Append markdown (@filename reads from file) as footer to every markdown page'; - SMDUsageHeader = 'Prepend markdown (@filename reads from file) as header to every markdown page'; - SMDIndexColcount = 'Use N columns in the identifier index pages'; - SMDImageUrl = 'Prefix image URLs with url'; - SMDTheme = 'Use name as theme name'; - SMDNavigation = 'Use scheme for navigation tree, here scheme is one of:'; - SMDNavSubtree = ' UnitSubTree : put all units in a sub tree of a Units node'; - SMDNavTree = ' UnitTree : put every units as a node on the same level as packages node'; - - SXMLUsageFlatStructure = 'Use a flat output structure of XML files and directories'; - SXMLUsageSource = 'Include source file and line info in generated XML'; - - // Linear usage - SLinearUsageDupLinkedDocsP1 = 'Duplicate linked element documentation in'; - SLinearUsageDupLinkedDocsP2 = 'descendant classes.'; - - STitle = 'FPDoc - Free Pascal Documentation Tool'; - SVersion = 'Version %s [%s]'; - SCopyright1 = '(c) 2000 - 2003 Areca Systems GmbH / Sebastian Guenther, sg@freepascal.org'; - SCopyright2 = '(c) 2005 - 2021 various FPC contributors'; - - SCmdLineHelp = 'Usage: %s [options]'; - SUsageOption008 = '--base-descr-dir=DIR prefix all description files with this directory'; - SUsageOption009 = '--base-input-dir=DIR prefix all input files with this directory'; - SUsageOption010 = '--content Create content file for package cross-references'; - SUsageOption020 = '--cputarget=value Set the target CPU for the scanner.'; - SUsageOption030 = '--descr=file use file as description file, e.g.: '; - SUsageOption035 = ' --descr=c:\WIP\myzipperdoc.xml'; - SUsageOption040 = ' This option is allowed more than once'; - SUsageOption050 = '--descr-dir=Dir Add All XML files in Dir to list of description files'; - SUsageOption060 = '--format=fmt Select output format.'; - SUsageOption070 = '--help Show this help.'; - SUsageOption080 = '--hide-protected Do not show protected methods in overview'; - SUsageOption090 = '--import=file Import content file for package cross-references'; - SUsageOption100 = '--input=cmd use cmd as input for the parser, e.g.:'; - SUsageOption110 = ' --input=C:\fpc\packages\paszlib\src\zipper.pp'; - SUsageOption120 = ' At least one input option is required.'; - SUsageOption130 = '--input-dir=Dir Add All *.pp and *.pas files in Dir to list of input files'; - SUsageOption140 = '--lang=lng Select output language.'; - SUsageOption145 = '--macro=name=value Define a macro to preprocess the project file with.'; - SUsageOption150 = '--ostarget=value Set the target OS for the scanner.'; - SUsageOption160 = '--output=name use name as the output name.'; - SUsageOption170 = ' Each backend interprets this as needed.'; - SUsageOption180 = '--package=name Set the package name for which to create output,'; - SUsageOption190 = ' e.g. --package=fcl'; - SUsageOption200 = '--project=file Use file as project file'; - SUsageOption210 = '--show-private Show private methods.'; - SUsageOption215 = '--stop-on-parser-error'; - SUsageOption215A = ' Stop when a parser error occurs. Default is to ignore parser errors.'; - SUsageOption220 = '--warn-no-node Warn if no documentation node was found.'; - SUsageOption230 = '--mo-dir=dir Set directory where language files reside to dir'; - SUsageOption240 = '--parse-impl (Experimental) try to parse implementation too'; - SUsageOption250 = '--dont-trim Do not trim XML contents. Useful for preserving'; - SUsageOption260 = ' formatting inside e.g
tags'; - SUsageOption270 = '--write-project=file'; - SUsageOption280 = ' Do not write documentation, create project file instead'; - SUsageOption290 = '--verbose Write more information on the screen'; - SUsageOption300 = '--dry-run Only parse sources and XML, do not create output'; - SUsageOption310 = '--write-project=file'; - SUsageOption320 = ' Write all command-line options to a project file'; - SUsageSubNames = 'Use the file subnames instead the indexes as postfixes'; - - SUsageFormats = 'The following output formats are supported by this fpdoc:'; - SUsageBackendHelp = 'Specify an output format, combined with --help to get more help for this backend.'; - SUsageFormatSpecific = 'Output format "%s" supports the following options:'; - SCmdLineErrInvalidMacro = 'Macro needs to be in the form name=value'; - - SCmdLineInvalidOption = 'Ignoring unknown option "%s"'; - SCmdLineInvalidFormat = 'Invalid format "%s" specified'; - SCmdLineOutputOptionMissing = 'Need an output filename, please specify one with --output='; - SWritingPages = 'Writing %d pages...'; - SNeedPackageName = 'No package name specified. Please specify one using the --package option.'; - SAvailablePackages = 'Available packages: '; - SDone = 'Done.'; - SErrCouldNotCreateOutputDir = 'Could not create output directory "%s"'; - SErrCouldNotCreateFile = 'Could not create file "%s": %s'; - SSeeURL = '(See %s)'; // For linear text writers. - SParsingUsedUnit = 'Parsing used unit "%s" with commandLine "%s"'; Const SVisibility: array[TPasMemberVisibility] of string = @@ -335,7 +138,7 @@ type // The main FPDoc engine - TFPDocLogLevel = (dleWarnNoNode); + TFPDocLogLevel = (dleWarnNoNode, dleWarnUsedFile, dleDocumentationEmpty, dleXCT); TFPDocLogLevels = set of TFPDocLogLevel; TOnParseUnitEvent = Procedure (Sender : TObject; Const AUnitName : String; Out AInputFile,OSTarget,CPUTarget : String) of Object; @@ -364,7 +167,6 @@ type HasContentFile: Boolean; HidePrivate: Boolean; // Hide private class members in output? HideProtected: Boolean; // Hide protected class members in output? - WarnNoNode : Boolean; // Warn if no description node found for element. constructor Create; destructor Destroy; override; @@ -378,7 +180,7 @@ type AParent: TPasElement; AVisibility: TPasMemberVisibility; const ASourceFilename: String; ASourceLinenumber: Integer): TPasElement; override; - function FindInModule(const AName: String ; AModule: TPasModule): TPasElement; + function FindElement(const AName: String ; AModule: TPasModule): TPasElement; overload; function FindElement(const AName: String): TPasElement; override; function FindModule(const AName: String): TPasModule; override; Function HintsToStr(Hints : TPasMemberHints) : String; @@ -411,7 +213,9 @@ type procedure TranslateDocStrings(const Lang: String); +{$IFDEF EXCEPTION_STACK} function DumpExceptionCallStack(E: Exception):String; +{$ENDIF} Function IsLinkNode(Node : TDomNode) : Boolean; Function IsExampleNode(Example : TDomNode) : Boolean; @@ -422,7 +226,7 @@ Function IsLinkAbsolute(ALink: String): boolean; implementation -uses Gettext, XMLRead; +uses Gettext, XMLRead, fpdocstrs; const AbsoluteLinkPrefixes : array[0..2] of string = ('/', 'http://', 'ms-its:'); @@ -670,8 +474,11 @@ destructor TFPDocEngine.Destroy; var i: Integer; begin + if FPackages.Count > 0 then for i := 0 to FPackages.Count - 1 do - TPasPackage(FPackages[i]).Release{$IFDEF CheckPasTreeRefCount}('TFPDocEngine.Destroy'){$ENDIF}; + TPasPackage(FPackages[i]).Release{$IFDEF CheckPasTreeRefCount}('TFPDocEngine.Destroy'){$ENDIF} + else + FreeAndNil(FPackages); FreeAndNil(FRootDocNode); FreeAndNil(FRootLinkNode); FreeAndNil(DescrDocNames); @@ -910,7 +717,7 @@ var end; end else - if cls<>result then + if (dleXCT in FDocLogLevels) and (cls<>result) then DoLog('Warning : ancestor class %s of class %s could not be resolved',[clname,cls.name]); end; @@ -970,7 +777,7 @@ var if alname<>'' then // the class//interface we refered to is an alias begin // writeln('Found alias pair ',clname,' = ',alname); - if not assigned(CreateAliasType(alname,clname,cls,cls2)) then + if (dleXCT in FDocLogLevels) and not assigned(CreateAliasType(alname,clname,cls,cls2)) then DoLog('Warning: creating alias %s for %s failed!',[alname,clname]); end else @@ -1217,7 +1024,7 @@ begin Result.SourceLinenumber := ASourceLinenumber; end; -function TFPDocEngine.FindInModule ( const AName: String; AModule: TPasModule +function TFPDocEngine.FindElement ( const AName: String; AModule: TPasModule ) : TPasElement; var l: TFPList; @@ -1244,14 +1051,14 @@ var i: Integer; Module: TPasElement; begin - Result := FindInModule( AName, CurModule ); + Result := FindElement( AName, CurModule ); if not Assigned(Result) and assigned (CurModule.InterfaceSection) then for i := CurModule.InterfaceSection.UsesList.Count - 1 downto 0 do begin Module := TPasElement(CurModule.InterfaceSection.UsesList[i]); if Module.ClassType.InheritsFrom(TPasModule) then begin - Result := FindInModule(AName, TPasModule(Module)); + Result := FindElement(AName, TPasModule(Module)); if Assigned(Result) then exit; end; @@ -1264,6 +1071,7 @@ function TFPDocEngine.FindModule(const AName: String): TPasModule; var i: Integer; begin + if not Assigned(APackage) then Exit; for i := 0 to APackage.Modules.Count - 1 do begin Result := TPasModule(APackage.Modules[i]); @@ -1279,7 +1087,7 @@ var begin Result := FindInPackage(Package); - if not Assigned(Result) then + if not Assigned(Result) and (FPackages.Count > 0) then for i := FPackages.Count - 1 downto 0 do begin if TPasPackage(FPackages[i]) = Package then @@ -1319,11 +1127,12 @@ Var M : TPasModule; begin - DoLog(SParsingUsedUnit,[AName,AInputLine]); + if dleWarnUsedFile in FDocLogLevels then + DoLog(SParsingUsedUnit,[AName,AInputLine]); M:=CurModule; CurModule:=Nil; try - ParseSource(Self,AInputLine,AOSTarget,ACPUTarget,[poUseStreams,poSkipDefaultDefs]); + ParseSource(Self,AInputLine,AOSTarget,ACPUTarget,[poUseStreams]); //[poSkipDefaultDefs]; Result:=CurModule; finally CurModule:=M; @@ -1590,7 +1399,7 @@ begin if aElement.CustomData=Nil then aElement.CustomData:=Result; end - else if WarnNoNode and + else if (dleWarnNoNode in FDocLogLevels) and (Length(AElement.PathName)>0) and (AElement.PathName[1]='#') then DoLog(Format('No documentation node found for identifier : %s',[AElement.PathName])); @@ -1791,6 +1600,7 @@ begin end; end; +{$IFDEF EXCEPTION_STACK} function DumpExceptionCallStack(E: Exception):String; var I: Integer; @@ -1807,6 +1617,7 @@ begin for I := 0 to ExceptFrameCount - 1 do Result := Result + LineEnding + BackTraceStrFunc(Frames[I]); end; +{$ENDIF} initialization LEOL:=Length(LineEnding); diff --git a/utils/fpdoc/dw_basehtml.pp b/utils/fpdoc/dw_basehtml.pp index c0a82aae25..38e8340682 100644 --- a/utils/fpdoc/dw_basehtml.pp +++ b/utils/fpdoc/dw_basehtml.pp @@ -158,7 +158,7 @@ Function FixHTMLpath(S : String) : STring; implementation -uses xmlread, sysutils, sh_pas; +uses fpdocstrs, xmlread, sysutils, sh_pas; Function FixHTMLpath(S : String) : STring; diff --git a/utils/fpdoc/dw_basemd.pp b/utils/fpdoc/dw_basemd.pp index 6ab3e04c39..cf55c6c84e 100644 --- a/utils/fpdoc/dw_basemd.pp +++ b/utils/fpdoc/dw_basemd.pp @@ -184,15 +184,8 @@ Type implementation -resourcestring - SErrCannotChangeIndentSizeWhenIndented = 'Cannot change indent size while text is indented.'; - SErrIndentMismatch = 'Indent mismatch: trying to undent when current indent too small'; - SErrNotInList = 'Not in list'; - SErrPopListStack = 'Pop list stack list type mismatch'; - SErrMinListStack = 'Min list stack reached'; - SErrMaxListStack = 'Max list stack reached'; - SErrMinIndentStack = 'Min indent stack reached'; - SErrMaxIndentStack = 'Max indent stack reached'; +uses fpdocstrs; + procedure TBaseMarkdownWriter.SetIndentSize(AValue: Byte); begin diff --git a/utils/fpdoc/dw_chm.pp b/utils/fpdoc/dw_chm.pp index 30195d5b07..7c0bc30932 100644 --- a/utils/fpdoc/dw_chm.pp +++ b/utils/fpdoc/dw_chm.pp @@ -63,7 +63,7 @@ type implementation -uses SysUtils, HTMWrite, dw_basehtml; +uses fpdocstrs, SysUtils, HTMWrite, dw_basehtml; { TCHmFileNameAllocator } diff --git a/utils/fpdoc/dw_html.pp b/utils/fpdoc/dw_html.pp index 298114f9f7..ea8be55842 100644 --- a/utils/fpdoc/dw_html.pp +++ b/utils/fpdoc/dw_html.pp @@ -129,7 +129,7 @@ type implementation -uses SysUtils, HTMWrite, fpdocclasstree; +uses fpdocstrs, SysUtils, HTMWrite, fpdocclasstree; {$i css.inc} {$i plusimage.inc} diff --git a/utils/fpdoc/dw_ipflin.pas b/utils/fpdoc/dw_ipflin.pas index 8bf9e117cc..b8bdf9c981 100644 --- a/utils/fpdoc/dw_ipflin.pas +++ b/utils/fpdoc/dw_ipflin.pas @@ -151,7 +151,7 @@ type implementation uses - SysUtils, dwriter; + fpdocstrs, SysUtils, dwriter; { TFPDocWriter overrides } diff --git a/utils/fpdoc/dw_latex.pp b/utils/fpdoc/dw_latex.pp index ce04c3a082..d49227e280 100644 --- a/utils/fpdoc/dw_latex.pp +++ b/utils/fpdoc/dw_latex.pp @@ -30,7 +30,7 @@ Procedure CreateLaTeXDocForPackage(APackage: TPasPackage; AEngine: TFPDocEngine) implementation -uses SysUtils, Classes, dwLinear, dwriter; +uses fpdocstrs, SysUtils, Classes, dwLinear, dwriter; Type diff --git a/utils/fpdoc/dw_linrtf.pp b/utils/fpdoc/dw_linrtf.pp index dd25f5a7f0..3ab507ccca 100644 --- a/utils/fpdoc/dw_linrtf.pp +++ b/utils/fpdoc/dw_linrtf.pp @@ -28,7 +28,7 @@ Procedure CreateRTFDocForPackage(APackage: TPasPackage; AEngine: TFPDocEngine); implementation -uses SysUtils, Classes, dwLinear, dwriter; +uses fpdocstrs, SysUtils, Classes, dwLinear, dwriter; const Indent = 300; diff --git a/utils/fpdoc/dw_man.pp b/utils/fpdoc/dw_man.pp index 1874bdf1ef..30122d4906 100644 --- a/utils/fpdoc/dw_man.pp +++ b/utils/fpdoc/dw_man.pp @@ -185,6 +185,8 @@ Type implementation +uses fpdocstrs; + { TManWriter } constructor TManWriter.Create(APackage: TPasPackage; AEngine: TFPDocEngine); diff --git a/utils/fpdoc/dw_markdown.pp b/utils/fpdoc/dw_markdown.pp index e9a74d90b6..aafa82808a 100644 --- a/utils/fpdoc/dw_markdown.pp +++ b/utils/fpdoc/dw_markdown.pp @@ -142,7 +142,7 @@ type implementation -uses SysUtils, fpdocclasstree; +uses fpdocstrs, SysUtils, fpdocclasstree; Function FixHTMLpath(S : String) : STring; diff --git a/utils/fpdoc/dw_txt.pp b/utils/fpdoc/dw_txt.pp index 9557b196d2..2c057b966b 100644 --- a/utils/fpdoc/dw_txt.pp +++ b/utils/fpdoc/dw_txt.pp @@ -28,7 +28,7 @@ Procedure CreateTxtDocForPackage(APackage: TPasPackage; AEngine: TFPDocEngine); implementation -uses SysUtils, Classes, dwLinear; +uses fpdocstrs, SysUtils, Classes, dwLinear; Const MaxListLevel = 10; diff --git a/utils/fpdoc/dw_xml.pp b/utils/fpdoc/dw_xml.pp index 1f7bfbce51..2a548ae637 100644 --- a/utils/fpdoc/dw_xml.pp +++ b/utils/fpdoc/dw_xml.pp @@ -61,6 +61,8 @@ Type implementation +uses fpdocstrs; + const DefaultVisibility = [visDefault, visPublic, visPublished, visProtected]; diff --git a/utils/fpdoc/dwlinear.pp b/utils/fpdoc/dwlinear.pp index 5b36cec805..c024067e05 100644 --- a/utils/fpdoc/dwlinear.pp +++ b/utils/fpdoc/dwlinear.pp @@ -121,6 +121,8 @@ Type implementation +uses fpdocstrs; + const cDupLinkedDocParam = '--duplinkeddoc'; diff --git a/utils/fpdoc/dwriter.pp b/utils/fpdoc/dwriter.pp index eb0bf599cf..2b25dfbad6 100644 --- a/utils/fpdoc/dwriter.pp +++ b/utils/fpdoc/dwriter.pp @@ -27,31 +27,6 @@ interface uses Classes, DOM, contnrs, dGlobals, PasTree, SysUtils, fpdocclasstree; -resourcestring - SErrFileWriting = 'An error occurred during writing of file "%s": %s'; - - SErrInvalidShortDescr = 'Invalid short description'; - SErrInvalidDescr = 'Invalid description (illegal XML element: "%s")'; - SErrInvalidParaContent = 'Invalid paragraph content'; - SErrInvalidElementInList = 'Invalid element in list - only "li" allowed'; - SErrInvalidListContent = 'Invalid list content'; - SErrInvalidRemarkContent = 'Invalid content (illegal XML element: "%s")'; - SErrListIsEmpty = 'List is empty - need at least one "li" element'; - SErrInvalidDefinitionTermContent = 'Invalid content in definition term'; - SErrDefinitionEntryMissing = 'Definition entry after definition term is missing'; - SErrInvalidBorderValue = 'Invalid "border" value for %s'; - SErrInvalidTableContent = 'Invalid table content'; - SErrTableRowEmpty = 'Table row is empty (no "td" elements found)'; - SErrInvalidContentBeforeSectionTitle = 'Invalid content before section title'; - SErrSectionTitleExpected = 'Section title ("title" element) expected'; - - SErrDescrTagUnknown = 'Warning: Unknown tag "%s" in description'; - SErrUnknownEntityReference = 'Warning: Unknown entity reference "&%s;" found'; - SErrUnknownLinkID = 'Warning: Target ID of in unit "%s", element "%s", is unknown: "%s"'; - SErrUnknownPrintShortID = 'Warning: Target ID of is unknown: "%s"'; - SErrUnknownLink = 'Could not resolve link to "%s"'; - SErralreadyRegistered = 'Class for output format "%s" already registered'; - SErrUnknownWriterClass = 'Unknown output format "%s"'; type // Phony element for pas pages. @@ -339,6 +314,8 @@ function SortPasElements(Item1, Item2: Pointer): Integer; implementation +uses fpdocstrs; + function SortPasElements(Item1, Item2: Pointer): Integer; begin Result:=CompareText(TPasElement(Item1).Name,TPasElement(Item2).Name) @@ -1065,8 +1042,8 @@ begin FPackage := APackage; FTopics:=Tlist.Create; FImgExt:='.png'; - TreeClass:= TClassTreeBuilder.Create(FEngine, FPackage, okClass); - TreeInterface:= TClassTreeBuilder.Create(FEngine, FPackage, okInterface); + TreeClass:= TClassTreeBuilder.Create(FEngine, FPackage, okWithFields); + TreeInterface:= TClassTreeBuilder.Create(FEngine, FPackage, [okInterface]); CreateClassTree; end; @@ -1722,8 +1699,8 @@ begin if Node.NodeType <> ELEMENT_NODE then begin if Node.NodeType = TEXT_NODE then - Result := IsWhitespaceNode(TDOMText(Node)) - else + Result := IsWhitespaceNode(TDOMText(Node)) + else Result := Node.NodeType = COMMENT_NODE; exit; end; diff --git a/utils/fpdoc/fpclasschart.pp b/utils/fpdoc/fpclasschart.pp index 1ce706f8bb..4172a5d81b 100644 --- a/utils/fpdoc/fpclasschart.pp +++ b/utils/fpdoc/fpclasschart.pp @@ -42,7 +42,7 @@ type FTree : TClassTreeBuilder; FObjects : TStringList; public - Constructor Create(AClassTree : TXMLDocument; AObjectKind : TPasObjKind); + Constructor Create(AClassTree : TXMLDocument; AObjectKindSet : TPasObjKindSet); Destructor Destroy; override; function CreateElement(AClass: TPTreeElement; const AName: String; AParent: TPasElement; AVisibility :TPasMemberVisibility; @@ -442,14 +442,12 @@ begin end; end; -Constructor TClassTreeEngine.Create(AClassTree : TXMLDocument; AObjectKind : TPasObjKind); - - +Constructor TClassTreeEngine.Create(AClassTree : TXMLDocument; AObjectKindSet : TPasObjKindSet); begin - FPackage:=TPasPackage.Create('dummy',Nil); - FTree:=TClassTreeBuilder.Create(Self,FPackage,AObjectKind); - FObjects:=TStringList.Create; Inherited Create; + FPackage:=TPasPackage.Create('dummy',Nil); + FTree:=TClassTreeBuilder.Create(Self,FPackage,AObjectKindSet); + FObjects:=TStringList.Create; end; destructor TClassTreeEngine.Destroy; @@ -538,11 +536,13 @@ Var end; begin + Result:= 0; aSrc:=TXMLDocument.Create(); try aSrc.AppendChild(aSrc.CreateElement('TObject')); AppendChildClasses(aSrc.DocumentElement,aRootNode); MergeTrees(Dest,aSrc); + Inc(Result); finally aSrc.Free; end; @@ -578,7 +578,7 @@ begin end; For I:=0 to InputFiles.Count-1 do begin - Engine := TClassTreeEngine.Create(XML,AObjectKind); + Engine := TClassTreeEngine.Create(XML,[AObjectKind]); Try ParseSource(Engine,InputFiles[I],OSTarget,CPUTarget); Engine.Ftree.BuildTree(Engine.FObjects); diff --git a/utils/fpdoc/fpdoc.lpi b/utils/fpdoc/fpdoc.lpi index b9c99b0c3f..d4126e5fdf 100644 --- a/utils/fpdoc/fpdoc.lpi +++ b/utils/fpdoc/fpdoc.lpi @@ -8,6 +8,7 @@ + @@ -46,7 +47,7 @@ - + @@ -134,6 +135,10 @@ + + + + @@ -143,13 +148,22 @@ + + + + + + ++ diff --git a/utils/fpdoc/fpdoc.pp b/utils/fpdoc/fpdoc.pp index 5e789409e1..3892bb8e3b 100644 --- a/utils/fpdoc/fpdoc.pp +++ b/utils/fpdoc/fpdoc.pp @@ -37,7 +37,7 @@ uses dw_man, // Man page writer dw_linrtf, // linear RTF writer dw_txt, // TXT writer - fpdocproj, mkfpdoc, dw_basemd, dw_basehtml; + fpdocproj, mkfpdoc, dw_basemd, dw_basehtml, fpdocstrs; Type @@ -104,6 +104,9 @@ begin Writeln(SUsageOption215); Writeln(SUsageOption215A); Writeln(SUsageOption220); + Writeln(SUsageOption221); + Writeln(SUsageOption222); + Writeln(SUsageOption223); Writeln(SUsageOption230); Writeln(SUsageOption240); Writeln(SUsageOption250); @@ -151,7 +154,9 @@ end; procedure TFPDocApplication.ExceptProc(Sender: TObject; E: Exception); begin +{$IFDEF EXCEPTION_STACK} OutputLog(Sender, DumpExceptionCallStack(E)); +{$ENDIF} end; destructor TFPDocApplication.Destroy; @@ -307,6 +312,12 @@ begin FCreator.Options.HideProtected := True else if s = '--warn-no-node' then FCreator.Options.WarnNoNode := True + else if s = '--warn-documentation-empty' then + FCreator.Options.WarnDocumentationEmpty := True + else if s = '--warn-used-file' then + FCreator.Options.WarnUsedFile := True + else if s = '--warn-XCT' then + FCreator.Options.WarnXCT := True else if s = '--show-private' then FCreator.Options.ShowPrivate := True else if s = '--stop-on-parser-error' then diff --git a/utils/fpdoc/fpdocclasstree.pp b/utils/fpdoc/fpdocclasstree.pp index 3ea8c84d65..fdb2618996 100644 --- a/utils/fpdoc/fpdocclasstree.pp +++ b/utils/fpdoc/fpdocclasstree.pp @@ -2,6 +2,7 @@ unit fpdocclasstree; {$mode objfpc}{$H+} + interface uses @@ -9,6 +10,8 @@ uses Type + TPasObjKindSet = set of TPasObjKind; + { TPasElementNode } TPasElementNode = Class @@ -35,7 +38,7 @@ Type Private FEngine:TFPDocEngine; FElementList : TFPObjectHashTable; - FObjectKind : TPasObjKind; + FObjectKind : TPasObjKindSet; FPackage: TPasPackage; FParentObject : TPasClassType; FRootNode : TPasElementNode; @@ -45,7 +48,7 @@ Type function AddToList(aElement: TPasClassType): TPasElementNode; Public Constructor Create(AEngine:TFPDocEngine; APackage : TPasPackage; - AObjectKind : TPasObjKind = okClass); + AObjectKind : TPasObjKindSet = okWithFields); Destructor Destroy; override; Function BuildTree(AObjects : TStringList) : Integer; Procedure SaveToXml(AFileName: String); @@ -56,6 +59,9 @@ Type implementation +uses + fpdocstrs, pasresolver; + { TPasElementNode } function SortOnElementName(Item1, Item2: Pointer): Integer; @@ -104,33 +110,36 @@ begin end; constructor TClassTreeBuilder.Create(AEngine:TFPDocEngine; APackage : TPasPackage; - AObjectKind: TPasObjKind); + AObjectKind: TPasObjKindSet); begin FEngine:= AEngine; FPackage:= APAckage; FObjectKind:=AObjectKind; - Case FObjectkind of - okInterface : + if (okInterface in FObjectkind) then begin FRootObjectPathName:='#rtl.System.IInterface'; FRootObjectName:= 'IInterface'; - end; - okObject, okClass : + end + else if (FObjectkind * okWithFields) <> [] then begin FRootObjectPathName:='#rtl.System.TObject'; FRootObjectName:= 'TObject'; end - else + else // TODO: I don`t know need it ? Without that the code may be simplified. begin FRootObjectPathName:='#rtl.System.TObject'; FRootObjectName:= 'TObject'; end; - end; FParentObject:=TPasClassType.Create(FRootObjectName,FEngine.FindModule('System')); if not Assigned(FParentObject) then FParentObject:=TPasClassType.Create(FRootObjectName,FPackage); - FParentObject.ObjKind:=FObjectKind; + if (okInterface in FObjectkind) then + FParentObject.ObjKind:=okInterface + else if (FObjectkind * okWithFields) <> [] then + FParentObject.ObjKind:=okClass + else + FParentObject.ObjKind:=okClass; FRootNode:=TPasElementNode.Create(FParentObject); FRootNode.FParentNode := nil; FElementList:=TFPObjectHashTable.Create(False); @@ -154,7 +163,8 @@ Var begin Result:= nil; - if (aElement.ObjKind <> FObjectKind) then exit; + if not (aElement.ObjKind in FObjectKind) then exit; + aParentNode:= nil; if aElement=Nil then aName:=FRootObjectName @@ -227,10 +237,11 @@ procedure TClassTreeBuilder.SaveToXml ( AFileName: String ); for CounterVar := 0 to ParentPasEl.ChildCount-1 do begin PasElNode:= ParentPasEl.Children[CounterVar]; - xmlEl:= AXmlDoc.CreateElement(UnicodeString(PasElNode.Element.Name)); + xmlEl:= AXmlDoc.CreateElement(UTF8Decode(PasElNode.Element.Name)); M:= PasElNode.Element.GetModule; - xmlEl['unit'] := UnicodeString(M.Name); - xmlEl['package'] := UnicodeString(M.PackageName); + xmlEl['unit'] := UTF8Decode(M.Name); + xmlEl['package'] := UTF8Decode(M.PackageName); + xmlEl['type'] := UTF8Decode(GetElementTypeName(PasElNode.Element)); ParentxmlEl.AppendChild(xmlEl); AddPasElChildsToXml(xmlEl, PasElNode); end; @@ -244,17 +255,24 @@ begin XmlDoc:= TXMLDocument.Create; XmlDoc.AppendChild(XmlDoc.CreateComment(UTF8Decode(SDocGeneratedByComment))); try - XmlRootEl:= XmlDoc.CreateElement(UnicodeString(FRootNode.Element.Name)); + XmlRootEl:= XmlDoc.CreateElement(UTF8Decode(FRootNode.Element.Name)); M:= FRootNode.Element.GetModule; if Assigned(M) then begin - XmlRootEl['unit'] := UnicodeString(M.Name); - XmlRootEl['package'] := UnicodeString(M.PackageName); + XmlRootEl['unit'] := UTF8Decode(M.Name); + XmlRootEl['package'] := UTF8Decode(M.PackageName); + XmlRootEl['type'] := UTF8Decode(GetElementTypeName(FRootNode.Element)); end else begin XmlRootEl['unit'] := 'system'; XmlRootEl['package'] := 'rtl'; + if (okWithFields * FObjectKind) <> [] then + XmlRootEl['type'] := 'class' + else if (okInterface in FObjectKind) then + XmlRootEl['type'] := 'interface' + else + XmlRootEl['type'] := 'class'; end; XmlDoc.AppendChild(XmlRootEl); AddPasElChildsToXml(XmlRootEl, FRootNode); diff --git a/utils/fpdoc/fpdocproj.pas b/utils/fpdoc/fpdocproj.pas index 7ea90f3401..040ff81007 100644 --- a/utils/fpdoc/fpdocproj.pas +++ b/utils/fpdoc/fpdocproj.pas @@ -60,8 +60,11 @@ Type FMoDir: String; FOSTarget: String; FSOPE: Boolean; + FWarnDocumentationEmpty: Boolean; FWarnNoNode: Boolean; FDontTrim : Boolean; + FWarnUsedFile: Boolean; + FWarnXCT: Boolean; procedure SetBackendOptions(const AValue: TStrings); Public Constructor Create; @@ -77,6 +80,9 @@ Type Property StopOnParseError : Boolean Read FSOPE Write FSOPE; Property HideProtected : Boolean Read FHideProtected Write FHideProtected; Property WarnNoNode : Boolean Read FWarnNoNode Write FWarnNoNode; + Property WarnUsedFile : Boolean Read FWarnUsedFile Write FWarnUsedFile; + Property WarnDocumentationEmpty : Boolean Read FWarnDocumentationEmpty Write FWarnDocumentationEmpty; + Property WarnXCT : Boolean Read FWarnXCT Write FWarnXCT; Property ShowPrivate : Boolean Read FHidePrivate Write FHidePrivate; Property InterfaceOnly : Boolean Read FIO Write FIO; Property MoDir : String Read FMoDir Write FMODir; @@ -189,6 +195,9 @@ begin FSOPE:=O.StopOnParseError; HideProtected:=O.HideProtected; WarnNoNode:=O.WarnNoNode; + WarnUsedFile:=O.WarnUsedFile; + WarnDocumentationEmpty:=O.WarnDocumentationEmpty; + WarnXCT:=O.WarnXCT; ShowPrivate:=O.ShowPrivate; InterfaceOnly:=O.InterfaceOnly; MoDir:=O.MoDir; diff --git a/utils/fpdoc/fpdocstrs.pp b/utils/fpdoc/fpdocstrs.pp new file mode 100644 index 0000000000..e61871e393 --- /dev/null +++ b/utils/fpdoc/fpdocstrs.pp @@ -0,0 +1,253 @@ +unit fpdocstrs; + +{$mode objfpc}{$H+} + +interface + +resourcestring + // Output strings + SDocPackageTitle = 'Reference for package ''%s'''; + SDocPackageMenuTitle = 'Package ''%s'''; + SDocPackageLinkTitle = 'Package'; + SDocPrograms = 'Programs'; + SDocUnits = 'Units'; + SDocUnitTitle = 'Reference for unit ''%s'''; + SDocUnitMenuTitle = 'Unit ''%s'''; + SDocInheritanceHierarchy = 'Inheritance Hierarchy'; + SDocInterfaceSection = 'Interface section'; + SDocImplementationSection = 'Implementation section'; + SDocUsedUnits = 'Used units'; + SDocUsedUnitsByUnitXY = 'Used units by unit ''%s'''; + SDocConstsTypesVars = 'Constants, types and variables'; + SDocResStrings = 'Resource strings'; + SDocTypes = 'Types'; + SDocType = 'Type'; + SDocConstants = 'Constants'; + SDocConstant = 'Constant'; + SDocClasses = 'Classes'; + SDocClass = 'Class'; + SDocProceduresAndFunctions = 'Procedures and functions'; + SDocProcedureOrFunction = 'Procedure/function'; + SDocVariables = 'Variables'; + SDocVariable = 'Variable'; + SDocIdentifierIndex = 'Index'; + SDocPackageClassHierarchy = 'Class hierarchy'; + SDocModuleIndex = 'Index of all identifiers in unit ''%s'''; + SDocPackageIndex = 'Index of all identifiers in package ''%s'''; + SDocUnitOverview = 'Overview of unit ''%s'''; + SDocOverview = 'Overview'; + SDocSearch = 'Search'; + SDocDeclaration = 'Declaration'; + SDocDescription = 'Description'; + SDocErrors = 'Errors'; + SDocVersion = 'Version info'; + SDocSeeAlso = 'See also'; + SDocExample = 'Example'; + SDocArguments = 'Arguments'; + SDocFunctionResult = 'Function result'; + SDocRemark = 'Remark: '; + SDocMethodOverview = 'Method overview'; + SDocPropertyOverview = 'Property overview'; + SDocEventOverview = 'Event overview'; + SDocInterfacesOverview = 'Interfaces overview'; + SDocInterface = 'Interfaces'; + SDocPage = 'Page'; + SDocMember = 'Member'; + SDocMembers = 'Members'; + SDocField = 'Field'; + SDocMethod = 'Method'; + SDocProperty = 'Property'; + SDocAccess = 'Access'; + SDocInheritance = 'Inheritance'; + SDocProperties = 'Properties'; + SDocMethods = 'Methods'; + SDocEvents = 'Events'; + SDocByName = 'by Name'; + SDocByInheritance = 'By inheritance'; + SDocValue = 'Value'; + SDocExplanation = 'Explanation'; + SDocProcedure = 'Procedure'; + SDocValuesForEnum = 'Enumeration values for type %s'; + SDocSourcePosition = 'Source position: %s line %d'; + SDocSynopsis = 'Synopsis'; + SDocVisibility = 'Visibility'; + SDocOpaque = 'Opaque type'; + SDocDateGenerated = 'Documentation generated on: %s'; + // The next line requires leading/trailing space due to XML comment layout: + SDocGeneratedByComment = ' Generated using FPDoc - (c) 2000-2021 FPC contributors and Sebastian Guenther, sg@freepascal.org '; + SDocNotes = 'Notes'; + SDocName = 'Name'; + SDocType_s = 'Type(s)'; + SDocTopic = 'Topic'; + SDocNoneAVailable = 'No members available'; + + // Topics + SDocRelatedTopics = 'Related topics'; + SDocUp = 'Up'; + SDocNext = 'Next'; + SDocPrevious = 'Previous'; + + // Various backend constants + SDocChapter = 'Chapter'; + SDocSection = 'Section'; + SDocSubSection = 'Subsection'; + SDocTable = 'Table'; + SDocListing = 'Listing'; + + // Man page usage + SManUsageManSection = 'Use ASection as the man page section'; + SManUsageNoUnitPrefix = 'Do not prefix man pages with unit name.'; + SManUsageWriterDescr = 'UNIX man page output.'; + SManUsagePackageDescription = 'Use descr as the description of man pages'; + + // HTML usage + SHTMLUsageFooter = 'Append xhtml (@filename reads from file) as footer to html page'; + SHTMLUsageNavigator = 'Append xhtml (@filename reads from file) in navigator bar'; + SHTMLUsageHeader = 'Append xhtml (@filename reads from file) as header to html page below navigation bar'; + SHTMLUsageFooterDate = 'Append footer with date. fmt is Optional format for FormatDateTime'; + SHTMLUsageCharset = 'Set the HTML character set'; + SHTMLHtmlSearch = 'Add search page with given name to the menu bar'; + SHTMLIndexColcount = 'Use N columns in the identifier index pages'; + SHTMLImageUrl = 'Prefix image URLs with url'; + SHTMLDisableMenuBrackets = 'Disable ''['' and '']'' characters around menu items at the top of the page. Useful for custom css'; + + // CHM usage + SCHMUsageTOC = 'Use [File] as the table of contents. Usually a .hhc file.'; + SCHMUsageIndex = 'Use [File] as the index. Usually a .hhk file.'; + SCHMUsageDefPage = 'Set the "Home" page relative to where it lives in the chm. i.e. "/index.html"'; + SCHMUsageOtrFiles= 'A txt file containing a list of files to be added relative to the working directory.'; + SCHMUsageCSSFile = 'Filename of a .css file to be included in the chm.'; + SCHMUsageAutoTOC = 'Automatically generate a Table of Contents. Ignores --toc-file'; + SCHMUsageAutoIDX = 'Automatically generate an Index. Ignores --index-file'; + SCHMUsageMakeSearch = 'Automatically generate a Search Index from filenames that match *.htm*'; + SCHMUsageChmTitle= 'Title of the chm. Defaults to the value from --package'; + + // MarkDown usage + SMDUsageFooter = 'Append markdown (@filename reads from file) as footer to every markdown page'; + SMDUsageHeader = 'Prepend markdown (@filename reads from file) as header to every markdown page'; + SMDIndexColcount = 'Use N columns in the identifier index pages'; + SMDImageUrl = 'Prefix image URLs with url'; + SMDTheme = 'Use name as theme name'; + SMDNavigation = 'Use scheme for navigation tree, here scheme is one of:'; + SMDNavSubtree = ' UnitSubTree : put all units in a sub tree of a Units node'; + SMDNavTree = ' UnitTree : put every units as a node on the same level as packages node'; + + SXMLUsageFlatStructure = 'Use a flat output structure of XML files and directories'; + SXMLUsageSource = 'Include source file and line info in generated XML'; + + // Linear usage + SLinearUsageDupLinkedDocsP1 = 'Duplicate linked element documentation in'; + SLinearUsageDupLinkedDocsP2 = 'descendant classes.'; + + STitle = 'FPDoc - Free Pascal Documentation Tool'; + SVersion = 'Version %s [%s]'; + SCopyright1 = '(c) 2000 - 2003 Areca Systems GmbH / Sebastian Guenther, sg@freepascal.org'; + SCopyright2 = '(c) 2005 - 2021 various FPC contributors'; + + SCmdLineHelp = 'Usage: %s [options]'; + SUsageOption008 = '--base-descr-dir=DIR prefix all description files with this directory'; + SUsageOption009 = '--base-input-dir=DIR prefix all input files with this directory'; + SUsageOption010 = '--content Create content file for package cross-references'; + SUsageOption020 = '--cputarget=value Set the target CPU for the scanner.'; + SUsageOption030 = '--descr=file use file as description file, e.g.: '; + SUsageOption035 = ' --descr=c:\WIP\myzipperdoc.xml'; + SUsageOption040 = ' This option is allowed more than once'; + SUsageOption050 = '--descr-dir=Dir Add All XML files in Dir to list of description files'; + SUsageOption060 = '--format=fmt Select output format.'; + SUsageOption070 = '--help Show this help.'; + SUsageOption080 = '--hide-protected Do not show protected methods in overview'; + SUsageOption090 = '--import=file Import content file for package cross-references'; + SUsageOption100 = '--input=cmd use cmd as input for the parser, e.g.:'; + SUsageOption110 = ' --input=C:\fpc\packages\paszlib\src\zipper.pp'; + SUsageOption120 = ' At least one input option is required.'; + SUsageOption130 = '--input-dir=Dir Add All *.pp and *.pas files in Dir to list of input files'; + SUsageOption140 = '--lang=lng Select output language.'; + SUsageOption145 = '--macro=name=value Define a macro to preprocess the project file with.'; + SUsageOption150 = '--ostarget=value Set the target OS for the scanner.'; + SUsageOption160 = '--output=name use name as the output name.'; + SUsageOption170 = ' Each backend interprets this as needed.'; + SUsageOption180 = '--package=name Set the package name for which to create output,'; + SUsageOption190 = ' e.g. --package=fcl'; + SUsageOption200 = '--project=file Use file as project file'; + SUsageOption210 = '--show-private Show private methods.'; + SUsageOption215 = '--stop-on-parser-error'; + SUsageOption215A = ' Stop when a parser error occurs. Default is to ignore parser errors.'; + SUsageOption220 = '--warn-no-node Warn if no documentation node was found.'; + SUsageOption221 = '--warn-documentation-empty Warn if documentation is empty.'; + SUsageOption222 = '--warn-xct Warn if an external class could not be resolved.'; + SUsageOption223 = '--warn-used-file Warn if an external class could not be resolved.'; + SUsageOption230 = '--mo-dir=dir Set directory where language files reside to dir'; + SUsageOption240 = '--parse-impl (Experimental) try to parse implementation too'; + SUsageOption250 = '--dont-trim Do not trim XML contents. Useful for preserving'; + SUsageOption260 = ' formatting inside e.g tags'; + SUsageOption270 = '--write-project=file'; + SUsageOption280 = ' Do not write documentation, create project file instead'; + SUsageOption290 = '--verbose Write more information on the screen'; + SUsageOption300 = '--dry-run Only parse sources and XML, do not create output'; + SUsageOption310 = '--write-project=file'; + SUsageOption320 = ' Write all command-line options to a project file'; + SUsageSubNames = 'Use the file subnames instead the indexes as postfixes'; + + SUsageFormats = 'The following output formats are supported by this fpdoc:'; + SUsageBackendHelp = 'Specify an output format, combined with --help to get more help for this backend.'; + SUsageFormatSpecific = 'Output format "%s" supports the following options:'; + SCmdLineErrInvalidMacro = 'Macro needs to be in the form name=value'; + + SCmdLineInvalidOption = 'Ignoring unknown option "%s"'; + SCmdLineInvalidFormat = 'Invalid format "%s" specified'; + SCmdLineOutputOptionMissing = 'Need an output filename, please specify one with --output='; + SWritingPages = 'Writing %d pages...'; + SNeedPackageName = 'No package name specified. Please specify one using the --package option.'; + SAvailablePackages = 'Available packages: '; + SDone = 'Done.'; + SErrCouldNotCreateOutputDir = 'Could not create output directory "%s"'; + SErrCouldNotCreateFile = 'Could not create file "%s": %s'; + SSeeURL = '(See %s)'; // For linear text writers. + SParsingUsedUnit = 'Parsing used unit "%s" with commandLine "%s"'; + + SErrFileWriting = 'An error occurred during writing of file "%s": %s'; + + SErrInvalidShortDescr = 'Invalid short description'; + SErrInvalidDescr = 'Invalid description (illegal XML element: "%s")'; + SErrInvalidParaContent = 'Invalid paragraph content'; + SErrInvalidElementInList = 'Invalid element in list - only "li" allowed'; + SErrInvalidListContent = 'Invalid list content'; + SErrInvalidRemarkContent = 'Invalid content (illegal XML element: "%s")'; + SErrListIsEmpty = 'List is empty - need at least one "li" element'; + SErrInvalidDefinitionTermContent = 'Invalid content in definition term'; + SErrDefinitionEntryMissing = 'Definition entry after definition term is missing'; + SErrInvalidBorderValue = 'Invalid "border" value for %s'; + SErrInvalidTableContent = 'Invalid table content'; + SErrTableRowEmpty = 'Table row is empty (no "td" elements found)'; + SErrInvalidContentBeforeSectionTitle = 'Invalid content before section title'; + SErrSectionTitleExpected = 'Section title ("title" element) expected'; + + SErrDescrTagUnknown = 'Warning: Unknown tag "%s" in description'; + SErrUnknownEntityReference = 'Warning: Unknown entity reference "&%s;" found'; + SErrUnknownLinkID = 'Warning: Target ID of in unit "%s", element "%s", is unknown: "%s"'; + SErrUnknownPrintShortID = 'Warning: Target ID of is unknown: "%s"'; + SErrUnknownLink = 'Could not resolve link to "%s"'; + SErralreadyRegistered = 'Class for output format "%s" already registered'; + SErrUnknownWriterClass = 'Unknown output format "%s"'; + + SErrCannotChangeIndentSizeWhenIndented = 'Cannot change indent size while text is indented.'; + SErrIndentMismatch = 'Indent mismatch: trying to undent when current indent too small'; + SErrNotInList = 'Not in list'; + SErrPopListStack = 'Pop list stack list type mismatch'; + SErrMinListStack = 'Min list stack reached'; + SErrMaxListStack = 'Max list stack reached'; + SErrMinIndentStack = 'Min indent stack reached'; + SErrMaxIndentStack = 'Max indent stack reached'; + + // doc xml + SErrInvalidRootNode = 'Invalid options root node: Got "%s", expected "docproject"'; + SErrNoPackagesNode = 'No "packages" node found in docproject'; + SErrNoInputFile = 'unit tag without file attribute found'; + SErrNoDescrFile = 'description tag without file attribute'; + SErrNoImportFile = 'Import tag without file attribute'; + SErrNoImportPrefix = 'Import tag without prefix attribute'; + +implementation + +end. + diff --git a/utils/fpdoc/fpmake.pp b/utils/fpdoc/fpmake.pp index 1dabb89934..88f3c39b8b 100644 --- a/utils/fpdoc/fpmake.pp +++ b/utils/fpdoc/fpmake.pp @@ -42,6 +42,7 @@ begin P.Options.Add('-S2h'); T:=P.Targets.AddProgram('fpdoc.pp'); + T.Dependencies.AddUnit('fpdocstrs'); T.Dependencies.AddUnit('dglobals'); T.Dependencies.AddUnit('dw_ipflin'); T.Dependencies.AddUnit('dwriter'); @@ -65,17 +66,15 @@ begin T:=P.Targets.AddProgram('fpclasschart.pp'); T.ResourceStrings:=true; - T := P.Targets.AddUnit('dglobals.pp'); + T := P.Targets.AddUnit('fpdocstrs.pp'); T.install:=false; T.ResourceStrings:=true; T := P.Targets.AddUnit('dwriter.pp'); T.install:=false; - T.ResourceStrings:=true; T := P.Targets.AddUnit('fpdocxmlopts.pas'); T.install:=false; - T.ResourceStrings:=true; P.Targets.AddUnit('dw_xml.pp').install:=false; P.Targets.AddUnit('sh_pas.pp').install:=false; @@ -84,7 +83,7 @@ begin P.Targets.AddUnit('dw_markdown.pp').install:=false; T:=P.Targets.AddUnit('dw_latex.pp'); T.install:=false; - T.ResourceStrings:=true; + P.Targets.AddUnit('dw_txt.pp').install:=false; P.Targets.AddUnit('dw_man.pp').install:=false; P.Targets.AddUnit('dwlinear.pp').install:=false; diff --git a/utils/fpdoc/mkfpdoc.pp b/utils/fpdoc/mkfpdoc.pp index 019369425b..56f4bdabf5 100644 --- a/utils/fpdoc/mkfpdoc.pp +++ b/utils/fpdoc/mkfpdoc.pp @@ -34,6 +34,7 @@ Type FProjectMacros: TStrings; FScannerLogEvents: TPScannerLogEvents; FVerbose: Boolean; + function GetLogLevels: TFPDocLogLevels; function GetOptions: TEngineOptions; function GetPackages: TFPDocPackages; procedure SetBaseDescrDir(AValue: String); @@ -73,6 +74,7 @@ Type implementation +uses fpdocstrs; { TFPDocCreator } @@ -255,6 +257,23 @@ begin Engine.WriteContentFile(APackage.ContentFile); end; +Function TFPDocCreator.GetLogLevels : TFPDocLogLevels; + + Procedure DoOpt(doSet : Boolean; aLevel: TFPDocLogLevel); + + begin + if DoSet then + Result:=Result+[aLevel]; + end; + +begin + Result:=[]; + DoOpt(Options.WarnNoNode,dleWarnNoNode); + DoOpt(Options.WarnUsedFile,dleWarnUsedFile); + DoOpt(Options.WarnDocumentationEmpty,dleDocumentationEmpty); + DoOpt(Options.WarnXCT,dleXCT); +end; + procedure TFPDocCreator.CreateDocumentation(APackage: TFPDocPackage; ParseOnly: Boolean); @@ -291,7 +310,7 @@ begin Engine.HideProtected:=Options.HideProtected; Engine.HidePrivate:=Not Options.ShowPrivate; Engine.OnParseUnit:=@HandleOnParseUnit; - Engine.WarnNoNode:=Options.WarnNoNode; + Engine.DocLogLevels:=GetLogLevels; if Length(Options.Language) > 0 then TranslateDocStrings(Options.Language); // scan the input source files