Cleaning up callback code generation; Fixing a few minor issues, e.g. indentation...
[iot2.git] / iotjava / iotpolicy / IoTCompiler.java
index 028373b77b8883a43f9b70ee16089ec01bfa7fd1..857199833799691896a5153f3e01c368d18319ec 100644 (file)
@@ -327,7 +327,9 @@ public class IoTCompiler {
                        InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
                        List<String> methods = intDecl.getMethods();
                        Set<String> importClasses = getImportClasses(methods, intDecl);
-                       printImportStatements(importClasses);
+                       List<String> stdImportClasses = getStandardJavaIntfaceImportClasses();
+                       List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
+                       printImportStatements(allImportClasses);
                        // Write interface header
                        println("");
                        println("public interface " + intface + " {");
@@ -359,13 +361,16 @@ public class IoTCompiler {
                                DeclarationHandler decHandler = mapIntDeclHand.get(intface);
                                InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
                                // Pass in set of methods and get import classes
-                               Set<String> importClasses = getImportClasses(intMeth.getValue(), intDecl);
-                               printImportStatements(importClasses);
+                               List<String> methods = intDecl.getMethods();
+                               Set<String> importClasses = getImportClasses(methods, intDecl);
+                               List<String> stdImportClasses = getStandardJavaIntfaceImportClasses();
+                               List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
+                               printImportStatements(allImportClasses);
                                // Write interface header
                                println("");
                                println("public interface " + newIntface + " {\n");
                                // Write methods
-                               writeMethodJavaInterface(intMeth.getValue(), intDecl);
+                               writeMethodJavaInterface(methods, intDecl);
                                println("}");
                                pw.close();
                                System.out.println("IoTCompiler: Generated interface " + newIntface + ".java...");
@@ -382,7 +387,7 @@ public class IoTCompiler {
                Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
                for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
                        String newIntface = intMeth.getKey();
-                       int newObjectId = mapNewIntfaceObjId.get(newIntface);
+                       int newObjectId = getNewIntfaceObjectId(newIntface);
                        println("private final static int object" + newObjectId + "Id = " + 
                                newObjectId + ";\t//" + newIntface);
                        Set<String> methodIds = intMeth.getValue();
@@ -441,7 +446,7 @@ public class IoTCompiler {
                Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
                for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
                        String newIntface = intMeth.getKey();
-                       int newObjectId = mapNewIntfaceObjId.get(newIntface);
+                       int newObjectId = getNewIntfaceObjectId(newIntface);
                        println("set" + newObjectId + "Allowed = Arrays.asList(object" + newObjectId +"Permission);");
                }
        }
@@ -477,7 +482,7 @@ public class IoTCompiler {
                Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
                for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
                        String newIntface = intMeth.getKey();
-                       int newObjectId = mapNewIntfaceObjId.get(newIntface);
+                       int newObjectId = getNewIntfaceObjectId(newIntface);
                        println("if (!set" + newObjectId + "Allowed.contains(methodId)) {");
                        println("throw new Error(\"Callback object for " + intface + " is not allowed to access method: \" + methodId);");
                        println("}");
@@ -503,11 +508,13 @@ public class IoTCompiler {
                println(intface + "_CallbackSkeleton skel = (" + intface + "_CallbackSkeleton) listCallbackObj.get(objId);");
                println("if (skel != null) {");
                println("skel.invokeMethod(rmiObj);");
-               println("} else {");
+               print("}");
+               println(" else {");
                println("throw new Error(\"" + intface + ": Object with Id \" + objId + \" not found!\");");
                println("}");
                println("}");
-               println("} catch (Exception ex) {");
+               print("}");
+               println(" catch (Exception ex) {");
                println("ex.printStackTrace();");
                println("throw new Error(\"Error instantiating class " + intface + "_CallbackSkeleton!\");");
                println("}");
@@ -931,7 +938,8 @@ public class IoTCompiler {
                                        println("}");
                        }
                }
-               println("} catch (Exception ex) {");
+               print("}");
+               println(" catch (Exception ex) {");
                println("ex.printStackTrace();");
                println("throw new Error(\"Exception when generating skeleton objects!\");");
                println("}\n");
@@ -1637,7 +1645,8 @@ public class IoTCompiler {
                                println("rmiObj.sendReturnObj(retObj);");
                }
                if (isCallbackMethod) { // Catch exception if this is callback
-                       println("} catch(Exception ex) {");
+                       print("}");
+                       println(" catch(Exception ex) {");
                        println("ex.printStackTrace();");
                        println("throw new Error(\"Exception from callback object instantiation!\");");
                        println("}");
@@ -1979,7 +1988,7 @@ public class IoTCompiler {
                Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
                for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
                        String newIntface = intMeth.getKey();
-                       int newObjectId = mapNewIntfaceObjId.get(newIntface);
+                       int newObjectId = getNewIntfaceObjectId(newIntface);
                        println("if (_objectId == object" + newObjectId + "Id) {");
                        println("if (!set" + newObjectId + "Allowed.contains(methodId)) {");
                        println("throw new Error(\"Object with object Id: \" + _objectId + \"  is not allowed to access method: \" + methodId);");
@@ -2494,6 +2503,9 @@ public class IoTCompiler {
 
                        List<String> methParams = intDecl.getMethodParams(method);
                        List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
+
+                       //System.out.println("\n\nMethod return type: " + checkAndGetCplusType(intDecl.getMethodType(method)) + "\n\n");
+
                        print(checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
                                intDecl.getMethodId(method) + "(");
                        boolean isCallbackMethod = false;
@@ -2560,8 +2572,9 @@ public class IoTCompiler {
                println("int numParam = " + methParams.size() + ";");
                println("int methodId = " + intDecl.getMethodNumId(method) + ";");
                String retType = intDecl.getMethodType(method);
-               String retTypeC = checkAndGetCplusType(retType);
-               println("string retType = \"" + checkAndGetCplusArrayType(retTypeC) + "\";");
+               //String retTypeC = checkAndGetCplusType(retType);
+               //println("string retType = \"" + checkAndGetCplusArrayType(getStructType(getEnumType(retTypeC))) + "\";");
+               println("string retType = \"" + checkAndGetCplusRetClsType(getStructType(getEnumType(retType))) + "\";");
                // Generate array of parameter types
                print("string paramCls[] = { ");
                for (int i = 0; i < methParams.size(); i++) {
@@ -2569,8 +2582,10 @@ public class IoTCompiler {
                        if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
                                print("\"int\"");
                        } else { // Generate normal classes if it's not a callback object
-                               String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
-                               String prmType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
+                               //String paramTypeC = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
+                               //String prmType = getSimpleType(getEnumType(paramTypeC));
+                               String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
+                               String prmType = getEnumType(paramTypeC);
                                print("\"" + prmType + "\"");
                        }
                        if (i != methParams.size() - 1) // Check if this is the last element
@@ -2891,8 +2906,9 @@ public class IoTCompiler {
                checkAndWriteStructSetupCplusStub(methParams, methPrmTypes, intDecl, method);
                println("int methodId = " + intDecl.getMethodNumId(method) + ";");
                String retType = intDecl.getMethodType(method);
-               String retTypeC = checkAndGetCplusType(retType);
-               println("string retType = \"" + checkAndGetCplusArrayType(getStructType(getEnumType(retTypeC))) + "\";");
+               //String retTypeC = checkAndGetCplusType(retType);
+               //println("string retType = \"" + checkAndGetCplusArrayType(getStructType(getEnumType(retTypeC))) + "\";");
+               println("string retType = \"" + checkAndGetCplusRetClsType(getStructType(getEnumType(retType))) + "\";");
                // Generate array of parameter types
                if (isStructPresent(methParams, methPrmTypes)) {
                        writeStructParamClassCplusStub(methParams, methPrmTypes);
@@ -2900,9 +2916,11 @@ public class IoTCompiler {
                        println("int numParam = " + methParams.size() + ";");
                        print("string paramCls[] = { ");
                        for (int i = 0; i < methParams.size(); i++) {
-                               String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
-                               String paramType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
-                               print("\"" + getEnumType(paramType) + "\"");
+                               //String paramTypeC = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
+                               //String prmType = getSimpleType(getEnumType(paramTypeC));
+                               String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
+                               String prmType = getEnumType(paramTypeC);
+                               print("\"" + prmType + "\"");
                                // Check if this is the last element (don't print a comma)
                                if (i != methParams.size() - 1) {
                                        print(", ");
@@ -2934,10 +2952,12 @@ public class IoTCompiler {
                                if (getParamCategory(retType) == ParamCategory.ENUM) {
                                        checkAndWriteEnumRetTypeCplusStub(retType);
                                } else {
-                                       if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
+                                       //if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
+                                       if (isArrayOrList(retType,retType))
                                                println(checkAndGetCplusType(retType) + " retVal;");
-                                       else
+                                       else {
                                                println(checkAndGetCplusType(retType) + " retVal = " + generateCplusInitializer(retType) + ";");
+                                       }
                                        println("void* retObj = &retVal;");
                                        println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
                                        println("return retVal;");
@@ -2955,8 +2975,8 @@ public class IoTCompiler {
                Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
                for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
                        String newIntface = intMeth.getKey();
-                       int newObjectId = mapNewIntfaceObjId.get(newIntface);
-                       println("const static int object" + newObjectId + "Id = " + newObjectId + ";");
+                       int newObjectId = getNewIntfaceObjectId(newIntface);
+                       println("const static int object" + newObjectId + "Id = " + newObjectId + ";\t//" + newIntface);
                        println("const static set<int> set" + newObjectId + "Allowed;");
                }
        }       
@@ -3001,7 +3021,6 @@ public class IoTCompiler {
                println("ports = _ports;");
                println("rmiCall = new IoTRMICall(_port, _address, _rev, _bResult);");
                if (callbackExist) {
-                       println("objIdCnt = 0;");
                        Iterator it = callbackClasses.iterator();
                        String callbackType = (String) it.next();
                        println("thread th1 (&" + newStubClass + "::___initCallBack, this);");
@@ -3050,7 +3069,7 @@ public class IoTCompiler {
                Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
                for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
                        String newIntface = intMeth.getKey();
-                       int newObjectId = mapNewIntfaceObjId.get(newIntface);
+                       int newObjectId = getNewIntfaceObjectId(newIntface);
                        println("if (set" + newObjectId + "Allowed.find(methodId) == set" + newObjectId + "Allowed.end()) {");
                        println("cerr << \"Callback object for " + intface + " is not allowed to access method: \" << methodId;");
                        println("exit(-1);");
@@ -3075,7 +3094,8 @@ public class IoTCompiler {
                println(intface + "_CallbackSkeleton* skel = dynamic_cast<" + intface + 
                        "_CallbackSkeleton*> (vecCallbackObj.at(objId));");
                println("skel->invokeMethod(rmiObj);");
-               println("} else {");
+               print("}");
+               println(" else {");
                println("cerr << \"Illegal object Id: \" << to_string(objId);");
                // TODO: perhaps need to change this into "throw" to make it cleaner (allow stack unfolding)
                println("exit(-1);");
@@ -3148,6 +3168,7 @@ public class IoTCompiler {
                                print("}"); println(";");
                                if (callbackExist)
                                        writePermissionInitializationCplus(intface, newStubClass, intDecl);
+                               writeObjectIdCountInitializationCplus(newStubClass, callbackExist);
                                println("#endif");
                                pw.close();
                                System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".hpp...");
@@ -3163,7 +3184,7 @@ public class IoTCompiler {
 
                println("IoTRMICall *rmiCall;");
                // Get the object Id
-               println("static int objectId;");
+               println("int objectId;");
                if (callbackExist) {
                // We assume that each class only has one callback interface for now
                        Iterator it = callbackClasses.iterator();
@@ -3243,6 +3264,7 @@ public class IoTCompiler {
                                println("};");
                                if (callbackExist)
                                        writePermissionInitializationCplus(intface, newStubClass, intDecl);
+                               writeObjectIdCountInitializationCplus(newStubClass, callbackExist);
                                println("#endif");
                                pw.close();
                                System.out.println("IoTCompiler: Generated callback stub class " + newIntface + ".hpp...");
@@ -3274,6 +3296,16 @@ public class IoTCompiler {
        }
 
 
+       /**
+        * HELPER: writeObjectIdCountInitializationCplus() writes the initialization of objIdCnt variable
+        */
+       private void writeObjectIdCountInitializationCplus(String newSkelClass, boolean callbackExist) {
+
+               if (callbackExist)
+                       println("int " + newSkelClass + "::objIdCnt = 0;");
+       }
+
+
        /**
         * HELPER: writePermissionInitializationCplus() writes the initialization of permission set
         */
@@ -3283,7 +3315,7 @@ public class IoTCompiler {
                Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
                for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
                        String newIntface = intMeth.getKey();
-                       int newObjectId = mapNewIntfaceObjId.get(newIntface);
+                       int newObjectId = getNewIntfaceObjectId(newIntface);
                        print("const set<int> " + newSkelClass + "::set" + newObjectId + "Allowed {");
                        Set<String> methodIds = intMeth.getValue();
                        int i = 0;
@@ -3310,11 +3342,6 @@ public class IoTCompiler {
                println("bool _bResult = false;");
                println("mainObj = _mainObj;");
                println("rmiObj = new IoTRMIObject(_port, &_bResult);");
-               // Callback
-               if (callbackExist) {
-                       println("objIdCnt = 0;");
-               }
-               //println("set0Allowed = Arrays.asList(object0Permission);");
                println("___waitRequestInvokeMethod();");
                println("}\n");
        }
@@ -3384,7 +3411,9 @@ public class IoTCompiler {
                println("int param1 = 0;");
                println("string param2 = \"\";");
                println("int param3 = 0;");
+               println("string paramCls[] = { \"int\", \"string\", \"int\" };");
                println("void* paramObj[] = { &param1, &param2, &param3 };");
+               println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
                println("bool bResult = false;");
                println("rmiCall = new IoTRMICall(param1, param2.c_str(), param3, &bResult);");
                println("}\n");
@@ -3596,7 +3625,7 @@ public class IoTCompiler {
                        if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type
                                println("rmiObj->sendReturnObj(retObj, retCls, numRetObj);");
                        else
-                               println("rmiObj->sendReturnObj(retObj, \"" + getEnumType(checkAndGetCplusArrayType(retTypeC)) + "\");");
+                               println("rmiObj->sendReturnObj(retObj, \"" + checkAndGetCplusRetClsType(getEnumType(retType)) + "\");");
                }
        }
 
@@ -3618,9 +3647,11 @@ public class IoTCompiler {
                                callbackType = paramType;
                                print("\"int\"");
                        } else {        // Generate normal classes if it's not a callback object
-                               String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
-                               String prmType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
-                               print("\"" + getEnumType(prmType) + "\"");
+                               //String paramTypeC = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
+                               //String prmType = getSimpleType(getEnumType(paramTypeC));
+                               String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
+                               String prmType = getEnumType(paramTypeC);
+                               print("\"" + prmType + "\"");
                        }
                        if (i != methParams.size() - 1) {
                                print(", ");
@@ -3639,7 +3670,6 @@ public class IoTCompiler {
                                        println("vector<int> paramEnumInt" + i + ";");
                                } else {
                                        String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
-                                       //println(methParamComplete + " = " + generateCplusInitializer(methPrmType) + ";");
                     println(methParamComplete + ";");
                                }
                        }
@@ -3990,7 +4020,7 @@ public class IoTCompiler {
                Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
                for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
                        String newIntface = intMeth.getKey();
-                       int newObjectId = mapNewIntfaceObjId.get(newIntface);
+                       int newObjectId = getNewIntfaceObjectId(newIntface);
                        println("if (_objectId == object" + newObjectId + "Id) {");
                        println("if (set" + newObjectId + "Allowed.find(methodId) == set" + newObjectId + "Allowed.end()) {");
                        println("cerr << \"Object with object Id: \" << _objectId << \"  is not allowed to access method: \" << methodId << endl;");
@@ -4099,6 +4129,7 @@ public class IoTCompiler {
                        writeCplusWaitRequestInvokeMethod(methods, intDecl, callbackExist, intface);
                        println("};");
                        writePermissionInitializationCplus(intface, newSkelClass, intDecl);
+                       writeObjectIdCountInitializationCplus(newSkelClass, callbackExist);
                        println("#endif");
                        pw.close();
                        System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".hpp...");
@@ -4113,7 +4144,7 @@ public class IoTCompiler {
 
                println(intface + " *mainObj;");
                // Keep track of object Ids of all stubs registered to this interface
-               println("static int objectId;");
+               println("int objectId;");
                // Callback
                if (callbackExist) {
                        Iterator it = callbackClasses.iterator();
@@ -4136,10 +4167,6 @@ public class IoTCompiler {
                println(newSkelClass + "(" + intface + " *_mainObj, int _objectId) {");
                println("mainObj = _mainObj;");
                println("objectId = _objectId;");
-               // Callback
-               if (callbackExist) {
-                       println("objIdCnt = 0;");
-               }
                println("}\n");
        }
 
@@ -4321,6 +4348,7 @@ public class IoTCompiler {
                        // Write waitRequestInvokeMethod() - main loop
                        writeCplusCallbackWaitRequestInvokeMethod(methods, intDecl, callbackExist);
                        println("};");
+                       writeObjectIdCountInitializationCplus(newSkelClass, callbackExist);
                        println("#endif");
                        pw.close();
                        System.out.println("IoTCompiler: Generated callback skeleton class " + newSkelClass + ".hpp...");
@@ -4403,7 +4431,7 @@ public class IoTCompiler {
                        pn = (ParseNode) parse.parse().value;
                } catch (Exception e) {
                        e.printStackTrace();
-                       throw new Error("IoTCompiler: ERROR parsing policy file or wrong command line option: " + file);
+                       throw new Error("IoTCompiler: ERROR parsing policy file or wrong command line option: " + file + "\n");
                }
 
                return pn;
@@ -4513,6 +4541,21 @@ public class IoTCompiler {
        }
 
 
+       // Check and find object Id for new interface in mapNewIntfaceObjId (callbacks)
+       // Throw an error if the new interface is not found!
+       // Basically the compiler needs to parse the policy (and requires) files for callback class first
+       private int getNewIntfaceObjectId(String newIntface) {
+
+               if (!mapNewIntfaceObjId.containsKey(newIntface)) {
+                       throw new Error("IoTCompiler: Need to parse policy and requires files for callback class first! " +
+                                                       "Please place the two files for callback class in front...\n");
+               } else {
+                       int retObjId = mapNewIntfaceObjId.get(newIntface);
+                       return retObjId;
+               }
+       }
+
+
        // Return parameter category, i.e. PRIMITIVES, NONPRIMITIVES, USERDEFINED, ENUM, or STRUCT
        private ParamCategory getParamCategory(String paramType) {
 
@@ -4559,6 +4602,18 @@ public class IoTCompiler {
        }
 
 
+       // Generate a set of standard classes for import statements
+       private List<String> getStandardJavaIntfaceImportClasses() {
+
+               List<String> importClasses = new ArrayList<String>();
+               // Add the standard list first
+               importClasses.add("java.util.List");
+               importClasses.add("java.util.ArrayList");
+
+               return importClasses;
+       }
+
+
        // Generate a set of standard classes for import statements
        private List<String> getStandardJavaImportClasses() {
 
@@ -4898,7 +4953,7 @@ public class IoTCompiler {
                        } else
                                return getNonPrimitiveCplusClass(paramType);
                } else if(paramType.contains("[]")) {   // Array type (used for return type only)
-                       String cArray = "vector<" + getSimpleArrayType(paramType) + ">";
+                       String cArray = "vector<" + convertType(getSimpleArrayType(paramType)) + ">";
                        return cArray;
                } else if(getParamCategory(paramType) == ParamCategory.USERDEFINED) {
                        return paramType + "*";
@@ -4966,6 +5021,47 @@ public class IoTCompiler {
        }
 
 
+       // Return the class type for class resolution (for return value)
+       // - Check and return C++ array class, e.g. int A[] into int*
+       // - Check and return C++ vector class, e.g. List<Integer> A into vector<int>
+       private String checkAndGetCplusRetClsType(String paramType) {
+
+               String paramTypeRet = null;
+               // Check for array declaration
+               if (paramType.contains("[]")) {
+                       String type = paramType.split("\\[\\]")[0];
+                       paramTypeRet = getSimpleArrayType(type) + "*";
+               } else if (paramType.contains("<") && paramType.contains(">")) {
+                       // Just return it as is if it's not an array
+                       String type = paramType.split("<")[1].split(">")[0];
+                       paramTypeRet = "vector<" + getGenericType(type) + ">";
+               } else
+                       paramTypeRet = paramType;
+
+               return paramTypeRet;
+       }
+
+
+       // Return the class type for class resolution (for method arguments)
+       // - Check and return C++ array class, e.g. int A[] into int*
+       // - Check and return C++ vector class, e.g. List<Integer> A into vector<int>
+       private String checkAndGetCplusArgClsType(String paramType, String param) {
+
+               String paramTypeRet = null;
+               // Check for array declaration
+               if (param.contains("[]")) {
+                       paramTypeRet = getSimpleArrayType(paramType) + "*";
+               } else if (paramType.contains("<") && paramType.contains(">")) {
+                       // Just return it as is if it's not an array
+                       String type = paramType.split("<")[1].split(">")[0];
+                       paramTypeRet = "vector<" + getGenericType(type) + ">";
+               } else
+                       paramTypeRet = paramType;
+
+               return paramTypeRet;
+       }
+
+
        // Detect array declaration, e.g. int A[],
        //              then generate type "int[]"
        private String checkAndGetArray(String paramType, String param) {
@@ -5047,7 +5143,7 @@ public class IoTCompiler {
                        } else {
                                throw new Error("IoTCompiler: Ambiguous stub interfaces: " + setExchInt.toString() + 
                                        ". Only one new interface can be declared if the object " + intface +
-                                       " needs to be passed in as an input parameter!");
+                                       " needs to be passed in as an input parameter!\n");
                        }
                } else {
                // NULL value - this means policy files missing
@@ -5056,7 +5152,7 @@ public class IoTCompiler {
                                " If this is an array please type the brackets after the variable name," +
                                " e.g. \"String str[]\", not \"String[] str\"." +
                                " If this is a Collections (Java) / STL (C++) type, this compiler only" +
-                               " supports List/ArrayList (Java) or list (C++).");
+                               " supports List/ArrayList (Java) or list (C++).\n");
                }
        }
 
@@ -5115,12 +5211,12 @@ public class IoTCompiler {
                                        // Error checking
                                        if (!args[i].equals("-java") &&
                                                !args[i].equals("-cplus")) {
-                                               throw new Error("IoTCompiler: ERROR - unrecognized command line option: " + args[i]);
+                                               throw new Error("IoTCompiler: ERROR - unrecognized command line option: " + args[i] + "\n");
                                        } else {
                                                if (i + 1 < args.length) {
                                                        comp.setDirectory(args[i+1]);
                                                } else
-                                                       throw new Error("IoTCompiler: ERROR - please provide <directory> after option: " + args[i]);
+                                                       throw new Error("IoTCompiler: ERROR - please provide <directory> after option: " + args[i] + "\n");
 
                                                if (args[i].equals("-java")) {
                                                        comp.generateEnumJava();
@@ -5148,7 +5244,7 @@ public class IoTCompiler {
                } else {
                // Need to at least have exactly 2 parameters, i.e. main policy file and requires file
                        IoTCompiler.printUsage();
-                       throw new Error("IoTCompiler: At least two arguments (main and requires policy files) have to be provided!");
+                       throw new Error("IoTCompiler: At least two arguments (main and requires policy files) have to be provided!\n");
                }
        }
 }