diff --git a/.gitignore b/.gitignore index 7d94a9bf6..d77019988 100644 --- a/.gitignore +++ b/.gitignore @@ -35,7 +35,7 @@ missing *.mo *.gambas main/trunk_version.h -main/*/gb*3 +main/gb*/gb*3 DISABLED* .startup .settings diff --git a/main/tools/gbh3/.directory b/main/tools/gbh3/.directory new file mode 100644 index 000000000..06dab1c8a --- /dev/null +++ b/main/tools/gbh3/.directory @@ -0,0 +1,2 @@ +[Desktop Entry] +Icon=./.icon.png diff --git a/main/tools/gbh3/.icon.png b/main/tools/gbh3/.icon.png new file mode 100644 index 000000000..271c30e14 Binary files /dev/null and b/main/tools/gbh3/.icon.png differ diff --git a/main/tools/gbh3/.project b/main/tools/gbh3/.project new file mode 100644 index 000000000..350470d4a --- /dev/null +++ b/main/tools/gbh3/.project @@ -0,0 +1,12 @@ +# Gambas Project File 3.0 +# Compiled with Gambas 3.6.90 +Title=gbh3 +Startup=MMain +Icon=icon.png +Version=3.6.90 +VersionFile=1 +Description="Extract help comments from C/C++ source files and format them into a .help file." +Authors="(C) 2014 Tobias Boege , GPLv2+" +TabSize=2 +Language=en_GB +Packager=1 diff --git a/main/tools/gbh3/.src/MMain.module b/main/tools/gbh3/.src/MMain.module new file mode 100644 index 000000000..d863e2c60 --- /dev/null +++ b/main/tools/gbh3/.src/MMain.module @@ -0,0 +1,447 @@ +' Gambas module file + +Private $sRoot As String +Private $sComponent As String +Private $bVerbose As Boolean + +Private Sub PrintError(sErr As String) + + Error File.Name(Args[0]); ": error: "; sErr + Quit 1 + +End + +Private Sub PrintMessage(sMsg As String) + + If Not $bVerbose Then Return + Error sMsg + +End + +Public Sub Main() + + Dim iInd As Integer, aSources As New String[] + Dim sArg, sRec As String, aRec As String[] + Dim sPath As String + Dim hOut As File + Dim bOnlySources As Boolean + Dim sMsg As String + + $sRoot = System.Path + + For iInd = 1 To Args.Max + Select Case Args[iInd] + Case "-h", "--help" + Print File.Load("usage") + Quit + Case "-V", "--version" + Print Application.Version + Quit + Case "-L", "--license" + Print File.Load("license") + Quit + Case "-v", "--verbose" + $bVerbose = True + Case "-r", "--root" + $sRoot = Args[iInd + 1] + If Not $sRoot Then PrintError(Args[iInd] & " requires an argument") + Inc iInd + Case "-c", "--component" + $sComponent = Args[iInd + 1] + If Not $sComponent Then PrintError(Args[iInd] & " requires an argument") + Inc iInd + Case "--" + bOnlySources = True + Default + If Not bOnlySources Then + If Args[iInd] Begins "-" Then + PrintError("unknown option: " & Args[iInd]) + Endif + Endif + aSources.Add(Args[iInd]) + End Select + Next + + If aSources.Count = 0 Then aSources.Add(".") + + If $sComponent Then + sPath = $sRoot &/ "share/gambas" & System.Version &/ "info" &/ $sComponent & ".help" + PrintMessage("Output to " & sPath) + hOut = Open sPath For Create + Else + hOut = File.Out + Endif + + For Each sArg In aSources + If Left(sArg) <> "/" Then + If sArg = "." Then + sArg = Application.Dir + Else + sArg = Application.Dir &/ sArg + Endif + Endif + If IsDir(sArg) Then + aRec = RDir(sArg, "*.{c,cc,cpp}") + For Each sRec In aRec + OneFile(sArg &/ sRec, hOut) + Next + Else + OneFile(sArg, hOut) + Endif + Next + + If $sComponent Then + Close #hOut + If Stat(sPath).Size = 0 Then + PrintMessage("Removing void data file") + Try Kill sPath + Endif + Endif + +Catch + + sMsg = Error.Text & ": " & Error.Backtrace.Join(" ") + Output To Default + PrintError(sMsg) + +End + +Private Sub AddHelp(cHelp As Collection, sClass As String, sSymbol As String, sHelp As String) + + Dim cCol As Collection + + PrintMessage("AddHelp: " & sClass & "." & sSymbol) + + cCol = cHelp[sClass] + If Not cCol Then + cCol = New Collection + cHelp[sClass] = cCol + Endif + + cCol[sSymbol] = sHelp + +End + + +Private Sub OneFile(sPath As String, hOut As File) + + Dim hFile As File + Dim sLine As String + Dim aHelp As New String[] + Dim bInsideComments As Boolean + Dim sHelp As String + Dim iPos As Integer + Dim bInsideDesc As Boolean + Dim sMacro As String + Dim iPos2 As Integer + Dim aArg As String[] + Dim sClass As String + Dim sSymbol As String + Dim cHelp As Collection + Dim sDeclareClass As String + Dim cCol As Variant + Dim aClass As String[] + Dim sImpl As String + + PrintMessage("Processing " & sPath & "...") + hFile = Open sPath For Input + + cHelp = New Collection + + For Each sLine In hFile.Lines + + sLine = Trim(sLine) + If Not sLine Then Continue + + 'PrintMessage(sLine) + + If sLine Begins "/// " Then + + aHelp.Add(Mid$(sLine, 5)) + Continue + + Else If sLine = "/**G" Or If sLine = "/**" Then + + bInsideComments = True + Continue + + Else If sLine Begins "/** " Then + + aHelp.Add(Mid$(sLine, 5)) + bInsideComments = True + Continue + + Else If bInsideComments Then + + If RTrim(sLine) Ends "*/" Then + + bInsideComments = False + Continue + + Else + + While Left(sLine) = "*" + sLine = Mid$(sLine, 2) + Wend + If Left(sLine) = " " Then sLine = Mid$(sLine, 2) + aHelp.Add(sLine) + Continue + + Endif + + Endif + + If aHelp.Count Then + + sHelp = Trim(aHelp[0]) + If Len(sHelp) >= 3 And If sHelp Begins "[" And If sHelp Ends "]" Then + sHelp = Mid$(sHelp, 2, -1) + iPos = InStr(sHelp, ".") + If iPos = 0 Then + sClass = sHelp + sSymbol = "" + Else + sClass = Left$(sHelp, iPos - 1) + sSymbol = Mid$(sHelp, iPos + 1) + Endif + + aHelp.Remove(0) + AddHelp(cHelp, sClass, sSymbol, aHelp.Join("\n")) + sHelp = "" + Else + sHelp = Trim(aHelp.Join("\n")) + Endif + aHelp.Clear + + Endif + + If sHelp Then + If sLine Begins "BEGIN_METHOD" Or If sLine Begins "BEGIN_PROPERTY" Then + + iPos = InStr(sLine, "(") + If iPos = 0 Then Continue + sLine = Mid$(sLine, iPos + 1) + iPos = InStr(sLine, ",") + If iPos = 0 Then iPos = InStr(sLine, ")") + If iPos = 0 Then Continue + sLine = Left(sLine, iPos - 1) + + AddHelp(cHelp, "@", sLine, sHelp) + sHelp = "" + Continue + + Endif + Endif + + If sLine Begins "GB_DECLARE" Then + bInsideDesc = True + Try sDeclareClass = Scan(sLine, "GB_DECLARE*(\"*\"*")[1] + If Error Then PrintError("Missing class name in GB_DECLARE macro: " & sLine) + Continue + Endif + + If bInsideDesc Then + + If sLine Begins "GB_END_DECLARE" Then + bInsideDesc = False + Continue + Endif + + + iPos = InStr(sLine, "(") + If iPos = 0 Then Continue + sMacro = Left(sLine, iPos - 1) + + If sMacro Not Begins "GB_" Then Continue + If InStr(sMacro, "_CONSTANT") = 0 And If InStr(sMacro, "_PROPERTY") = 0 And If InStr(sMacro, "_METHOD") = 0 Then Continue + + iPos2 = InStr(sLine, ")", iPos + 1) + If iPos2 = 0 Then Continue + + aArg = Split(Mid$(sLine, iPos + 1, iPos2 - iPos - 1), ",", Chr$(34)) + sSymbol = Trim(aArg[0]) + Try sImpl = Trim(aArg[2]) + + If sHelp Then + + AddHelp(cHelp, sDeclareClass, sSymbol, sHelp) + sHelp = "" + + Else + + If InStr(sMacro, "_CONSTANT") Then Continue + If InStr(sMacro, "_SELF") Then Continue + Try sHelp = cHelp["@"][sImpl] + If sHelp Then + AddHelp(cHelp, sDeclareClass, sSymbol, sHelp) + sHelp = "" + Endif + + Endif + + Endif + + Next + + Close #hFile + + ' Make class list + + aClass = New String[] + For Each cCol In cHelp + If cHelp.Key = "@" Then Continue + aClass.Add(cHelp.Key) + Next + aClass.Sort(gb.IgnoreCase) + + ' Generate help + + For Each sClass In aClass + + cCol = cHelp[sClass] + If cCol.Count = 0 Then Continue + + Print #hOut, "#"; sClass + + For Each sHelp In cCol + Print #hOut, cCol.Key + Print #hOut, "'"; Split(sHelp, "\n").Join("\n'") + Next + + Next + +End + +' Private Function Extract(hFile As File) As String[] +' +' Dim hNameFn As New RegExp, hNameInline As New RegExp +' Dim sLine As String, sInline As String +' Dim aRes As New String[] +' Dim bRecord As Boolean +' +' hNameFn.Compile("^BEGIN_.*\\(([^,)]+).*") +' hNameInline.Compile("/\\*\\*G (.+)$") +' +' For Each sLine In hFile.Lines +' If sLine Match "^[\\t ]*\\*?\\*/$" Then +' If sInline Then +' aRes.Add("G " & sInline) +' sInline = "" +' bRecord = False +' Endif +' Continue +' Endif +' hNameFn.Exec(sLine) +' If hNameFn.Offset <> -1 And If bRecord And If Not sInline Then +' aRes.Add(hNameFn[1].Text) +' bRecord = False +' Endif +' +' If bRecord Then aRes.Add(RegExp.Replace(sLine, "^[\\t ]*\\*", "'")) +' +' If sLine Match "^/\\*\\*G$" Then +' If bRecord Then aRes.Add("ERROR") +' sInline = "" +' bRecord = True +' Endif +' hNameInline.Exec(sLine) +' If hNameInline.Offset <> -1 Then +' If bRecord Then aRes.Add("ERROR") +' sInline = LTrim$(hNameInline[1].Text) +' bRecord = True +' Endif +' Next +' If bRecord Then aRes.Add("ERROR") +' Return aRes +' End +' +' Private Function Translate(aSource As String[], sPath As String) As String[] +' +' Dim sLine As String, aRes As New String[] +' +' For Each sLine In aSource +' If Not sLine Then Continue +' If sLine = "ERROR" Or If sLine Begins "'" Then +' aRes.Add(sLine) +' Continue +' Endif +' If sLine Begins "G " Then ' Syntax-2? +' aRes.Add(Right$(sLine, -2)) +' Continue +' Endif +' ' Syntax-1 +' aRes.Add(GetSyntax1(sLine, sPath)) +' Next +' Return aRes +' End +' +' Private Function GetSyntax1(sFunc As String, sPath As String) As String +' +' Dim hClassName As New RegExp, hFunction As New RegExp +' Dim hFile As File, sLine, sClass As String +' Dim aRes As New String[] +' +' hClassName.Compile("GB_DECLARE\\(\\\"([^\\\"]+).*") +' hFunction.Compile("GB_[^(]+\\(\\\"([^\"]+)\\\".*" & sFunc & "\\W") +' +' hFile = Open sPath For Input +' sClass = "ERROR" +' For Each sLine In hFile.Lines +' If Not sLine Then Continue +' hClassName.Exec(sLine) +' If hClassName.Offset <> -1 Then sClass = hClassName[1].Text +' hFunction.Exec(sLine) +' If hFunction.Offset <> -1 Then +' If Not aRes.Count Then aRes.Add(sClass) +' aRes.Add(hFunction[1].Text) +' Endif +' Next +' Close #hFile +' Return aRes.Join(" ") +' End +' +' Public Sub MakeHelp(aSource As String[], hOut As File) +' +' Dim sLine, sCls, sSym As String +' Dim cHelp As New Collection, aCurrent As New String[] +' Dim cClass As Collection, aHelp, aSyn As String[] +' Dim iInd As Integer +' +' Output To hOut +' For Each sLine In aSource +' If Not sLine Then Continue +' If sLine Begins "'" Then +' aCurrent.Add(sLine) +' Else +' With Scan(sLine, "* *") +' If .Count = 0 Then ' +' sCls = sLine +' sSym = "#" +' Else If .Count = 2 Then ' +' sCls = Trim$(.[0]) +' sSym = Trim$(.[1]) +' Endif +' If Not cHelp[sCls] Then cHelp[sCls] = New Collection +' cHelp[sCls][sSym] = aCurrent +' aCurrent = New String[] +' End With +' Endif +' Next +' +' For Each cClass In cHelp +' Print "#"; cHelp.Key +' aHelp = cClass["#"] +' If aHelp Then Print aHelp.Join("\n") +' For Each aHelp In cClass +' If cClass.Key = "#" Then Continue +' aSyn = Split(cClass.Key, " ") +' Print aSyn[0] +' If aHelp.Count Then Print aHelp.Join("\n") +' For iInd = 1 To aSyn.Max +' Print aSyn[iInd] +' Print "' A synonym for";; aSyn[0]; "." +' Next +' Next +' Next +' Output To Default +' End diff --git a/main/tools/gbh3/.src/MOldMain.module b/main/tools/gbh3/.src/MOldMain.module new file mode 100644 index 000000000..d08330f4a --- /dev/null +++ b/main/tools/gbh3/.src/MOldMain.module @@ -0,0 +1,256 @@ +' Gambas module file + +' ' Gambas module file +' +' Private $sRoot As String +' Private $sComponent As String +' Private $bVerbose As Boolean +' +' Private Sub PrintError(sErr As String) +' +' Error File.Name(Args[0]); ": error: "; sErr +' Quit 1 +' +' End +' +' Private Sub PrintMessage(sMsg As String) +' +' If Not $bVerbose Then Return +' Error sMsg +' +' End +' +' Public Sub Main() +' +' Dim iInd As Integer, aSources As New String[] +' Dim sArg, sRec As String, aRec As String[] +' Dim sPath As String +' Dim hOut As File +' Dim bOnlySources As Boolean +' Dim sMsg As String +' +' $sRoot = System.Path +' +' For iInd = 1 To Args.Max +' Select Case Args[iInd] +' Case "-h", "--help" +' Print File.Load("usage") +' Quit +' Case "-V", "--version" +' Print Application.Version +' Quit +' Case "-L", "--license" +' Print File.Load("license") +' Quit +' Case "-v", "--verbose" +' $bVerbose = True +' Case "-r", "--root" +' $sRoot = Args[iInd + 1] +' If Not $sRoot Then PrintError(Args[iInd] & " requires an argument") +' Inc iInd +' Case "-c", "--component" +' $sComponent = Args[iInd + 1] +' If Not $sComponent Then PrintError(Args[iInd] & " requires an argument") +' Inc iInd +' Case "--" +' bOnlySources = True +' Default +' If Not bOnlySources Then +' If Args[iInd] Begins "-" Then +' PrintError("unknown option: " & Args[iInd]) +' Endif +' Endif +' aSources.Add(Args[iInd]) +' End Select +' Next +' +' If aSources.Count = 0 Then aSources.Add(".") +' +' If $sComponent Then +' sPath = $sRoot &/ "share/gambas" & System.Version &/ "info" &/ $sComponent & ".help" +' PrintMessage("Output to " & sPath) +' hOut = Open sPath For Create +' Else +' hOut = File.Out +' Endif +' +' For Each sArg In aSources +' If Left(sArg) <> "/" Then +' If sArg = "." Then +' sArg = Application.Dir +' Else +' sArg = Application.Dir &/ sArg +' Endif +' Endif +' If IsDir(sArg) Then +' aRec = RDir(sArg, "*.{c,cc,cpp}") +' For Each sRec In aRec +' OneFile(sArg &/ sRec, hOut) +' Next +' Else +' OneFile(sArg, hOut) +' Endif +' Next +' +' If $sComponent Then +' Close #hOut +' If Stat(sPath).Size = 0 Then +' PrintMessage("Removing void data file") +' Try Kill sPath +' Endif +' Endif +' +' Catch +' +' sMsg = Error.Text & ": " & Error.Backtrace.Join(" ") +' Output To Default +' PrintError(sMsg) +' +' End +' +' Private Sub OneFile(sPath As String, hOut As File) +' +' Dim hFile As File +' +' PrintMessage("Processing " & sPath & "...") +' hFile = Open sPath For Input +' +' MakeHelp(Translate(Extract(hFile), sPath), hOut) +' +' Close #hFile +' +' End +' +' Private Function Extract(hFile As File) As String[] +' +' Dim hNameFn As New RegExp, hNameInline As New RegExp +' Dim sLine As String, sInline As String +' Dim aRes As New String[] +' Dim bRecord As Boolean +' +' hNameFn.Compile("^BEGIN_.*\\(([^,)]+).*") +' hNameInline.Compile("/\\*\\*G (.+)$") +' +' For Each sLine In hFile.Lines +' If sLine Match "^[\\t ]*\\*?\\*/$" Then +' If sInline Then +' aRes.Add("G " & sInline) +' sInline = "" +' bRecord = False +' Endif +' Continue +' Endif +' hNameFn.Exec(sLine) +' If hNameFn.Offset <> -1 And If bRecord And If Not sInline Then +' aRes.Add(hNameFn[1].Text) +' bRecord = False +' Endif +' +' If bRecord Then aRes.Add(RegExp.Replace(sLine, "^[\\t ]*\\*", "'")) +' +' If sLine Match "^/\\*\\*G$" Then +' If bRecord Then aRes.Add("ERROR") +' sInline = "" +' bRecord = True +' Endif +' hNameInline.Exec(sLine) +' If hNameInline.Offset <> -1 Then +' If bRecord Then aRes.Add("ERROR") +' sInline = LTrim$(hNameInline[1].Text) +' bRecord = True +' Endif +' Next +' If bRecord Then aRes.Add("ERROR") +' Return aRes +' End +' +' Private Function Translate(aSource As String[], sPath As String) As String[] +' +' Dim sLine As String, aRes As New String[] +' +' For Each sLine In aSource +' If Not sLine Then Continue +' If sLine = "ERROR" Or If sLine Begins "'" Then +' aRes.Add(sLine) +' Continue +' Endif +' If sLine Begins "G " Then ' Syntax-2? +' aRes.Add(Right$(sLine, -2)) +' Continue +' Endif +' ' Syntax-1 +' aRes.Add(GetSyntax1(sLine, sPath)) +' Next +' Return aRes +' End +' +' Private Function GetSyntax1(sFunc As String, sPath As String) As String +' +' Dim hClassName As New RegExp, hFunction As New RegExp +' Dim hFile As File, sLine, sClass As String +' Dim aRes As New String[] +' +' hClassName.Compile("GB_DECLARE\\(\\\"([^\\\"]+).*") +' hFunction.Compile("GB_[^(]+\\(\\\"([^\"]+)\\\".*" & sFunc & "\\W") +' +' hFile = Open sPath For Input +' sClass = "ERROR" +' For Each sLine In hFile.Lines +' If Not sLine Then Continue +' hClassName.Exec(sLine) +' If hClassName.Offset <> -1 Then sClass = hClassName[1].Text +' hFunction.Exec(sLine) +' If hFunction.Offset <> -1 Then +' If Not aRes.Count Then aRes.Add(sClass) +' aRes.Add(hFunction[1].Text) +' Endif +' Next +' Close #hFile +' Return aRes.Join(" ") +' End +' +' Public Sub MakeHelp(aSource As String[], hOut As File) +' +' Dim sLine, sCls, sSym As String +' Dim cHelp As New Collection, aCurrent As New String[] +' Dim cClass As Collection, aHelp, aSyn As String[] +' Dim iInd As Integer +' +' Output To hOut +' For Each sLine In aSource +' If Not sLine Then Continue +' If sLine Begins "'" Then +' aCurrent.Add(sLine) +' Else +' With Scan(sLine, "* *") +' If .Count = 0 Then ' +' sCls = sLine +' sSym = "#" +' Else If .Count = 2 Then ' +' sCls = Trim$(.[0]) +' sSym = Trim$(.[1]) +' Endif +' If Not cHelp[sCls] Then cHelp[sCls] = New Collection +' cHelp[sCls][sSym] = aCurrent +' aCurrent = New String[] +' End With +' Endif +' Next +' +' For Each cClass In cHelp +' Print "#"; cHelp.Key +' aHelp = cClass["#"] +' If aHelp Then Print aHelp.Join("\n") +' For Each aHelp In cClass +' If cClass.Key = "#" Then Continue +' aSyn = Split(cClass.Key, " ") +' Print aSyn[0] +' If aHelp.Count Then Print aHelp.Join("\n") +' For iInd = 1 To aSyn.Max +' Print aSyn[iInd] +' Print "' A synonym for";; aSyn[0]; "." +' Next +' Next +' Next +' Output To Default +' End diff --git a/main/tools/gbh3/README b/main/tools/gbh3/README new file mode 100644 index 000000000..7f741ac1d --- /dev/null +++ b/main/tools/gbh3/README @@ -0,0 +1,112 @@ +About gbh3 +---------- + +gbh3 is used to extract Gambas documentation from C/C++ source files and +create .help files for a component from them. It is a single Gambas project +depending only on gb.pcre. + +... and why? +------------ + +Components written in Gambas can already be documented in-code. This docu- +mentation is then stored inside their .info files. With a similar result +provided by gbh3 for C/C++ components, we can document all[*] Gambas in +its source files (at least my components will be) which makes it, IMHO, +easier to keep the documentation up-to-date. Also the help could be +displayed locally by the IDE or remotely once these .help files are imported +to the gambaswiki.org site. + +Also, documentation can be bound to a specific source code version, so that +you get docs for the version of Gambas you are running, not only for the +development branch. + +[*] I'm not sure about intrinsic functions, though. Should be feasible, + looking at gbx_class_info.c... + +Great! How do I prepare my component? +------------------------------------- + +The No. 0 rule is to BE CAREFUL! There are quite some rules to remember: + +1. Documentation syntax. + +You may write a Gambas documentation comment like + + /**G + * Here goes the documentation. + **/ + BEGIN_METHOD_VOID(ClassName_MethodName) + /* ... */ + END_METHOD + +or alternatively + + /**G Class Symbol + * Documenting Class.Symbol + **/ + +Instead of the **/ at the end, you may also write */. Cool, huh? + +The second syntax can also be used to document the class per se: + + /**G Class + * Class documentation here + **/ + +The difference between both notations is that the first must immediately +precede a BEGIN_{PROPERTY,METHOD,METHOD_VOID) line that defines the symbol +to which the documentation refers. The second syntax documents the indicated +symbol -- no matter where the comment is. + +This is intended to document GB_CONSTANTs or GB_PROPERTY_SELFs which don't +have a BEGIN_* line. It can neverthelss be used for any other symbol but +NEVER intermix both syntaxes on a single symbol. + +The ClassName_MethodName part I call "(implementation) function name". The +particular function naming convention shown is not mandatory. The scripts +take the function name and look up the corresponding symbol in your +GB_DESC[]. + +2. Regular expressions. + +The regular expressions used to filter these comments are somewhat strict. +You have to pass the spaces exactly as indicated in the line where your +comment text starts, i.e. *text. Also note that Class and +Symbol in the second syntax are case sensitive! + +OTOH, I can't guarantee that the expressions will not consume junk that you +left behind where I didn't expect junk to be. + +3. Strict structure. + +DON'T try to confuse the parsers by not giving information it needs where +it expects it. + +4. Synonyms. + +The first match for a function name lookup in a GB_DESC[] is taken as the +"primary" implementation of that symbol. That means the help comment will +be attched to that symbol. All other symbols which call the same function +are considered synonyms and are *automatically* documented with the default +sentence: "This is a synonym for ". DO NOT document them +separately using a syntax-2 help block! + +5. Don't reuse method and property implementations (except for synonyms). + +As the implementation function name is searched in the GB_DESC[]s in your +source file, you may not put the same function into different classes -- or +the parser may get confused. + +Also, keep the GB_DESC[] in the same source file as the help comment. + +Umm... I need an example +------------------------ + +gb.openssl and gb.data are partially documented that way. Digest.Hash() and +Digest._call() in gb.openssl show how to deal with synonyms. There the entry +for Hash precedes the entry for _call, thus Hash is the primary symbol and +_call a synonym. + +To see a sample .help file (on stdout), you can do at the source tree root: + + $ gbx3 app/src/gbh3 -- gb.openssl diff --git a/main/tools/gbh3/icon.png b/main/tools/gbh3/icon.png new file mode 100644 index 000000000..c2abe70a5 Binary files /dev/null and b/main/tools/gbh3/icon.png differ diff --git a/main/tools/gbh3/license b/main/tools/gbh3/license new file mode 100644 index 000000000..cdff94eb6 --- /dev/null +++ b/main/tools/gbh3/license @@ -0,0 +1,6 @@ +(c) Tobias Boege, BenoƮt Minisini + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2, or +(at your option) any later version. diff --git a/main/tools/gbh3/usage b/main/tools/gbh3/usage new file mode 100644 index 000000000..835af79c0 --- /dev/null +++ b/main/tools/gbh3/usage @@ -0,0 +1,18 @@ + +Extract Gambas help comments from source files. + +Usage: gbh3 [options] [] + +Options: + -r --root gives the Gambas installation directory + -c --component generate help directly in a component '*.help' file + -V --version display version + -L --license display license + -h --help display this help + +If contains directories, they are searched recursively for '*.c' +and '*.cpp' files. If is not specified, the current directory +is searched. + +The extracted help is printed on the standard output, unless the '-c' +option is specified.