/* * Jast Another Symbol Table * Copyright (c) 2012 Guillermo Ramos GutiƩrrez <0xwille@gmail.com> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of copyright holders nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include "doll.h" #include "jast.h" #define MIN(m,n) ((m) < (n) ? (m) : (n)) #define MAX(m,n) ((m) > (n) ? (m) : (n)) static struct doll *tables; static long uniq_count = 1; static char *__jast_alloc_string(char *s) { int copylen = MIN(JAST_MAX_NAMELEN, strlen(s)); char *copy = malloc((copylen+1) * sizeof(char)); strncpy(copy, s, copylen); copy[copylen] = '\0'; return copy; } struct jast *jast_creat(char *name) { struct jast *new_tab = malloc(sizeof(struct jast)); if (name) { new_tab->name = __jast_alloc_string(name); } else { int len = sizeof(char *)+12; // 12 == length of "[jast@0x]\0" new_tab->name = malloc(len); snprintf(new_tab->name, len, "[jast@%p]", (void *)new_tab); } new_tab->entries = doll_new(); new_tab->children = doll_new(); if (tables == NULL) tables = doll_new(); doll_append(tables, new_tab); return new_tab; } void jast_destroy(struct jast *tab) { // TODO comprobar que tab existe struct jast_entry *entry; doll_foreach(entry, tab->entries) { free(entry->name); free(entry->uniq); } doll_remove(tables, tab); doll_destroy(tab->entries); doll_destroy(tab->children); free(tab->name); free(tab); } void jast_destroy_all(void) { struct jast *tab; doll_foreach(tab, tables) jast_destroy(tab); } char *jast_uniq(char *begin) { long varlen = strlen(begin) + ceill(log10(uniq_count)+1) + 1; char *uniqname = malloc(varlen * sizeof(char)); snprintf(uniqname, varlen, "%s%ld", begin, uniq_count++); return uniqname; } struct jast_entry *jast_new_entry(struct jast *tab, char *name) { struct jast_entry *new; if (name == NULL || (new = malloc(sizeof(struct jast_entry))) == NULL) return NULL; new->name = __jast_alloc_string(name); new->uniq = jast_uniq("jast_var_"); new->tmp = 0; new->type = JAST_UNDEF_T; new->datatype = JAST_UNDEF_D; new->datasize = 0; new->attribs = NULL; if (tab->entries == NULL) tab->entries = doll_new(); doll_append(tab->entries, new); return new; } struct jast_entry *jast_get_entry(struct jast *tab, char *name) { struct jast_entry *entry; doll_foreach(entry, tab->entries) if (!strcmp(entry->name, name)) return entry; return NULL; } // TODO usar get_entry enum jast_entry_t jast_entry_gettype(struct jast *tab, char *name) { struct jast_entry *entry; doll_foreach(entry, tab->entries) if (!strcmp(entry->name, name)) return entry->type; return JAST_ERR; } void jast_entry_settype(struct jast *tab, char *name, enum jast_entry_t type) { struct jast_entry *entry; doll_foreach(entry, tab->entries) if (!strcmp(entry->name, name)) entry->type = type; // struct jast_entry *entry = doll_find(tab->entries, name); // if (entry) // entry->type = type; } enum jast_data_t jast_entry_getdatatype(struct jast *tab, char *name) { struct jast_entry *entry; doll_foreach(entry, tab->entries) if (!strcmp(entry->name, name)) return entry->datatype; return JAST_ERR; } void jast_entry_setdatatype(struct jast *tab, char *name, enum jast_data_t type) { struct jast_entry *entry; doll_foreach(entry, tab->entries) if (!strcmp(entry->name, name)) entry->datatype = type; } inline void __jast_dump_n_spaces(int spaces, FILE *f) { while (spaces--) putc(' ', f); } int jast_dump(struct jast *tab, char *filename) { struct jast_entry *entry; int i; char *entry_type, *data_type; FILE *f = fopen(filename, "w"); char *cols[] = {"name", "type", "data type", "uniq", "data size"}; int ncols = sizeof(cols)/sizeof(cols[0]); unsigned collen[ncols]; unsigned colnamelen[ncols]; int totallen = (ncols*3)+1; if (f == NULL || tab == NULL) // TODO quitar (puesto por warnings) return -1; for (i = 0; i < ncols; i++) collen[i] = colnamelen[i] = strlen(cols[i]); doll_foreach(entry, tab->entries) { __jast_strentry(entry->type, entry_type); __jast_strdata(entry->datatype, data_type); collen[0] = MAX(collen[0], strlen(entry->name)); collen[1] = MAX(collen[1], strlen(entry_type)); collen[2] = MAX(collen[2], strlen(data_type)); collen[3] = MAX(collen[3], strlen(entry->uniq)); collen[4] = MAX(collen[4], log10(entry->datasize/10) + 2); } for (i = 0; i < ncols; i++) totallen += collen[i]; char interline[totallen - 1]; memset(interline, '-', totallen-2); interline[totallen-2] = '\0'; fprintf(f, "\n /==# %s (parent: %s)\n", tab->name, tab->parent ? tab->parent->name : "none"); fprintf(f, "/%s\\\n|", interline); for (i = 0; i < ncols; i++) { __jast_dump_n_spaces(collen[i]-colnamelen[i]+1, f); fprintf(f, "%s |", cols[i]); } fprintf(f, "\n|%s|\n", interline); doll_foreach(entry, tab->entries) { putc('|', f); __jast_strentry(entry->type, entry_type); __jast_strdata(entry->datatype, data_type); __jast_dump_n_spaces(collen[0]-strlen(entry->name)+1, f); fprintf(f, "%s |", entry->name); __jast_dump_n_spaces(collen[1]-strlen(entry_type)+1, f); fprintf(f, "%s |", entry_type); __jast_dump_n_spaces(collen[2]-strlen(data_type)+1, f); fprintf(f, "%s |", data_type); __jast_dump_n_spaces(collen[3]-strlen(entry->uniq)+1, f); fprintf(f, "%s |", entry->uniq); __jast_dump_n_spaces(collen[4]-log10(entry->datasize/10+3), f); fprintf(f, "%dB |\n", entry->datasize); } fprintf(f, "\\%s/\n\n", interline); fclose(f); return 0; } void jast_show_all(void) { struct jast *t; printf("\n-----------------------\n"); doll_foreach(t, tables) printf("%s\n", t->name); printf("-----------------------\n"); }