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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
-- license:BSD-3-Clause
-- copyright-holders:Carl
-- use plugin options to save the input port list to a gettext formatted file
-- the file is saved in the ctrlrpath dir
-- use #import <filename.po> to load names from a different file
-- use #set <set1>,<set2>,... to override names for a child set, common names should be listed at the top before any #set tags
local exports = {}
exports.name = "portname"
exports.version = "0.0.1"
exports.description = "IOPort name/translation plugin"
exports.license = "The BSD 3-Clause License"
exports.author = { name = "Carl" }
local portname = exports
function portname.startplugin()
local ctrlrpath = lfs.env_replace(manager:options().entries.ctrlrpath:value():match("([^;]+)"))
local function get_filename(nosoft)
local filename
if emu.softname() ~= "" and not nosoft then
filename = emu.romname() .. "_" .. emu.softname() .. ".po"
else
filename = emu.romname() .. ".po"
end
return filename
end
emu.register_start(function()
local reclevel = 0
local function parse_names(names)
local orig, rep
local setfound = true
reclevel = reclevel + 1
if reclevel == 3 then
emu.print_verbose("portname: too many import levels\n")
return
end
names:gsub("[^\n\r]*", function (line)
if line:find("^#import") then
local impfile = emu.file(ctrlrpath .. "/portname", "r")
local ret = impfile:open(line:match("^#import (.*)"))
if ret then
emu.print_verbose("portname: import file not found\n")
else
parse_names(impfile:read(impfile:size()))
end
elseif line:find("^#set") then
local sets = line:match("^#set (.*)")
setfound = false
for s in sets:gmatch("[^,]*") do
if s == emu.romname() then
setfound = true
break
end
end
elseif line:find("^msgid") then
orig = line:match("^msgid \"(.+)\"")
elseif line:find("^msgstr") then
rep = line:match("^msgstr \"(.+)\"")
if rep and rep ~= "" and setfound then
rep = rep:gsub("\\(.)", "%1")
orig = orig:gsub("\\(.)", "%1")
for pname, port in pairs(manager:machine():ioport().ports) do
if port.fields[orig] then
port.fields[orig].live.name = rep
end
end
end
end
return line
end)
reclevel = reclevel - 1
end
local file = emu.file(ctrlrpath .. "/portname", "r")
local ret = file:open(get_filename())
if ret then
ret = file:open(get_filename(true))
if ret then
ret = file:open(manager:machine():system().parent .. ".po")
if ret then
return
end
end
end
parse_names(file:read(file:size()))
end)
local function menu_populate()
return {{ _("Save input names to file"), "", 0 }}
end
local function menu_callback(index, event)
if event == "select" then
local fields = {}
for pname, port in pairs(manager:machine():ioport().ports) do
for fname, field in pairs(port.fields) do
local dname = field.default_name
if not fields[dname] then
fields[dname] = {}
fields[dname].name = ""
end
if fname ~= dname then
fields[dname].name = fname
end
fields[dname].port = pname
fields[dname].mask = field.mask
fields[dname].default = dname
end
end
local function check_path(path)
local attr = lfs.attributes(path)
if not attr then
lfs.mkdir(path)
if not lfs.attributes(path) then
manager:machine():popmessage(_("Failed to save input name file"))
emu.print_verbose("portname: unable to create path " .. path .. "\n")
return false
end
elseif attr.mode ~= "directory" then
manager:machine():popmessage(_("Failed to save input name file"))
emu.print_verbose("portname: path exists but isn't directory " .. path .. "\n")
return false
end
return true
end
if not check_path(ctrlrpath) then
return false
end
if not check_path(ctrlrpath .. "/portname") then
return false
end
local filename = get_filename()
local file = io.open(ctrlrpath .. "/portname/" .. filename, "r")
if file then
emu.print_verbose("portname: input name file exists " .. filename .. "\n")
manager:machine():popmessage(_("Failed to save input name file"))
file:close()
return false
end
local sfields = {}
for def, field in pairs(fields) do
sfields[#sfields + 1] = field
end
table.sort(sfields, function(a, b) if(a.port == b.port) then return a.mask < b.mask end return a.port < b.port end)
file = io.open(ctrlrpath .. "/portname/" .. filename, "w")
for n, field in ipairs(sfields) do
def = field.default:gsub("[\\\"]", function (s) return "\\" .. s end)
custom = field.name:gsub("[\\\"]", function (s) return "\\" .. s end)
file:write(string.format("# port %s mask %08x\n", field.port, field.mask))
file:write("msgid \"" .. def .."\"\nmsgstr \"" .. custom .. "\"\n\n")
end
file:close()
manager:machine():popmessage(string.format(_("Input port name file saved to %s"), ctrlrpath .. "/portname/" .. filename))
end
return false
end
emu.register_menu(menu_callback, menu_populate, _("Input ports"))
end
return exports
|