All Downloads are FREE. Search and download functionalities are using the official Maven repository.

oms3.nap.JNAFortran Maven / Gradle / Ivy

There is a newer version: 0.8.1
Show newest version
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package oms3.nap;

import java.io.File;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 *
 * @author od
 */
public abstract class JNAFortran implements AnnotationHandler {

    String libname;
    String modName;
    String javaExecFunction;
    String description = "";
    File srcFile;
    File genFile;
    String packageName;

    private static class Decl {

        Map> ann;
        String type;
        String name;

        Decl(Map> ann, String type, String name) {
            this.ann = ann;
            this.type = type;
            this.name = name;
        }

        boolean isOut() {
            return ann.containsKey("Out");
        }

        boolean isIn() {
            return ann.containsKey("In");
        }

        boolean isScalar() {
            return type.equals("float") || type.equals("double") || type.equals("boolean")
                    || type.equals("int");
        }

        String getReferenceType() {
            if (type.equals("float")) {
                return "FloatByReference";
            } else if (type.equals("double")) {
                return "DoubleByReference";
            } else if (type.equals("int")) {
                return "IntByReference";
            }
            throw new IllegalArgumentException(type);
        }

        //   fDecl  INTEGER(C_INT), VALUE :: erosion_inp_len
        static String getJavaType(String fDecl) {
            String d = fDecl.toLowerCase().trim();

            if (d.contains("c_float") && isArray(fDecl)) {
                return "float[]";
            } else if (d.contains("c_int") && isArray(fDecl)) {
                return "int[]";
            } else if (d.contains("c_double") && isArray(fDecl)) {
                return "double[]";
            } else if (d.contains("c_float")) {
                return "float";
            } else if (d.contains("c_int")) {
                return "int";
            } else if (d.contains("c_double")) {
                return "double";
            } else if (d.startsWith("char")) {
                return "String";
            }
            throw new IllegalArgumentException(fDecl);
        }

        static String[] getDeclNames(String fDecl) {
            String d = fDecl.toLowerCase().trim();
            String s[] = d.split("::");
            if (s.length != 2) {
                throw new IllegalArgumentException(fDecl);
            }
            return s[1].trim().split("\\s*,\\s*");
        }

        /** Parse a single src line
         *
         * @param decl
         * @param ann
         * @return
         */
        static List parse(String decl, Map> ann) {
            List l = new ArrayList();
            String jType = getJavaType(decl);
            String[] names = getDeclNames(decl);
            for (String name : names) {
                l.add(new Decl(ann, jType, name));
            }
            return l;
        }

        static boolean isArray(String fDecl) {
            String d = fDecl.toLowerCase().trim();
            return d.indexOf("dimension") > -1;
        }
    }
    /** All the declarations */
    List decl = new ArrayList();

    public void setGenFile(File genFile) {
        this.genFile = genFile;
    }

    public void setSrcFile(File srcFile) {
        this.srcFile = srcFile;
    }

    void setRelativeFile(String incFile) {
        this.packageName = new File(incFile).getParent().toString();
    }

    public void setLibname(String libname) {
        this.libname = libname;
    }

    @Override
    public void handle(Map> ann, String line) {
        if (ann.containsKey("Execute")) {
            javaExecFunction = ann.get("Execute").get("value");
            if (javaExecFunction == null) {
                line = line.trim();
                javaExecFunction = line.substring(line.indexOf(' '), line.indexOf('('));
            } else {
                javaExecFunction = AnnotationParser.trimQuotes(javaExecFunction);
            }
            javaExecFunction = javaExecFunction.trim().toLowerCase();
        } else if (ann.containsKey("In") || ann.containsKey("Out")) {
            decl.addAll(Decl.parse(line.trim(), ann));
        }
    }

    @Override
    public void start(String src) {
        src = src.toLowerCase();
        if (src.contains("module")) {
            String line = src.substring(src.indexOf("module"));
            line = src.substring(0, src.indexOf("\n"));
            String[] mdecl = line.trim().split("\\s+");
            if (mdecl.length > 0) {
                modName = mdecl[1];
            }
        }
    }

    @Override
    public void done() throws Exception {
        if (javaExecFunction == null) {
            return;
        }
        genFile.getParentFile().mkdirs();

        String className = genFile.getName().substring(0, genFile.getName().indexOf('.'));
        PrintStream w = new PrintStream(genFile);

        w.println("// OMS3 Native proxy from '" + srcFile.getPath() + "'");
        w.println("// Generated at " + new Date());
        w.println("package " + packageName.replace('/', '.') + ";");
        w.println();
        w.println("import com.sun.jna.ptr.*;");
        w.println("import oms3.annotations.*;");
        w.println();
        w.println("// " + description);
        w.println("public class " + className + " {");
        w.println();

        for (Decl d : decl) {
            w.print(AnnotationParser.toString(d.ann));
            w.println(" public " + d.type + " " + d.name + ";");
            w.println();
        }

        w.println(" @Execute");
        w.println(" public void exec() {");
        for (Decl d : decl) {
            if (d.isScalar()) {
                w.println("  " + d.getReferenceType() + " " + d.name + "__ = new " + d.getReferenceType() + "(" + d.name + ");");
            }
        }
        w.print("   __Native__.lib." + getNativeName() + "(");
        for (int i = 0; i < decl.size(); i++) {
            Decl d = decl.get(i);
            w.print(d.name);
            if (d.isScalar()) {
                w.print("__");
            }
            if (d.type.equals("String")) {
                w.print(", " + d.name + ".length()");
            }
            if (i < decl.size() - 1) {
                w.print(",");
            }
        }

        w.println(");");

        for (Decl d : decl) {
            if (d.isScalar() && d.isOut()) {
                w.println("  " + d.name + " = " + d.name + "__.getValue();");
            }
        }

        w.println(" }");
        w.println();
        w.println(" @DLL(\"" + libname + "\")");
        w.println(" interface __Native__ extends com.sun.jna.Library {");
        w.println("   // library mapping reference");
        w.println("   __Native__ lib = oms3.util.NativeLibraries.bind(__Native__.class);");
        w.println();
        w.println("   // DLL function(s)");
        w.print("   void " + getNativeName() + "(");

        for (int i = 0; i < decl.size(); i++) {
            Decl d = decl.get(i);
            if (d.isScalar()) {
                w.print("ByReference " + d.name);
            } else {
                w.print(d.type + " " + d.name);
                if (d.type.equals("String")) {
                    w.print(", int " + d.name + "_len");
                }
            }
            if (i < decl.size() - 1) {
                w.print(",");
            }
        }

        w.println(");");
        w.println(" }");
        w.println("}");
        w.close();


        // checking later the update.
        //  genFile.setLastModified(srcFile.lastModified());
    }

    String getNativeName() {
        return modName != null ? ("__" + modName + "_MOD_" + javaExecFunction)
                : javaExecFunction + "_";
    }

    public static void main(String[] args) throws Exception {
//        if (args.length != 1) {
//            return;
//        }
//
//        File natSrc = new File(args[0]);
//        File natSrc = new File(System.getProperty("user.dir") + "/test/oms3/ap/Arr.f90");
//        AnnotationHandler ah = new JNA();
//        AnnotationParser.handle(natSrc, ah);

        System.out.println(Arrays.toString(Decl.getDeclNames("CHARACTER(C_CHAR, len=hyd2er_len)  :: a")));
//        System.out.println(getDeclModifier("CHARACTER(C_CHAR, len=hyd2er_len)"));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy