Added Translator tool for easier localization

This commit is contained in:
Jindra Petřík
2022-11-23 17:28:59 +01:00
parent 5a2d75933d
commit 4f4c22006d
15 changed files with 2457 additions and 17 deletions

1
.gitignore vendored
View File

@@ -24,6 +24,7 @@ Thumbs.db
/testdata/recompile/
/build_exe.xml
/build_exe64.xml
/build_translator_exe.xml
/coverage.ec
/libsrc/jsyntaxpane/jsyntaxpane/src/target/
hs_err_pid*.log

View File

@@ -2,6 +2,7 @@
All notable changes to this project will be documented in this file.
##[Unreleased]
- Translator tool for easier localization
##[17.0.2] - 2022-11-22
### Fixed

View File

@@ -21,18 +21,15 @@
- Turkish
- Ukrainian
## New translation
## Help translating
If you would like to translate FFDec to your language, please follow these steps:
1. Check whether your language is not already present in the development branch:
[dev/TRANSLATIONS.md](https://github.com/jindrapetrik/jpexs-decompiler/blob/dev/TRANSLATIONS.md)
2. Find out your language code (See [table](http://www.loc.gov/standards/iso639-2/php/code_list.php) )
4. Download `Language pack for translators (zipped)` from latest (including nightly) version on [releases page](https://github.com/jindrapetrik/jpexs-decompiler/releases)
5. The archive contains all language files for newest version of FFDec. Each language in this pack has files with its own suffix which is standard language code.
6. Extract Language pack ZIP file
7. Copy each `.properties` file without `_xx` suffix (english), to new file which has your language code suffix (`_cs` is for czech, etc...)
8. Open `.properties` files with an editor. (`.properties` editor bundled with some Java IDE is better than standard text editor)
9. In order to `.properties` to work in FFDec, all nonascii characters should be replaced with unicode escapes (like `\u1234`). IDE editors like Netbeans do this automatically. If you have classic text editor, you can skip this phase, I will do it later myself.
10. Don't forget to place your name in `AboutDialog_xx.properties` file.
11. Create branch from `dev` and place .properties files to correct locations. TODO: specify what's correct location
12. Create pull request
1. Download latest nightly version of FFDec to have the latest english strings.
2. In the FFDec installation directory, run FFDec Translator:
`translator.exe`, `translator.bat`, `translator.sh` or `java -jar ffdec.jar -translator` will do
3. Use GUI editor to edit existing translations and/or add new Locale
4. If you create brand new locale, you will be asked for its code
See [table](http://www.loc.gov/standards/iso639-2/php/code_list.php) (ISO 639-1 Code) for available codes.
5. When you are ready, use `Export JPT` button to export modified strings to an archive (.jpt extension)
6. Send that archive to us, you can use either Issue tracker (preffered) or e-mail contact `jindra.petrik@gmail.com`

View File

@@ -34,6 +34,11 @@ core.lib.version_info = libsrc/ffdec_lib/version.properties
version_info = version.properties
exe.config = build_exe.xml
translator_exe.config = build_translator_exe.xml
translator_exe.filename = translator
translator_internal.name = FFDec
translator_product.name = JPEXS Free Flash Decompiler
website.upload.url = -
website.version.url = -

View File

@@ -444,16 +444,66 @@
</launch4jConfig>
</echoxml>
</target>
<target name="-exe-linux" unless="is_windows" depends="-load-tools,-exe-config">
<target name="-exe-translator-config">
<echoxml file="${translator_exe.config}">
<launch4jConfig>
<dontWrapJar>true</dontWrapJar>
<headerType>gui</headerType>
<jar>${jar.filename}.jar</jar>
<outfile>${basedir}/${dist.dir}/${translator_exe.filename}.exe</outfile>
<errTitle></errTitle>
<cmdLine>-translator</cmdLine>
<chdir></chdir>
<priority>normal</priority>
<downloadUrl>http://java.com/download</downloadUrl>
<supportUrl></supportUrl>
<customProcName>false</customProcName>
<stayAlive>false</stayAlive>
<restartOnCrash>false</restartOnCrash>
<manifest></manifest>
<icon></icon>
<jre>
<path></path>
<minVersion>${min.java.version}</minVersion>
<maxVersion></maxVersion>
<jdkPreference>preferJre</jdkPreference>
<runtimeBits>64/32</runtimeBits>
<maxHeapPercent>${max.heap.size.percent}</maxHeapPercent>
</jre>
<versionInfo>
<fileVersion>${version.number}</fileVersion>
<txtFileVersion>${version}${version.suffix}</txtFileVersion>
<fileDescription>${translator_product.name}</fileDescription>
<copyright>${vendor}</copyright>
<productVersion>${version.number}</productVersion>
<txtProductVersion>${version}${version.suffix}</txtProductVersion>
<productName>${translator_product.name}</productName>
<companyName></companyName>
<internalName>${translator_internal.name}</internalName>
<originalFilename>${translator_exe.filename}.exe</originalFilename>
</versionInfo>
</launch4jConfig>
</echoxml>
</target>
<target name="-exe-linux" unless="is_windows" depends="-load-tools,-exe-config,-exe-translator-config">
<java jar="${launch4j.path}/launch4j.jar" fork="true">
<arg line="${exe.config}" />
</java>
<java jar="${launch4j.path}/launch4j.jar" fork="true">
<arg line="${translator_exe.config}" />
</java>
</target>
<target name="-exe-windows" if="is_windows" depends="-load-tools,-exe-config">
<target name="-exe-windows" if="is_windows" depends="-load-tools,-exe-config,-exe-translator-config">
<java jar="${launch4j.path}/launch4j.jar" fork="true">
<arg line="${exe.config}" />
</java>
<java jar="${launch4j.path}/launch4j.jar" fork="true">
<arg line="${translator_exe.config}" />
</java>
</target>
<target name="exe" depends="-set-gui-type,-exe-linux,-exe-windows">
</target>

View File

@@ -0,0 +1,158 @@
/*
* Copyright (C) 2010-2016 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.helpers.properties;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
%%
%public
%class PropertiesLexer
%final
%unicode
%char
%type ParsedSymbol
%throws PropertiesParseException
%{
private String sourceCode;
public PropertiesLexer(String sourceCode){
this(new StringReader(sourceCode));
this.sourceCode = sourceCode;
}
public void yypushbackstr(String s, int state)
{
sourceCode = s + sourceCode.substring(yychar + yylength());
yyreset(new StringReader(sourceCode));
yybegin(state);
}
public void yypushbackstr(String s)
{
yypushbackstr(s, YYINITIAL);
}
StringBuilder string = new StringBuilder();
private static String xmlTagName = "";
public int yychar() {
return yychar;
}
private Stack<ParsedSymbol> pushedBack = new Stack<>();
public int yyline() {
return yyline + 1;
}
public void pushback(ParsedSymbol symb) {
pushedBack.push(symb);
last = null;
}
ParsedSymbol last;
public ParsedSymbol lex() throws java.io.IOException, PropertiesParseException{
ParsedSymbol ret = null;
if (!pushedBack.isEmpty()){
ret = last = pushedBack.pop();
} else {
ret = last = yylex();
}
return ret;
}
private int count(String str, String target) {
return (str.length() - str.replace(target, "").length()) / target.length();
}
%}
/* main character classes */
LineTerminator = \r|\n|\r\n
InputCharacter = [^\r\n]
WhiteSpace = [ \t\f]+
NonWhiteSpaceChar = [^ \t\f]
Separator = {WhiteSpace} | ({WhiteSpace}? [:=] {WhiteSpace}?)
NewLineEscape = "\\" {LineTerminator} {WhiteSpace}?
Comment = [#!] {InputCharacter}*
UnicodeEscape = "\\" u[0-9a-fA-F]{4}
/*return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.BREAK, yytext());*/
%state COMMENT, KEY, VALUE
%%
<YYINITIAL> {
{WhiteSpace} {}
{Comment} { yybegin(COMMENT);
return new ParsedSymbol(SymbolType.COMMENT, yytext().substring(1));}
{LineTerminator} { return new ParsedSymbol(SymbolType.EMPTY_LINE, null); }
{NonWhiteSpaceChar} {string.setLength(0); string.append(yytext()); yybegin(KEY);}
}
<COMMENT> {
{LineTerminator} {yybegin(YYINITIAL);}
}
<KEY> {
"\\t" { string.append("\\t"); }
"\\f" { string.append("\\f"); }
"\\r" { string.append("\\r"); }
"\\n" { string.append("\\n"); }
"\\\\" { string.append("\\\\"); }
"\\ " { string.append(" "); }
"\\!" { string.append("!"); }
"\\#" { string.append("#"); }
"\\=" { string.append("="); }
"\\:" { string.append(":"); }
{UnicodeEscape} { string.append((char)Integer.parseInt(yytext().substring(2), 16));}
{Separator} { String key = string.toString();
yybegin(VALUE);
string.setLength(0);
return new ParsedSymbol(SymbolType.KEY, key);}
{NonWhiteSpaceChar} { string.append(yytext());}
}
<VALUE> {
"\\t" { string.append("\\t"); }
"\\f" { string.append("\\f"); }
"\\r" { string.append("\\r"); }
"\\n" { string.append("\\n"); }
"\\\\" { string.append("\\\\"); }
"\\ " { string.append(" "); }
{UnicodeEscape} { string.append((char)Integer.parseInt(yytext().substring(2), 16));}
{NewLineEscape} { string.append("\r\n"); }
{LineTerminator} {yybegin(YYINITIAL);
return new ParsedSymbol(SymbolType.VALUE, string.toString());}
{InputCharacter} { string.append(yytext());}
<<EOF>> {yybegin(YYINITIAL);
return new ParsedSymbol(SymbolType.VALUE, string.toString());}
}
/* error fallback */
[^] { }
<<EOF>> { return new ParsedSymbol(SymbolType.EOF, null); }

View File

@@ -0,0 +1,25 @@
package com.jpexs.helpers.properties;
/**
*
* @author JPEXS
*/
public class ParsedSymbol {
public Object value;
public SymbolType type;
public ParsedSymbol(SymbolType type, Object value) {
this.type = type;
this.value = value;
}
@Override
public String toString() {
return type+": " + value;
}
}

View File

@@ -0,0 +1,742 @@
/* The following code was generated by JFlex 1.6.0 */
/*
* Copyright (C) 2010-2016 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.helpers.properties;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/**
* This class is a scanner generated by
* <a href="http://www.jflex.de/">JFlex</a> 1.6.0
* from the specification file <tt>C:/Dropbox/Programovani/JavaSE/FFDec/libsrc/ffdec_lib/lexers/properties.flex</tt>
*/
public final class PropertiesLexer {
/** This character denotes the end of file */
public static final int YYEOF = -1;
/** initial size of the lookahead buffer */
private static final int ZZ_BUFFERSIZE = 16384;
/** lexical states */
public static final int YYINITIAL = 0;
public static final int COMMENT = 2;
public static final int KEY = 4;
public static final int VALUE = 6;
/**
* ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l
* ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l
* at the beginning of a line
* l is of the form l = 2*k, k a non negative integer
*/
private static final int ZZ_LEXSTATE[] = {
0, 0, 1, 1, 2, 2, 3, 3
};
/**
* Translates characters to character classes
*/
private static final String ZZ_CMAP_PACKED =
"\11\0\1\3\1\2\1\0\1\3\1\1\22\0\1\15\1\16\1\0"+
"\1\6\14\0\12\10\1\4\2\0\1\17\3\0\6\10\25\0\1\5"+
"\4\0\5\10\1\12\7\0\1\14\3\0\1\13\1\0\1\11\1\7"+
"\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uff9a\0";
/**
* Translates characters to character classes
*/
private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED);
/**
* Translates DFA states to action switch labels.
*/
private static final int [] ZZ_ACTION = zzUnpackAction();
private static final String ZZ_ACTION_PACKED_0 =
"\4\0\1\1\2\2\1\3\1\4\1\3\2\5\1\6"+
"\2\7\1\6\2\10\1\6\1\11\1\12\1\13\1\0"+
"\1\14\1\15\1\16\1\17\1\20\1\21\1\22\2\23"+
"\3\0\1\24";
private static int [] zzUnpackAction() {
int [] result = new int[36];
int offset = 0;
offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);
return result;
}
private static int zzUnpackAction(String packed, int offset, int [] result) {
int i = 0; /* index in packed string */
int j = offset; /* index in unpacked array */
int l = packed.length();
while (i < l) {
int count = packed.charAt(i++);
int value = packed.charAt(i++);
do result[j++] = value; while (--count > 0);
}
return j;
}
/**
* Translates a state to a row index in the transition table
*/
private static final int [] ZZ_ROWMAP = zzUnpackRowMap();
private static final String ZZ_ROWMAP_PACKED_0 =
"\0\0\0\20\0\40\0\60\0\100\0\120\0\100\0\140"+
"\0\160\0\100\0\200\0\100\0\100\0\220\0\240\0\260"+
"\0\300\0\100\0\320\0\100\0\100\0\100\0\340\0\100"+
"\0\100\0\100\0\100\0\100\0\100\0\100\0\360\0\u0100"+
"\0\u0110\0\u0120\0\u0130\0\100";
private static int [] zzUnpackRowMap() {
int [] result = new int[36];
int offset = 0;
offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);
return result;
}
private static int zzUnpackRowMap(String packed, int offset, int [] result) {
int i = 0; /* index in packed string */
int j = offset; /* index in unpacked array */
int l = packed.length();
while (i < l) {
int high = packed.charAt(i++) << 16;
result[j++] = high | packed.charAt(i++);
}
return j;
}
/**
* The transition table of the DFA
*/
private static final int [] ZZ_TRANS = zzUnpackTrans();
private static final String ZZ_TRANS_PACKED_0 =
"\1\5\1\6\1\7\1\10\2\5\1\11\6\5\1\10"+
"\1\11\1\5\1\12\1\13\1\14\15\12\3\15\1\16"+
"\1\17\1\20\7\15\1\16\1\15\1\17\1\15\1\21"+
"\1\22\2\15\1\23\12\15\22\0\1\7\20\0\1\10"+
"\11\0\1\10\2\0\1\11\2\0\15\11\2\0\1\14"+
"\20\0\1\16\1\17\10\0\1\16\1\0\1\17\3\0"+
"\1\17\11\0\1\17\6\0\1\24\1\25\1\26\1\27"+
"\1\0\1\30\1\31\1\32\1\33\1\34\1\35\1\36"+
"\2\0\1\22\16\0\1\37\1\40\2\0\1\25\1\0"+
"\1\27\1\0\1\30\1\31\1\32\1\33\1\34\12\0"+
"\1\41\1\0\1\41\7\0\2\40\11\0\1\40\5\0"+
"\1\40\11\0\1\40\12\0\1\42\1\0\1\42\15\0"+
"\1\43\1\0\1\43\15\0\1\44\1\0\1\44\5\0";
private static int [] zzUnpackTrans() {
int [] result = new int[320];
int offset = 0;
offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);
return result;
}
private static int zzUnpackTrans(String packed, int offset, int [] result) {
int i = 0; /* index in packed string */
int j = offset; /* index in unpacked array */
int l = packed.length();
while (i < l) {
int count = packed.charAt(i++);
int value = packed.charAt(i++);
value--;
do result[j++] = value; while (--count > 0);
}
return j;
}
/* error codes */
private static final int ZZ_UNKNOWN_ERROR = 0;
private static final int ZZ_NO_MATCH = 1;
private static final int ZZ_PUSHBACK_2BIG = 2;
/* error messages for the codes above */
private static final String ZZ_ERROR_MSG[] = {
"Unkown internal scanner error",
"Error: could not match input",
"Error: pushback value was too large"
};
/**
* ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code>
*/
private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute();
private static final String ZZ_ATTRIBUTE_PACKED_0 =
"\4\0\1\11\1\1\1\11\2\1\1\11\1\1\2\11"+
"\4\1\1\11\1\1\3\11\1\0\7\11\2\1\3\0"+
"\1\11";
private static int [] zzUnpackAttribute() {
int [] result = new int[36];
int offset = 0;
offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);
return result;
}
private static int zzUnpackAttribute(String packed, int offset, int [] result) {
int i = 0; /* index in packed string */
int j = offset; /* index in unpacked array */
int l = packed.length();
while (i < l) {
int count = packed.charAt(i++);
int value = packed.charAt(i++);
do result[j++] = value; while (--count > 0);
}
return j;
}
/** the input device */
private java.io.Reader zzReader;
/** the current state of the DFA */
private int zzState;
/** the current lexical state */
private int zzLexicalState = YYINITIAL;
/** this buffer contains the current text to be matched and is
the source of the yytext() string */
private char zzBuffer[] = new char[ZZ_BUFFERSIZE];
/** the textposition at the last accepting state */
private int zzMarkedPos;
/** the current text position in the buffer */
private int zzCurrentPos;
/** startRead marks the beginning of the yytext() string in the buffer */
private int zzStartRead;
/** endRead marks the last character in the buffer, that has been read
from input */
private int zzEndRead;
/** number of newlines encountered up to the start of the matched text */
private int yyline;
/** the number of characters up to the start of the matched text */
private int yychar;
/**
* the number of characters from the last newline up to the start of the
* matched text
*/
private int yycolumn;
/**
* zzAtBOL == true <=> the scanner is currently at the beginning of a line
*/
private boolean zzAtBOL = true;
/** zzAtEOF == true <=> the scanner is at the EOF */
private boolean zzAtEOF;
/** denotes if the user-EOF-code has already been executed */
private boolean zzEOFDone;
/**
* The number of occupied positions in zzBuffer beyond zzEndRead.
* When a lead/high surrogate has been read from the input stream
* into the final zzBuffer position, this will have a value of 1;
* otherwise, it will have a value of 0.
*/
private int zzFinalHighSurrogate = 0;
/* user code: */
private String sourceCode;
public PropertiesLexer(String sourceCode){
this(new StringReader(sourceCode));
this.sourceCode = sourceCode;
}
public void yypushbackstr(String s, int state)
{
sourceCode = s + sourceCode.substring(yychar + yylength());
yyreset(new StringReader(sourceCode));
yybegin(state);
}
public void yypushbackstr(String s)
{
yypushbackstr(s, YYINITIAL);
}
StringBuilder string = new StringBuilder();
private static String xmlTagName = "";
public int yychar() {
return yychar;
}
private Stack<ParsedSymbol> pushedBack = new Stack<>();
public int yyline() {
return yyline + 1;
}
public void pushback(ParsedSymbol symb) {
pushedBack.push(symb);
last = null;
}
ParsedSymbol last;
public ParsedSymbol lex() throws java.io.IOException, PropertiesParseException{
ParsedSymbol ret = null;
if (!pushedBack.isEmpty()){
ret = last = pushedBack.pop();
} else {
ret = last = yylex();
}
return ret;
}
private int count(String str, String target) {
return (str.length() - str.replace(target, "").length()) / target.length();
}
/**
* Creates a new scanner
*
* @param in the java.io.Reader to read input from.
*/
public PropertiesLexer(java.io.Reader in) {
this.zzReader = in;
}
/**
* Unpacks the compressed character translation table.
*
* @param packed the packed character translation table
* @return the unpacked character translation table
*/
private static char [] zzUnpackCMap(String packed) {
char [] map = new char[0x110000];
int i = 0; /* index in packed string */
int j = 0; /* index in unpacked array */
while (i < 94) {
int count = packed.charAt(i++);
char value = packed.charAt(i++);
do map[j++] = value; while (--count > 0);
}
return map;
}
/**
* Refills the input buffer.
*
* @return <code>false</code>, iff there was new input.
*
* @exception java.io.IOException if any I/O-Error occurs
*/
private boolean zzRefill() throws java.io.IOException {
/* first: make room (if you can) */
if (zzStartRead > 0) {
zzEndRead += zzFinalHighSurrogate;
zzFinalHighSurrogate = 0;
System.arraycopy(zzBuffer, zzStartRead,
zzBuffer, 0,
zzEndRead-zzStartRead);
/* translate stored positions */
zzEndRead-= zzStartRead;
zzCurrentPos-= zzStartRead;
zzMarkedPos-= zzStartRead;
zzStartRead = 0;
}
/* is the buffer big enough? */
if (zzCurrentPos >= zzBuffer.length - zzFinalHighSurrogate) {
/* if not: blow it up */
char newBuffer[] = new char[zzBuffer.length*2];
System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length);
zzBuffer = newBuffer;
zzEndRead += zzFinalHighSurrogate;
zzFinalHighSurrogate = 0;
}
/* fill the buffer with new input */
int requested = zzBuffer.length - zzEndRead;
int totalRead = 0;
while (totalRead < requested) {
int numRead = zzReader.read(zzBuffer, zzEndRead + totalRead, requested - totalRead);
if (numRead == -1) {
break;
}
totalRead += numRead;
}
if (totalRead > 0) {
zzEndRead += totalRead;
if (totalRead == requested) { /* possibly more input available */
if (Character.isHighSurrogate(zzBuffer[zzEndRead - 1])) {
--zzEndRead;
zzFinalHighSurrogate = 1;
}
}
return false;
}
// totalRead = 0: End of stream
return true;
}
/**
* Closes the input stream.
*/
public final void yyclose() throws java.io.IOException {
zzAtEOF = true; /* indicate end of file */
zzEndRead = zzStartRead; /* invalidate buffer */
if (zzReader != null)
zzReader.close();
}
/**
* Resets the scanner to read from a new input stream.
* Does not close the old reader.
*
* All internal variables are reset, the old input stream
* <b>cannot</b> be reused (internal buffer is discarded and lost).
* Lexical state is set to <tt>ZZ_INITIAL</tt>.
*
* Internal scan buffer is resized down to its initial length, if it has grown.
*
* @param reader the new input stream
*/
public final void yyreset(java.io.Reader reader) {
zzReader = reader;
zzAtBOL = true;
zzAtEOF = false;
zzEOFDone = false;
zzEndRead = zzStartRead = 0;
zzCurrentPos = zzMarkedPos = 0;
zzFinalHighSurrogate = 0;
yyline = yychar = yycolumn = 0;
zzLexicalState = YYINITIAL;
if (zzBuffer.length > ZZ_BUFFERSIZE)
zzBuffer = new char[ZZ_BUFFERSIZE];
}
/**
* Returns the current lexical state.
*/
public final int yystate() {
return zzLexicalState;
}
/**
* Enters a new lexical state
*
* @param newState the new lexical state
*/
public final void yybegin(int newState) {
zzLexicalState = newState;
}
/**
* Returns the text matched by the current regular expression.
*/
public final String yytext() {
return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead );
}
/**
* Returns the character at position <tt>pos</tt> from the
* matched text.
*
* It is equivalent to yytext().charAt(pos), but faster
*
* @param pos the position of the character to fetch.
* A value from 0 to yylength()-1.
*
* @return the character at position pos
*/
public final char yycharat(int pos) {
return zzBuffer[zzStartRead+pos];
}
/**
* Returns the length of the matched text region.
*/
public final int yylength() {
return zzMarkedPos-zzStartRead;
}
/**
* Reports an error that occured while scanning.
*
* In a wellformed scanner (no or only correct usage of
* yypushback(int) and a match-all fallback rule) this method
* will only be called with things that "Can't Possibly Happen".
* If this method is called, something is seriously wrong
* (e.g. a JFlex bug producing a faulty scanner etc.).
*
* Usual syntax/scanner level error handling should be done
* in error fallback rules.
*
* @param errorCode the code of the errormessage to display
*/
private void zzScanError(int errorCode) {
String message;
try {
message = ZZ_ERROR_MSG[errorCode];
}
catch (ArrayIndexOutOfBoundsException e) {
message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR];
}
throw new Error(message);
}
/**
* Pushes the specified amount of characters back into the input stream.
*
* They will be read again by then next call of the scanning method
*
* @param number the number of characters to be read again.
* This number must not be greater than yylength()!
*/
public void yypushback(int number) {
if ( number > yylength() )
zzScanError(ZZ_PUSHBACK_2BIG);
zzMarkedPos -= number;
}
/**
* Resumes scanning until the next regular expression is matched,
* the end of input is encountered or an I/O-Error occurs.
*
* @return the next token
* @exception java.io.IOException if any I/O-Error occurs
*/
public ParsedSymbol yylex() throws java.io.IOException, PropertiesParseException {
int zzInput;
int zzAction;
// cached fields:
int zzCurrentPosL;
int zzMarkedPosL;
int zzEndReadL = zzEndRead;
char [] zzBufferL = zzBuffer;
char [] zzCMapL = ZZ_CMAP;
int [] zzTransL = ZZ_TRANS;
int [] zzRowMapL = ZZ_ROWMAP;
int [] zzAttrL = ZZ_ATTRIBUTE;
while (true) {
zzMarkedPosL = zzMarkedPos;
yychar+= zzMarkedPosL-zzStartRead;
zzAction = -1;
zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL;
zzState = ZZ_LEXSTATE[zzLexicalState];
// set up zzAction for empty match case:
int zzAttributes = zzAttrL[zzState];
if ( (zzAttributes & 1) == 1 ) {
zzAction = zzState;
}
zzForAction: {
while (true) {
if (zzCurrentPosL < zzEndReadL) {
zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL);
zzCurrentPosL += Character.charCount(zzInput);
}
else if (zzAtEOF) {
zzInput = YYEOF;
break zzForAction;
}
else {
// store back cached positions
zzCurrentPos = zzCurrentPosL;
zzMarkedPos = zzMarkedPosL;
boolean eof = zzRefill();
// get translated positions and possibly new buffer
zzCurrentPosL = zzCurrentPos;
zzMarkedPosL = zzMarkedPos;
zzBufferL = zzBuffer;
zzEndReadL = zzEndRead;
if (eof) {
zzInput = YYEOF;
break zzForAction;
}
else {
zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL);
zzCurrentPosL += Character.charCount(zzInput);
}
}
int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ];
if (zzNext == -1) break zzForAction;
zzState = zzNext;
zzAttributes = zzAttrL[zzState];
if ( (zzAttributes & 1) == 1 ) {
zzAction = zzState;
zzMarkedPosL = zzCurrentPosL;
if ( (zzAttributes & 8) == 8 ) break zzForAction;
}
}
}
// store back cached position
zzMarkedPos = zzMarkedPosL;
switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
case 1:
{ string.setLength(0); string.append(yytext()); yybegin(KEY);
}
case 21: break;
case 2:
{ return new ParsedSymbol(SymbolType.EMPTY_LINE, null);
}
case 22: break;
case 3:
{
}
case 23: break;
case 4:
{ yybegin(COMMENT);
return new ParsedSymbol(SymbolType.COMMENT, yytext().substring(1));
}
case 24: break;
case 5:
{ yybegin(YYINITIAL);
}
case 25: break;
case 6:
{ string.append(yytext());
}
case 26: break;
case 7:
{ String key = string.toString();
yybegin(VALUE);
string.setLength(0);
return new ParsedSymbol(SymbolType.KEY, key);
}
case 27: break;
case 8:
{ yybegin(YYINITIAL);
return new ParsedSymbol(SymbolType.VALUE, string.toString());
}
case 28: break;
case 9:
{ string.append(":");
}
case 29: break;
case 10:
{ string.append("\\\\");
}
case 30: break;
case 11:
{ string.append("#");
}
case 31: break;
case 12:
{ string.append("\\t");
}
case 32: break;
case 13:
{ string.append("\\f");
}
case 33: break;
case 14:
{ string.append("\\r");
}
case 34: break;
case 15:
{ string.append("\\n");
}
case 35: break;
case 16:
{ string.append(" ");
}
case 36: break;
case 17:
{ string.append("!");
}
case 37: break;
case 18:
{ string.append("=");
}
case 38: break;
case 19:
{ string.append("\r\n");
}
case 39: break;
case 20:
{ string.append((char)Integer.parseInt(yytext().substring(2), 16));
}
case 40: break;
default:
if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {
zzAtEOF = true;
switch (zzLexicalState) {
case VALUE: {
yybegin(YYINITIAL);
return new ParsedSymbol(SymbolType.VALUE, string.toString());
}
case 37: break;
default:
{
return new ParsedSymbol(SymbolType.EOF, null);
}
}
}
else {
zzScanError(ZZ_NO_MATCH);
}
}
}
}
}

View File

@@ -0,0 +1,9 @@
package com.jpexs.helpers.properties;
/**
*
* @author JPEXS
*/
public class PropertiesParseException extends Exception {
}

View File

@@ -0,0 +1,13 @@
package com.jpexs.helpers.properties;
/**
*
* @author JPEXS
*/
public enum SymbolType {
KEY,
VALUE,
COMMENT,
EMPTY_LINE,
EOF
}

2
resources/translator.bat Normal file
View File

@@ -0,0 +1,2 @@
@echo off
start javaw -jar "%~dp0\ffdec.jar" -translator

105
resources/translator.sh Normal file
View File

@@ -0,0 +1,105 @@
#!/usr/bin/env bash
# Based on Freerapid Downloader startup script - created by Petris 2009
# FFDec requires Oracle Java 8
# Look for java in these directories
LOOKUP_JRE_DIRS="/usr/lib/jvm/* /opt/java* /opt/jre*"
# Required version
REQ_JVER1=1
REQ_JVER2=8
REQ_JVER3=0
REQ_JVER4=0
search_jar_file() {
JAR_FILE_CANDIDATES='./ffdec.jar ../dist/ffdec.jar /usr/share/java/ffdec.jar /usr/share/java/ffdec/ffdec.jar /usr/share/java/jpexs-decompiler/ffdec.jar'
for f in $JAR_FILE_CANDIDATES ; do
[ -r "$f" ] && JAR_FILE="$f" && return 0
done
echo Unable to find ffdec.jar in the following locations:
echo "${JAR_FILE_CANDIDATES// /$'\n'}"
return 1
}
check_java_version () {
JVER1=`echo $JAVA_VERSION_OUTPUT | sed 's/java version "\([0-9]*\)\.[0-9]*\.[0-9]*_[0-9]*".*/\1/'`
JVER2=`echo $JAVA_VERSION_OUTPUT | sed 's/java version "[0-9]*\.\([0-9]*\)\.[0-9]*_[0-9]*".*/\1/'`
JVER3=`echo $JAVA_VERSION_OUTPUT | sed 's/java version "[0-9]*\.[0-9]*\.\([0-9]*\)_[0-9]*".*/\1/'`
JVER4=`echo $JAVA_VERSION_OUTPUT | sed 's/java version "[0-9]*\.[0-9]*\.[0-9]*_\([0-9]*\)".*/\1/'`
if [ $JVER1 -gt $REQ_JVER1 ]; then
return 0
elif [ $JVER1 -lt $REQ_JVER1 ]; then
return 1
fi
if [ $JVER2 -gt $REQ_JVER2 ]; then
return 0
elif [ $JVER2 -lt $REQ_JVER2 ]; then
return 1
fi
if [ $JVER3 -gt $REQ_JVER3 ]; then
return 0
elif [ $JVER3 -lt $REQ_JVER3 ]; then
return 1
fi
if [ $JVER4 -lt $REQ_JVER4 ]; then
return 1
fi
return 0
}
# Handle symlinks
PROGRAM="$0"
while [ -L "$PROGRAM" ]; do
PROGRAM=`readlink -f "$PROGRAM"`
done
pushd "`dirname \"$PROGRAM\"`" > /dev/null
search_jar_file || exit 1
if [ ${JAR_FILE:0:1} != '/' ] ; then
JAR_FILE=`pwd`/$JAR_FILE
fi
popd > /dev/null
args=(-jar $JAR_FILE -translator)
if [ "`uname`" = "Darwin" ]; then
args=(-Xdock:name=FFDec -Xdock:icon=icon.png "${args[@]}")
fi
# Check default java
if [ -x "`which java`" ]; then
JAVA_VERSION_OUTPUT=`java -version 2>&1`
JAVA_VERSION_OUTPUT=`echo $JAVA_VERSION_OUTPUT | sed 's/openjdk version/java version/'`
check_java_version && exec java "${args[@]}"
fi
# Test other possible Java locations
for JRE_PATH in $LOOKUP_JRE_DIRS; do
if [ -x "$JRE_PATH/bin/java" ]; then
JAVA_VERSION_OUTPUT=`"$JRE_PATH/bin/java" -version 2>&1`
JAVA_VERSION_OUTPUT=`echo $JAVA_VERSION_OUTPUT | sed 's/openjdk version/java version/'`
check_java_version && {
export JRE_PATH
exec $JRE_PATH/bin/java "${args[@]}"
}
fi
done
# Failed
if [ -x "`which xmessage`" ]; then
xmessage -nearmouse -file - <<EOF
Failed to find a suitable java version.
Required: $REQ_JVER1.$REQ_JVER2.$REQ_JVER3_$REQ_JVER4 or newer.
EOF
else
echo Failed to find a suitable java version.
echo Required: $REQ_JVER1.$REQ_JVER2.$REQ_JVER3_$REQ_JVER4 or newer.
fi
exit 1

View File

@@ -216,6 +216,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.jpexs.decompiler.flash.Bundle;
import com.jpexs.decompiler.flash.gui.translator.Translator;
/**
*
@@ -908,7 +909,9 @@ public class CommandLineArgumentParser {
command = nextParam.substring(1);
}
if (command.equals("swf2exe")) {
if (command.equals("translator")) {
Translator.main(new String[]{});
} else if (command.equals("swf2exe")) {
parseSwf2Exe(args, charset);
} else if (command.equals("abcmerge")) {
parseAbcMerge(args, charset);

View File

@@ -152,7 +152,7 @@ public class View {
* Sets windows Look and Feel
*/
public static void setLookAndFeel() {
// Save default font for Chinese characters
final Font defaultFont = (new JLabel()).getFont();
try {

File diff suppressed because it is too large Load Diff