/* This file is part of GCC. GCC 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 3, or (at your option) any later version. GCC 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 GCC; see the file COPYING3. If not see . */ #include "config.h" #include "system.h" #include "ansidecl.h" #include "coretypes.h" #include "opts.h" #include "tree.h" #include "gimple.h" #include "toplev.h" #include "debug.h" #include "options.h" #include "flags.h" #include "convert.h" #include "diagnostic-core.h" #include "langhooks.h" #include "langhooks-def.h" #include "target.h" #include #include #include "vec.h" #include "hashtab.h" #include "gpython.h" #include "py-dot.h" #include "py-vec.h" #include "py-tree.h" #define threshold_alloc(x) (((x)+16)*3/2) gpy_hashval_t gpy_dd_hash_string (const char * s) { const unsigned char *str = (const unsigned char *) s; gpy_hashval_t r = 0; unsigned char c; while ((c = *str++) != 0) r = r * 67 + c - 113; return r; } gpy_hash_entry_t * gpy_dd_hash_lookup_table (gpy_hash_tab_t * tbl, gpy_hashval_t h) { gpy_hash_entry_t* retval = NULL; if (tbl->array) { int size= tbl->size, idx= (h % size); gpy_hash_entry_t *array= tbl->array; while( array[idx].data ) { if( array[idx].hash == h ) break; idx++; if( idx >= size ) idx= 0; } retval= (array+idx); } else retval= NULL; return retval; } void ** gpy_dd_hash_insert (gpy_hashval_t h, void * obj, gpy_hash_tab_t *tbl) { void ** retval = NULL; gpy_hash_entry_t * entry = NULL; if (tbl->length >= tbl->size) gpy_dd_hash_grow_table (tbl); entry= gpy_dd_hash_lookup_table (tbl, h); if (entry->data) retval = &(entry->data); else { entry->data = obj; entry->hash = h; tbl->length++; } return retval; } void gpy_dd_hash_grow_table (gpy_hash_tab_t * tbl) { unsigned int prev_size= tbl->size, size= 0, i= 0; gpy_hash_entry_t *prev_array= tbl->array, *array; size = threshold_alloc( prev_size ); array = (gpy_hash_entry_t*) xcalloc( size, sizeof(gpy_hash_entry_t) ); tbl->length = 0; tbl->size= size; tbl->array= array; for ( ; isize= 0; tb->length= 0; tb->array= NULL; } bool gpy_ctx_push_decl (tree decl, const char * s, gpy_hash_tab_t * tbl) { bool retval = true; gpy_hashval_t h = 0; h = gpy_dd_hash_string (s); void ** slot = gpy_dd_hash_insert (h,decl,tbl); if (!slot) { debug ("pushed decl <%s> into context!\n", s); } else { debug ("error pushing decl <%s>!\n", s); } return retval; } tree gpy_ctx_lookup_decl (VEC(gpy_ctx_t,gc) * context, const char * s) { tree retval = NULL_TREE; gpy_hashval_t h = gpy_dd_hash_string (s); gpy_hash_tab_t * it; int i = 0, l = VEC_length (gpy_ctx_t,context); for (i = (l-1); i>=0; --i) { it = VEC_index (gpy_ctx_t, context, i); gpy_hash_entry_t * o = NULL; o = gpy_dd_hash_lookup_table (it, h); if (o) { if (o->data) { debug ("found decl <%s>!\n", s); retval = (tree) o->data; break; } } } return retval; } void __gpy_debug__ (const char * file, unsigned int lineno, const char * fmt, ...) { va_list args; fprintf( stderr, "debug: <%s:%i> -> ", file, lineno ); va_start( args, fmt ); vfprintf( stderr, fmt, args ); va_end( args ); }