Added documentation for nativez-gen.
authorMichael Zucchi <michael@swordfish.com.au>
Tue, 23 Apr 2019 01:25:47 +0000 (10:55 +0930)
committerMichael Zucchi <michael@swordfish.com.au>
Tue, 23 Apr 2019 01:25:47 +0000 (10:55 +0930)
nativez-gen now passes all unknown arguments to cproto.

README
src/notzed.nativez/jni/nativez-gen

diff --git a/README b/README
index e73f60d..e361372 100644 (file)
--- a/README
+++ b/README
@@ -9,6 +9,10 @@ Introduction
 This is a C link library and Java base class which can be used to help
 implement libraries which use the Java Native Interface (JNI).
 
+It provides a base class for native objects which provides automatic
+(and manual) reclaimation, and a shared library for easy access to
+these and other JNI utilities.
+
 Compile
 -------
 
@@ -32,6 +36,7 @@ compilation, or non-modular use:
 `bin/notzed.nativez/<target>/include' - header files
 `bin/notzed.nativez/<target>/lib/libnativez.so' - linux shared library
 `bin/modules/notzed.nativez/' - compiled class files
+`bin/notzed.nativez/<target>/bin/nativez-gen' - table generator
 
 Usage
 -----
@@ -57,13 +62,17 @@ directive.
 Native Library
 - - - - - - --
 
+Whilst not necessary one can use the native library for access to the
+NativeZ_* functions and some other cross-platform tools.
+
 The native library should link with -lnativez and include "nativez.h".
 
 Before using any functions invoke the nativez_OnLoad() function,
 typically in the native library's JNI_OnLoad() function.
 
-Any instance of a class derived from NativeZ must be created using the
-NativeZ_* functions.
+Any instance of a class derived from NativeZ must be created or
+referenced using the NativeZ_* functions in order to partake of
+automatic cleanup.
 
 Native functions should take object arguments and resolve them to
 native pointers using NativeZ_getP().
@@ -71,12 +80,136 @@ native pointers using NativeZ_getP().
 The nativez_* functions are just general JNI and useful cross-platform
 utility functions which may be freely used within (any) JNI code.
 
+See nativez.h for more information.
+
+nativez-gen
+-- - - - --
+
+nativez provides a couple of functions for compact table based
+resolution of shared library entry points from dynamically loaded
+libraries, and for resolving Java classes and field and method
+acccessors.
+
+Whilst the tables can be generated manually nativez-gen can be used to
+generate correct tables from a definition file.  When run on a
+definition file it will create one or two pairs of static variables to
+be included in the C file that uses it.
+
+nativez-gen requires `perl' and the header section processing requires
+`cproto'.
+
+The definition file is made of any number of sections.  Each section
+starts with a header which must be on the same line (including the
+`{') and a number of entries each on their own line followed by a `}'.
+Non-EOL whitespace is ignored. No quoting or escaping is available.
+
+See also `src/notzed.nativez/jni/nativez.gen'.  It's dumb but somewhat
+messy perl.
+
+See also `src/notzed.nativez/jni/jni.make' for an example of how to
+invoke it automatically.
+
+java section
+-  -- --  --
+
+Each entry must be on a separate line as below.
+
+java VarName com/package/name/ClassName {
+   static funcName, funcSig
+   funcName, funcSig
+   static fieldName,fieldSig
+   fieldName,fieldSig
+}
+
+VarName must be unique for each section in a single definition file.
+
+The *Name* and *Sig values are those passed to the corresponding JNI
+functions.  The static modifier calls the *Static* variaants.  A
+funcSig will contain a pair of parentheses and a fieldSig will not.
+
+For each java section the following definitions will be created:
+
+static struct {
+       jclass VarName_classid;
+       jmethodID funcName_[encodedSig];
+       jmethodID funcName_[encodedSig];
+       jfieldID fieldName_[encodedSig];
+       jfieldID fieldName_[encodedSig];
+} java;
+
+static const char *java_names =
+       "#com/package/name/ClassName\0"
+       ":funcName\0funcSig\0"
+       ".funcName\0funcSig\0"
+       ";fieldName\0fieldSig\0"
+       ",fieldName\0fieldSig\0"
+       ;
+  
+encodedSig depends on the arguments to nativez-gen.  By default for
+functions a compact variation of JNI name mangling is used where the
+primitive types are lowercased and any object types are converted to
+'l' with all [ collapsed to nothing.  A longer option (--java-long) is
+somewhat similar but not (current) quite the same as the JNI name
+mangling and allows for overriden functions taking different object
+types in the same position.
+
+See the nativez-gen header for the rest of the options.
+
+header section
+ --  -- --  --
+
+A header section extracts prototypes from C .h header files and
+creates a typesafe structure of same.
+
+header libname path/header.h {
+   funcname_a
+   funcmame_b
+}
+
+libname is the name of the library as used in the
+nativez_ResolveLibraries() table.  i.e. it's just a key and not the
+actual name.
+
+path/header.h should be the name as included directly in a C file,
+i.e. it can be used direclty in a #include directive.  It is relative
+to the (-b path) command line argument.
+
+The contents of the section are just the function names required.
+
+All header sections in a definition file will be combined to create a
+pair of variables.  If one assumes a second section for libname2 is in
+the file, this is an example output:
+
+#inclulde <path/header.h>
+#inclulde <path/header2.h>
+
+static struct {
+       /* libname */
+       type (*funcname_a)(args);
+       type (*funcname_b)(args);
+       /* libname2 */
+       type (*funcname_c)(args);
+} fn;
+
+static const char *fn_names =
+       "#libname\0"
+       "funcname_a\0"
+       "funcname_b\0"
+       "@libname2\0"
+       "funcname_c\0"
+       ;
+
+See the nativez-gen header for the options.
+
 LICENSE
 -------
 
 This is supplied under the permissive 3-clause BSD license.  It allows
 for commercial use.  See also notzed.nativez/legal/LICENSE.
 
+java.make is covered by the GNU GPL Version 3 or later but is only
+required at build time.
+
  Copyright (C) 2018,2019 Michael Zucchi
 
  Redistribution and use in source and binary forms, with or without
index 2c7844c..ec47677 100755 (executable)
@@ -1,30 +1,27 @@
 #!/usr/bin/perl
 
 # usage [ options ]* def-file.def
-#  -b basedir  Base directory for any 'header' sections.
-#  -I incdir   Extra include directory
-#  -Iincdir    Extra include directory
+
+#  -b basedir  Base directory for any 'header' sections.  It is added to the include path.
 #  --func-name  Function table variable name.  Default is `fn'.
 #  --java-name  Java table variable name.  Default is 'java'.
 #  -J          Create #defines to map java names to the variable name.
 #  --java-long  Create long java names for object types.  Sort of like mangled jni names.
 
+# All other options and arguments are passed to cproto.
+
 $args = "$0 ".join " ", @ARGV;
 $java_name = "java";
 $func_name = "fn";
 $doJ = 0;
 $doLong = 0;
+$cproto = "";
 
-while ($#ARGV >= 0) {
+while ($#ARGV > 0) {
     my $cmd = shift;
     if ($cmd eq "-b") {
        $basedir = shift;
-       $includes.=" '-I${basedir}'";
-    } elsif ($cmd eq "-I") {
-       my $dir = shift;
-       $includes.= " '-I$dir'";
-    } elsif ($cmd =~ m/^-I/) {
-       $includes.= " '$cmd'";
+       $cproto .= " -I '${basedir}'";
     } elsif ($cmd eq "--func-name") {
        $func_name = shift;
     } elsif ($cmd eq "--java-name") {
@@ -34,12 +31,12 @@ while ($#ARGV >= 0) {
     } elsif ($cmd eq "--java-long") {
        $doLong = 1;
     } else {
-       $def = $cmd;
+       $cproto .= " '$cmd'";
     }
 }
+$def = shift;
 
-#die ("`$def': input file doesn't exist") if ! -f $def;
-#die ("`$basedir': doesn't exist") if ! -d $basedir;
+die ("`$def': input file doesn't exist") if ! -f $def;
 
 $header = "";
 $librart = "";
@@ -62,7 +59,7 @@ while (<IN>) {
        -f "$basedir/$header" || die ("header $header not found");
        
        %proto = ();
-       open PROTO, "cproto -q -x ${includes} $basedir/$header|";
+       open PROTO, "cproto -q -x ${cproto} $basedir/$header|";
        
        while (<PROTO>) {
            chop;