Consistently use PUSH_PARENT()/POP_PARENT().
[cparser] / wrappergen / write_jna.c
index 39ca1bb..1f180d2 100644 (file)
 #include "type.h"
 #include "printer.h"
 #include "adt/error.h"
+#include "adt/xmalloc.h"
 #include <libfirm/adt/pset_new.h>
 
+typedef struct output_limit {
+       const char          *filename;
+       struct output_limit *next;
+} output_limit;
+
 static const scope_t *global_scope;
 static FILE          *out;
 static pset_new_t     avoid_symbols;
-
-static void write_type(type_t *type);
+static output_limit  *output_limits;
+static const char    *libname;
 
 static bool is_system_header(const char *fname)
 {
@@ -73,7 +79,7 @@ static const char *get_atomic_type_string(const atomic_type_kind_t type)
        case ATOMIC_TYPE_CHAR:        return "byte";
        case ATOMIC_TYPE_SCHAR:       return "byte";
        case ATOMIC_TYPE_UCHAR:       return "byte";
-       case ATOMIC_TYPE_SHORT:       return "short";
+       case ATOMIC_TYPE_SHORT:       return "short";
        case ATOMIC_TYPE_USHORT:      return "short";
        case ATOMIC_TYPE_INT:         return "int";
        case ATOMIC_TYPE_UINT:        return "int";
@@ -83,7 +89,6 @@ static const char *get_atomic_type_string(const atomic_type_kind_t type)
        case ATOMIC_TYPE_ULONGLONG:   return "long";
        case ATOMIC_TYPE_FLOAT:       return "float";
        case ATOMIC_TYPE_DOUBLE:      return "double";
-       case ATOMIC_TYPE_LONG_DOUBLE: return "double";
        case ATOMIC_TYPE_BOOL:        return "boolean";
        default:                      panic("unsupported atomic type");
        }
@@ -217,9 +222,6 @@ static void write_type(type_t *type)
        case TYPE_ENUM:
                write_enum_type(&type->enumt);
                return;
-       case TYPE_BUILTIN:
-               write_type(type->builtin.real_type);
-               return;
        case TYPE_ERROR:
        case TYPE_INVALID:
        case TYPE_TYPEOF:
@@ -443,6 +445,19 @@ static void write_function(const entity_t *entity)
        fprintf(out, ");\n");
 }
 
+void jna_limit_output(const char *filename)
+{
+       output_limit *limit = xmalloc(sizeof(limit[0]));
+       limit->filename = filename;
+
+       limit->next   = output_limits;
+       output_limits = limit;
+}
+
+void jna_set_libname(const char *new_libname)
+{
+       libname = new_libname;
+}
 
 void write_jna_decls(FILE *output, const translation_unit_t *unit)
 {
@@ -457,10 +472,14 @@ void write_jna_decls(FILE *output, const translation_unit_t *unit)
        fputs("import com.sun.jna.Pointer;\n", out);
        fputs("\n", out);
 
+       const char *register_libname = libname;
+       if (register_libname == NULL)
+               register_libname = "library";
+
        /* TODO: where to get the name from? */
        fputs("public class binding {\n", out);
        fputs("\tstatic {\n", out);
-       fputs("\t\tNative.register(\"firm\");\n", out);
+       fprintf(out, "\t\tNative.register(\"%s\");\n", register_libname);
        fputs("\t}\n", out);
        fputs("\n", out);
 
@@ -514,8 +533,23 @@ void write_jna_decls(FILE *output, const translation_unit_t *unit)
        for ( ; entity != NULL; entity = entity->base.next) {
                if (entity->kind != ENTITY_FUNCTION)
                        continue;
-               if (is_system_header(entity->base.source_position.input_name))
+               const char *input_name = entity->base.source_position.input_name;
+               if (is_system_header(input_name))
+                       continue;
+               if (entity->function.elf_visibility != ELF_VISIBILITY_DEFAULT)
                        continue;
+               if (output_limits != NULL) {
+                       bool in_limits = false;
+                       for (output_limit *limit = output_limits; limit != NULL;
+                            limit = limit->next) {
+                           if (strcmp(limit->filename, input_name) == 0) {
+                                       in_limits = true;
+                                       break;
+                               }
+                       }
+                       if (!in_limits)
+                               continue;
+               }
 
                if (pset_new_contains(&avoid_symbols, entity->base.symbol))
                        continue;