String/Array Problem ?

  • Moin,

    ich verstehe mal wieder gar nichts mehr... ?(

    Mein Skript soll Funktionen die in einem AutoItScript genutzt werden aus den UDF kopieren und in eine Datei schreiben.
    Der SyntaxCeck ist i.O., Return ist 0, aber es wird nichts in die Datei geschrieben.
    Bin ich schon wieder zu unlogisch ???

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <File.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global $ArUDF
    Global $ScriptFile = FileOpenDialog('Select Source Script', 'c:\Downloads\AutoIt-Skripte\Entwicklung\ForumTests\', '(*.au3)', 0, 'Source.au3')
    Global $StrScriptFile = FileRead(FileOpen($ScriptFile, 0))
    Global $ScriptFunction = _Search_FuncInSource()
    Global $OptScript = FileOpen('Opt.au3', 1)
    ;_ArraySort($ScriptFunction)
    ;_ArrayDisplay($ScriptFunction)
    _Search_FuncInInclude()

    ;Search for _Functions in Source File
    Func _Search_FuncInSource()
    $funcs = StringRegExp($StrScriptFile, '_[a-zA-Z0-9]+(?=[ ]*\()', 3)
    Return _ArrayUnique($funcs)
    EndFunc ;==>_Search_FuncInSource

    Func _ArrayUnique(ByRef $aArray, $vDelim = '', $iBase = 1, $iUnique = 1)
    If $vDelim = '' Then $vDelim = Chr(01)
    Local $sHold
    For $iCC = $iBase To UBound($aArray) - 1
    If Not StringInStr($vDelim & $sHold, $vDelim & $aArray[$iCC] & $vDelim, $iUnique) Then _
    $sHold &= $aArray[$iCC] & $vDelim
    Next
    Return StringSplit(StringTrimRight($sHold, StringLen($vDelim)), $vDelim)
    EndFunc ;==>_ArrayUnique

    [/autoit] [autoit][/autoit] [autoit]

    ; Search and extract Functions from UDF file
    Func _Search_FuncInInclude()
    $ArFiles = _FileListToArray(@ProgramFilesDir & '\AutoIt3\Include', '*.au3', 1)
    For $i = 1 To $ArFiles[0]
    If StringInStr($StrScriptFile, $ArFiles[$i]) Then
    _FileReadToArray(@ProgramFilesDir & '\AutoIt3\Include\' & $ArFiles[$i], $ArUDF)
    FileWriteLine($OptScript, '')
    _Extract_Func()
    EndIf

    Next
    EndFunc
    ; Extract Function and writes to file
    Func _Extract_Func()
    For $i = 1 To $ArUDF[0]
    For $int = 0 To UBound($ScriptFunction)-2
    If StringInStr($ArUDF[$i], 'Func ' & $ScriptFunction[$int]) Then
    Do
    FileWriteLine($OptScript, $ArUDF[$i])
    $i += 1
    Until StringInStr($ArUDF[$i], 'EndFunc') <> 0
    FileWriteLine($OptScript, $ArUDF[$i])
    FileWriteLine($OptScript, '')
    EndIf
    Next
    Next

    EndFunc

    [/autoit]


    Gruß
    Greenhorn


    • Offizieller Beitrag

    Hi,

    mit Regexpwäre sicher schneller, abastel du erstmal :)

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <File.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global $ArUDF
    Global $ScriptFile = FileOpenDialog('Select Source Script', 'c:\Downloads\AutoIt-Skripte\Entwicklung\ForumTests\', '(*.au3)', 0, 'Source.au3')
    Global $StrScriptFile = FileRead(FileOpen($ScriptFile, 0))
    Global $ScriptFunction = _Search_FuncInSource()
    If Not FileExists(@ScriptDir & '\Opt.au3') Then _FileCreate(@ScriptDir & '\Opt.au3')
    Global $OptScript = FileOpen(@ScriptDir & '\Opt.au3', 1)
    ;_ArraySort($ScriptFunction)
    ;_ArrayDisplay($ScriptFunction)
    _Search_FuncInInclude()

    [/autoit] [autoit][/autoit] [autoit]

    ;Search for _Functions in Source File
    Func _Search_FuncInSource()
    $funcs = StringRegExp($StrScriptFile, '_[a-zA-Z0-9]+(?=[ ]*\()', 3)
    Return _ArrayUnique($funcs)
    EndFunc ;==>_Search_FuncInSource

    [/autoit] [autoit][/autoit] [autoit]

    Func _ArrayUnique(ByRef $aArray, $vDelim = '', $iBase = 1, $iUnique = 1)
    If $vDelim = '' Then $vDelim = Chr(01)
    Local $sHold
    For $iCC = $iBase To UBound($aArray) - 1
    If Not StringInStr($vDelim & $sHold, $vDelim & $aArray[$iCC] & $vDelim, $iUnique) Then _
    $sHold &= $aArray[$iCC] & $vDelim
    Next
    Return StringSplit(StringTrimRight($sHold, StringLen($vDelim)), $vDelim)
    EndFunc ;==>_ArrayUnique

    [/autoit] [autoit][/autoit] [autoit]

    ; Search and extract Functions from UDF file
    Func _Search_FuncInInclude()
    $ArFiles = _FileListToArray(@ProgramFilesDir & '\AutoIt3\Include', '*.au3', 1)
    For $i = 1 To $ArFiles[0]
    If StringInStr($StrScriptFile, $ArFiles[$i]) Then
    _FileReadToArray(@ProgramFilesDir & '\AutoIt3\Include\' & $ArFiles[$i], $ArUDF)
    FileWriteLine($OptScript, '')
    _Extract_Func()
    EndIf

    Next
    EndFunc ;==>_Search_FuncInInclude
    ; Extract Function and writes to file
    Func _Extract_Func()
    For $i = 1 To $ArUDF[0]
    For $int = 0 To UBound($ScriptFunction) - 2
    If StringInStr($ArUDF[$i], 'Func ' & $ScriptFunction[$int]) Then
    Do
    ConsoleWrite($ArUDF[$i] & @CRLF)
    FileWriteLine($OptScript, $ArUDF[$i])
    $i += 1
    Until StringInStr($ArUDF[$i], 'EndFunc') <> 0
    FileWriteLine($OptScript, $ArUDF[$i])
    FileWriteLine($OptScript, '')
    EndIf
    Next
    Next

    EndFunc ;==>_Extract_Func

    [/autoit]

    So long,

    Mega

  • Läuft prima ! Danke Mega !

    Aber wieso muss ich ConsoleWrite benutzen, oder lag's an der Pfadangabe zur Opt.au3 ???

    Mit StringRegExp habe ich probleme sobald ich unbekannte/breit gestreute Pattern brauche.
    So wie Du ($funcs = StringRegExp($StrScriptFile, '_[a-zA-Z0-9]+(?=[ ]*\()', 3)) kriege ich das noch nicht hin ! :(
    Mein Programmierstil ist noch zu umständlich und oftmals auch zu unlogisch/verworren. :baby:

    Aber wer weiss, kann ja alles noch kommen... ;)


    Gruß
    Greenhorn


  • Jetzt möchte ich gern mit StringRegExpReplace den String '#include <Xxx.au3>' entfernen, jetzt weiss ich nicht wie ich es definieren soll, oder es liegt an den Zeichen < und > ?!

    Etwa so... StringRegExpReplace($StrScriptFile, '#include <[A-Za-z].au3>, '')'
    Oder wie muss ich es definieren ???

    Gruß


    Einmal editiert, zuletzt von Greenhorn (30. Juni 2007 um 19:00)

  • Ja die Zeilen sollen gelöscht werden...

    Die Definition funzt hervorragend ! =)
    Vielleicht begreife ich die Zeichensetzung ja irgendwann... ;)

    Jetzt muss ich mein/unser Stückwerk erstmal aufarbeiten.
    Das grobe Gerüst steht, auch wenn etwas umständlich, aber es funzt erstmal.
    Vieleicht frage ich dich noch mal nach verbesserungsvorschlägen, wenn Du erlaubst...


    Gruß


  • Weit bin ich noch nicht gekommen, aber hier hat sich schon mal der Quellcode selbst optimiert... ;)

    Ich weiss noch nicht wie ich das ganze verpacken will/soll, als GUI oder als .exe mit Parametern ?!?
    Vielleicht beides oder ein Mix daraus...

    au3Optimizer über's Kontextmenü starten (optional)

    Spoiler anzeigen
    [autoit]


    #cs ----------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit]

    AutoIt Version: 3.2.4.9
    Author: Greenhorn

    [/autoit] [autoit][/autoit] [autoit]

    Script Function:
    Registryeinträge für das Kontextmenü. (Optimize Script)

    [/autoit] [autoit][/autoit] [autoit]

    #ce ----------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit]

    RegWrite("HKLM\SOFTWARE\Classes\AutoIt3Script\Shell\Optimize Script\Command", _ ; Registryeinträge für das Kontextmenü.
    "", "REG_SZ", '"' & @ProgramFilesDir & "\AutoIt3\au3Optimizer.exe" & '" "%1"') ; au3Optimizer muss im AutoIt3 Ordner zu finden sein.
    Exit

    [/autoit] [autoit][/autoit] [autoit]

    ; Delete Shell Command
    ;RegDelete('HKLM\SOFTWARE\Classes\AutoIt3Script\Shell\Optimize Script')

    [/autoit]

    au3Optimizer
    (Enthält zwei UDFs --> Kompilierte Größe: 209.646 KB, unoptimiert: 240.624 KB)

    Spoiler anzeigen
    [autoit]


    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_outfile=D:\Programme\AutoIt3\Au3Optimizer.exe
    #AutoIt3Wrapper_Res_Comment=Includes only the Funktions which are needed to run Script
    #AutoIt3Wrapper_Res_Description=Optimizes your au3 Files
    #AutoIt3Wrapper_Res_Fileversion=0.5.0.1
    #AutoIt3Wrapper_Res_Language=1031
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
    #cs ----------------------------------------------------------------------------

    AutoIt Version: 3.2.4.9
    Author: Greenhorn

    Script Function:
    AutoIt Code Minimizer.
    Includes only the Funktions which are needed to run Script.

    #ce ----------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    If $cmdline[0] <> 0 Then
    Global $ScriptFile = $cmdline[1]
    Else
    Global $ScriptFile = FileOpenDialog('Select Source Script', _
    'c:\Downloads\AutoIt-Skripte\Entwicklung\ForumTests\', '(*.au3)', 0, 'Source.au3')
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    #region Main
    Global $ArUDF
    Global $StrScriptFile = FileRead(FileOpen($ScriptFile, 0))
    Global $ScriptFunction = _Search_FuncInSource()
    ; Hier würde ich gern @error setzen, funzt aber nicht...
    FileCopy($ScriptFile, StringRegExpReplace($ScriptFile, '.au3', 'Bak.au3'))
    Global $OptScript = FileOpen($ScriptFile, 2)
    FileWrite($OptScript, StringRegExpReplace($StrScriptFile, '(?i)#include[ ]*<[ ]*.*\.au3[ ]*>', ''))
    FileWriteLine($OptScript, '')
    FileWriteLine($OptScript, '#Region User Defiened Funktions')
    _Search_FuncInInclude()
    FileWriteLine($OptScript, '#EndRegion User Defiened Funktions')
    FileClose($OptScript)
    Exit
    #endregion

    [/autoit] [autoit][/autoit] [autoit]

    #region Funktions
    ; Search for _Functions in Source File
    Func _Search_FuncInSource()
    $funcs = StringRegExp($StrScriptFile, '_[a-zA-Z0-9]+(?=[ ]*\()', 3)
    If @error = 1 Then
    MsgBox(64, '', 'Das Skript enthält keine benutzerdefinierten Funktionen')
    Exit
    EndIf
    Return _ArrayUnique($funcs)
    EndFunc ;==>_Search_FuncInSource

    Func _ArrayUnique(ByRef $aArray, $vDelim = '', $iBase = 1, $iUnique = 1)
    If $vDelim = '' Then $vDelim = Chr(01)
    Local $sHold
    For $iCC = $iBase To UBound($aArray) - 1
    If Not StringInStr($vDelim & $sHold, $vDelim & $aArray[$iCC] & $vDelim, $iUnique) Then _
    $sHold &= $aArray[$iCC] & $vDelim
    Next
    Return StringSplit(StringTrimRight($sHold, StringLen($vDelim)), $vDelim)
    EndFunc ;==>_ArrayUnique

    ; Search and extract Functions from UDF file
    Func _Search_FuncInInclude()
    $ArFiles = _FileListToArray(@ProgramFilesDir & '\AutoIt3\Include', '*.au3', 1)
    For $i = 1 To $ArFiles[0]
    If StringInStr($StrScriptFile, $ArFiles[$i]) Then
    _FileReadToArray(@ProgramFilesDir & '\AutoIt3\Include\' & $ArFiles[$i], $ArUDF)
    _Extract_Func()
    EndIf
    Next
    EndFunc ;==>_Search_FuncInInclude
    ; Extract Function and writes to file
    Func _Extract_Func()
    For $i = 1 To $ArUDF[0]
    For $int = 0 To UBound($ScriptFunction) - 2
    If StringInStr($ArUDF[$i], 'Func ' & $ScriptFunction[$int]) Then
    Do
    ConsoleWrite($ArUDF[$i] & @CRLF)
    FileWriteLine($OptScript, $ArUDF[$i])
    $i += 1
    Until StringInStr($ArUDF[$i], 'EndFunc') <> 0
    FileWriteLine($OptScript, $ArUDF[$i])
    FileWriteLine($OptScript, '')
    EndIf
    Next
    Next

    EndFunc ;==>_Extract_Func
    #endregion

    [/autoit] [autoit][/autoit] [autoit]

    #Region User Defiened Funktions

    [/autoit] [autoit][/autoit] [autoit]

    Func _FileListToArray($sPath, $sFilter = "*", $iFlag = 0)
    Local $hSearch, $sFile, $asFileList[1]
    If Not FileExists($sPath) Then Return SetError(1, 1, "")
    If (StringInStr($sFilter, "\")) Or (StringInStr($sFilter, "/")) Or (StringInStr($sFilter, ":")) Or (StringInStr($sFilter, ">")) Or (StringInStr($sFilter, "<")) Or (StringInStr($sFilter, "|")) Or (StringStripWS($sFilter, 8) = "") Then Return SetError(2, 2, "")
    If Not ($iFlag = 0 Or $iFlag = 1 Or $iFlag = 2) Then Return SetError(3, 3, "")
    $hSearch = FileFindFirstFile($sPath & "\" & $sFilter)
    If $hSearch = -1 Then Return SetError(4, 4, "")
    While 1
    $sFile = FileFindNextFile($hSearch)
    If @error Then
    SetError(0)
    ExitLoop
    EndIf
    If $iFlag = 1 And StringInStr(FileGetAttrib($sPath & "\" & $sFile), "D") <> 0 Then ContinueLoop
    If $iFlag = 2 And StringInStr(FileGetAttrib($sPath & "\" & $sFile), "D") = 0 Then ContinueLoop
    ReDim $asFileList[UBound($asFileList) + 1]
    $asFileList[0] = $asFileList[0] + 1
    $asFileList[UBound($asFileList) - 1] = $sFile
    WEnd
    FileClose($hSearch)
    Return $asFileList
    EndFunc ;==>_FileListToArray

    [/autoit] [autoit][/autoit] [autoit]

    Func _FileReadToArray($sFilePath, ByRef $aArray)
    ;==============================================
    ; Local Constant/Variable Declaration Section
    ;==============================================
    Local $hFile

    [/autoit] [autoit][/autoit] [autoit]

    $hFile = FileOpen($sFilePath, 0)

    [/autoit] [autoit][/autoit] [autoit]

    If $hFile = -1 Then
    SetError(1)
    Return 0
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $aArray = StringSplit(StringStripCR(FileRead($hFile, FileGetSize($sFilePath))), @LF)

    [/autoit] [autoit][/autoit] [autoit]

    FileClose($hFile)
    Return 1
    EndFunc ;==>_FileReadToArray

    [/autoit] [autoit][/autoit] [autoit]

    #EndRegion User Defiened Funktions

    [/autoit] [autoit][/autoit] [autoit][/autoit]

    Jetzt müsste ich den Code im Hauptskript etwas übersichtlicher gestalten und überflüssige Leerzeilen entfernen, ist irgendwie 'n ganz schönes Kuddelmuddel...

    Gruß


    11 Mal editiert, zuletzt von Greenhorn (1. Juli 2007 um 19:45)