1084 lines
25 KiB
Java
1084 lines
25 KiB
Java
/**
|
|
* @author jakoboberbuchner
|
|
*
|
|
*/
|
|
package Converters;
|
|
|
|
import java.io.*;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
import java.time.OffsetDateTime;
|
|
import java.time.format.DateTimeFormatter;
|
|
|
|
|
|
public class C_Swift_Converter {
|
|
|
|
public static String topLevelComments( String inName, String outName ) {
|
|
|
|
String[] tokens = inName.split("[\\|/]");
|
|
inName = tokens[tokens.length - 1];
|
|
|
|
tokens = outName.split("[\\|/]");
|
|
outName = tokens[tokens.length - 1];
|
|
|
|
DateTimeFormatter datef = DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss O" );
|
|
|
|
return "///\n/// V2.1 - C to Swift Convertor Created by: Jakob A. Oberbuchner ©2024\n///\n"
|
|
+ "/// Converted Info:\n"
|
|
+ "/// \t" + inName + " --> " + outName
|
|
+ "\n/// \tDate: " + OffsetDateTime.now().format( datef )
|
|
+ "\n///\n";
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* @param args
|
|
*/
|
|
public static void main(String[] args) {
|
|
|
|
if (args.length == 2) {
|
|
|
|
String inputFile = args[0];
|
|
|
|
|
|
//Create the file if it does not exist, or open it to overwrite.
|
|
try {
|
|
|
|
//Init the PrintWriter for the output file
|
|
BufferedReader sourceFile = new BufferedReader( new FileReader(inputFile) );
|
|
|
|
String line = sourceFile.readLine();
|
|
|
|
ArrayList<CodeItem> mainBlocks = new ArrayList<CodeItem>();
|
|
ArrayList<Definition> defines = new ArrayList<Definition>();
|
|
mainBlocks.add(null);
|
|
|
|
boolean hasBlockComment = false;
|
|
|
|
while (line != null) { //Parsing Loop
|
|
line.replace("typedef", "");
|
|
String[] codeComments = line.split("//"); //Split up comments if they exist
|
|
|
|
|
|
// Check if the block comment starts on this line
|
|
if (line.contains("/*")) {
|
|
hasBlockComment = true;
|
|
}
|
|
|
|
|
|
if (!hasBlockComment && codeComments.length != 0) { //If there is any data on this line
|
|
parseLine(codeComments[0], mainBlocks, defines);
|
|
}
|
|
|
|
//Check if the line has the end of the block comment
|
|
if (line.contains("*/")) {
|
|
hasBlockComment = false;
|
|
}
|
|
|
|
//TODO Comments pass through optional
|
|
line = sourceFile.readLine(); //Read the Next line
|
|
}
|
|
|
|
sourceFile.close(); //Save changes
|
|
|
|
} catch (IOException e) {
|
|
System.out.println("Error: " + e.getMessage());
|
|
e.printStackTrace();
|
|
}
|
|
} else {
|
|
System.out.println("\nError: No Input and/or Output file specified!!\n");
|
|
}
|
|
|
|
}//main(String[] args)
|
|
|
|
|
|
|
|
public static String hexToDec(String code) {
|
|
while(code.contains("0x")) {
|
|
int inx = code.indexOf("0x");
|
|
int end = code.indexOf("\\s+", inx);
|
|
|
|
Pattern p = Pattern.compile("0x[0-9]|[a-f]"); // insert your pattern here
|
|
Matcher m = p.matcher(code.substring(inx));
|
|
if (m.find()) {
|
|
end = m.start();
|
|
} else {
|
|
end = -1;
|
|
}
|
|
|
|
// String strvalue = code.substring(code.indexOf("=") + 1).strip().replace(",", "");
|
|
|
|
long value = 0;
|
|
// value = Long.decode(strvalue);
|
|
end = 2;
|
|
while( (end + inx < code.length()) && ( Character.isDigit(code.charAt(inx + end)) || code.charAt(inx + end) >= 'a' && code.charAt(inx + end) <= 'f' || code.charAt(inx + end) >= 'A' && code.charAt(inx + end) <= 'F') ) {
|
|
end++;
|
|
}
|
|
|
|
if (end > 0) {
|
|
// value = Long.parseLong(code.substring(inx+2, inx+end), 16); //Convert from hex
|
|
value = Long.decode(code.substring(inx, inx+end));
|
|
code = code.substring(0, inx) + value + code.substring(inx+end);
|
|
} else {
|
|
// value = Long.parseLong(code.substring(inx+2), 16); //Convert from hex
|
|
value = Long.decode(code.substring(inx));
|
|
code = code.substring(0, inx) + value;
|
|
}
|
|
|
|
}
|
|
return code;
|
|
}
|
|
|
|
|
|
/***********************************************************************************************************/
|
|
|
|
|
|
public static void parseLine(String code, ArrayList<CodeItem> mainItems, ArrayList<Definition> defines) {
|
|
|
|
if (code.contains("(") && !code.contains("#") ) {
|
|
//It is a function definition and we ignore it
|
|
return;
|
|
}
|
|
|
|
if (!code.contains("#define") && code.contains("#")) {
|
|
//is a #if, #endif, #include, etc...
|
|
return;
|
|
}
|
|
|
|
//Check for any hex values, change to decimal
|
|
code = hexToDec(code);
|
|
|
|
code = code.replace("typedef", "").replace("__attribute__((packed))", "");
|
|
code = code.strip(); //remove leading and trailing whitespace
|
|
code = code.replace(";", ""); //.replace("\t", "") if needed but strip chould remove tabs
|
|
String[] tokens = code.split("\\s+"); //splits at any whitespace
|
|
for( int i = 0; i < tokens.length; i++) {
|
|
tokens[i] = tokens[i].strip( ); //remove leading and trailing whitespace for each part
|
|
}
|
|
|
|
boolean mainComplete = false;
|
|
|
|
switch (tokens.length) {
|
|
case 1: //A single word or character
|
|
mainComplete = case1(tokens, mainItems);
|
|
break;
|
|
|
|
|
|
case 2: //Variable or Type definition ie. "struct Hello", "uint32_t var;, struct {", "} hello;
|
|
mainComplete = case2(tokens, mainItems, defines);
|
|
break;
|
|
|
|
|
|
case 3: //ie. "struct Hello {", or an enum case "hello = 1"
|
|
mainComplete = case3(tokens, mainItems, defines);
|
|
break;
|
|
|
|
|
|
default:
|
|
System.out.println("Error: parseLine Error, missing a case!!!!");
|
|
}
|
|
|
|
if (mainComplete) {
|
|
mainItems.add(null); //Add empty non-initialized Item
|
|
}
|
|
}
|
|
|
|
|
|
/***********************************************************************************************************/
|
|
|
|
|
|
public static boolean case1(String[] tokens, ArrayList<CodeItem> mainItems) { //The argument must have 1 arguments minimum extra will be ignored
|
|
if (tokens.length < 1) { return false; }
|
|
|
|
if (tokens[0].length() == 0) { //skips empty lines like ''
|
|
return false;
|
|
}
|
|
|
|
CodeItem main = mainItems.get(mainItems.size()-1); //The reference to the main Item
|
|
|
|
boolean isComplete = false;
|
|
|
|
switch (tokens[0].charAt(0)) {
|
|
case '{':
|
|
//Doesn't do anything here
|
|
break;
|
|
|
|
case '}': //Ending the current section
|
|
if ( main.setFinishedItem() ) { //tell the main Item that it or a sub item is complete, get if the main is completed
|
|
isComplete = true;
|
|
}
|
|
break;
|
|
|
|
//Cases for structures, enums, unions.
|
|
case 's':
|
|
case 'u':
|
|
case 'e':
|
|
Type type = getType(mainItems, tokens[0].strip());
|
|
String name = "notNamed";
|
|
|
|
if (main == null) {
|
|
mainItems.set(mainItems.size()-1, new CodeItem(type, name)); //Override the null value
|
|
|
|
} else {
|
|
main.addSubItem(new CodeItem(type, name)); //add the item to the main item
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
System.out.println("Error: parseLine case 1: error");
|
|
}
|
|
|
|
return isComplete;
|
|
}
|
|
|
|
|
|
/***********************************************************************************************************/
|
|
|
|
|
|
/**
|
|
* Purpose:
|
|
* @param tokens: An Array of Strings to be parsed
|
|
* @param main: The Encompassing Item, null if there is not yet an item
|
|
* @return Boolean representing if the main item is complete (aka found a '}')
|
|
*/
|
|
public static boolean case2(String[] tokens, ArrayList<CodeItem> mainItems, ArrayList<Definition> defines) { //The argument must have 1 arguments minimum extra will be ignored
|
|
if (tokens.length < 2) { return false; }
|
|
|
|
boolean isComplete = false;
|
|
CodeItem main = mainItems.get(mainItems.size()-1); //The reference to the main Item
|
|
|
|
if ( tokens[0].strip().equals("}") ) {
|
|
main.getArrayValues(defines, tokens[1]); //Must be before main.setFinishedItem()
|
|
|
|
int bracketInx = tokens[1].indexOf("["); //Try to get the brackets index
|
|
|
|
if (bracketInx == -1) { //if there is no bracket
|
|
bracketInx = tokens[1].length(); //Set to the max index excluded
|
|
}
|
|
|
|
main.setName(tokens[1].substring(0, bracketInx)); //Set the name of the Item
|
|
|
|
if ( main.setFinishedItem() ) { //tell the main Item that it or a sub item is complete, get if the main is completed
|
|
isComplete = true; //The main (encompassing) item is complete
|
|
}
|
|
|
|
|
|
} else if ( tokens[1].strip().equals("{") ) { //This is like struct {, enum {, uinion
|
|
|
|
Type type = getType(mainItems, tokens[0].strip());
|
|
String name = "noName";
|
|
|
|
//Add the Item to the
|
|
if (main == null) {
|
|
mainItems.set(mainItems.size()-1, new CodeItem(type, name)); //Override the null value
|
|
|
|
} else {
|
|
main.addSubItem(new CodeItem(type, name)); //add the item to the main item
|
|
}
|
|
|
|
|
|
} else { //Internal Item not the main
|
|
Type type = getType(mainItems, tokens[0].strip());
|
|
String name = "noName";
|
|
|
|
if (type == null) { //does not recognize the type
|
|
isComplete = false;
|
|
return isComplete;
|
|
}
|
|
|
|
CodeItem item = new CodeItem(type, name); //Initialize the Item and finally add it to the main later.
|
|
|
|
item.getArrayValues(defines, tokens[1]); //Must be before main.setFinishedItem()
|
|
|
|
int bracketInx = tokens[1].indexOf("["); //Try to get the brackets index
|
|
|
|
if (bracketInx == -1) { //if there is no bracket
|
|
bracketInx = tokens[1].length(); //Set to the max index excluded
|
|
}
|
|
name = tokens[1].substring(0, bracketInx);
|
|
item.setName(name); //Set the name of the Item
|
|
|
|
if (main == null) {
|
|
mainItems.set(mainItems.size()-1, item); //Override the null value
|
|
|
|
} else {
|
|
main.addSubItem(item); //add the item to the main item
|
|
}
|
|
|
|
// System.out.println("TEST this Section: else: case2()");
|
|
|
|
isComplete = false;
|
|
}
|
|
|
|
|
|
return isComplete;
|
|
}
|
|
|
|
|
|
/***********************************************************************************************************/
|
|
|
|
|
|
public static boolean case3(String[] tokens, ArrayList<CodeItem> mainItems, ArrayList<Definition> defines) { //The argument must have 1 arguments minimum extra will be ignored
|
|
if (tokens.length < 3) { return false; }
|
|
|
|
CodeItem main = mainItems.get(mainItems.size()-1); //The reference to the main Item
|
|
|
|
Type type = getType(mainItems, tokens[0].strip());
|
|
String name = tokens[1].strip();
|
|
|
|
if (type == null) {
|
|
type = new Type(Types.EnumItem);
|
|
name = tokens[0].strip();
|
|
long eVal = Long.parseLong(tokens[2].replace(",", "").strip());
|
|
main.addSubItem( new CodeItem(type, name, eVal) ); //Add the enum value to the Enum Code Item, false becasue enum case cannot contain sub items
|
|
|
|
} else if (type.type() == Types.Definition) {
|
|
|
|
Definition define = new Definition(name, findType(mainItems, tokens[2]), findValue(tokens[2]) );
|
|
|
|
defines.add(define); //add the definition to the array list
|
|
return false;
|
|
|
|
} else if (main != null) {
|
|
System.out.println("\nERROR: Should never get here: In 'case3()' main is not null and is being initialized??\n");
|
|
// main = new CodeItem(type, name); //Set the main Item
|
|
|
|
} else {
|
|
//Must set the first main Item
|
|
mainItems.set(mainItems.size()-1, new CodeItem(type, name)); //Override the null value
|
|
}
|
|
|
|
return false; //Always returns false
|
|
}
|
|
|
|
|
|
/***********************************************************************************************************/
|
|
|
|
|
|
public static Type getType(ArrayList<CodeItem> customTypes, String word) {
|
|
Type type = null;
|
|
|
|
switch(word) {
|
|
|
|
case "DateTime_t": //Custom Type
|
|
System.out.println("INFO: Using a custom type 'DateTime_t' treated as a swift 'Date' Type.");
|
|
type = new Type(Types.Date);
|
|
break;
|
|
|
|
case "#define":
|
|
type = new Type(Types.Definition);
|
|
break;
|
|
|
|
case "double":
|
|
type = new Type(Types.Double);
|
|
break;
|
|
case "float":
|
|
type = new Type(Types.Float);
|
|
break;
|
|
|
|
case "int":
|
|
type = new Type(Types.Int);
|
|
break;
|
|
case "int8_t":
|
|
type = new Type(Types.Int8);
|
|
break;
|
|
case "int16_t":
|
|
type = new Type(Types.Int16);
|
|
break;
|
|
case "int32_t":
|
|
type = new Type(Types.Int32);
|
|
break;
|
|
case "int64_t":
|
|
type = new Type(Types.Int64);
|
|
break;
|
|
|
|
case "uint":
|
|
System.out.println("NO SUCH Type as 'uint' in C");
|
|
type = new Type(Types.UInt);
|
|
break;
|
|
case "uint8_t":
|
|
type = new Type(Types.UInt8);
|
|
break;
|
|
case "uint16_t":
|
|
type = new Type(Types.UInt16);
|
|
break;
|
|
case "uint32_t":
|
|
type = new Type(Types.UInt32);
|
|
break;
|
|
case "uint64_t":
|
|
type = new Type(Types.UInt64);
|
|
break;
|
|
|
|
case "struct":
|
|
type = new Type(Types.Struct);
|
|
break;
|
|
|
|
case "enum":
|
|
type = new Type(Types.Enum);
|
|
break;
|
|
|
|
case "union":
|
|
type = new Type(Types.Union);
|
|
break;
|
|
|
|
case "char":
|
|
//TODO Sort out what to do for multiple type names
|
|
// case "const char*":
|
|
// case "const char *":
|
|
|
|
default:
|
|
// System.out.println("getType() error: type not found OR ADDED!!!!");
|
|
// System.out.println("Info: 'getType()': Found Enum case or unknown type.");
|
|
|
|
//Check for types defined previously
|
|
for (int i = 0; i < customTypes.size(); i++) {
|
|
if ( customTypes.get(i) != null && customTypes.get(i).getType() != null && customTypes.get(i).getName().matches(word) ) {
|
|
switch(customTypes.get(i).getType().type()) {
|
|
case Enum:
|
|
type = new Type(word, word + "_E", Types.Enum);
|
|
break;
|
|
|
|
case Struct:
|
|
type = new Type(word, word + "_C", Types.Struct);
|
|
break;
|
|
|
|
case Union:
|
|
type = new Type(word, word + "_U", Types.Union);
|
|
break;
|
|
|
|
default:
|
|
System.out.println("ERROR: Cannot have a Custom Primitive Type!!!");
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return type;
|
|
}
|
|
|
|
/***********************************************************************************************************/
|
|
|
|
|
|
public static Type findType(ArrayList<CodeItem> customTypes, String text) {
|
|
|
|
//Only checks for the basic types
|
|
String[] checkWith = {"uint8_t", "uint16_t", "uint32_t", "uint64_t", "int8_t", "int16_t", "int32_t", "int64_t", "int", "float", "double", "char"};
|
|
|
|
for(int i = 0; i < checkWith.length; i++) {
|
|
if (text.contains(checkWith[i])) {
|
|
|
|
return getType(customTypes, checkWith[i]);
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/***********************************************************************************************************/
|
|
|
|
public static String findValue(String text) {
|
|
|
|
//Only checks for the basic types
|
|
String[] checkWith = {"(uint8_t)", "(uint16_t)", "(uint32_t)", "(uint64_t)", "(int8_t)", "(int16_t)", "(int32_t)", "(int64_t)", "(int)", "(float)", "(double)", "(char)"};
|
|
|
|
for(int i = 0; i < checkWith.length; i++) {
|
|
|
|
text = text.replace(checkWith[i], "");
|
|
}
|
|
|
|
// text.replace("[a-zA-Z]", "");
|
|
return text;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
enum Types {
|
|
Date, //NOT an actual C type but is a structure
|
|
// Void, //Ignores all void items
|
|
Definition, //C defines, -> let constant in swift
|
|
Double, Float,
|
|
|
|
Int, Int64, Int32, Int16, Int8,
|
|
|
|
UInt, UInt64, UInt32, UInt16, UInt8,
|
|
|
|
Char, /* String(""), */
|
|
|
|
Enum, EnumItem,
|
|
|
|
Struct, //Swift Struct NOT USED!!
|
|
Union,
|
|
|
|
UserDefined
|
|
|
|
// public final String cName; //Type name in C Lang
|
|
// public final String sName; //Type name in Swift
|
|
// public final Type superType;//Type of the UserDefined Type
|
|
//
|
|
// private Type(String cName, String sName) {
|
|
// this.cName = cName;
|
|
// this.sName = sName;
|
|
// this.superType = null;
|
|
// }
|
|
//
|
|
// private Type(String cName, String sName, Type superType) {
|
|
// this.cName = cName;
|
|
// this.sName = sName;
|
|
// this.superType = superType;
|
|
// }
|
|
//
|
|
//// public static Type custom(String cName, String sName, Type superType) {
|
|
//// Type type = Type.UserDefined;
|
|
//// type.cName = cName;
|
|
//// type.sName = sName;
|
|
//// type.superType = superType;
|
|
//// return type;
|
|
//// }
|
|
//
|
|
// public boolean isCustom( ) {
|
|
// if(this == Type.UserDefined) {
|
|
// return true;
|
|
// } else {
|
|
// return false;
|
|
// }
|
|
// }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
class Type {
|
|
private Types type;
|
|
private String cName;
|
|
private String sName;
|
|
private Types superType;
|
|
|
|
|
|
public Type(Types type, String cName, String sName) {
|
|
this.cName = cName;
|
|
this.sName = sName;
|
|
this.superType = null;
|
|
}
|
|
|
|
public Type(String cName, String sName, Types superType) {
|
|
this.type = Types.UserDefined;
|
|
this.cName = cName;
|
|
this.sName = sName;
|
|
this.superType = superType;
|
|
}
|
|
|
|
public Types type( ) {
|
|
return this.type;
|
|
}
|
|
|
|
public String getCName( ) {
|
|
return this.cName;
|
|
}
|
|
|
|
public String getSName( ) {
|
|
return this.sName;
|
|
}
|
|
|
|
public Types getSuperType( ) {
|
|
return this.superType;
|
|
}
|
|
|
|
public boolean isCustom( ) {
|
|
if(this.type == Types.UserDefined) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public Type(Types type) {
|
|
this.type = type;
|
|
this.superType = null;
|
|
|
|
switch(type) {
|
|
case Char:
|
|
this.cName = "char";
|
|
this.sName = "Character";
|
|
break;
|
|
|
|
case Date:
|
|
this.cName = "DateTime_t";
|
|
this.sName = "Date";
|
|
break;
|
|
|
|
case Definition:
|
|
this.cName = "#define";
|
|
this.sName = "";
|
|
break;
|
|
|
|
case Double:
|
|
this.cName = "double";
|
|
this.sName = "Double";
|
|
break;
|
|
|
|
case Enum:
|
|
this.cName = "enum";
|
|
this.sName = "Enum";
|
|
break;
|
|
|
|
case EnumItem:
|
|
this.cName = "";
|
|
this.sName = "";
|
|
break;
|
|
|
|
case Float:
|
|
this.cName = "float";
|
|
this.sName = "Float";
|
|
break;
|
|
|
|
|
|
case Int:
|
|
this.cName = "int";
|
|
this.sName = "Int";
|
|
break;
|
|
|
|
case Int16:
|
|
this.cName = "int16_t";
|
|
this.sName = "Int16";
|
|
break;
|
|
|
|
case Int32:
|
|
this.cName = "int32_t";
|
|
this.sName = "Int32";
|
|
break;
|
|
|
|
case Int64:
|
|
this.cName = "int64_t";
|
|
this.sName = "Int64";
|
|
break;
|
|
|
|
case Int8:
|
|
this.cName = "int8_t";
|
|
this.sName = "Int8";
|
|
break;
|
|
|
|
case Struct:
|
|
this.cName = "struct";
|
|
this.sName = "";
|
|
break;
|
|
|
|
|
|
case UInt:
|
|
this.cName = "unsigned int";
|
|
this.sName = "UInt";
|
|
break;
|
|
|
|
case UInt16:
|
|
this.cName = "uint16_t";
|
|
this.sName = "UInt16";
|
|
break;
|
|
|
|
case UInt32:
|
|
this.cName = "uint32_t";
|
|
this.sName = "UInt32";
|
|
break;
|
|
|
|
case UInt64:
|
|
this.cName = "uint64_t";
|
|
this.sName = "UInt64";
|
|
break;
|
|
|
|
case UInt8:
|
|
this.cName = "uint8_t";
|
|
this.sName = "UInt8";
|
|
break;
|
|
|
|
case Union:
|
|
this.cName = "uinion";
|
|
this.sName = "";
|
|
break;
|
|
|
|
case UserDefined:
|
|
this.cName = "unknown!!!!";
|
|
this.sName = "unknown!!!!";
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
// Date("DateTime_t", "Date"), //NOT an actual C type but is a structure
|
|
//// Void, //Ignores all void items
|
|
// Definition("#define", ""), //C defines, -> let constant in swift
|
|
// Double("double", "Double"),
|
|
// Float("float", "Float"),
|
|
//
|
|
// Int("int", "Int"),
|
|
// Int64("int64_t", "Int64"),
|
|
// Int32("int32_t", "Int32"),
|
|
// Int16("int16_t", "Int16"),
|
|
// Int8("int8_t", "Int8"),
|
|
//
|
|
// UInt("unsigned int", "UInt"),
|
|
// UInt64("uint64_t", "UInt64"),
|
|
// UInt32("uint32_t", "UInt32"),
|
|
// UInt16("uint16_t", "UInt16"),
|
|
// UInt8("uint8_t", "UInt8"),
|
|
//
|
|
// Char("char", "Character"), /* String(""), */
|
|
//
|
|
// Enum("enum", "Enum"),
|
|
// EnumItem("", ""),
|
|
//
|
|
// Struct("struct", "Struct"), //Swift Struct NOT USED!!
|
|
// Union("uinion", ""),
|
|
//
|
|
// UserDefined("", "");
|
|
|
|
|
|
}
|
|
|
|
|
|
class IntegerDefine {
|
|
private Integer value;
|
|
private Definition define;
|
|
|
|
public IntegerDefine(int value) {
|
|
this.value = value;
|
|
}
|
|
|
|
public IntegerDefine(Definition define) {
|
|
this.define = define;
|
|
}
|
|
|
|
public String toString( ) {
|
|
if (value != null) {
|
|
return value + "";
|
|
} else {
|
|
return define.getName();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
class CodeItem {
|
|
private Type type;
|
|
private String name;
|
|
private long eValue; //Used for Enums only
|
|
private ArrayList<IntegerDefine> arrayData;
|
|
private ArrayList<CodeItem> subItems; //Stores Sub items inside
|
|
|
|
//Internal ONLY
|
|
private int addItemTo = -1; // -1 if do not add to any subItem, otherwise the index of the item in subItems Array List
|
|
|
|
|
|
//General Constructor
|
|
public CodeItem(Type type, String name) {
|
|
this.type = type;
|
|
this.name = name;
|
|
this.eValue = -1;
|
|
this.arrayData = new ArrayList<IntegerDefine>();
|
|
this.subItems = new ArrayList<CodeItem>();
|
|
}
|
|
|
|
|
|
//Constructor used for enumerations
|
|
public CodeItem(Type type, String name, long eValue) {
|
|
this.type = type;
|
|
this.name = name;
|
|
this.eValue = eValue;
|
|
this.arrayData = new ArrayList<IntegerDefine>();;
|
|
this.subItems = new ArrayList<CodeItem>();
|
|
}
|
|
|
|
|
|
//*********** Getters and Setters *************//
|
|
public Type getType( ) {
|
|
return this.type;
|
|
}
|
|
|
|
public String getName( ) {
|
|
return this.name;
|
|
}
|
|
|
|
public void setName( String name ) {
|
|
|
|
if (this.addItemTo < 0) {
|
|
this.name = name;
|
|
|
|
} else {
|
|
this.subItems.get(addItemTo).setName(name);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Purpose: Used when checking for array dimensions
|
|
* @param size: Size of the array dimension to add
|
|
*/
|
|
private void addArrayDimension( IntegerDefine size ) {
|
|
this.arrayData.add(size);
|
|
}
|
|
|
|
|
|
/**
|
|
* Purpose: Adds the Item to the most internal structure that is active
|
|
* @param item: The CodeItem to be added
|
|
* @param canHold: If the 'item' can hold other items inside it
|
|
* @apiNote Is a recursive function!
|
|
*/
|
|
public void addSubItem( CodeItem item ) {
|
|
|
|
if (this.addItemTo < 0) {
|
|
this.subItems.add(item);
|
|
|
|
if (item.type.type() == Types.Enum || item.type.type() == Types.Struct || item.type.type() == Types.Union ) { //tell if the item can have sub items
|
|
this.addItemTo = subItems.size() - 1; //Set to the index of the new item
|
|
}
|
|
|
|
} else {
|
|
//Passes it into the structure that 'item' is in
|
|
this.subItems.get(addItemTo).addSubItem(item);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Purpose: Used when the end of a structure type thing is found at a '}'
|
|
* @apiNote Is a recursive function!
|
|
* @return boolean indicating if it is finished filling the sub Items
|
|
*/
|
|
//TODO: Check make sure working correctly
|
|
public boolean setFinishedItem( ) {
|
|
|
|
if (this.addItemTo < 0) {
|
|
return true;
|
|
} else {
|
|
if (this.subItems.get(addItemTo).setFinishedItem() ) { //Will countinue until the most internal structure is set complete
|
|
this.addItemTo = -1;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public boolean hasSubItems( ) {
|
|
return this.subItems != null;
|
|
}
|
|
|
|
|
|
//********************* Methods ***********************//
|
|
|
|
public void getArrayValues(ArrayList<Definition> defines, String word ) {
|
|
|
|
if (this.addItemTo < 0) {
|
|
word = word.replace("]","").replace(";", "");
|
|
|
|
String[] tokens = word.split("\\[");
|
|
|
|
if (tokens.length > 1) {
|
|
for(int i = 1; i < tokens.length; i++) { //skip the name of the variable
|
|
try {
|
|
this.addArrayDimension( new IntegerDefine(Integer.parseInt(tokens[i])) );
|
|
|
|
} catch (NumberFormatException e) {
|
|
boolean isDefined = false;
|
|
|
|
for(int j = 0; j < defines.size() && !isDefined; j++) {
|
|
if (defines.get(j).getName().equals(tokens[i])) {
|
|
this.addArrayDimension( new IntegerDefine(defines.get(j)) );
|
|
isDefined = true;
|
|
}
|
|
}
|
|
|
|
if (!isDefined) {
|
|
System.out.println("ERROR in 'getArrayValues()': ");
|
|
System.out.println( "\t" + e.getMessage());
|
|
}
|
|
} //try catch
|
|
}
|
|
}// if
|
|
|
|
} else {
|
|
this.subItems.get(addItemTo).getArrayValues(defines, word);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************************************************/
|
|
|
|
private String arrayStr(String typeStr, String initStr) {
|
|
String strOut = "";
|
|
|
|
for(int i = 0; i < arrayData.size(); i++) { strOut += "["; }
|
|
strOut += typeStr;
|
|
for(int i = 0; i < arrayData.size(); i++) { strOut += "]"; }
|
|
|
|
|
|
|
|
/** Following part initializes the array */
|
|
|
|
if (arrayData.size() > 0) {
|
|
strOut += " = " + strOut + "()";
|
|
}
|
|
|
|
// int embededCount = arrayData.size - 1;
|
|
// strOut += " = ";
|
|
// for(int i = 0; i < arrayData.size(); i++) {
|
|
// strOut += "Array<" + nChars(embededCount, "[") + typeStr + nChars(embededCount, "]") + ">(repeating: ";
|
|
// embededCount--;
|
|
// }
|
|
// strOut += initStr;
|
|
// for(int i = arrayData.size - 1; i >= 0; i--) {
|
|
// strOut += ", count: " + arrayData[i] + ")";
|
|
// }
|
|
|
|
return strOut;
|
|
}
|
|
|
|
|
|
/************************************************************************************************************/
|
|
|
|
private String nChars(int n, String str) {
|
|
String outStr = "";
|
|
|
|
for(int i = 0; i < n; i++) { //Bad for large "n" values
|
|
outStr += str;
|
|
}
|
|
return outStr;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class Definition extends CodeItem {
|
|
|
|
private Type actualType;
|
|
private String value;
|
|
|
|
public Definition(String name, Type type, String value) {
|
|
super(new Type(Types.Definition), name);
|
|
|
|
this.actualType = type;
|
|
this.value = value;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Purpose:
|
|
* @param tabs
|
|
* @param isInside
|
|
* @param valueOffset
|
|
* @return String Array index 0 If null then not used, otherwise used for Structure and Enum definition before main struct
|
|
*/
|
|
public String[] getSwift( String tabs, boolean isInside, int valueOffset ) { //if isInside is true then it will also output the variable definition
|
|
|
|
String out = tabs + "let " + super.getName();
|
|
|
|
if (this.actualType != null) { //check if there is an actual type for it
|
|
out += ": ";
|
|
|
|
switch(this.actualType.type()) {
|
|
case Char:
|
|
out += "Character";
|
|
break;
|
|
|
|
case Double:
|
|
out += "Double";
|
|
break;
|
|
case Float:
|
|
out += "Float";
|
|
break;
|
|
|
|
case Int:
|
|
out += "Int";
|
|
break;
|
|
|
|
case Int16:
|
|
out += "Int16";
|
|
break;
|
|
|
|
case Int32:
|
|
out += "Int32";
|
|
break;
|
|
|
|
case Int64:
|
|
out += "Int64";
|
|
break;
|
|
|
|
case Int8:
|
|
out += "Int8";
|
|
break;
|
|
|
|
case UInt:
|
|
out += "UInt";
|
|
break;
|
|
|
|
case UInt16:
|
|
out += "UInt16";
|
|
break;
|
|
|
|
case UInt32:
|
|
out += "UInt32";
|
|
break;
|
|
|
|
case UInt64:
|
|
out += "UInt64";
|
|
break;
|
|
|
|
case UInt8:
|
|
out += "UInt8";
|
|
break;
|
|
|
|
|
|
case Enum:
|
|
// case String:
|
|
case Struct:
|
|
case Union:
|
|
case Date:
|
|
case EnumItem:
|
|
case Definition:
|
|
default:
|
|
out = "#define ERROR! Found Type is NOT supported";
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
out += " = " + this.value;
|
|
|
|
String[] output = {out, ""};
|
|
|
|
return output;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|