medfall

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

leakcheck.lua (1647B)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#! /usr/bin/lua

local lpeg = require( "lpeg" )
local json = require( "cjson.safe" )

-- b_ = begin
-- e_ = end
-- ne_ = not end
-- slc = single line comment
-- mlc = multiline comment
local b_slc = lpeg.P( "//" )
local e_slc = lpeg.P( "\n" )
local ne_slc = ( 1 - e_slc ) ^ 0
local slc = b_slc * ne_slc

local b_mlc = lpeg.P( "/*" )
local e_mlc = lpeg.P( "*/" )
local ne_mlc = ( 1 - e_mlc ) ^ 0
local mlc = b_mlc * ne_mlc * e_mlc

local quote = lpeg.P( "\"" )
local escaped = lpeg.P( "\\" ) * 1
local string = quote * ( escaped + ( 1 - quote ) ) ^ 0 * quote

local comments = slc + mlc
local none = 1 - ( string + comments )

local just_code = ( comments + string + lpeg.C( none ^ 1 ) ) ^ 0

local f = io.open( arg[ 1 ] )
local contents = f:read( "*all" )
local stripped = table.concat( { just_code:match( contents ) } )

local function check_leaks( leaks, levels, depth, body )
	for code, block in ( body .. "{}" ):gmatch( "(.-)(%b{})" ) do
		if code == "" and block == "{}" then
			break
		end

		for line in code:gmatch( "([^\n]+)" ) do
			if line:find( "memarena_push" ) then
				if not levels[ depth ] then
					table.insert( leaks, line )
				end
			end

			if line:find( "MEMARENA_SCOPED_CHECKPOINT" ) then
				levels[ depth ] = true
			end
		end

		if not cp then
			levels[ depth + 1 ] = false
			check_leaks( leaks, levels, depth + 1, block:sub( 2, -2 ) )
			levels[ depth + 1 ] = nil
		end
	end
end

for ret, name, args, body in stripped:gmatch( "([^\n]-)%s*([^%s]+)(%b())\n? *(%b{})" ) do
	local leaks = { }
	check_leaks( leaks, { false }, 1, body )

	if #leaks > 0 then
		print( name )
		print( table.concat( leaks, "\n" ) )
	end
end