From 6f87b3855d1b178ed55db451e5738572c7103699 Mon Sep 17 00:00:00 2001 From: Maksym H Date: Sat, 13 Aug 2022 22:39:37 +0200 Subject: [PATCH] Drop `intllib` and `string.trim8` (#88) --- builtin/common/misc_helpers.lua | 4 - builtin/init.lua | 2 - builtin/intllib/LICENSE.md | 27 ---- builtin/intllib/gettext.lua | 217 ------------------------------ builtin/intllib/init.lua | 229 -------------------------------- builtin/intllib/lib.lua | 70 ---------- 6 files changed, 549 deletions(-) delete mode 100644 builtin/intllib/LICENSE.md delete mode 100644 builtin/intllib/gettext.lua delete mode 100644 builtin/intllib/init.lua delete mode 100644 builtin/intllib/lib.lua diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua index 797fd7195..35c821f39 100644 --- a/builtin/common/misc_helpers.lua +++ b/builtin/common/misc_helpers.lua @@ -207,10 +207,6 @@ function string:trim() return (self:gsub("^%s*(.-)%s*$", "%1")) end -function string:trim8() - return utf8.gsub(self, "^%s*(.-)%s*$", "%1") -end - -------------------------------------------------------------------------------- function math.hypot(x, y) local t diff --git a/builtin/init.lua b/builtin/init.lua index 602ca0b4f..89b1fdc64 100644 --- a/builtin/init.lua +++ b/builtin/init.lua @@ -29,14 +29,12 @@ local gamepath = scriptdir .. "game" .. DIR_DELIM local clientpath = scriptdir .. "client" .. DIR_DELIM local commonpath = scriptdir .. "common" .. DIR_DELIM local asyncpath = scriptdir .. "async" .. DIR_DELIM -local intlpath = scriptdir .. "intllib" .. DIR_DELIM dofile(commonpath .. "strict.lua") dofile(commonpath .. "serialize.lua") dofile(commonpath .. "misc_helpers.lua") if INIT == "game" then - dofile(intlpath .. "init.lua") dofile(gamepath .. "init.lua") assert(not core.get_http_api) elseif INIT == "mainmenu" then diff --git a/builtin/intllib/LICENSE.md b/builtin/intllib/LICENSE.md deleted file mode 100644 index a48ea737a..000000000 --- a/builtin/intllib/LICENSE.md +++ /dev/null @@ -1,27 +0,0 @@ -By Diego Martínez (kaeza). -Released under Unlicense. - -This is free and unencumbered software released into the public domain. - -Anyone is free to copy, modify, publish, use, compile, sell, or -distribute this software, either in source code form or as a compiled -binary, for any purpose, commercial or non-commercial, and by any -means. - -In jurisdictions that recognize copyright laws, the author or authors -of this software dedicate any and all copyright interest in the -software to the public domain. We make this dedication for the benefit -of the public at large and to the detriment of our heirs and -successors. We intend this dedication to be an overt act of -relinquishment in perpetuity of all present and future rights to this -software under copyright law. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -For more information, please refer to diff --git a/builtin/intllib/gettext.lua b/builtin/intllib/gettext.lua deleted file mode 100644 index c56deec96..000000000 --- a/builtin/intllib/gettext.lua +++ /dev/null @@ -1,217 +0,0 @@ -local escapes = { n="\n", r="\r", t="\t" } - -local function unescape(str) - return (str:gsub("(\\+)([nrt]?)", function(bs, c) - local bsl = #bs - local realbs = ("\\"):rep(bsl/2) - if bsl%2 == 1 then - c = escapes[c] or c - end - return realbs..c - end)) -end - -local function parse_po(str) - local state, msgid, msgid_plural, msgstrind - local texts = { } - local lineno = 0 - local function perror(msg) - return error(msg.." at line "..lineno) - end - for _, line in ipairs(str:split("\n")) do repeat - lineno = lineno + 1 - line = line:trim8() - - if line == "" or line:match("^#") then - state, msgid, msgid_plural = nil, nil, nil - break -- continue - end - - local mid = line:match("^%s*msgid%s*\"(.*)\"%s*$") - if mid then - if state == "id" then - return perror("unexpected msgid") - end - state, msgid = "id", unescape(mid) - break -- continue - end - - mid = line:match("^%s*msgid_plural%s*\"(.*)\"%s*$") - if mid then - if state ~= "id" then - return perror("unexpected msgid_plural") - end - state, msgid_plural = "idp", unescape(mid) - break -- continue - end - - local ind, mstr = line:match("^%s*msgstr([0-9%[%]]*)%s*\"(.*)\"%s*$") - if ind then - if not msgid then - return perror("missing msgid") - elseif ind == "" then - msgstrind = 0 - elseif ind:match("%[[0-9]+%]") then - msgstrind = tonumber(ind:sub(2, -2)) - else - return perror("malformed msgstr") - end - texts[msgid] = texts[msgid] or { } - if msgid_plural then - texts[msgid_plural] = texts[msgid] - end - texts[msgid][msgstrind] = unescape(mstr) - state = "str" - break -- continue - end - - mstr = line:match("^%s*\"(.*)\"%s*$") - if mstr then - if state == "id" then - msgid = msgid..unescape(mstr) - break -- continue - elseif state == "idp" then - msgid_plural = msgid_plural..unescape(mstr) - break -- continue - elseif state == "str" then - local text = texts[msgid][msgstrind] - texts[msgid][msgstrind] = text..unescape(mstr) - break -- continue - end - end - - return perror("malformed line") - - -- luacheck: ignore - until true end -- end for - - return texts -end - -local M = { } - -local function warn(msg) - core.log("warning", "[intllib] "..msg) -end - --- hax! --- This function converts a C expression to an equivalent Lua expression. --- It handles enough stuff to parse the `Plural-Forms` header correctly. --- Note that it assumes the C expression is valid to begin with. -local function compile_plural_forms(str) - local plural = str:match("plural=([^;]+);?$") - local function replace_ternary(s) - local c, t, f = s:match(s"^(.-)%?(.-):(.*)") - if c then - return ("__if(" - ..replace_ternary(c) - ..","..replace_ternary(t) - ..","..replace_ternary(f) - ..")") - end - return s - end - plural = replace_ternary(plural) - plural = plural:gsub("&&", " and ") - plural = plural:gsub("||", " or ") - plural = plural:gsub("!=", "~=") - plural = plural:gsub("!", " not ") - local f, err = loadstring([[ - local function __if(c, t, f) - if c and c~=0 then return t else return f end - end - local function __f(n) - return (]]..plural..[[) - end - return (__f(...)) - ]]) - if not f then return nil, err end - local env = { } - env._ENV, env._G = env, env - setfenv(f, env) - return function(n) - local v = f(n) - if type(v) == "boolean" then - -- Handle things like a plain `n != 1` - v = v and 1 or 0 - end - return v - end -end - -local function parse_headers(str) - local headers = { } - for _, line in ipairs(str:split("\n")) do - local k, v = line:match("^([^:]+):%s*(.*)") - if k then - headers[k] = v - end - end - return headers -end - -local function load_catalog(filename) - local f, data, err - - local function bail(msg) - warn(msg..(err and ": " or "")..(err or "")) - return nil - end - - f, err = io.open(filename, "rb") - if not f then - return --bail("failed to open catalog") - end - - data, err = f:read("*a") - - f:close() - - if not data then - return bail("failed to read catalog") - end - - data, err = parse_po(data) - if not data then - return bail("failed to parse catalog") - end - - err = nil - local hdrs = data[""] - if not (hdrs and hdrs[0]) then - return bail("catalog has no headers") - end - - hdrs = parse_headers(hdrs[0]) - - local pf = hdrs["Plural-Forms"] - if not pf then - -- XXX: Is this right? Gettext assumes this if header not present. - pf = "nplurals=2; plural=n != 1" - end - - data.plural_index, err = compile_plural_forms(pf) - if not data.plural_index then - return bail("failed to compile plural forms") - end - - --warn("loaded: "..filename) - - return data -end - -function M.load_catalogs(path) - local langs = intllib.get_detected_languages() - - local cats = { } - for _, lang in ipairs(langs) do - local cat = load_catalog(path.."/"..lang..".po") - if cat then - cats[#cats+1] = cat - end - end - - return cats -end - -return M diff --git a/builtin/intllib/init.lua b/builtin/intllib/init.lua deleted file mode 100644 index 743c94cdb..000000000 --- a/builtin/intllib/init.lua +++ /dev/null @@ -1,229 +0,0 @@ -intllib = { - getters = {}, - strings = {}, -} - -local path = core.get_builtin_path() .. "intllib" .. DIR_DELIM -dofile(path .. "lib.lua") - -local LANG = core.settings:get("language") -if not (LANG and (LANG ~= "")) then LANG = os.getenv("LANG") end -if not (LANG and (LANG ~= "")) then LANG = "en" end - - -local INS_CHAR = intllib.INSERTION_CHAR -local insertion_pattern = "("..INS_CHAR.."?)"..INS_CHAR.."(%(?)(%d+)(%)?)" - -local function do_replacements(str, ...) - local args = {...} - -- Outer parens discard extra return values - return (str:gsub(insertion_pattern, function(escape, open, num, close) - if escape == "" then - local replacement = tostring(args[tonumber(num)]) - if open == "" then - replacement = replacement..close - end - return replacement - else - return INS_CHAR..open..num..close - end - end)) -end - -local function make_getter(msgstrs) - return function(s, ...) - local str - if msgstrs then - str = msgstrs[s] - end - if not str or str == "" then - str = s - end - if select("#", ...) == 0 then - return str - end - return do_replacements(str, ...) - end -end - - -local function Getter(modname) - modname = modname or core.get_current_modname() - if not intllib.getters[modname] then - local msgstr = intllib.get_strings(modname) - intllib.getters[modname] = make_getter(msgstr) - end - return intllib.getters[modname] -end - - -function intllib.Getter(modname) - local info = debug and debug.getinfo and debug.getinfo(2) - local loc = info and info.short_src..":"..info.currentline - core.log("deprecated", "intllib.Getter is deprecated." - .." Please use intllib.make_gettext_pair instead." - ..(info and " (called from "..loc..")" or "")) - return Getter(modname) -end - - -local langs - -local function split(str, sep) - local pos, endp = 1, #str+1 - return function() - if (not pos) or pos > endp then return end - local s, e = str:find(sep, pos, true) - local part = str:sub(pos, s and s-1) - pos = e and e + 1 - return part - end -end - -function intllib.get_detected_languages() - if langs then return langs end - - langs = { } - - local function addlang(l) - local sep - langs[#langs+1] = l - sep = l:find(".", 1, true) - if sep then - l = l:sub(1, sep-1) - langs[#langs+1] = l - end - sep = l:find("_", 1, true) - if sep then - langs[#langs+1] = l:sub(1, sep-1) - end - end - - local v - - v = core.settings:get("language") - if v and v~="" then - addlang(v) - end - - v = os.getenv("LANGUAGE") - if v then - for item in split(v, ":") do - langs[#langs+1] = item - end - end - - v = os.getenv("LANG") - if v then - addlang(v) - end - - langs[#langs+1] = "en" - - return langs -end - - -local gettext = dofile(path .. "gettext.lua") - - -local function catgettext(catalogs, msgid) - for _, cat in ipairs(catalogs) do - local msgstr = cat and cat[msgid] - if msgstr and msgstr~="" then - local msg = msgstr[0] - return msg~="" and msg or nil - end - end -end - -local floor = math.floor -local function catngettext(catalogs, msgid, msgid_plural, n) - n = floor(n) - for _, cat in ipairs(catalogs) do - local msgstr = cat and cat[msgid] - if msgstr then - local index = cat.plural_index(n) - local msg = msgstr[index] - return msg~="" and msg or nil - end - end - return n==1 and msgid or msgid_plural -end - - -local gettext_getters = { } -function intllib.make_gettext_pair(modname) - modname = modname or core.get_current_modname() - if gettext_getters[modname] then - return unpack(gettext_getters[modname]) - end - local modpath = core.get_modpath(modname) - local localedir = modpath and modpath.."/locale" - local catalogs = localedir and gettext.load_catalogs(localedir) or {} - local getter = Getter(modname) - local function gettext_func(msgid, ...) - local msgstr = (catgettext(catalogs, msgid) - or getter(msgid)) - return do_replacements(msgstr, ...) - end - local function ngettext_func(msgid, msgid_plural, n, ...) - local msgstr = (catngettext(catalogs, msgid, msgid_plural, n) - or getter(msgid)) - return do_replacements(msgstr, ...) - end - gettext_getters[modname] = { gettext_func, ngettext_func } - return gettext_func, ngettext_func -end - - -local function get_locales(code) - local ll, cc = code:match("^(..)_(..)") - if ll then - return { ll.."_"..cc, ll, ll~="en" and "en" or nil } - else - return { code, code~="en" and "en" or nil } - end -end - - -function intllib.get_strings(modname, langcode) - langcode = langcode or LANG - modname = modname or core.get_current_modname() - local msgstr = intllib.strings[modname] - if not msgstr then - local modpath = core.get_modpath(modname) - msgstr = { } - if modpath then - for _, l in ipairs(get_locales(langcode)) do - local t = intllib.load_strings(modpath.."/locale/"..modname.."."..l..".tr") - or intllib.load_strings(modpath.."/locale/"..l..".txt") or { } - for k, v in pairs(t) do - msgstr[k] = msgstr[k] or v - end - end - intllib.strings[modname] = msgstr - end - end - return msgstr -end - - -function core.get_translator_auto(langs) - if type(langs) == "table" then - for _, l in ipairs(langs) do - if LANG == l then - -- Surrounded in brackets so there's only one return value - return (intllib.make_gettext_pair()) - end - end - elseif langs then - -- If intllib can find any translations for this mod in the current - -- language then use intllib. - if next(intllib.get_strings()) then - return (intllib.make_gettext_pair()) - end - end - - return core.get_translator(core.get_current_modname()) -end diff --git a/builtin/intllib/lib.lua b/builtin/intllib/lib.lua deleted file mode 100644 index 3cab7e3f6..000000000 --- a/builtin/intllib/lib.lua +++ /dev/null @@ -1,70 +0,0 @@ -local INS_CHAR = "@" -intllib.INSERTION_CHAR = INS_CHAR - -local escapes = { - ["\\"] = "\\", - ["n"] = "\n", - ["s"] = " ", - ["t"] = "\t", - ["r"] = "\r", - ["f"] = "\f", - [INS_CHAR] = INS_CHAR..INS_CHAR, -} - -local function unescape(str) - local parts = {} - local n = 1 - local function add(s) - parts[n] = s - n = n + 1 - end - - local start = 1 - while true do - local pos = str:find("[\\@]", start) - if pos then - add(str:sub(start, pos - 1)) - else - add(str:sub(start)) - break - end - local c = str:sub(pos + 1, pos + 1) - if escapes[c] then - add(escapes[c]) - elseif str:sub(pos, pos) == "@" then - add("@" .. c) - else - add(c) - end - start = pos + 2 - end - return table.concat(parts) -end - -local function find_eq(s) - for slashes, pos in s:gmatch("([\\]*)=()") do - if (slashes:len() % 2) == 0 then - return pos - 1 - end - end -end - -function intllib.load_strings(filename) - local file, err = io.open(filename, "r") - if not file then - return nil, err - end - local strings = {} - for line in file:lines() do - line = line:trim8() - if line ~= "" and line:sub(1, 1) ~= "#" then - local pos = find_eq(line) - if pos then - local msgid = unescape(line:sub(1, pos - 1):trim8()) - strings[msgid] = unescape(line:sub(pos + 1):trim8()) - end - end - end - file:close() - return strings -end