Le_Dieu_du_fond_du_Jardin/tools/lockit.gd
2020-05-07 17:33:05 +02:00

344 lines
7 KiB
GDScript

extends MainLoop
func _iteration(time):
return true
func get_input_files(argv):
var list = []
if "-esc" in argv:
for i in range(argv.size()):
if argv[i] == "-esc":
list.push_back(argv[i+1])
return list
find_esc("", list)
return list
func find_esc(path, list):
var loc = path
if loc == "":
loc = "."
var d = Directory.new()
d.open(loc)
d.list_dir_begin()
var f = d.get_next()
while f != "":
if f == "." || f == "..":
f = d.get_next()
continue
if d.current_is_dir():
find_esc(path + f + "/", list)
else:
if f.find(".esc") == f.length() - 4:
list.push_back(path + f)
f = d.get_next()
d.list_dir_end()
func get_token(line, p_from):
while p_from < line.length():
if line[p_from] == " " || line[p_from] == "\t":
p_from += 1
else:
break
if p_from >= line.length():
return -1
var tk_end
if line[p_from] == "\"":
tk_end = line.find("\"", p_from+1)
if tk_end == -1:
tk_end = line.length()-1
tk_end += 1
else:
tk_end = p_from
while tk_end < line.length():
if line[tk_end] == ":":
var ntk = get_token(line, tk_end+1)
tk_end = ntk
break
if line[tk_end] == " " || line[tk_end] == "\t":
break
tk_end += 1
return tk_end
func process_file(path, ids):
printt("process file ", path)
var f = File.new()
f.open(path, File.READ)
if !f.is_open():
print(" ** Failed opening file ", path)
return
var fo = File.new()
var tmp_dst = "esc_tmp_" + str(OS.get_process_id())
fo.open(tmp_dst, File.WRITE)
if !fo.is_open():
print(" ** Failed opening temp file ", tmp_dst, " for ", path)
f.close()
return
var section = ""
var section_count = 0
var line_count = 0
var base = path.get_file().get_basename()
ids._found.push_back(["file", base])
var section_ids = []
while !f.eof_reached():
var line = f.get_line()
line_count += 1
if line == "":
continue
if line[0] == "#":
continue
if line[0] == ":":
var end = line.find(" ")
if end == -1:
end = line.length()
section = line.substr(1, end-1)
var pos = f.get_position()
section_ids = find_section_ids(f)
f.seek(pos)
ids._found.push_back(["section", section])
else:
var from = 0
var first = null
var args = []
while true:
var tk_end
if args.size() == 1 && args[0] == "*":
var cond = line.find("[")
if cond >= 0:
tk_end = cond - 1
else:
tk_end = line.length()
else:
tk_end = get_token(line, from)
if tk_end == -1:
break
var next = line.substr(from, tk_end - from)
next = next.strip_edges()
if args.size() == 1 && args[0] == "*":
next = "\""+next+"\""
if next.find(":\"") != -1:
section_count += 1
# already has an id
var sep = next.find(":")
var id = next.substr(0, sep)
var text = next.right(sep+1)
text = text.substr(1, text.length()-2)
add_to_ids(ids, id, text, path, line_count, args)
elif next[0] == "\"": # a string
section_count += 1
var text = next.substr(1, next.length()-2)
var has = has_id(text, ids, args)
var id
if has != null:
id = has
else:
id = get_new_id(base, section, section_count, section_ids, args)
section_ids.push_back(id)
add_to_ids(ids, id, text, path, line_count, args)
var line_new = line.substr(0, from+1)
next = id + ":\"" + text + "\""
line_new = line_new + next
var tend = line_new.length()
line_new = line_new + line.right(tk_end)
tk_end = tend
line = line_new
elif next == "*":
var line_new = line.substr(0, tk_end - 1)
line = line_new + "-" + line.right(tk_end)
elif next[0] == "#":
next += " " + line.right(tk_end)
# Comments may contain quotes. Double quote in accordance with RFC-4180.
next = next.replace("\"", "\"\"")
tk_end = line.length()
args.push_back(next)
from = tk_end
fo.store_line(line)
f.close()
fo.close()
var d = Directory.new()
d.open(".")
d.rename(tmp_dst, path+".lockit")
func has_id(text, ids, args):
if !(text in ids._texts):
return null
if args[0] == "say":
if args[1] in ids._texts[text]:
return ids._texts[text][args[1]]
else: # match any
var key = ids._texts[text].keys()[0]
return ids._texts[text][key]
return null
func add_to_ids(ids, id, text, path, line_count, args):
ids._found.push_back(["text", id])
if id in ids:
ids[id].files.push_back(path + ":" + str(line_count))
if text != ids[id].text:
ids[id].conflicts.push_back([path + ":" + str(line_count), text])
else:
ids[id] = { "text": text, "files": [ path + ":" + str(line_count) ], "conflicts": [], "args": args }
if !(text in ids._texts):
ids._texts[text] = {}
if args[0] == "say":
if !(args[1] in ids._texts[text]):
ids._texts[text][args[1]] = id
else:
ids._texts[text]["dialog"] = id
func get_new_id(base, section, section_count, section_ids, args):
var r = base + "_" + section + "_" + str(section_count)
var count = 0
var ret = r
while ret in section_ids:
count += 1
ret = r + "." + str(count)
return ret
func find_section_ids(f):
var sec_ids = []
while !f.eof_reached():
var line = f.get_line()
if line == "":
continue
if line[0] == "#":
continue
if line[0] == ":":
break
var from = 0
while true:
var tk_end = get_token(line, from)
if tk_end == -1:
break
var next = line.substr(from, tk_end - from)
next = next.strip_edges()
if next.find(":\"") != -1:
var sep = next.find(":")
var id = next.substr(0, sep)
sec_ids.push_back(id)
from = tk_end
return sec_ids
func write_csv(out, ids):
var f = File.new()
f.open(out, File.WRITE)
var last_type = ""
for id in ids._found:
if id[0] == "file":
f.store_string("\n#,")
f.store_string("\"" + id[1] + "\",")
elif id[0] == "section":
if last_type != "file":
f.store_string("\n")
f.store_string("##,")
f.store_string("\"" + id[1] + "\",\n")
elif id[0] == "text":
var t = ids[id[1]]
f.store_string("\"" + id[1] + "\",")
f.store_string("\"" + t.text + "\",")
if t.args[0] == "say":
f.store_string("\""+t.args[1]+"\",")
elif t.args[0] == "*":
f.store_string("\"dialog\",")
else:
f.store_string("\""+t.args[0]+"\",")
f.store_string("\"")
var tfiles = PoolStringArray(t.files)
f.store_string(tfiles.join(", "))
f.store_string("\",")
f.store_string("\"")
var tconflicts = PoolStringArray([])
for tf in t.conflicts:
tconflicts.append(tf[0] + ":" + tf[1])
f.store_string(tconflicts.join(", "))
f.store_string("\"")
if t.args.back()[0] == "#":
var comment = t.args.back().right(1).strip_edges()
f.store_string(",\"" + comment + "\"")
f.store_string("\n")
last_type = id[0]
f.close()
func _initialize():
var argv = Array(OS.get_cmdline_args())
while argv.size():
var p = argv[0]
argv.remove(0)
if p in ["-s", "--script"]:
break
var out = "strings.csv"
for i in range(argv.size()):
if argv[i] == "-out":
out = argv[i+1]
break
var ids = { "_found": [], "_texts": {} }
var input_files = get_input_files(argv)
for f in input_files:
process_file(f, ids)
write_csv(out, ids)