diff options
| author | kaeza <kaeza@users.sf.net> | 2013-10-29 15:54:14 -0200 | 
|---|---|---|
| committer | kaeza <kaeza@users.sf.net> | 2013-10-29 15:54:14 -0200 | 
| commit | 17314b53890a1716296c21a913a7ebf74a306d23 (patch) | |
| tree | ad3745f5de2a500a3ab5cd7a39f789c5cc44ffef | |
| parent | af31d71d1a9ffd6d1373b2714bcf025c63afaaee (diff) | |
Rewrite `findtext.lua'.
| -rwxr-xr-x | tools/findtext.lua | 372 | 
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") +]] | 
