projects
/
cparser
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
rename source_position_t to position_t, rename members to pos
[cparser]
/
wrappergen
/
write_jna.c
diff --git
a/wrappergen/write_jna.c
b/wrappergen/write_jna.c
index
b3e0469
..
0960578
100644
(file)
--- a/
wrappergen/write_jna.c
+++ b/
wrappergen/write_jna.c
@@
-1,6
+1,6
@@
/*
* This file is part of cparser.
/*
* This file is part of cparser.
- * Copyright (C) 2007-200
8
Matthias Braun <matze@braunis.de>
+ * Copyright (C) 2007-200
9
Matthias Braun <matze@braunis.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@
-22,39
+22,52
@@
#include <errno.h>
#include <string.h>
#include <errno.h>
#include <string.h>
+#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 "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 "adt/error.h"
-#include <libfirm/adt/pset_new.h>
+#include "adt/xmalloc.h"
+#include "adt/pset_new.h"
+#include "separator_t.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 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)
{
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_position.input_name)
+ return true;
+ return false;
}
static const char *fix_builtin_names(const char *name)
{
}
static const char *fix_builtin_names(const char *name)
{
- if (str
cmp(name, "class") == 0
) {
+ if (str
eq(name, "class")
) {
return "_class";
return "_class";
- } else if
(strcmp(name, "this") == 0
) {
+ } else if
(streq(name, "this")
) {
return "_this";
return "_this";
- } else if
(strcmp(name, "public") == 0
) {
+ } else if
(streq(name, "public")
) {
return "_public";
return "_public";
- } else if
(strcmp(name, "protected") == 0
) {
+ } else if
(streq(name, "protected")
) {
return "_protected";
return "_protected";
- } else if
(strcmp(name, "private") == 0
) {
+ } else if
(streq(name, "private")
) {
return "_private";
return "_private";
- } else if
(strcmp(name, "final") == 0
) {
+ } else if
(streq(name, "final")
) {
return "_final";
}
/* TODO put all reserved names here */
return "_final";
}
/* TODO put all reserved names here */
@@
-68,17
+81,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_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_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_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");
}
case ATOMIC_TYPE_BOOL: return "boolean";
default: panic("unsupported atomic type");
}
@@
-98,7
+110,7
@@
static void write_pointer_type(const pointer_type_t *type)
}
if (is_type_pointer(points_to)) {
/* hack... */
}
if (is_type_pointer(points_to)) {
/* hack... */
- fputs("
Pointer[]
", out);
+ fputs("
java.nio.Buffer
", out);
return;
}
fputs("Pointer", out);
return;
}
fputs("Pointer", out);
@@
-212,16
+224,11
@@
static void write_type(type_t *type)
case TYPE_ENUM:
write_enum_type(&type->enumt);
return;
case TYPE_ENUM:
write_enum_type(&type->enumt);
return;
- case TYPE_BUILTIN:
- write_type(type->builtin.real_type);
- return;
case TYPE_ERROR:
case TYPE_ERROR:
- case TYPE_INVALID:
case TYPE_TYPEOF:
case TYPE_TYPEDEF:
case TYPE_TYPEOF:
case TYPE_TYPEDEF:
- panic("invalid type
found
");
+ panic("invalid type");
case TYPE_ARRAY:
case TYPE_ARRAY:
- case TYPE_BITFIELD:
case TYPE_REFERENCE:
case TYPE_FUNCTION:
case TYPE_COMPLEX:
case TYPE_REFERENCE:
case TYPE_FUNCTION:
case TYPE_COMPLEX:
@@
-265,11
+272,11
@@
static void write_unary_expression(const unary_expression_t *expression)
case EXPR_UNARY_NOT:
fputc('!', out);
break;
case EXPR_UNARY_NOT:
fputc('!', out);
break;
- case EXPR_UNARY_CAST
_IMPLICIT
:
+ case EXPR_UNARY_CAST:
write_expression(expression->value);
return;
default:
write_expression(expression->value);
return;
default:
- panic("unim
eplemented unary expression found
");
+ panic("unim
plemented unary expression
");
}
write_expression(expression->value);
}
}
write_expression(expression->value);
}
@@
-278,6
+285,7
@@
static void write_binary_expression(const binary_expression_t *expression)
{
fputs("(", out);
write_expression(expression->left);
{
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;
switch(expression->base.kind) {
case EXPR_BINARY_BITWISE_OR: fputs("|", out); break;
case EXPR_BINARY_BITWISE_AND: fputs("&", out); break;
@@
-291,34
+299,37
@@
static void write_binary_expression(const binary_expression_t *expression)
default:
panic("unimplemented binexpr");
}
default:
panic("unimplemented binexpr");
}
+ fputc(' ', out);
write_expression(expression->right);
fputs(")", out);
}
write_expression(expression->right);
fputs(")", out);
}
+static void write_integer(const literal_expression_t *literal)
+{
+ for (const char *c = literal->value.begin; c != literal->suffix; ++c) {
+ fputc(*c, out);
+ }
+}
+
static void write_expression(const expression_t *expression)
{
static void write_expression(const expression_t *expression)
{
- const const_expression_t *constant;
/* TODO */
switch(expression->kind) {
/* 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:
+ write_integer(&expression->literal);
break;
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;
}
/* 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;
write_unary_expression(&expression->unary);
break;
- EXPR_BINARY_CASES
+ case EXPR_BINARY_CASES:
write_binary_expression(&expression->binary);
break;
default:
write_binary_expression(&expression->binary);
break;
default:
@@
-358,23
+369,29
@@
static void write_enum(const symbol_t *symbol, const enum_t *entity)
}
}
fprintf(out, "\t\tpublic final int val;\n");
}
}
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, "\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%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\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, "\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
}
#if 0
@@
-388,7
+405,7
@@
static void write_variable(const entity_t *entity)
static void write_function(const entity_t *entity)
{
static void write_function(const entity_t *entity)
{
- if (entity->function.
statement
!= NULL) {
+ if (entity->function.
body
!= NULL) {
fprintf(stderr, "Warning: can't convert function bodies (at %s)\n",
entity->base.symbol->string);
return;
fprintf(stderr, "Warning: can't convert function bodies (at %s)\n",
entity->base.symbol->string);
return;
@@
-398,21
+415,18
@@
static void write_function(const entity_t *entity)
const function_type_t *function_type
= (const function_type_t*) entity->declaration.type;
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);
type_t *return_type = skip_typeref(function_type->return_type);
write_type(return_type);
fprintf(out, " %s(", entity->base.symbol->string);
- entity_t *parameter = entity->function.parameters.entities;
-
int first = 1
;
- int n = 0;
- for( ; parameter != NULL; parameter = parameter->base.next) {
+ entity_t
*parameter = entity->function.parameters.entities;
+
separator_t sep = { "", ", " }
;
+ int
n = 0;
+ for
( ; parameter != NULL; parameter = parameter->base.next) {
assert(parameter->kind == ENTITY_PARAMETER);
assert(parameter->kind == ENTITY_PARAMETER);
- if(!first) {
- fprintf(out, ", ");
- } else {
- first = 0;
- }
+ fputs(sep_next(&sep), out);
write_type(parameter->declaration.type);
if(parameter->base.symbol != NULL) {
fprintf(out, " %s", fix_builtin_names(parameter->base.symbol->string));
write_type(parameter->declaration.type);
if(parameter->base.symbol != NULL) {
fprintf(out, " %s", fix_builtin_names(parameter->base.symbol->string));
@@
-421,16
+435,25
@@
static void write_function(const entity_t *entity)
}
}
if(function_type->variadic) {
}
}
if(function_type->variadic) {
- if(!first) {
- fprintf(out, ", ");
- } else {
- first = 0;
- }
+ fputs(sep_next(&sep), out);
fputs("Object ... args", out);
}
fprintf(out, ");\n");
}
fputs("Object ... args", out);
}
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)
{
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);
pset_new_init(&avoid_symbols);
- ast_set_output(out);
- type_set_output(out);
+ print_to_file(out);
fprintf(out, "/* WARNING: Automatically generated file */\n");
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.Native;\n", out);
- fputs("import com.sun.jna.Platform;\n", out);
fputs("import com.sun.jna.Pointer;\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? */
/* 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];
/* 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;
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);
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;
/* 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;
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 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
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;
/* 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 (entity->kind != ENTITY_FUNCTION)
continue;
- if (is_system_header(entity->base.source_position.input_name))
+ const char *input_name = entity->base.pos.input_name;
+ if (is_system_header(input_name))
continue;
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;
if (pset_new_contains(&avoid_symbols, entity->base.symbol))
continue;