slandau Posted May 23, 2010 Share Posted May 23, 2010 So I'm getting a recursion error with my script. Here is the error it's spitting out: >"C:\Program Files (x86)\AutoIt3\SciTE\..\autoit3.exe" /ErrorStdOut "C:\Users\Scott\Documents\AutoItScripts\archive_tool.au3" C:\Users\Scott\Documents\AutoItScripts\archive_tool.au3 (52) : ==> Recursion level has been exceeded - AutoIt will quit to prevent stack overflow.: Local $fileList = _FileListToArray($dir) >Exit code: 1 Time: 23.433 And here is my script: expandcollapse popup;Tool to archive files with specific extensions grouped by that extension and kept in same file structure ;Will also keep original files in tact ;@Author - Scott Landau ;@Created - 5/23/2010 ;@Last Edited - 5/23/2010 ;Includes #include <File.au3> #include <Array.au3> #include <Zip.au3> ;Globals Local $tempExts = "txt|doc|cpp" Local $arrayExts = StringSplit($tempExts, "|") ;Methods ;Get the root directory for the archive ;@Return String Func getRoot() Local $root = InputBox("Root Directory", "Please enter the starting directory for the archive process...") Return $root EndFunc ;Gets all the subdirectories of the given directory ;@Param String ;@Return Array Func getAllDirs($dir) Local $added = 0 Local $dirs[1] Local $fileList = _FileListToArray($dir) Local $size = UBound($fileList) For $i = 0 to $size - 1 Local $pos = StringInStr($fileList[$i], ".") If ($pos == 0) Then If ($added == 0) Then $added = 1 $dirs[0] = $fileList[$i] Else _ArrayAdd($dirs, $fileList[$i]) EndIf EndIf Next Return $dirs EndFunc ;Gets all the files of the given directory ;@Param String ;@Return Array Func getAllFiles($dir) Local $added = 0 Local $files[1] Local $fileList = _FileListToArray($dir) Local $size = UBound($fileList) For $i = 0 to $size - 1 Local $pos = StringInStr($fileList[$i], ".") If Not ($pos == 0) Then If ($added == 0) Then $added = 1 $files[0] = $fileList[$i] Else _ArrayAdd($files, $fileList[$i]) EndIf EndIf Next Return $files EndFunc ;Get the file extension ;@Param String ;@Return String Func getExt($file) Local $ext Local $pos = StringInStr($file, ".") $ext = StringTrimLeft($file, $pos) Return $ext EndFunc ;Is bad extension? ;@Param String ;@Return Int Func isBad($file) Local $retval Local $ext = getExt($file) Local $pos = _ArraySearch($arrayExts, $ext) If Not ($pos == -1) Then $retval = 1 Else $retval = 0 EndIf Return $retval EndFunc ;Get all file extensions in current directory ;@Param String ;@Return Array Func getAllExts($dir) Local $added = 0 Local $allExts[1] Local $files = getAllFiles($dir) Local $max = UBound($files) For $i = 0 to $max - 1 Local $ext = getExt($files[$i]) If ($added == 0) Then $allExts[0] = $ext $added = 1 Else _ArrayAdd($allExts, $ext) EndIf Next EndFunc ;Actual archiving algorithm ;@Param String Func algorithm($dir) Local $dirs = getAllDirs($dir) Local $files = getAllFiles($dir) Local $allExts = getAllExts($dir) Local $numExts = UBound($arrayExts) Local $numFiles = UBound($files) For $i = 0 to $numExts - 1 Local $pos = _ArraySearch($allExts, $arrayExts[$i]) If Not ($pos == -1) Then $zip = _Zip_Create(@WorkingDir & "\" & $arrayExts[$i] & "_zip.zip") For $j = 0 to $numFiles - 1 Local $fileExt = getExt($files[$j]) If ($fileExt == $arrayExts[$i]) Then _Zip_AddFile($zip, $files[$j]) EndIf Next EndIf Next Local $numDirs = UBound($dirs) For $k = 0 to $numDirs - 1 algorithm($dirs[$k]) Next EndFunc ;Main archiving function to be run in 'Main' comment field ;Void Func main() Local $root = getRoot() algorithm($root) EndFunc ;Main main() As you can see there is a recursive call to itself within the algorithm($dir) method, however it is within a for loop meaning it should only call it if a number of directories exist. If none exist, it shouldn't call it at all so that should be the 'exit' to that recursion, so I don't know why it's giving me an error. Any ideas? Link to comment Share on other sites More sharing options...
BrettF Posted May 24, 2010 Share Posted May 24, 2010 Try search example scripts for weaponx's work on the subject. Cheers, Brett Vist my blog!UDFs: Opens The Default Mail Client | _LoginBox | Convert Reg to AU3 | BASS.au3 (BASS.dll) (Includes various BASS Libraries) | MultiLang.au3 (Multi-Language GUIs!)Example Scripts: Computer Info Telnet Server | "Secure" HTTP Server (Based on Manadar's Server)Software: AAMP- Advanced AutoIt Media Player | WorldCam | AYTU - Youtube Uploader Tutorials: Learning to Script with AutoIt V3Projects (Hardware + AutoIt): ArduinoUseful Links: AutoIt 1-2-3 | The AutoIt Downloads Section: | SciTE4AutoIt3 Full Version! Link to comment Share on other sites More sharing options...
jchd Posted May 24, 2010 Share Posted May 24, 2010 Be aware that: -) a directory name can contain (and even consist of) one or more dots -) a file name can contain one or more dots -) files can be extensionless. That alone undermines the behavior of your script in the general case. Also _FileListToArray doesn't return the full path, but can be passed a parameter to list directories or files (or both). Then you should probably be using the FileSelectFolder dialog to grab your root directory name. Better use the search feature to locate recent Melba23's recurvive directory traversal and build from there, or weaponx'. This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
omikron48 Posted May 24, 2010 Share Posted May 24, 2010 Still haven't figured out why your script recurs so much but what I did find is that the error message occurs during a getAllFiles call. I tried following the function calls a bit and it seems to be just a continuous loop of calls consisting of: algorithm, getAllDirs, getAllFiles, getAllExts, getAllFile... Dunno what it looks like in recursion levels though. I do agree that it would be much better for you to start off with a working search script then modify it or use it to your purpose. There are some quick recursive and stack-based search scripts here in the forums which can give full paths and filter between files and folders. Or, if you are feeling industrious for some reason, you can simply code one on your own. It's not make-your-brain-melt difficult to do. Link to comment Share on other sites More sharing options...
slandau Posted May 24, 2010 Author Share Posted May 24, 2010 Be aware that: -) a directory name can contain (and even consist of) one or more dots -) a file name can contain one or more dots -) files can be extensionless. That alone undermines the behavior of your script in the general case. Also _FileListToArray doesn't return the full path, but can be passed a parameter to list directories or files (or both). Then you should probably be using the FileSelectFolder dialog to grab your root directory name. Better use the search feature to locate recent Melba23's recurvive directory traversal and build from there, or weaponx'. I made a couple changes. Added the parameter with _FileListToArray, and have the user pick a folder now instead of type in a directory. However, now it doesn't even run. expandcollapse popup;Tool to archive files with specific extensions grouped by that extension and kept in same file structure ;Will also keep original files in tact ;@Author - Scott Landau ;@Created - 5/23/2010 ;@Last Edited - 5/23/2010 ;Includes #include <File.au3> #include <Array.au3> #include <Zip.au3> ;Globals Local $tempExts="ade|adp|app|asa|ashx|asp|bas|bat|cdx|cer|chm|class|cmd|com|cpl|crt|csh|der|exe|fxp|gadget|hlp|hta|htr|htw|ida|idc|idq|ins|isp|its|jse|ksh|lnk|mad|maf|mag|mam|maq|mar|mas|mat|mau|mav|maw|mda|mdb|mde|mdt|mdw|mdz|msc|msh|msh1|msh1xml|msh2|msh2xml|mshxml|msi|msp|mst|ops|pcd|pif|prf|prg|printer|pst|reg|rem|scf|scr|sct|shb|shs|shtm|shtml|soap|stm|url|vb|vbe|vbs|ws|wsc|wsf|wsh" Local $arrayExts = StringSplit($tempExts, "|") ;Methods ;Get the root directory for the archive ;@Return String Func getRoot() Local $root = FileSelectFolder("Select Root:", "C:\") Return $root EndFunc ;Gets all the subdirectories of the given directory ;@Param String ;@Return Array Func getAllDirs($dir) Local $folderList = _FileListToArray($dir, "*", 2) Return $folderList EndFunc ;Gets all the files of the given directory ;@Param String ;@Return Array Func getAllFiles($dir) Local $fileList = _FileListToArray($dir, "*", 1) Return $fileList EndFunc ;Get the file extension ;@Param String ;@Return String Func getExt($file) Local $ext Local $pos = StringInStr($file, ".") $ext = StringTrimLeft($file, $pos) Return $ext EndFunc ;Is bad extension? ;@Param String ;@Return Int Func isBad($file) Local $retval Local $ext = getExt($file) Local $pos = _ArraySearch($arrayExts, $ext) If Not ($pos == -1) Then $retval = 1 Else $retval = 0 EndIf Return $retval EndFunc ;Get all file extensions in current directory ;@Param String ;@Return Array Func getAllExts($dir) Local $added = 0 Local $allExts[1] Local $files = getAllFiles($dir) Local $max = UBound($files) For $i = 0 to $max - 1 Local $ext = getExt($files[$i]) If ($added == 0) Then $allExts[0] = $ext $added = 1 Else _ArrayAdd($allExts, $ext) EndIf Next EndFunc ;Actual archiving algorithm ;@Param String Func algorithm($dir) Local $dirs = getAllDirs($dir) Local $files = getAllFiles($dir) Local $allExts = getAllExts($dir) Local $numExts = UBound($arrayExts) Local $numFiles = UBound($files) For $i = 0 to $numExts - 1 Local $pos = _ArraySearch($allExts, $arrayExts[$i]) If Not ($pos == -1) Then $zip = _Zip_Create(@WorkingDir & "\" & $arrayExts[$i] & "_zip.zip") For $j = 0 to $numFiles - 1 Local $fileExt = getExt($files[$j]) If ($fileExt == $arrayExts[$i]) Then _Zip_AddFile($zip, $files[$j]) EndIf Next EndIf Next Local $numDirs = UBound($dirs) For $k = 0 to $numDirs - 1 algorithm($dirs[$k]) Next EndFunc ;Main archiving function to be run in 'Main' comment field ;Void Func main() Local $root = getRoot() algorithm($root) EndFunc ;Main main() Link to comment Share on other sites More sharing options...
evilertoaster Posted May 24, 2010 Share Posted May 24, 2010 What is #include <Zip.au3> ? If a remove that the script compiles... Link to comment Share on other sites More sharing options...
slandau Posted May 24, 2010 Author Share Posted May 24, 2010 What is #include <Zip.au3> ?If a remove that the script compiles...It compiles no matter what. It just doesn't do anything (not even error) anymore after choosing the directory and running the script.#include <Zip.au3> is required for the archiving process. Link to comment Share on other sites More sharing options...
bo8ster Posted May 25, 2010 Share Posted May 25, 2010 I always found stepping it out on paper to be most beneficial. Play the computer and step though it line by line. In the end it will save you lots of time. Post your code because code says more then your words can. SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y. Use Opt("MustDeclareVars", 1)[topic="84960"]Brett F's Learning To Script with AutoIt V3[/topic][topic="21048"]Valuater's AutoIt 1-2-3, Class... is now in Session[/topic]Contribution: [topic="87994"]Get SVN Rev Number[/topic], [topic="93527"]Control Handle under mouse[/topic], [topic="91966"]A Presentation using AutoIt[/topic], [topic="112756"]Log ConsoleWrite output in Scite[/topic] Link to comment Share on other sites More sharing options...
omikron48 Posted May 25, 2010 Share Posted May 25, 2010 (edited) I modified your script a bit to make tracking it a little easier. Apparently, your 'algorithm' function keeps recurring repeatedly even for a shallow folder containing few files. Modified script: expandcollapse popup;Tool to archive files with specific extensions grouped by that extension and kept in same file structure ;Will also keep original files in tact ;@Author - Scott Landau ;@Created - 5/23/2010 ;@Last Edited - 5/23/2010 ;Includes #include <File.au3> #include <Array.au3> ;#include <Zip.au3> ;Globals Local $tempExts = "txt|doc|cpp" Local $arrayExts = StringSplit($tempExts, "|") ;counters for functions Global $getAllDirs = 0, $getAllFiles = 0, $getAllExts = 0, $algorithm = 0 ;log file location Global $logpath = @DesktopDir & "\board.txt" ;writes line to log file Func _WriteLog($msg) $fhandle = FileOpen($logpath, 9) FileWriteLine($fhandle, $msg) FileClose($fhandle) EndFunc ;Methods ;Get the root directory for the archive ;@Return String Func getRoot() Local $root = InputBox("Root Directory", "Please enter the starting directory for the archive process...") Return $root EndFunc ;Gets all the subdirectories of the given directory ;@Param String ;@Return Array Func getAllDirs($dir1) ;write count to log file _WriteLog("getAllDirs" & @TAB & $getAllDirs) ;increase count by 1 on function start $getAllDirs += 1 Local $added = 0 Local $dirs[1] Local $fileList = _FileListToArray($dir1) Local $size = UBound($fileList) For $i = 0 to $size - 1 Local $pos = StringInStr($fileList[$i], ".") If ($pos == 0) Then If ($added == 0) Then $added = 1 $dirs[0] = $fileList[$i] Else _ArrayAdd($dirs, $fileList[$i]) EndIf EndIf Next ;decrease count by 1 one function exit $getAllDirs -= 1 Return $dirs EndFunc ;Gets all the files of the given directory ;@Param String ;@Return Array Func getAllFiles($dir2) _WriteLog("getAllFiles" & @TAB & $getAllFiles) $getAllFiles += 1 Local $added = 0 Local $files[1] Local $fileList = _FileListToArray($dir2) Local $size = UBound($fileList) For $i = 0 to $size - 1 Local $pos = StringInStr($fileList[$i], ".") If Not ($pos == 0) Then If ($added == 0) Then $added = 1 $files[0] = $fileList[$i] Else _ArrayAdd($files, $fileList[$i]) EndIf EndIf Next $getAllFiles -= 1 Return $files EndFunc ;Get the file extension ;@Param String ;@Return String Func getExt($file) Local $ext Local $pos = StringInStr($file, ".") $ext = StringTrimLeft($file, $pos) Return $ext EndFunc ;Is bad extension? ;@Param String ;@Return Int Func isBad($file) Local $retval Local $ext = getExt($file) Local $pos = _ArraySearch($arrayExts, $ext) If Not ($pos == -1) Then $retval = 1 Else $retval = 0 EndIf Return $retval EndFunc ;Get all file extensions in current directory ;@Param String ;@Return Array Func getAllExts($dir3) _WriteLog("getAllExts" & @TAB & $getAllExts) $getAllExts += 1 Local $added = 0 Local $allExts[1] Local $files = getAllFiles($dir3) Local $max = UBound($files) For $i = 0 to $max - 1 Local $ext = getExt($files[$i]) If ($added == 0) Then $allExts[0] = $ext $added = 1 Else _ArrayAdd($allExts, $ext) EndIf Next $getAllExts -= 1 EndFunc ;Actual archiving algorithm ;@Param String Func algorithm($dir) _WriteLog("algorithm" & @TAB & $algorithm) $algorithm += 1 Local $dirs = getAllDirs($dir) Local $files = getAllFiles($dir) Local $allExts = getAllExts($dir) Local $numExts = UBound($arrayExts) Local $numFiles = UBound($files) For $i = 0 to $numExts - 1 Local $pos = _ArraySearch($allExts, $arrayExts[$i]) If Not ($pos == -1) Then ; $zip = _Zip_Create(@WorkingDir & "\" & $arrayExts[$i] & "_zip.zip") For $j = 0 to $numFiles - 1 Local $fileExt = getExt($files[$j]) If ($fileExt == $arrayExts[$i]) Then ; _Zip_AddFile($zip, $files[$j]) EndIf Next EndIf Next Local $numDirs = UBound($dirs) For $k = 0 to $numDirs - 1 algorithm($dirs[$k]) Next $algorithm -= 1 EndFunc ;Main archiving function to be run in 'Main' comment field ;Void Func main() Local $root = getRoot() algorithm($root) EndFunc ;Main main() Input used in testing: "D:\_Setup\Kiosk" Contents of folder used for testing: D:\_Setup\Kiosk\antivirus.bat D:\_Setup\Kiosk\pcsetup.bat D:\_Setup\Kiosk\wallpaper.bat D:\_Setup\Kiosk\files\SetWallpaper.exe D:\_Setup\Kiosk\files\CB.url D:\_Setup\Kiosk\files\Autorun.reg D:\_Setup\Kiosk\files\nt2kxp2k3.exe D:\_Setup\Kiosk\files\RB.url EDIT: Upon further inspection of your code, I think I may have found the root of your problem. You keep using _FileListToArray but you use UBound to get the array size. Thing is, _FileListToArray returns an array with the [0] element containing the count of the elements returned. Using UBound on that will always give you a value of at least 1. That's why your recursion doesn't terminate. Edited May 25, 2010 by omikron48 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now