static void grow_ptr_vec (PTR_VEC * vec) { int new_max_elems; void **new_elems; new_max_elems = vec->max_elems + vec->chunk_size; if (vec->elems == vec->inline_elems) { new_elems = (void **) pp_malloc (sizeof (vec->elems[0]) * new_max_elems); memcpy ((char *) new_elems, (char *) vec->elems, sizeof (vec->elems[0]) * vec->n_elems); } else { new_elems = (void **) realloc (vec->elems, sizeof (vec->elems[0]) * new_max_elems); } if (new_elems == NULL) { esql_yyverror (pp_get_msg (EX_MISC_SET, MSG_OUT_OF_MEMORY)); exit (1); } vec->elems = new_elems; vec->max_elems = new_max_elems; }
/* * pp_new_ptr_vec() - Create a new counted vector, and initialize it as empty. * return : PTR_VEC * * vec(in): The address of a PTR_VEC structure to be initialized, or NULL. */ PTR_VEC * pp_new_ptr_vec (PTR_VEC * vec) { if (vec == NULL) { vec = malloc (sizeof (PTR_VEC)); if (vec == NULL) { esql_yyverror (pp_get_msg (EX_MISC_SET, MSG_OUT_OF_MEMORY)); exit (1); return NULL; } vec->heap_allocated = TRUE; } else { vec->heap_allocated = FALSE; } vec->n_elems = 0; vec->max_elems = DIM (vec->inline_elems); vec->elems = vec->inline_elems; vec->chunk_size = PTR_VEC_CHUNK_SIZE; return vec; }
/* * pp_new_cursor() - Allocate (and enter in pp_cursor_table) a new CURSOR * struct, initializing it with the given name and initialize the static * and dynamic fields accordingly. * return : CURSOR * * name(in): A character string. * static_stmt(in): A prepared SQL/X SELECT statement, or NULL. * length(in) : * dynamic_stmt(in): A STMT pointer, or NULL. * host_refs(in): */ CURSOR * pp_new_cursor (char *name, char *static_stmt, int length, STMT * dynamic_stmt, HOST_LOD * host_refs) { CURSOR *cursor; cursor = pp_lookup_cursor (name); if (cursor && cursor->level >= pp_nesting_level) { esql_yyverror (pp_get_msg (EX_CURSOR_SET, MSG_REDEFINITION), cursor->name); return NULL; } cursor = es_ht_alloc_new_symbol (sizeof (CURSOR)); cursor->name = (unsigned char *) strdup (name); cursor->cid = next_cid++; cursor->level = pp_nesting_level; cursor->next = NULL; cursor->host_refs = host_refs; cursor->static_stmt = (unsigned char *) (static_stmt ? strdup (static_stmt) : NULL); cursor->stmtLength = length; cursor->dynamic_stmt = dynamic_stmt; pp_cursor_table->add_symbol (pp_cursor_table, cursor); pp_add_cursor_to_scope (cursor); return cursor; }
/* * pp_print_cursor() - Dump a printed representation of the cursor structure * to the designated stream. * return : nothing * cursor(in): A pointer to a cursor to be printed. * fp(in): The stream to print it on. */ static void pp_print_cursor (void *cp, void *fp) { CURSOR *cursor = (CURSOR *) cp; FILE *stream = (FILE *) fp; fprintf (stream, " * %s (cid %d, level %d):\n", cursor->name, cursor->cid, cursor->level); if (cursor->static_stmt) { int i; fprintf (stream, " *\t%s\n", cursor->static_stmt); if (cursor->host_refs) { for (i = 0; i < cursor->host_refs->n_refs; ++i) { fprintf (stream, " *\thv[%d]: ", i); pp_print_host_ref (&cursor->host_refs->refs[i], stream); fputs ("\n", stream); } } } else fprintf (stream, pp_get_msg (EX_CURSOR_SET, MSG_STMT_TITLE), cursor->dynamic_stmt->name); fputs (" *\n", stream); }
/* * es_write_log() - write log message to file * return: void * fname(in) : log file name to write * msg(in) : message string */ static void es_write_log (const char *fname, const char *msg) { char *msg_copy; /* We have to copy the message in case it came from pp_get_msg(). */ msg_copy = pp_strdup (msg); fprintf (stderr, pp_get_msg (EX_HASH_SET, MSG_INTERNAL_ERROR), fname, msg_copy); free_and_init (msg_copy); }
/* * pp_malloc() - Safe malloc. prints a message and exits if no memory. * return : void * * int(in): number of bytes needed */ void * pp_malloc (int n) { char *tmp; tmp = malloc (n); if (tmp == NULL) { fprintf (stderr, "%s: %s\n", prog_name, pp_get_msg (EX_MISC_SET, MSG_OUT_OF_MEMORY)); exit (1); } return tmp; }
/* * pp_print_cursors() - Print a representation of every declared cursor * on the given stream. * return : void * fp(in): The stream on which to print the contents of the cursor table. */ void pp_print_cursors (FILE * fp) { if (!fp) { fp = stdout; } if (pp_cursor_table->get_symbol_count (pp_cursor_table)) { fputs (pp_get_msg (EX_CURSOR_SET, MSG_TABLE_TITLE), fp); pp_cursor_table->print_table (pp_cursor_table, pp_print_cursor, fp, 1); } }
/* * pp_set_class_bit() - Change the class of the specifier pointed to by p * as indicated by storage_class. * return : void * storage_class(in): The new storage class for the specifier p. * p(out): The specifier to be changed. * note :The TYPEDEF class is used here only to remember that the input * storage class was a typedef. */ static void pp_set_class_bit (int storage_class, LINK * p) { switch (storage_class) { case 0: { p->decl.s.sclass = C_FIXED; p->decl.s.is_static = 0; p->decl.s.is_extern = 0; p->decl.s.is_const = 0; p->decl.s.is_volatile = 0; } break; case TYPEDEF_: p->decl.s.sclass = C_TYPEDEF; break; case REGISTER_: p->decl.s.is_register = 1; break; case AUTO_: p->decl.s.is_auto = 1; break; case EXTERN_: p->decl.s.is_extern = 1; break; case STATIC_: p->decl.s.is_static = 1; break; default: { esql_yyverror (pp_get_msg (EX_DECL_SET, MSG_BAD_STORAGE_CLASS), storage_class); exit (1); } break; } }
/* * pp_add_spec_to_decl() - Add the specifier to each of the declarators in * decl_chain. This is accomplished by cloning p_spec and then tacking it * onto the end of every declaration chain in decl_chain. * return : void * p_spec(in): A pointer to a specifier/declarator chain created by a previous * typedef, or to a single specifier. It is cloned and then tacked onto * the end of every declaration chain in the list pointed to by decl_chain. * decl_chain(out): A chain of declarators, each of which is to receive the * p_spec specifier. */ void pp_add_spec_to_decl (LINK * p_spec, SYMBOL * decl_chain) { LINK *clone_start, *clone_end; for (; decl_chain; decl_chain = decl_chain->next) { clone_start = pp_clone_type (p_spec, &clone_end); if (clone_start == NULL) { esql_yyverror (pp_get_msg (EX_DECL_SET, MSG_MALFORMED_CHAIN)); exit (1); } if (IS_PSEUDO_TYPE (clone_start) && clone_start->decl.s.val.v_struct == NULL) { LINK *old_etype; char tmp[32]; old_etype = decl_chain->etype; if (old_etype == NULL || (IS_VAR_TYPE (clone_start) && IS_ARRAY (old_etype) == 0)) { esql_yyverror (pp_get_msg (EX_DECL_SET, MSG_BAD_PSEUDO_DECL), pp_type_str (clone_start)); exit (1); } clone_start->decl.s.val.v_struct = pp_new_pseudo_def (clone_start->decl.s.noun, old_etype->decl.d.num_ele); if (clone_start->decl.s.noun == N_VARCHAR) { sprintf (tmp, " = { %s, \"\" }", old_etype->decl.d.num_ele); } else { sprintf (tmp, " = { ((%s)+7)/8, \"\" }", old_etype->decl.d.num_ele); } decl_chain->args = pp_new_symbol (tmp, decl_chain->level); pp_discard_link (old_etype); if (decl_chain->type == old_etype) { decl_chain->type = NULL; } else { LINK *parent; for (parent = decl_chain->type; parent->next != old_etype; parent = parent->next) { ; } parent->next = NULL; decl_chain->etype = parent; } } if (decl_chain->type == NULL) /* No declarators */ { decl_chain->type = clone_start; } else { decl_chain->etype->next = clone_start; } decl_chain->etype = clone_end; /* * If the declaration we're looking at is really a typedef, * record the symbol itself within the specifier. This will * make it easier to point back to the symbol from other * declarations, which will make it easier to print out * later declarations using the typedef name rather than its * expansion. */ if (IS_TYPEDEF (clone_end)) { pp_set_class_bit (0, clone_end); decl_chain->type->tdef = decl_chain; decl_chain->type->from_tdef = decl_chain; } } }
/* * es_ht_print_table() - This function prints the table with given * print function. * return : 0 if a sorted table can't be printed because of insufficient * memory, else return 1 if the table was printed. * table(in): The hash table to be printed. * print(in): The function used to print a symbol. * param(in): Parameter passed to the print function. * sort(in): TRUE if the table should be sorted. * * note : The print function is called with two arguments: * (*print)(sym, param) * 'sym' is a pointer to a BUCKET user area, and 'param' is the * third argument to ptab(). */ static int es_ht_print_table (HASH_TAB * table, void (*print) (), void *param, int sort) { BUCKET **outtab, **outp, *sym, **symtab; int i; HASH_TAB_IMPL *tbl = (HASH_TAB_IMPL *) table; if (tbl == NULL || tbl->size == 0) /* Table is empty */ { return 1; } if (!sort) { for (symtab = tbl->table, i = tbl->size; --i >= 0; ++symtab) { /* * Print all symbols in the current chain. The +1 in the * print call adjusts the bucket pointer to point to the user * area of the bucket. */ for (sym = *symtab; sym; sym = sym->next) { (*print) (sym + 1, param); } } } else { /* * Allocate enough memory for 'outtab', an array of pointers to * BUCKETs, and initialize it. 'outtab' is different from the * actual hash table in that every 'outtab' element points to a * single BUCKET structure, rather than to a linked list of them. * * Go ahead and just use malloc() here; it's not a terrible * problem if we can't get enough memory. */ outtab = (BUCKET **) pp_malloc (tbl->numsyms * sizeof (BUCKET *)); outp = outtab; for (symtab = tbl->table, i = tbl->size; --i >= 0; ++symtab) { for (sym = *symtab; sym; sym = sym->next) { if (outp > outtab + tbl->numsyms) { es_write_log ("es_ht_print_table", pp_get_msg (EX_HASH_SET, MSG_TABLE_OVERFLOW)); free_and_init (outtab); return 0; } *outp++ = sym; } } /* * Sort 'outtab' and then print it. */ es_User_cmp = tbl->cmp; qsort (outtab, tbl->numsyms, sizeof (BUCKET *), es_symcmp); for (outp = outtab, i = tbl->numsyms; --i >= 0; ++outp) { (*print) ((*outp) + 1, param); } free_and_init (outtab); } return 1; }