/*
* This file is part of cparser.
- * Copyright (C) 2007-2009 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
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * Copyright (C) 2012 Matthias Braun <matze@braunis.de>
*/
#include <config.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.h"
#include "printer.h"
#include "adt/error.h"
-#include <libfirm/adt/pset_new.h>
+#include "adt/xmalloc.h"
+#include "adt/pset_new.h"
+#include "separator_t.h"
+#include "symbol_table.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 bool is_system_header(const char *fname)
-{
- if (strncmp(fname, "/usr/include", 12) == 0)
- return true;
- if (fname == builtin_source_position.input_name)
- return true;
- return false;
-}
+static output_limit *output_limits;
+static const char *libname;
static const char *fix_builtin_names(const char *name)
{
- if (strcmp(name, "class") == 0) {
- return "_class";
- } else if(strcmp(name, "this") == 0) {
- return "_this";
- } else if(strcmp(name, "public") == 0) {
- return "_public";
- } else if(strcmp(name, "protected") == 0) {
- return "_protected";
- } else if(strcmp(name, "private") == 0) {
- return "_private";
- } else if(strcmp(name, "final") == 0) {
- return "_final";
- }
+#define FIX(x) if (streq(name, x)) return "_" x
+ FIX("class");
+ FIX("final");
+ FIX("private");
+ FIX("protected");
+ FIX("public");
+ FIX("this");
/* TODO put all reserved names here */
+#undef FIX
return name;
}
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 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");
+ panic("invalid type");
case TYPE_ARRAY:
- case TYPE_BITFIELD:
case TYPE_REFERENCE:
case TYPE_FUNCTION:
case TYPE_COMPLEX:
case EXPR_UNARY_NOT:
fputc('!', out);
break;
- case EXPR_UNARY_CAST_IMPLICIT:
+ case EXPR_UNARY_CAST:
write_expression(expression->value);
return;
default:
- panic("unimeplemented unary expression found");
+ panic("unimplemented unary expression");
}
write_expression(expression->value);
}
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)
{
/* TODO */
switch(expression->kind) {
case EXPR_LITERAL_INTEGER:
- case EXPR_LITERAL_INTEGER_OCTAL:
- fprintf(out, "%s", expression->literal.value.begin);
+ write_integer(&expression->literal);
break;
- case EXPR_LITERAL_INTEGER_HEXADECIMAL:
- fprintf(out, "0x%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:
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;
write_type(return_type);
fprintf(out, " %s(", entity->base.symbol->string);
- entity_t *parameter = entity->function.parameters.entities;
- int first = 1;
- int n = 0;
+ 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);
- 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));
}
}
if(function_type->variadic) {
- if(!first) {
- fprintf(out, ", ");
- } else {
- first = 0;
- }
+ fputs(sep_next(&sep), out);
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)
{
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);
/* read the avoid list */
FILE *avoid = fopen("avoid.config", "r");
if (avoid != NULL) {
- while (!feof(avoid)) {
+ for (;;) {
char buf[1024];
char *res = fgets(buf, sizeof(buf), avoid);
if (res == NULL)
}
#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
for ( ; entity != NULL; entity = entity->base.next) {
if (entity->kind != ENTITY_FUNCTION)
continue;
- if (is_system_header(entity->base.source_position.input_name))
+ if (entity->base.pos.is_system_header)
+ continue;
+ if (entity->function.elf_visibility != ELF_VISIBILITY_DEFAULT)
continue;
+ if (output_limits != NULL) {
+ bool in_limits = false;
+ char const *const input_name = entity->base.pos.input_name;
+ 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;