diff --git a/ChangeLog.txt b/ChangeLog.txt index b4e822efc1..67273e0cf9 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,79 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2016-10-21 07:54 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com) + * extras/hbdoc/_genbase.prg + * extras/hbdoc/_genhtml.prg + * extras/hbdoc/_gentxt.prg + * extras/hbdoc/_genxml.prg + * extras/hbdoc/_tmplate.prg + * extras/hbdoc/hbdoc.ch + * extras/hbdoc/hbdoc.css + * extras/hbdoc/hbdoc.hbp + * extras/hbdoc/hbdoc.prg + ! fix linter problems in generated html + * html5/css cleanups + * use VF IO + ! fix double close in hbdoc + ! fix file handle leak in hbdoc + * use Class(y) syntax in class definitions + * remove internal file references + % use hb_AScanI() + ! use hb_ATokens() instead of hand-rolled line splitting, + making this code EOL agnostic + % use hb_cwd(), hb_FName*(), hb_DirSep*() (also fixes potential portability issues) + * cleanups/opts + * cleaned doc tags + % force disable LTO at link-time + ! typo in comment + ; notice that you can regenerate the docs + for the Harbour website (https://harbour.github.io/doc/) + using this command: + extras/hbdoc$ hbmk2 hbdoc -run -runflag=-format=html -runflag=-output-single + or in this fork, using this command: + extras/hbdoc$ hbmk2 hbdoc -run + ; for NF doc parsing I created an internal API long ago + (it is used by HBIDE f.e.): + hbmk2 -find __hbdoc_ + usage examples in Harbour: + grep -R __hbdoc_ * + % optimized string handling / temp variable usage, IFs cleaned + % enabled -kmo build options + % cleaned header inclusion + % reworked to not use PUBLIC vars at all + % avoided some more macro expansions + % converted a public var to hb_StrReplace() with hash + * minor cleanups and optimizations + * use PROTECTED obj vars + % use SWITCH + % merged some nested branches + * use #if 0 for commented code + % cleaned some array declarations + % use hb_FNameExt() + * avoid one macro expansion + + added -run flags to regenarate docs for Harbour website + * cleaned .AND./.OR. ambiguity + % converted PUBLIC var to STATIC + ; Above patches come from 3.4 fork commits below: + 2016-09-20 02:31 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com) + 2016-09-19 18:51 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com) + 2016-09-19 18:03 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com) + 2015-07-18 17:57 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com) + 2015-06-28 11:27 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com) + 2015-06-05 20:47 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com) + 2015-03-17 13:54 UTC+0100 Viktor Szakats (vszakats users.noreply.github.com) + 2014-12-13 03:15 UTC+0100 Viktor Szakats (vszakats users.noreply.github.com) + 2014-07-15 23:04 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com) + 2014-06-21 12:46 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com) + 2014-06-20 15:38 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com) + 2014-02-12 01:58 UTC+0100 Viktor Szakáts (vszakats users.noreply.github.com) + 2014-02-03 21:07 UTC+0100 Viktor Szakáts (vszakats users.noreply.github.com) + 2014-02-03 19:19 UTC+0100 Viktor Szakáts (vszakats users.noreply.github.com) + 2014-02-03 18:37 UTC+0100 Viktor Szakáts (vszakats users.noreply.github.com) + 2014-02-03 18:22 UTC+0100 Viktor Szakáts (vszakats users.noreply.github.com) + 2014-02-03 17:45 UTC+0100 Viktor Szakáts (vszakats users.noreply.github.com) + ; plus various minor maintenance updates from multiple other commits + 2016-10-19 01:24 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com) + contrib/hbxpp/doc/en/binnumx.txt + contrib/hbxpp/doc/en/browse.txt diff --git a/extras/hbdoc/_genbase.prg b/extras/hbdoc/_genbase.prg index e4102fcfae..351fa310ef 100644 --- a/extras/hbdoc/_genbase.prg +++ b/extras/hbdoc/_genbase.prg @@ -1,11 +1,8 @@ /* * Document generator base class * - * Copyright 2009 April White - * - * Portions of this project are based on hbdoc - * Copyright 1999-2003 Luiz Rafael Culik - * + * Copyright 2009 April White + * Copyright 1999-2003 Luiz Rafael Culik (Portions of this project are based on hbdoc) * * 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 @@ -49,63 +46,63 @@ */ #include "hbclass.ch" -#include "hbdoc.ch" -#define DOCUMENT_ 1 -#define INDEX_ 2 +#include "fileio.ch" + +#define DOCUMENT_ 1 +#define INDEX_ 2 CREATE CLASS TPLGenerate - EXPORTED: - // ~ PROTECTED: - VAR nHandle AS NUMERIC - VAR cFolder AS STRING + METHOD NewIndex( cDir, cFilename, cTitle, cExtension ) + METHOD NewDocument( cDir, cFilename, cTitle, cExtension ) + METHOD AddEntry( oEntry ) INLINE HB_SYMBOL_UNUSED( oEntry ), NIL + METHOD AddReference( oEntry ) INLINE HB_SYMBOL_UNUSED( oEntry ), NIL + METHOD BeginSection( cSection, cFilename ) INLINE HB_SYMBOL_UNUSED( cSection ), HB_SYMBOL_UNUSED( cFilename ), ::Depth++ + METHOD EndSection( cSection, cFilename ) INLINE HB_SYMBOL_UNUSED( cSection ), HB_SYMBOL_UNUSED( cFilename ), ::Depth-- + METHOD Generate() INLINE NIL + METHOD IsIndex() INLINE ::nType == INDEX_ + + PROTECTED: + + METHOD New( cDir, cFilename, cTitle, cExtension, nType ) HIDDEN + + VAR nType AS INTEGER + VAR Depth AS INTEGER INIT 0 + + VAR hFile + VAR cDir AS STRING VAR cFilename AS STRING VAR cTitle AS STRING VAR cExtension AS STRING - METHOD NewIndex( cFolder, cFilename, cTitle, cExtension ) - METHOD NewDocument( cFolder, cFilename, cTitle, cExtension ) - METHOD AddEntry( oEntry ) INLINE HB_SYMBOL_UNUSED( oEntry ), NIL - METHOD AddReference( oEntry ) INLINE HB_SYMBOL_UNUSED( oEntry ), NIL - METHOD BeginSection( cSection, cFilename ) INLINE HB_SYMBOL_UNUSED( cSection ), HB_SYMBOL_UNUSED( cFilename ), ::Depth++ - METHOD EndSection( cSection, cFilename ) INLINE HB_SYMBOL_UNUSED( cSection ), HB_SYMBOL_UNUSED( cFilename ), ::Depth-- - METHOD Generate() INLINE NIL - METHOD IsIndex() INLINE ( ::nType == INDEX_ ) - - PROTECTED: - METHOD New( cFolder, cFilename, cTitle, cExtension, nType ) HIDDEN - VAR nType AS INTEGER - VAR Depth AS INTEGER INIT 0 - ENDCLASS -METHOD NewIndex( cFolder, cFilename, cTitle, cExtension ) CLASS TPLGenerate +METHOD NewIndex( cDir, cFilename, cTitle, cExtension ) CLASS TPLGenerate - self:New( cFolder, cFilename, cTitle, cExtension, INDEX_ ) + ::New( cDir, cFilename, cTitle, cExtension, INDEX_ ) RETURN self -METHOD NewDocument( cFolder, cFilename, cTitle, cExtension ) CLASS TPLGenerate +METHOD NewDocument( cDir, cFilename, cTitle, cExtension ) CLASS TPLGenerate - self:New( cFolder, cFilename, cTitle, cExtension, DOCUMENT_ ) + ::New( cDir, cFilename, cTitle, cExtension, DOCUMENT_ ) RETURN self -METHOD New( cFolder, cFilename, cTitle, cExtension, nType ) CLASS TPLGenerate +METHOD New( cDir, cFilename, cTitle, cExtension, nType ) CLASS TPLGenerate - ::nHandle := 0 - ::cFolder := cFolder + ::cDir := cDir ::cFilename := cFilename ::cTitle := cTitle ::cExtension := cExtension ::nType := nType - IF ! hb_DirExists( ::cFolder ) - OutStd( hb_eol() + "Creating folder '" + ::cFolder + "'" ) - hb_DirCreate( ::cFolder ) + IF ! hb_vfDirExists( ::cDir ) + OutStd( hb_eol() + "Creating directory", "'" + ::cDir + "'" ) + hb_vfDirMake( ::cDir ) ENDIF - ::nHandle := FCreate( ::cFolder + hb_ps() + ::cFilename + ::cExtension ) + ::hFile := hb_vfOpen( ::cDir + hb_ps() + ::cFilename + ::cExtension, FO_CREAT + FO_TRUNC + FO_WRITE ) RETURN self diff --git a/extras/hbdoc/_genhtml.prg b/extras/hbdoc/_genhtml.prg index d33ecb385a..89625824cb 100644 --- a/extras/hbdoc/_genhtml.prg +++ b/extras/hbdoc/_genhtml.prg @@ -1,10 +1,8 @@ /* * Document generator - HTML output * - * Copyright 2009 April White - * - * Portions of this project are based on hbdoc - * Copyright 1999-2003 Luiz Rafael Culik + * Copyright 2009 April White + * Copyright 1999-2003 Luiz Rafael Culik (Portions of this project are based on hbdoc) * * 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 @@ -48,36 +46,35 @@ */ #include "hbclass.ch" -#include "hbdoc.ch" #ifdef __PLATFORM__DOS -# define EXTENSION ".htm" + #define EXTENSION ".htm" #else -# define EXTENSION ".html" + #define EXTENSION ".html" #endif #define STYLEFILE "hbdoc.css" -CREATE CLASS GenerateHTML2 FROM GenerateHTML +CREATE CLASS GenerateHTML2 INHERIT GenerateHTML - METHOD NewIndex( cFolder, cFilename, cTitle ) - METHOD NewDocument( cFolder, cFilename, cTitle ) + METHOD NewIndex( cDir, cFilename, cTitle ) + METHOD NewDocument( cDir, cFilename, cTitle ) ENDCLASS -METHOD NewDocument( cFolder, cFilename, cTitle ) CLASS GenerateHTML2 +METHOD NewDocument( cDir, cFilename, cTitle ) CLASS GenerateHTML2 - ::super:NewDocument( cFolder, cFilename, cTitle, EXTENSION ) + ::super:NewDocument( cDir, cFilename, cTitle, EXTENSION ) RETURN self -METHOD NewIndex( cFolder, cFilename, cTitle ) CLASS GenerateHTML2 +METHOD NewIndex( cDir, cFilename, cTitle ) CLASS GenerateHTML2 - ::super:NewIndex( cFolder, cFilename, cTitle, EXTENSION ) + ::super:NewIndex( cDir, cFilename, cTitle, EXTENSION ) RETURN self -CREATE CLASS GenerateHTML FROM TPLGenerate +CREATE CLASS GenerateHTML INHERIT TPLGenerate HIDDEN: METHOD RecreateStyleDocument( cStyleFile ) @@ -85,77 +82,74 @@ CREATE CLASS GenerateHTML FROM TPLGenerate METHOD Tagged( cText, cTag, ... ) METHOD CloseTag( cText ) METHOD Append( cText, cFormat ) - METHOD Newline() INLINE FWrite( ::nHandle, "
" + hb_eol() ), self + METHOD Newline() INLINE hb_vfWrite( ::hFile, "
" + hb_eol() ), self CLASS VAR lCreateStyleDocument AS LOGICAL INIT .T. VAR TargetFilename AS STRING INIT "" EXPORTED: METHOD NewFile() HIDDEN - METHOD NewIndex( cFolder, cFilename, cTitle ) - METHOD NewDocument( cFolder, cFilename, cTitle ) + METHOD NewIndex( cDir, cFilename, cTitle ) + METHOD NewDocument( cDir, cFilename, cTitle ) METHOD AddEntry( oEntry ) METHOD AddReference( oEntry, cReference, cSubReference ) METHOD BeginSection( cSection, cFilename ) METHOD EndSection( cSection, cFilename ) METHOD Generate() - METHOD WriteEntry( cField, oEntry, lPreformatted, nIndent ) HIDDEN + METHOD WriteEntry( cField, oEntry, lPreformatted ) HIDDEN ENDCLASS METHOD NewFile() CLASS GenerateHTML - FWrite( ::nHandle, "" + hb_eol() ) + hb_vfWrite( ::hFile, "" + hb_eol() ) - ::OpenTag( "html", "xmlns", "http://www.w3.org/1999/xhtml", "lang", "en" ) - ::OpenTag( "head" ) + ::OpenTag( "html", "lang", "en" ) - ::Append( ::cTitle /* + iif( Empty( ::cDescription ), "", " - " + ::cDescription ) */, "title" ) - ::OpenTag( "meta", "http-equiv", "content-type", "content", "text/html; charset=UTF-8" ) - ::CloseTag( "meta" ) - ::OpenTag( "meta", "name", "generator", "content", "Harbour examples/hbdoc" ) - ::CloseTag( "meta" ) - ::OpenTag( "meta", "name", "keywords", "content", "Harbour project, Clipper, xBase, database, Free Software, GNU, compiler, cross platform, 32-bit, FiveWin" ) - ::CloseTag( "meta" ) + ::OpenTag( "meta", "charset", "utf-8" ) + ::OpenTag( "meta", "name", "generator", "content", "hbdoc" ) + ::OpenTag( "meta", "name", "keywords", "content", "Harbour, Clipper, xBase, database, Free Software, GPL, compiler, cross platform, 32-bit, 64-bit" ) IF ::lCreateStyleDocument ::lCreateStyleDocument := .F. ::RecreateStyleDocument( STYLEFILE ) ENDIF - ::OpenTag( "link", "rel", "stylesheet", "type", "text/css", "href", STYLEFILE ) - ::CloseTag( "link" ) - ::CloseTag( "head" ) - ::OpenTag( "body" ) + ::Append( ::cTitle /* + iif( Empty( ::cDescription ), "", " - " + ::cDescription ) */, "title" ) + + ::OpenTag( "link", "rel", "stylesheet", "href", STYLEFILE ) + ::Append( ::cTitle, "h1" ) RETURN self -METHOD NewDocument( cFolder, cFilename, cTitle ) CLASS GenerateHTML +METHOD NewDocument( cDir, cFilename, cTitle ) CLASS GenerateHTML - ::super:NewDocument( cFolder, cFilename, cTitle, EXTENSION ) + ::super:NewDocument( cDir, cFilename, cTitle, EXTENSION ) ::NewFile() RETURN self -METHOD NewIndex( cFolder, cFilename, cTitle ) CLASS GenerateHTML +METHOD NewIndex( cDir, cFilename, cTitle ) CLASS GenerateHTML - ::super:NewIndex( cFolder, cFilename, cTitle, EXTENSION ) + ::super:NewIndex( cDir, cFilename, cTitle, EXTENSION ) ::NewFile() RETURN self METHOD BeginSection( cSection, cFilename ) CLASS GenerateHTML + cSection := SymbolToHTMLID( cSection ) + IF ::IsIndex() IF cFilename == ::cFilename - ::OpenTag( "div", "id", cSection ):Append( cSection, "h" + hb_ntos( ::Depth + 2 ) ):CloseTag( "div" )// :Newline() + ::OpenTag( "div", "id", cSection ):Append( cSection, "h" + hb_ntos( ::Depth + 2 ) ):CloseTag( "div" ) ELSE - ::OpenTag( "a", "href", cFilename + ::cExtension + "#" + cSection ):Append( cSection, "h" + hb_ntos( ::Depth + 2 ) ):CloseTag( "a" )// :Newline() + ::OpenTag( "a", "href", cFilename + ::cExtension + "#" + cSection ):Append( cSection, "h" + hb_ntos( ::Depth + 2 ) ):CloseTag( "a" ) ENDIF ELSE - ::OpenTag( "div", "id", cSection ):Append( cSection, "h" + hb_ntos( ::Depth + 2 ) ):CloseTag( "div" )// :Newline() + ::OpenTag( "div", "id", cSection ):Append( cSection, "h" + hb_ntos( ::Depth + 2 ) ):CloseTag( "div" ) ENDIF ::TargetFilename := cFilename ::Depth++ @@ -175,10 +169,10 @@ METHOD AddReference( oEntry, cReference, cSubReference ) CLASS GenerateHTML IF HB_ISOBJECT( oEntry ) .AND. oEntry:ClassName() == "ENTRY" ::OpenTag( "a", "href", ::TargetFilename + ::cExtension + "#" + oEntry:Filename ):Append( oEntry:Name ):CloseTag( "a" ):Append( oEntry:OneLiner ):Newline() ELSE - IF cSubReference == NIL - ::OpenTag( "a", "href", cReference + ::cExtension /* + "#" + oEntry:Filename */ ):Append( oEntry ):CloseTag( "a" ):Newline() - ELSE + IF HB_ISSTRING( cSubReference ) ::OpenTag( "a", "href", cReference + ::cExtension + "#" + cSubReference ):Append( oEntry ):CloseTag( "a" ):Newline() + ELSE + ::OpenTag( "a", "href", cReference + ::cExtension /* + "#" + oEntry:Filename */ ):Append( oEntry ):CloseTag( "a" ):Newline() ENDIF ENDIF @@ -186,63 +180,58 @@ METHOD AddReference( oEntry, cReference, cSubReference ) CLASS GenerateHTML METHOD AddEntry( oEntry ) CLASS GenerateHTML - LOCAL idx + LOCAL item - FOR idx := 1 TO Len( oEntry:Fields ) - IF oEntry:Fields[ idx ][ 1 ] == "NAME" - ::OpenTag( "div", "id", oEntry:filename ):OpenTag( "h4" ):Append( oEntry:Name ):CloseTag( "h4" ):CloseTag( "div" ) - ELSEIF oEntry:IsField( oEntry:Fields[ idx ][ 1 ] ) .AND. oEntry:IsOutput( oEntry:Fields[ idx ][ 1 ] ) .AND. Len( oEntry:&( oEntry:Fields[ idx ][ 1 ] ) ) > 0 - ::WriteEntry( oEntry:Fields[ idx ][ 1 ], oEntry, oEntry:IsPreformatted( oEntry:Fields[ idx ][ 1 ] ) ) + FOR EACH item IN oEntry:Fields + IF item[ 1 ] == "NAME" + ::OpenTag( "div", "id", SymbolToHTMLID( oEntry:filename ) ):OpenTag( "h4" ):Append( oEntry:Name ):CloseTag( "h4" ):CloseTag( "div" ) + ELSEIF oEntry:IsField( item[ 1 ] ) .AND. oEntry:IsOutput( item[ 1 ] ) .AND. Len( oEntry:&( item[ 1 ] ) ) > 0 + ::WriteEntry( item[ 1 ], oEntry, oEntry:IsPreformatted( item[ 1 ] ) ) ENDIF NEXT RETURN self METHOD Generate() CLASS GenerateHTML - - IF ! Empty( ::nHandle ) - ::CloseTag( "body" ) - ::CloseTag( "html" ) - FClose( ::nHandle ) - ::nHandle := 0 - ENDIF - RETURN self -METHOD PROCEDURE WriteEntry( cField, oEntry, lPreformatted, nIndent ) CLASS GenerateHTML +METHOD PROCEDURE WriteEntry( cField, oEntry, lPreformatted ) CLASS GenerateHTML LOCAL cCaption := oEntry:FieldName( cField ) LOCAL cEntry := oEntry:&( cField ) - // TODO: change this to search the CSS document itself + /* TODO: change this to search the CSS document itself */ LOCAL cTagClass := iif( Lower( cField ) + "|" $ "name|oneliner|examples|tests|", Lower( cField ), "itemtext" ) IF ! Empty( cEntry ) - hb_default( @cCaption, "" ) - hb_default( @nIndent, 0 ) - // ~ hb_default( @lPreformatted, .F. ) - // ~ hb_default( @cTagClass, "itemtext" ) +#if 0 + hb_default( @lPreformatted, .F. ) + hb_default( @cTagClass, "itemtext" ) +#endif - IF Len( cCaption ) > 0 /* .AND. nIndent > 0 */ + hb_default( @cCaption, "" ) + IF ! HB_ISNULL( cCaption ) ::Tagged( cCaption, "div", "class", "itemtitle" ) ENDIF IF lPreformatted - ::OpenTag( "pre", iif( cTagClass != NIL, "class", ), cTagClass ) - DO WHILE Len( cEntry ) > 0 + ::OpenTag( "pre", "class", cTagClass ) + DO WHILE ! HB_ISNULL( cEntry ) IF Lower( cField ) + "|" $ "examples|tests|" ::Append( SubStr( Parse( @cEntry, hb_eol() ), 5 ), "" ) ELSE ::Append( Indent( Parse( @cEntry, hb_eol() ), 0, , .T. ), "" ) ENDIF - // ~ IF Len( cEntry ) > 0 .AND. ! lPreformatted - // ~ FWrite( ::nHandle, hb_eol() ) - // ~ ENDIF +#if 0 + IF ! HB_ISNULL( cEntry ) .AND. ! lPreformatted + hb_vfWrite( ::hFile, hb_eol() ) + ENDIF +#endif ENDDO ::CloseTag( "pre" ) ELSE - DO WHILE Len( cEntry ) > 0 + DO WHILE ! HB_ISNULL( cEntry ) ::OpenTag( "div", "class", cTagClass ) ::Append( Indent( Parse( @cEntry, hb_eol() ), 0, 70 ), "" ):Newline() ::CloseTag( "div" ) @@ -250,72 +239,69 @@ METHOD PROCEDURE WriteEntry( cField, oEntry, lPreformatted, nIndent ) CLASS Gene ENDIF ENDIF + RETURN + METHOD OpenTag( cText, ... ) CLASS GenerateHTML LOCAL aArgs := hb_AParams() - LOCAL cTag := cText LOCAL idx FOR idx := 2 TO Len( aArgs ) STEP 2 - cTag += " " + aArgs[ idx ] + "=" + '"' + aArgs[ idx + 1 ] + '"' + cText += " " + aArgs[ idx ] + "=" + '"' + aArgs[ idx + 1 ] + '"' NEXT - FWrite( ::nHandle, "<" + cTag + ">" + hb_eol() ) + hb_vfWrite( ::hFile, "<" + cText + ">" + hb_eol() ) RETURN self METHOD Tagged( cText, cTag, ... ) CLASS GenerateHTML LOCAL aArgs := hb_AParams() - LOCAL cResult := "<" + cTag + LOCAL cResult := "" LOCAL idx FOR idx := 3 TO Len( aArgs ) STEP 2 cResult += " " + aArgs[ idx ] + "=" + '"' + aArgs[ idx + 1 ] + '"' NEXT - FWrite( ::nHandle, cResult + ">" + cText + "" + /* "4" + */ hb_eol() ) + hb_vfWrite( ::hFile, "<" + cTag + cResult + ">" + cText + "" + hb_eol() ) RETURN self METHOD CloseTag( cText ) CLASS GenerateHTML - FWrite( ::nHandle, "" + hb_eol() ) + hb_vfWrite( ::hFile, "" + hb_eol() ) IF cText == "html" - FClose( ::nHandle ) - ::nHandle := 0 + hb_vfClose( ::hFile ) + ::hFile := NIL ENDIF RETURN self METHOD Append( cText, cFormat ) CLASS GenerateHTML - LOCAL cResult := cText - LOCAL aFormat LOCAL idx - IF Len( cResult ) > 0 + IF ! HB_ISNULL( cText ) - hb_default( @cFormat, "" ) + cText := hb_StrReplace( cText, { ; + "&" => "&", ; + '"' => """, ; + "<" => "<", ; + ">" => ">" } ) - aFormat := p_aConversionList - FOR idx := 1 TO Len( aFormat ) STEP 2 - cResult := StrTran( cResult, aFormat[ idx ], "&" + aFormat[ idx + 1 ] + ";" ) - NEXT - - aFormat := hb_ATokens( cFormat, "," ) - FOR idx := Len( aFormat ) TO 1 STEP -1 - IF ! Empty( aFormat[ idx ] ) - cResult := "<" + aFormat[ idx ] + ">" + cResult + "" + FOR EACH idx IN hb_ATokens( hb_defaultValue( cFormat, "" ), "," ) DESCEND + IF ! Empty( idx ) + cText := "<" + idx + ">" + cText + "" ENDIF NEXT - DO WHILE Right( cResult, Len( hb_eol() ) ) == hb_eol() - cResult := Left( cResult, Len( cResult ) - Len( hb_eol() ) ) + DO WHILE Right( cText, Len( hb_eol() ) ) == hb_eol() + cText := hb_StrShrink( cText, Len( hb_eol() ) ) ENDDO - FWrite( ::nHandle, cResult + hb_eol() ) + hb_vfWrite( ::hFile, cText + hb_eol() ) ENDIF @@ -327,8 +313,11 @@ METHOD RecreateStyleDocument( cStyleFile ) CLASS GenerateHTML #pragma __streaminclude "hbdoc.css" | cString := %s - IF ! hb_MemoWrit( ::cFolder + hb_ps() + cStyleFile, cString ) - // TODO: raise an error, could not create style file + IF ! hb_MemoWrit( ::cDir + hb_ps() + cStyleFile, cString ) + /* TODO: raise an error, could not create style file */ ENDIF RETURN self + +STATIC FUNCTION SymbolToHTMLID( cID ) + RETURN Lower( hb_StrReplace( cID, "_ ", "--" ) ) diff --git a/extras/hbdoc/_gentxt.prg b/extras/hbdoc/_gentxt.prg index e6dd709253..de758408fb 100644 --- a/extras/hbdoc/_gentxt.prg +++ b/extras/hbdoc/_gentxt.prg @@ -1,11 +1,8 @@ /* * Document generator - text output * - * Copyright 2009 April White - * - * Portions of this project are based on hbdoc - * Copyright 1999-2003 Luiz Rafael Culik - * + * Copyright 2009 April White + * Copyright 1999-2003 Luiz Rafael Culik (Portions of this project are based on hbdoc) * * 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 @@ -49,30 +46,29 @@ */ #include "hbclass.ch" -#include "hbdoc.ch" -CREATE CLASS GenerateAscii FROM GenerateText +CREATE CLASS GenerateAscii INHERIT GenerateText - METHOD NewIndex( cFolder, cFilename, cTitle, cDescription ) - METHOD NewDocument( cFolder, cFilename, cTitle, cDescription ) + METHOD NewIndex( cDir, cFilename, cTitle, cDescription ) + METHOD NewDocument( cDir, cFilename, cTitle, cDescription ) ENDCLASS -METHOD NewDocument( cFolder, cFilename, cTitle, cDescription ) CLASS GenerateAscii +METHOD NewDocument( cDir, cFilename, cTitle, cDescription ) CLASS GenerateAscii ::lContinuous := .T. - ::super:NewDocument( cFolder, cFilename, cTitle, cDescription ) + ::super:NewDocument( cDir, cFilename, cTitle, cDescription ) RETURN self -METHOD NewIndex( cFolder, cFilename, cTitle, cDescription ) CLASS GenerateAscii +METHOD NewIndex( cDir, cFilename, cTitle, cDescription ) CLASS GenerateAscii ::lContinuous := .T. - ::super:NewIndex( cFolder, cFilename, cTitle, cDescription ) + ::super:NewIndex( cDir, cFilename, cTitle, cDescription ) RETURN self -CREATE CLASS GenerateText FROM TPLGenerate +CREATE CLASS GenerateText INHERIT TPLGenerate HIDDEN: @@ -80,28 +76,30 @@ CREATE CLASS GenerateText FROM TPLGenerate VAR lContinuous AS LOGICAL INIT .F. EXPORTED: - METHOD NewIndex( cFolder, cFilename, cTitle ) - METHOD NewDocument( cFolder, cFilename, cTitle ) + METHOD NewIndex( cDir, cFilename, cTitle ) + METHOD NewDocument( cDir, cFilename, cTitle ) METHOD AddEntry( oEntry ) METHOD AddIndex( oEntry ) HIDDEN METHOD BeginSection( cSection, cFilename ) - // ~ METHOD EndSection( cSection, cFilename ) // will use inherited method +#if 0 + METHOD EndSection( cSection, cFilename ) /* will use inherited method */ +#endif METHOD Generate() METHOD WriteEntry( cCaption, cEntry, lPreformatted ) HIDDEN ENDCLASS -METHOD NewDocument( cFolder, cFilename, cTitle ) CLASS GenerateText +METHOD NewDocument( cDir, cFilename, cTitle ) CLASS GenerateText - ::super:NewDocument( cFolder, cFilename, cTitle, ".txt" ) + ::super:NewDocument( cDir, cFilename, cTitle, ".txt" ) ::WriteEntry( "", cTitle + hb_eol(), .F. ) RETURN self -METHOD NewIndex( cFolder, cFilename, cTitle ) CLASS GenerateText +METHOD NewIndex( cDir, cFilename, cTitle ) CLASS GenerateText - ::super:NewIndex( cFolder, cFilename, cTitle, ".txt" ) + ::super:NewIndex( cDir, cFilename, cTitle, ".txt" ) ::WriteEntry( "", cTitle + hb_eol(), .F. ) RETURN self @@ -125,19 +123,19 @@ METHOD AddIndex( oEntry ) CLASS GenerateText METHOD AddEntry( oEntry ) CLASS GenerateText - LOCAL idx + LOCAL item - IF self:IsIndex() - self:AddIndex( oEntry ) + IF ::IsIndex() + ::AddIndex( oEntry ) ELSE - FOR idx := 1 TO Len( oEntry:Fields ) - IF oEntry:IsField( oEntry:Fields[ idx ][ 1 ] ) .AND. oEntry:IsOutput( oEntry:Fields[ idx ][ 1 ] ) .AND. Len( oEntry:&( oEntry:Fields[ idx ][ 1 ] ) ) > 0 - ::WriteEntry( oEntry:FieldName( oEntry:Fields[ idx ][ 1 ] ), oEntry:&( oEntry:Fields[ idx ][ 1 ] ), oEntry:IsPreformatted( oEntry:Fields[ idx ][ 1 ] ) ) + FOR EACH item IN oEntry:Fields + IF oEntry:IsField( item[ 1 ] ) .AND. oEntry:IsOutput( item[ 1 ] ) .AND. Len( oEntry:&( item[ 1 ] ) ) > 0 + ::WriteEntry( oEntry:FieldName( item[ 1 ] ), oEntry:&( item[ 1 ] ), oEntry:IsPreformatted( item[ 1 ] ) ) ENDIF NEXT IF ! ::lContinuous - FWrite( ::nHandle, hb_BChar( 12 ) + hb_eol() ) + hb_vfWrite( ::hFile, hb_BChar( 12 ) + hb_eol() ) ENDIF ENDIF @@ -148,27 +146,25 @@ METHOD PROCEDURE WriteEntry( cCaption, cEntry, lPreformatted ) CLASS GenerateTex LOCAL nIndent IF ! Empty( cEntry ) - nIndent := iif( Len( cCaption ) > 0, 6, 0 ) - IF Len( cCaption ) > 0 .AND. nIndent > 0 - FWrite( ::nHandle, Space( ::Depth * 6 ) + cCaption + ": " + hb_eol() ) + nIndent := iif( HB_ISNULL( cCaption ), 0, 6 ) + IF ! HB_ISNULL( cCaption ) .AND. nIndent > 0 + hb_vfWrite( ::hFile, Space( ::Depth * 6 ) + cCaption + ": " + hb_eol() ) ENDIF nIndent += ::Depth * 6 - DO WHILE Len( cEntry ) > 0 - FWrite( ::nHandle, Indent( Parse( @cEntry, hb_eol() ), nIndent, 70, lPreformatted ) ) + DO WHILE ! HB_ISNULL( cEntry ) + hb_vfWrite( ::hFile, Indent( Parse( @cEntry, hb_eol() ), nIndent, 70, lPreformatted ) ) ENDDO ENDIF METHOD Generate() CLASS GenerateText - IF ::IsIndex() - IF ! ::lContinuous - FWrite( ::nHandle, hb_BChar( 12 ) + hb_eol() ) - ENDIF + IF ::IsIndex() .AND. ! ::lContinuous + hb_vfWrite( ::hFile, hb_BChar( 12 ) + hb_eol() ) ENDIF - IF ! Empty( ::nHandle ) - FClose( ::nHandle ) - ::nHandle := 0 + IF ::hFile != NIL + hb_vfClose( ::hFile ) + ::hFile := NIL ENDIF RETURN self diff --git a/extras/hbdoc/_genxml.prg b/extras/hbdoc/_genxml.prg index a57d3b1097..c23302c94e 100644 --- a/extras/hbdoc/_genxml.prg +++ b/extras/hbdoc/_genxml.prg @@ -1,11 +1,8 @@ /* * Document generator - XML output * - * Copyright 2009 April White - * - * Portions of this project are based on hbdoc - * Copyright 1999-2003 Luiz Rafael Culik - * + * Copyright 2009 April White + * Copyright 1999-2003 Luiz Rafael Culik (Portions of this project are based on hbdoc) * * 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 @@ -49,17 +46,16 @@ */ #include "hbclass.ch" -#include "hbdoc.ch" -CREATE CLASS GenerateXML FROM TPLGenerate +CREATE CLASS GenerateXML INHERIT TPLGenerate HIDDEN: PROTECTED: EXPORTED: - METHOD NewIndex( cFolder, cFilename, cTitle ) - METHOD NewDocument( cFolder, cFilename, cTitle ) + METHOD NewIndex( cDir, cFilename, cTitle ) + METHOD NewDocument( cDir, cFilename, cTitle ) METHOD AddEntry( oEntry ) METHOD AddIndex( oEntry ) HIDDEN METHOD BeginSection( cSection, cFilename ) @@ -70,28 +66,28 @@ CREATE CLASS GenerateXML FROM TPLGenerate ENDCLASS -METHOD NewDocument( cFolder, cFilename, cTitle ) CLASS GenerateXML +METHOD NewDocument( cDir, cFilename, cTitle ) CLASS GenerateXML - ::super:NewDocument( cFolder, cFilename, cTitle, ".xml" ) - FWrite( ::nHandle, '' + hb_eol() ) - FWrite( ::nHandle, '' + hb_eol() ) + ::super:NewDocument( cDir, cFilename, cTitle, ".xml" ) + hb_vfWrite( ::hFile, '' + hb_eol() ) + hb_vfWrite( ::hFile, '' + hb_eol() ) RETURN self -METHOD NewIndex( cFolder, cFilename, cTitle ) CLASS GenerateXML +METHOD NewIndex( cDir, cFilename, cTitle ) CLASS GenerateXML - ::super:NewIndex( cFolder, cFilename, cTitle, ".xml" ) - FWrite( ::nHandle, '' + hb_eol() ) - FWrite( ::nHandle, '' + hb_eol() ) + ::super:NewIndex( cDir, cFilename, cTitle, ".xml" ) + hb_vfWrite( ::hFile, '' + hb_eol() ) + hb_vfWrite( ::hFile, '' + hb_eol() ) RETURN self METHOD BeginSection( cSection, cFilename ) CLASS GenerateXML IF ::Depth == 0 - FWrite( ::nHandle, Replicate( Chr( 9 ), ::Depth ) + '
' + hb_eol() ) + hb_vfWrite( ::hFile, Replicate( Chr( 9 ), ::Depth ) + '
' + hb_eol() ) ELSE - FWrite( ::nHandle, Replicate( Chr( 9 ), ::Depth ) + '
' + hb_eol() ) + hb_vfWrite( ::hFile, Replicate( Chr( 9 ), ::Depth ) + '
' + hb_eol() ) ENDIF ::Depth++ @@ -102,7 +98,7 @@ METHOD EndSection( cSection, cFilename ) CLASS GenerateXML HB_SYMBOL_UNUSED( cSection ) HB_SYMBOL_UNUSED( cFilename ) ::Depth-- - FWrite( ::nHandle, Replicate( Chr( 9 ), ::Depth ) + '
' + hb_eol() ) + hb_vfWrite( ::hFile, Replicate( Chr( 9 ), ::Depth ) + '
' + hb_eol() ) RETURN self @@ -114,51 +110,48 @@ METHOD AddIndex( oEntry ) CLASS GenerateXML METHOD AddEntry( oEntry ) CLASS GenerateXML - LOCAL idx + LOCAL item - IF self:IsIndex() - self:AddIndex( oEntry ) + IF ::IsIndex() + ::AddIndex( oEntry ) ELSE - FWrite( ::nHandle, '' + hb_eol() ) + hb_vfWrite( ::hFile, '' + hb_eol() ) ::Depth++ - FOR idx := 1 TO Len( oEntry:Fields ) - ::WriteEntry( oEntry:Fields[ idx ][ 1 ], oEntry:&( oEntry:Fields[ idx ][ 1 ] ), oEntry:IsPreformatted( oEntry:Fields[ idx ][ 1 ] ) ) + FOR EACH item IN oEntry:Fields + ::WriteEntry( item[ 1 ], oEntry:&( item[ 1 ] ), oEntry:IsPreformatted( item[ 1 ] ) ) NEXT ::Depth-- - FWrite( ::nHandle, '' + hb_eol() ) + hb_vfWrite( ::hFile, '' + hb_eol() ) ENDIF RETURN self METHOD Generate() CLASS GenerateXML - FWrite( ::nHandle, '' + hb_eol() ) + hb_vfWrite( ::hFile, '' + hb_eol() ) - IF ::IsIndex() - ENDIF - - IF ! Empty( ::nHandle ) - FClose( ::nHandle ) - ::nHandle := 0 + IF ::hFile != NIL + hb_vfClose( ::hFile ) + ::hFile := NIL ENDIF RETURN self METHOD PROCEDURE WriteEntry( cCaption, cEntry, lPreformatted ) CLASS GenerateXML - LOCAL cResult - LOCAL idx - IF ! Empty( cEntry ) - cResult := iif( hb_eol() $ cEntry, hb_eol() + cEntry, cEntry ) - FOR idx := 1 TO Len( p_aConversionList ) STEP 2 - cResult := StrTran( cResult, p_aConversionList[ idx ], "&" + p_aConversionList[ idx + 1 ] + ";" ) - NEXT - cEntry := cResult - FWrite( ::nHandle, Replicate( Chr( 9 ), ::Depth ) + "<" + cCaption + iif( lPreformatted, ' preformatted="yes"', "" ) + ">" ) - FWrite( ::nHandle, cEntry ) - FWrite( ::nHandle, /* Replicate( Chr( 9 ), ::Depth ) + */ "" + hb_eol() ) + IF hb_eol() $ cEntry + cEntry := hb_eol() + cEntry + ENDIF + + hb_vfWrite( ::hFile, Replicate( Chr( 9 ), ::Depth ) + "<" + cCaption + iif( lPreformatted, ' preformatted="yes"', "" ) + ">" ) + hb_vfWrite( ::hFile, hb_StrReplace( cEntry, { ; + "&" => "&", ; + '"' => """, ; + "<" => "<", ; + ">" => ">" } ) ) + hb_vfWrite( ::hFile, /* Replicate( Chr( 9 ), ::Depth ) + */ "" + hb_eol() ) ENDIF RETURN diff --git a/extras/hbdoc/_tmplate.prg b/extras/hbdoc/_tmplate.prg index 6c9a27b22f..8c711fd5f6 100644 --- a/extras/hbdoc/_tmplate.prg +++ b/extras/hbdoc/_tmplate.prg @@ -1,10 +1,8 @@ /* * Document generator, templates * - * Copyright 2009 April White - * - * Portions of this project are based on hbdoc - * Copyright 1999-2003 Luiz Rafael Culik + * Copyright 2009 April White + * Copyright 1999-2003 Luiz Rafael Culik (Portions of this project are based on hbdoc) * * 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 @@ -62,24 +60,23 @@ CREATE CLASS Entry { "NAME", "" }, ; { "CATEGORY", "Category" }, ; { "SUBCATEGORY", "Sub category" }, ; - { "ONELINER", "" },; - { "SYNTAX", "Syntax" },; - { "ARGUMENTS", "Argument(s)" },; - { "RETURNS", "Returns" },; - { "DESCRIPTION", "Description" },; - { "DATALINK", "Data link" },; - { "DATANOLINK", "Data no link" },; - { "METHODSLINK", "Methods link" },; - { "METHODSNOLINK","Methods no link" },; - { "EXAMPLES", "Example(s)" },; - { "TESTS", "Test(s)" },; - { "STATUS", "Status" },; /* p_aStatus is the constraint list */ - { "COMPLIANCE", "Compliance" },; /* p_aCompliance is the constraint list */ - { "PLATFORMS", "Platform(s)" },; /* p_aPlatforms is the constraint list */ - { "FILES", "File(s)" },; + { "ONELINER", "" }, ; + { "SYNTAX", "Syntax" }, ; + { "ARGUMENTS", "Argument(s)" }, ; + { "RETURNS", "Returns" }, ; + { "DESCRIPTION", "Description" }, ; + { "DATALINK", "Data link" }, ; + { "DATANOLINK", "Data no link" }, ; + { "METHODSLINK", "Methods link" }, ; + { "METHODSNOLINK","Methods no link" }, ; + { "EXAMPLES", "Example(s)" }, ; + { "TESTS", "Test(s)" }, ; + { "STATUS", "Status" }, ; /* ::hConstraint[ "status" ] is the constraint list */ + { "COMPLIANCE", "Compliance" }, ; /* ::hConstraint[ "compliance" ] is the constraint list */ + { "PLATFORMS", "Platform(s)" }, ; /* ::hConstraint[ "platforms" ] is the constraint list */ + { "FILES", "File(s)" }, ; { "SEEALSO", "See also" }, ; - { "END", "End" } ; - } + { "END", "End" } } #define _S TPL_START #define _E TPL_END @@ -89,8 +86,7 @@ CREATE CLASS Entry #define _P TPL_PREFORMATTED #define _U TPL_OUTPUT - // this is best viewed with a fixed-width font - // the columns of this array correspond to the elements of Fields + /* the columns of this array correspond to the elements of Fields */ CLASS VAR Templates AS ARRAY INIT { ; { "Template" , { _S, _T, 0+_U, 0, _O , 0+_U, 0+_U, 0+_U, 0+_U, 0+_U, 0+_U, 0+_U, 0+_U, 0+_U, 0 +_U, 0 +_U, 0+_U, 0+_U, 0+_U, 0+_U, 0+_U, _E } }, ; { "Document" , { _S, _T, _R+_U, _R, _O+_U, _O+_U, 0+_U, 0+_U, 0+_U, _R+_U, 0+_U, 0+_U, 0+_U, 0+_U, 0 +_U, 0 +_U, 0+_U, 0+_U, _O+_U, _O+_U, _O+_U, _E } }, ; @@ -101,10 +97,9 @@ CREATE CLASS Entry { "Class" , { _S, _T, _R+_U, _R, _R , _O+_U, _R+_U, _R+_U, _R+_U, _R+_U, _O+_U, _O+_U, _O+_U, _O+_U, _P+_O+_U, _P+_O+_U, _O+_U, _O+_U, _O+_U, _O+_U, _O+_U, _E } }, ; { "Class method" , { _S, _T, _R+_U, _R, _R , _O+_U, _R+_U, _R+_U, _R+_U, _R+_U, 0+_U, 0+_U, 0+_U, 0+_U, _P+_O+_U, 0 +_U, 0+_U, 0+_U, 0+_U, 0+_U, _O+_U, _E } }, ; { "Class data" , { _S, _T, _R+_U, _R, _R , _O+_U, _R+_U, 0+_U, 0+_U, _R+_U, 0+_U, 0+_U, 0+_U, 0+_U, _P+_O+_U, 0 +_U, 0+_U, 0+_U, 0+_U, 0+_U, _O+_U, _E } }, ; - { "Run time error", { _S, _T, _R+_U, _R, 0 , _O+_U, 0+_U, 0+_U, 0+_U, _R+_U, 0+_U, 0+_U, 0+_U, 0+_U, _P+_O+_U, 0 +_U, 0+_U, _O+_U, 0+_U, 0+_U, _O+_U, _E } }, ; - } + { "Run time error", { _S, _T, _R+_U, _R, 0 , _O+_U, 0+_U, 0+_U, 0+_U, _R+_U, 0+_U, 0+_U, 0+_U, 0+_U, _P+_O+_U, 0 +_U, 0+_U, _O+_U, 0+_U, 0+_U, _O+_U, _E } } } - METHOD New( cType ) CONSTRUCTOR + METHOD New( cType, hConstraint ) CONSTRUCTOR METHOD IsField( c, nType ) METHOD IsTemplate( cType ) METHOD SetTemplate( cTemplate ) @@ -124,18 +119,22 @@ CREATE CLASS Entry VAR sourcefile_ AS STRING VAR sourcefileversion_ AS STRING VAR uid_ AS STRING + VAR hConstraint AS HASH + CLASS VAR uid__ AS INTEGER INIT 0 ENDCLASS -METHOD New( cType ) CLASS Entry +METHOD New( cType, hConstraint ) CLASS Entry + + ::hConstraint := hConstraint ::uid_ := hb_ntos( ++::uid__ ) - IF ! __objHasData( self, self:Fields[ 1 ][ 1 ] ) - AEval( self:Fields, {| a | __objAddData( self, a[ 1 ] ) } ) + IF ! __objHasData( self, ::Fields[ 1 ][ 1 ] ) + AEval( ::Fields, {| a | __objAddData( self, a[ 1 ] ) } ) ENDIF - IF cType != NIL - self:Group := self:Templates[ AScan( self:Templates, {| a | Upper( a[ 1 ] ) == Upper( cType ) } ) ][ 2 ] + IF HB_ISSTRING( cType ) + ::Group := ::Templates[ AScan( ::Templates, {| a | Upper( a[ 1 ] ) == Upper( cType ) } ) ][ 2 ] ENDIF RETURN self @@ -145,10 +144,10 @@ METHOD IsField( c, nType ) CLASS Entry LOCAL idx LOCAL lResult - IF ( lResult := ( idx := AScan( self:Fields, {| a | Upper( a[ 1 ] ) == Upper( c ) } ) ) > 0 ) - IF self:Group[ idx ] == 0 + IF ( lResult := ( idx := AScan( ::Fields, {| a | Upper( a[ 1 ] ) == Upper( c ) } ) ) > 0 ) + IF ::Group[ idx ] == 0 lResult := .F. - ELSEIF nType != NIL .AND. hb_bitAnd( self:Group[ idx ], nType ) != nType + ELSEIF HB_ISNUMERIC( nType ) .AND. hb_bitAnd( ::Group[ idx ], nType ) != nType lResult := .F. ENDIF ENDIF @@ -156,19 +155,19 @@ METHOD IsField( c, nType ) CLASS Entry RETURN lResult METHOD IsTemplate( cType ) CLASS Entry - RETURN AScan( self:Templates, {| a | Upper( a[ 1 ] ) == Upper( cType ) } ) > 0 + RETURN AScan( ::Templates, {| a | Upper( a[ 1 ] ) == Upper( cType ) } ) > 0 METHOD SetTemplate( cTemplate ) CLASS Entry - LOCAL aData := Array( Len( self:Fields ) ) + LOCAL aData := Array( Len( ::Fields ) ) LOCAL idx - self:Group := self:Templates[ AScan( self:Templates, {| a | Upper( a[ 1 ] ) == Upper( cTemplate ) } ) ][ 2 ] + ::Group := ::Templates[ AScan( ::Templates, {| a | Upper( a[ 1 ] ) == Upper( cTemplate ) } ) ][ 2 ] FOR idx := 1 TO Len( aData ) - IF self:Fields[ idx ][ 1 ] == "TEMPLATE" - aData[ idx ] := { self:Fields[ idx ][ 1 ], cTemplate } + IF ::Fields[ idx ][ 1 ] == "TEMPLATE" + aData[ idx ] := { ::Fields[ idx ][ 1 ], cTemplate } ELSE - aData[ idx ] := { self:Fields[ idx ][ 1 ], iif( self:Group[ idx ] == TPL_REQUIRED, NIL, "" ) } + aData[ idx ] := { ::Fields[ idx ][ 1 ], iif( ::Group[ idx ] == TPL_REQUIRED, NIL, "" ) } ENDIF NEXT __objSetValueList( self, aData ) @@ -178,14 +177,14 @@ METHOD SetTemplate( cTemplate ) CLASS Entry METHOD IsConstraint( cSectionName, cSection ) CLASS Entry LOCAL lResult - LOCAL idx := AScan( self:Fields, {| a | a[ 1 ] == cSectionName } ) + LOCAL idx := AScan( ::Fields, {| a | a[ 1 ] == cSectionName } ) - IF hb_bitAnd( self:Group[ idx ], hb_bitAnd( TPL_REQUIRED, TPL_OPTIONAL ) ) == 0 + IF hb_bitAnd( ::Group[ idx ], hb_bitAnd( TPL_REQUIRED, TPL_OPTIONAL ) ) == 0 lResult := .T. - ELSEIF Type( "p_a" + cSectionName ) == "A" + ELSEIF cSectionName $ ::hConstraint lResult := ; - hb_AScan( &( "p_a" + cSectionName ), cSection, , , .T. ) .OR. ; - hb_AScan( &( "p_a" + cSectionName ), Parse( cSection, "," ), , , .T. ) + hb_AScan( ::hConstraint[ cSectionName ], cSection, , , .T. ) .OR. ; + hb_AScan( ::hConstraint[ cSectionName ], Parse( cSection, "," ), , , .T. ) ELSE lResult := .T. ENDIF @@ -199,9 +198,9 @@ METHOD IsComplete( cIncompleteFielsList ) CLASS Entry cIncompleteFielsList := "" - FOR idx := 1 TO Len( self:Fields ) - IF hb_bitAnd( self:Group[ idx ], TPL_REQUIRED ) != 0 .AND. Empty( self:&( self:Fields[ idx ][ 1 ] ) ) - cIncompleteFielsList += "," + self:Fields[ idx ][ 1 ] + FOR idx := 1 TO Len( ::Fields ) + IF hb_bitAnd( ::Group[ idx ], TPL_REQUIRED ) != 0 .AND. Empty( ::&( ::Fields[ idx ][ 1 ] ) ) + cIncompleteFielsList += "," + ::Fields[ idx ][ 1 ] lResult := .F. ENDIF NEXT @@ -211,209 +210,23 @@ METHOD IsComplete( cIncompleteFielsList ) CLASS Entry RETURN lResult METHOD IsPreformatted( cField ) CLASS Entry - RETURN hb_bitAnd( self:Group[ AScan( self:Fields, {| a | a[ 1 ] == cField } ) ], TPL_PREFORMATTED ) != 0 + RETURN hb_bitAnd( ::Group[ AScan( ::Fields, {| a | a[ 1 ] == cField } ) ], TPL_PREFORMATTED ) != 0 METHOD IsRequired( cField ) CLASS Entry - RETURN hb_bitAnd( self:Group[ AScan( self:Fields, {| a | a[ 1 ] == cField } ) ], TPL_REQUIRED ) != 0 + RETURN hb_bitAnd( ::Group[ AScan( ::Fields, {| a | a[ 1 ] == cField } ) ], TPL_REQUIRED ) != 0 METHOD IsOptional( cField ) CLASS Entry - RETURN hb_bitAnd( self:Group[ AScan( self:Fields, {| a | a[ 1 ] == cField } ) ], TPL_OPTIONAL ) != 0 + RETURN hb_bitAnd( ::Group[ AScan( ::Fields, {| a | a[ 1 ] == cField } ) ], TPL_OPTIONAL ) != 0 METHOD IsOutput( cField ) CLASS Entry - RETURN hb_bitAnd( self:Group[ AScan( self:Fields, {| a | a[ 1 ] == cField } ) ], TPL_OUTPUT ) != 0 + RETURN hb_bitAnd( ::Group[ AScan( ::Fields, {| a | a[ 1 ] == cField } ) ], TPL_OUTPUT ) != 0 METHOD FieldName( cField ) CLASS Entry - RETURN self:Fields[ AScan( self:Fields, {| a | a[ 1 ] == cField } ) ][ 2 ] + RETURN ::Fields[ AScan( ::Fields, {| a | a[ 1 ] == cField } ) ][ 2 ] METHOD CategoryIndex( cCategory ) CLASS Entry - RETURN AScan( p_aCategories, {| a | HB_ISARRAY( a ) .AND. Len( a ) >= 1 .AND. a[ 1 ] == cCategory } ) + RETURN AScan( ::hConstraint[ "categories" ], {| a | HB_ISARRAY( a ) .AND. Len( a ) >= 1 .AND. a[ 1 ] == cCategory } ) METHOD SubcategoryIndex( cCategory, cSubcategory ) CLASS Entry RETURN ::CategoryIndex( cCategory ) >= 1 .AND. ; - hb_AScan( p_aCategories[ ::CategoryIndex( cCategory ) ][ 2 ], cSubcategory, , , .T. ) - -PROCEDURE init_Templates() - - LOCAL idx - LOCAL aSubCategories := { ; - "Application", ; - "Array", ; - "Classes", ; - "Conversion", ; - "Database", ; - "Date/Time", ; - "Environment", ; - "Error", ; - "Events", ; - "Execute and execution", ; /* replace w/ "Environment"? */ - "Extend", ; - "FileSys", ; - "Fixed memory", ; - "Garbage collector", ; - "Hash table", ; - "Idle states", ; - "INET", ; - "Internal", ; - "Item", ; - "Language and Nation", ; - "Legacy", ; - "Macro", ; - "Math", ; - "Objects", ; - "Printer", ; - "RDD", ; - "Strings", ; - "Terminal", ; - "Undocumented", ; - "User interface", ; - "Variable management", ; - "Virtual machine", ; - } - - PUBLIC p_aCategories := { ; - { "Document", { "License", "Compiler", "" } }, ; - { "API", AClone( aSubCategories ) }, ; - { "C level API", AClone( aSubCategories ) }, ; - { "C level API compatability", AClone( aSubCategories ) }, ; - { "Class", { ; - "", ; - "Access", ; - "Assign", ; - "Constructor", ; - "Data", ; - "Definition", ; - "Destructor", ; - "Method", ; - "Var", ; - } }, ; - { "Command", AClone( aSubCategories ) }, ; - /* { "Compile time errors", { {} } }, */ ; - { "Run time errors", { "" } }, ; - } - - FOR idx := 1 TO Len( p_aCategories ) - IF ! Empty( p_aCategories[ idx ] ) - AAdd( p_aCategories[ idx ], Array( Len( p_aCategories[ idx ][ 2 ] ) ) ) // holder array of sub-category entries - AAdd( p_aCategories[ idx ], "" ) // holder for sub-category file name - ENDIF - NEXT - - PUBLIC p_aCompliance := { ; - { "", "" }, ; - { "C", "This is CA-Cl*pper v5.2 compliant" }, ; - { "C(array)", "This is CA-Cl*pper v5.2 compliant except that arrays in Harbour can have an unlimited number of elements" }, ; - { "C(menu)", "This is CA-Cl*pper v5.2 compliant except that menus (internally arrays) in Harbour can have an unlimited number of elements" }, ; - { "C(arrayblock)", "Codeblock calling frequency and order differs from CA-Cl*pper, since Harbour uses a different (faster) sorting algorithm (quicksort)" }, ; - { "C52S", "? verbage: This is an CA-Cl*pper v5.2 compliant and is only visible if source was compiled with the HB_C52_STRICT flag" }, ; - { "C52U", "This is an undocumented CA-Cl*pper v5.2 function and is only visible if source was compiled with the HB_C52_UNDOC flag" }, ; - { "C53", "This is CA-Cl*pper v5.3 compliant and is only visible if source was compiled with the HB_COMPAT_C53 flag" }, ; - { "H", "This is Harbour specific" }, ; - { "NA", "Not applicable" } ; - } - - PUBLIC p_aPlatforms := { ; - { "", "" }, ; - { "All", "This is available on all platforms" }, ; - { "All(GT)", "This part of the GT API and supported only by some platforms." }, ; - { "All(LFN)", "This is available on all platforms." + hb_eol() + ; - "If long file names are available Harbour will use/display the first 15 characters " +; - "else Harbour will use/display a 8.3 file name consistent with CA-Cl*pper" }, ; - { "Linux(GT)", "Under Linux the number of columns avaliable depends of the current Terminal screen size." }, ; - { "OS2(GT)", "Under OS/2 the number of columns avaliable depends of the current Terminal screen size." }, ; - { "Win(GT)", "Under Windows, the return value of MaxRow() function is only affected if called after an SetMode() function" }, ; - { "BSD", "This is available on the BSD platform" }, ; - { "DARWIN", "This is available on the Darwin platform" }, ; - { "DOS", "This is available on the MS-DOS platform" }, ; - { "HPUX", "This is available on the HPUX platform" }, ; - { "LINUX", "This is available on the Linux platform" }, ; - { "OS2", "This is available on the OS/2 platform" }, ; - { "SUNOS", "This is available on the SunOS platform" }, ; - { "Unix", "This is available on the Unix platform(s)" }, ; - { "Win", "This is available on the Windows platform(s)" }, ; - { "WinCE", "This is available on the Windows CE platform" } ; - } - - PUBLIC p_aStatus := { ; - { "", "" }, ; - { "R", "Ready" }, ; - { "S", "Started" }, ; - { "N", "Not started" } ; - } - - PUBLIC p_aConversionList := { ; - "&", "amp", ; - '"', "quot", ; - "<", "lt", ; - ">", "gt" ; - } - - RETURN - -PROCEDURE ShowTemplatesHelp( cTemplate, cDelimiter ) - - LOCAL o := Entry():New() - LOCAL idxTemplates, nFrom := 1, nTo := Len( o:Templates ) - LOCAL idx - - IF ! Empty( cTemplate ) .AND. !( cTemplate == "Template" ) - IF o:IsTemplate( cTemplate ) - nFrom := nTo := AScan( o:Templates, {| a | Upper( a[ 1 ] ) == Upper( cTemplate ) } ) - ELSE - ShowHelp( "Unknown template '" + cTemplate + "'" ) - RETURN - ENDIF - ENDIF - - FOR idxTemplates := nFrom TO nTo - IF ! Empty( o:Templates[ idxTemplates ] ) .AND. ; - ! Empty( o:Templates[ idxTemplates ][ 1 ] ) .AND. ; - !( o:Templates[ idxTemplates ][ 1 ] == "Template" ) - -#if 0 - IF nFrom != nTo - ShowSubHelp( o:Templates[ idxTemplates ][ 1 ], 1, 0 ) - ENDIF -#endif - - o:SetTemplate( o:Templates[ idxTemplates ][ 1 ] ) - - FOR idx := 1 TO Len( o:Fields ) - IF o:Group[ idx ] != 0 - ShowSubHelp( iif( idx == 1, "/", " " ) + "* " + cDelimiter + o:Fields[ idx ][ 1 ] + cDelimiter, 1, 0 ) - IF o:Fields[ idx ][ 1 ] == "TEMPLATE" - ShowSubHelp( " * " + o:Template, 1, 0 ) - ELSEIF o:Group[ idx ] != TPL_START .AND. o:Group[ idx ] != TPL_END .AND. .T. - ShowSubHelp( " * " + iif( o:IsRequired( o:Fields[ idx ][ 1 ] ), "", "" ), 1, 0 ) - ENDIF - ENDIF - NEXT - ShowSubHelp( " */", 1, 0 ) - ShowSubHelp( "", 1, 0 ) - ENDIF - NEXT - - RETURN - -PROCEDURE ShowComplianceHelp() - - LOCAL idx - - FOR idx := 1 TO Len( p_aCompliance ) - ShowSubHelp( p_aCompliance[ idx ][ 1 ], 1, 0, idx ) - ShowSubHelp( Decode( "COMPLIANCE", NIL, p_aCompliance[ idx ][ 1 ] ), 1, 6, idx ) - ShowSubHelp( "", 1, 0 ) - NEXT - - RETURN - -PROCEDURE ShowPlatformsHelp - - LOCAL idx - - FOR idx := 1 TO Len( p_aPlatforms ) - ShowSubHelp( p_aPlatforms[ idx ][ 1 ], 1, 0, idx ) - ShowSubHelp( Decode( "PLATFORMS", NIL, p_aPlatforms[ idx ][ 1 ] ), 1, 6, idx ) - ShowSubHelp( "", 1, 0 ) - NEXT - - RETURN + hb_AScan( ::hConstraint[ "categories" ][ ::CategoryIndex( cCategory ) ][ 2 ], cSubcategory, , , .T. ) diff --git a/extras/hbdoc/hbdoc.ch b/extras/hbdoc/hbdoc.ch index 998103fff8..e755bbb39d 100644 --- a/extras/hbdoc/hbdoc.ch +++ b/extras/hbdoc/hbdoc.ch @@ -1,10 +1,8 @@ /* * Document generator include file * - * Copyright 2009 April White - * - * Portions of this project are based on hbdoc - * Copyright 1999-2003 Luiz Rafael Culik + * Copyright 2009 April White + * Copyright 1999-2003 Luiz Rafael Culik (Portions of this project are based on hbdoc) * * 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 @@ -50,16 +48,10 @@ #ifndef HBDOC_CH_ #define HBDOC_CH_ -MEMVAR p_aCategories -MEMVAR p_aCompliance -MEMVAR p_aPlatforms -MEMVAR p_aStatus -MEMVAR p_aConversionList - // Template definitions #define TPL_START 1 #define TPL_END 2 -#define TPL_REQUIRED 4 // intentially has a 'required' and 'optional' flag +#define TPL_REQUIRED 4 // intentionally has a 'required' and 'optional' flag #define TPL_OPTIONAL 8 #define TPL_PREFORMATTED 16 #define TPL_CONSTRAINTLIST 32 diff --git a/extras/hbdoc/hbdoc.css b/extras/hbdoc/hbdoc.css index ab6d7868a7..c8f06885cd 100644 --- a/extras/hbdoc/hbdoc.css +++ b/extras/hbdoc/hbdoc.css @@ -1,44 +1,40 @@ -/* Harbour Documentation Stylesheet */ - -@charset "utf-8"; - body { - font-size: 14px; - font-family: arial; - line-height: 18px; + font-family: Arial, sans-serif; + font-size: 14px; + line-height: 18px; } .name { - margin-left: 0; - padding-top: 0; - padding-bottom: 4px; - font-weight: bold; - font-size: 18px; + font-size: 18px; + font-weight: bold; + margin-left: 0; + padding-top: 0; + padding-bottom: 4px; } .oneliner { - margin-bottom: 12px; - font-style: italic; + font-style: italic; + margin-bottom: 12px; } .itemtitle { - margin-left: 0; - padding-top: 0; - padding-bottom: 4px; - font-weight: bold; + font-weight: bold; + margin-left: 0; + padding-top: 0; + padding-bottom: 4px; } .itemtext { - margin-left: 10px; - padding-bottom: 4px; + margin-left: 10px; + padding-bottom: 4px; } .examples { - margin-left: 10px; - padding-bottom: 4px; + margin-left: 10px; + padding-bottom: 4px; } .tests { - margin-left: 10px; - padding-bottom: 4px; + margin-left: 10px; + padding-bottom: 4px; } diff --git a/extras/hbdoc/hbdoc.hbp b/extras/hbdoc/hbdoc.hbp index 01bad27076..8251c2aa1d 100644 --- a/extras/hbdoc/hbdoc.hbp +++ b/extras/hbdoc/hbdoc.hbp @@ -1,5 +1,4 @@ --w3 -es2 --l +-w3 -es2 -kmo -l -o${hb_name} @@ -17,3 +16,10 @@ _tmplate.prg # NOTE: hbdoc doesn't work from other locations than # the current one, so we don't install it yet. # $hb_pkg_install.hbm + +# default -run params useful to update the online docs +# on the Harbour website +-runflag=-format=html +-runflag=-output-single + +{allgcc}-ldflag=-fno-lto diff --git a/extras/hbdoc/hbdoc.prg b/extras/hbdoc/hbdoc.prg index f842f133aa..afcd10f1ea 100644 --- a/extras/hbdoc/hbdoc.prg +++ b/extras/hbdoc/hbdoc.prg @@ -1,12 +1,8 @@ /* * Document generator * - * Copyright 2009 April White - * - * Portions of this project are based on hbdoc - * Copyright 1999-2003 Luiz Rafael Culik - * - * + * Copyright 2009 April White + * Copyright 1999-2003 Luiz Rafael Culik (Portions of this project are based on hbdoc) * * 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 @@ -49,9 +45,7 @@ * */ -/* - -todo +/* TODO: - handle preformatted text / code / etc - include links back to index - include jumps to 'top' @@ -60,34 +54,19 @@ todo - one method to retrieve, one to add? - key-value pair [hash table?] -todo - treat '' / as an non-conformance condition + TODO: - treat '' / as an non-conformance condition ntf: this may be okay for EXAMPLES and TESTS but this is also used within other sections, much like -todo - look for embedded 'fixed' + TODO: - look for embedded 'fixed' -these files have - *..\..\doc\en\cmdline.txt txt\lineutility.txt - ..\..\doc\en\dbstrux.txt txt\dbstrux.txt - *..\..\doc\en\file.txt txt\file.txt - ..\..\doc\en\input.txt txt\input.txt - ..\..\doc\en\lang.txt txt\lang.txt - ..\..\doc\en\menu.txt txt\menu.txt - ..\..\doc\en\objfunc.txt txt\objfunc.txt - ..\..\doc\en\rdddb.txt txt\rdddb.txt - ..\..\doc\en\sayget.txt txt\sayget.txt - ..\..\doc\en\set.txt txt\set.txt - ..\..\doc\en\setmode.txt txt\setmode.txt - ..\..\doc\en\string.txt txt\string.txt - ..\..\doc\en\var.txt txt\var.txt - -done - recognize and accept ; see macro.txt output esp. hb_setmacro -done - list 'compliance' and 'platforms' within help -done - list 'category' and 'subcategory' types on help screen -done - load into memory (class and) method template -done - minimize these to the barest -done - build a list of 'categories' and validate against; see what 'classdoc' uses -done - validate sources against these templates + done - recognize and accept ; see macro.txt output esp. hb_setmacro + done - list 'compliance' and 'platforms' within help + done - list 'category' and 'subcategory' types on help screen + done - load into memory (class and) method template + done - minimize these to the barest + done - build a list of 'categories' and validate against; see what 'classdoc' uses + done - validate sources against these templates */ #include "directry.ch" @@ -99,20 +78,22 @@ done - validate sources against these templates ANNOUNCE HB_GTSYS REQUEST HB_GT_CGI_DEFAULT -#define BASE_DIR ".." + hb_ps() + ".." + hb_ps() +REQUEST HB_CODEPAGE_UTF8EX -#define OnOrOff( b ) iif( b, "excluded", "included" ) -#define YesOrNo( b ) iif( b, "yes", "no" ) -#define IsDefault( b ) iif( b, "; default", "" ) +#define BASE_DIR ".." + hb_ps() + ".." + hb_ps() + +#define OnOrOff( b ) iif( b, "excluded", "included" ) +#define YesOrNo( b ) iif( b, "yes", "no" ) +#define IsDefault( b ) iif( b, "; default", "" ) STATIC sc_aExclusions := { "class_tp.txt", "hdr_tpl.txt" } - -MEMVAR p_hsSwitches +STATIC sc_hConstraint +STATIC s_hSwitches PROCEDURE Main( ... ) LOCAL aArgs := hb_AParams() - LOCAL idx, idx2, idx3, idx4 + LOCAL idx, idx2, item, item4 LOCAL arg LOCAL cArgName LOCAL cFormat @@ -128,7 +109,7 @@ PROCEDURE Main( ... ) init_Templates() - PUBLIC p_hsSwitches := { ; + s_hSwitches := { ; /* configuration settings, values, etc */ ; "basedir" => BASE_DIR, ; "doc" => .T., ; @@ -147,11 +128,11 @@ PROCEDURE Main( ... ) "not in hbextern" => {}, ; "" => NIL } - // remove formats that have not been implemented yet - FOR idx := Len( p_hsSwitches[ "format-list" ] ) TO 1 STEP -1 - IF p_hsSwitches[ "format-list" ][ idx ] == "all" - ELSEIF ! hb_IsFunction( "Generate" + p_hsSwitches[ "format-list" ][ idx ] ) - hb_ADel( p_hsSwitches[ "format-list" ], idx, .T. ) + /* remove formats that have not been implemented yet */ + FOR EACH item IN s_hSwitches[ "format-list" ] DESCEND + IF item == "all" + ELSEIF ! hb_IsFunction( "Generate" + item ) + hb_ADel( item:__enumBase(), item:__enumIndex(), .T. ) ENDIF NEXT @@ -171,55 +152,53 @@ PROCEDURE Main( ... ) ENDIF DO CASE - CASE cArgName == "-source" ; p_hsSwitches[ "basedir" ] := arg + iif( Right( arg, 1 ) == hb_ps(), "", hb_ps() ) + CASE cArgName == "-source" ; s_hSwitches[ "basedir" ] := hb_DirSepAdd( arg ) CASE cArgName == "-format" - IF arg == "" .OR. hb_AScan( p_hsSwitches[ "format-list" ], arg, , , .T. ) == 0 - ShowHelp( "Unknown format option '" + arg + "'" ) + IF arg == "" .OR. hb_AScan( s_hSwitches[ "format-list" ], arg, , , .T. ) == 0 + ShowHelp( "Unrecognized format option '" + arg + "'" ) RETURN + ELSEIF arg == "all" + s_hSwitches[ "format" ] := s_hSwitches[ "format-list" ] ELSE - IF arg == "all" - p_hsSwitches[ "format" ] := p_hsSwitches[ "format-list" ] - ELSE - AAdd( p_hsSwitches[ "format" ], arg ) - ENDIF + AAdd( s_hSwitches[ "format" ], arg ) ENDIF - CASE cArgName == "-output-single" ; p_hsSwitches[ "output" ] := "single" - CASE cArgName == "-output-category" ; p_hsSwitches[ "output" ] := "category" - CASE cArgName == "-output-entry" ; p_hsSwitches[ "output" ] := "entry" - CASE cArgName == "-include-doc-source" ; p_hsSwitches[ "include-doc-source" ] := .T. - CASE cArgName == "-include-doc-version" ; p_hsSwitches[ "include-doc-version" ] := .T. + CASE cArgName == "-output-single" ; s_hSwitches[ "output" ] := "single" + CASE cArgName == "-output-category" ; s_hSwitches[ "output" ] := "category" + CASE cArgName == "-output-entry" ; s_hSwitches[ "output" ] := "entry" + CASE cArgName == "-include-doc-source" ; s_hSwitches[ "include-doc-source" ] := .T. + CASE cArgName == "-include-doc-version" ; s_hSwitches[ "include-doc-version" ] := .T. OTHERWISE - IF hb_AScan( p_hsSwitches[ "format-list" ], SubStr( cArgName, 2 ), , , .T. ) > 0 + IF hb_AScan( s_hSwitches[ "format-list" ], SubStr( cArgName, 2 ), , , .T. ) > 0 IF SubStr( cArgName, 2 ) == "all" - p_hsSwitches[ "format" ] := p_hsSwitches[ "format-list" ] + s_hSwitches[ "format" ] := s_hSwitches[ "format-list" ] ELSE - AAdd( p_hsSwitches[ "format" ], SubStr( cArgName, 2 ) ) + AAdd( s_hSwitches[ "format" ], SubStr( cArgName, 2 ) ) ENDIF ELSE - ShowHelp( "Unknown option:" + cArgName + iif( Len( arg ) > 0, "=" + arg, "" ) ) + ShowHelp( "Unrecognized option:" + cArgName + iif( Len( arg ) > 0, "=" + arg, "" ) ) RETURN ENDIF ENDCASE ENDIF NEXT - // load hbextern.ch - FileEval( p_hsSwitches[ "basedir" ] + "include" + hb_ps() + "hbextern.ch", ; - {| c | iif( Left( c, Len( "EXTERNAL " ) ) == "EXTERNAL ", ; - AAdd( p_hsSwitches[ "hbextern.ch" ], SubStr( c, Len( "EXTERNAL " ) + 1 ) ), ; + /* load hbextern.ch */ + FileEval( s_hSwitches[ "basedir" ] + "include" + hb_ps() + "hbextern.ch", ; + {| c | iif( hb_LeftEq( c, "EXTERNAL " ), ; + AAdd( s_hSwitches[ "hbextern.ch" ], SubStr( c, Len( "EXTERNAL " ) + 1 ) ), ; ) } ) - ASort( p_hsSwitches[ "hbextern.ch" ] ) + ASort( s_hSwitches[ "hbextern.ch" ] ) aContent := {} AEval( ; {; - p_hsSwitches[ "basedir" ] + "doc" + hb_ps() + "en", ; - iif( p_hsSwitches[ "source" ], p_hsSwitches[ "basedir" ] + "src", NIL ), ; - iif( p_hsSwitches[ "contribs" ], p_hsSwitches[ "basedir" ] + "contrib", NIL ), ; + s_hSwitches[ "basedir" ] + "doc" + hb_ps() + "en", ; + iif( s_hSwitches[ "source" ], s_hSwitches[ "basedir" ] + "src", NIL ), ; + iif( s_hSwitches[ "contribs" ], s_hSwitches[ "basedir" ] + "contrib", NIL ), ; }, ; - {| c | iif( ! Empty( c ), ProcessFolder( c, @aContent ), ) } ) + {| c | iif( Empty( c ),, ProcessDir( c, @aContent ) ) } ) - OutStd( hb_ntos( Len( aContent ) ) + " items found" + hb_eol() ) + OutStd( hb_ntos( Len( aContent ) ), "items found" + hb_eol() ) OutStd( hb_eol() ) ASort( aContent, , , {| oL, oR | ; @@ -228,138 +207,138 @@ PROCEDURE Main( ... ) hb_ntos( oR:CategoryIndex( oR:Category ) ) + " " + hb_ntos( oR:SubcategoryIndex( oR:Category, oR:Subcategory ) ) + Chr( 1 ) + oR:Name + " " ; } ) - // TODO: what is this for? it is sorting the category sub-arrays and removing empty (?) sub-arrays, but why? - FOR idx := 1 TO Len( p_aCategories ) - IF ! Empty( p_aCategories[ idx ] ) - IF Len( p_aCategories[ idx ] ) == 4 // category, list of subcategory, list of entries, handle - FOR idx2 := Len( p_aCategories[ idx ][ 3 ] ) TO 1 STEP -1 - IF HB_ISARRAY( p_aCategories[ idx ][ 3 ][ idx2 ] ) - ASort( p_aCategories[ idx ][ 3 ][ idx2 ], , , ; + /* TODO: what is this for? it is sorting the category sub-arrays and removing empty (?) sub-arrays, but why? */ + FOR EACH item IN sc_hConstraint[ "categories" ] + IF ! Empty( item ) + IF Len( item ) == 4 /* category, list of subcategory, list of entries, handle */ + FOR idx2 := Len( item[ 3 ] ) TO 1 STEP -1 + IF HB_ISARRAY( item[ 3 ][ idx2 ] ) + ASort( item[ 3 ][ idx2 ], , , ; {| oL, oR | ; hb_ntos( oL:CategoryIndex( oL:Category ) ) + " " + hb_ntos( oL:SubcategoryIndex( oL:Category, oL:Subcategory ) ) + " " + oL:Name ; <= ; hb_ntos( oR:CategoryIndex( oR:Category ) ) + " " + hb_ntos( oR:SubcategoryIndex( oR:Category, oR:Subcategory ) ) + " " + oR:Name ; } ) ELSE - hb_ADel( p_aCategories[ idx ][ 2 ], idx2, .T. ) - hb_ADel( p_aCategories[ idx ][ 3 ], idx2, .T. ) + hb_ADel( item[ 2 ], idx2, .T. ) + hb_ADel( item[ 3 ], idx2, .T. ) ENDIF NEXT ELSE - OutStd( "Index", idx, " is not length 4 but rather", Len( p_aCategories[ idx ] ), hb_eol() ) + OutStd( "Index", item:__enumIndex(), "is not length 4 but rather", Len( item ), hb_eol() ) ENDIF ENDIF NEXT - IF Len( p_hsSwitches[ "format" ] ) == 0 - p_hsSwitches[ "format" ] := { "text" } + IF Len( s_hSwitches[ "format" ] ) == 0 + s_hSwitches[ "format" ] := { "text" } ENDIF - FOR idx2 := 1 TO Len( p_hsSwitches[ "format" ] ) - cFormat := p_hsSwitches[ "format" ][ idx2 ] + FOR EACH cFormat IN s_hSwitches[ "format" ] IF !( cFormat == "all" ) - OutStd( "Output as " + cFormat + hb_eol() ) + OutStd( "Output as", cFormat + hb_eol() ) DO CASE - CASE p_hsSwitches[ "output" ] == "single" + CASE s_hSwitches[ "output" ] == "single" oDocument := &( "Generate" + cFormat + "()" ):NewDocument( cFormat, "harbour", "Harbour Reference Guide" ) - FOR idx := 1 TO Len( aContent ) - IF Right( aContent[ idx ]:sourcefile_, Len( "1stread.txt" ) ) == "1stread.txt" - oDocument:AddEntry( aContent[ idx ] ) - idx := Len( aContent ) + FOR EACH item IN aContent + IF Right( item:sourcefile_, Len( "1stread.txt" ) ) == "1stread.txt" + oDocument:AddEntry( item ) + EXIT ENDIF NEXT - FOR idx := 1 TO Len( aContent ) - IF !( Right( aContent[ idx ]:sourcefile_, Len( "1stread.txt" ) ) == "1stread.txt" ) - oDocument:AddEntry( aContent[ idx ] ) + FOR EACH item IN aContent + IF !( Right( item:sourcefile_, Len( "1stread.txt" ) ) == "1stread.txt" ) + oDocument:AddEntry( item ) ENDIF NEXT oDocument:Generate() oDocument := NIL - CASE p_hsSwitches[ "output" ] == "category" + CASE s_hSwitches[ "output" ] == "category" oIndex := &( "Generate" + cFormat + "()" ):NewIndex( cFormat, "harbour", "Harbour Reference Guide" ) - FOR idx := 1 TO Len( aContent ) - IF Right( aContent[ idx ]:sourcefile_, Len( "1stread.txt" ) ) == "1stread.txt" + FOR EACH item IN aContent + IF Right( item:sourcefile_, Len( "1stread.txt" ) ) == "1stread.txt" IF oIndex != NIL - oIndex:AddEntry( aContent[ idx ] ) + oIndex:AddEntry( item ) ENDIF - idx := Len( aContent ) + EXIT ENDIF NEXT - FOR idx3 := 1 TO Len( p_aCategories ) - IF ! Empty( p_aCategories[ idx3 ] ) - p_aCategories[ idx3 ][ 4 ] := Filename( p_aCategories[ idx3 ][ 1 ] ) - // ~ oIndex:BeginSection( p_aCategories[ idx3 ][ 1 ], p_aCategories[ idx3 ][ 4 ] ) - // ~ oIndex:EndSection( p_aCategories[ idx3 ][ 1 ], p_aCategories[ idx3 ][ 4 ] ) + FOR EACH item IN sc_hConstraint[ "categories" ] + IF ! Empty( item ) + item[ 4 ] := Filename( item[ 1 ] ) +#if 0 + oIndex:BeginSection( item[ 1 ], item[ 4 ] ) + oIndex:EndSection( item[ 1 ], item[ 4 ] ) +#endif ENDIF NEXT - FOR idx3 := 1 TO Len( p_aCategories ) - IF ! Empty( p_aCategories[ idx3 ] ) - oDocument := &( "Generate" + cFormat + "()" ):NewDocument( cFormat, p_aCategories[ idx3 ][ 4 ], "Harbour Reference Guide - " + p_aCategories[ idx3 ][ 1 ] ) + FOR EACH item IN sc_hConstraint[ "categories" ] + IF ! Empty( item ) + oDocument := &( "Generate" + cFormat + "()" ):NewDocument( cFormat, item[ 4 ], "Harbour Reference Guide - " + item[ 1 ] ) IF oIndex != NIL - oIndex:BeginSection( p_aCategories[ idx3 ][ 1 ], oDocument:cFilename ) + oIndex:BeginSection( item[ 1 ], oDocument:cFilename ) ENDIF - oDocument:BeginSection( p_aCategories[ idx3 ][ 1 ], oDocument:cFilename ) + oDocument:BeginSection( item[ 1 ], oDocument:cFilename ) - FOR idx := 1 TO Len( p_aCategories[ idx3 ][ 3 ] ) - IF ! Empty( p_aCategories[ idx3 ][ 3 ][ idx ] ) - ASort( p_aCategories[ idx3 ][ 3 ][ idx ], , , {| oL, oR | oL:Name <= oR:Name } ) - IF Len( p_aCategories[ idx3 ][ 2 ][ idx ] ) > 1 .OR. Len( p_aCategories[ idx3 ][ 2 ][ idx ] ) > 0 + FOR idx := 1 TO Len( item[ 3 ] ) + IF ! Empty( item[ 3 ][ idx ] ) + ASort( item[ 3 ][ idx ], , , {| oL, oR | oL:Name <= oR:Name } ) + IF Len( item[ 2 ][ idx ] ) > 1 .OR. Len( item[ 2 ][ idx ] ) > 0 IF oIndex != NIL - oIndex:BeginSection( p_aCategories[ idx3 ][ 2 ][ idx ], oDocument:cFilename ) + oIndex:BeginSection( item[ 2 ][ idx ], oDocument:cFilename ) ENDIF - oDocument:BeginSection( p_aCategories[ idx3 ][ 2 ][ idx ], oDocument:cFilename ) + oDocument:BeginSection( item[ 2 ][ idx ], oDocument:cFilename ) ENDIF - FOR idx4 := 1 TO Len( p_aCategories[ idx3 ][ 3 ][ idx ] ) - IF ! Empty( p_aCategories[ idx3 ][ 3 ][ idx ][ idx4 ] ) - IF Right( p_aCategories[ idx3 ][ 3 ][ idx ][ idx4 ]:sourcefile_, Len( "1stread.txt" ) ) == "1stread.txt" - ELSE + FOR EACH item4 IN item[ 3 ][ idx ] + IF ! Empty( item4 ) + IF !( Right( item4:sourcefile_, Len( "1stread.txt" ) ) == "1stread.txt" ) IF oIndex != NIL - oIndex:AddReference( p_aCategories[ idx3 ][ 3 ][ idx ][ idx4 ] ) + oIndex:AddReference( item4 ) ENDIF - oDocument:AddEntry( p_aCategories[ idx3 ][ 3 ][ idx ][ idx4 ] ) + oDocument:AddEntry( item4 ) IF oIndex != NIL oDocument:AddReference( "Index", oIndex:cFilename ) - // this kind of works; the reference is outputed but it is not what I meant - oDocument:AddReference( p_aCategories[ idx3 ][ 1 ], oIndex:cFilename, p_aCategories[ idx3 ][ 4 ] ) + /* this kind of works; the reference is outputed but it is not what I meant */ + oDocument:AddReference( item[ 1 ], oIndex:cFilename, item[ 4 ] ) ENDIF ENDIF ENDIF NEXT - IF Len( p_aCategories[ idx3 ][ 2 ][ idx ] ) > 1 .OR. Len( p_aCategories[ idx3 ][ 2 ][ idx ] ) > 0 + IF Len( item[ 2 ][ idx ] ) > 1 .OR. Len( item[ 2 ][ idx ] ) > 0 IF oIndex != NIL - oIndex:EndSection( p_aCategories[ idx3 ][ 2 ][ idx ], oDocument:cFilename ) + oIndex:EndSection( item[ 2 ][ idx ], oDocument:cFilename ) ENDIF - oDocument:EndSection( p_aCategories[ idx3 ][ 2 ][ idx ], oDocument:cFilename ) + oDocument:EndSection( item[ 2 ][ idx ], oDocument:cFilename ) ENDIF ENDIF NEXT IF oIndex != NIL - oIndex:EndSection( p_aCategories[ idx3 ][ 1 ], oDocument:cFilename ) + oIndex:EndSection( item[ 1 ], oDocument:cFilename ) ENDIF - oDocument:EndSection( p_aCategories[ idx3 ][ 1 ], oDocument:cFilename ) + oDocument:EndSection( item[ 1 ], oDocument:cFilename ) oDocument:Generate() ENDIF NEXT - CASE p_hsSwitches[ "output" ] == "entry" + CASE s_hSwitches[ "output" ] == "entry" - FOR idx := 1 TO Len( aContent ) - oDocument := &( "Generate" + cFormat + "()" ):NewDocument( cFormat, aContent[ idx ]:filename, "Harbour Reference Guide" ) + FOR EACH item IN aContent + oDocument := &( "Generate" + cFormat + "()" ):NewDocument( cFormat, item:filename, "Harbour Reference Guide" ) IF oIndex != NIL - oIndex:AddEntry( aContent[ idx ] ) + oIndex:AddEntry( item ) ENDIF - oDocument:AddEntry( aContent[ idx ] ) + oDocument:AddEntry( item ) oDocument:Generate() NEXT @@ -379,69 +358,63 @@ PROCEDURE Main( ... ) RETURN -STATIC PROCEDURE ProcessFolder( cFolder, aContent ) // this is a recursive procedure +STATIC PROCEDURE ProcessDir( cDir, aContent ) /* this is a recursive procedure */ - LOCAL aFiles - LOCAL nLen - LOCAL idx - LOCAL cExt + LOCAL file - // ~ OutStd( ">>> " + cFolder + hb_eol() ) +#if 0 + OutStd( ">>> " + cDir + hb_eol() ) +#endif - cFolder += hb_ps() + cDir += hb_ps() - aFiles := Directory( cFolder + hb_osFileMask(), "D" ) - IF ( nLen := Len( aFiles ) ) > 0 - FOR idx := 1 TO nLen - IF aFiles[ idx ][ F_ATTR ] == "D" - IF !( aFiles[ idx ][ F_NAME ] == "." ) .AND. ; - !( aFiles[ idx ][ F_NAME ] == ".." ) + FOR EACH file IN hb_vfDirectory( cDir + hb_osFileMask(), "D" ) + IF file[ F_ATTR ] == "D" + IF !( file[ F_NAME ] == "." ) .AND. ; + !( file[ F_NAME ] == ".." ) - IF p_hsSwitches[ "source" ] .OR. p_hsSwitches[ "contribs" ] - /* .AND. AScan( s_aSkipDirs, {| d | Lower( d ) == Lower( aFiles[ idx ][ F_NAME ] ) } ) == 0 */ - ProcessFolder( cFolder + aFiles[ idx ][ F_NAME ], @aContent ) - ENDIF - ENDIF - ELSEIF AScan( sc_aExclusions, {| f | Lower( f ) == Lower( aFiles[ idx ][ F_NAME ] ) } ) == 0 - hb_FNameSplit( aFiles[ idx ][ F_NAME ], , , @cExt ) - IF Lower( cExt ) == ".txt" - IF ! ProcessFile( cFolder + aFiles[ idx ][ F_NAME ], @aContent ) - EXIT - ENDIF + IF s_hSwitches[ "source" ] .OR. s_hSwitches[ "contribs" ] + /* .AND. hb_AScanI( s_aSkipDirs, file[ F_NAME ],,, .T. ) == 0 */ + ProcessDir( cDir + file[ F_NAME ], @aContent ) ENDIF ENDIF - NEXT - ENDIF + ELSEIF hb_AScanI( sc_aExclusions, file[ F_NAME ],,, .T. ) == 0 + IF Lower( hb_FNameExt( file[ F_NAME ] ) ) == ".txt" .AND. ; + ! ProcessFile( cDir + file[ F_NAME ], @aContent ) + EXIT + ENDIF + ENDIF + NEXT RETURN STATIC FUNCTION ProcessFile( cFile, aContent ) - LOCAL aHandle := { F_ERROR, 0 } // file handle and position + LOCAL aHandle := { NIL, 0 } /* file handle and position */ LOCAL cSectionName LOCAL cVersion LOCAL o LOCAL nOldContentLen := Len( aContent ) - IF ( aHandle[ 1 ] := FOpen( cFile ) ) == F_ERROR - OutErr( "error: could not open " + cFile + ", " + hb_ntos( aHandle[ 1 ] ) + hb_eol() ) + IF ( aHandle[ 1 ] := hb_vfOpen( cFile, FO_READ ) ) == NIL + OutErr( "error: could not open", cFile + hb_eol() ) RETURN .F. ENDIF cVersion := "" - o := Entry():New( "Template" ) + o := Entry():New( "Template", sc_hConstraint ) DO WHILE FReadSection( aHandle, @cSectionName, , o ) IF o:IsField( @cSectionName, TPL_START ) - o := Entry():New( "Template" ) + o := Entry():New( "Template", sc_hConstraint ) ProcessBlock( aHandle, @aContent, cFile, cSectionName, @cVersion, @o ) ENDIF ENDDO - FClose( aHandle[ 1 ] ) + hb_vfClose( aHandle[ 1 ] ) - IF ( Len( aContent ) - nOldContentLen ) > 0 - OutStd( "> " + cFile + " (" + hb_ntos( Len( aContent ) - nOldContentLen ) + " items)" + hb_eol() ) + IF Len( aContent ) > nOldContentLen + OutStd( ">", cFile, "(" + hb_ntos( Len( aContent ) - nOldContentLen ), "items)" + hb_eol() ) ENDIF RETURN .T. @@ -456,7 +429,7 @@ STATIC PROCEDURE ProcessBlock( aHandle, aContent, cFile, cType, cVersion, o ) LOCAL idxSubCategory := -1 LOCAL cSourceFile - cSourceFile := StrTran( ".." + hb_ps() + cFile /* SubStr( cFile, Len( p_hsSwitches[ "basedir" ] + hb_ps() ) ) */, iif( hb_ps() == "\", "/", "\" ), hb_ps() ) + cSourceFile := StrTran( ".." + hb_ps() + cFile /* SubStr( cFile, Len( s_hSwitches[ "basedir" ] + hb_ps() ) ) */, iif( hb_ps() == "\", "/", "\" ), hb_ps() ) o:type_ := cType o:sourcefile_ := cSourceFile @@ -466,130 +439,136 @@ STATIC PROCEDURE ProcessBlock( aHandle, aContent, cFile, cType, cVersion, o ) DO WHILE FReadSection( aHandle, @cSectionName, @cSection, @o ) - DO CASE - CASE cSectionName == "TEMPLATE" + IF cSectionName == "TEMPLATE" IF o:IsTemplate( cSection ) o:SetTemplate( cSection ) ELSE - AddErrorCondition( cFile, "Unknown TEMPLATE '" + cSection + "'" ) // + "' (line " + hb_ntos( aHandle[ 2 ] ) + ")" // exclude link number, it reports tonnes of entries + AddErrorCondition( cFile, "Unrecognized TEMPLATE '" + cSection + "'" ) // + "' (line " + hb_ntos( aHandle[ 2 ] ) + ")" // exclude link number, it reports tonnes of entries lAccepted := .F. EXIT ENDIF - OTHERWISE + ELSEIF HB_ISNULL( cSectionName ) - IF Len( cSectionName ) == 0 + ELSEIF o:IsField( cSectionName ) - ELSEIF o:IsField( cSectionName ) + DO CASE + CASE o:IsField( cSectionName, TPL_START ) - DO CASE - CASE o:IsField( cSectionName, TPL_START ) + AddErrorCondition( cFile, "Encountered another section '" + cSection, aHandle[ 2 ] ) + lAccepted := .F. + EXIT - AddErrorCondition( cFile, "Encountered another section '" + cSection, aHandle[ 2 ] ) - lAccepted := .F. - EXIT + CASE o:IsField( cSectionName, TPL_END ) - CASE o:IsField( cSectionName, TPL_END ) + EXIT - EXIT + CASE ! Empty( o:&cSectionName ) - CASE ! Empty( o:&cSectionName ) - - AddErrorCondition( cFile, "Duplicate " + cSectionName, aHandle[ 2 ] ) - lAccepted := .F. - - CASE cSectionName == "CATEGORY" - - IF ( idxCategory := AScan( p_aCategories, {| c | ! Empty( c ) .AND. ( iif( HB_ISCHAR( c ), Lower( c ) == Lower( cSection ), Lower( c[ 1 ] ) == Lower( cSection ) ) ) } ) ) == 0 - AddErrorCondition( cFile, "Unknown CATEGORY '" + cSection + "' for template '" + o:Template, aHandle[ 2 ] ) - // lAccepted := .F. - ENDIF - - CASE cSectionName == "SUBCATEGORY" .AND. o:IsField( "SUBCATEGORY" ) - - IF idxCategory <= 0 .OR. o:Category == "" - - AddErrorCondition( cFile, "SUBCATEGORY '" + cSection + "' defined before CATEGORY", aHandle[ 2 ] ) - // lAccepted := .F. - - ELSEIF ( idxSubCategory := AScan( p_aCategories[ idxCategory ][ 2 ], {| c | c != NIL .AND. ( iif( HB_ISCHAR( c ), Lower( c ) == Lower( cSection ), Lower( c[ 1 ] ) == Lower( cSection ) ) ) } ) ) == 0 - - AddErrorCondition( cFile, "Unknown SUBCATEGORY '" + p_aCategories[ idxCategory ][ 1 ] + "-" + cSection, aHandle[ 2 ] ) - // lAccepted := .F. - - ENDIF - - CASE o:IsField( "RETURNS" ) .AND. cSectionName == "RETURNS" .AND. ( ; - Empty( cSection ) .OR. ; - Lower( cSection ) == "nil" .OR. ; - Lower( cSection ) == "none" .OR. ; - Lower( cSection ) == "none." ) - - AddErrorCondition( cFile, "'" + o:Name + "' is identified as template " + o:Template + " but has no RETURNS value (" + cSection + ")", aHandle[ 2 ] - 1 ) - // lAccepted := .F. - - CASE ! o:IsConstraint( cSectionName, cSection ) - - cSource := cSectionName + " is '" + iif( Len( cSection ) <= 20, cSection, Left( StrTran( cSection, hb_eol() ), 20 ) + "..." ) + "', should be one of: " - // ~ cSource := hb_HKeyAt( hsTemplate, idx ) + " should be one of: " - AEval( &( "p_a" + cSectionName ), {| c, n | cSource += iif( n == 1, "", "," ) + c } ) - AddErrorCondition( cFile, cSource, aHandle[ 2 ] - 1 ) - - OTHERWISE - - ENDCASE - - IF lAccepted - o:&cSectionName := Decode( cSectionName, , cSection ) - ENDIF - - ELSE - - AddErrorCondition( cFile, "Using template '" + o:Template + "' encountered an unexpected section '" + cSectionName, aHandle[ 2 ] ) + AddErrorCondition( cFile, "Duplicate " + cSectionName, aHandle[ 2 ] ) lAccepted := .F. + CASE cSectionName == "CATEGORY" + + IF ( idxCategory := AScan( sc_hConstraint[ "categories" ], {| c | ! Empty( c ) .AND. iif( HB_ISCHAR( c ), Lower( c ) == Lower( cSection ), Lower( c[ 1 ] ) == Lower( cSection ) ) } ) ) == 0 + AddErrorCondition( cFile, "Unrecognized CATEGORY '" + cSection + "' for template '" + o:Template, aHandle[ 2 ] ) +#if 0 + lAccepted := .F. +#endif + ENDIF + + CASE cSectionName == "SUBCATEGORY" .AND. o:IsField( "SUBCATEGORY" ) + + IF idxCategory <= 0 .OR. o:Category == "" + + AddErrorCondition( cFile, "SUBCATEGORY '" + cSection + "' defined before CATEGORY", aHandle[ 2 ] ) +#if 0 + lAccepted := .F. +#endif + + ELSEIF ( idxSubCategory := AScan( sc_hConstraint[ "categories" ][ idxCategory ][ 2 ], {| c | c != NIL .AND. iif( HB_ISCHAR( c ), Lower( c ) == Lower( cSection ), Lower( c[ 1 ] ) == Lower( cSection ) ) } ) ) == 0 + + AddErrorCondition( cFile, "Unrecognized SUBCATEGORY '" + sc_hConstraint[ "categories" ][ idxCategory ][ 1 ] + "-" + cSection, aHandle[ 2 ] ) +#if 0 + lAccepted := .F. +#endif + + ENDIF + + CASE o:IsField( "RETURNS" ) .AND. cSectionName == "RETURNS" .AND. ( ; + Empty( cSection ) .OR. ; + Lower( cSection ) == "nil" .OR. ; + Lower( cSection ) == "none" .OR. ; + Lower( cSection ) == "none." ) + + AddErrorCondition( cFile, "'" + o:Name + "' is identified as template " + o:Template + " but has no RETURNS value (" + cSection + ")", aHandle[ 2 ] - 1 ) +#if 0 + lAccepted := .F. +#endif + + CASE ! o:IsConstraint( cSectionName, cSection ) + + cSource := cSectionName + " is '" + iif( Len( cSection ) <= 20, cSection, Left( StrTran( cSection, hb_eol() ), 20 ) + "..." ) + "', should be one of: " +#if 0 + cSource := hb_HKeyAt( hsTemplate, idx ) + " should be one of: " +#endif + AEval( sc_hConstraint[ cSectionName ], {| c, n | cSource += iif( n == 1, "", "," ) + c } ) + AddErrorCondition( cFile, cSource, aHandle[ 2 ] - 1 ) + + OTHERWISE + + ENDCASE + + IF lAccepted + o:&cSectionName := Decode( cSectionName, , cSection ) ENDIF - ENDCASE + ELSE + AddErrorCondition( cFile, "Using template '" + o:Template + "' encountered an unexpected section '" + cSectionName, aHandle[ 2 ] ) + lAccepted := .F. + ENDIF ENDDO - IF lAccepted - IF ! o:IsComplete( @cSource ) - AddErrorCondition( cFile, "Missing sections: '" + cSource + "'", aHandle[ 2 ] ) - // lAccepted := .F. - ENDIF + IF lAccepted .AND. ! o:IsComplete( @cSource ) + AddErrorCondition( cFile, "Missing sections: '" + cSource + "'", aHandle[ 2 ] ) +#if 0 + lAccepted := .F. +#endif ENDIF IF ! lAccepted ELSEIF o:Template == "Function" .AND. ( ; - Empty( o:Returns ) .OR. ; - Lower( o:Returns ) == "nil" .OR. ; - Lower( o:Returns ) == "none" .OR. ; - Lower( o:Returns ) == "none." ) + Empty( o:Returns ) .OR. ; + Lower( o:Returns ) == "nil" .OR. ; + Lower( o:Returns ) == "none" .OR. ; + Lower( o:Returns ) == "none." ) AddErrorCondition( cFile, "'" + o:Name + "' is identified as template " + o:Template + " but has no RETURNS value (" + o:Returns + ")", aHandle[ 2 ] ) - // ~ lAccepted := .F. +#if 0 + lAccepted := .F. +#endif ELSE - IF ! ( ; + IF !( ; /* Lower( hsBlock[ "CATEGORY" ] ) == "document" .OR. */ ; /* ! ( hsBlock[ "SUBCODE" ] == "" ) .OR. */ ; .F. ) cSectionName := Parse( Upper( o:Name ), "(" ) - IF hb_AScan( p_hsSwitches[ "hbextern.ch" ], cSectionName, , , .T. ) > 0 - AAdd( p_hsSwitches[ "in hbextern" ], cSectionName ) + IF hb_AScan( s_hSwitches[ "hbextern.ch" ], cSectionName, , , .T. ) > 0 + AAdd( s_hSwitches[ "in hbextern" ], cSectionName ) ELSE - AAdd( p_hsSwitches[ "not in hbextern" ], cSectionName + "; " + cFile ) + AAdd( s_hSwitches[ "not in hbextern" ], cSectionName + "; " + cFile ) ENDIF - // ~ OutStd( " > " + cSectionName + hb_eol() ) - +#if 0 + OutStd( " > " + cSectionName + hb_eol() ) +#endif ENDIF - IF p_hsSwitches[ "include-doc-source" ] - o:Files += hb_eol() + o:sourcefile_ + iif( p_hsSwitches[ "include-doc-version" ], " (" + o:sourcefileversion_ + ")", "" ) + IF s_hSwitches[ "include-doc-source" ] + o:Files += hb_eol() + o:sourcefile_ + iif( s_hSwitches[ "include-doc-version" ], " (" + o:sourcefileversion_ + ")", "" ) ENDIF o:filename := Filename( o:Name ) @@ -601,17 +580,16 @@ STATIC PROCEDURE ProcessBlock( aHandle, aContent, cFile, cType, cVersion, o ) ENDIF IF idxCategory > 0 .AND. idxSubCategory > 0 - IF ! HB_ISARRAY( p_aCategories[ idxCategory ][ 3 ][ idxSubCategory ] ) - p_aCategories[ idxCategory ][ 3 ][ idxSubCategory ] := {} + IF ! HB_ISARRAY( sc_hConstraint[ "categories" ][ idxCategory ][ 3 ][ idxSubCategory ] ) + sc_hConstraint[ "categories" ][ idxCategory ][ 3 ][ idxSubCategory ] := {} ENDIF - AAdd( p_aCategories[ idxCategory ][ 3 ][ idxSubCategory ], o ) + AAdd( sc_hConstraint[ "categories" ][ idxCategory ][ 3 ][ idxSubCategory ], o ) ENDIF - ENDIF RETURN -STATIC FUNCTION FReadSection( aHandle, cSectionName, cSection, o ) +STATIC FUNCTION FReadSection( aHandle, /* @ */ cSectionName, /* @ */ cSection, /* @ */ o ) LOCAL nPosition LOCAL cBuffer @@ -621,22 +599,22 @@ STATIC FUNCTION FReadSection( aHandle, cSectionName, cSection, o ) cSectionName := cSection := "" - IF FReadLn( @aHandle, @cSectionName ) + IF FReadLn( aHandle, @cSectionName ) cSectionName := LTrim( SubStr( cSectionName, 3 ) ) - IF Left( cSectionName, 1 ) == p_hsSwitches[ "DELIMITER" ] .AND. ; - Right( cSectionName, 1 ) == p_hsSwitches[ "DELIMITER" ] + IF Left( cSectionName, 1 ) == s_hSwitches[ "DELIMITER" ] .AND. ; + Right( cSectionName, 1 ) == s_hSwitches[ "DELIMITER" ] - cSectionName := SubStr( cSectionName, 1 + Len( p_hsSwitches[ "DELIMITER" ] ), Len( cSectionName ) - ( 2 * Len( p_hsSwitches[ "DELIMITER" ] ) ) ) + cSectionName := SubStr( cSectionName, 1 + Len( s_hSwitches[ "DELIMITER" ] ), Len( cSectionName ) - ( 2 * Len( s_hSwitches[ "DELIMITER" ] ) ) ) IF o:IsField( cSectionName ) lLastPreformatted := lPreformatted := o:IsPreformatted( cSectionName ) nLastIndent := -1 - DO WHILE ( nPosition := FSeek( aHandle[ 1 ], 0, FS_RELATIVE ) ), FReadLn( @aHandle, @cBuffer ) - // TOFIX: this assumes that every line starts with " *" + DO WHILE ( nPosition := hb_vfSeek( aHandle[ 1 ], 0, FS_RELATIVE ) ), FReadLn( aHandle, @cBuffer ) + /* TOFIX: this assumes that every line starts with " *" */ cBuffer := RTrim( SubStr( cBuffer, 3 ) ) - IF Left( LTrim( cBuffer ), 1 ) == p_hsSwitches[ "DELIMITER" ] .AND. ; - Right( cBuffer, 1 ) == p_hsSwitches[ "DELIMITER" ] - FSeek( aHandle[ 1 ], nPosition, FS_SET ) - aHandle[ 2 ]-- // decrement the line number when rewinding the file + IF Left( LTrim( cBuffer ), 1 ) == s_hSwitches[ "DELIMITER" ] .AND. ; + Right( cBuffer, 1 ) == s_hSwitches[ "DELIMITER" ] + hb_vfSeek( aHandle[ 1 ], nPosition, FS_SET ) + aHandle[ 2 ]-- /* decrement the line number when rewinding the file */ EXIT ELSEIF Len( AllTrim( cBuffer ) ) == 0 IF !( Right( cSection, Len( hb_eol() ) ) == hb_eol() ) @@ -658,7 +636,7 @@ STATIC FUNCTION FReadSection( aHandle, cSectionName, cSection, o ) lPreformatted := lLastPreformatted ELSEIF nLastIndent != ( Len( cBuffer ) - Len( LTrim( cBuffer ) ) ) .OR. lPreformatted .OR. Right( cBuffer, Len( "" ) ) == "" IF Right( cBuffer, Len( "" ) ) == "" - cBuffer := Left( cBuffer, Len( cBuffer ) - Len( "" ) ) + cBuffer := hb_StrShrink( cBuffer, Len( "" ) ) ENDIF nLastIndent := ( Len( cBuffer ) - Len( LTrim( cBuffer ) ) ) IF !( Right( cSection, Len( hb_eol() ) ) == hb_eol() ) @@ -670,24 +648,23 @@ STATIC FUNCTION FReadSection( aHandle, cSectionName, cSection, o ) ENDIF ENDDO ENDIF - ENDIF ELSE RETURN .F. ENDIF - DO WHILE Left( cSection, Len( hb_eol() ) ) == hb_eol() + DO WHILE hb_LeftEq( cSection, hb_eol() ) cSection := SubStr( cSection, Len( hb_eol() ) + 1 ) ENDDO DO WHILE Right( cSection, Len( hb_eol() ) ) == hb_eol() - cSection := Left( cSection, Len( cSection ) - Len( hb_eol() ) ) + cSection := hb_StrShrink( cSection, Len( hb_eol() ) ) ENDDO IF lPreformatted .AND. Lower( Right( cSection, Len( "" ) ) ) == "" - cSection := Left( cSection, Len( cSection ) - Len( "" ) ) + cSection := hb_StrShrink( cSection, Len( "" ) ) DO WHILE Right( cSection, Len( hb_eol() ) ) == hb_eol() - cSection := Left( cSection, Len( cSection ) - Len( hb_eol() ) ) + cSection := hb_StrShrink( cSection, Len( hb_eol() ) ) ENDDO ENDIF @@ -695,55 +672,51 @@ STATIC FUNCTION FReadSection( aHandle, cSectionName, cSection, o ) STATIC PROCEDURE FileEval( acFile, bBlock, nMaxLine ) - LOCAL aHandle := { F_ERROR, 0 } + LOCAL aHandle := { NIL, 0 } LOCAL cBuffer LOCAL lCloseFile := .F. - LOCAL xResult hb_default( @nMaxLine, 256 ) - IF HB_ISSTRING( acFile ) + DO CASE + CASE HB_ISSTRING( acFile ) lCloseFile := .T. - IF ( aHandle[ 1 ] := FOpen( acFile ) ) == F_ERROR + IF ( aHandle[ 1 ] := hb_vfOpen( acFile, FO_READ ) ) == NIL RETURN ENDIF - ELSEIF HB_ISNUMERIC( acFile ) - aHandle[ 1 ] := acFile - ELSE + OTHERWISE aHandle := acFile - ENDIF + ENDCASE - DO WHILE FReadLn( @aHandle, @cBuffer, nMaxLine ) - xResult := Eval( bBlock, cBuffer ) - IF xResult != NIL .AND. HB_ISLOGICAL( xResult ) .AND. ! xResult + DO WHILE FReadLn( aHandle, @cBuffer, nMaxLine ) + IF ! hb_defaultValue( Eval( bBlock, cBuffer ), .T. ) EXIT ENDIF ENDDO IF lCloseFile - FClose( aHandle ) + hb_vfClose( aHandle[ 1 ] ) ENDIF RETURN -STATIC FUNCTION FReadLn( aHandle, cBuffer, nMaxLine ) +STATIC FUNCTION FReadLn( aHandle, /* @ */ cBuffer, nMaxLine ) STATIC s_aEOL := { Chr( 13 ) + Chr( 10 ), Chr( 10 ), Chr( 13 ) } - LOCAL cLine, nSavePos, nEol, nNumRead, nLenEol, idx - hb_default( @nMaxLine, 256 ) + LOCAL cLine, nSavePos, nEol, nNumRead, nLenEol, cEOL cBuffer := "" - nSavePos := FSeek( aHandle[ 1 ], 0, FS_RELATIVE ) - cLine := Space( nMaxLine ) - nNumRead := FRead( aHandle[ 1 ], @cLine, hb_BLen( cLine ) ) + nSavePos := hb_vfSeek( aHandle[ 1 ], 0, FS_RELATIVE ) + cLine := Space( hb_defaultValue( nMaxLine, 256 ) ) + nNumRead := hb_vfRead( aHandle[ 1 ], @cLine, hb_BLen( cLine ) ) cLine := hb_BLeft( cLine, nNumRead ) nEol := 0 - FOR idx := 1 TO Len( s_aEOL ) - IF ( nEol := At( s_aEOL[ idx ], cLine ) ) > 0 - nLenEol := hb_BLen( s_aEOL[ idx ] ) - 1 + FOR EACH cEOL IN s_aEOL + IF ( nEol := hb_BAt( cEOL, cLine ) ) > 0 + nLenEol := hb_BLen( cEOL ) - 1 EXIT ENDIF NEXT @@ -751,91 +724,92 @@ STATIC FUNCTION FReadLn( aHandle, cBuffer, nMaxLine ) IF nEol == 0 cBuffer := cLine ELSE - cBuffer := Left( cLine, nEol - 1 ) - FSeek( aHandle[ 1 ], nSavePos + hb_BLen( cBuffer ) + 1 + nLenEol, FS_SET ) + cBuffer := hb_BLeft( cLine, nEol - 1 ) + hb_vfSeek( aHandle[ 1 ], nSavePos + hb_BLen( cBuffer ) + 1 + nLenEol, FS_SET ) ENDIF aHandle[ 2 ]++ - RETURN nNumRead != 0 + RETURN nNumRead > 0 -FUNCTION Decode( cType, hsBlock, cKey ) +STATIC FUNCTION Decode( cType, hsBlock, cKey ) LOCAL cCode LOCAL cResult LOCAL idx - IF cKey != NIL .AND. hsBlock != NIL .AND. hb_HHasKey( hsBlock, cKey ) + IF cKey != NIL .AND. HB_ISHASH( hsBlock ) .AND. cKey $ hsBlock cCode := hsBlock[ cKey ] ELSE cCode := cKey ENDIF - DO CASE - CASE cType == "STATUS" - IF "," $ cCode .AND. hb_AScan( p_aStatus, Parse( cCode, "," ), , , .T. ) > 0 + SWITCH cType + CASE "STATUS" + IF "," $ cCode .AND. hb_AScan( sc_hConstraint[ "status" ], Parse( cCode, "," ), , , .T. ) > 0 cResult := "" - DO WHILE Len( cCode ) > 0 + DO WHILE ! HB_ISNULL( cCode ) cResult += hb_eol() + Decode( cType, hsBlock, Parse( @cCode, "," ) ) ENDDO RETURN SubStr( cResult, Len( hb_eol() ) + 1 ) ENDIF - IF ( idx := AScan( p_aStatus, {| a | a[ 1 ] == cCode } ) ) > 0 - RETURN p_aStatus[ idx ][ 2 ] + IF ( idx := AScan( sc_hConstraint[ "status" ], {| a | a[ 1 ] == cCode } ) ) > 0 + RETURN sc_hConstraint[ "status" ][ idx ][ 2 ] ELSEIF Len( cCode ) > 1 RETURN cCode - ELSEIF Len( cCode ) > 0 - RETURN "Unknown 'STATUS' code: '" + cCode + "'" + ELSEIF ! HB_ISNULL( cCode ) + RETURN "Unrecognized 'STATUS' code: '" + cCode + "'" ELSE - RETURN ATail( p_aStatus )[ 2 ] + RETURN ATail( sc_hConstraint[ "status" ] )[ 2 ] ENDIF - CASE cType == "PLATFORMS" - IF "," $ cCode .AND. hb_AScan( p_aPlatforms, Parse( cCode, "," ), , , .T. ) > 0 + CASE "PLATFORMS" + IF "," $ cCode .AND. hb_AScan( sc_hConstraint[ "platforms" ], Parse( cCode, "," ), , , .T. ) > 0 cResult := "" - DO WHILE Len( cCode ) > 0 + DO WHILE ! HB_ISNULL( cCode ) cResult += hb_eol() + Decode( cType, hsBlock, Parse( @cCode, "," ) ) ENDDO RETURN SubStr( cResult, Len( hb_eol() ) + 1 ) ENDIF - IF ( idx := AScan( p_aPlatforms, {| a | a[ 1 ] == cCode } ) ) > 0 - RETURN p_aPlatforms[ idx ][ 2 ] + IF ( idx := AScan( sc_hConstraint[ "platforms" ], {| a | a[ 1 ] == cCode } ) ) > 0 + RETURN sc_hConstraint[ "platforms" ][ idx ][ 2 ] ELSE RETURN cCode ENDIF - CASE cType == "COMPLIANCE" - IF "," $ cCode .AND. hb_AScan( p_aCompliance, Parse( cCode, "," ), , , .T. ) > 0 + CASE "COMPLIANCE" + IF "," $ cCode .AND. hb_AScan( sc_hConstraint[ "compliance" ], Parse( cCode, "," ), , , .T. ) > 0 cResult := "" - DO WHILE Len( cCode ) > 0 + DO WHILE ! HB_ISNULL( cCode ) cResult += hb_eol() + Decode( cType, hsBlock, Parse( @cCode, "," ) ) ENDDO RETURN SubStr( cResult, Len( hb_eol() ) + 1 ) ENDIF - IF ( idx := AScan( p_aCompliance, {| a | a[ 1 ] == cCode } ) ) > 0 - RETURN p_aCompliance[ idx ][ 2 ] + IF ( idx := AScan( sc_hConstraint[ "compliance" ], {| a | a[ 1 ] == cCode } ) ) > 0 + RETURN sc_hConstraint[ "compliance" ][ idx ][ 2 ] ELSE RETURN cCode ENDIF - DO CASE - CASE cCode == "C" ; RETURN "This is CA-Cl*pper v5.2 compliant" - CASE cCode == "C(array)" ; RETURN "This is CA-Cl*pper v5.2 compliant except that arrays in Harbour can have an unlimited number of elements" - CASE cCode == "C(menu)" ; RETURN "This is CA-Cl*pper v5.2 compliant except that menus (internally arrays) in Harbour can have an unlimited number of elements" - CASE cCode == "C52U" ; RETURN "This is an undocumented CA-Cl*pper v5.2 function and is only visible if source was compiled with the HB_CLP_UNDOC flag" - CASE cCode == "C52S" ; RETURN "? verbage: This is an CA-Cl*pper v5.2 compliant and is only visible if source was compiled with the HB_CLP_STRICT flag" - CASE cCode == "C53" ; RETURN "This is CA-Cl*pper v5.3 compliant and is only visible if source was compiled with the HB_COMPAT_C53 flag" - CASE cCode == "H" ; RETURN "This is Harbour specific" - CASE cCode == "NA" ; RETURN "Not applicable" - OTHERWISE ; RETURN cCode - ENDCASE - CASE cType == "NAME" + SWITCH cCode + CASE "C" ; RETURN "This is CA-Cl*pper v5.2 compliant" + CASE "C(array)" ; RETURN "This is CA-Cl*pper v5.2 compliant except that arrays in Harbour can have an unlimited number of elements" + CASE "C(menu)" ; RETURN "This is CA-Cl*pper v5.2 compliant except that menus (internally arrays) in Harbour can have an unlimited number of elements" + CASE "C52U" ; RETURN "This is an undocumented CA-Cl*pper v5.2 function and is only visible if source was compiled with the HB_CLP_UNDOC flag" + CASE "C52S" ; RETURN "? verbage: This is an CA-Cl*pper v5.2 compliant and is only visible if source was compiled with the HB_CLP_STRICT flag" + CASE "C53" ; RETURN "This is CA-Cl*pper v5.3 compliant and is only visible if source was compiled with the HB_COMPAT_C53 flag" + CASE "H" ; RETURN "This is Harbour specific" + CASE "NA" ; RETURN "Not applicable" + OTHERWISE ; RETURN cCode + ENDSWITCH + + CASE "NAME" IF hsBlock == NIL RETURN cCode - ELSEIF ! hb_HHasKey( hsBlock, "RETURNS" ) + ELSEIF !( "RETURNS" $ hsBlock ) RETURN hsBlock[ "NAME" ] ELSEIF Empty( hsBlock[ "RETURNS" ] ) .OR. ; Upper( hsBlock[ "RETURNS" ] ) == "NIL" .OR. ; @@ -847,64 +821,60 @@ FUNCTION Decode( cType, hsBlock, cKey ) DO CASE CASE Lower( hsBlock[ "CATEGORY" ] ) == "document" RETURN hsBlock[ "NAME" ] + CASE Lower( hsBlock[ "TEMPLATE" ] ) == "function" .OR. ; + Lower( hsBlock[ "TEMPLATE" ] ) == "procedure" + RETURN "Procedure " + hsBlock[ "NAME" ] OTHERWISE - IF Lower( hsBlock[ "TEMPLATE" ] ) == "function" .OR. Lower( hsBlock[ "TEMPLATE" ] ) == "procedure" - RETURN "Procedure " + hsBlock[ "NAME" ] - ELSE - RETURN LTrim( hsBlock[ "SUBCATEGORY" ] + " " ) + hsBlock[ "CATEGORY" ] + " " + hsBlock[ "NAME" ] - ENDIF + RETURN LTrim( hsBlock[ "SUBCATEGORY" ] + " " ) + hsBlock[ "CATEGORY" ] + " " + hsBlock[ "NAME" ] ENDCASE ELSE DO CASE CASE ! Empty( hsBlock[ "NAME" ] ) RETURN "Function " + hsBlock[ "NAME" ] OTHERWISE - RETURN "Unknown 'CATEGORY': " + hsBlock[ "CATEGORY" ] + RETURN "Unrecognized 'CATEGORY': " + hsBlock[ "CATEGORY" ] ENDCASE ENDIF - ENDCASE + ENDSWITCH - RETURN /* cType + "=" + */cCode + RETURN /* cType + "=" + */ cCode -PROCEDURE ShowSubHelp( xLine, nMode, nIndent, n ) +STATIC PROCEDURE ShowSubHelp( xLine, /* @ */ nMode, nIndent, n ) - LOCAL cIndent := Space( nIndent ) - - IF xLine != NIL + DO CASE + CASE xLine == NIL + CASE HB_ISNUMERIC( xLine ) + nMode := xLine + CASE HB_ISEVALITEM( xLine ) + Eval( xLine ) + CASE HB_ISARRAY( xLine ) + IF nMode == 2 + OutStd( Space( nIndent ) + Space( 2 ) ) + ENDIF + AEval( xLine, {| x, n | ShowSubHelp( x, @nMode, nIndent + 2, n ) } ) + IF nMode == 2 + OutStd( hb_eol() ) + ENDIF + OTHERWISE DO CASE - CASE HB_ISNUMERIC( xLine ) - nMode := xLine - CASE HB_ISBLOCK( xLine ) - Eval( xLine ) - CASE HB_ISARRAY( xLine ) - IF nMode == 2 - OutStd( cIndent + Space( 2 ) ) - ENDIF - AEval( xLine, {| x, n | ShowSubHelp( x, @nMode, nIndent + 2, n ) } ) - IF nMode == 2 - OutStd( hb_eol() ) - ENDIF - OTHERWISE - DO CASE - CASE nMode == 1 ; OutStd( cIndent + xLine ) ; OutStd( hb_eol() ) - CASE nMode == 2 ; OutStd( iif( n > 1, ", ", "" ) + xLine ) - OTHERWISE ; OutStd( "(" + hb_ntos( nMode ) + ") " ) ; OutStd( xLine ) ; OutStd( hb_eol() ) - ENDCASE + CASE nMode == 1 ; OutStd( Space( nIndent ) + xLine + hb_eol() ) + CASE nMode == 2 ; OutStd( iif( n > 1, ", ", "" ) + xLine ) + OTHERWISE ; OutStd( "(" + hb_ntos( nMode ) + ") " + xLine + hb_eol() ) ENDCASE - ENDIF + ENDCASE RETURN STATIC FUNCTION HBRawVersion() - RETURN hb_StrFormat( "%d.%d.%d%s (r%d)", ; + RETURN hb_StrFormat( "%d.%d.%d%s (%s)", ; hb_Version( HB_VERSION_MAJOR ), ; hb_Version( HB_VERSION_MINOR ), ; hb_Version( HB_VERSION_RELEASE ), ; hb_Version( HB_VERSION_STATUS ), ; - hb_Version( HB_VERSION_REVISION ) ) + "20" + Transform( hb_Version( HB_VERSION_REVISION ), "99-99-99 99:99" ) ) -PROCEDURE ShowHelp( cExtraMessage, aArgs ) +STATIC PROCEDURE ShowHelp( cExtraMessage, aArgs ) LOCAL nMode := 1 @@ -915,7 +885,7 @@ PROCEDURE ShowHelp( cExtraMessage, aArgs ) aHelp := { ; cExtraMessage, ; "Harbour Document Compiler (hbdoc) " + HBRawVersion(), ; - "Copyright (c) 1999-2010, http://harbour-project.org/", ; + "Copyright (c) 1999-2016, " + hb_Version( HB_VERSION_URL_BASE ), ; "", ; "Syntax:", ; "", ; @@ -923,84 +893,74 @@ PROCEDURE ShowHelp( cExtraMessage, aArgs ) "", ; "Options:", ; { ; - "-? or --help // this screen", ; - "-?
" lRaw := .T. ELSEIF cLine == "
" @@ -1048,8 +1006,8 @@ FUNCTION Indent( cText, nLeftMargin, nWidth, lRaw ) DO WHILE idx > 0 idx-- DO CASE - CASE At( SubStr( cLine, idx, 1 ), " ,;.!?" ) == 0 - // + CASE ! SubStr( cLine, idx, 1 ) $ " ,;.!?" + /* do nothing */ CASE Upper( SubStr( cLine, idx, 3 ) ) == ".T." .OR. Upper( SubStr( cLine, idx, 3 ) ) == ".F." idx-- CASE Upper( SubStr( cLine, idx - 2, 3 ) ) == ".T." .OR. Upper( SubStr( cLine, idx - 1, 3 ) ) == ".F." @@ -1084,66 +1042,241 @@ FUNCTION Indent( cText, nLeftMargin, nWidth, lRaw ) cLine := LTrim( SubStr( cLine, idx + 1 ) ) ENDDO - IF Len( cLine ) > 0 + IF ! HB_ISNULL( cLine ) cResult += Space( nLeftMargin ) + cLine + hb_eol() ENDIF cResult += hb_eol() ENDIF - ENDDO + NEXT ENDIF RETURN cResult -FUNCTION Filename( cFile, cFormat, nLength ) +STATIC FUNCTION Filename( cFile, cFormat, nLength ) - STATIC s_Files := {} + STATIC s_aFiles := {} LOCAL cResult := "" LOCAL idx LOCAL char - hb_default( @cFormat, "alnum" ) - #ifdef __PLATFORM__DOS hb_default( @nLength, 8 ) #else hb_default( @nLength, 0 ) #endif - DO CASE - CASE Lower( cFormat ) == "alnum" - + IF Lower( hb_defaultValue( cFormat, "alnum" ) ) == "alnum" FOR idx := 1 TO Len( cFile ) - char := Lower( SubStr( cFile, idx, 1 ) ) - IF "0" <= char .AND. char <= "9" .OR. "a" <= char .AND. char <= "z" .OR. char == "_" - cResult += char + char := SubStr( cFile, idx, 1 ) + IF hb_asciiIsDigit( char ) .OR. hb_asciiIsAlpha( char ) .OR. char == "_" + cResult += Lower( char ) IF nLength > 0 .AND. Len( cResult ) == nLength EXIT ENDIF ENDIF NEXT - - OTHERWISE + ELSE cResult := cFile + ENDIF - ENDCASE - - IF hb_AScan( s_Files, cResult, , , .T. ) == 0 - AAdd( s_Files, cResult ) + IF hb_AScan( s_aFiles, cResult, , , .T. ) == 0 + AAdd( s_aFiles, cResult ) ELSE #ifdef __PLATFORM__DOS - cResult := Left( cResult, Len( cResult ) - 3 ) + cResult := hb_StrShrink( cResult, 3 ) #endif idx := 0 - DO WHILE hb_AScan( s_Files, cResult + PadL( hb_ntos( ++idx ), 3, "0" ), , , .T. ) > 0 + DO WHILE hb_AScan( s_aFiles, cResult + StrZero( ++idx, 3 ), , , .T. ) > 0 ENDDO - cResult += PadL( hb_ntos( idx ), 3, "0" ) - AAdd( s_Files, cResult ) + cResult += StrZero( idx, 3 ) + AAdd( s_aFiles, cResult ) ENDIF RETURN cResult +STATIC PROCEDURE init_Templates() + + LOCAL item + LOCAL aSubCategories := { ; + "Application", ; + "Array", ; + "Classes", ; + "Conversion", ; + "Database", ; + "Date/Time", ; + "Environment", ; + "Error", ; + "Events", ; + "Execute and execution", ; /* replace w/ "Environment"? */ + "Extend", ; + "FileSys", ; + "Fixed memory", ; + "Garbage collector", ; + "Hash table", ; + "Idle states", ; + "INET", ; + "Internal", ; + "Item", ; + "Language and Nation", ; + "Legacy", ; + "Macro", ; + "Math", ; + "Objects", ; + "Printer", ; + "RDD", ; + "Strings", ; + "Terminal", ; + "Undocumented", ; + "User interface", ; + "Variable management", ; + "Virtual machine" } + + LOCAL aCategories := { ; + { "Document", { "License", "Compiler", "" } }, ; + { "API", AClone( aSubCategories ) }, ; + { "C level API", AClone( aSubCategories ) }, ; + { "C level API compatability", AClone( aSubCategories ) }, ; + { "Class", { ; + "", ; + "Access", ; + "Assign", ; + "Constructor", ; + "Data", ; + "Definition", ; + "Destructor", ; + "Method", ; + "Var" } }, ; + { "Command", AClone( aSubCategories ) }, ; + /* { "Compile time errors", { {} } }, */ ; + { "Run time errors", { "" } } } + + LOCAL aCompliance := { ; + { "", "" }, ; + { "C", "This is CA-Cl*pper v5.2 compliant" }, ; + { "C(array)", "This is CA-Cl*pper v5.2 compliant except that arrays in Harbour can have an unlimited number of elements" }, ; + { "C(menu)", "This is CA-Cl*pper v5.2 compliant except that menus (internally arrays) in Harbour can have an unlimited number of elements" }, ; + { "C(arrayblock)", "Codeblock calling frequency and order differs from CA-Cl*pper, since Harbour uses a different (faster) sorting algorithm (quicksort)" }, ; + { "C52S", "? verbage: This is an CA-Cl*pper v5.2 compliant and is only visible if source was compiled with the HB_C52_STRICT flag" }, ; + { "C52U", "This is an undocumented CA-Cl*pper v5.2 function and is only visible if source was compiled with the HB_C52_UNDOC flag" }, ; + { "C53", "This is CA-Cl*pper v5.3 compliant and is only visible if source was compiled with the HB_COMPAT_C53 flag" }, ; + { "H", "This is Harbour specific" }, ; + { "NA", "Not applicable" } } + + LOCAL aPlatforms := { ; + { "", "" }, ; + { "All", "This is available on all platforms" }, ; + { "All(GT)", "This part of the GT API and supported only by some platforms." }, ; + { "All(LFN)", "This is available on all platforms." + hb_eol() + ; + "If long file names are available Harbour will use/display the first 15 characters " +; + "else Harbour will use/display a 8.3 file name consistent with CA-Cl*pper" }, ; + { "Linux(GT)", "Under Linux the number of columns avaliable depends of the current Terminal screen size." }, ; + { "OS2(GT)", "Under OS/2 the number of columns avaliable depends of the current Terminal screen size." }, ; + { "Win(GT)", "Under Windows, the return value of MaxRow() function is only affected if called after an SetMode() function" }, ; + { "BSD", "This is available on the BSD platform" }, ; + { "DARWIN", "This is available on the Darwin platform" }, ; + { "DOS", "This is available on the MS-DOS platform" }, ; + { "HPUX", "This is available on the HPUX platform" }, ; + { "LINUX", "This is available on the Linux platform" }, ; + { "OS2", "This is available on the OS/2 platform" }, ; + { "SUNOS", "This is available on the SunOS platform" }, ; + { "Unix", "This is available on the Unix platform(s)" }, ; + { "Win", "This is available on the Windows platform(s)" }, ; + { "WinCE", "This is available on the Windows CE platform" } } + + LOCAL aStatus := { ; + { "", "" }, ; + { "R", "Ready" }, ; + { "S", "Started" }, ; + { "N", "Not started" } } + + FOR EACH item IN aCategories + IF ! Empty( item ) + AAdd( item, Array( Len( item[ 2 ] ) ) ) /* holder array of sub-category entries */ + AAdd( item, "" ) /* holder for sub-category file name */ + ENDIF + NEXT + + sc_hConstraint := { ; + "categories" => aCategories, ; + "compliance" => aCompliance, ; + "platforms" => aPlatforms, ; + "status" => aStatus } + + hb_HCaseMatch( sc_hConstraint, .F. ) + + RETURN + +STATIC PROCEDURE ShowTemplatesHelp( cTemplate, cDelimiter ) + + LOCAL o := Entry():New( , sc_hConstraint ) + LOCAL idxTemplates, nFrom := 1, nTo := Len( o:Templates ) + LOCAL idx + + IF ! Empty( cTemplate ) .AND. !( cTemplate == "Template" ) + IF o:IsTemplate( cTemplate ) + nFrom := nTo := AScan( o:Templates, {| a | Upper( a[ 1 ] ) == Upper( cTemplate ) } ) + ELSE + ShowHelp( "Unrecognized template '" + cTemplate + "'" ) + RETURN + ENDIF + ENDIF + + FOR idxTemplates := nFrom TO nTo + IF ! Empty( o:Templates[ idxTemplates ] ) .AND. ; + ! Empty( o:Templates[ idxTemplates ][ 1 ] ) .AND. ; + !( o:Templates[ idxTemplates ][ 1 ] == "Template" ) + +#if 0 + IF nFrom != nTo + ShowSubHelp( o:Templates[ idxTemplates ][ 1 ], 1, 0 ) + ENDIF +#endif + + o:SetTemplate( o:Templates[ idxTemplates ][ 1 ] ) + + FOR idx := 1 TO Len( o:Fields ) + IF o:Group[ idx ] != 0 + ShowSubHelp( iif( idx == 1, "/", " " ) + "* " + cDelimiter + o:Fields[ idx ][ 1 ] + cDelimiter, 1, 0 ) + IF o:Fields[ idx ][ 1 ] == "TEMPLATE" + ShowSubHelp( " * " + o:Template, 1, 0 ) + ELSEIF o:Group[ idx ] != TPL_START .AND. o:Group[ idx ] != TPL_END .AND. .T. + ShowSubHelp( " * " + iif( o:IsRequired( o:Fields[ idx ][ 1 ] ), "", "" ), 1, 0 ) + ENDIF + ENDIF + NEXT + ShowSubHelp( " */", 1, 0 ) + ShowSubHelp( "", 1, 0 ) + ENDIF + NEXT + + RETURN + +STATIC PROCEDURE ShowComplianceHelp() + + LOCAL item + + FOR EACH item IN sc_hConstraint[ "compliance" ] + ShowSubHelp( item[ 1 ], 1, 0, item:__enumIndex() ) + ShowSubHelp( Decode( "COMPLIANCE", , item[ 1 ] ), 1, 6, item:__enumIndex() ) + ShowSubHelp( "", 1, 0 ) + NEXT + + RETURN + +STATIC PROCEDURE ShowPlatformsHelp() + + LOCAL item + + FOR EACH item IN sc_hConstraint[ "platforms" ] + ShowSubHelp( item[ 1 ], 1, 0, item:__enumIndex() ) + ShowSubHelp( Decode( "PLATFORMS", , item[ 1 ] ), 1, 6, item:__enumIndex() ) + ShowSubHelp( "", 1, 0 ) + NEXT + + RETURN + #if defined( __HBSCRIPT__HBSHELL ) SET PROCEDURE TO "_tmplate.prg" SET PROCEDURE TO "_genbase.prg"