summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkaeza <kaeza@users.sf.net>2013-10-29 15:54:14 -0200
committerkaeza <kaeza@users.sf.net>2013-10-29 15:54:14 -0200
commit17314b53890a1716296c21a913a7ebf74a306d23 (patch)
treead3745f5de2a500a3ab5cd7a39f789c5cc44ffef
parentaf31d71d1a9ffd6d1373b2714bcf025c63afaaee (diff)
Rewrite `findtext.lua'.
-rwxr-xr-xtools/findtext.lua372
1 files changed, 128 insertions, 244 deletions
diff --git a/tools/findtext.lua b/tools/findtext.lua
index 54bb229..2c9c0e6 100755
--- a/tools/findtext.lua
+++ b/tools/findtext.lua
@@ -1,257 +1,141 @@
#! /usr/bin/env lua
-local function listdir ( dir )
- local LS;
- if (os.getenv("WINDIR")) then
- LS = 'dir /b %s';
- else
- LS = 'ls %s';
- end
- local tmp = os.tmpname();
- local r = os.execute(LS:format(dir).." > "..tmp)
- if ((r ~= nil) and (r == 0)) then
- local list = { };
- local f = io.open(tmp);
- if (not f) then
- os.remove(tmp);
- return nil;
- end
- for line in f:lines() do
- list[#list + 1] = line;
- end
- f:close();
- os.remove(tmp);
- return list;
- end
- os.remove(tmp);
- return nil;
+local me = arg[0]:gsub(".*[/\\](.*)$", "%1")
+
+local function err(fmt, ...)
+ io.stderr:write(("%s: %s\n"):format(me, fmt:format(...)))
+ os.exit(1)
+end
+
+local output
+local inputs = { }
+local lang
+local author
+
+local i = 1
+
+local function usage()
+ print([[
+Usage: ]]..me..[[ [OPTIONS] FILE...
+
+Extract translatable strings from the given FILE(s).
+
+Available options:
+ -h,--help Show this help screen and exit.
+ -o,--output X Set output file (default: stdout).
+ -a,--author X Set author.
+ -l,--lang X Set language name.
+]])
+end
+
+while i <= #arg do
+ local a = arg[i]
+ if (a == "-h") or (a == "--help") then
+ usage()
+ elseif (a == "-o") or (a == "--output") then
+ i = i + 1
+ if i > #arg then
+ err("missing required argument to `%s'", a)
+ end
+ output = arg[i]
+ elseif (a == "-a") or (a == "--author") then
+ i = i + 1
+ if i > #arg then
+ err("missing required argument to `%s'", a)
+ end
+ author = arg[i]
+ elseif (a == "-l") or (a == "--lang") then
+ i = i + 1
+ if i > #arg then
+ err("missing required argument to `%s'", a)
+ end
+ lang = arg[i]
+ elseif a:sub(1, 1) ~= "-" then
+ table.insert(inputs, a)
+ else
+ err("unrecognized option `%s'", a)
+ end
+ i = i + 1
+end
+
+if #inputs == 0 then
+ err("no input files")
+end
+
+local outfile = io.stdout
+
+local function printf(fmt, ...)
+ outfile:write(fmt:format(...))
end
-local function StringOutput ( s, file )
- return {
- _buf = (s or "");
- _file = file;
- write = function ( self, ... )
- local spc = false;
- for _, v in ipairs({...}) do
- if (spc) then self._buf = self._buf.." "; end
- spc = true;
- self._buf = self._buf..tostring(v);
- end
- end;
- print = function ( self, ... )
- local spc = false;
- for _, v in ipairs({...}) do
- if (spc) then self._buf = self._buf.." "; end
- spc = true;
- self._buf = self._buf..tostring(v);
- end
- self._buf = self._buf.."\n";
- end;
- tostring = function ( self )
- return self._buf;
- end;
- flush = function ( self, file )
- local f = (file or self._file or io.stdout);
- f:write(self._buf);
- f:flush();
- end;
- };
+if output then
+ local e
+ outfile, e = io.open(output, "w")
+ if not outfile then
+ err("error opening file for writing: %s", e)
+ end
end
-local function err_print ( s )
- io.stderr:write((s or "").."\n");
+if author or lang then
+ outfile:write("\n")
end
-local function ArgParser ( appname, usageline, description )
- return {
- prefix = ((appname and (appname..": ")) or "");
- description = description;
- options = {
- { name = "help";
- short = "h";
- long = "help";
- help = "Show this help screen and exit.";
- },
- };
- values = { };
- inputs = { };
- no_exit = (appname == nil);
- add_option = function ( self, name, short, long, has_arg, arg_name, help )
- self.options[#self.options+1] = {
- name = name;
- short = short;
- long = long;
- has_arg = has_arg;
- arg_name = arg_name;
- help = help;
- };
- end;
- parse = function ( self, args, no_exit )
- local opts = { };
- local inputs = { };
- local i = 1;
- while (i <= #args) do
- local a = args[i];
- if (a:sub(1, 1) == '-') then
- local found = false;
- if ((a == "-h") or (a == "--help")) then
- if (no_exit or self.no_exit) then
- return nil, "--help";
- else
- self:show_usage();
- os.exit(0);
- end
- end
- for _, opt in ipairs(self.options) do
- if ((a == "-"..opt.short) or (a == "--"..opt.long)) then
- if (opt.has_arg) then
- i = i + 1;
- if (not args[i]) then
- local msg = self.prefix.."option `"..a.."' requires an argument.";
- if (no_exit) then
- return nil, msg;
- else
- err_print(msg);
- os.exit(-1);
- end
- end
- opts[opt.name] = args[i];
- else
- opts[opt.name] = true;
- end
- found = true;
- break;
- end
- end
- if (not found) then
- local msg = self.prefix.."unrecognized option `"..a.."'. Try `--help'.";
- if (no_exit or self.no_exit) then
- return nil, msg;
- else
- err_print(msg);
- os.exit(-1);
- end
- end
- else
- inputs[#inputs + 1] = a;
- end
- i = i + 1;
- end
- return opts, inputs;
- end;
- show_usage = function ( self, extramsg )
- if (extramsg) then
- err_print(self.prefix..extramsg);
- end
- err_print("Usage: "..appname.." "..(usageline or ""));
- if (self.description) then
- err_print(self.description)
- end
- if (#self.options > 0) then
- err_print("\nAvailable Options:");
- local optwidth = 0;
- local optline = { };
- for _, opt in ipairs(self.options) do
- local sh = (opt.short and "-"..opt.short);
- local ln = (opt.long and "--"..opt.long);
- local sep = (sh and ln and ",") or " ";
- sh = sh or "";
- ln = ln or "";
- if (opt.long and opt.has_arg) then
- ln = ln.." "..opt.arg_name;
- end
- optline[#optline + 1] = sh..sep..ln;
- if (optline[#optline]:len() > optwidth) then
- optwidth = optline[#optline]:len();
- end
- end
- for i, opt in ipairs(self.options) do
- local sep = string.rep(" ", optwidth - optline[i]:len()).." ";
- err_print(" "..optline[i]..sep..opt.help);
- end
- err_print();
- if (self.footer) then
- err_print(self.footer.."\n");
- end
- end
- end;
- };
+if lang then
+ printf("# Language: %s\n", lang)
end
-local function main ( arg )
-
- local APPNAME = "findtext.lua";
-
- local ap = ArgParser(APPNAME, "[OPTIONS] FILES...");
- ap:add_option("output", "o", "output", true, "FILE", "Write translated strings to FILE. (default: stdout)");
- ap:add_option("langname", "l", "langname", true, "NAME", "Set the language name to NAME.");
- ap:add_option("author", "a", "author", true, "NAME", "Set the author to NAME.");
- ap:add_option("mail", "m", "mail", true, "EMAIL", "Set the author contact address to EMAIL.");
- ap.description = "Finds all the strings that need to be localized, by"..
- " searching for things\n like `S(\"foobar\")'.";
- ap.footer = "Report bugs to <lkaezadl3@gmail.com>.";
-
- local opts, files = ap:parse(arg);
-
- if (#files == 0) then
- files = listdir("*.lua");
- if ((not files) or (#files == 0)) then
- io.stderr:write(APPNAME..": no input files\n");
- os.exit(-1);
- end
- end
-
- local buffer = StringOutput();
-
- buffer:write("\n");
-
- if (opts.langname) then
- buffer:write("# Language: "..opts.langname.."\n");
- end
- if (opts.author) then
- buffer:write("# Author: "..opts.author);
- if (opts.mail) then
- buffer:write(" <"..opts.mail..">");
- end
- buffer:write("\n");
- end
- if (opts.author or opts.langname) then
- buffer:write("\n");
- end
-
- for _, file in ipairs(files) do
- local infile, e = io.open(file);
- if (not infile) then
- io.stderr:write(APPNAME..": "..e.."\n");
- os.exit(1);
- end
- for line in infile:lines() do
- local s = line:match('.-S%("([^"]*)"%).*');
- if (s) then
- buffer:write(s.." = \n");
- end
- end
- infile:close();
- end
-
- local outfile, e;
- if (opts.output) then
- outfile, e = io.open(opts.output, "w");
- if (not outfile) then
- io.stderr:write(APPNAME..": "..e.."\n");
- os.exit(1);
- end
- else
- outfile = io.stdout;
- end
-
- buffer:flush(outfile);
-
- if (outfile ~= io.stdout) then
- outfile:close();
- end
+if author then
+ printf("# Author: %s\n", author)
+end
+
+if author or lang then
+ outfile:write("\n")
+end
+
+local escapes = {
+ ["\n"] = "\\n",
+ ["="] = "\\=",
+ ["\\"] = "\\\\",
+}
+
+local function escape(s)
+ return s:gsub("[\\\n=]", escapes)
+end
+
+local messages = { }
+
+for _, file in ipairs(inputs) do
+ local infile, e = io.open(file, "r")
+ if infile then
+ for line in infile:lines() do
+ for s in line:gmatch('S%("([^"]*)"%)') do
+ table.insert(messages, s)
+ end
+ end
+ infile:close()
+ else
+ io.stderr:write(("%s: WARNING: error opening file: %s\n"):format(me, e))
+ end
+end
+
+table.sort(messages)
+
+local last_msg
+
+for i, msg in ipairs(messages) do
+ if msg ~= last_msg then
+ printf("%s =\n", escape(msg))
+ end
+ last_msg = msg
+end
+if output then
+ outfile:close()
end
-main(arg);
+--[[
+TESTS:
+S("foo") S("bar")
+S("bar")
+S("foo")
+]]