static long get_offsetof_offset(const offsetof_expression_t *expression) { type_t *orig_type = expression->type; long offset = 0; designator_t *designator = expression->designator; for ( ; designator != NULL; designator = designator->next) { type_t *type = skip_typeref(orig_type); if (designator->symbol != NULL) { assert(is_type_compound(type)); symbol_t *symbol = designator->symbol; compound_t *compound = type->compound.compound; entity_t *iter = compound->members.first_entity; for (; iter->base.symbol != symbol; iter = iter->base.next) {} assert(iter->kind == ENTITY_COMPOUND_MEMBER); offset += iter->compound_member.offset; orig_type = iter->declaration.type; } else { expression_t *array_index = designator->array_index; assert(designator->array_index != NULL); assert(is_type_array(type)); long index_long = fold_expression_to_int(array_index); type_t *element_type = type->array.element_type; long element_size = get_type_size(element_type); /* TODO: check for overflow */ offset += index_long * element_size; orig_type = type->array.element_type; } } return offset; }
void write_jna_decls(FILE *output, const translation_unit_t *unit) { out = output; global_scope = &unit->scope; pset_new_init(&avoid_symbols); print_to_file(out); fprintf(out, "/* WARNING: Automatically generated file */\n"); fputs("import com.sun.jna.Native;\n", out); 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); 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) { for (;;) { char buf[1024]; 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; char *str = malloc(len+1); memcpy(str, buf, len+1); symbol_t *symbol = symbol_table_insert(str); pset_new_insert(&avoid_symbols, symbol); } fclose(avoid); } /* write structs,unions + enums */ entity_t *entity = unit->scope.entities; for ( ; entity != NULL; entity = entity->base.next) { if (entity->kind == ENTITY_ENUM) { if (find_enum_typedef(&entity->enume) != NULL) continue; write_enum(entity->base.symbol, &entity->enume); } else if (entity->kind == ENTITY_TYPEDEF) { type_t *type = entity->declaration.type; if (type->kind == TYPE_ENUM) { write_enum(entity->base.symbol, type->enumt.enume); } } #if 0 if (is_type_compound(type)) { write_compound(entity->base.symbol, &type->compound); } #endif } /* write functions */ entity = unit->scope.entities; for ( ; entity != NULL; entity = entity->base.next) { if (entity->kind != ENTITY_FUNCTION) continue; 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; write_function(entity); } fputs("}\n", out); pset_new_destroy(&avoid_symbols); }