/* * parser_free_parser() - clean up all parse structures after they are through * being used. Values which need to be persistent, should have been * copied by now * return: * parser(in): */ void parser_free_parser (PARSER_CONTEXT * parser) { assert (parser != NULL); /* free string blocks */ pt_free_string_blocks (parser); /* free node blocks */ pt_free_node_blocks (parser); pt_unregister_parser (parser); if (parser->error_buffer) free ((char *) parser->error_buffer); if (parser->host_variables) { DB_VALUE *hv; int i; for (i = 0, hv = parser->host_variables; i < parser->host_var_count + parser->auto_param_count; i++, hv++) db_value_clear (hv); free_and_init (parser->host_variables); } parser_free_lcks_classes (parser); free_and_init (parser); }
/* * bit_to_string() - convert bit value to string * return: formatted string * value(in): bit value to convert */ static char * bit_to_string (DB_VALUE * value, char string_delimiter, bool plain_string) { char *temp_string; char *return_string; int max_length; /* * Allocate string length based on precision plus the the leading * introducer plus quotes, and NULL terminator. Precision / 4 (rounded up) * represents the number of bytes needed to represent the bit string in * hexadecimal. */ max_length = ((db_get_string_length (value) + 3) / 4) + 4; temp_string = (char *) malloc (max_length); if (temp_string == NULL) { return (NULL); } if (db_bit_string (value, "%X", temp_string, max_length) != CSQL_SUCCESS) { free_and_init (temp_string); return (NULL); /* Should never get here */ } return_string = string_to_string (temp_string, string_delimiter, 'X', strlen (temp_string), NULL, plain_string); free_and_init (temp_string); return (return_string); }
/* * cursor_free () - Free the area allocated for the cursor identifier. * return: * cursor_id(in/out): Cursor Identifier */ void cursor_free (CURSOR_ID * cursor_id_p) { int i; cursor_free_list_id (&cursor_id_p->list_id, false); if (cursor_id_p->buffer_area != NULL) { free_and_init (cursor_id_p->buffer_area); cursor_id_p->buffer_filled_size = 0; cursor_id_p->buffer = NULL; } free_and_init (cursor_id_p->tuple_record.tpl); free_and_init (cursor_id_p->oid_set); if (cursor_id_p->mop_set != NULL) { for (i = 0; i < cursor_id_p->oid_ent_count; i++) { cursor_id_p->mop_set[i] = NULL; } free_and_init (cursor_id_p->mop_set); } }
/* * pp_free_ptr_vec() - Free the internal structures used by the PTR_VEC, * and the PTR_VEC itself if it was heap-allocated. * return : void * vec(in): A pointer to a PTR_VEC, or NULL. */ void pp_free_ptr_vec (PTR_VEC * vec) { int i; if (vec == NULL) { return; } for (i = 0; i < vec->n_elems; ++i) { if (vec->elems[i]) { free_and_init (vec->elems[i]); } } if (vec->elems != vec->inline_elems) { free_and_init (vec->elems); } if (vec->heap_allocated) { free_and_init (vec); } }
/* * event_file_open - Open event log file * return: FILE * * path(in): file path */ static FILE * event_file_open (const char *path) { FILE *fp; char dir[PATH_MAX], *tpath; assert (path != NULL); tpath = strdup (path); if (tpath == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, (size_t) strlen (path)); return NULL; } while (1) { if (cub_dirname_r (tpath, dir, PATH_MAX) > 0 && access (dir, F_OK) < 0) { if (mkdir (dir, 0777) < 0 && errno == ENOENT) { free_and_init (tpath); tpath = strdup (dir); if (tpath == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, (size_t) strlen (dir)); return NULL; } continue; } } break; } free_and_init (tpath); fp = fopen (path, "r+"); if (fp != NULL) { fseek (fp, 0, SEEK_END); if (ftell (fp) > prm_get_integer_value (PRM_ID_ER_LOG_SIZE)) { fp = event_file_backup (fp, path); } } else { fp = fopen (path, "w"); } return fp; }
/* * log_zip_free - free LOG_ZIP structure * return: none * log_zip(in): LOG_ZIP structure to be freed */ void log_zip_free (LOG_ZIP * log_zip) { assert (log_zip != NULL); if (log_zip->log_data) { free_and_init (log_zip->log_data); } if (log_zip->wrkmem) { free_and_init (log_zip->wrkmem); } free_and_init (log_zip); }
/* * numeric_to_string() - convert numeric value to string * return: formatted string * value(in): numeric value to convert * commas(in): whether or not to display commas */ static char * numeric_to_string (DB_VALUE * value, bool commas) { char str_buf[NUMERIC_MAX_STRING_SIZE]; char *return_string; int prec; int comma_length; int max_length; /* * Allocate string length based on precision plus the commas plus a * character for each of the sign, decimal point, and NULL terminator. */ prec = DB_VALUE_PRECISION (value); comma_length = COMMAS_OFFSET (commas, prec); max_length = prec + comma_length + 3; return_string = (char *) malloc (max_length); if (return_string == NULL) { return (NULL); } numeric_db_value_print (value, str_buf); if (strlen (str_buf) > max_length - 1) { free_and_init (return_string); return (duplicate_string ("NUM OVERFLOW")); } strcpy (return_string, str_buf); return return_string; }
/* * db_drop_constraint() - This function is used remove constraint from a class. * Please refer to the header information for db_add_constraint() for basic * information on classes and constraints. * return : error code * classmop: class (or instance) pointer * constraint_type: type of constraint to drop * constraint_name: constraint name * att_names: names of attributes to be constrained * class_attributes: flag indicating class attribute status * (0 if this is not a class attribute, * non-zero if this is a class attribute) * * note : * If the name is known, the constraint can be dropped by name, in which * case the <att_names> parameter should be NULL. * If the name is not known, the constraint can be specified by the * combination of class pointer and attribute names. * The order of the attribute names must match the order given when the * constraint was added. In this case, the <constraint_name> should be NULL. */ int db_drop_constraint (MOP classmop, DB_CONSTRAINT_TYPE constraint_type, const char *constraint_name, const char **att_names, int class_attributes) { int retval; char *name = NULL; CHECK_CONNECT_ERROR (); CHECK_1ARG_ERROR (classmop); CHECK_MODIFICATION_ERROR (); name = sm_produce_constraint_name_mop (classmop, constraint_type, att_names, NULL, constraint_name); if (name == NULL) { assert (er_errid () != NO_ERROR); retval = er_errid (); } else { retval = sm_drop_constraint (classmop, constraint_type, name, att_names, class_attributes ? true : false, false); free_and_init (name); } return (retval); }
/* * pt_free_a_string_block() - finds a string block, removes it from * the hash table linked list frees the memory * return: * parser(in): * string_to_free(in): */ static void pt_free_a_string_block (const PARSER_CONTEXT * parser, PARSER_STRING_BLOCK * string_to_free) { PARSER_STRING_BLOCK **previous_string; PARSER_STRING_BLOCK *string; int idhash; #if defined(SERVER_MODE) int rv; #endif /* SERVER_MODE */ /* find string holding old_string for for this parse_id */ idhash = parser->id % HASH_NUMBER; #if defined(SERVER_MODE) MUTEX_LOCK (rv, parser_memory_lock); #endif /* SERVER_MODE */ previous_string = &parser_String_blocks[idhash]; string = *previous_string; while (string != string_to_free) { previous_string = &string->next; string = *previous_string; } if (string) { *previous_string = string->next; free_and_init (string); } #if defined(SERVER_MODE) MUTEX_UNLOCK (parser_memory_lock); #endif /* SERVER_MODE */ }
static void cursor_allocate_oid_buffer (CURSOR_ID * cursor_id_p) { size_t oids_size, mops_size; /* * NOTE: Currently assume a PAGESIZE. In fact, since we can * find average tuple count per page from the LIST FILE * identifier we can make a good estimate of oid entry count. */ cursor_id_p->oid_ent_count = CEIL_PTVDIV (DB_PAGESIZE, sizeof (OID)) - 1; oids_size = cursor_id_p->oid_ent_count * sizeof (OID); cursor_id_p->oid_set = (OID *) malloc (oids_size); if (cursor_id_p->oid_set == NULL) { /* Ignore the failure, this is an optimization */ cursor_id_p->oid_ent_count = 0; } mops_size = cursor_id_p->oid_ent_count * sizeof (MOP); cursor_id_p->mop_set = (MOP *) malloc (mops_size); if (cursor_id_p->mop_set == NULL) { /* Ignore the failure, this is an optimization */ free_and_init (cursor_id_p->oid_set); cursor_id_p->oid_ent_count = 0; } }
/* * flush_class_tables - Free storage for all the class tables. * return: void */ static void flush_class_tables () { CLASS_TABLE *table, *next; for (table = Classes, next = NULL; table != NULL; table = next) { next = table->next; if (table->instances) { free_and_init (table->instances); } free_and_init (table); } Classes = NULL; }
/* * event_log_bind_values - * return: * log_fp(in): * tran_index(in): * bind_index(in): */ void event_log_bind_values (FILE * log_fp, int tran_index, int bind_index) { LOG_TDES *tdes; int i, indent = 2; char *val_str; if (bind_index < 0) { return; } tdes = LOG_FIND_TDES (tran_index); if (tdes == NULL || tdes->bind_history[bind_index].vals == NULL) { return; } for (i = 0; i < tdes->bind_history[bind_index].size; i++) { val_str = pr_valstring (&tdes->bind_history[bind_index].vals[i]); fprintf (log_fp, "%*cbind: %s\n", indent, ' ', (val_str == NULL) ? "(null)" : val_str); if (val_str != NULL) { free_and_init (val_str); } } }
/* * pt_unregister_parser () - unregisters parser as existing, * or registers it as not existing * return: none * parser(in): */ static void pt_unregister_parser (const PARSER_CONTEXT * parser) { int idhash; PARSER_NODE_FREE_LIST *free_list; PARSER_NODE_FREE_LIST **previous_free_list; #if defined(SERVER_MODE) int rv; #endif /* SERVER_MODE */ /* find free list for for this id */ idhash = parser->id % HASH_NUMBER; #if defined(SERVER_MODE) MUTEX_LOCK (rv, free_lists_lock); #endif /* SERVER_MODE */ previous_free_list = &parser_Node_free_lists[idhash]; free_list = *previous_free_list; while (free_list != NULL && free_list->parser_id != parser->id) { previous_free_list = &free_list->next; free_list = *previous_free_list; } if (free_list) { /* all is ok, remove the free list from the hash list of free lists. */ *previous_free_list = free_list->next; free_and_init (free_list); } #if defined(SERVER_MODE) MUTEX_UNLOCK (free_lists_lock); #endif /* SERVER_MODE */ }
/* * log_zip_alloc - allocate LOG_ZIP structure * return: LOG_ZIP structure or NULL if error * length(in): log_zip data buffer to be allocated * is_zip(in): to be used zip or not * * Note: */ LOG_ZIP * log_zip_alloc (LOG_ZIP_SIZE_T size, bool is_zip) { LOG_ZIP *log_zip = NULL; LOG_ZIP_SIZE_T buf_size = 0; buf_size = LOG_ZIP_BUF_SIZE (size); log_zip = (LOG_ZIP *) malloc (sizeof (LOG_ZIP)); if (log_zip == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (LOG_ZIP)); return NULL; } log_zip->data_length = 0; log_zip->log_data = (lzo_bytep) malloc ((size_t) buf_size); if (log_zip->log_data == NULL) { free_and_init (log_zip); er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, buf_size); return NULL; } log_zip->buf_size = buf_size; if (is_zip) { /* lzo method is best speed : LZO1X_1_MEM_COMPRESS */ log_zip->wrkmem = (lzo_bytep) malloc (LZO1X_1_MEM_COMPRESS); if (log_zip->wrkmem == NULL) { free_and_init (log_zip->log_data); free_and_init (log_zip); er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, LZO1X_1_MEM_COMPRESS); return NULL; } } else { log_zip->wrkmem = NULL; } return log_zip; }
/* * log_unzip - decompress(unzip) log data into LOG_ZIP * return: true on success, false on failure * log_unzip(out): LOG_ZIP structure allocated by log_zip_alloc * length(in): length of given data * data(out): compressed log data */ bool log_unzip (LOG_ZIP * log_unzip, LOG_ZIP_SIZE_T length, void *data) { lzo_uint unzip_len; LOG_ZIP_SIZE_T org_len; LOG_ZIP_SIZE_T buf_size; int rc; assert (length > 0 && data != NULL); assert (log_unzip != NULL); /* get original legnth from the compressed data */ memcpy (&org_len, data, sizeof (LOG_ZIP_SIZE_T)); if (org_len <= 0) return false; unzip_len = (lzo_uint) org_len; buf_size = LOG_ZIP_BUF_SIZE (org_len); length -= sizeof (LOG_ZIP_SIZE_T); if (buf_size > log_unzip->buf_size) { if (log_unzip->log_data) { free_and_init (log_unzip->log_data); } log_unzip->log_data = (unsigned char *) malloc (buf_size); if (log_unzip->log_data == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, buf_size); } log_unzip->buf_size = buf_size; } if (log_unzip->log_data == NULL) { log_unzip->data_length = 0; log_unzip->buf_size = 0; return false; } rc = lzo1x_decompress_safe ((lzo_bytep) data + sizeof (LOG_ZIP_SIZE_T), (lzo_uint) length, log_unzip->log_data, &unzip_len, NULL); if (rc == LZO_E_OK) { log_unzip->data_length = unzip_len; /* if the uncompressed data length != original length, * then it means that uncompression failed */ if (unzip_len == (lzo_uint) org_len) { return true; } } return false; }
/* * free_recdes - frees a storage for a record * return: void * rec(out): record */ static void free_recdes (RECDES * rec) { if (rec != NULL) { free_and_init (rec); } }
/* * db_private_free () - call free function for current private heap * return: * thrd(in): thread conext if it is server, otherwise NULL * ptr(in): memory pointer to free */ void db_private_free (void *thrd, void *ptr) { #if defined (SERVER_MODE) HL_HEAPID heap_id; #endif if (ptr == NULL) { return; } #if defined (CS_MODE) db_ws_free (ptr); #elif defined (SERVER_MODE) heap_id = (thrd ? ((THREAD_ENTRY *) thrd)->private_heap_id : css_get_private_heap (NULL)); if (heap_id) { hl_lea_free (heap_id, ptr); } else { free_and_init (ptr); } #else /* SA_MODE */ if (private_heap_id == 0) { free (ptr); } else { PRIVATE_MALLOC_HEADER *h; h = private_user2hl_ptr (ptr); if (h->magic != PRIVATE_MALLOC_HEADER_MAGIC) { /* assertion point */ return; } if (h->alloc_type == PRIVATE_ALLOC_TYPE_LEA) { hl_lea_free (private_heap_id, h); } else if (h->alloc_type == PRIVATE_ALLOC_TYPE_WS) { db_ws_free (ptr); /* not h */ } else { return; } } #endif /* SA_MODE */ }
/* * parser_free_lcks_classes() - free allocated memory in pt_class_pre_fetch() * and pt_find_lck_classes () * return: void * parser(in): */ void parser_free_lcks_classes (PARSER_CONTEXT * parser) { int i; if (parser->lcks_classes) { for (i = 0; i < parser->num_lcks_classes; i++) { free_and_init (parser->lcks_classes[i]); } free_and_init (parser->lcks_classes); parser->num_lcks_classes = 0; } return; }
static void free_last_referenced_name (WHENEVER_SCOPE * scope, WHENEVER_SCOPE * new_scope) { char *name; if (LAST_REF (SQLWARNING)) { free_and_init (name); } if (LAST_REF (SQLERROR)) { free_and_init (name); } if (LAST_REF (NOT_FOUND)) { free_and_init (name); } }
/* * log_zip - compress(zip) log data into LOG_ZIP * return: true on success, false on failure * log_zip(in/out): LOG_ZIP structure allocated by log_zip_alloc * length(in): length of given data * data(in): log data to be compressed */ bool log_zip (LOG_ZIP * log_zip, LOG_ZIP_SIZE_T length, const void *data) { lzo_uint zip_len = 0; LOG_ZIP_SIZE_T buf_size; int rc; assert (length > 0 && data != NULL); assert (log_zip != NULL); log_zip->data_length = 0; buf_size = LOG_ZIP_BUF_SIZE (length); if (buf_size > log_zip->buf_size) { if (log_zip->log_data) { free_and_init (log_zip->log_data); } log_zip->log_data = (unsigned char *) malloc (buf_size); if (log_zip->log_data == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, buf_size); } log_zip->buf_size = buf_size; } if (log_zip->log_data == NULL) { log_zip->data_length = 0; log_zip->buf_size = 0; return false; } /* save original data length */ memcpy (log_zip->log_data, &length, sizeof (LOG_ZIP_SIZE_T)); rc = lzo1x_1_compress ((lzo_bytep) data, (lzo_uint) length, log_zip->log_data + sizeof (LOG_ZIP_SIZE_T), &zip_len, log_zip->wrkmem); if (rc == LZO_E_OK) { log_zip->data_length = zip_len + sizeof (LOG_ZIP_SIZE_T); /* if the compressed data length >= orginal length, * then it means that compression failed */ if (log_zip->data_length < length) { return true; } } return false; }
/* * pp_free_stmt() - Free the indicated structure. * It is assumed to have already been removed from pp_stmt_table * if it was ever in there. * return : void * stmt(in): A pointer to a STMT struct to be freed. */ void pp_free_stmt (STMT * stmt) { if (stmt == NULL) { return; } free_and_init (stmt->name); es_ht_free_symbol (stmt); }
/* * 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_free_cursor() - Free the given cursor. * return : void * cur(in): The cursor object to be freed. */ void pp_free_cursor (CURSOR * cursor) { free_and_init (cursor->name); if (cursor->static_stmt) { free_and_init (cursor->static_stmt); } if (cursor->host_refs) { pp_free_host_lod (cursor->host_refs); } /* * Don't free any dynamic statement associated with this cursor; * those statements have lifetimes that differ from the lifetimes of * cursors. */ es_ht_free_symbol (cursor); }
/* * hb_register_to_master () - * return: NO_ERROR or ER_FAILED * * conn(in): * type(in): */ int hb_register_to_master (CSS_CONN_ENTRY * conn, int type) { int error; HBP_PROC_REGISTER *hbp_register = NULL; if (NULL == conn) { er_log_debug (ARG_FILE_LINE, "invalid conn. (conn:NULL).\n"); return (ER_FAILED); } hbp_register = hb_make_set_hbp_register (type); if (NULL == hbp_register) { er_log_debug (ARG_FILE_LINE, "hbp_register failed. \n"); return (ER_FAILED); } if (!IS_INVALID_SOCKET (conn->fd)) { error = css_send_heartbeat_request (conn, SERVER_REGISTER_HA_PROCESS); if (error != NO_ERRORS) { goto error_return; } error = css_send_heartbeat_data (conn, (const char *) hbp_register, sizeof (*hbp_register)); if (error != NO_ERRORS) { goto error_return; } } free_and_init (hbp_register); return (NO_ERROR); error_return: free_and_init (hbp_register); return (ER_FAILED); }
FARPROC WINAPI delay_load_hook (unsigned dliNotify, PDelayLoadInfo pdli) { FARPROC fp = NULL; switch (dliNotify) { case dliFailLoadLib: { char *java_home = NULL, *tmp = NULL, *tail; char jvm_lib_path[BUF_SIZE]; void *libVM; java_home = getenv ("JAVA_HOME"); tail = JVM_LIB_PATH_JDK; if (java_home == NULL) { tmp = (char *) malloc (BUF_SIZE); if (tmp) { if (get_java_root_path (tmp)) { java_home = tmp; tail = JVM_LIB_PATH_JRE; } } } if (java_home) { sprintf (jvm_lib_path, "%s\\%s\\jvm.dll", java_home, tail); libVM = LoadLibrary (jvm_lib_path); if (libVM) { fp = (FARPROC) (HMODULE) libVM; } } if (tmp) { free_and_init (tmp); } } break; default: break; } return fp; }
/* * cursor_free_list_id () - Area allocated for list file identifier is freed * return: nothing * list_id: List file identifier */ void cursor_free_list_id (QFILE_LIST_ID * list_id_p, bool self) { if (list_id_p->last_pgptr) { free_and_init (list_id_p->last_pgptr); } if (list_id_p->tpl_descr.f_valp) { free_and_init (list_id_p->tpl_descr.f_valp); } if (list_id_p->sort_list) { free_and_init (list_id_p->sort_list); } if (list_id_p->type_list.domp) { free_and_init (list_id_p->type_list.domp); } if (self) { free_and_init (list_id_p); } }
/* * hb_connect_to_master() - connect to the master server * return: conn * server_name(in): server name * log_path(in): log path * copylogdbyn(in): */ static CSS_CONN_ENTRY * hb_connect_to_master (const char *server_name, const char *log_path, HB_PROC_TYPE type) { CSS_CONN_ENTRY *conn; int error = NO_ERROR; char *packed_name; int name_length = 0; packed_name = hb_pack_server_name (server_name, &name_length, log_path, type); if (packed_name == NULL) { return NULL; } conn = css_connect_to_master_server (prm_get_master_port_id (), packed_name, name_length); if (conn == NULL) { free_and_init (packed_name); return NULL; } hb_Pipe_to_master = conn->fd; free_and_init (packed_name); return conn; }
/* * parser_create_parser () - creates a parser context * The pointer can be passed to top level * parse functions and then freed by parser_free_parser. * return: */ PARSER_CONTEXT * parser_create_parser (void) { PARSER_CONTEXT *parser; struct timeval t; #if defined(SERVER_MODE) int rv; #endif /* SERVER_MODE */ parser = (PARSER_CONTEXT *) calloc (sizeof (PARSER_CONTEXT), 1); if (parser == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (PARSER_CONTEXT)); return NULL; } #if !defined (SERVER_MODE) parser_init_func_vectors (); #endif /* !SERVER_MODE */ #if defined(SERVER_MODE) MUTEX_LOCK (rv, parser_id_lock); #endif /* SERVER_MODE */ parser->id = parser_id++; #if defined(SERVER_MODE) MUTEX_UNLOCK (parser_id_lock); #endif /* SERVER_MODE */ if (pt_register_parser (parser) == ER_FAILED) { free_and_init (parser); return NULL; } parser->execution_values.row_count = -1; /* Generate random values for rand() and drand() */ gettimeofday (&t, NULL); srand48 (t.tv_usec); parser->lrand = lrand48 (); parser->drand = drand48 (); return parser; }
/* * stats_get_statistics () - Get class statistics * return: * classoid(in): OID of the class * timestamp(in): * * Note: This function provides an easier interface for the client for * obtaining statistics to the client side by taking care of the * communication details . (Note that the upper levels shouldn't have to * worry about the communication buffer.) */ CLASS_STATS * stats_get_statistics (OID * class_oid_p, unsigned int time_stamp, int node_id) { CLASS_STATS *stats_p = NULL; char *buffer_p; int length; buffer_p = stats_get_statistics_from_server (class_oid_p, time_stamp, &length, node_id); if (buffer_p != NULL) { stats_p = stats_client_unpack_statistics (buffer_p); free_and_init (buffer_p); } return (stats_p); }
/* * css_finalize_list() - destroy the list * return: 0 if success, or error code * ptr(in/out): list */ int css_finalize_list (CSS_LIST * list) { CSS_LIST_ENTRY *e; while (list->free_list != NULL) { e = list->free_list; list->free_list = e->next; free_and_init (e); list->free_count--; } assert (list->free_count == 0); assert (list->count == 0); PRINT_FINALIZE_LIST (list); return NO_ERROR; }