* Bug 13796 fixed: tbx_generate_pofile() failed
[scilab.git] / scilab / modules / modules_manager / macros / tbx_generate_pofile.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) 2013 - Scilab Enterprises - Antoine ELIAS
3 // Copyright (C) 2016, 2018 - Samuel GOUGEON
4 //
5 // Copyright (C) 2012 - 2016 - Scilab Enterprises
6 //
7 // This file is hereby licensed under the terms of the GNU GPL v2.0,
8 // pursuant to article 5.3.4 of the CeCILL v.2.1.
9 // This file was originally licensed under the terms of the CeCILL v2.1,
10 // and continues to be available under such terms.
11 // For more information, see the COPYING file which you should have received
12 // along with this program.
13
14 function ret = tbx_generate_pofile(tbx_name, tbx_path)
15     // tbx_generate_pofile(tbx_name, tbx_path)   // deprecated (6.0)
16     // tbx_generate_pofile(tbx_name)             // deprecated (6.0)
17     // tbx_generate_pofile(tbx_path)             // 6.0
18     // tbx_generate_pofile()                     // 6.0  path = pwd()
19
20     fname = "tbx_generate_pofile"
21     rhs = argn(2)
22
23     // CHECKING INPUT PARAMETERS
24     // -------------------------
25     if and(rhs <> [0 1 2]) then
26         msg = _("%s: Wrong number of input arguments: %d to %d expected.\n")
27         error(msprintf(msg, fname, 0, 1))
28     end
29
30     if rhs==2
31         msg = "%s: %s(name, path) is obsolete. Please use %s(path) instead.\n"
32         warning(msprintf(msg, fname, fname, fname))  // no translation
33
34     elseif rhs==0
35         tbx_path = pwd()
36     else
37         tbx_path = tbx_name
38         if type(tbx_path) <> 10 then
39             msg = _("%s: Argument #%d: Text(s) expected.\n")
40             error(msprintf(msg, fname, rhs))
41         end
42         tbx_path = tbx_path(1)
43         // May be
44         //  * either the former tbx_generate_pofile(tbx_name) (until 5.5.2)
45         //  * or the new        tbx_generate_pofile(tbx_path) (from 6.0.0)
46         if grep(tbx_path,["/" "\"])==[] && ~isdir(tbx_path) then // only name was provided
47             tbx_path = pwd()
48         end
49         if ~isdir(tbx_path) then
50             msg = _("%s: The directory ''%s'' doesn''t exist or is not read accessible.\n")
51             error(msprintf(msg, fname, tbx_path))
52         end
53     end
54
55     // Retrieving the toolbox name
56     // ---------------------------
57     tbx_name = tbx_get_name_from_path(tbx_path)
58
59     //
60     old = pwd();
61     cd(tbx_path);
62     if getos() == "Windows" then
63         XGETTEXT= WSCI + "\tools\gettext\xgettext";
64     else
65         XGETTEXT="xgettext";
66     end
67     XGETTEXT_OPTIONS=" --omit-header  --language=python --no-wrap " + ..
68                  "-k --keyword=gettext:2 --keyword=_:2 " + ..
69                  "--keyword=dgettext:2 --keyword=_d:2 --keyword=xmlgettext:2";
70
71     EXTENSIONS=["c" "h" "cpp" "cxx" "hxx" "hpp" "java"];
72     EXTENSIONS_MACROS=["sci" "sce" "start" "quit"];
73     EXTENSIONS_XML=["xml" "xsl"];
74     TARGETDIR="locales";
75
76     mkdir(TARGETDIR);
77     srcFiles = getFilesList("src", EXTENSIONS);
78     srcFiles = [srcFiles ; getFilesList("sci_gateway", EXTENSIONS)];
79     srcFiles = [srcFiles ; getFilesList("macros", EXTENSIONS_MACROS)];
80     srcFiles = [srcFiles ; getFilesList("etc", EXTENSIONS_MACROS)];
81
82     //manage xml preferences files
83     xmlFiles = getFilesList("etc", EXTENSIONS_XML);
84
85     if size(xmlFiles, "*") > 0 then
86         xmlTmpFile = fullpath(TMPDIR + "/tmpLoc.xml");
87         srcFiles = [srcFiles; xmlTmpFile];
88         xmlFake = mopen(xmlTmpFile, "w");
89         search = "\(\s*(.*)\s*,\s*(.*)\s*\)\""/";
90         replace = "xmlgettext(""\1"", ""\2"")";
91         for i = 1:size(xmlFiles, "*")
92             content = mgetl(xmlFiles(i));
93             newLine = sedLoc(content, "/\""_d"+search, replace);// "_d(xxx,xxx)"
94             newLine = sedLoc(newLine, "/\""dgettext"+search, replace);
95             newLine = sedLoc(newLine, "/\""gettext"+search, replace);
96             newLine = sedLoc(newLine, "/\""_"+search, replace);
97             mputl(newLine, xmlFake);
98         end
99         mclose(xmlFake);
100     end
101
102     //parse all files
103     srcFiles = strcat(srcFiles, " ");
104     cmd = XGETTEXT + XGETTEXT_OPTIONS + " -d " + tbx_name + " " + srcFiles + " -p " + TARGETDIR + " -o " + "en_US.po.tmp";
105     host(cmd);
106     if exists("xmlTmpFile") then
107         deletefile(xmlTmpFile);
108     end
109
110     fi = fileinfo(TARGETDIR + "/en_US.po.tmp");
111     if fi == [] | fi(1) == 0 then
112         //nothing to extract
113         deletefile(TARGETDIR + "/en_US.po.tmp");
114         rmdir(TARGETDIR);
115         cd(old);
116         ret = [];
117         return;
118     end
119
120     //add header
121     header = ["msgid """"";
122     "msgstr """"";
123     """Content-Type: text/plain; charset=UTF-8\n""";
124     """Content-Transfer-Encoding: 8bit\n""";""];
125
126     poFile = mgetl(TARGETDIR + "/en_US.po.tmp");
127     poFile = [header ; poFile];
128
129     // Translating '' coming from Scilab into '
130     poFile = strsubst(poFile, "''''", "''");
131
132     // Making location paths relative to the toolbox root
133     poFile = strsubst(poFile, "#: "+fullpath(tbx_path), "#: ~");
134     poFile = strsubst(poFile, "#: "+xmlTmpFile, "#: a XML file");
135
136     // Building the final file
137     mputl(poFile, TARGETDIR + "/en_US.po");
138     deletefile(TARGETDIR + "/en_US.po.tmp");
139
140     cd(old);
141     ret = tbx_path + filesep() + TARGETDIR + filesep() + "en_US.po";
142 endfunction
143
144 function result = sedLoc(str, findExp, replaceExp)
145     result = str;
146     index = grep(result, findExp, "r");
147     while index <> []
148         idx = index(1);
149         [startPos, endPos, match, captured] = regexp(result(idx), findExp);
150
151         if captured <> [] then
152             //multiple matches on the same line
153             for i=1:size(captured, "r")
154                 replace = replaceExp;
155                 for j = 1:size(captured, "c")
156                     replace = strsubst(replace, "\" + string(j), captured(i,j));
157                 end
158
159                 if size(replace, "*") > 1 & (startPos <> 1 | endPos <> length(result(idx))) then
160                     //replace partial line by multiline expression
161                     replace(1) = part(result(idx), 1:startPos) + " " + replace(1);
162                     replace($) = replace($) + " " + part(result(idx), (endPos+1):length(result(idx)));
163
164                     result = [result(1:(idx-1)); replace; result((idx+1):$)];
165                 elseif size(replace, "*") > 1 then
166                     //replace entire line by multiline expression
167                     result = [result(1:(idx-1)); replace; result((idx+1):$)];
168                 else
169                     //replace partial line by 1-line expression
170                     result(idx) = strsubst(result(idx), match(i), replace);
171                 end
172             end
173         end
174
175         //update index with new "file"
176         index = grep(result, findExp, "r");
177     end
178 endfunction
179
180 function ret = getFilesList(folder, mask)
181     if ~isdir(folder) then
182         ret = [];
183         return;
184     end
185
186     old = pwd();
187     cd(folder)
188
189     ret = [];
190
191     files = ls();
192
193     for j = 1:size(files, "*")
194         if isdir(files(j)) then
195             ret = [ret ; getFilesList(files(j), mask)];
196         end
197     end
198
199     for i = 1:size(mask, "*")
200         srcFiles = findfiles(pwd(), "*." + mask(i));
201         if srcFiles <> [] then
202             ret = [ret ; pwd() + filesep() + srcFiles];
203         end
204     end
205
206     cd(old);
207 endfunction