summaryrefslogtreecommitdiffstatshomepage
path: root/plugins/data/load_dat.lua
blob: a113da7fd63252da378fa4bb9bfa375d08605aa1 (plain) (blame)
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
local datfile = {}

function datfile.open(file, vertag)
	local data = {}
	local ver
	local filepath
	local fh
	for path in mame_manager:ui():options().entries.historypath:value():gmatch("([^;]+)") do
		filepath = lfs.env_replace(path) .. "/" .. file
		fh = io.open(filepath, "rb")
		if fh then
			break
		end
	end
	if not fh then
		return nil
	end
	do
		local inblock = false
		local buffer = fh:read("a")
		if vertag then
			local match = buffer:match("^" .. vertag .. "%s([^%s]+)")
			if match then
				ver = match
			end
		end
		local function gmatchpos()
			local pos = 1
			local function iter()
				local spos, epos = buffer:find("\n$", pos, true)
				if not spos then
					return nil
				end
				spos = spos + 1
				local spos, epos, match = buffer:find("([^\n]+)", spos)
				pos = epos + 1
				return match, pos, iter
			end
			return iter
		end
		for line, epos, iter in gmatchpos() do

			local flag = line:sub(1, 1)
			if flag ~= "#" then
				if flag == "$" then
					if line:sub(1, 4) == "$end" then
						inblock = false
					elseif not inblock then
						local tag, set = line:match("^%$([^%s=]+)=?([^%s]*)")
						if set and set ~= "" then
							local tags = {}
							local sets = {}
							local tag1 = ""
							tag:gsub("([^,]+)", function(s) tags[#tags + 1] = s end)
							set:gsub("([^,]+)", function(s) sets[#sets + 1] = s end)
							repeat
								tag1, epos = iter()
							until tag1:sub(1, 1) == "$" 
							tag1 = tag1:match("^$([^%s]*)")
							if not data[tag1] then
								data[tag1] = {}
							end
							for num1, tag2 in pairs(tags) do
								if not data[tag1][tag2] then
									data[tag1][tag2] = {}
								end
								for num2, set in pairs(sets) do
									data[tag1][tag2][set] = epos
								end
							end
						end
						inblock = true
					end
				end
			end
		end
	end
	fh:close()
	fh = io.open(filepath, "r")
	local function read(tag1, tag2, set)
		local output = {}
		if not data[tag1][tag2][set] then
			return nil
		end
		fh:seek("set", data[tag1][tag2][set])
		for line in fh:lines() do
			if line == "$end" then
				return table.concat(output, "\n")
			end
			output[#output + 1] = line
		end
	end

	return read, ver
end

return datfile