1 /*
   2  * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /* This code generate an LTTest.java and LTTest.c files with corresponding *.cfg files which containt test defenition
  25  * for JNI testing.
  26  *
  27  */
  28 import java.io.File;
  29 import java.io.FileWriter;
  30 import java.io.IOException;
  31 import java.util.ArrayList;
  32 import java.util.Arrays;
  33 import java.util.Random;
  34 
  35 //Java and C file generator for JNI tests
  36 public class JniArmHFTestGenerator {
  37 
  38     private final String JAVA_CLASS_NAME = "LTTest";
  39     private final String C_FNC_NAME_PREFIX = "Java_vm_jit_LongTransitions_" + JAVA_CLASS_NAME + "_";
  40     private final String JAVA_PACKAGE_NAME = "vm.jit.LongTransitions";
  41     private final String TEST_LIST_PREFIX = "vm/jit/LongTransitions";
  42     private final String TEST_LIST_NAME = "vm.jit.long.testlist";
  43     //Maximal line length for some SRC generation function
  44     private final int LINE_LENGTH = 70;
  45     //127 is maximal value for JAVA parameters list
  46     private final int PARAMS_COUNTER = 127;
  47     StringBuilder javaFileSrc;
  48     StringBuilder cFileSrc;
  49     //StringBuilder cfgFileSrc;
  50     private String javaTxtFileName;
  51     private String cTxtFileName;
  52     private File outputDir;
  53     private ArrayList<String> javaFncNames = new ArrayList<String>();
  54 
  55     public static void main(String[] args) throws IOException {
  56         new JniArmHFTestGenerator().makeSomeTest();
  57     }
  58 
  59     public void makeSomeTest() throws IOException {
  60 
  61         makeJavaIntro(JAVA_CLASS_NAME);
  62         makeCIntro();
  63         int cnt = PARAMS_COUNTER;
  64 
  65         makeOneTest(cnt, ParamType.EASY_F, TestType.RANDOM, "nativeFnc1");
  66         makeOneTest(cnt, ParamType.EASY_D, TestType.RANDOM, "nativeFnc2");
  67         makeOneTest(cnt, ParamType.MIXED_FI1, TestType.RANDOM, "nativeFnc3");
  68         makeOneTest(cnt, ParamType.MIXED_FB1, TestType.RANDOM, "nativeFnc4");
  69         makeOneTest(cnt, ParamType.MIXED_FBI1, TestType.RANDOM, "nativeFnc5");
  70         makeOneTest(cnt, ParamType.MIXED_DI1, TestType.RANDOM, "nativeFnc6");
  71         makeOneTest(cnt, ParamType.MIXED_DB1, TestType.RANDOM, "nativeFnc7");
  72         makeOneTest(cnt, ParamType.MIXED_DBI1, TestType.RANDOM, "nativeFnc8");
  73         makeOneTest(cnt, ParamType.MIXED_DFBI1, TestType.RANDOM, "nativeFnc9");
  74         makeOneTest(cnt, ParamType.MIXED_DF1, TestType.RANDOM, "nativeFnc10");
  75         makeOneTest(cnt, ParamType.MIXED_DFI1, TestType.RANDOM, "nativeFnc11");
  76         makeOneTest(cnt, ParamType.MIXED_DFB1, TestType.RANDOM, "nativeFnc12");
  77 
  78         makeOneTest(cnt, ParamType.MIXED_FI2, TestType.RANDOM, "nativeFnc13");
  79         makeOneTest(cnt, ParamType.MIXED_FB2, TestType.RANDOM, "nativeFnc14");
  80         makeOneTest(cnt, ParamType.MIXED_FBI2, TestType.RANDOM, "nativeFnc15");
  81         makeOneTest(cnt, ParamType.MIXED_DI2, TestType.RANDOM, "nativeFnc16");
  82         makeOneTest(cnt, ParamType.MIXED_DB2, TestType.RANDOM, "nativeFnc17");
  83         makeOneTest(cnt, ParamType.MIXED_DBI2, TestType.RANDOM, "nativeFnc18");
  84         makeOneTest(cnt, ParamType.MIXED_DFBI2, TestType.RANDOM, "nativeFnc19");
  85         makeOneTest(cnt, ParamType.MIXED_DF2, TestType.RANDOM, "nativeFnc20");
  86         makeOneTest(cnt, ParamType.MIXED_DFI2, TestType.RANDOM, "nativeFnc21");
  87         makeOneTest(cnt, ParamType.MIXED_DFB2, TestType.RANDOM, "nativeFnc22");
  88 
  89         makeOneTest(cnt, ParamType.MIXED_FI3, TestType.RANDOM, "nativeFnc23");
  90         makeOneTest(cnt, ParamType.MIXED_FB3, TestType.RANDOM, "nativeFnc24");
  91         makeOneTest(cnt, ParamType.MIXED_FBI3, TestType.RANDOM, "nativeFnc25");
  92         makeOneTest(cnt, ParamType.MIXED_DI3, TestType.RANDOM, "nativeFnc26");
  93         makeOneTest(cnt, ParamType.MIXED_DB3, TestType.RANDOM, "nativeFnc27");
  94         makeOneTest(cnt, ParamType.MIXED_DBI3, TestType.RANDOM, "nativeFnc28");
  95         makeOneTest(cnt, ParamType.MIXED_DFBI3, TestType.RANDOM, "nativeFnc29");
  96         makeOneTest(cnt, ParamType.MIXED_DF3, TestType.RANDOM, "nativeFnc30");
  97         makeOneTest(cnt, ParamType.MIXED_DFI3, TestType.RANDOM, "nativeFnc31");
  98         makeOneTest(cnt, ParamType.MIXED_DFB3, TestType.RANDOM, "nativeFnc32");
  99 
 100         makeOneTest(cnt, ParamType.MIXED_FI4, TestType.RANDOM, "nativeFnc33");
 101         makeOneTest(cnt, ParamType.MIXED_FB4, TestType.RANDOM, "nativeFnc34");
 102         makeOneTest(cnt, ParamType.MIXED_FBI4, TestType.RANDOM, "nativeFnc35");
 103         makeOneTest(cnt, ParamType.MIXED_DI4, TestType.RANDOM, "nativeFnc36");
 104         makeOneTest(cnt, ParamType.MIXED_DB4, TestType.RANDOM, "nativeFnc37");
 105         makeOneTest(cnt, ParamType.MIXED_DBI4, TestType.RANDOM, "nativeFnc38");
 106         makeOneTest(cnt, ParamType.MIXED_DFBI4, TestType.RANDOM, "nativeFnc39");
 107         makeOneTest(cnt, ParamType.MIXED_DF4, TestType.RANDOM, "nativeFnc40");
 108         makeOneTest(cnt, ParamType.MIXED_DFI4, TestType.RANDOM, "nativeFnc41");
 109         makeOneTest(cnt, ParamType.MIXED_DFB4, TestType.RANDOM, "nativeFnc42");
 110 
 111         makeOneTest(cnt, ParamType.MIXED_FI5, TestType.RANDOM, "nativeFnc43");
 112         makeOneTest(cnt, ParamType.MIXED_FB5, TestType.RANDOM, "nativeFnc44");
 113         makeOneTest(cnt, ParamType.MIXED_FBI5, TestType.RANDOM, "nativeFnc45");
 114         makeOneTest(cnt, ParamType.MIXED_DI5, TestType.RANDOM, "nativeFnc46");
 115         makeOneTest(cnt, ParamType.MIXED_DB5, TestType.RANDOM, "nativeFnc47");
 116         makeOneTest(cnt, ParamType.MIXED_DBI5, TestType.RANDOM, "nativeFnc48");
 117         makeOneTest(cnt, ParamType.MIXED_DFBI5, TestType.RANDOM, "nativeFnc49");
 118         makeOneTest(cnt, ParamType.MIXED_DF5, TestType.RANDOM, "nativeFnc50");
 119         makeOneTest(cnt, ParamType.MIXED_DFI5, TestType.RANDOM, "nativeFnc51");
 120         makeOneTest(cnt, ParamType.MIXED_DFB5, TestType.RANDOM, "nativeFnc52");
 121         makeJavaInvoke();
 122         makeJavaOutro();
 123 
 124         writeToJavaFile(JAVA_CLASS_NAME);
 125         writeToCFile(JAVA_CLASS_NAME);
 126         //writeCmpFile();
 127 
 128         writeTestListFile();
 129         writeCfgFile();
 130     }
 131 
 132     private void makeJavaInvoke() {
 133         appendToJava("    public static void main(String[] args) throws Exception");
 134         appendToJava("    {");
 135         appendToJava("        if ( System.getProperty(\"os.name\").matches(\".*[Ww][Ii][Nn].*\") )");
 136         appendToJava("        {");
 137         appendToJava("            System.out.println(\"TEST PASSED! Dummy execution on Windows* OS!\");");
 138         appendToJava("            return;");
 139         appendToJava("        }");
 140 
 141         appendToJava("        deleteFiles();");
 142         appendToJavaN("        PrintStream ps=new PrintStream(new File(\"");
 143         appendToJavaN(javaTxtFileName);
 144         appendToJava("\"));");
 145 
 146         appendToJava("    if (args.length>0)");
 147         appendToJava("        switch(args[0])");
 148         appendToJava("        {");
 149 
 150         for (String s : javaFncNames) {
 151             appendToJava("        case \"" + s + "\":");
 152             appendToJavaN("            ");
 153             appendToJavaN(s);
 154             appendToJava("_invoke(ps);");
 155             appendToJava("            break;");
 156 
 157         }
 158         appendToJava("        default:");
 159         appendToJava("            throw new Exception(\"FAIL: invalid args!\");");
 160         appendToJava("        }");
 161         appendToJava("        else");
 162         appendToJava("        {");
 163         appendToJava("            throw new Exception(\"FAIL: invalid args!\");");
 164         appendToJava("        }");
 165 
 166 
 167     }
 168 
 169     private void makeCIntro() {
 170         //appendToC(" //------------------------C----------------------------");
 171         //appendToC("#include \""+className+".h\"");
 172         appendToC("#include <jni.h>");
 173         appendToC("#include <stdio.h>");
 174     }
 175 
 176     private void makeJavaIntro(String className) {
 177 
 178         cFileSrc = new StringBuilder();
 179         javaFileSrc = new StringBuilder();
 180 
 181 
 182         File outputDirL1 = new File("vm" + File.separatorChar + "jit" + File.separatorChar + "LongTransitions");
 183         //outputDir=new File(outputDirL1,className);
 184         outputDir = outputDirL1;
 185         outputDir.mkdirs();
 186 
 187         javaTxtFileName = className + "_java.txt";
 188         cTxtFileName = className + "_c.txt";
 189 
 190         appendToJava("package " + JAVA_PACKAGE_NAME + ";");
 191         appendToJava("import java.io.*;");
 192         appendToJava("import java.util.Random;");
 193         appendToJava("public class " + className);
 194         appendToJava("{");
 195         appendToJava("    public static boolean flag = false;");
 196         appendToJava("    static Random rnd;");
 197         appendToJava("    static{");
 198         appendToJava("        rnd=new Random();");
 199         appendToJava("        System.loadLibrary(\"" + className + "\");");
 200         appendToJava("    }");
 201         //Different randoms
 202         appendToJava("    public static int getRndInt(){return rnd.nextInt(Integer.MAX_VALUE);}");
 203         appendToJava("    public static float getRndFloat(){return rnd.nextFloat()*Float.MAX_VALUE;}");
 204         appendToJava("    public static double getRndDouble(){return rnd.nextDouble()*Double.MAX_VALUE;}");
 205         appendToJava("    public static byte getRndByte(){return (byte)rnd.nextInt(Byte.MAX_VALUE);}");
 206 
 207         //deleteFiles method
 208         appendToJava("    private static void deleteFiles()");
 209         appendToJava("    {");
 210         appendToJavaN("        File f=new File(\"");
 211         appendToJavaN(javaTxtFileName);
 212         appendToJava("\");");
 213         appendToJava("        if ( f.exists())");
 214         appendToJava("        f.delete();");
 215         appendToJavaN("        f=new File(\"");
 216         appendToJavaN(cTxtFileName);
 217         appendToJava("\");");
 218         appendToJava("        if ( f.exists())");
 219         appendToJava("         f.delete();");
 220         appendToJava("    }");
 221     }
 222 
 223     private void makeJavaOutro() {
 224         appendToJava("        flag=chkFile();");
 225         appendToJava("        if(!flag)");
 226         appendToJava("            throw new Exception(\"FAIL:Tests failed!\"); ");
 227         appendToJava("    }");
 228         appendToJava("    private static boolean chkFile()");
 229         appendToJava("    {");
 230         appendToJava("        File javaFile=new File(\"" + javaTxtFileName + "\");");
 231         appendToJava("        if (! javaFile.exists())");
 232         appendToJava("        {");
 233         appendToJava("            System.out.println(\"FAIL:Failed to open file " + javaTxtFileName + " - file not exists!\");");
 234         appendToJava("            return false;");
 235         appendToJava("        }");
 236         appendToJava("        File cFile=new File(\"" + cTxtFileName + "\");");
 237         appendToJava("        if (! cFile.exists())");
 238         appendToJava("        {");
 239         appendToJava("                System.out.println(\"FAIL:Failed to open file " + cTxtFileName + " - file not exists!\");");
 240         appendToJava("                return false;");
 241         appendToJava("        }");
 242         appendToJava("        if ( cFile.length()!=javaFile.length() )");
 243         appendToJava("        {");
 244         appendToJava("            System.out.println(\"FAIL:File length not equal!\");");
 245         appendToJava("            return false;");
 246         appendToJava("        }");
 247         appendToJava("        long byteCount=cFile.length();");
 248 
 249 
 250         appendToJava("        try{");
 251         appendToJava("            FileInputStream fisC=new FileInputStream(cFile);");
 252         appendToJava("            FileInputStream fisJava=new FileInputStream(javaFile);");
 253         appendToJava("            byte[] cData=new byte[fisC.available()];");
 254         appendToJava("            fisC.read(cData);");
 255         appendToJava("            byte[] javaData=new byte[fisJava.available()];");
 256         appendToJava("            fisJava.read(javaData);");
 257 
 258         appendToJava("            for ( int cnt=0;cnt<byteCount;++cnt)");
 259         appendToJava("            {");
 260         appendToJava("                if ( cData[cnt]!=javaData[cnt] )");
 261         appendToJava("                {");
 262         appendToJava("                    System.out.println(\"FAIL:Test failed! \"+cnt+\" byte are wrong! C file - \" + cData[cnt] + \" Java file - \"+javaData[cnt] );");
 263         appendToJava("                    return false;");
 264         appendToJava("                }");
 265         appendToJava("            }");
 266         appendToJava("        }");
 267         appendToJava("        catch (FileNotFoundException ex)");
 268         appendToJava("        {");
 269         appendToJava("            System.out.println(\"FAIL:Some of files not found!\");");
 270         appendToJava("            return false;");
 271         appendToJava("        }");
 272         appendToJava("        catch (IOException ex)");
 273         appendToJava("        {");
 274         appendToJava("            System.out.println(\"FAIL:Failed to read files!\");");
 275         appendToJava("            return false;");
 276         appendToJava("        }");
 277         appendToJava("        System.out.println(\"PASS: all data passed correctly!\");");
 278         appendToJava("        return true;");
 279 
 280 
 281 
 282         appendToJava("    }");
 283 
 284         appendToJava("}");
 285 
 286 
 287     }
 288 
 289     private void makeOneTest(int paramCounter, ParamType paramType, TestType testType, String fncName) throws IOException {
 290 
 291         javaFncNames.add(fncName);
 292         SrcGenerator gen = new SrcGenerator(paramCounter, 1, paramType, testType, fncName, LINE_LENGTH);
 293         generateJava(gen);
 294         generateCpp(gen);
 295 
 296 
 297     }
 298 
 299     /*
 300      * Create Java file containing code to call C native method. Method
 301      * arguments list generated randomly.
 302      *
 303      */
 304     private void generateJava(SrcGenerator srcGen) throws IOException {
 305 
 306         //native method
 307         appendToJavaN("    native public static void " + srcGen.getFncName() + "(");
 308         //appendToJavaN(srcGen.getJParm().toString());
 309         appendToJavaN(srcGen.getJParm().toFormatString("        ", LINE_LENGTH));
 310         appendToJava("    );");
 311         //main
 312         //appendToJava(srcGen.getJExecVarCreation());
 313         appendToJava("    private static void " + srcGen.getFncName() + "_invoke(PrintStream ps)");
 314         appendToJava(srcGen.getJExec("        "));
 315     }
 316 
 317     private void writeToJavaFile(String className) throws IOException {
 318 
 319         File javaFile = new File(outputDir, className + ".java");
 320         try (FileWriter javaFileWriter = new FileWriter(javaFile)) {
 321             javaFileWriter.write(javaFileSrc.toString());
 322         }
 323     }
 324 
 325     private void writeToCFile(String className) throws IOException {
 326 
 327         File cFile = new File(outputDir, className + ".c");
 328         try (FileWriter cFileWriter = new FileWriter(cFile)) {
 329             cFileWriter.write(cFileSrc.toString());
 330         }
 331     }
 332 
 333     private void writeTestListFile() {
 334 
 335         StringBuilder cfg = new StringBuilder();
 336 
 337         for (String fncName : javaFncNames) {
 338             cfg.append(TEST_LIST_PREFIX).append("/").append(fncName);
 339             cfg.append(" ").append("execute_positive\n");
 340         }
 341 
 342         File cfgFile = new File(outputDir, TEST_LIST_NAME);
 343         try (FileWriter fw = new FileWriter(cfgFile)) {
 344             fw.write(cfg.toString());
 345         } catch (Exception e) {
 346         }
 347 
 348     }
 349 
 350     private void writeCfgFile() {
 351 
 352         for (String fncName : javaFncNames) {
 353 
 354             StringBuilder cfg = new StringBuilder();
 355 
 356             cfg.append("LD_LIBRARY_PATH=${COMMON_LIBS_LOCATION}/lib/${ARCH}/vm/jit/LongTransitions${PS}$LD_LIBRARY_PATH\n");
 357             cfg.append("export LD_LIBRARY_PATH\n");
 358             cfg.append("JAVA_OPTS=${JAVA_OPTS} ${JIT_OPTS}\n");
 359             cfg.append("export JAVA_OPTS\n");
 360             cfg.append("EXECUTE_CLASS=" + JAVA_PACKAGE_NAME + "." + JAVA_CLASS_NAME + "\n");
 361             cfg.append("TEST_ARGS=" + fncName);
 362 
 363             File tdir = new File(outputDir, fncName);
 364             tdir.mkdirs();
 365             File cfgFile = new File(tdir, fncName + ".cfg");
 366             try (FileWriter fw = new FileWriter(cfgFile)) {
 367                 fw.write(cfg.toString());
 368             } catch (Exception e) {
 369             }
 370         }
 371     }
 372 
 373     /*
 374      * Generate C file. This file containing instructions to put passed
 375      * arguments into output file for further comparsion with java output *
 376      */
 377     private void generateCpp(SrcGenerator srcGen) throws IOException {
 378 
 379         appendToC("JNIEXPORT void JNICALL " + C_FNC_NAME_PREFIX + srcGen.getFncName() + "(JNIEnv *e, jclass c");
 380         appendToCN(srcGen.getCParm().toFormatString("    ", LINE_LENGTH));
 381         appendToCN(")");
 382         appendToC("\n{");
 383 
 384         appendToCN("    FILE *file=fopen(\"");
 385         appendToCN(cTxtFileName);
 386         appendToCN("\",\"a\");");
 387 
 388         appendToC(srcGen.getCExec(LINE_LENGTH,"    "));
 389         appendToC("    fclose(file);");
 390         appendToC("}");
 391     }
 392 
 393     private void appendToJava(String s) {
 394         javaFileSrc.append(s);
 395         javaFileSrc.append("\n");
 396         System.out.println(s);
 397     }
 398 
 399     private void appendToJavaN(String s) {
 400         javaFileSrc.append(s);
 401         System.out.print(s);
 402     }
 403 
 404     private void appendToC(String s) {
 405         cFileSrc.append(s);
 406         cFileSrc.append("\n");
 407         System.out.println(s);
 408     }
 409 
 410     private void appendToCN(String s) {
 411         cFileSrc.append(s);
 412         System.out.print(s);
 413 
 414     }
 415 }
 416 
 417 enum NumberType {
 418 
 419     INT("int ", "getRndInt()", "jint ", "%d", "%d"),
 420     DOUBLE("double ", "getRndDouble()", "jdouble ", "%e", "%e"),
 421     FLOAT("float ", "getRndFloat()", "jfloat ", "%e", "%e"),
 422     BYTE("byte ", "getRndByte()", "jbyte ", "%d", "%d");
 423     private String cType;
 424     private String jType;
 425     private String cConv;
 426     private String jConv;
 427     private String rndFnc;
 428 
 429     NumberType(String jType, String rndFnc, String cType, String jConv, String cConv) {
 430         this.cType = cType;
 431         this.jType = jType;
 432         this.cConv = cConv;
 433         this.jConv = jConv;
 434         this.rndFnc = rndFnc;
 435     }
 436 
 437     public String getСType() {
 438         return cType;
 439     }
 440 
 441     public String getJType() {
 442         return jType;
 443     }
 444 
 445     public String getСConv() {
 446         return cConv;
 447     }
 448 
 449     public String getJConv() {
 450         return jConv;
 451     }
 452 
 453     public String getFnc() {
 454         return rndFnc;
 455     }
 456 }
 457 
 458 //Types for testing
 459 enum ParamType {
 460     //DFBI
 461 
 462     MIXED_DFBI1(NumberType.DOUBLE, NumberType.FLOAT, NumberType.BYTE, NumberType.INT),
 463     MIXED_DFBI2(NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.BYTE, NumberType.INT),
 464     MIXED_DFBI3(NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.BYTE, NumberType.INT),
 465     MIXED_DFBI4(NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.BYTE, NumberType.INT),
 466     MIXED_DFBI5(NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.BYTE, NumberType.INT),
 467     //DFB
 468     MIXED_DFB1(NumberType.DOUBLE, NumberType.FLOAT, NumberType.BYTE),
 469     MIXED_DFB2(NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.BYTE),
 470     MIXED_DFB3(NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.BYTE),
 471     MIXED_DFB4(NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.BYTE),
 472     MIXED_DFB5(NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.BYTE),
 473     //DFI
 474     MIXED_DFI1(NumberType.DOUBLE, NumberType.FLOAT, NumberType.INT),
 475     MIXED_DFI2(NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.INT),
 476     MIXED_DFI3(NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.INT),
 477     MIXED_DFI4(NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.INT),
 478     MIXED_DFI5(NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.DOUBLE, NumberType.FLOAT, NumberType.INT),
 479     //
 480     MIXED_DF1(NumberType.DOUBLE, NumberType.FLOAT),
 481     MIXED_DF2(NumberType.DOUBLE, NumberType.FLOAT, NumberType.FLOAT),
 482     MIXED_DF3(NumberType.DOUBLE, NumberType.FLOAT, NumberType.FLOAT, NumberType.FLOAT),
 483     MIXED_DF4(NumberType.DOUBLE, NumberType.DOUBLE, NumberType.FLOAT),
 484     MIXED_DF5(NumberType.DOUBLE, NumberType.DOUBLE, NumberType.DOUBLE, NumberType.FLOAT),
 485     //
 486     EASY_D(NumberType.DOUBLE),
 487     EASY_F(NumberType.FLOAT),
 488     //Not needed
 489     EASY_I(NumberType.INT),
 490     EASY_B(NumberType.BYTE),
 491     MIXED_IB(NumberType.INT, NumberType.BYTE),
 492     //
 493     MIXED_FBI1(NumberType.FLOAT, NumberType.BYTE, NumberType.INT),
 494     MIXED_FBI2(NumberType.FLOAT, NumberType.FLOAT, NumberType.BYTE, NumberType.INT),
 495     MIXED_FBI3(NumberType.FLOAT, NumberType.FLOAT, NumberType.FLOAT, NumberType.BYTE, NumberType.INT),
 496     MIXED_FBI4(NumberType.FLOAT, NumberType.FLOAT, NumberType.FLOAT, NumberType.FLOAT, NumberType.BYTE, NumberType.INT),
 497     MIXED_FBI5(NumberType.FLOAT, NumberType.FLOAT, NumberType.FLOAT, NumberType.FLOAT, NumberType.FLOAT, NumberType.BYTE, NumberType.INT),
 498     //
 499     MIXED_FB1(NumberType.FLOAT, NumberType.BYTE),
 500     MIXED_FB2(NumberType.FLOAT, NumberType.FLOAT, NumberType.BYTE),
 501     MIXED_FB3(NumberType.FLOAT, NumberType.FLOAT, NumberType.FLOAT, NumberType.BYTE),
 502     MIXED_FB4(NumberType.FLOAT, NumberType.FLOAT, NumberType.FLOAT, NumberType.FLOAT, NumberType.BYTE),
 503     MIXED_FB5(NumberType.FLOAT, NumberType.FLOAT, NumberType.FLOAT, NumberType.FLOAT, NumberType.FLOAT, NumberType.BYTE),
 504     //
 505     MIXED_DBI1(NumberType.DOUBLE, NumberType.BYTE, NumberType.INT),
 506     MIXED_DBI2(NumberType.DOUBLE, NumberType.DOUBLE, NumberType.BYTE, NumberType.INT),
 507     MIXED_DBI3(NumberType.DOUBLE, NumberType.DOUBLE, NumberType.DOUBLE, NumberType.BYTE, NumberType.INT),
 508     MIXED_DBI4(NumberType.DOUBLE, NumberType.DOUBLE, NumberType.DOUBLE, NumberType.DOUBLE, NumberType.BYTE, NumberType.INT),
 509     MIXED_DBI5(NumberType.DOUBLE, NumberType.DOUBLE, NumberType.DOUBLE, NumberType.DOUBLE, NumberType.DOUBLE, NumberType.BYTE, NumberType.INT),
 510     //
 511     MIXED_DB1(NumberType.DOUBLE, NumberType.BYTE),
 512     MIXED_DB2(NumberType.DOUBLE, NumberType.DOUBLE, NumberType.BYTE),
 513     MIXED_DB3(NumberType.DOUBLE, NumberType.DOUBLE, NumberType.DOUBLE, NumberType.BYTE),
 514     MIXED_DB4(NumberType.DOUBLE, NumberType.DOUBLE, NumberType.DOUBLE, NumberType.DOUBLE, NumberType.BYTE),
 515     MIXED_DB5(NumberType.DOUBLE, NumberType.DOUBLE, NumberType.DOUBLE, NumberType.DOUBLE, NumberType.DOUBLE, NumberType.BYTE),
 516     //
 517     MIXED_FI1(NumberType.FLOAT, NumberType.INT),
 518     MIXED_FI2(NumberType.FLOAT, NumberType.FLOAT, NumberType.INT),
 519     MIXED_FI3(NumberType.FLOAT, NumberType.FLOAT, NumberType.FLOAT, NumberType.INT),
 520     MIXED_FI4(NumberType.FLOAT, NumberType.FLOAT, NumberType.FLOAT, NumberType.FLOAT, NumberType.INT),
 521     MIXED_FI5(NumberType.FLOAT, NumberType.FLOAT, NumberType.FLOAT, NumberType.FLOAT, NumberType.FLOAT, NumberType.INT),
 522     //
 523     MIXED_DI1(NumberType.DOUBLE, NumberType.INT),
 524     MIXED_DI2(NumberType.DOUBLE, NumberType.DOUBLE, NumberType.INT),
 525     MIXED_DI3(NumberType.DOUBLE, NumberType.DOUBLE, NumberType.DOUBLE, NumberType.INT),
 526     MIXED_DI4(NumberType.DOUBLE, NumberType.DOUBLE, NumberType.DOUBLE, NumberType.DOUBLE, NumberType.INT),
 527     MIXED_DI5(NumberType.DOUBLE, NumberType.DOUBLE, NumberType.DOUBLE, NumberType.DOUBLE, NumberType.DOUBLE, NumberType.INT);
 528     ArrayList<NumberType> value = new ArrayList();
 529 
 530     ParamType(NumberType... type) {
 531         value.addAll(Arrays.asList(type));
 532     }
 533 
 534     public ArrayList<NumberType> getValue() {
 535         return value;
 536     }
 537 }
 538 
 539 class GeneratorLogic {
 540 
 541     public String generateJava(String fncName, ParameterList parmOut, ParameterList parmType, int maxLength, String prefix) {
 542         StringBuilder sb = new StringBuilder();
 543 
 544         sb.append("    {\n").append(prefix);
 545         int lineLength = 0;
 546         for (ParameterItem p : parmType.getList()) {
 547             sb.append(p.value1);
 548             sb.append(" ");
 549             sb.append(p.value2);
 550             sb.append("=");
 551             sb.append(p.value3);
 552             sb.append(";");
 553             if (sb.length() - lineLength > maxLength) {
 554                 sb.append("\n").append(prefix);
 555                 lineLength = sb.length();
 556             }
 557         }
 558 
 559         sb.append("\n");
 560         sb.append(prefix);
 561         for (ParameterItem p : parmOut.getList()) {
 562             sb.append("ps.format(\"");
 563             sb.append(p.value2);
 564             sb.append("=");
 565             sb.append(p.value1);
 566             sb.append("\\n\",");
 567 
 568 
 569             sb.append(p.value2);
 570             sb.append(");");
 571             if (sb.length() - lineLength > maxLength) {
 572                 sb.append("\n").append(prefix);
 573                 lineLength = sb.length();
 574             }
 575 
 576         }
 577 
 578         sb.append("\n").append(prefix);
 579 
 580         sb.append(fncName);
 581         sb.append("(");
 582         for (ParameterItem p : parmOut.getList()) {
 583             sb.append(p.getDelim());
 584             sb.append(p.value2);
 585             if (sb.length() - lineLength > maxLength) {
 586                 sb.append("\n").append(prefix);
 587                 lineLength = sb.length();
 588             }
 589         }
 590         sb.append(");\n}\n");
 591 
 592         return sb.toString();
 593     }
 594 }
 595 
 596 //Test types
 597 enum TestType {
 598 
 599     RANDOM(new GeneratorLogic());
 600     private GeneratorLogic genLogic;
 601 
 602     TestType(GeneratorLogic genLogic) {
 603         this.genLogic = genLogic;
 604     }
 605 
 606     public GeneratorLogic getLogic() {
 607         return genLogic;
 608     }
 609 }
 610 
 611 //One item for ParameterList (delimiter and value to build strings)
 612 class ParameterItem {
 613 
 614     private String delimiter;
 615     String value1;
 616     String value2;
 617     String value3;
 618     //private String endVal="";
 619 
 620     public ParameterItem(String delimiter, String value) {
 621         this.delimiter = delimiter;
 622         this.value1 = value;
 623         value2 = "";
 624         value3 = "";
 625     }
 626 
 627     public ParameterItem(String delimiter, String value1, String value2) {
 628         this.delimiter = delimiter;
 629         this.value1 = value1;
 630         this.value2 = value2;
 631         value3 = "";
 632     }
 633 
 634     public ParameterItem(String delimiter, String value1, String value2, String value3) {
 635         this.delimiter = delimiter;
 636         this.value1 = value1;
 637         this.value2 = value2;
 638         this.value3 = value3;
 639     }
 640 
 641     public String toString() {
 642         return delimiter + value1 + value2 + value3;
 643     }
 644 
 645     public String getDelim() {
 646         return delimiter;
 647     }
 648 }
 649 //Delimiters and values to generate calls, etc.
 650 class ParameterList {
 651 
 652     ArrayList<ParameterItem> list = new ArrayList();
 653     private String initDelim;
 654     private String delim;
 655     boolean lineBreak;
 656 
 657     public ParameterList(String initialDelimiter, String delimiter, boolean lineBreak) {
 658         initDelim = initialDelimiter;
 659         delim = delimiter;
 660         this.lineBreak = lineBreak;
 661     }
 662 
 663     public ArrayList<ParameterItem> getList() {
 664         return list;
 665     }
 666 
 667     public void add(String value) {
 668         list.add(new ParameterItem(initDelim, value));
 669         initDelim = delim;
 670     }
 671 
 672     public void add(String value1, String value2) {
 673         list.add(new ParameterItem(initDelim, value1, value2));
 674         initDelim = delim;
 675     }
 676 
 677     public void add(String value1, String value2, String value3) {
 678         list.add(new ParameterItem(initDelim, value1, value2, value3));
 679         initDelim = delim;
 680     }
 681 
 682     public ParameterItem get(int id) {
 683         return list.get(id);
 684     }
 685 
 686     public String toString() {
 687         StringBuilder sb = new StringBuilder();
 688         for (ParameterItem p : list) {
 689             sb.append(p.toString());
 690             if (lineBreak) {
 691                 sb.append("\n");
 692             }
 693 
 694         }
 695         return sb.toString();
 696     }
 697 
 698     public String toFormatString(String prefix, int maxLength) {
 699         StringBuilder sb = new StringBuilder();
 700         int charCount = 0;
 701         for (ParameterItem p : list) {
 702             sb.append(p.toString());
 703             if (sb.length() - charCount > maxLength) {
 704                 sb.append("\n").append(prefix);
 705                 charCount = sb.length();
 706             }
 707         }
 708         return sb.toString();
 709     }
 710 
 711     public int size() {
 712         return list.size();
 713     }
 714 
 715     public String getAllItemExclude(int excludeId) {
 716         StringBuilder sb = new StringBuilder();
 717         int cnt = list.size();
 718 
 719         for (int id = 0; id < cnt; ++id) {
 720             ParameterItem p = list.get(id);
 721             if (id == excludeId) {
 722                 sb.append(p.getDelim());
 723                 sb.append("0");
 724             } else {
 725                 sb.append(p.toString());
 726 
 727             }
 728         }
 729 
 730         return sb.toString();
 731 
 732     }
 733 
 734     public String getAllItemExcludeNot(int excludeId) {
 735         StringBuilder sb = new StringBuilder();
 736         int cnt = list.size();
 737 
 738         for (int id = 0; id < cnt; ++id) {
 739             ParameterItem p = list.get(id);
 740             if (id != excludeId) {
 741                 sb.append(p.getDelim());
 742                 sb.append("0");
 743 //                sb.append(p.getEnd());
 744             } else {
 745                 sb.append(p.toString());
 746 
 747             }
 748         }
 749 
 750         return sb.toString();
 751     }
 752 }
 753 
 754 class ParameterListGenerator {
 755 
 756     private ArrayList<NumberType> list = new ArrayList();
 757     private Random random;
 758     private int typeCnt;
 759     ParameterList cParms = new ParameterList(",", ",", true);
 760     ParameterList rParms = new ParameterList("", ",", true);
 761     ParameterList jParms = new ParameterList("", ",", true);
 762     ParameterList cExec = new ParameterList("", "", true);
 763     ParameterList jExecParm = new ParameterList("", ",", true);
 764     ParameterList jExecOut = new ParameterList("", ",", true);
 765 
 766     public ParameterListGenerator(int length, ParamType paramType) {
 767         generateRndTest(paramType, length);
 768     }
 769 
 770     private void add(ParameterList list, String s1) {
 771         list.add(s1);
 772     }
 773 
 774     private void add(ParameterList list, String s1, String s2) {
 775         list.add(s1, s2);
 776     }
 777 
 778     private void add(ParameterList list, String s1, String s2, String s3) {
 779         list.add(s1, s2, s3);
 780     }
 781 
 782     private void generateRndTest(ParamType paramType, int length) {
 783         generateTypeList(paramType);
 784 
 785         typeCnt = list.size();
 786         random = new Random();
 787         random.setSeed(System.currentTimeMillis());
 788 
 789         for (int cnt = 0; cnt < length; ++cnt) {
 790             int type = random.nextInt(typeCnt);
 791 
 792             String randomVal = list.get(type).getFnc();
 793 
 794             String ctype = list.get(type).getСType();
 795             String jtype = list.get(type).getJType();
 796             String cconv = list.get(type).getСConv();
 797             String jconv = list.get(type).getJConv();
 798 
 799             String varName = "p" + cnt;
 800             add(jParms, jtype, varName);
 801             //jParmGen.add(jtype + varName);
 802 
 803             //cParms.add(ctype + varName);
 804             add(cParms, ctype, varName);
 805 
 806 
 807             //rParms.add(varName);
 808             add(rParms, varName);
 809 
 810             add(cExec, varName, cconv);
 811 
 812             add(jExecParm, jtype, varName, randomVal);
 813             //jExecOut.add(new PairString(jconv,varName,jtype));
 814             add(jExecOut, jconv, varName, jtype);
 815         }
 816 
 817     }
 818 
 819     public ParameterList getCExec() {
 820         return cExec;
 821     }
 822 
 823     public ParameterList getCParm() {
 824         return cParms;
 825     }
 826 
 827     //Return generated java text
 828     public ParameterList getJExecParameters() {
 829         return jExecParm;
 830     }
 831 
 832     public ParameterList getJExecOut() {
 833         return jExecOut;
 834     }
 835 
 836     /*
 837      * Return string containing parameters for Java
 838      */
 839     public ParameterList getJParm() {
 840         return jParms;
 841     }
 842 
 843     public ParameterList getRParm() {
 844         return rParms;
 845     }
 846 
 847     private void generateTypeList(ParamType paramType) {
 848         list.addAll(paramType.getValue());
 849     }
 850 }
 851 
 852 class SrcGenerator {
 853 
 854     ParameterListGenerator parmListGen;
 855     GeneratorLogic genLogic;
 856     int iterationCounter;
 857     int parametersCounter;
 858     ParamType paramType;
 859     TestType testType;
 860     String fncName;
 861     //SrcGenerator g1=new SrcGenerator(3,1,ParamType.MIXED_DFIB,TestType.RANDOM,"callRandom");
 862     int maxLength;
 863 
 864     public SrcGenerator(int parmCounter, int iterCounter, ParamType parType, TestType testType, String fncName, int maxLength) {
 865         this.maxLength = maxLength;
 866         parametersCounter = parmCounter;
 867         iterationCounter = iterCounter;
 868         paramType = parType;
 869         this.testType = testType;
 870         this.fncName = fncName;
 871         parmListGen = new ParameterListGenerator(parametersCounter, paramType);
 872         genLogic = testType.getLogic();
 873 
 874     }
 875 
 876     public String getFncName() {
 877         return fncName;
 878     }
 879 
 880     public ParameterList getJParm() {
 881         return parmListGen.getJParm();
 882     }
 883 
 884     public ParameterList getCParm() {
 885         return parmListGen.getCParm();
 886     }
 887 
 888     public String getCExec() {
 889 
 890         StringBuilder sb = new StringBuilder();
 891         for (ParameterItem p : parmListGen.getCExec().getList()) {
 892             sb.append("fprintf(file,\"");
 893             sb.append(p.value1);
 894             sb.append("=");
 895             sb.append(p.value2);
 896             sb.append("\\n\",");
 897             sb.append(p.value1);
 898             sb.append(");\n");
 899         }
 900         return sb.toString();
 901     }
 902 
 903     public String getCExec(int maxLength,String prefix) {
 904 
 905         int lineLength = 0;
 906         StringBuilder sb = new StringBuilder();
 907         for (ParameterItem p : parmListGen.getCExec().getList()) {
 908             sb.append("fprintf(file,\"");
 909             sb.append(p.value1);
 910             sb.append("=");
 911             sb.append(p.value2);
 912             sb.append("\\n\",");
 913             sb.append(p.value1);
 914             sb.append(");");
 915             if (sb.length() - lineLength > maxLength) {
 916                 lineLength = sb.length();
 917                 sb.append("\n").append(prefix);
 918             }
 919         }
 920         return sb.toString();
 921     }
 922 
 923     public String getJExec(String prefix) {
 924         return genLogic.generateJava(fncName, parmListGen.getJExecOut(), parmListGen.getJExecParameters(), maxLength, prefix);
 925 
 926     }
 927 }