Seite 1 von 1

Selbst ausgebender Code

Verfasst: 10.10.2010 13:19
von AND51
Hallo,

Ich entstaube gerade meinen Desktop und habe hier einen alten Code gefunden, der sich selbst ausgeben kann. Er wurde für eine frühere Version geschrieben, ich aktualisiere ihn hier nicht (es sei denn, ich brauch den selbst mal wieder). Auch kommentieren oder optimieren tue ich ihn nicht mehr. Siehe unten für eine kurze Erklärung zum Code.

Da ich ihn nicht ins Nirvana schicken will sei er hier für die Nachwelt festgehalten:

Code: Alles auswählen

EnableExplicit

Procedure.s giveCodeLine(line);, trim=1)
    DataSection
        beginSourceCode:
        IncludeBinary #PB_Compiler_File
        endSourceCode:
    EndDataSection
    Static Dim code.s(0), prepared
    If Not prepared
        Protected n, source.s=PeekS(?beginSourceCode, ?endSourceCode-?beginSourceCode, #PB_Ascii)
        prepared=CountString(source, #LF$)
        ReDim code(prepared)
        For n=1 To prepared
            code(n)=StringField(source, n, #LF$)
        Next
        
;         Protected separator=CreateRegularExpression(#PB_Any, "(?U).*\s", #PB_RegularExpression_AnyNewLine|#PB_RegularExpression_MultiLine)
;         prepared=ExtractRegularExpression(separator, PeekS(?beginSourceCode, ?endSourceCode-?beginSourceCode, #PB_Ascii), code())
;         FreeRegularExpression(separator)
; ;         Debug StringField(PeekS(?beginSourceCode, ?endSourceCode-?beginSourceCode, #PB_Ascii), line, #CR$)
;         Debug prepared
    EndIf
    If line < prepared And line > 0
        ProcedureReturn code(line)
    EndIf
;     Static bom, code.s;, exp_trimLine
;     If Not bom
;         bom=#PB_Ascii
;         If PeekS(?beginSourceCode, 3, #PB_Ascii) = ""
;             bom=#PB_UTF8
;             code=PeekS(?beginSourceCode+3, ?endSourceCode-?beginSourceCode-3, bom)
;         Else
;             bom=#PB_Ascii
;             code=PeekS(?beginSourceCode, ?endSourceCode-?beginSourceCode, bom)
;     EndIf
; ;     If Not exp_trimLine
; ;         exp_trimLine=CreateRegularExpression(#PB_Any, "^\s*")   ; ^\s* entfernt nur führende spaces
; ;         If Not exp_trimLine
; ;             Debug RegularExpressionError()
; ;             End
; ;         EndIf
; ;     EndIf
;     Protected exp_giveLine=CreateRegularExpression(#PB_Any, "(?U)(?<=\n{"+Str(line)+"}).*\n")
;     Protected Dim source.s(0)
;     source(0)=PeekS(?beginSourceCode, ?endSourceCode-?beginSourceCode, bom)
;     ProcedureReturn source(0)
EndProcedure

Debug giveCodeLine(3)
Debug giveCodeLine(#PB_Compiler_Line)
MessageRequester("B E I S P I E L", "Fehler im Programmablauf in Zeile 9:"+#CRLF$+"Array konnte nicht erstellt werden."+#CRLF$+#CRLF$+"Codezeile:"+#CRLF$+Trim(giveCodeLine(9)), #MB_ICONINFORMATION)
Diese Prozedur gibt eine beliebige Codezeile aus dem eigenem Programmcode zurück. Dazu wird der eigene Source-Code per Include in eine DataSection eingebunden. Anschließend wird mit StringField() drüber gegangen und die entsprechende Zeile ausgelesen. Bitte selber gucken, dass der Code mit der aktuellen PB Version funktioniert. Auch weiß ich gerade nicht, ob der Code Unicode-tauglich ist.


Der erste auskommentierte Codeblock war dazu gedacht, den Code per Regular Expression anhand der Zeilenumbrüche aufzuteilen um bessere Kompatiblität zwischen den verschiedenen Plattformen und ihren Zeilenumbrüchen zu erzielen. Die StringField()-Methode sucht einfach nur nach #LF$, was bei Windows (#CRLF$) unschön ist, denn StringField() akzeptiert nur ein Zeichen als Separator.

Der zwiete auskommentierte Codeblock sollte glaube ich automatisch feststellen, ob der eigene inkludierte Code Ascii oder Unicode ist; das Auslesen der eigentlichen Code-Zeile wollte ich elegant via Regular Expressions lösen. Scheint nicht ganz geklappt zu haben, sonst hätte ich beide Code-Blocks nicht auskommentiert. Vielleicht kriegt ihr das ja hin.