gattrib
|
00001 /* gEDA - GPL Electronic Design Automation 00002 * gattrib -- gEDA component and net attribute manipulation using spreadsheet. 00003 * Copyright (C) 2003-2010 Stuart D. Brorson. 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00018 */ 00019 00020 /*------------------------------------------------------------------*/ 00032 #include <config.h> 00033 00034 #include <stdio.h> 00035 #ifdef HAVE_STRING_H 00036 #include <string.h> 00037 #endif 00038 #include <math.h> 00039 00040 /*------------------------------------------------------------------ 00041 * Gattrib specific includes 00042 *------------------------------------------------------------------*/ 00043 #include <libgeda/libgeda.h> /* geda library functions */ 00044 #include "../include/struct.h" /* typdef and struct declarations */ 00045 #include "../include/prototype.h" /* function prototypes */ 00046 #include "../include/globals.h" 00047 00048 #ifdef HAVE_LIBDMALLOC 00049 #include <dmalloc.h> 00050 #endif 00051 00052 /* =================== Public Functions ====================== */ 00053 00054 /*------------------------------------------------------------------*/ 00068 TABLE **s_table_new(int rows, int cols) 00069 { 00070 TABLE **new_table; 00071 int i, j; 00072 00073 /* Here I am trying to create a 2 dimensional array of structs */ 00074 new_table = (TABLE **) g_malloc(rows*sizeof(TABLE *)); 00075 for (i = 0; i < rows; i++) { 00076 new_table[i] = (TABLE *) g_malloc(cols * sizeof(TABLE)); 00077 /* Note that I should put some checks in here to verify that 00078 * malloc worked correctly. */ 00079 } 00080 00081 /* Now pre-load the table with NULLs */ 00082 for (i = 0; i < rows; i++) { 00083 for (j = 0; j < cols; j++) { 00084 (new_table[i][j]).attrib_value = NULL; 00085 (new_table[i][j]).row_name = NULL; 00086 (new_table[i][j]).col_name = NULL; 00087 (new_table[i][j]).row = i; 00088 (new_table[i][j]).col = j; 00089 (new_table[i][j]).visibility = VISIBLE; 00090 (new_table[i][j]).show_name_value = SHOW_VALUE; 00091 } 00092 } 00093 00094 return (new_table); 00095 00096 } 00097 00098 00099 /*------------------------------------------------------------------*/ 00115 TABLE **s_table_resize(TABLE **table, 00116 int rows, int old_cols, int new_cols) 00117 { 00118 int i, j; 00119 00120 /* Here I am trying to resize the 2 dimensional array of structs */ 00121 for (i = 0; i < rows; i++) { 00122 table[i] = (TABLE *) realloc(table[i], new_cols*sizeof(TABLE) ); 00123 if (table[i] == NULL) exit(-1); /* die if failed to realloc new memory */ 00124 } 00125 00126 /* Now pre-load new cols with NULLs */ 00127 for (i = 0; i < rows; i++) { 00128 for (j = old_cols; j < new_cols; j++) { 00129 (table[i][j]).attrib_value = NULL; 00130 (table[i][j]).row_name = NULL; 00131 (table[i][j]).col_name = NULL; 00132 (table[i][j]).row = i; 00133 (table[i][j]).col = j; 00134 (table[i][j]).visibility = VISIBLE; 00135 (table[i][j]).show_name_value = SHOW_VALUE; 00136 } 00137 } 00138 00139 return table; 00140 } 00141 00142 00143 /*------------------------------------------------------------------*/ 00153 void s_table_destroy(TABLE **table, int row_count, int col_count) 00154 { 00155 int i, j; 00156 00157 if (table == NULL) 00158 return; 00159 00160 for (i = 0; i < row_count; i++) { 00161 for (j = 0; j < col_count; j++) { 00162 g_free( (table[i][j]).attrib_value ); 00163 g_free( (table[i][j]).row_name ); 00164 g_free( (table[i][j]).col_name ); 00165 } 00166 } 00167 00168 for (i = 0; i < row_count; i++) { 00169 g_free( table[i] ); 00170 } 00171 00172 g_free(table); 00173 table = NULL; 00174 00175 return; 00176 } 00177 00178 00179 00180 /*------------------------------------------------------------------*/ 00191 int s_table_get_index(STRING_LIST *local_list, char *local_string) { 00192 int count = 0; 00193 STRING_LIST *list_element; 00194 00195 #ifdef DEBUG 00196 printf("In s_table_get_index, examining %s to see if it is in the list.\n", local_string); 00197 #endif 00198 00199 00200 list_element = local_list; 00201 while (list_element != NULL) { 00202 if (strcmp(list_element->data, local_string) == 0) { 00203 return count; 00204 } 00205 count++; 00206 list_element = list_element->next; 00207 } 00208 return(-1); /* return code when string is not in master_list */ 00209 } 00210 00211 00212 00213 /*------------------------------------------------------------------*/ 00228 STRING_LIST *s_table_create_attrib_pair(gchar *row_name, 00229 TABLE **table, 00230 STRING_LIST *row_list, 00231 int num_attribs) 00232 { 00233 STRING_LIST *attrib_pair_list; 00234 char *attrib_name, *attrib_value, *name_value_pair; 00235 int row, col; 00236 int count = 0; 00237 00238 attrib_pair_list = s_string_list_new(); 00239 00240 row = s_table_get_index(row_list, row_name); 00241 /* Sanity check */ 00242 if (row == -1) { 00243 /* we didn't find the item in the list */ 00244 fprintf (stderr, 00245 "In s_table_create_attrib_pair, we didn't find the row name in the row list!\n"); 00246 return attrib_pair_list; 00247 } 00248 00249 for (col = 0; col < num_attribs; col++) { 00250 /* pull attrib from table. If non-null, add it to attrib_pair_list */ 00251 if ( (table[row][col]).attrib_value != NULL) { 00252 attrib_name = (table[row][col]).col_name; 00253 attrib_value = (table[row][col]).attrib_value; 00254 name_value_pair = g_strconcat(attrib_name, "=", attrib_value, NULL); 00255 s_string_list_add_item(attrib_pair_list, &count, name_value_pair); 00256 g_free(name_value_pair); 00257 } 00258 } 00259 00260 return attrib_pair_list; 00261 } 00262 00263 00264 00265 00266 /*------------------------------------------------------------------*/ 00275 void s_table_add_toplevel_comp_items_to_comp_table (const GList *obj_list) { 00276 gchar *temp_uref; 00277 int row, col; 00278 gchar *attrib_text; 00279 gchar *attrib_name; 00280 gchar *attrib_value; 00281 const GList *o_iter; 00282 GList *a_iter; 00283 OBJECT *a_current; 00284 gint old_visibility, old_show_name_value; 00285 00286 00287 if (verbose_mode) { 00288 printf("- Starting internal component TABLE creation\n"); 00289 } 00290 00291 #ifdef DEBUG 00292 fflush(stderr); 00293 fflush(stdout); 00294 printf("=========== Just entered s_table_add_toplevel_comp_items_to_comp_table! ==============\n"); 00295 #endif 00296 00297 /* ----- Iterate through all objects found on page ----- */ 00298 for (o_iter = obj_list; o_iter != NULL; o_iter = g_list_next (o_iter)) { 00299 OBJECT *o_current = o_iter->data; 00300 00301 #ifdef DEBUG 00302 printf(" ---> In s_table_add_toplevel_comp_items_to_comp_table, examining o_current->name = %s\n", o_current->name); 00303 #endif 00304 00305 /* ----- Now process objects found on page ----- */ 00306 if (o_current->type == OBJ_COMPLEX && 00307 o_current->attribs != NULL) { 00308 00309 /* ---- Don't process part if it lacks a refdes ----- */ 00310 temp_uref = g_strdup(s_attrib_get_refdes(o_current)); 00311 if (temp_uref) { 00312 00313 #if DEBUG 00314 printf(" In s_table_add_toplevel_comp_items_to_comp_table, found component on page. Refdes = %s\n", temp_uref); 00315 #endif 00316 verbose_print(" C"); 00317 00318 /* Having found a component, we loop over all attribs in this 00319 * component, and stick them 00320 * into cells in the table. */ 00321 a_iter = o_current->attribs; 00322 while (a_iter != NULL) { 00323 a_current = a_iter->data; 00324 if (a_current->type == OBJ_TEXT 00325 && a_current->text != NULL) { /* found an attribute */ 00326 /* may need to check more thoroughly here. . . . */ 00327 attrib_text = g_strdup(a_current->text->string); 00328 attrib_name = u_basic_breakup_string(attrib_text, '=', 0); 00329 attrib_value = s_misc_remaining_string(attrib_text, '=', 1); 00330 old_visibility = o_is_visible (pr_current, a_current) 00331 ? VISIBLE : INVISIBLE; 00332 old_show_name_value = a_current->show_name_value; 00333 00334 /* Don't include "refdes" or "slot" because they form the row name. */ 00335 /* Also don't include "net" per bug found by Steve W. 4.3.2007 -- SDB */ 00336 if ( (strcmp(attrib_name, "refdes") != 0) && 00337 (strcmp(attrib_name, "net") != 0) && 00338 (strcmp(attrib_name, "slot") != 0) ) { 00339 00340 /* Get row and col where to put this attrib */ 00341 row = s_table_get_index(sheet_head->master_comp_list_head, temp_uref); 00342 col = s_table_get_index(sheet_head->master_comp_attrib_list_head, attrib_name); 00343 /* Sanity check */ 00344 if (row == -1 || col == -1) { 00345 /* we didn't find the item in the table */ 00346 fprintf (stderr, 00347 "In s_table_add_toplevel_comp_items_to_comp_table, we didn't find either row or col in the lists!\n"); 00348 } else { 00349 00350 #if DEBUG 00351 printf(" In s_table_add_toplevel_comp_items_to_comp_table, about to add row %d, col %d, attrib_value = %s\n", 00352 row, col, attrib_value); 00353 printf(" . . . current address of attrib_value cell is [%p]\n", &((sheet_head->component_table)[row][col]).attrib_value); 00354 #endif 00355 /* Is there a compelling reason for me to put this into a separate fcn? */ 00356 ((sheet_head->component_table)[row][col]).row = row; 00357 ((sheet_head->component_table)[row][col]).col = col; 00358 ((sheet_head->component_table)[row][col]).row_name = g_strdup(temp_uref); 00359 ((sheet_head->component_table)[row][col]).col_name = g_strdup(attrib_name); 00360 ((sheet_head->component_table)[row][col]).attrib_value = g_strdup(attrib_value); 00361 ((sheet_head->component_table)[row][col]).visibility = old_visibility; 00362 ((sheet_head->component_table)[row][col]).show_name_value = old_show_name_value; 00363 } 00364 } 00365 g_free(attrib_name); 00366 g_free(attrib_text); 00367 g_free(attrib_value); 00368 } 00369 a_iter = g_list_next (a_iter); 00370 00371 } /* while (a_current != NULL) */ 00372 g_free(temp_uref); 00373 } /* if (temp_uref) */ 00374 } /* if (o_current->type == OBJ_COMPLEX) */ 00375 } 00376 00377 verbose_done(); 00378 00379 } 00380 00381 #if 0 00382 /*------------------------------------------------------------------*/ 00396 void s_table_add_toplevel_net_items_to_net_table(OBJECT *start_obj) { 00397 OBJECT *o_current; 00398 char *temp_netname; 00399 int row, col; 00400 char *attrib_text; 00401 char *attrib_name; 00402 char *attrib_value; 00403 ATTRIB *a_current; 00404 00405 /* ----- Iterate through all objects found on page ----- */ 00406 o_current = start_obj; 00407 while (o_current != NULL) { 00408 00409 /* ----- Now process objects found on page ----- */ 00410 if (o_current->type == OBJ_NET) { 00411 #if DEBUG 00412 fflush(stderr); 00413 fflush(stdout); 00414 printf("In s_table_add_toplevel_net_items_to_net_table, Found net on page\n"); 00415 #endif 00416 verbose_print(" N"); 00417 00418 /* Having found a net, we stick it into the table. */ 00419 a_current = o_current->attribs; 00420 while (a_current != NULL) { 00421 if (a_current->object->type == OBJ_TEXT 00422 && a_current->object->text != NULL) { /* found an attribute */ 00423 /* may need to check more thoroughly here. . . . */ 00424 attrib_text = g_strdup(a_current->object->text->string); 00425 attrib_name = u_basic_breakup_string(attrib_text, '=', 0); 00426 attrib_value = s_misc_remaining_string(attrib_text, '=', 1); 00427 if (strcmp(attrib_name, "netname") != 0) { 00428 /* Don't include "netname" */ 00429 00430 /* Get row and col where to put this attrib */ 00431 row = s_table_get_index(sheet_head->master_net_list_head, temp_netname); 00432 col = s_table_get_index(sheet_head->master_net_attrib_list_head, attrib_name); 00433 #if DEBUG 00434 fflush(stderr); 00435 fflush(stdout); 00436 printf("In s_table_add_toplevel_net_items_to_net_table, about to add row %d, col %d, attrib_value = %s\n", 00437 row, col, attrib_value); 00438 printf(" . . . current address of attrib_value cell is [%p]\n", &((sheet_head->net_table)[row][col]).attrib_value); 00439 #endif 00440 /* Is there a compelling reason for me to put this into a separate fcn? */ 00441 ((sheet_head->net_table)[row][col]).row = row; 00442 ((sheet_head->net_table)[row][col]).col = col; 00443 ((sheet_head->net_table)[row][col]).row_name = g_strdup(temp_netname); 00444 ((sheet_head->net_table)[row][col]).col_name = g_strdup(attrib_name); 00445 ((sheet_head->net_table)[row][col]).attrib_value = g_strdup(attrib_value); 00446 } 00447 g_free(attrib_name); 00448 g_free(attrib_text); 00449 g_free(attrib_value); 00450 } 00451 a_current = a_current->next; 00452 00453 } /* while (a_current != NULL) */ 00454 g_free(temp_netname); 00455 00456 } /*--- if (o_current->type == OBJ_NET) ---*/ 00457 00458 00459 o_current = o_current->next; /* iterate to next object on page */ 00460 } /* while o_current != NULL */ 00461 00462 verbose_done(); 00463 00464 #if DEBUG 00465 fflush(stderr); 00466 fflush(stdout); 00467 printf("In s_table_add_toplevel_net_items_to_net_table -- we are about to return\n"); 00468 #endif 00469 00470 } 00471 #endif 00472 00473 00474 /*------------------------------------------------------------------*/ 00482 void s_table_add_toplevel_pin_items_to_pin_table (const GList *obj_list) { 00483 gchar *temp_uref; 00484 gchar *pinnumber; 00485 gchar *row_label; 00486 int row, col; 00487 gchar *attrib_text; 00488 gchar *attrib_name; 00489 gchar *attrib_value; 00490 const GList *o_iter; 00491 GList *a_iter; 00492 GList *o_lower_iter; 00493 OBJECT *pin_attrib; 00494 00495 if (verbose_mode) { 00496 printf("- Starting internal pin TABLE creation\n"); 00497 } 00498 00499 #ifdef DEBUG 00500 printf("=========== Just entered s_table_add_toplevel_pin_items_to_pin_table! ==============\n"); 00501 #endif 00502 00503 /* ----- Iterate through all objects found on page ----- */ 00504 for (o_iter = obj_list; o_iter != NULL; o_iter = g_list_next (o_iter)) { 00505 OBJECT *o_current = o_iter->data; 00506 00507 #ifdef DEBUG 00508 printf(" ---> In s_table_add_toplevel_pin_items_to_pin_table, examining o_current->name = %s\n", o_current->name); 00509 #endif 00510 00511 /* ----- Now process objects found on page ----- */ 00512 if (o_current->type == OBJ_COMPLEX && 00513 o_current->attribs != NULL) { 00514 00515 /* ---- Don't process part if it lacks a refdes ----- */ 00516 temp_uref = s_attrib_get_refdes(o_current); 00517 if (temp_uref) { 00518 00519 /* ----- Now iterate through lower level objects looking for pins. ----- */ 00520 for (o_lower_iter = o_current->complex->prim_objs; 00521 o_lower_iter != NULL; 00522 o_lower_iter = g_list_next (o_lower_iter)) { 00523 OBJECT *o_lower_current = o_lower_iter->data; 00524 00525 if (o_lower_current->type == OBJ_PIN) { 00526 /* ----- Found a pin. First get its pinnumber. then get attrib head and loop on attribs. ----- */ 00527 pinnumber = o_attrib_search_object_attribs_by_name (o_lower_current, "pinnumber", 0); 00528 row_label = g_strconcat(temp_uref, ":", pinnumber, NULL); 00529 00530 #if DEBUG 00531 printf(" In s_table_add_toplevel_pin_items_to_pin_table, examining pin %s\n", row_label); 00532 #endif 00533 00534 a_iter = o_lower_current->attribs; 00535 while (a_iter != NULL) { 00536 pin_attrib = a_iter->data; 00537 if (pin_attrib->type == OBJ_TEXT 00538 && pin_attrib->text != NULL) { /* found an attribute */ 00539 attrib_text = g_strdup(pin_attrib->text->string); 00540 attrib_name = u_basic_breakup_string(attrib_text, '=', 0); 00541 attrib_value = s_misc_remaining_string(attrib_text, '=', 1); 00542 00543 if ( (strcmp(attrib_name, "pinnumber") != 0) 00544 && (attrib_value != 0) ) { 00545 /* Don't include "pinnumber" because it is already in other master list. 00546 * Also must ensure that value is non-null; certain symbols are not well formed. 00547 */ 00548 00549 /* Get row and col where to put this attrib */ 00550 row = s_table_get_index(sheet_head->master_pin_list_head, row_label); 00551 col = s_table_get_index(sheet_head->master_pin_attrib_list_head, attrib_name); 00552 /* Sanity check */ 00553 if (row == -1 || col == -1) { 00554 /* we didn't find the item in the table */ 00555 fprintf (stderr, 00556 "In s_table_add_toplevel_pin_items_to_pin_table, we didn't find either row or col in the lists!\n"); 00557 } else { 00558 00559 #if DEBUG 00560 printf(" In s_table_add_toplevel_pin_items_to_pin_table, about to add row %d, col %d, attrib_value = %s\n", 00561 row, col, attrib_value); 00562 printf(" . . . current address of attrib_value cell is [%p]\n", &((sheet_head->component_table)[row][col]).attrib_value); 00563 #endif 00564 /* Is there a compelling reason for me to put this into a separate fcn? */ 00565 ((sheet_head->pin_table)[row][col]).row = row; 00566 ((sheet_head->pin_table)[row][col]).col = col; 00567 ((sheet_head->pin_table)[row][col]).row_name = g_strdup(row_label); 00568 ((sheet_head->pin_table)[row][col]).col_name = g_strdup(attrib_name); 00569 ((sheet_head->pin_table)[row][col]).attrib_value = g_strdup(attrib_value); 00570 } 00571 } 00572 g_free(attrib_name); 00573 g_free(attrib_text); 00574 g_free(attrib_value); 00575 } 00576 a_iter = g_list_next (a_iter); 00577 00578 } /* while (pin_attrib != NULL) */ 00579 g_free(pinnumber); 00580 g_free(row_label); 00581 } 00582 00583 } 00584 } 00585 00586 g_free(temp_uref); 00587 } 00588 00589 } 00590 00591 verbose_done(); 00592 } 00593 00594 00595 /*------------------------------------------------------------------*/ 00603 void s_table_gtksheet_to_all_tables() { 00604 00605 int num_rows; 00606 int num_cols; 00607 STRING_LIST *master_row_list; 00608 STRING_LIST *master_col_list; 00609 TABLE **local_table; 00610 GtkSheet *local_gtk_sheet; 00611 00612 /* First handle component sheet */ 00613 num_rows = sheet_head->comp_count; 00614 num_cols = sheet_head->comp_attrib_count; 00615 local_gtk_sheet = sheets[0]; 00616 master_row_list = sheet_head->master_comp_list_head; 00617 master_col_list = sheet_head->master_comp_attrib_list_head; 00618 00619 local_table = sheet_head->component_table; 00620 00621 /* now fill out new table */ 00622 #ifdef DEBUG 00623 printf("In s_table_gtksheet_to_all_tables, now about to fill out new component table.\n"); 00624 #endif 00625 s_table_gtksheet_to_table(local_gtk_sheet, master_row_list, 00626 master_col_list, local_table, 00627 num_rows, num_cols); 00628 00629 #if 0 00630 /* Next handle net sheet */ 00631 num_rows = sheet_head->net_count; 00632 num_cols = sheet_head->net_attrib_count; 00633 local_gtk_sheet = sheets[1]; 00634 master_row_list = sheet_head->master_net_list_head; 00635 master_col_list = sheet_head->master_net_attrib_list_head; 00636 local_table = sheet_head->net_table; 00637 00638 s_table_gtksheet_to_table(local_gtk_sheet, master_row_list, 00639 master_col_list, local_table, 00640 num_rows, num_cols); 00641 #endif 00642 00643 #ifdef UNIMPLEMENTED_FEATURES 00644 /* Finally, handle component pin sheet */ 00645 num_rows = sheet_head->pin_count; 00646 num_cols = sheet_head->pin_attrib_count; 00647 local_gtk_sheet = sheets[2]; 00648 master_row_list = sheet_head->master_pin_list_head; 00649 master_col_list = sheet_head->master_pin_attrib_list_head; 00650 /* local_table = s_table_new(num_rows, num_cols); */ 00651 local_table = sheet_head->pin_table; 00652 00653 s_table_gtksheet_to_table(local_gtk_sheet, master_row_list, 00654 master_col_list, local_table, 00655 num_rows, num_cols); 00656 #endif 00657 00658 return; 00659 } 00660 00661 00662 /* =================== Private Functions ====================== */ 00663 /*------------------------------------------------------------------*/ 00678 void s_table_gtksheet_to_table(GtkSheet *local_gtk_sheet, STRING_LIST *master_row_list, 00679 STRING_LIST *master_col_list, TABLE **local_table, 00680 int num_rows, int num_cols) 00681 { 00682 int row, col; 00683 00684 STRING_LIST *row_list_item; 00685 gchar *row_title; 00686 00687 STRING_LIST *col_list_item; 00688 gchar *col_title; 00689 00690 gchar *attrib_value; 00691 00692 #ifdef DEBUG 00693 printf("********** Entering s_table_gtksheet_to_table ******************\n"); 00694 #endif 00695 00696 00697 row_list_item = master_row_list; 00698 for (row = 0; row < num_rows; row++) { 00699 row_title = (gchar *) g_strdup(row_list_item->data); 00700 00701 col_list_item = master_col_list; 00702 for (col = 0; col < num_cols; col++) { 00703 col_title = (gchar *) g_strdup(col_list_item->data); 00704 00705 /* get value of attrib in cell */ 00706 attrib_value = (gchar *) gtk_sheet_cell_get_text(GTK_SHEET(local_gtk_sheet), row, col); 00707 00708 #if 0 00709 if (strlen(attrib_value) == 0) { 00710 /* g_free(attrib_value); */ /* sometimes we have spurious, zero length strings creep */ 00711 attrib_value = NULL; /* into the GtkSheet */ 00712 } 00713 #endif 00714 00715 00716 #ifdef DEBUG 00717 printf("In s_table_gtksheet_to_table, found attrib_value = %s in cell row=%d, col=%d\n", 00718 attrib_value, row, col); 00719 #endif 00720 00721 /* first handle attrib value in cell */ 00722 #ifdef DEBUG 00723 printf(" Updating attrib_value %s\n", attrib_value); 00724 #endif 00725 g_free( local_table[row][col].attrib_value ); 00726 if (attrib_value != NULL) { 00727 local_table[row][col].attrib_value = (gchar *) g_strdup(attrib_value); 00728 } else { 00729 local_table[row][col].attrib_value = NULL; 00730 } 00731 00732 /* next handle name of row (also held in TABLE cell) */ 00733 #ifdef DEBUG 00734 printf(" Updating row_name %s\n", row_title); 00735 #endif 00736 g_free( local_table[row][col].row_name ); 00737 if (row_title != NULL) { 00738 local_table[row][col].row_name = (gchar *) g_strdup(row_title); 00739 } else { 00740 local_table[row][col].row_name = NULL; 00741 } 00742 00743 /* finally handle name of col */ 00744 #ifdef DEBUG 00745 printf(" Updating col_name %s\n", col_title); 00746 #endif 00747 g_free( local_table[row][col].col_name ); 00748 if (col_title != NULL) { 00749 local_table[row][col].col_name = (gchar *) g_strdup(col_title); 00750 } else { 00751 local_table[row][col].col_name = NULL; 00752 } 00753 00754 /* get next col list item and then iterate. */ 00755 col_list_item = col_list_item->next; 00756 } 00757 00758 row_list_item = row_list_item->next; 00759 } 00760 00761 return; 00762 } 00763