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 /*------------------------------------------------------------------*/ 00031 #include <config.h> 00032 00033 #include <stdio.h> 00034 #ifdef HAVE_STRING_H 00035 #include <string.h> 00036 #endif 00037 #include <math.h> 00038 00039 /*------------------------------------------------------------------ 00040 * Gattrib specific includes 00041 *------------------------------------------------------------------*/ 00042 #include <libgeda/libgeda.h> /* geda library functions */ 00043 #include "../include/struct.h" /* typdef and struct declarations */ 00044 #include "../include/prototype.h" /* function prototypes */ 00045 #include "../include/globals.h" 00046 00047 #ifdef HAVE_LIBDMALLOC 00048 #include <dmalloc.h> 00049 #endif 00050 00051 00052 /* =================== Public Functions ====================== */ 00053 00054 00064 int s_toplevel_read_page(TOPLEVEL *toplevel, char *filename) 00065 { 00066 int file_return_code; 00067 GError *err = NULL; 00068 00069 /* Set the new filename */ 00070 toplevel->page_current->page_filename = g_strdup(filename); 00071 00072 /* read in and fill out toplevel using f_open and its callees */ 00073 file_return_code = f_open (toplevel, toplevel->page_current, filename, &err); 00074 00075 /* If an error occurred, print message */ 00076 if (err != NULL) { 00077 g_warning ("%s", err->message); 00078 g_error_free (err); 00079 } 00080 00081 return file_return_code; 00082 } 00083 00084 00096 void s_toplevel_verify_design (TOPLEVEL *toplevel) 00097 { 00098 GList *p_iter; 00099 const GList *o_iter; 00100 00101 int missing_sym_flag = 0; 00102 00103 for (p_iter = geda_list_get_glist (toplevel->pages); 00104 p_iter != NULL; 00105 p_iter = g_list_next (p_iter)) { 00106 PAGE *p_current = p_iter->data; 00107 00108 for (o_iter = s_page_objects (p_current); 00109 o_iter != NULL; 00110 o_iter = g_list_next (o_iter)) { 00111 OBJECT *o_current = o_iter->data; 00112 00113 /* --- look for object, and verify that it has a symbol file attached. ---- */ 00114 if (o_current->type == OBJ_PLACEHOLDER) { 00115 missing_sym_flag = 1; /* flag to signal that problem exists. */ 00116 } 00117 } 00118 } 00119 00120 if (missing_sym_flag) { 00121 x_dialog_missing_sym(); /* dialog gives user option to quit */ 00122 } 00123 } 00124 00125 /*------------------------------------------------------------------*/ 00134 void 00135 s_toplevel_gtksheet_to_toplevel(TOPLEVEL *toplevel) 00136 { 00137 GList *iter; 00138 PAGE *p_current; 00139 00140 #if DEBUG 00141 printf("--------------------- Entering s_toplevel_gtksheet_to_toplevel -------------------\n"); 00142 #endif 00143 00144 s_sheet_data_gtksheet_to_sheetdata(); /* read data from gtksheet into SHEET_DATA */ 00145 #if DEBUG 00146 printf("In s_toplevel_gtksheet_to_toplevel -- done writing stuff from gtksheet into SHEET_DATA.\n"); 00147 #endif 00148 00149 /* must iterate over all pages in design */ 00150 for ( iter = geda_list_get_glist( toplevel->pages ); 00151 iter != NULL; 00152 iter = g_list_next( iter ) ) { 00153 00154 p_current = (PAGE *)iter->data; 00155 toplevel->page_current = p_current; 00156 /* only traverse pages which are toplevel */ 00157 if (p_current->page_control == 0) { 00158 s_toplevel_sheetdata_to_toplevel (toplevel, p_current); /* adds all objects from page */ 00159 } 00160 } 00161 00162 #if DEBUG 00163 printf("In s_toplevel_gtksheet_to_toplevel -- done writing SHEEET_DATA text back into pr_currnet.\n"); 00164 #endif 00165 00166 return; 00167 00168 } 00169 00170 00171 /*------------------------------------------------------------------*/ 00183 void s_toplevel_add_new_attrib(gchar *new_attrib_name) { 00184 gint cur_page; /* current page in notbook */ 00185 gint old_comp_attrib_count; 00186 gint new_index; 00187 00188 if (strcmp(new_attrib_name, "_cancel") == 0) { 00189 return; /* user pressed cancel or closed window with no value in entry */ 00190 } 00191 00192 /* Next must figure out which sheet the attrib belongs to. */ 00193 cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); 00194 #ifdef DEBUG 00195 printf("In s_toplevel_add_new_attrib, adding new attrib to page %d.\n", 00196 cur_page); 00197 #endif 00198 00199 switch (cur_page) { 00200 case 0: /* component attribute */ 00201 00202 /* Eventually, I want to just resize the table to accomodate the 00203 * new attrib. However, that is difficult. Therefore, I will just 00204 * destroy the old table and recreate it for now. */ 00205 00206 /* 00207 s_table_destroy(sheet_head->component_table, 00208 sheet_head->comp_count, sheet_head->comp_attrib_count); 00209 */ 00210 old_comp_attrib_count = sheet_head->comp_attrib_count; 00211 #ifdef DEBUG 00212 printf("In s_toplevel_add_new_attrib, before adding new comp attrib.\n"); 00213 printf(" comp_attrib_count = %d\n", old_comp_attrib_count); 00214 #endif 00215 00216 s_string_list_add_item(sheet_head->master_comp_attrib_list_head, 00217 &(sheet_head->comp_attrib_count), 00218 new_attrib_name); 00219 s_string_list_sort_master_comp_attrib_list(); 00220 00221 /* Now, determine what index the new attrib ended up at 00222 * This is necessary to tell gtk_sheet_insert_columns 00223 * where the data should be shifted */ 00224 new_index = s_string_list_find_in_list(sheet_head->master_comp_attrib_list_head, 00225 (char*)new_attrib_name); 00226 00227 #ifdef DEBUG 00228 printf("In s_toplevel_add_new_attrib, just updated comp_attrib string list.\n"); 00229 printf(" new comp_attrib_count = %d\n", sheet_head->comp_attrib_count); 00230 #endif 00231 00232 /* Now create new table */ 00233 /* sheet_head->component_table = s_table_new(sheet_head->comp_count, 00234 sheet_head->comp_attrib_count); 00235 */ 00236 00237 /* resize table to accomodate new attrib col */ 00238 sheet_head->component_table = 00239 s_table_resize(sheet_head->component_table, 00240 sheet_head->comp_count, 00241 old_comp_attrib_count, sheet_head->comp_attrib_count); 00242 00243 #ifdef DEBUG 00244 printf("In s_toplevel_add_new_attrib, just resized component table.\n"); 00245 #endif 00246 00247 /* Fill out new sheet with new stuff from gtksheet */ 00248 gtk_sheet_insert_columns(GTK_SHEET(sheets[0]), new_index, 1); 00249 x_gtksheet_add_col_labels(GTK_SHEET(sheets[0]), 00250 sheet_head->comp_attrib_count, 00251 sheet_head->master_comp_attrib_list_head); 00252 00253 #ifdef DEBUG 00254 printf("In s_toplevel_add_new_attrib, just updated gtksheet.\n"); 00255 #endif 00256 00257 break; 00258 00259 case 1: /* net attribute */ 00260 /* insert into net attribute list */ 00261 break; 00262 00263 case 2: /* pin attribute */ 00264 /* insert into pin attribute list */ 00265 break; 00266 } /* switch */ 00267 00268 return; 00269 } 00270 00271 00272 /*------------------------------------------------------------------*/ 00279 void s_toplevel_delete_attrib_col() { 00280 gint cur_page; /* current page in notbook */ 00281 gint mincol, maxcol; 00282 GtkSheet *sheet; 00283 gchar *attrib_name; 00284 00285 /* Repeat previous checks */ 00286 cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); 00287 sheet = GTK_SHEET(sheets[cur_page]); 00288 if (sheet == NULL) { 00289 return; 00290 } 00291 mincol = x_gtksheet_get_min_col(sheet); 00292 maxcol = x_gtksheet_get_max_col(sheet); 00293 if ( (mincol != maxcol) || (mincol == -1) || (maxcol == -1) ) { 00294 return; 00295 } 00296 00297 #ifdef DEBUG 00298 printf("In s_toplevel_delete_attrib_col, checks were OK, now do real work\n"); 00299 #endif 00300 00301 /* Rebuild the gattrib-specific data structures */ 00302 switch (cur_page) { 00303 00304 case 0: /* component attribute */ 00305 00306 /* Eventually, I want to just resize the table after deleting the 00307 * attrib. However, that is difficult. Therefore, I will just 00308 * destroy the old table and recreate it for now. */ 00309 00310 s_table_destroy(sheet_head->component_table, 00311 sheet_head->comp_count, sheet_head->comp_attrib_count); 00312 00313 /* Get name (label) of the col to delete from the gtk sheet */ 00314 attrib_name = g_strdup( gtk_sheet_column_button_get_label(sheet, mincol) ); 00315 00316 if (attrib_name != NULL) { 00317 #ifdef DEBUG 00318 printf("In s_toplevel_delete_attrib_col, attrib to delete = %s\n", attrib_name); 00319 #endif 00320 } else { 00321 fprintf(stderr, "In s_toplevel_delete_attrib_col, can't get attrib name\n"); 00322 return; 00323 } 00324 00325 #ifdef DEBUG 00326 printf("In s_toplevel_delete_attrib_col, before deleting comp attrib.\n"); 00327 printf(" comp_attrib_count = %d\n", sheet_head->comp_attrib_count); 00328 #endif 00329 s_string_list_delete_item(&(sheet_head->master_comp_attrib_list_head), 00330 &(sheet_head->comp_attrib_count), 00331 attrib_name); 00332 s_string_list_sort_master_comp_attrib_list(); /* this renumbers list also */ 00333 g_free(attrib_name); 00334 00335 #ifdef DEBUG 00336 printf("In s_toplevel_delete_attrib_col, just updated comp_attrib string list.\n"); 00337 printf(" new comp_attrib_count = %d\n", sheet_head->comp_attrib_count); 00338 #endif 00339 00340 /* Now create new table with new attrib count*/ 00341 sheet_head->component_table = s_table_new(sheet_head->comp_count, 00342 sheet_head->comp_attrib_count); 00343 00344 00345 #ifdef DEBUG 00346 printf("In s_toplevel_delete_attrib_col, just updated SHEET_DATA info.\n"); 00347 #endif 00348 break; 00349 00350 case 1: /* net attribute */ 00351 /* insert into net attribute list */ 00352 break; 00353 00354 case 2: /* pin attribute */ 00355 /* insert into pin attribute list */ 00356 break; 00357 } /* switch */ 00358 00359 00360 /* Delete col on gtksheet */ 00361 #ifdef DEBUG 00362 printf("In s_toplevel_delete_attrib_col, about to delete col in gtksheet.\n"); 00363 #endif 00364 gtk_sheet_delete_columns (sheet, mincol, 1); 00365 #ifdef DEBUG 00366 printf("In s_toplevel_delete_attrib_col, done deleting col in gtksheet.\n"); 00367 #endif 00368 00369 sheet_head->CHANGED = TRUE; /* Set changed flag so user is prompted when exiting */ 00370 00371 return; 00372 } 00373 00374 00375 /* ======================= Private functions ====================== */ 00376 00377 /*------------------------------------------------------------------*/ 00393 void 00394 s_toplevel_sheetdata_to_toplevel (TOPLEVEL *toplevel, PAGE *page) 00395 { 00396 GList *copy_list; 00397 GList *o_iter, *prim_iter; 00398 char *temp_uref; 00399 STRING_LIST *new_comp_attrib_pair_list; 00400 STRING_LIST *new_pin_attrib_list; 00401 00402 /* ----- First deal with all components on the page. ----- */ 00403 #ifdef DEBUG 00404 printf("----- In s_toplevel_sheetdata_to_toplevel, handling components\n"); 00405 #endif 00406 00407 /* Work from a copy list, as objects can be deleted 00408 * from the list during iteration over the list. 00409 */ 00410 /* NB: g_list_copy doesn't declare its input const, so we cast */ 00411 copy_list = g_list_copy ((GList *)s_page_objects (page)); 00412 00413 /* Iterate backwards since attributes are attached after their 00414 * parent objects in the list. Attributes can get deleted during 00415 * the iteration. 00416 */ 00417 for (o_iter = g_list_last (copy_list); 00418 o_iter != NULL; 00419 o_iter = g_list_previous (o_iter)) { 00420 OBJECT *o_current = o_iter->data; 00421 00422 /* ------- Object is a component. Handle component attributes. ------- */ 00423 if (o_current->type == OBJ_COMPLEX) { /* Note that OBJ_COMPLEX = component + attribs */ 00424 00425 #if 0 00426 if (o_attrib_search_object_attribs_by_name (o_current, "graphical", 0)) { 00427 break; /* Ignore graphical components */ 00428 } 00429 #endif 00430 00431 temp_uref = s_attrib_get_refdes(o_current); 00432 if (temp_uref != NULL) { 00433 /* Must create a name=value pair list for each particular component 00434 * which we can pass to function updating o_current. This function 00435 * places all attribs 00436 * found in the row into new_comp_attrib_pair_list. */ 00437 new_comp_attrib_pair_list = s_table_create_attrib_pair(temp_uref, 00438 sheet_head->component_table, 00439 sheet_head->master_comp_list_head, 00440 sheet_head->comp_attrib_count); 00441 00442 00443 /* Now update attribs in toplevel using this list. */ 00444 s_toplevel_update_component_attribs_in_toplevel(toplevel, 00445 o_current, 00446 new_comp_attrib_pair_list); 00447 00448 g_free(temp_uref); 00449 } else { 00450 #ifdef DEBUG 00451 printf("In s_toplevel_sheetdata_to_toplevel, found complex with no refdes. name = %s\n", 00452 o_current->name); 00453 #endif 00454 } 00455 } /* if (o_current->type == OBJ_COMPLEX) */ 00456 00457 } 00458 00459 g_list_free (copy_list); 00460 00461 #if 0 00462 /* ----- Next deal with all nets on the page. ----- */ 00463 /* This is TBD */ 00464 00465 #endif 00466 00467 00468 /* ----- Finally deal with all pins on the page. ----- */ 00469 /* ----- Next deal with all nets on the page. ----- */ 00470 #ifdef DEBUG 00471 printf("----- In s_toplevel_sheetdata_to_toplevel, handling pins\n"); 00472 #endif 00473 00474 /* Work from a copy list in case objects are 00475 * deleted from the list during its iteration. 00476 */ 00477 /* NB: g_list_copy doesn't declare its input const, so we cast */ 00478 copy_list = g_list_copy ((GList *)s_page_objects (page)); 00479 00480 for (o_iter = g_list_last (copy_list); 00481 o_iter != NULL; 00482 o_iter = g_list_previous (o_iter)) { 00483 OBJECT *o_current = o_iter->data; 00484 00485 /* ------- Object is a complex. Handle pins by looking ------ */ 00486 /* ------- for all pins attached to a component. ------ */ 00487 if (o_current->type == OBJ_COMPLEX) { 00488 /* Upon finding a component, here's what to do: 00489 * 0. Get refdes of component. 00490 * 1. Loop over prim_objects, looking for pins. 00491 * 2. When a pin is found, create refdes:pinnumber pair 00492 * used in searching TABLE. 00493 * 3. Search TABLE using refdes:pinnumber as key, and get list of 00494 * attribs corresponding to this refdes:pinnumber 00495 * 4. Stick the attribs into the TOPLEVEL data structure. 00496 */ 00497 temp_uref = s_attrib_get_refdes(o_current); 00498 if ( (temp_uref != NULL) && (o_current->complex->prim_objs) ) { /* make sure object complex has a refdes */ 00499 00500 for (prim_iter = o_current->complex->prim_objs; 00501 prim_iter != NULL; 00502 prim_iter = g_list_next (prim_iter)) { 00503 OBJECT *comp_prim_obj = prim_iter->data; 00504 00505 if (comp_prim_obj->type == OBJ_PIN) { 00506 new_pin_attrib_list = 00507 s_toplevel_get_pin_attribs_in_sheet (temp_uref, comp_prim_obj); 00508 s_toplevel_update_pin_attribs_in_toplevel (toplevel, 00509 temp_uref, 00510 comp_prim_obj, 00511 new_pin_attrib_list); 00512 } 00513 } 00514 } /* if(temp_uref */ 00515 00516 g_free(temp_uref); 00517 } 00518 } 00519 00520 g_list_free (copy_list); 00521 00522 return; 00523 } 00524 00525 00526 /*------------------------------------------------------------------*/ 00534 STRING_LIST *s_toplevel_get_component_attribs_in_sheet(char *refdes) 00535 { 00536 STRING_LIST *new_attrib_list; 00537 STRING_LIST *local_attrib_list; 00538 int i; 00539 int row = -1; 00540 int count = 0; 00541 char *name_value_pair; 00542 char *new_attrib_value; 00543 char *new_attrib_name; 00544 00545 #if DEBUG 00546 printf("----- Entering s_toplevel_get_component_attribs_in_sheet.\n"); 00547 #endif 00548 00549 00550 /* First find pos of this refdes in the master list */ 00551 row = s_table_get_index(sheet_head->master_comp_list_head, refdes); 00552 00553 /* Sanity check */ 00554 if (row == -1) { 00555 /* we didn't find the item in the list */ 00556 fprintf(stderr, 00557 "In s_toplevel_get_component_attribs_in_sheet, we didn't find the refdes in the master list!\n"); 00558 return NULL; 00559 } 00560 00561 /* Now get all attribs associated with this refdes (in TABLE, indexed 00562 * by position), and insert them into new_attrib_list. */ 00563 new_attrib_list = s_string_list_new(); /* init new_attrib_list */ 00564 00565 i = 0; 00566 local_attrib_list = sheet_head->master_comp_attrib_list_head; 00567 while (local_attrib_list != NULL) { /* iterate over all possible attribs */ 00568 new_attrib_name = g_strdup(local_attrib_list->data); /* take attrib name from column headings */ 00569 00570 if ( ((sheet_head->component_table)[row][i]).attrib_value ) { 00571 new_attrib_value = g_strdup( ((sheet_head->component_table)[row][i]).attrib_value ); 00572 name_value_pair = g_strconcat(new_attrib_name, "=", new_attrib_value, NULL); 00573 g_free(new_attrib_value); 00574 } else { 00575 name_value_pair = g_strconcat(new_attrib_name, "=", NULL); /* empty attrib */ 00576 } 00577 s_string_list_add_item(new_attrib_list, &count, name_value_pair); /* add name=value to new list */ 00578 g_free(new_attrib_name); 00579 g_free(name_value_pair); 00580 00581 /* Sanity check */ 00582 if (count != i+1) { 00583 /* for some reason, we have lost a name_value_pair somewhere . . . */ 00584 fprintf(stderr, 00585 "In s_toplevel_get_component_attribs_in_sheet, count != i! Exiting . . . .\n"); 00586 exit(-1); 00587 } 00588 00589 /* iterate */ 00590 i++; 00591 local_attrib_list = local_attrib_list->next; 00592 } /* while (local_attrib_list != NULL) */ 00593 00594 return new_attrib_list; 00595 } 00596 00597 00598 00599 /*------------------------------------------------------------------*/ 00622 void 00623 s_toplevel_update_component_attribs_in_toplevel ( 00624 TOPLEVEL *toplevel, 00625 OBJECT *o_current, 00626 STRING_LIST *new_comp_attrib_list) 00627 { 00628 STRING_LIST *local_list; 00629 STRING_LIST *complete_comp_attrib_list; 00630 char *old_name_value_pair; 00631 char *new_attrib_name; 00632 char *new_attrib_value; 00633 char *old_attrib_name; 00634 char *old_attrib_value; 00635 gchar *refdes; 00636 GList *a_iter; 00637 OBJECT *a_current; 00638 int count = 0; /* This is to fake out a function called later */ 00639 gint row, col; 00640 gint visibility = 0; 00641 gint show_name_value = 0; 00642 00643 #if DEBUG 00644 printf("----- Entering s_toplevel_update_component_attribs_in_toplevel.\n"); 00645 #endif 00646 00647 /* 00648 * To remove dead attribs from o_current, we need to form a complete list of unique 00649 * attribs by taking the union of the new attribs from the SHEET_DATA, and 00650 * the old attribs living on o_current. That's what we're doing here. 00651 * Later, we can delete those attribs in o_current which don't apear in 00652 * new_comp_attrib_list. 00653 */ 00654 /* First duplicate new_comp_attrib_list */ 00655 complete_comp_attrib_list = s_string_list_duplicate_string_list(new_comp_attrib_list); 00656 00657 /* Now create a complete list of unique attribute names. This will be used in 00658 * the loop below when updating attributes. */ 00659 a_iter = o_current->attribs; 00660 while (a_iter != NULL) { 00661 a_current = a_iter->data; 00662 if (a_current->type == OBJ_TEXT 00663 && a_current->text != NULL) { /* found a name=value attribute pair. */ 00664 /* may need to check more thoroughly here. . . . */ 00665 old_name_value_pair = g_strdup(a_current->text->string); 00666 00667 /* Else clause is suggestion from Ales */ 00668 #if 1 00669 old_attrib_name = u_basic_breakup_string(old_name_value_pair, '=', 0); 00670 if ( (strcmp(old_attrib_name, "refdes") != 0) && 00671 (strcmp(old_attrib_name, "net") != 0) && 00672 (strcmp(old_attrib_name, "slot") != 0) && 00673 (s_attrib_name_in_list(new_comp_attrib_list, old_attrib_name) == FALSE) ) { 00674 s_string_list_add_item(complete_comp_attrib_list, &count, old_name_value_pair); 00675 } 00676 #else 00677 /* might now compile now, but this #if'd out branch isn't being built */ 00678 gint status; 00679 status = o_attrib_get_name_value (a_current, &old_attrib_name, &old_attrib_value); 00680 if (status == 0) { 00681 /* Don't put "refdes" or "slot" into list. Don't put old name=value pair into list if a new 00682 * one is already in there. */ 00683 if ( (strcmp(old_attrib_name, "refdes") != 0) && 00684 (strcmp(old_attrib_name, "net") != 0) && 00685 (strcmp(old_attrib_name, "slot") != 0) && 00686 (s_attrib_name_in_list(new_comp_attrib_list, old_attrib_name) == FALSE) ) { 00687 s_string_list_add_item(complete_comp_attrib_list, &count, old_name_value_pair); 00688 } 00689 g_free (old_attrib_name); 00690 g_free (old_attrib_value); 00691 } 00692 #endif 00693 g_free(old_name_value_pair); 00694 g_free(old_attrib_name); 00695 } 00696 a_iter = g_list_next (a_iter); 00697 } /* while (a_current != NULL) */ 00698 00699 00700 /* 00701 *Now the main business of this function: updating the attribs attached to this o_current. 00702 * Loop on name=value pairs held in complete_comp_attrib_list , and then use this to get the 00703 * name=value pairs out of new_comp_attrib_list and from o_current. 00704 */ 00705 00706 /* First handle a special case: the component has no attribs (beside refdes). */ 00707 if (complete_comp_attrib_list->data == NULL) 00708 return; 00709 00710 /* Now the normal case. . . . */ 00711 local_list = complete_comp_attrib_list; 00712 while (local_list != NULL) { 00713 00714 #if DEBUG 00715 printf("\n\n"); 00716 printf(" In s_toplevel_update_component_attribs_in_toplevel, handling entry in complete list %s .\n", 00717 local_list->data); 00718 #endif 00719 00720 /* Now get the old attrib name & value from complete_comp_attrib_list 00721 * and value from o_current */ 00722 old_attrib_name = u_basic_breakup_string(local_list->data, '=', 0); 00723 old_attrib_value = o_attrib_search_attached_attribs_by_name (o_current, old_attrib_name, 0); 00724 00725 #if DEBUG 00726 printf(" In s_toplevel_update_component_attribs_in_toplevel, old name = \"%s\" .\n", 00727 old_attrib_name); 00728 printf(" In s_toplevel_update_component_attribs_in_toplevel, old value = \"%s\" .\n", 00729 old_attrib_value); 00730 #endif 00731 00732 /* Next try to get this attrib from new_comp_attrib_list */ 00733 new_attrib_name = u_basic_breakup_string(local_list->data, '=', 0); 00734 if (s_string_list_in_list(new_comp_attrib_list, local_list->data)) { 00735 new_attrib_value = s_misc_remaining_string(local_list->data, '=', 1); 00736 } else { 00737 new_attrib_value = NULL; 00738 } 00739 #if DEBUG 00740 printf(" In s_toplevel_update_component_attribs_in_toplevel, new name = \"%s\" .\n", 00741 new_attrib_name); 00742 printf(" In s_toplevel_update_component_attribs_in_toplevel, new value = \"%s\" .\n", 00743 new_attrib_value); 00744 #endif 00745 00746 /* Now get row and col where this new attrib lives. Then get 00747 * visibility of the new attrib stored in the component table */ 00748 /* We'll need this later */ 00749 refdes = g_strdup(s_attrib_get_refdes(o_current)); 00750 row = s_table_get_index(sheet_head->master_comp_list_head, refdes); 00751 col = s_table_get_index(sheet_head->master_comp_attrib_list_head, new_attrib_name); 00752 /* if attribute has been deleted from the sheet, here is where we detect that */ 00753 if ( (row == -1) || (col == -1) ) { 00754 new_attrib_value = NULL; /* attrib will be deleted below */ 00755 } else { /* we need a better place to get this info since the TABLE can be out of date */ 00756 visibility = sheet_head->component_table[row][col].visibility; 00757 show_name_value = sheet_head->component_table[row][col].show_name_value; 00758 } 00759 g_free(refdes); 00760 00761 00762 /* ------- Four cases to consider: Case 1 ----- */ 00763 if ( (old_attrib_value != NULL) && (new_attrib_value != NULL) && (strlen(new_attrib_value) != 0) ) { 00764 /* simply write new attrib into place of old one. */ 00765 #if DEBUG 00766 printf(" -- In s_toplevel_update_component_attribs_in_toplevel,\n"); 00767 printf(" about to replace old attrib with name= %s, value= %s\n", 00768 new_attrib_name, new_attrib_value); 00769 printf(" visibility = %d, show_name_value = %d.\n", 00770 visibility, show_name_value); 00771 #endif 00772 s_object_replace_attrib_in_object(toplevel, 00773 o_current, 00774 new_attrib_name, 00775 new_attrib_value, 00776 visibility, 00777 show_name_value); 00778 } 00779 00780 /* ------- Four cases to consider: Case 2 ----- */ 00781 else if ( (old_attrib_value != NULL) && (new_attrib_value == NULL) ) { 00782 /* remove attrib from component*/ 00783 #if DEBUG 00784 printf(" -- In s_toplevel_update_component_attribs_in_toplevel, about to remove old attrib with name= %s, value= %s\n", 00785 old_attrib_name, old_attrib_value); 00786 #endif 00787 s_object_remove_attrib_in_object (toplevel, o_current, old_attrib_name); 00788 } 00789 00790 /* ------- Four cases to consider: Case 3 ----- */ 00791 else if ( (old_attrib_value == NULL) && (new_attrib_value != NULL) ) { 00792 /* add new attrib to component. */ 00793 00794 #if DEBUG 00795 printf(" -- In s_toplevel_update_component_attribs_in_toplevel, about to add new attrib with name= %s, value= %s\n", 00796 new_attrib_name, new_attrib_value); 00797 #endif 00798 00799 s_object_add_comp_attrib_to_object (toplevel, 00800 o_current, 00801 new_attrib_name, 00802 new_attrib_value, 00803 visibility, 00804 show_name_value); 00805 00806 /* ------- Four cases to consider: Case 4 ----- */ 00807 } else { 00808 /* Do nothing. */ 00809 #if DEBUG 00810 printf(" -- In s_toplevel_update_component_attribs_in_toplevel, nothing needs to be done.\n"); 00811 #endif 00812 } 00813 00814 /* Toggle attribute visibility and name/value setting */ 00815 00816 00817 /* free everything and iterate */ 00818 g_free(new_attrib_name); 00819 g_free(new_attrib_value); 00820 g_free(old_attrib_name); 00821 g_free(old_attrib_value); 00822 local_list = local_list->next; 00823 } /* while (local_list != NULL) */ 00824 return; 00825 } 00826 00827 00828 /*------------------------------------------------------------------*/ 00832 STRING_LIST *s_toplevel_get_net_attribs_in_sheet(char *netname) 00833 { 00834 /* must be filled in */ 00835 return NULL; 00836 } 00837 00838 00839 /*------------------------------------------------------------------*/ 00843 void s_toplevel_update_net_attribs_in_toplevel(OBJECT *o_current, 00844 STRING_LIST *new_net_attrib_list) 00845 { 00846 /* must be filled in */ 00847 return; 00848 } 00849 00850 00851 /*------------------------------------------------------------------*/ 00868 STRING_LIST *s_toplevel_get_pin_attribs_in_sheet(char *refdes, OBJECT *pin) 00869 { 00870 STRING_LIST *new_attrib_list; 00871 STRING_LIST *local_attrib_list; 00872 int i; 00873 int row = -1; 00874 int count = 0; 00875 char *pinnumber; 00876 char *row_label; 00877 char *name_value_pair; 00878 char *new_attrib_value; 00879 char *new_attrib_name; 00880 00881 #if DEBUG 00882 printf("----- Entering s_toplevel_get_pin_attribs_in_sheet.\n"); 00883 #endif 00884 00885 /* First find pos of this pin in the master pin list */ 00886 /* first convert refdes, pin to refdes:pinno text string. Then call table_get_index. */ 00887 00888 pinnumber = o_attrib_search_object_attribs_by_name (pin, "pinnumber", 0); 00889 00890 if ( (refdes != NULL) && (pinnumber != NULL) ) { 00891 row_label = g_strconcat(refdes, ":", pinnumber, NULL); 00892 } else { 00893 fprintf(stderr, 00894 "In s_toplevel_get_pin_attribs_in_sheet, either refdes or pinnumber of object missing!\n"); 00895 return NULL; 00896 } 00897 row = s_table_get_index(sheet_head->master_pin_list_head, row_label); 00898 00899 /* Sanity check */ 00900 if (row == -1) { 00901 /* we didn't find the item in the list */ 00902 fprintf(stderr, 00903 "In s_toplevel_get_pin_attribs_in_sheet, we didn't find the refdes:pin in the master list!\n"); 00904 return NULL; 00905 } 00906 00907 /* Now get all attribs associated with this refdes (in TABLE, indexed 00908 * by position), and insert them into new_attrib_list. */ 00909 new_attrib_list = s_string_list_new(); /* init new_attrib_list */ 00910 00911 i = 0; 00912 local_attrib_list = sheet_head->master_pin_attrib_list_head; 00913 while (local_attrib_list != NULL) { /* iterate over all possible attribs */ 00914 new_attrib_name = g_strdup(local_attrib_list->data); /* take attrib name from column headings */ 00915 00916 if ( ((sheet_head->pin_table)[row][i]).attrib_value ) { 00917 new_attrib_value = g_strdup( ((sheet_head->pin_table)[row][i]).attrib_value ); 00918 name_value_pair = g_strconcat(new_attrib_name, "=", new_attrib_value, NULL); 00919 g_free(new_attrib_value); 00920 } else { 00921 name_value_pair = g_strconcat(new_attrib_name, "=", NULL); /* empty attrib */ 00922 } 00923 s_string_list_add_item(new_attrib_list, &count, name_value_pair); /* add name=value to new list */ 00924 g_free(new_attrib_name); 00925 g_free(name_value_pair); 00926 00927 /* Sanity check */ 00928 if (count != i+1) { 00929 /* for some reason, we have lost a name_value_pair somewhere . . . */ 00930 fprintf(stderr, 00931 "In s_toplevel_get_pin_attribs_in_sheet, count != i! Exiting . . . .\n"); 00932 exit(-1); 00933 } 00934 00935 /* iterate */ 00936 i++; 00937 local_attrib_list = local_attrib_list->next; 00938 } /* while (local_attrib_list != NULL) */ 00939 00940 return new_attrib_list; 00941 } 00942 00943 00944 00945 /*------------------------------------------------------------------*/ 00963 void 00964 s_toplevel_update_pin_attribs_in_toplevel (TOPLEVEL *toplevel, 00965 char *refdes, 00966 OBJECT *o_pin, 00967 STRING_LIST *new_pin_attrib_list) 00968 { 00969 STRING_LIST *local_list; 00970 char *new_name_value_pair; 00971 char *new_attrib_name; 00972 char *new_attrib_value; 00973 char *old_attrib_value; 00974 00975 #if DEBUG 00976 printf("----- Entering s_toplevel_update_pin_attribs_in_toplevel.\n"); 00977 #endif 00978 00979 /* loop on name=value pairs held in new_pin_attrib_list */ 00980 local_list = new_pin_attrib_list; 00981 while (local_list != NULL) { 00982 new_name_value_pair = g_strdup(local_list->data); 00983 #if DEBUG 00984 printf(" In s_toplevel_update_pin_attribs_in_toplevel, handling entry in master list %s .\n", new_name_value_pair); 00985 #endif 00986 00987 new_attrib_name = u_basic_breakup_string(new_name_value_pair, '=', 0); 00988 new_attrib_value = u_basic_breakup_string(new_name_value_pair, '=', 1); 00989 00990 if (strlen(new_attrib_value) == 0) { 00991 g_free(new_attrib_value); 00992 new_attrib_value = NULL; /* s_misc_remaining_string doesn't return NULL for empty substring. */ 00993 } 00994 old_attrib_value = o_attrib_search_attached_attribs_by_name (o_pin, new_attrib_name, 0); 00995 00996 /* ------- Four cases to consider: Case 1: old and new attribs exist ----- */ 00997 if ( (old_attrib_value != NULL) && (new_attrib_value != NULL) && (strlen(new_attrib_value) != 0) ) { 00998 /* simply write new attrib into place of old one. */ 00999 #if DEBUG 01000 printf("In s_toplevel_update_pin_attribs_in_toplevel, about to replace old attrib with new one: name= %s, value= %s\n", 01001 new_attrib_name, new_attrib_value); 01002 #endif 01003 s_object_replace_attrib_in_object(toplevel, 01004 o_pin, 01005 new_attrib_name, 01006 new_attrib_value, 01007 LEAVE_VISIBILITY_ALONE, 01008 LEAVE_NAME_VALUE_ALONE); 01009 } 01010 01011 /* ------- Four cases to consider: Case 2: old attrib exists, new one doesn't ----- */ 01012 else if ( (old_attrib_value != NULL) && (new_attrib_value == NULL) ) { 01013 /* remove attrib from pin */ 01014 #if DEBUG 01015 printf("In s_toplevel_update_pin_attribs_in_toplevel, about to remove old attrib with name= %s, value= %s\n", 01016 new_attrib_name, old_attrib_value); 01017 #endif 01018 s_object_remove_attrib_in_object (toplevel, o_pin, new_attrib_name); 01019 } 01020 01021 /* ------- Four cases to consider: Case 3: No old attrib, new one exists. ----- */ 01022 else if ( (old_attrib_value == NULL) && (new_attrib_value != NULL) ) { 01023 /* add new attrib to pin. */ 01024 01025 #if DEBUG 01026 printf("In s_toplevel_update_pin_attribs_in_toplevel, about to add new attrib with name= %s, value= %s\n", 01027 new_attrib_name, new_attrib_value); 01028 #endif 01029 01030 s_object_add_pin_attrib_to_object (toplevel, 01031 o_pin, 01032 new_attrib_name, 01033 new_attrib_value); 01034 01035 /* ------- Four cases to consider: Case 4 ----- */ 01036 } else { 01037 /* Do nothing. */ 01038 #if DEBUG 01039 printf("In s_toplevel_update_pin_attribs_in_toplevel, nothing needs to be done.\n"); 01040 #endif 01041 } 01042 01043 /* free everything and iterate */ 01044 g_free(new_name_value_pair); 01045 g_free(new_attrib_name); 01046 g_free(new_attrib_value); 01047 g_free(old_attrib_value); 01048 local_list = local_list->next; 01049 } /* while (local_list != NULL) */ 01050 01051 return; 01052 } 01053 01054 01055 01056