#include #include #include #include #include "host.h" #include "ansi.h" #include "files.h" #include "units.h" #include "allocate.h" #include "vendor.h" #include "config.h" extern int auto_package; #undef NULL #define NULL 0 /* from limits.h */ #ifndef PATH_MAX #define PATH_MAX 1024 #endif #ifndef MAX_NEST #define MAX_NEST 64 /* Arbitrary limit */ #endif FILE *cur_unit_fd; static ada_unit_t *table[MAX_UNIQ_FNAMES]; static int cur_unit; static int nesting_table[MAX_NEST]; static int nest_level; int current_unit() { if (! auto_package) return 0; assert(cur_unit < num_files()); return cur_unit; } static void set_reference(ref, ord) unit_ref_t ref; int ord; { int index; int bit; index = ord / BITS_PER_INT; assert(index < UNIT_SET_SIZE); bit = 1 << (ord % BITS_PER_INT); ref[index] |= bit; } static void clear_reference(ref, ord) unit_ref_t ref; int ord; { int index; int bit; index = ord / BITS_PER_INT; assert(index < UNIT_SET_SIZE); bit = 1 << (ord % BITS_PER_INT); ref[index] &= ~bit; } static int is_referenced(ref, ord) unit_ref_t ref; int ord; { int index; int bit; index = ord / BITS_PER_INT; assert(index < UNIT_SET_SIZE); bit = 1 << (ord % BITS_PER_INT); return (ref[index] & bit) != 0; } static void ref_merge(r1, r2) unit_ref_t r1, r2; { int i; for (i = 0; i < UNIT_SET_SIZE; i++) { r1[i] |= r2[i]; } } static void merge_direct_refs() { ada_unit_t *unit, *ref; int last, i, j; if (! auto_package) return; last = num_files(); for (i = 0; i < last; i++) { unit = table[i]; assert(unit != NULL); for (j = 0; j < last; j++) { if (j != i && is_referenced(unit->direct_ref, j)) { ref = table[j]; assert(ref != NULL); ref_merge(unit->direct_ref, ref->direct_ref); } } /* Don't let unit "i" reference itself */ clear_reference(unit->direct_ref, i); clear_reference(unit->unit_ref, i); } } static void merge_refs() { ada_unit_t *unit, *ref; int last, i, j; if (! auto_package) return; last = num_files(); for (i = 0; i < last; i++) { unit = table[i]; assert(unit != NULL); for (j = 0; j < last; j++) { if (j != i && is_referenced(unit->unit_ref, j)) { ref = table[j]; assert(ref != NULL); ref_merge(unit->unit_ref, ref->unit_ref); } } /* Don't let unit "i" reference itself */ clear_reference(unit->direct_ref, i); clear_reference(unit->unit_ref, i); } } void unit_start_gen() { cur_unit_fd = stdout; #if 0 merge_direct_refs(); #else merge_refs(); #endif } static char* gen_unit_name(path) char *path; { char buf[PATH_MAX]; char res[PATH_MAX]; char *p; if (!strncmp(path, "/usr/include/", 13)) { p = buf; path = &path[13]; } else { char *last = path; char *s; for (s = path; *s; s++) { if (*s == '/') { last = s; } } path = last; p = buf; } for (; *path; path++) { switch (*path) { case '.': #ifdef HEADER_POSTFIX if (path[1] == 'h' && path[2] == 0) { strcpy(p, HEADER_POSTFIX); path++; break; } #endif case '/': *p++ = '_'; break; default: *p++ = *path; break; } } *p = 0; make_ada_identifier(buf, res); return new_string(res); } static void initialize_unit(ord) int ord; { char buf[PATH_MAX]; ada_unit_t *unit; assert(table[ord] == NULL); unit = allocate(sizeof(ada_unit_t)); unit->src_path = file_name_from_ord(ord); assert(unit->src_path != NULL); unit->unit_name = gen_unit_name(unit->src_path); assert(unit->unit_name != NULL); strcpy(buf, "bindings/"); strcat(buf, unit->unit_name); switch (ada_compiler) { case GNAT: strcat(buf, ".ads"); break; case VADS: strcat(buf, ".a"); break; case Rational: strcat(buf, ".1.ada"); break; default: strcat(buf, ".ada"); break; } unit->unit_path = new_string(buf); unit->initialized = 1; table[ord] = unit; } static void dump_unit(ord) int ord; { ada_unit_t *unit; unit = table[ord]; assert(unit != NULL); printf("unit %d\n", ord); printf("\tsrc = %s\n", unit->src_path); printf("\tname = %s\n", unit->unit_name); printf("\tpath = %s\n", unit->unit_path); fflush(stdout); } void unit_included(pos, nest) file_pos_t pos; int nest; { ada_unit_t *unit; int ord; int uord; if (! auto_package) return; if (nest < 1) return; if (nest >= MAX_NEST) return; ord = FILE_ORD(pos); if (nest > nest_level) { uord = nesting_table[nest_level]; unit = table[uord]; assert(unit != NULL); set_reference(unit->direct_ref, ord); set_reference(unit->unit_ref, ord); } nest_level = nest; nesting_table[nest] = ord; } void init_unit(pos) file_pos_t pos; { int ord; if (! auto_package) return; ord = FILE_ORD(pos); if (table[ord] == NULL) { initialize_unit(ord); } } int set_unit(ord) int ord; { ada_unit_t *unit; if (! auto_package) return 0; assert(ord < num_files()); unit = table[ord]; assert(unit != NULL); mkdir("bindings", 0777); cur_unit = ord; cur_unit_fd = fopen(unit->unit_path, "w"); if (cur_unit_fd == NULL) { syserr(unit->unit_path, 0); return 1; } inform(0, 0, "Generating %s", unit->unit_path); return 0; } void unit_completed() { if (auto_package) { fclose(cur_unit_fd); cur_unit = MAX_UNIQ_FNAMES + 1; } } void unit_dependency(ord, dep) int ord, dep; { ada_unit_t *unit; int last; if (! auto_package) return; last = num_files(); assert(ord >= 0 && ord < last); assert(dep >= 0 && dep < last); unit = table[ord]; assert(unit != NULL); set_reference(unit->unit_ref, dep); } char* unit_name(ord) int ord; { ada_unit_t *unit; if (! auto_package) return "y"; assert(ord < num_files()); unit = table[ord]; assert(unit != NULL); assert(unit->unit_name != NULL); return unit->unit_name; } char* include_path(ord) int ord; { ada_unit_t *unit; if (! auto_package) return NULL; assert(ord < num_files()); unit = table[ord]; assert(unit != NULL); assert(unit->src_path != NULL); return unit->src_path; } char* cur_unit_name() { return unit_name(current_unit()); } char* cur_unit_source() { ada_unit_t *unit; int ord; if (! auto_package) return NULL; ord = current_unit(); assert(ord < num_files()); unit = table[ord]; assert(unit != NULL); assert(unit->src_path != NULL); return unit->src_path; } char* cur_unit_path() { ada_unit_t *unit; int ord; if (! auto_package) return NULL; ord = current_unit(); assert(ord < num_files()); unit = table[ord]; assert(unit != NULL); assert(unit->unit_path != NULL); return unit->unit_path; } int nth_ref_unit_ord(n) int n; { ada_unit_t *unit; int count, i, last; if (auto_package) { unit = table[current_unit()]; assert(unit != NULL); last = num_files(); for (count = 0, i = 0; i < last; i++) { if (is_referenced(unit->unit_ref, i)) { if (count == n) { return i; } count++; } } } return -1; } int nth_direct_ref_unit_ord(n) int n; { ada_unit_t *unit; int count, i, last; int cur; if (auto_package) { cur = current_unit(); unit = table[cur]; assert(unit != NULL); last = num_files(); for (count = 0, i = 0; i < last; i++) { if (cur != i && is_referenced(unit->direct_ref, i)) { if (count == n) { return i; } count++; } } } return -1; }