X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=wrappergen%2Fwrite_jna.c;h=b20904277c527b6f3395489b47809aa18d698f4e;hb=c1cc71ca2c79b3f2a9afe2be86a678c544ff6e62;hp=070c15cc0b6ef66b1df3fdccf1bd5221a410886d;hpb=6d7d61de445629e1590d3a2ba2990ef7a651368a;p=cparser diff --git a/wrappergen/write_jna.c b/wrappergen/write_jna.c index 070c15c..b209042 100644 --- a/wrappergen/write_jna.c +++ b/wrappergen/write_jna.c @@ -22,39 +22,51 @@ #include #include +#include "adt/strutil.h" #include "write_jna.h" #include "symbol_t.h" #include "ast_t.h" #include "type_t.h" #include "entity_t.h" #include "type.h" +#include "printer.h" #include "adt/error.h" -#include +#include "adt/xmalloc.h" +#include "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) { - return strncmp(fname, "/usr/include", 12) == 0; + if (strstart(fname, "/usr/include")) + return true; + if (fname == builtin_source_position.input_name) + return true; + return false; } static const char *fix_builtin_names(const char *name) { - if (strcmp(name, "class") == 0) { + if (streq(name, "class")) { return "_class"; - } else if(strcmp(name, "this") == 0) { + } else if (streq(name, "this")) { return "_this"; - } else if(strcmp(name, "public") == 0) { + } else if (streq(name, "public")) { return "_public"; - } else if(strcmp(name, "protected") == 0) { + } else if (streq(name, "protected")) { return "_protected"; - } else if(strcmp(name, "private") == 0) { + } else if (streq(name, "private")) { return "_private"; - } else if(strcmp(name, "final") == 0) { + } else if (streq(name, "final")) { return "_final"; } /* TODO put all reserved names here */ @@ -68,17 +80,16 @@ 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"; - case ATOMIC_TYPE_LONG: return "NativeLong"; - case ATOMIC_TYPE_ULONG: return "NativeLong"; + case ATOMIC_TYPE_LONG: return "com.sun.jna.NativeLong"; + case ATOMIC_TYPE_ULONG: return "com.sun.jna.NativeLong"; case ATOMIC_TYPE_LONGLONG: return "long"; 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"); } @@ -98,7 +109,7 @@ static void write_pointer_type(const pointer_type_t *type) } if (is_type_pointer(points_to)) { /* hack... */ - fputs("Pointer[]", out); + fputs("java.nio.Buffer", out); return; } fputs("Pointer", out); @@ -212,16 +223,11 @@ 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: case TYPE_TYPEDEF: panic("invalid type found"); case TYPE_ARRAY: - case TYPE_BITFIELD: case TYPE_REFERENCE: case TYPE_FUNCTION: case TYPE_COMPLEX: @@ -265,7 +271,7 @@ static void write_unary_expression(const unary_expression_t *expression) case EXPR_UNARY_NOT: fputc('!', out); break; - case EXPR_UNARY_CAST_IMPLICIT: + case EXPR_UNARY_CAST: write_expression(expression->value); return; default: @@ -278,6 +284,7 @@ static void write_binary_expression(const binary_expression_t *expression) { fputs("(", out); write_expression(expression->left); + fputc(' ', out); switch(expression->base.kind) { case EXPR_BINARY_BITWISE_OR: fputs("|", out); break; case EXPR_BINARY_BITWISE_AND: fputs("&", out); break; @@ -291,34 +298,30 @@ static void write_binary_expression(const binary_expression_t *expression) default: panic("unimplemented binexpr"); } + fputc(' ', out); write_expression(expression->right); fputs(")", out); } static void write_expression(const expression_t *expression) { - const const_expression_t *constant; /* TODO */ switch(expression->kind) { - case EXPR_CONST: - constant = &expression->conste; - if(is_type_integer(expression->base.type)) { - fprintf(out, "%lld", constant->v.int_value); - } else { - fprintf(out, "%Lf", constant->v.float_value); - } + case EXPR_LITERAL_INTEGER: + fprintf(out, "%s", expression->literal.value.begin); break; - case EXPR_REFERENCE_ENUM_VALUE: { + + case EXPR_ENUM_CONSTANT: { /* UHOH... hacking */ entity_t *entity = expression->reference.entity; write_enum_name(& entity->enum_value.enum_type->enumt); fprintf(out, ".%s.val", entity->base.symbol->string); break; } - EXPR_UNARY_CASES + case EXPR_UNARY_CASES: write_unary_expression(&expression->unary); break; - EXPR_BINARY_CASES + case EXPR_BINARY_CASES: write_binary_expression(&expression->binary); break; default: @@ -358,23 +361,29 @@ static void write_enum(const symbol_t *symbol, const enum_t *entity) } } fprintf(out, "\t\tpublic final int val;\n"); - fprintf(out, "\t\tprivate static class C { static int next_val; }\n\n"); + fprintf(out, "\n"); + fprintf(out, "\t\tprivate static class C {\n"); + fprintf(out, "\t\t\tstatic int next_val;\n"); + fprintf(out, "\t\t}\n"); + fprintf(out, "\n"); fprintf(out, "\t\t%s(int val) {\n", name); fprintf(out, "\t\t\tthis.val = val;\n"); fprintf(out, "\t\t\tC.next_val = val + 1;\n"); fprintf(out, "\t\t}\n"); + fprintf(out, "\n"); fprintf(out, "\t\t%s() {\n", name); fprintf(out, "\t\t\tthis.val = C.next_val++;\n"); fprintf(out, "\t\t}\n"); - fprintf(out, "\t\t\n"); + fprintf(out, "\n"); fprintf(out, "\t\tpublic static %s getEnum(int val) {\n", name); - fprintf(out, "\t\t\tfor(%s entry : values()) {\n", name); + fprintf(out, "\t\t\tfor (%s entry : values()) {\n", name); fprintf(out, "\t\t\t\tif (val == entry.val)\n"); fprintf(out, "\t\t\t\t\treturn entry;\n"); fprintf(out, "\t\t\t}\n"); fprintf(out, "\t\t\treturn null;\n"); fprintf(out, "\t\t}\n"); fprintf(out, "\t}\n"); + fprintf(out, "\n"); } #if 0 @@ -398,7 +407,8 @@ static void write_function(const entity_t *entity) const function_type_t *function_type = (const function_type_t*) entity->declaration.type; - fputc('\t', out); + fputc('\n', out); + fprintf(out, "\tpublic static native "); type_t *return_type = skip_typeref(function_type->return_type); write_type(return_type); fprintf(out, " %s(", entity->base.symbol->string); @@ -406,7 +416,7 @@ static void write_function(const entity_t *entity) entity_t *parameter = entity->function.parameters.entities; int first = 1; int n = 0; - for( ; parameter != NULL; parameter = parameter->base.next) { + for ( ; parameter != NULL; parameter = parameter->base.next) { assert(parameter->kind == ENTITY_PARAMETER); if(!first) { fprintf(out, ", "); @@ -431,6 +441,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) { @@ -439,30 +462,37 @@ void write_jna_decls(FILE *output, const translation_unit_t *unit) pset_new_init(&avoid_symbols); - ast_set_output(out); - type_set_output(out); + print_to_file(out); fprintf(out, "/* WARNING: Automatically generated file */\n"); - fputs("import com.sun.jna.Library;\n", out); fputs("import com.sun.jna.Native;\n", out); - fputs("import com.sun.jna.Platform;\n", out); fputs("import com.sun.jna.Pointer;\n", out); - fputs("import com.sun.jna.NativeLong;\n", out); - fputs("\n\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 interface binding extends Library {\n", out); + fputs("public class binding {\n", out); + fputs("\tstatic {\n", out); + fprintf(out, "\t\tNative.register(\"%s\");\n", register_libname); + fputs("\t}\n", out); + fputs("\n", out); /* read the avoid list */ FILE *avoid = fopen("avoid.config", "r"); if (avoid != NULL) { while (!feof(avoid)) { char buf[1024]; - fgets(buf, sizeof(buf), avoid); + char *res = fgets(buf, sizeof(buf), avoid); + if (res == NULL) + break; + if (buf[0] == 0) + continue; + size_t len = strlen(buf); if (buf[len-1] == '\n') buf[len-1] = 0; - if (buf[0] == 0) - continue; char *str = malloc(len+1); memcpy(str, buf, len+1); @@ -474,7 +504,7 @@ void write_jna_decls(FILE *output, const translation_unit_t *unit) /* write structs,unions + enums */ entity_t *entity = unit->scope.entities; - for( ; entity != NULL; entity = entity->base.next) { + for ( ; entity != NULL; entity = entity->base.next) { if (entity->kind == ENTITY_ENUM) { if (find_enum_typedef(&entity->enume) != NULL) continue; @@ -487,8 +517,7 @@ void write_jna_decls(FILE *output, const translation_unit_t *unit) } #if 0 - if(type->kind == TYPE_COMPOUND_STRUCT - || type->kind == TYPE_COMPOUND_UNION) { + if (is_type_compound(type)) { write_compound(entity->base.symbol, &type->compound); } #endif @@ -496,11 +525,26 @@ void write_jna_decls(FILE *output, const translation_unit_t *unit) /* write functions */ entity = unit->scope.entities; - for( ; entity != NULL; entity = entity->base.next) { + 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 (streq(limit->filename, input_name)) { + in_limits = true; + break; + } + } + if (!in_limits) + continue; + } if (pset_new_contains(&avoid_symbols, entity->base.symbol)) continue;