' 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