gattrib

s_toplevel.c

Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines