medfall

A super great game engine
Log | Files | Refs

leak_check.lua (1647B)


      1 #! /usr/bin/lua
      2 
      3 local lpeg = require( "lpeg" )
      4 local json = require( "cjson.safe" )
      5 
      6 -- b_ = begin
      7 -- e_ = end
      8 -- ne_ = not end
      9 -- slc = single line comment
     10 -- mlc = multiline comment
     11 local b_slc = lpeg.P( "//" )
     12 local e_slc = lpeg.P( "\n" )
     13 local ne_slc = ( 1 - e_slc ) ^ 0
     14 local slc = b_slc * ne_slc
     15 
     16 local b_mlc = lpeg.P( "/*" )
     17 local e_mlc = lpeg.P( "*/" )
     18 local ne_mlc = ( 1 - e_mlc ) ^ 0
     19 local mlc = b_mlc * ne_mlc * e_mlc
     20 
     21 local quote = lpeg.P( "\"" )
     22 local escaped = lpeg.P( "\\" ) * 1
     23 local string = quote * ( escaped + ( 1 - quote ) ) ^ 0 * quote
     24 
     25 local comments = slc + mlc
     26 local none = 1 - ( string + comments )
     27 
     28 local just_code = ( comments + string + lpeg.C( none ^ 1 ) ) ^ 0
     29 
     30 local f = io.open( arg[ 1 ] )
     31 local contents = f:read( "*all" )
     32 local stripped = table.concat( { just_code:match( contents ) } )
     33 
     34 local function check_leaks( leaks, levels, depth, body )
     35 	for code, block in ( body .. "{}" ):gmatch( "(.-)(%b{})" ) do
     36 		if code == "" and block == "{}" then
     37 			break
     38 		end
     39 
     40 		for line in code:gmatch( "([^\n]+)" ) do
     41 			if line:find( "memarena_push" ) then
     42 				if not levels[ depth ] then
     43 					table.insert( leaks, line )
     44 				end
     45 			end
     46 
     47 			if line:find( "MEMARENA_SCOPED_CHECKPOINT" ) then
     48 				levels[ depth ] = true
     49 			end
     50 		end
     51 
     52 		if not cp then
     53 			levels[ depth + 1 ] = false
     54 			check_leaks( leaks, levels, depth + 1, block:sub( 2, -2 ) )
     55 			levels[ depth + 1 ] = nil
     56 		end
     57 	end
     58 end
     59 
     60 for ret, name, args, body in stripped:gmatch( "([^\n]-)%s*([^%s]+)(%b())\n? *(%b{})" ) do
     61 	local leaks = { }
     62 	check_leaks( leaks, { false }, 1, body )
     63 
     64 	if #leaks > 0 then
     65 		print( name )
     66 		print( table.concat( leaks, "\n" ) )
     67 	end
     68 end