/* * The routines here generate legal Ada identifiers from * C identifiers. All the klugy unique name munging is * done here as well */ #include #include "ansi.h" #include "config.h" #include "host.h" #include "allocate.h" #include "ada_name.h" #include "hash.h" #include "files.h" #include "il.h" extern int auto_package; #undef NULL #define NULL 0 #define HTAB 512 /* unique name hash table size */ /* * Unique name hash table node type */ typedef struct uniq_name_t { char *uname; int uord; hash_t uhash; struct uniq_name_t *ulink; } uniq_name_t; static uniq_name_t *hash_table[HTAB]; /* * allocator for unique name hash table nodes */ static uniq_name_t* new_uniq_name() { static uniq_name_t *free = NULL; static int free_index; if (free == NULL || free_index > 63) { free = (uniq_name_t*) allocate(sizeof(uniq_name_t) * 64); free_index = 0; } return &free[free_index++]; } /* * Function to determine if a name is an Ada83 keyword */ int is_ada_keyword(name) char *name; { #ifdef PUBLIC struct resword {char *name; short token;}; extern struct resword *ada_rsvd(); struct resword *r; #endif char buf[16]; char *p; assert(name != NULL); if (strlen(name) > 9) { return 0; } for (p = buf; *name; name++) { *p++ = lcase(*name); } *p = 0; #ifdef PUBLIC return ada_rsvd(buf, p-buf) != NULL; #else return ada_rsvd(buf) != -1; #endif } /* * Function to generate a legal Ada83 identifier */ void make_ada_identifier(name, buf) char *name, *buf; { assert(name != NULL); assert(buf != NULL); while (*name == '_' || *name == '$') { name++; } if (*name == 0) { strcpy(buf, "YIKES"); } while (*name) { switch (*name) { case '$': name++; break; case '_': if (name[1] != '_' && name[1] != 0) { *buf++ = *name; } name++; break; default: *buf++ = *name++; break; } } *buf = 0; } /* * Function to determine if an identifier has already * been used. */ static uniq_name_t* find_uniq(name, unit) char *name; int unit; { uniq_name_t *un; hash_t hash; int index; hash = lcase_hash(name); index = hash & (HTAB-1); if (!auto_package) { unit = 0; } for (un = hash_table[index]; un; un = un->ulink) { if (un->uord == unit && un->uhash == hash && !lcasecmp(un->uname, name)) { return un; } } return NULL; } int is_uniq_name(name, unit) char *name; int unit; { assert(name != NULL); return find_uniq(name,unit) == NULL; } char* uniq_name(name, unit) char *name; int unit; { char buf[2048]; uniq_name_t *un; int index, i, j, k; int last; strcpy(buf, name); if (find_uniq(name, unit) == NULL) { goto done; } strcat(buf, "_c"); last = strlen(buf); buf[last+1] = 0; for (i = '0'; i <= '9'; i++) { buf[last] = i; if (find_uniq(buf) == NULL) { goto done; } } buf[last+2] = 0; for (i = '0'; i <= '9'; i++) { buf[last] = i; for (j = '0'; j <= '9'; j++) { buf[last+1] = j; if (find_uniq(buf) == NULL) { goto done; } } } buf[last+3] = 0; for (i = '0'; i <= '9'; i++) { buf[last] = i; for (j = '0'; j <= '9'; j++) { buf[last+1] = j; for (k = '0'; k <= '9'; k++) { buf[last+2] = k; if (find_uniq(buf) == NULL) { goto done; } } } } assert(0); done: un = new_uniq_name(); un->uname = new_string(buf); un->uhash = common_hash(buf); un->uord = (auto_package) ? unit : 0; index = un->uhash & (HTAB-1); un->ulink = hash_table[index]; hash_table[index] = un; return un->uname; } /* * I do a half-hearted attempt at preserving the case * of the original C identifier. This is done so that * SIGINT doesn't turn into sigint. */ ident_case_t id_case(id) char *id; { if (id[0] >= 'A' && id[0] <= 'Z') { if (id[1] >= 'A' && id[1] <= 'Z') { return Upper; } return Cap; } return Lower; } static void uppercase(id) char *id; { char c; for (; *id; id++) { c = *id; if (c >= 'a' && c <= 'z') { *id = 'A' + (c - 'a'); } } } static void capitalize(id) char *id; { char *prev; char c; for (prev = id; *id; id++) { if (*id == '_') { c = *prev; if (c >= 'a' && c <= 'z') { *prev = 'A' + (c - 'a'); } prev = id + 1; } } } void id_format(id, icase) char *id; ident_case_t icase; { switch (icase) { case Upper: uppercase(id); break; case Cap: capitalize(id); break; } } char* ada_name(name, unit) char *name; int unit; { char buf[2048]; char *p; ident_case_t icase; for (; *name == '_'; name++); if (*name == 0) { name = "YIKES"; } if (is_ada_keyword(name)) { icase = id_case(name); strcpy(buf, ADA_RESERVED_PREFIX); strcat(buf, name); } else { switch (name[0]) { case ENUM_PREFIX: strcpy(buf, ENUM_TYPE_PREFIX); name++; break; case STRUCT_PREFIX: strcpy(buf, STRUCT_TYPE_PREFIX); name++; break; case UNION_PREFIX: strcpy(buf, UNION_TYPE_PREFIX); name++; break; default: buf[0] = 0; break; } icase = id_case(name); for (p = buf; *p; p++); make_ada_identifier(name, p); } if (unit == -1) { p = new_string(buf); } else { p = uniq_name(buf, unit); } id_format(p, icase); return p; }