That’s good Nigel, thanks. I’ve been playing around with spotlight for the last week so it’s in my mind. I think the fastest search would be to use spotlight. So I came up with a spotlight command to find the error files. I matched it to my original method and your revised method, and all 3 methods find the exact same files. Here’s the spotlight command and the script runs extremely fast now! After running 1 search subsequent searches are instantaneous. There must be some caching thing going on.
set filter to "(kMDItemDisplayName == \"Errors.h\"w || kMDItemDisplayName == \"mig_errors.h\") && kMDItemDisplayName != \"DRCoreErrors.h\" && kMDItemDisplayName != \"NSErrors.h\""
set errorFilesList to paragraphs of (do shell script "mdfind -onlyin /System/Library/Frameworks " & quoted form of filter)
And here’s the whole script now with the spotlight command. The formatting of the files is the crazy part. I have a hard time understanding it myself. Please optimize it if you can but it is fast as it is. I’m more interested in finding out if I made any mistakes… am I returning everything that needs to be returned? Because the code is so crazy I can’t be certain it’s 100% accurate.
-- This script will search the error code files on your computer
-- explanation about error code files was found here:
-- http://developer.apple.com/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/ErrorHandling/ErrorHandling.html
property errorNum : ""
global errorFilesList, errorFilesDomain, errorFilesNames
(*============= COMPILE A LIST OF ALL THE ERROR FILES FOUND ON YOUR COMPUTER =============*)
-- 3 lists are made in this section; errorFilesList, errorFilesDomain, and errorFilesNames
set errorFilesList to {"/usr/include/mach/kern_return.h", "/usr/include/sys/errno.h"}
set errorFilesDomain to {"Mach", "POSIX"}
-- add the Errors.h files in the /System/Library/Frameworks directory including the mig_errors.h file
-- the "w" option means filter by words where words are also denoted by transition from uppercase to lowercase too
-- this "w" option filters out almost all the unwanted "error.h" files like the ones in the "Python.framework" path
-- we also remove DRCoreErrors.h and NSErrors.h because they don't have any error codes in them
set theFilter to "(kMDItemDisplayName == \"Errors.h\"w || kMDItemDisplayName == \"mig_errors.h\") && kMDItemDisplayName != \"DRCoreErrors.h\" && kMDItemDisplayName != \"NSErrors.h\""
set errorFilesList to errorFilesList & paragraphs of (do shell script "mdfind -onlyin /System/Library/Frameworks " & quoted form of theFilter)
-- add Cocoa/Carbon to errorFilesDomain for each file in errorFilesList
repeat with i from 3 to (count of errorFilesList)
if (item i of errorFilesList) ends with "MacErrors.h" then
set end of errorFilesDomain to "Carbon"
else
set end of errorFilesDomain to "Cocoa"
end if
end repeat
-- get the list of file names
set errorFilesNames to getFileNames(errorFilesList)
repeat
(*============= GET THE ERROR NUMBER FROM THE USER =============*)
repeat
display dialog "This will use all of the error header files on your computer to locate an error code for you." & return & return & "Please enter the error code to find:" default answer errorNum with icon note buttons {"Cancel", "OK"} default button "OK" with title "Error Codes"
set {errorNum, button_pressed} to {text returned, button returned} of the result
if errorNum is not "" then
try
set numCheck to errorNum as number
exit repeat
on error
display dialog "Please enter only numbers!" buttons {"OK"} default button 1
end try
end if
end repeat
set formattedError to ""
repeat with theCounter from 1 to (count of errorFilesList)
set thisFile to item theCounter of errorFilesList
try
(*============= GREP THE FILES FOR THE ERROR NUMBER =============*)
if (item theCounter of errorFilesNames) is "kern_return.h" then
-- kern_return.h has the error description on multiple lines so we need to get a bunch of lines after the error number
if (errorNum as number) is greater than or equal to 0 then
set cmd to "grep -w --after-context=20 " & quoted form of errorNum & space & quoted form of thisFile & " | grep -v " & quoted form of ("\\-" & errorNum) & " | /usr/bin/grep -wi --after-context=20 \"#define\""
else
set cmd to "grep -w --after-context=20 " & quoted form of ("\\" & errorNum) & space & quoted form of thisFile & " | /usr/bin/grep -wi --after-context=20 \"#define\""
end if
set tempVar to do shell script cmd
set text item delimiters to "*/"
set tempVar to item 1 of (text items of tempVar)
set text item delimiters to ""
set errorParas to {tempVar}
else
if (errorNum as number) is greater than or equal to 0 then
set cmd to "grep -w " & quoted form of errorNum & space & quoted form of thisFile & " | grep -v " & quoted form of ("\\-" & errorNum)
else
set cmd to "grep -w " & quoted form of ("\\" & errorNum) & space & quoted form of thisFile
end if
set tempVar to do shell script cmd
set errorParas to paragraphs of tempVar
end if
repeat with j from 1 to (count of errorParas)
set errorText to item j of errorParas
(*============= REMOVE MISC CHARACTERS FROM THIS RESULT AND FORMAT IT =============*)
set theChars to {return, tab, "*", "/", "#define", "=", ",", errorNum, space}
repeat with aChar in theChars
set errorText to remove_chars(errorText, aChar)
end repeat
set aFormattedError to displayFormat(errorText, theCounter)
set formattedError to formattedError & return & aFormattedError
end repeat
end try
end repeat
(*============= GIVE THE RESULTS A FINAL FORMAT AND DISPLAY THEM =============*)
if formattedError is not "" then set formattedError to finalFormat(formattedError)
-- display the results
if formattedError is "" then
display dialog "The error numbered " & errorNum & " could not be found" buttons {"Quit", "Search Again"} default button 2
if button returned of the result is "Quit" then exit repeat
else
set finalErrorSting to "Results for error number ---> " & errorNum & return & return & formattedError
display dialog finalErrorSting buttons {"Quit", "Save Results", "Search Again"} default button 1
set theButton to button returned of result
if theButton is "Quit" then
exit repeat
else if theButton is "Save Results" then
set saveFile to choose file name with prompt "Specify where you want the file saved." default name "untitled.txt"
writeTo(finalErrorSting, saveFile, false, string)
exit repeat
end if
end if
end repeat
(*===================== SUBROUTINES ===================*)
on writeTo(this_data, target_file, append_data, mode) -- append_data is true or false, mode is string etc. (no quotes around either)
try
set target_file to target_file as Unicode text
if target_file does not contain ":" then set target_file to POSIX file target_file as Unicode text
set the open_target_file to open for access file target_file with write permission
if append_data is false then set eof of the open_target_file to 0
write this_data to the open_target_file starting at eof as mode
close access the open_target_file
return true
on error
try
close access file open_target_file
end try
return false
end try
end writeTo
on remove_chars(theString, aChar)
set {TIDs, text item delimiters} to {text item delimiters, aChar}
set a to text items of theString
set b to {}
repeat with i from 1 to (count of a)
if item i of a is not "" then
set end of b to item i of a
end if
end repeat
set text item delimiters to space
set c to b as text
set text item delimiters to TIDs
return c
end remove_chars
on getFileNames(theList_ofPaths)
set z to {}
set text item delimiters to "/"
repeat with anItem in theList_ofPaths
set end of z to (item -1 of (text items of anItem))
end repeat
set text item delimiters to ""
return z
end getFileNames
on displayFormat(a, theCounter)
set text item delimiters to space
set b to text items of a
set errorDef to item 1 of b
try
set errorDesc to (items 2 thru -1 of b) as text
on error
set errorDesc to errorDef
end try
set text item delimiters to ""
set aFormattedError to "Error Domain: " & (item theCounter of errorFilesDomain) & return & "Error File Name: " & (item theCounter of errorFilesNames) & return & "Error Name: " & errorDef & return & "Error Description: " & errorDesc & return
return aFormattedError
end displayFormat
on finalFormat(formattedError)
set text item delimiters to return
set b to text items of formattedError
set b to items 2 thru -2 of b
set formattedError to b as text
set text item delimiters to ""
return formattedError
end finalFormat