how to check for unnecessary local declarations?

Peter M. Brigham pmbrig at
Wed Jul 8 19:15:03 CEST 2015

Late to the party, but here's another approach (not fully tested). Iterate the function over the full list of stacks/cards/controls of your stacks.

-- Peter

Peter M. Brigham
pmbrig at


function findUnusedLocals pObjRef
   -- returns a cr-delimited list of handlerName, tLocal
   --    where tLocal is a declared local not used in the handler handlerName
   put the revAvailableHandlers of pObjRef into hList
   delete word 5 to -1 of line 1 of hList
   -- to cope with the odd format of revAvailableHandlers
   repeat for each line h in hList
      put word 1 to 2 of h into hName
      put caseSwitch(word 1 of hName,"F=function","M=command","G=getprop","S=setprop","*=*") \
            into tType
      put tType into word 1 of hName
      put getHandlerFromScript(pObjRef,word 2 of hName, tType) into thisHandler
      put thisHandler into theLocals
      filter theLocals with "   local *"
      replace "   local " with empty in theLocals
      replace comma & space with cr in theLocals
      replace comma with cr in theLocals
      filter thisHandler without "   local *"
      repeat for each line L in theLocals
         if L is among the words of thisHandler then next repeat
         put hName & comma && L & cr after orphanedList
      end repeat
   end repeat
   delete char -1 of orphanedList
   return pObjRef & cr & orphanedList
end findUnusedLocals

function getHandlerFromScript pObjRef, pHandlerName, pType
   -- returns the specified handler from the script of pObjRef
   -- pHandlerName should be the bare name of the handler
   -- if you have duplicate handler names, eg, a function and a command with
   --    the same name, or getprop and setprop handlers with the same name,
   --    then both/all will be returned, unless you specify the optional pType
   --       as "function" or "command" or "getprop" or "setprop"
   -- if not found, returns "no such handler:" && pType && pHandlerName
   -- by Peter M. Brigham, pmbrig at — freeware,
   --    based on a discussion on the use-LC list
   -- requires caseSwitch()
   put the script of pObjRef into tScript
   put the revAvailableHandlers of pObjRef into hList
   delete word 5 to -1 of line 1 of hList
   -- to cope with the odd format of revAvailableHandlers
   filter hList with "* " & pHandlerName & " *"
   -- now we have all lines with the handlerName
   put caseSwitch(pType,"function=F","command=M","getprop=G","setprop=S","*=*") \
         into tType
   if tType <> empty then
      -- get only the line with the correct type
      put cr before hList
      set the casesensitive to true
      replace cr & "P" with cr in hList
      filter hList with tType & " *"
   end if
   if hList = empty then
      put "no such handler:" && pType && pHandlerName into tError
      replace "  " with space in tError -- in case pType is empty
      return tError
   end if
   repeat for each line h in hList
      put line (word 3 of h) to (word 4 of h) of tScript & cr & cr after outScript
   end repeat
   delete char -2 to -1 of outScript
   return outScript
end getHandlerFromScript

function caseSwitch
   -- does a quick inline switch/case
   -- param 1 is checkValue
   -- params 2+ are in the form matchValue(s)=returnValue
   --    separate multiple matchValues with commas
   --    and enclose each matchValue=returnValue pair in quotes
   -- if checkValue matches one or more items in matchValue(s),
   --    returns returnValue
   -- use a matchValue of "*" to specify a default value,
   --    to be returned if no matches found in the list
   --    if the default is "*=*" then no match returns the original checkValue
   --    if no match and no default value specified, then returns empty
   -- examples:
   --    put caseSwitch(len(tZip),"5=zip","10=zip+4","*=not a zip code") \
      --             into zipCodeType
   --    put caseSwitch(item 1 of the abbr date,"Sat,Sun=weekend","*=weekday") \
      --             into dayType
   -- from Ken Ray, use-LC list, originally named stsSwitch()
   -- revised by Peter M. Brigham, pmbrig at
   --    to allow for an empty checkValue, eg "=no input"
   --    or ",4,5=other" or "4,,5=other" or "4,5,=other"
   --    meaning, if checkValue is 4 or 5 or empty, return "other"
   put param(1) into tCheckValue
   set the itemDel to "="
   repeat with x = 2 to the paramCount
      put param(x) into tCheck
      put item 1 of tCheck into tMatch
      put item 2 of tCheck into tRetVal
      replace "," with "=" in tMatch
      -- to avoid having to switch itemdelimiters
      if tCheckValue = empty and tMatch = empty then return tRetVal
      if tCheckValue = empty and (char 1 of tMatch = "=" or char -1 of tMatch = "=" \
            or "==" is in tMatch) then return tRetVal
      if tCheckValue is among the items of tMatch then return tRetVal
      if tMatch = "*" then
         if tRetVal = "*" then
            put tCheckValue into tDefault
            put tRetVal into tDefault
         end if
         return tDefault
      end if
   end repeat
end caseSwitch

On Jul 6, 2015, at 4:00 PM, Bob Sneidar wrote:

> Thanks Mark. The code to get the script locals looks suspiciously like what I suggested. Are you sure Jerry didn’t use Jacques Time Travel stack to steal my code??
> Bob S
>> On Jul 3, 2015, at 11:53 , Mark Wieder <mwieder at> wrote:
>> On 07/03/2015 11:11 AM, Peter Haworth wrote:
>>> Nice!  Only thing I don't see is dealing with block comments - the things
>>> surrounded by "/*" and "*/" and possibly spanning several lines.
>> There's some DRY cleanup that could be done as well.
>> Feel free to make it better and submit the changes.
>> It's all on bitbucket, and unfortunately it's a LiveCode stack rather than text files so you can't submit git pull requests, but drop me a note or create an issue.
>> -- 
>> Mark Wieder
>> ahsoftware at
> _______________________________________________
> use-livecode mailing list
> use-livecode at
> Please visit this url to subscribe, unsubscribe and manage your subscription preferences:

More information about the use-livecode mailing list