/*! \brief Replace attribute value in object * * Find the instance of attrib_name on o_current, and * replace its value with the new_attrib_value. * \param toplevel TOPLEVEL object * \param o_current object to operate on * \param new_attrib_name name of attribute to replace * \param new_attrib_value value to set attribute to * \param visibility set visibility of attribute * \param show_name_value set visibility of attribute name and value */ void s_object_replace_attrib_in_object(TOPLEVEL *toplevel, OBJECT *o_current, char *new_attrib_name, char *new_attrib_value, gint visibility, gint show_name_value) { GList *a_iter; OBJECT *a_current; char *old_attrib_text; char *old_attrib_name; char *new_attrib_text; 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 an attribute */ /* may need to check more thoroughly here. . . . */ old_attrib_text = g_strdup(a_current->text->string); old_attrib_name = u_basic_breakup_string(old_attrib_text, '=', 0); if (strcmp(old_attrib_name, new_attrib_name) == 0) { /* create attrib=value text string & stuff it back into toplevel */ new_attrib_text = g_strconcat(new_attrib_name, "=", new_attrib_value, NULL); g_free(a_current->text->string); /* remove old attrib string */ a_current->text->string = g_strdup(new_attrib_text); /* insert new attrib string */ if (visibility != LEAVE_VISIBILITY_ALONE) o_set_visibility (toplevel, a_current, visibility); if (show_name_value != LEAVE_NAME_VALUE_ALONE) a_current->show_name_value = show_name_value; g_free(new_attrib_text); g_free(old_attrib_text); g_free(old_attrib_name); return; /* we are done -- leave. */ } else { g_free(old_attrib_text); g_free(old_attrib_name); } /* if (strcmp . . . . */ } /* if (a_current . . . . */ a_iter = g_list_next (a_iter); } /* while */ /* if we get here, it's because we have failed to find the attrib on the component. * This is an error condition. */ fprintf(stderr, _("In s_object_replace_attrib_in_object, we have failed to find the attrib %s on the component. Exiting . . .\n"), new_attrib_name); exit(-1); }
/*! * \brief Remove attribute from object * * Remove an attribute from an object. * \param toplevel TOPLEVEL structure * \param o_current Object to remove attribute from * \param new_attrib_name Name of attribute to remove */ void s_object_remove_attrib_in_object (TOPLEVEL *toplevel, OBJECT *o_current, char *new_attrib_name) { GList *a_iter; OBJECT *a_current; OBJECT *attribute_object; char *old_attrib_text; char *old_attrib_name; 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 an attribute */ /* may need to check more thoroughly here. . . . */ old_attrib_text = g_strdup(a_current->text->string); old_attrib_name = u_basic_breakup_string(old_attrib_text, '=', 0); if (strcmp(old_attrib_name, new_attrib_name) == 0) { /* We've found the attrib. Delete it and then return. */ #ifdef DEBUG printf("In s_object_remove_attrib_in_object, removing attrib with name = %s\n", old_attrib_name); #endif attribute_object = a_current; s_object_delete_text_object_in_object (toplevel, attribute_object); g_free(old_attrib_text); g_free(old_attrib_name); return; /* we are done -- leave. */ } g_free(old_attrib_text); g_free(old_attrib_name); } a_iter = g_list_next (a_iter); } /* if we get here, it's because we have failed to find the attrib on the component. * This is an error condition. */ fprintf(stderr, _("In s_object_remove_attrib_in_object, we have failed to find the attrib %s on the component. Exiting . . .\n"), new_attrib_name); exit(-1); }
void s_hierarchy_traverse(TOPLEVEL * pr_current, OBJECT * o_current, NETLIST * netlist) { char *attrib; int page_control=-1; PAGE *p_current; PAGE *child_page; int count = 0; int pcount = 0; int looking_inside = FALSE; int loaded_flag = FALSE; char *current_filename; int graphical=FALSE; attrib = o_attrib_search_attached_attribs_by_name (o_current, "source", 0); /* if above is null, then look inside symbol */ if (attrib == NULL) { attrib = o_attrib_search_inherited_attribs_by_name (o_current, "source", count); looking_inside = TRUE; #if DEBUG printf("going to look inside now\n"); #endif } graphical = s_hierarchy_graphical_search(o_current, count); if (graphical) { /* Do not bother traversing the hierarchy if the symbol has an */ /* graphical attribute attached to it. */ if (attrib) { g_free(attrib); attrib = NULL; } } while (attrib) { /* look for source=filename,filename, ... */ pcount = 0; current_filename = u_basic_breakup_string(attrib, ',', pcount); /* loop over all filenames */ while (current_filename != NULL) { s_log_message(_("Going to traverse source [%1$s]"), current_filename); /* guts here */ /* guts for a single filename */ p_current = pr_current->page_current; #if DEBUG printf("Going down %s\n", current_filename); #endif GError *err = NULL; child_page = s_hierarchy_down_schematic_single(pr_current, current_filename, pr_current->page_current, page_control, HIERARCHY_FORCE_LOAD, &err); if (child_page == NULL) { g_warning (_("Failed to load subcircuit '%1$s': %2$s\n"), current_filename, err->message); fprintf(stderr, _("ERROR: Failed to load subcircuit '%1$s': %2$s\n"), current_filename, err->message); g_error_free (err); exit (2); } else { page_control = child_page->page_control; s_page_goto (pr_current, child_page); loaded_flag = TRUE; verbose_print("v\n"); verbose_reset_index(); netlist->composite_component = TRUE; /* can't do the following, don't know why... HACK TODO */ /*netlist->hierarchy_tag = u_basic_strdup (netlist->component_uref);*/ s_traverse_sheet (pr_current, s_page_objects (pr_current->page_current), netlist->component_uref); verbose_print("^"); } pr_current->page_current = p_current; g_free(current_filename); pcount++; current_filename = u_basic_breakup_string(attrib, ',', pcount); } g_free(attrib); g_free(current_filename); count++; /* continue looking outside first */ if (!looking_inside) { attrib = o_attrib_search_attached_attribs_by_name (o_current, "source", count); } /* okay we were looking outside and didn't */ /* find anything, so now we need to look */ /* inside the symbol */ if (!looking_inside && attrib == NULL && !loaded_flag) { looking_inside = TRUE; #if DEBUG printf("switching to go to look inside\n"); #endif } if (looking_inside) { #if DEBUG printf("looking inside\n"); #endif attrib = o_attrib_search_inherited_attribs_by_name (o_current, "source", count); } graphical = s_hierarchy_graphical_search(o_current, count); if (graphical) { /* Do not bother looking further in the hierarchy if the symbol */ /* has an graphical attribute attached to it. */ if (attrib) { g_free(attrib); attrib = NULL; } } } }
/*! \brief Add nets to net table * * This function iterates over adds all * items found on this page looking * for nets and adds them individually to the net table. Looping over * objects occurs here. * * \param start_obj Pointer to first object * * \todo Why do the calling semantics of this function disagree with * s_table_add_toplevel_pin_items_to_pin_table()? That function * takes a GList, this one takes a pointer to OBJECT. */ void s_table_add_toplevel_net_items_to_net_table(OBJECT *start_obj) { OBJECT *o_current; char *temp_netname; int row, col; char *attrib_text; char *attrib_name; char *attrib_value; ATTRIB *a_current; /* ----- Iterate through all objects found on page ----- */ o_current = start_obj; while (o_current != NULL) { /* ----- Now process objects found on page ----- */ if (o_current->type == OBJ_NET) { #if DEBUG fflush(stderr); fflush(stdout); printf("In s_table_add_toplevel_net_items_to_net_table, Found net on page\n"); #endif verbose_print(" N"); /* Having found a net, we stick it into the table. */ a_current = o_current->attribs; while (a_current != NULL) { if (a_current->object->type == OBJ_TEXT && a_current->object->text != NULL) { /* found an attribute */ /* may need to check more thoroughly here. . . . */ attrib_text = g_strdup(a_current->object->text->string); attrib_name = u_basic_breakup_string(attrib_text, '=', 0); attrib_value = s_misc_remaining_string(attrib_text, '=', 1); if (strcmp(attrib_name, "netname") != 0) { /* Don't include "netname" */ /* Get row and col where to put this attrib */ row = s_table_get_index(sheet_head->master_net_list_head, temp_netname); col = s_table_get_index(sheet_head->master_net_attrib_list_head, attrib_name); #if DEBUG fflush(stderr); fflush(stdout); printf("In s_table_add_toplevel_net_items_to_net_table, about to add row %d, col %d, attrib_value = %s\n", row, col, attrib_value); printf(" . . . current address of attrib_value cell is [%p]\n", &((sheet_head->net_table)[row][col]).attrib_value); #endif /* Is there a compelling reason for me to put this into a separate fcn? */ ((sheet_head->net_table)[row][col]).row = row; ((sheet_head->net_table)[row][col]).col = col; ((sheet_head->net_table)[row][col]).row_name = g_strdup(temp_netname); ((sheet_head->net_table)[row][col]).col_name = g_strdup(attrib_name); ((sheet_head->net_table)[row][col]).attrib_value = g_strdup(attrib_value); } g_free(attrib_name); g_free(attrib_text); g_free(attrib_value); } a_current = a_current->next; } /* while (a_current != NULL) */ g_free(temp_netname); } /*--- if (o_current->type == OBJ_NET) ---*/ o_current = o_current->next; /* iterate to next object on page */ } /* while o_current != NULL */ verbose_done(); #if DEBUG fflush(stderr); fflush(stdout); printf("In s_table_add_toplevel_net_items_to_net_table -- we are about to return\n"); #endif }
/*! \brief Add pins to pin table. * * This function iterates over adds all items found on this page * looking for pins. WHen it finds a pin, it gathers all * pin attribs and sticks them into the pin table. * \param obj_list List of objects on page */ void s_table_add_toplevel_pin_items_to_pin_table (const GList *obj_list) { gchar *temp_uref; gchar *pinnumber; gchar *row_label; int row, col; gchar *attrib_text; gchar *attrib_name; gchar *attrib_value; const GList *o_iter; GList *a_iter; GList *o_lower_iter; OBJECT *pin_attrib; if (verbose_mode) { printf("- Starting internal pin TABLE creation\n"); } #ifdef DEBUG printf("=========== Just entered s_table_add_toplevel_pin_items_to_pin_table! ==============\n"); #endif /* ----- Iterate through all objects found on page ----- */ for (o_iter = obj_list; o_iter != NULL; o_iter = g_list_next (o_iter)) { OBJECT *o_current = o_iter->data; #ifdef DEBUG printf(" ---> In s_table_add_toplevel_pin_items_to_pin_table, examining o_current->name = %s\n", o_current->name); #endif /* ----- Now process objects found on page ----- */ if (o_current->type == OBJ_COMPLEX && o_current->attribs != NULL) { /* ---- Don't process part if it lacks a refdes ----- */ temp_uref = s_attrib_get_refdes(o_current); if (temp_uref) { /* ----- Now iterate through lower level objects looking for pins. ----- */ for (o_lower_iter = o_current->complex->prim_objs; o_lower_iter != NULL; o_lower_iter = g_list_next (o_lower_iter)) { OBJECT *o_lower_current = o_lower_iter->data; if (o_lower_current->type == OBJ_PIN) { /* ----- Found a pin. First get its pinnumber. then get attrib head and loop on attribs. ----- */ pinnumber = o_attrib_search_object_attribs_by_name (o_lower_current, "pinnumber", 0); row_label = g_strconcat(temp_uref, ":", pinnumber, NULL); #if DEBUG printf(" In s_table_add_toplevel_pin_items_to_pin_table, examining pin %s\n", row_label); #endif a_iter = o_lower_current->attribs; while (a_iter != NULL) { pin_attrib = a_iter->data; if (pin_attrib->type == OBJ_TEXT && pin_attrib->text != NULL) { /* found an attribute */ attrib_text = g_strdup(pin_attrib->text->string); attrib_name = u_basic_breakup_string(attrib_text, '=', 0); attrib_value = s_misc_remaining_string(attrib_text, '=', 1); if ( (strcmp(attrib_name, "pinnumber") != 0) && (attrib_value != 0) ) { /* Don't include "pinnumber" because it is already in other master list. * Also must ensure that value is non-null; certain symbols are not well formed. */ /* Get row and col where to put this attrib */ row = s_table_get_index(sheet_head->master_pin_list_head, row_label); col = s_table_get_index(sheet_head->master_pin_attrib_list_head, attrib_name); /* Sanity check */ if (row == -1 || col == -1) { /* we didn't find the item in the table */ fprintf (stderr, "In s_table_add_toplevel_pin_items_to_pin_table, we didn't find either row or col in the lists!\n"); } else { #if DEBUG printf(" In s_table_add_toplevel_pin_items_to_pin_table, about to add row %d, col %d, attrib_value = %s\n", row, col, attrib_value); printf(" . . . current address of attrib_value cell is [%p]\n", &((sheet_head->component_table)[row][col]).attrib_value); #endif /* Is there a compelling reason for me to put this into a separate fcn? */ ((sheet_head->pin_table)[row][col]).row = row; ((sheet_head->pin_table)[row][col]).col = col; ((sheet_head->pin_table)[row][col]).row_name = g_strdup(row_label); ((sheet_head->pin_table)[row][col]).col_name = g_strdup(attrib_name); ((sheet_head->pin_table)[row][col]).attrib_value = g_strdup(attrib_value); } } g_free(attrib_name); g_free(attrib_text); g_free(attrib_value); } a_iter = g_list_next (a_iter); } /* while (pin_attrib != NULL) */ g_free(pinnumber); g_free(row_label); } } } g_free(temp_uref); } } verbose_done(); }
/*! \brief Add components to the component table * * This fcn iterates over adds all * objects found on this page looking * for components. When it finds a component, it finds all component * attribs and sticks them in the TABLE. * \param obj_list pointer to GList containing objects on this page */ void s_table_add_toplevel_comp_items_to_comp_table (const GList *obj_list) { gchar *temp_uref; int row, col; gchar *attrib_text; gchar *attrib_name; gchar *attrib_value; const GList *o_iter; GList *a_iter; OBJECT *a_current; gint old_visibility, old_show_name_value; if (verbose_mode) { printf("- Starting internal component TABLE creation\n"); } #ifdef DEBUG fflush(stderr); fflush(stdout); printf("=========== Just entered s_table_add_toplevel_comp_items_to_comp_table! ==============\n"); #endif /* ----- Iterate through all objects found on page ----- */ for (o_iter = obj_list; o_iter != NULL; o_iter = g_list_next (o_iter)) { OBJECT *o_current = o_iter->data; #ifdef DEBUG printf(" ---> In s_table_add_toplevel_comp_items_to_comp_table, examining o_current->name = %s\n", o_current->name); #endif /* ----- Now process objects found on page ----- */ if (o_current->type == OBJ_COMPLEX && o_current->attribs != NULL) { /* ---- Don't process part if it lacks a refdes ----- */ temp_uref = g_strdup(s_attrib_get_refdes(o_current)); if (temp_uref) { #if DEBUG printf(" In s_table_add_toplevel_comp_items_to_comp_table, found component on page. Refdes = %s\n", temp_uref); #endif verbose_print(" C"); /* Having found a component, we loop over all attribs in this * component, and stick them * into cells in the table. */ 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 an attribute */ /* may need to check more thoroughly here. . . . */ attrib_text = g_strdup(a_current->text->string); attrib_name = u_basic_breakup_string(attrib_text, '=', 0); attrib_value = s_misc_remaining_string(attrib_text, '=', 1); old_visibility = o_is_visible (pr_current, a_current) ? VISIBLE : INVISIBLE; old_show_name_value = a_current->show_name_value; /* Don't include "refdes" or "slot" because they form the row name. */ /* Also don't include "net" per bug found by Steve W. 4.3.2007 -- SDB */ if ( (strcmp(attrib_name, "refdes") != 0) && (strcmp(attrib_name, "net") != 0) && (strcmp(attrib_name, "slot") != 0) ) { /* Get row and col where to put this attrib */ row = s_table_get_index(sheet_head->master_comp_list_head, temp_uref); col = s_table_get_index(sheet_head->master_comp_attrib_list_head, attrib_name); /* Sanity check */ if (row == -1 || col == -1) { /* we didn't find the item in the table */ fprintf (stderr, "In s_table_add_toplevel_comp_items_to_comp_table, we didn't find either row or col in the lists!\n"); } else { #if DEBUG printf(" In s_table_add_toplevel_comp_items_to_comp_table, about to add row %d, col %d, attrib_value = %s\n", row, col, attrib_value); printf(" . . . current address of attrib_value cell is [%p]\n", &((sheet_head->component_table)[row][col]).attrib_value); #endif /* Is there a compelling reason for me to put this into a separate fcn? */ ((sheet_head->component_table)[row][col]).row = row; ((sheet_head->component_table)[row][col]).col = col; ((sheet_head->component_table)[row][col]).row_name = g_strdup(temp_uref); ((sheet_head->component_table)[row][col]).col_name = g_strdup(attrib_name); ((sheet_head->component_table)[row][col]).attrib_value = g_strdup(attrib_value); ((sheet_head->component_table)[row][col]).visibility = old_visibility; ((sheet_head->component_table)[row][col]).show_name_value = old_show_name_value; } } g_free(attrib_name); g_free(attrib_text); g_free(attrib_value); } a_iter = g_list_next (a_iter); } /* while (a_current != NULL) */ g_free(temp_uref); } /* if (temp_uref) */ } /* if (o_current->type == OBJ_COMPLEX) */ } verbose_done(); }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * * \todo Only descends into the first source schematic * */ int o_edit_find_text (GSCHEM_TOPLEVEL *w_current, const GList *o_list, char *stext, int descend, int skip) { TOPLEVEL *toplevel = w_current->toplevel; char *attrib = NULL; int count = 0; PAGE *parent = NULL; char *current_filename = NULL; int page_control = 0; int pcount = 0; int rv; int x1, y1, x2, y2; int text_screen_height; const GList *iter; OBJECT *o_current; skiplast = skip; iter = o_list; while (iter != NULL) { o_current = (OBJECT *)iter->data; if (descend) { if (o_current->type == OBJ_COMPLEX) { parent = toplevel->page_current; attrib = o_attrib_search_attached_attribs_by_name (o_current, "source", count); /* if above is null, then look inside symbol */ if (attrib == NULL) { attrib = o_attrib_search_inherited_attribs_by_name (o_current, "source", count); /* looking_inside = TRUE; */ } if (attrib) { pcount = 0; current_filename = u_basic_breakup_string(attrib, ',', pcount); if (current_filename != NULL) { PAGE *child_page = s_hierarchy_down_schematic_single(toplevel, current_filename, parent, page_control, HIERARCHY_NORMAL_LOAD); if (child_page != NULL) { page_control = child_page->page_control; rv = o_edit_find_text (w_current, s_page_objects (child_page), stext, descend, skiplast); if (!rv) { s_page_goto( toplevel, child_page ); return 0; } } } } } } if (o_current->type == OBJ_TEXT) { const gchar *str = o_text_get_string (toplevel, o_current); /* replaced strcmp with strstr to simplify the search */ if (strstr (str,stext)) { if (!skiplast) { a_zoom(w_current, ZOOM_FULL, DONTCARE, A_PAN_DONT_REDRAW); world_get_single_object_bounds (toplevel, o_current, &x1, &y1, &x2, &y2); text_screen_height = SCREENabs (w_current, y2 - y1); /* this code will zoom/pan till the text screen height is about */ /* 50 pixels high, perhaps a future enhancement will be to make */ /* this number configurable */ while (text_screen_height < 50) { a_zoom(w_current, ZOOM_IN, DONTCARE, A_PAN_DONT_REDRAW); text_screen_height = SCREENabs (w_current, y2 - y1); } a_pan_general(w_current, o_current->text->x, o_current->text->y, 1, 0); /* Make sure the titlebar and scrollbars are up-to-date */ x_window_set_current_page(w_current, w_current->toplevel->page_current ); last_o = o_current; break; } if (last_o == o_current) { skiplast = 0; } } /* if (strstr(o_current->text->string,stext)) */ } /* if (o_current->type == OBJ_TEXT) */ iter = g_list_next (iter); if (iter == NULL) { return 1; } } return (iter == NULL); }
/*! \brief Update pin attributes in toplevel * * For each attrib string attached to the pin, update it using the value * held in new_pin_attrib_list. Algorithm: * -# Loop over name=value pairs held in new_pin_attrib_list. * -# For each name=value pair, look for corresponding attrib on pin. * -# If the attrib exists on pin and in name=value pair, write the * new value in. * -# If the attrib exists on pin, but is null in name=value pair, * delete the attrib. * -# If the attribs doesn't exist on pin, but is non-null in * the name=value pair, create an attrib object and add it to the pin. * \param toplevel TOPLEVEL structure * \param refdes Unused - needs refactored out * \param [in,out] o_pin pin to update * \param [in] new_pin_attrib_list New pin attribute list to apply */ void s_toplevel_update_pin_attribs_in_toplevel (TOPLEVEL *toplevel, char *refdes, OBJECT *o_pin, STRING_LIST *new_pin_attrib_list) { STRING_LIST *local_list; char *new_name_value_pair; char *new_attrib_name; char *new_attrib_value; char *old_attrib_value; #if DEBUG printf("----- Entering s_toplevel_update_pin_attribs_in_toplevel.\n"); #endif /* loop on name=value pairs held in new_pin_attrib_list */ local_list = new_pin_attrib_list; while (local_list != NULL) { new_name_value_pair = g_strdup(local_list->data); #if DEBUG printf(" In s_toplevel_update_pin_attribs_in_toplevel, handling entry in master list %s .\n", new_name_value_pair); #endif new_attrib_name = u_basic_breakup_string(new_name_value_pair, '=', 0); new_attrib_value = u_basic_breakup_string(new_name_value_pair, '=', 1); if (strlen(new_attrib_value) == 0) { g_free(new_attrib_value); new_attrib_value = NULL; /* s_misc_remaining_string doesn't return NULL for empty substring. */ } old_attrib_value = o_attrib_search_attached_attribs_by_name (o_pin, new_attrib_name, 0); /* ------- Four cases to consider: Case 1: old and new attribs exist ----- */ 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_pin_attribs_in_toplevel, about to replace old attrib with new one: name= %s, value= %s\n", new_attrib_name, new_attrib_value); #endif s_object_replace_attrib_in_object(toplevel, o_pin, new_attrib_name, new_attrib_value, LEAVE_VISIBILITY_ALONE, LEAVE_NAME_VALUE_ALONE); } /* ------- Four cases to consider: Case 2: old attrib exists, new one doesn't ----- */ else if ( (old_attrib_value != NULL) && (new_attrib_value == NULL) ) { /* remove attrib from pin */ #if DEBUG printf("In s_toplevel_update_pin_attribs_in_toplevel, about to remove old attrib with name= %s, value= %s\n", new_attrib_name, old_attrib_value); #endif s_object_remove_attrib_in_object (toplevel, o_pin, new_attrib_name); } /* ------- Four cases to consider: Case 3: No old attrib, new one exists. ----- */ else if ( (old_attrib_value == NULL) && (new_attrib_value != NULL) ) { /* add new attrib to pin. */ #if DEBUG printf("In s_toplevel_update_pin_attribs_in_toplevel, about to add new attrib with name= %s, value= %s\n", new_attrib_name, new_attrib_value); #endif s_object_add_pin_attrib_to_object (toplevel, o_pin, new_attrib_name, new_attrib_value); /* ------- Four cases to consider: Case 4 ----- */ } else { /* Do nothing. */ #if DEBUG printf("In s_toplevel_update_pin_attribs_in_toplevel, nothing needs to be done.\n"); #endif } /* free everything and iterate */ g_free(new_name_value_pair); g_free(new_attrib_name); g_free(new_attrib_value); g_free(old_attrib_value); local_list = local_list->next; } /* while (local_list != NULL) */ return; }
/*! \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; }
void s_check_slotdef (const GList *obj_list, SYMCHECK *s_current) { char* value = NULL; char* slotdef = NULL; char* slotnum = NULL; char* pins = NULL; char* temp = NULL; char numslots_str[10]; int slot; int i,j; char *message; char tempstr1[10]; /* pinlist will store the pin definitions for each slot */ /* example: pinlist[0] = 3,2,8,4,1 ; pinlist[1] = 5,6,8,4,7 */ char** pinlist = NULL; int n,m; char* pin; char* cmp; int match; gboolean error_parsing = FALSE; int errors_found = 0; /* look for numslots to see if this symbol has slotting info */ value = o_attrib_search_floating_attribs_by_name (obj_list, "numslots", 0); if (!value) { message = g_strdup ("Did not find numslots= attribute, not checking slotting\n"); s_current->warning_messages = g_list_append(s_current->warning_messages, message); s_current->warning_count++; message = g_strdup ("If this symbol does not need slotting, set numslots to zero (numslots=0)\n"); s_current->info_messages = g_list_append(s_current->info_messages, message); return; } s_current->numslots=atoi(value); sprintf(numslots_str, "%d", s_current->numslots); g_free(value); message = g_strdup_printf ("Found numslots=%s attribute\n", numslots_str); s_current->info_messages = g_list_append(s_current->info_messages, message); if (s_current->numslots == 0) { message = g_strdup ("numslots set to zero, symbol does not have slots\n"); s_current->info_messages = g_list_append(s_current->info_messages, message); return; } pinlist = (char**)g_malloc0(sizeof(*pinlist) * s_current->numslots); i = 0; /* get the slotdef attribute */ slotdef = o_attrib_search_floating_attribs_by_name (obj_list, "slotdef", 0); while ((slotdef != NULL) && (!error_parsing)) { if (i > s_current->numslots-1) { sprintf(tempstr1, "%d", i+1); /* i starts at zero */ message = g_strdup_printf ( "Found %s slotdef= attributes. Expecting %s slotdef= attributes\n", tempstr1, numslots_str); s_current->error_messages = g_list_append(s_current->error_messages, message); s_current->error_count++; s_current->slotting_errors++; } message = g_strdup_printf ("Found slotdef=%s attribute\n", slotdef); s_current->info_messages = g_list_append(s_current->info_messages, message); slotnum = u_basic_breakup_string(slotdef, ':', 0); if (!slotnum) { message = g_strdup_printf ( "Invalid slotdef=%s attributes, not continuing\n", slotdef); s_current->error_messages = g_list_append(s_current->error_messages, message); s_current->error_count++; s_current->slotting_errors++; error_parsing = TRUE; continue; } if (strcmp(slotnum, "0") == 0) { message = g_strdup_printf ( "Found a zero slot in slotdef=%s\n", slotdef); s_current->error_messages = g_list_append(s_current->error_messages, message); s_current->error_count++; } slot = atoi(slotnum); g_free(slotnum); /* make sure that the slot # is less than the number of slots */ if (slot > s_current->numslots) { sprintf(tempstr1, "%d", slot); message = g_strdup_printf ( "Slot %s is larger then the maximum number (%s) of slots\n", tempstr1, numslots_str); s_current->error_messages = g_list_append(s_current->error_messages, message); s_current->error_count++; s_current->slotting_errors++; } /* skip over the : */ pins = strchr(slotdef, ':'); if (!pins) { message = g_strdup_printf ( "Invalid slotdef=%s attributes, not continuing\n", slotdef); s_current->error_messages = g_list_append(s_current->error_messages, message); s_current->error_count++; s_current->slotting_errors++; error_parsing = TRUE; continue; } pins++; /* get past that : */ if (!pins) { message = g_strdup_printf ( "Invalid slotdef=%s attributes, not continuing\n", slotdef); s_current->error_messages = g_list_append(s_current->error_messages, message); s_current->error_count++; s_current->slotting_errors++; error_parsing = TRUE; continue; } if (*pins == '\0') { message = g_strdup_printf ( "Invalid slotdef=%s attributes, not continuing\n", slotdef); s_current->error_messages = g_list_append(s_current->error_messages, message); s_current->error_count++; s_current->slotting_errors++; error_parsing = TRUE; continue; } if ((slot > 0) && (slot <= s_current->numslots)) { if (pinlist[slot-1]) { message = g_strdup_printf ("Duplicate slot number in slotdef=%s\n", slotdef); s_current->error_messages = g_list_append(s_current->error_messages, message); s_current->error_count++; s_current->slotting_errors++; } else { pinlist[slot-1] = g_strdup_printf(",%s,", pins); } } j = 0; do { if (temp) { g_free(temp); temp = NULL; } temp = u_basic_breakup_string(pins, ',', j); if (!temp && j < s_current->numpins) { message = g_strdup_printf ( "Not enough pins in slotdef=%s\n", slotdef); s_current->error_messages = g_list_append(s_current->error_messages, message); s_current->error_count++; s_current->slotting_errors++; break; } if (j > s_current->numpins) { message = g_strdup_printf ( "Too many pins in slotdef=%s\n", slotdef); s_current->error_messages = g_list_append(s_current->error_messages, message); s_current->error_count++; s_current->slotting_errors++; g_free(temp); temp = NULL; break; } if (temp && strcmp(temp, "0") == 0) { message = g_strdup_printf ( "Found a zero pin in slotdef=%s\n", slotdef); s_current->error_messages = g_list_append(s_current->error_messages, message); s_current->error_count++; } j++; } while (temp); g_free(temp); g_free(slotdef); slotdef = NULL; i++; slotdef = o_attrib_search_floating_attribs_by_name (obj_list, "slotdef", i); } if (!slotdef && i < s_current->numslots) { message = g_strdup_printf ( "Missing slotdef= (there should be %s slotdef= attributes)\n", numslots_str); s_current->error_messages = g_list_append(s_current->error_messages, message); s_current->error_count++; s_current->slotting_errors++; } else { /* Validate that pinslist does not contain a null entry. If any entry */ /* is null, that means the slotdef= attribute was malformed to start */ /* with. */ for (i = 0; i < s_current->numslots; i++) { if (pinlist[i] == NULL) { errors_found++; } } if (errors_found) { message = g_strdup_printf( "Malformed slotdef= (the format is #:#,#,#,...)\n"); s_current->error_messages = g_list_append(s_current->error_messages, message); s_current->error_count++; s_current->slotting_errors++; } else { /* Now compare each pin with the rest */ s_current->numslotpins = 0; for (i = 0; i < s_current->numslots; i++) { for (n = 1; n <= s_current->numpins; n++) { /* Get the number of one pin */ pin = u_basic_breakup_string(pinlist[i], ',', n); if (pin && *pin) { match = FALSE; for (j = i - 1; j >= 0 && !match; j--) { for (m = 1; m <= s_current->numpins && !match; m++) { /* Get the number of the other pin */ cmp = u_basic_breakup_string(pinlist[j], ',', m); if (cmp && *cmp) { match = (0 == strcmp (pin, cmp)); g_free(cmp); } } } if (!match) { /* If they don't match, then increase the number of pins */ s_current->numslotpins++; } g_free(pin); } } } message = g_strdup_printf ("Found %d distinct pins in slots\n", s_current->numslotpins); s_current->info_messages = g_list_append(s_current->info_messages, message); } } g_free(slotdef); if (pinlist) { /* Free the pinlist */ for (i = 0; i < s_current->numslots; i++) { g_free(pinlist[i]); } g_free(pinlist); } return; }