Update jflex to 1.8.2
[scilab.git] / scilab / modules / helptools / src / java / org / scilab / modules / helptools / Helpers.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2008 - INRIA - Hussein SHAFIE
4  * Copyright (C) 2008 - INRIA - Sylvestre LEDRU
5  *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14  *
15  */
16 package org.scilab.modules.helptools;
17
18 import java.io.IOException;
19 import java.io.File;
20 import java.io.InputStream;
21 import java.io.FileInputStream;
22 import java.io.InputStreamReader;
23 import java.io.OutputStream;
24 import java.io.FileOutputStream;
25 import java.io.OutputStreamWriter;
26 import java.io.PrintWriter;
27
28 public final class Helpers {
29
30     public static final boolean IS_WINDOWS = (File.pathSeparatorChar == ';');
31
32     private Helpers() { }
33
34     // -----------------------------------------------------------------------
35
36     public static String reason(Throwable e) {
37         String reason = e.getMessage();
38         if (reason == null) {
39             return e.getClass().getName();
40         }
41
42         return reason;
43     }
44
45     // -----------------------------------------------------------------------
46
47     public static void escapeXML(String text, PrintWriter out) {
48         char[] chars = text.toCharArray();
49         escapeXML(chars, 0, chars.length, out);
50     }
51
52     public static void escapeXML(char[] chars, int offset, int length,
53                                  PrintWriter out) {
54         int end = offset + length;
55         for (int i = offset; i < end; ++i) {
56             char c = chars[i];
57
58             switch (c) {
59                 case '\'':
60                     out.write("&apos;");
61                     break;
62                 case '\"':
63                     out.write("&quot;");
64                     break;
65                 case '<':
66                     out.write("&lt;");
67                     break;
68                 case '>':
69                     out.write("&gt;");
70                     break;
71                 case '&':
72                     out.write("&amp;");
73                     break;
74                 default:
75                     out.write(c);
76                     break;
77             }
78         }
79     }
80
81     // -----------------------------------------------------------------------
82
83     public static String getBaseName(String language) {
84         return "scilab_" + language + "_help";
85     }
86
87     public static String getTemporaryNameFo(String baseDirectory) {
88         return baseDirectory + "/__doc.fo";
89     }
90
91     public static String getFileExtension(File file) {
92         return getFileExtension(file.getPath());
93     }
94
95     public static String getFileExtension(String path) {
96         int dot = indexOfDot(path);
97         if (dot < 0) {
98             return null;
99         } else {
100             return path.substring(dot + 1);
101         }
102     }
103
104     private static int indexOfDot(String path) {
105         int baseNameStart = path.lastIndexOf(File.separatorChar);
106         if (baseNameStart < 0) {
107             baseNameStart = 0;
108         } else {
109             ++baseNameStart;
110         }
111
112         int dot = -1;
113
114         int pos = path.length();
115         while ((pos = path.lastIndexOf('.', pos - 1)) > baseNameStart) {
116             dot = pos;
117         }
118
119         return dot;
120     }
121
122     public static File setFileExtension(File file, String extension) {
123         String path = setFileExtension(file.getPath(), extension);
124         return new File(path);
125     }
126
127     public static String setFileExtension(String path, String extension) {
128         if (path.endsWith(File.separator)) {
129             return path;
130         }
131
132         int dot = indexOfDot(path);
133         if (dot < 0) {
134             if (extension == null) {
135                 return path;
136             } else {
137                 return path + "." + extension;
138             }
139         } else {
140             if (extension == null) {
141                 return path.substring(0, dot);
142             } else {
143                 return path.substring(0, dot + 1) + extension;
144             }
145         }
146     }
147
148     // -----------------------------------------------------------------------
149
150     public static void copyFile(File srcFile, File dstFile)
151     throws IOException {
152         FileInputStream src = new FileInputStream(srcFile);
153         try {
154             copyFile(src, dstFile);
155         } finally {
156             src.close();
157         }
158     }
159
160     public static void copyFile(InputStream src, File dstFile)
161     throws IOException {
162         FileOutputStream dst = new FileOutputStream(dstFile);
163         byte[] bytes = new byte[65536];
164         int count;
165
166         try {
167             while ((count = src.read(bytes)) != -1) {
168                 dst.write(bytes, 0, count);
169             }
170
171             dst.flush();
172
173         } finally {
174             dst.close();
175         }
176     }
177
178     // -----------------------------------------------------------------------
179
180     /**
181      * Delete a directory and all his content
182      *
183      * @param dir The path to the directory
184      */
185     public static void deleteDirectory(String dir) {
186         deleteDirectory(new File(dir));
187     }
188
189     /**
190      * Delete a directory and all his content
191      *
192      * @param dir The file object of the path to the directory
193      */
194     public static void deleteDirectory(File dir) {
195
196         String[] files = dir.list();
197         if (files == null) {
198             files = new String[0];
199         }
200         for (int i = 0; i < files.length; i++) {
201             File file = new File(dir, files[i]);
202             if (file.isDirectory()) {
203                 Helpers.deleteDirectory(file);
204             } else {
205                 file.delete();
206             }
207         }
208         dir.delete();
209
210     }
211
212     // -----------------------------------------------------------------------
213
214     public static String[] split(String string, char separatorChar) {
215         // Count elements ---
216
217         int elementCount = 0;
218         int sep = 0;
219         while ((sep = string.indexOf(separatorChar, sep)) >= 0) {
220             ++elementCount;
221             ++sep;
222         }
223         ++elementCount;
224
225         // Build element array ---
226
227         String[] elements = new String[elementCount];
228
229         elementCount = 0;
230         sep = 0;
231         int nextSep;
232         while ((nextSep = string.indexOf(separatorChar, sep)) >= 0) {
233             elements[elementCount++] =
234                 (sep == nextSep) ? "" : string.substring(sep, nextSep);
235             sep = nextSep + 1;
236         }
237         elements[elementCount++] = string.substring(sep);
238
239         return elements;
240     }
241
242     // -----------------------------------------------------------------------
243
244     public static File findInPath(String appName) {
245         String pathEnvVar = System.getenv("PATH");
246         if (pathEnvVar == null) {
247             return null;
248         }
249
250         String[] split = Helpers.split(pathEnvVar, File.pathSeparatorChar);
251         for (int i = 0; i < split.length; ++i) {
252             String path = split[i].trim();
253             if (path.length() == 0) {
254                 continue;
255             }
256
257             if (!path.endsWith(File.separator)) {
258                 path += File.separator;
259             }
260
261             File file = new File(path + appName);
262             if (file.isFile()) {
263                 return file;
264             }
265
266             if (IS_WINDOWS && appName.lastIndexOf('.') < 0) {
267                 String[] suffixes = {".COM", ".EXE", ".BAT", ".CMD" };
268
269                 String pathExtEnvVar = System.getenv("PATHEXT");
270                 if (pathExtEnvVar != null) {
271                     suffixes = Helpers.split(pathExtEnvVar,
272                                              File.pathSeparatorChar);
273                 }
274
275                 for (int j = 0; j < suffixes.length; ++j) {
276                     String suffix = suffixes[j].trim();
277                     if (!suffix.startsWith(".")) {
278                         continue;
279                     }
280
281                     file = new File(path + appName + suffix);
282                     if (file.isFile()) {
283                         return file;
284                     }
285                 }
286             }
287         }
288
289         return null;
290     }
291
292     public static Process shellStart(String command, String[] envp, File dir)
293     throws IOException {
294         Process process;
295
296         if (IS_WINDOWS) {
297             process = Runtime.getRuntime().exec(
298                           new String[] {"cmd.exe", "/s", "/c", "\"" + command + "\"" },
299                           envp, dir);
300         } else {
301             process = Runtime.getRuntime().exec(
302                           new String[] {"/bin/sh", "-c", command }, envp, dir);
303         }
304
305         return process;
306     }
307
308     public static int shellExec(String command, String[] envp, File dir,
309                                 boolean verbose)
310     throws IOException, InterruptedException {
311         if (verbose) {
312             System.out.println(command);
313         }
314
315         Process process = shellStart(command, envp, dir);
316
317         // Without these consumer threads, any shell command that outputs
318         // something lengthy will block on Windows NT.
319
320         InputConsumer consumer1;
321         InputConsumer consumer2;
322         if (verbose) {
323             consumer1 = new InputConsumer(process.getInputStream(), System.out);
324             consumer2 = new InputConsumer(process.getErrorStream(), System.err);
325         } else {
326             consumer1 = new InputConsumer(process.getInputStream());
327             consumer2 = new InputConsumer(process.getErrorStream());
328         }
329         consumer1.start();
330         consumer2.start();
331
332         int exitStatus = process.waitFor();
333
334         consumer1.join();
335         consumer2.join();
336
337         return exitStatus;
338     }
339
340     private static class InputConsumer extends Thread {
341         private InputStream in;
342         private OutputStream out;
343         private byte[] bytes = new byte[4096];
344
345         public InputConsumer(InputStream in) {
346             this(in, null);
347         }
348
349         public InputConsumer(InputStream in, OutputStream out) {
350             this.in = in;
351             this.out = out;
352         }
353
354         public void run() {
355             for (;;) {
356                 int count;
357                 try {
358                     count = in.read(bytes);
359                 } catch (IOException e) {
360                     //e.printStackTrace();
361                     count = -1;
362                 }
363                 if (count < 0) {
364                     break;
365                 }
366
367                 if (count > 0 && out != null) {
368                     try {
369                         out.write(bytes, 0, count);
370                         out.flush();
371                     } catch (IOException e) {
372                         //e.printStackTrace();
373                         out = null;
374                     }
375                 }
376             }
377         }
378     }
379
380     // -----------------------------------------------------------------------
381
382     public static String loadString(File file, String charsetName)
383     throws IOException {
384         InputStream in = new FileInputStream(file);
385
386         String loaded = null;
387         try {
388             loaded = loadString(in, charsetName);
389         } finally {
390             in.close();
391         }
392
393         return loaded;
394     }
395
396     public static String loadString(InputStream stream, String charsetName)
397     throws IOException {
398         InputStreamReader in;
399         if (charsetName == null) {
400             in = new InputStreamReader(stream, "UTF-8");
401         } else {
402             in = new InputStreamReader(stream, charsetName);
403         }
404
405         char[] chars = new char[8192];
406         StringBuffer buffer = new StringBuffer(chars.length);
407         int count;
408
409         while ((count = in.read(chars, 0, chars.length)) != -1) {
410             if (count > 0) {
411                 buffer.append(chars, 0, count);
412             }
413         }
414
415         return buffer.toString();
416     }
417
418     public static void saveString(String string, File file,
419                                   String charsetName)
420     throws IOException {
421         OutputStream out = new FileOutputStream(file);
422
423         try {
424             saveString(string, out, charsetName);
425         } finally {
426             out.close();
427         }
428     }
429
430     private static void saveString(String string, OutputStream stream,
431                                    String charsetName)
432     throws IOException {
433         OutputStreamWriter out;
434         if (charsetName == null) {
435             out = new OutputStreamWriter(stream, "UTF-8");
436         } else {
437             out = new OutputStreamWriter(stream, charsetName);
438         }
439
440         out.write(string, 0, string.length());
441         out.flush();
442     }
443 }
444