/*! \brief Create attribute pair * * This function takes a table, a row list, and a row name, * and returns a list holding * name=value pairs for all attribs pertainent to that particular * row. * If the row holds no attribs, it just returns NULL. * * \param row_name Name of the row to search for * \param table Table to be searched * \param row_list list of rows * \param num_attribs * \returns STRING_LIST of name=value pairs */ STRING_LIST *s_table_create_attrib_pair(gchar *row_name, TABLE **table, STRING_LIST *row_list, int num_attribs) { STRING_LIST *attrib_pair_list; char *attrib_name, *attrib_value, *name_value_pair; int row, col; int count = 0; attrib_pair_list = s_string_list_new(); row = s_table_get_index(row_list, row_name); /* Sanity check */ if (row == -1) { /* we didn't find the item in the list */ fprintf (stderr, "In s_table_create_attrib_pair, we didn't find the row name in the row list!\n"); return attrib_pair_list; } for (col = 0; col < num_attribs; col++) { /* pull attrib from table. If non-null, add it to attrib_pair_list */ if ( (table[row][col]).attrib_value != NULL) { attrib_name = (table[row][col]).col_name; attrib_value = (table[row][col]).attrib_value; name_value_pair = g_strconcat(attrib_name, "=", attrib_value, NULL); s_string_list_add_item(attrib_pair_list, &count, name_value_pair); g_free(name_value_pair); } } return attrib_pair_list; }
/*! \brief Duplicate a STRING_LIST * * Given a STRING_LIST, duplicate it and returns a pointer * to the new, duplicate list. * \param old_string_list pointer to the STRING_LIST to be duplicated * \returns a pointer to the duplicate STRING_LIST */ STRING_LIST *s_string_list_duplicate_string_list(STRING_LIST *old_string_list) { STRING_LIST *new_string_list; STRING_LIST *local_string_list; char *data; gint count; new_string_list = s_string_list_new(); if (old_string_list->data == NULL) /* This is an empty string list */ return new_string_list; local_string_list = old_string_list; while (local_string_list != NULL) { data = g_strdup(local_string_list->data); s_string_list_add_item(new_string_list, &count, data); g_free(data); local_string_list = local_string_list->next; } return new_string_list; }
/*! \brief Get pin attributes * * This function takes a pointer to the OBJECT pin, and returns a list * of attribs found attached to the pin. The returned list is a * STRING_LIST where the ->data holds a name=value string. * The algorithm is as follows: * -# Form refdes:pinnumber label for this pin. * -# Get row number of this refdes:pinnumber * -# Create a list of name=value pairs from entries in the pin_table * on this row. * -# Return list of name=value pairs found. * * \param refdes Ref des string * \param pin Pin object * \returns name=value pair as a STRING_LIST */ STRING_LIST *s_toplevel_get_pin_attribs_in_sheet(char *refdes, OBJECT *pin) { STRING_LIST *new_attrib_list; STRING_LIST *local_attrib_list; int i; int row = -1; int count = 0; char *pinnumber; char *row_label; char *name_value_pair; char *new_attrib_value; char *new_attrib_name; #if DEBUG printf("----- Entering s_toplevel_get_pin_attribs_in_sheet.\n"); #endif /* First find pos of this pin in the master pin list */ /* first convert refdes, pin to refdes:pinno text string. Then call table_get_index. */ pinnumber = o_attrib_search_object_attribs_by_name (pin, "pinnumber", 0); if ( (refdes != NULL) && (pinnumber != NULL) ) { row_label = g_strconcat(refdes, ":", pinnumber, NULL); } else { fprintf(stderr, "In s_toplevel_get_pin_attribs_in_sheet, either refdes or pinnumber of object missing!\n"); return NULL; } row = s_table_get_index(sheet_head->master_pin_list_head, row_label); /* Sanity check */ if (row == -1) { /* we didn't find the item in the list */ fprintf(stderr, "In s_toplevel_get_pin_attribs_in_sheet, we didn't find the refdes:pin in the master list!\n"); return NULL; } /* Now get all attribs associated with this refdes (in TABLE, indexed * by position), and insert them into new_attrib_list. */ new_attrib_list = s_string_list_new(); /* init new_attrib_list */ i = 0; local_attrib_list = sheet_head->master_pin_attrib_list_head; while (local_attrib_list != NULL) { /* iterate over all possible attribs */ new_attrib_name = g_strdup(local_attrib_list->data); /* take attrib name from column headings */ if ( ((sheet_head->pin_table)[row][i]).attrib_value ) { new_attrib_value = g_strdup( ((sheet_head->pin_table)[row][i]).attrib_value ); name_value_pair = g_strconcat(new_attrib_name, "=", new_attrib_value, NULL); g_free(new_attrib_value); } else { name_value_pair = g_strconcat(new_attrib_name, "=", NULL); /* empty attrib */ } s_string_list_add_item(new_attrib_list, &count, name_value_pair); /* add name=value to new list */ g_free(new_attrib_name); g_free(name_value_pair); /* Sanity check */ if (count != i+1) { /* for some reason, we have lost a name_value_pair somewhere . . . */ fprintf(stderr, "In s_toplevel_get_pin_attribs_in_sheet, count != i! Exiting . . . .\n"); exit(-1); } /* iterate */ i++; local_attrib_list = local_attrib_list->next; } /* while (local_attrib_list != NULL) */ return new_attrib_list; }
/*! \brief Update component attributes in TOP_LEVEL * * For each attrib string attached to the component, update it using the value * held in new_comp_attrib_list. Algorithm: * -# Form list of all component attribs held on both the component * (o_current), as well as in the attrib list (SHEET_DATA). * -# Loop over name=value pairs held in complete_comp_attrib_list. * -# For each name=value pair, look for corresponding attrib on o_current. * -# For each name=value pair, look for the corresponding attrib in * new_comp_attrib_list. * -# If the attrib exists on o_current and in new_comp_attrib_list, write the * new value (from new_comp_attrib_list) into o_current. * -# If the attrib exists on o_current, but is null in name=value pair, * delete the attrib from o_current. * -# If the attribs doesn't exist on o_current, but is non-null in * the name=value pair, create an attrib object and add it to the part * on o_current. * \param toplevel TOPLEVEL structure * \param o_current Component (complex) to be updated. * \param new_comp_attrib_list list of name=value attribute pairs * from SHEET_DATA. */ void s_toplevel_update_component_attribs_in_toplevel ( TOPLEVEL *toplevel, OBJECT *o_current, STRING_LIST *new_comp_attrib_list) { STRING_LIST *local_list; STRING_LIST *complete_comp_attrib_list; char *old_name_value_pair; char *new_attrib_name; char *new_attrib_value; char *old_attrib_name; char *old_attrib_value; gchar *refdes; GList *a_iter; OBJECT *a_current; int count = 0; /* This is to fake out a function called later */ gint row, col; gint visibility = 0; gint show_name_value = 0; #if DEBUG printf("----- Entering s_toplevel_update_component_attribs_in_toplevel.\n"); #endif /* * To remove dead attribs from o_current, we need to form a complete list of unique * attribs by taking the union of the new attribs from the SHEET_DATA, and * the old attribs living on o_current. That's what we're doing here. * Later, we can delete those attribs in o_current which don't apear in * new_comp_attrib_list. */ /* First duplicate new_comp_attrib_list */ complete_comp_attrib_list = s_string_list_duplicate_string_list(new_comp_attrib_list); /* Now create a complete list of unique attribute names. This will be used in * the loop below when updating attributes. */ a_iter = o_current->attribs; while (a_iter != NULL) { a_current = a_iter->data; if (a_current->type == OBJ_TEXT && a_current->text != NULL) { /* found a name=value attribute pair. */ /* may need to check more thoroughly here. . . . */ old_name_value_pair = g_strdup(a_current->text->string); /* Else clause is suggestion from Ales */ #if 1 old_attrib_name = u_basic_breakup_string(old_name_value_pair, '=', 0); if ( (strcmp(old_attrib_name, "refdes") != 0) && (strcmp(old_attrib_name, "net") != 0) && (strcmp(old_attrib_name, "slot") != 0) && (s_attrib_name_in_list(new_comp_attrib_list, old_attrib_name) == FALSE) ) { s_string_list_add_item(complete_comp_attrib_list, &count, old_name_value_pair); } #else /* might now compile now, but this #if'd out branch isn't being built */ gint status; status = o_attrib_get_name_value (a_current, &old_attrib_name, &old_attrib_value); if (status == 0) { /* Don't put "refdes" or "slot" into list. Don't put old name=value pair into list if a new * one is already in there. */ if ( (strcmp(old_attrib_name, "refdes") != 0) && (strcmp(old_attrib_name, "net") != 0) && (strcmp(old_attrib_name, "slot") != 0) && (s_attrib_name_in_list(new_comp_attrib_list, old_attrib_name) == FALSE) ) { s_string_list_add_item(complete_comp_attrib_list, &count, old_name_value_pair); } g_free (old_attrib_name); g_free (old_attrib_value); } #endif g_free(old_name_value_pair); g_free(old_attrib_name); } a_iter = g_list_next (a_iter); } /* while (a_current != NULL) */ /* *Now the main business of this function: updating the attribs attached to this o_current. * Loop on name=value pairs held in complete_comp_attrib_list , and then use this to get the * name=value pairs out of new_comp_attrib_list and from o_current. */ /* First handle a special case: the component has no attribs (beside refdes). */ if (complete_comp_attrib_list->data == NULL) return; /* Now the normal case. . . . */ local_list = complete_comp_attrib_list; while (local_list != NULL) { #if DEBUG printf("\n\n"); printf(" In s_toplevel_update_component_attribs_in_toplevel, handling entry in complete list %s .\n", local_list->data); #endif /* Now get the old attrib name & value from complete_comp_attrib_list * and value from o_current */ old_attrib_name = u_basic_breakup_string(local_list->data, '=', 0); old_attrib_value = o_attrib_search_attached_attribs_by_name (o_current, old_attrib_name, 0); #if DEBUG printf(" In s_toplevel_update_component_attribs_in_toplevel, old name = \"%s\" .\n", old_attrib_name); printf(" In s_toplevel_update_component_attribs_in_toplevel, old value = \"%s\" .\n", old_attrib_value); #endif /* Next try to get this attrib from new_comp_attrib_list */ new_attrib_name = u_basic_breakup_string(local_list->data, '=', 0); if (s_string_list_in_list(new_comp_attrib_list, local_list->data)) { new_attrib_value = s_misc_remaining_string(local_list->data, '=', 1); } else { new_attrib_value = NULL; } #if DEBUG printf(" In s_toplevel_update_component_attribs_in_toplevel, new name = \"%s\" .\n", new_attrib_name); printf(" In s_toplevel_update_component_attribs_in_toplevel, new value = \"%s\" .\n", new_attrib_value); #endif /* Now get row and col where this new attrib lives. Then get * visibility of the new attrib stored in the component table */ /* We'll need this later */ refdes = g_strdup(s_attrib_get_refdes(o_current)); row = s_table_get_index(sheet_head->master_comp_list_head, refdes); col = s_table_get_index(sheet_head->master_comp_attrib_list_head, new_attrib_name); /* if attribute has been deleted from the sheet, here is where we detect that */ if ( (row == -1) || (col == -1) ) { new_attrib_value = NULL; /* attrib will be deleted below */ } else { /* we need a better place to get this info since the TABLE can be out of date */ visibility = sheet_head->component_table[row][col].visibility; show_name_value = sheet_head->component_table[row][col].show_name_value; } g_free(refdes); /* ------- Four cases to consider: Case 1 ----- */ if ( (old_attrib_value != NULL) && (new_attrib_value != NULL) && (strlen(new_attrib_value) != 0) ) { /* simply write new attrib into place of old one. */ #if DEBUG printf(" -- In s_toplevel_update_component_attribs_in_toplevel,\n"); printf(" about to replace old attrib with name= %s, value= %s\n", new_attrib_name, new_attrib_value); printf(" visibility = %d, show_name_value = %d.\n", visibility, show_name_value); #endif s_object_replace_attrib_in_object(toplevel, o_current, new_attrib_name, new_attrib_value, visibility, show_name_value); } /* ------- Four cases to consider: Case 2 ----- */ else if ( (old_attrib_value != NULL) && (new_attrib_value == NULL) ) { /* remove attrib from component*/ #if DEBUG printf(" -- In s_toplevel_update_component_attribs_in_toplevel, about to remove old attrib with name= %s, value= %s\n", old_attrib_name, old_attrib_value); #endif s_object_remove_attrib_in_object (toplevel, o_current, old_attrib_name); } /* ------- Four cases to consider: Case 3 ----- */ else if ( (old_attrib_value == NULL) && (new_attrib_value != NULL) ) { /* add new attrib to component. */ #if DEBUG printf(" -- In s_toplevel_update_component_attribs_in_toplevel, about to add new attrib with name= %s, value= %s\n", new_attrib_name, new_attrib_value); #endif s_object_add_comp_attrib_to_object (toplevel, o_current, new_attrib_name, new_attrib_value, visibility, show_name_value); /* ------- Four cases to consider: Case 4 ----- */ } else { /* Do nothing. */ #if DEBUG printf(" -- In s_toplevel_update_component_attribs_in_toplevel, nothing needs to be done.\n"); #endif } /* Toggle attribute visibility and name/value setting */ /* free everything and iterate */ g_free(new_attrib_name); g_free(new_attrib_value); g_free(old_attrib_name); g_free(old_attrib_value); local_list = local_list->next; } /* while (local_list != NULL) */ return; }
/*! \brief Get the component attributes from the top level * * This function returns a list of attributes attached to obj_name = comp * refdes or netlist. * \param refdes component refdes to return values from * \returns a STRING_LIST where the data field holds a name=value string. */ STRING_LIST *s_toplevel_get_component_attribs_in_sheet(char *refdes) { STRING_LIST *new_attrib_list; STRING_LIST *local_attrib_list; int i; int row = -1; int count = 0; char *name_value_pair; char *new_attrib_value; char *new_attrib_name; #if DEBUG printf("----- Entering s_toplevel_get_component_attribs_in_sheet.\n"); #endif /* First find pos of this refdes in the master list */ row = s_table_get_index(sheet_head->master_comp_list_head, refdes); /* Sanity check */ if (row == -1) { /* we didn't find the item in the list */ fprintf(stderr, "In s_toplevel_get_component_attribs_in_sheet, we didn't find the refdes in the master list!\n"); return NULL; } /* Now get all attribs associated with this refdes (in TABLE, indexed * by position), and insert them into new_attrib_list. */ new_attrib_list = s_string_list_new(); /* init new_attrib_list */ i = 0; local_attrib_list = sheet_head->master_comp_attrib_list_head; while (local_attrib_list != NULL) { /* iterate over all possible attribs */ new_attrib_name = g_strdup(local_attrib_list->data); /* take attrib name from column headings */ if ( ((sheet_head->component_table)[row][i]).attrib_value ) { new_attrib_value = g_strdup( ((sheet_head->component_table)[row][i]).attrib_value ); name_value_pair = g_strconcat(new_attrib_name, "=", new_attrib_value, NULL); g_free(new_attrib_value); } else { name_value_pair = g_strconcat(new_attrib_name, "=", NULL); /* empty attrib */ } s_string_list_add_item(new_attrib_list, &count, name_value_pair); /* add name=value to new list */ g_free(new_attrib_name); g_free(name_value_pair); /* Sanity check */ if (count != i+1) { /* for some reason, we have lost a name_value_pair somewhere . . . */ fprintf(stderr, "In s_toplevel_get_component_attribs_in_sheet, count != i! Exiting . . . .\n"); exit(-1); } /* iterate */ i++; local_attrib_list = local_attrib_list->next; } /* while (local_attrib_list != NULL) */ return new_attrib_list; }
/*! \brief Add a new attribute to the top level * * This function gets called when the user has entered a new attrib name, * and clicked the OK button. It does this: * -# It figures out which attrib/sheet is being added to * -# It destroys the old table in preparation for the new attrib. * -# It adds the new attrib to the master lists. * -# It creates a new table with the new attrib. * -# It then adds the appropriate col to the gtksheet. * \param new_attrib_name attribute to be added */ void s_toplevel_add_new_attrib(gchar *new_attrib_name) { gint cur_page; /* current page in notbook */ gint old_comp_attrib_count; if (strcmp(new_attrib_name, "_cancel") == 0) { return; /* user pressed cancel or closed window with no value in entry */ } /* Next must figure out which sheet the attrib belongs to. */ cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); #ifdef DEBUG printf("In s_toplevel_add_new_attrib, adding new attrib to page %d.\n", cur_page); #endif switch (cur_page) { case 0: /* component attribute */ /* Eventually, I want to just resize the table to accomodate the * new attrib. However, that is difficult. Therefore, I will just * destroy the old table and recreate it for now. */ /* s_table_destroy(sheet_head->component_table, sheet_head->comp_count, sheet_head->comp_attrib_count); */ old_comp_attrib_count = sheet_head->comp_attrib_count; #ifdef DEBUG printf("In s_toplevel_add_new_attrib, before adding new comp attrib.\n"); printf(" comp_attrib_count = %d\n", old_comp_attrib_count); #endif s_string_list_add_item(sheet_head->master_comp_attrib_list_head, &(sheet_head->comp_attrib_count), new_attrib_name); s_string_list_sort_master_comp_attrib_list(); #ifdef DEBUG printf("In s_toplevel_add_new_attrib, just updated comp_attrib string list.\n"); printf(" new comp_attrib_count = %d\n", sheet_head->comp_attrib_count); #endif /* Now create new table */ /* sheet_head->component_table = s_table_new(sheet_head->comp_count, sheet_head->comp_attrib_count); */ /* resize table to accomodate new attrib col */ sheet_head->component_table = s_table_resize(sheet_head->component_table, sheet_head->comp_count, old_comp_attrib_count, sheet_head->comp_attrib_count); #ifdef DEBUG printf("In s_toplevel_add_new_attrib, just resized component table.\n"); #endif /* Fill out new sheet with new stuff from gtksheet */ gtk_sheet_insert_columns(GTK_SHEET(sheets[0]), sheet_head->comp_attrib_count, 1); x_gtksheet_add_col_labels(GTK_SHEET(sheets[0]), sheet_head->comp_attrib_count, sheet_head->master_comp_attrib_list_head); #ifdef DEBUG printf("In s_toplevel_add_new_attrib, just updated gtksheet.\n"); #endif break; case 1: /* net attribute */ /* insert into net attribute list */ break; case 2: /* pin attribute */ /* insert into pin attribute list */ break; } /* switch */ return; }