/*! * \brief Check to see if a particular name is the name of an already * existing rats line. */ static int rat_used (char *name) { if (name == NULL) return -1; MENU_LOOP (&PCB->NetlistLib); { if (menu->Name && (strcmp (menu->Name, name) == 0)) return 1; } END_LOOP; return 0; }
/*! * \brief Free the memory that's allocated by the library. */ void FreeLibraryMemory (LibraryType *lib) { MENU_LOOP (lib); { ENTRY_LOOP (menu); { free (entry->AllocatedMemory); free (entry->ListEntry); } END_LOOP; free (menu->Entry); free (menu->Name); } END_LOOP; free (lib->Menu); /* clear struct */ memset (lib, 0, sizeof (LibraryType)); }
/* --------------------------------------------------------------------------- * releases the memory that's allocated by the library */ void FreeLibraryMemory (LibraryTypePtr lib) { MENU_LOOP (lib); { ENTRY_LOOP (menu); { SaveFree ((void *) entry->AllocatedMemory); SaveFree ((void *) entry->ListEntry); } END_LOOP; SaveFree ((void *) menu->Entry); SaveFree ((void *) menu->Name); } END_LOOP; SaveFree ((void *) lib->Menu); /* clear struct */ memset (lib, 0, sizeof (LibraryType)); }
static char * describe_location (Coord X, Coord Y) { void *ptr1, *ptr2, *ptr3; int type; int Range = 0; char *elename = ""; char *pinname; char *netname = NULL; char *description; /* check if there are any pins or pads at that position */ type = SearchObjectByLocation (PIN_TYPE | PAD_TYPE, &ptr1, &ptr2, &ptr3, X, Y, Range); if (type == NO_TYPE) return NULL; /* don't mess with silk objects! */ if (type & SILK_TYPE && GetLayerNumber (PCB->Data, (LayerType *) ptr1) >= max_copper_layer) return NULL; if (type == PIN_TYPE || type == PAD_TYPE) elename = (char *)UNKNOWN (NAMEONPCB_NAME ((ElementType *) ptr1)); pinname = ConnectionName (type, ptr1, ptr2); if (pinname == NULL) return NULL; /* Find netlist entry */ MENU_LOOP (&PCB->NetlistLib); { if (!menu->Name) continue; ENTRY_LOOP (menu); { if (!entry->ListEntry) continue; if (strcmp (entry->ListEntry, pinname) == 0) { netname = g_strdup (menu->Name); /* For some reason, the netname has spaces in front of it, strip them */ g_strstrip (netname); break; } } END_LOOP; if (netname != NULL) break; } END_LOOP; description = g_strdup_printf ("Element name: %s\n" "Pinname : %s\n" "Netname : %s", elename, (pinname != NULL) ? pinname : "--", (netname != NULL) ? netname : "--"); g_free (netname); return description; }
static GtkTreeModel * net_model_create (void) { GtkTreeModel *model; GtkTreeStore *store; GtkTreeIter new_iter; GtkTreeIter parent_iter; GtkTreeIter *parent_ptr; GtkTreePath *path; GtkTreeRowReference *row_ref; GHashTable *prefix_hash; char *display_name; char *hash_string; char **join_array; char **path_segments; int path_depth; int try_depth; store = gtk_tree_store_new (N_NET_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); model = GTK_TREE_MODEL (store); /* Hash table stores GtkTreeRowReference for given path prefixes */ prefix_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) gtk_tree_row_reference_free); MENU_LOOP (&PCB->NetlistLib); { if (!menu->Name) continue; if (loading_new_netlist) menu->flag = TRUE; parent_ptr = NULL; path_segments = g_strsplit (menu->Name, NET_HIERARCHY_SEPARATOR, 0); path_depth = g_strv_length (path_segments); for (try_depth = path_depth - 1; try_depth > 0; try_depth--) { join_array = g_new0 (char *, try_depth + 1); memcpy (join_array, path_segments, sizeof (char *) * try_depth); /* See if this net's parent node is in the hash table */ hash_string = g_strjoinv (NET_HIERARCHY_SEPARATOR, join_array); g_free (join_array); row_ref = (GtkTreeRowReference *)g_hash_table_lookup (prefix_hash, hash_string); g_free (hash_string); /* If we didn't find the path at this level, keep looping */ if (row_ref == NULL) continue; path = gtk_tree_row_reference_get_path (row_ref); gtk_tree_model_get_iter (model, &parent_iter, path); parent_ptr = &parent_iter; break; } /* NB: parent_ptr may still be NULL if we reached the toplevel */ /* Now walk up the desired path, adding the nodes */ for (; try_depth < path_depth - 1; try_depth++) { display_name = g_strconcat (path_segments[try_depth], NET_HIERARCHY_SEPARATOR, NULL); gtk_tree_store_append (store, &new_iter, parent_ptr); gtk_tree_store_set (store, &new_iter, NET_ENABLED_COLUMN, "", NET_NAME_COLUMN, display_name, NET_LIBRARY_COLUMN, NULL, -1); g_free (display_name); path = gtk_tree_model_get_path (model, &new_iter); row_ref = gtk_tree_row_reference_new (model, path); parent_iter = new_iter; parent_ptr = &parent_iter; join_array = g_new0 (char *, try_depth + 2); memcpy (join_array, path_segments, sizeof (char *) * (try_depth + 1)); hash_string = g_strjoinv (NET_HIERARCHY_SEPARATOR, join_array); g_free (join_array); /* Insert those node in the hash table */ g_hash_table_insert (prefix_hash, hash_string, row_ref); /* Don't free hash_string, it is now oened by the hash table */ } gtk_tree_store_append (store, &new_iter, parent_ptr); gtk_tree_store_set (store, &new_iter, NET_ENABLED_COLUMN, menu->flag ? "" : "*", NET_NAME_COLUMN, path_segments[path_depth - 1], NET_LIBRARY_COLUMN, menu, -1); g_strfreev (path_segments); } END_LOOP; g_hash_table_destroy (prefix_hash); return model; }
/*! * \brief Read the library-netlist build a true Netlist structure. */ NetListType * ProcNetlist (LibraryType *net_menu) { ConnectionType *connection; ConnectionType LastPoint; NetType *net; static NetListType *Wantlist = NULL; if (!net_menu->MenuN) return (NULL); FreeNetListMemory (Wantlist); free (Wantlist); badnet = false; /* find layer groups of the component side and solder side */ bottom_group = GetLayerGroupNumberBySide (BOTTOM_SIDE); top_group = GetLayerGroupNumberBySide (TOP_SIDE); Wantlist = (NetListType *)calloc (1, sizeof (NetListType)); if (Wantlist) { ALLPIN_LOOP (PCB->Data); { pin->Spare = NULL; CLEAR_FLAG (DRCFLAG, pin); } ENDALL_LOOP; ALLPAD_LOOP (PCB->Data); { pad->Spare = NULL; CLEAR_FLAG (DRCFLAG, pad); } ENDALL_LOOP; MENU_LOOP (net_menu); { if (menu->Name[0] == '*' || menu->flag == 0) { badnet = true; continue; } net = GetNetMemory (Wantlist); if (menu->Style) { STYLE_LOOP (PCB); { if (style->Name && !NSTRCMP (style->Name, menu->Style)) { net->Style = style; break; } } END_LOOP; } else /* default to NULL if none found */ net->Style = NULL; ENTRY_LOOP (menu); { if (SeekPad (entry, &LastPoint, false)) { if (TEST_FLAG (DRCFLAG, (PinType *) LastPoint.ptr2)) Message (_ ("Error! Element %s pin %s appears multiple times in the netlist file.\n"), NAMEONPCB_NAME ((ElementType *) LastPoint.ptr1), (LastPoint.type == PIN_TYPE) ? ((PinType *) LastPoint.ptr2)-> Number : ((PadType *) LastPoint.ptr2)->Number); else { connection = GetConnectionMemory (net); *connection = LastPoint; /* indicate expect net */ connection->menu = menu; /* mark as visited */ SET_FLAG (DRCFLAG, (PinType *) LastPoint.ptr2); if (LastPoint.type == PIN_TYPE) ((PinType *) LastPoint.ptr2)->Spare = (void *) menu; else ((PadType *) LastPoint.ptr2)->Spare = (void *) menu; } } else badnet = true; /* check for more pins with the same number */ for (; SeekPad (entry, &LastPoint, true);) { connection = GetConnectionMemory (net); *connection = LastPoint; /* indicate expect net */ connection->menu = menu; /* mark as visited */ SET_FLAG (DRCFLAG, (PinType *) LastPoint.ptr2); if (LastPoint.type == PIN_TYPE) ((PinType *) LastPoint.ptr2)->Spare = (void *) menu; else ((PadType *) LastPoint.ptr2)->Spare = (void *) menu; } } END_LOOP; } END_LOOP; } /* clear all visit marks */ ALLPIN_LOOP (PCB->Data); { CLEAR_FLAG (DRCFLAG, pin); } ENDALL_LOOP; ALLPAD_LOOP (PCB->Data); { CLEAR_FLAG (DRCFLAG, pad); } ENDALL_LOOP; return (Wantlist); }
/* \brief Create the tree model for the "Library" view. * \par Function Description * Creates a tree where the branches are the available library * sources and the leaves are the footprints. */ static GtkTreeModel * create_lib_tree_model (GhidLibraryWindow * library_window) { GtkTreeStore *tree; GtkTreeIter iter, p_iter, e_iter, c_iter; gchar *name; gboolean exists; tree = gtk_tree_store_new (N_MENU_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER); MENU_LOOP (&Library); { /* Watch for directory changes of library parts and create new | parent iter at each change. */ if (!menu->directory) /* Shouldn't happen */ menu->directory = g_strdup ("???"); exists = FALSE; if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tree), &e_iter)) do { gtk_tree_model_get (GTK_TREE_MODEL (tree), &e_iter, MENU_NAME_COLUMN, &name, -1); if (!strcmp (name, menu->directory)) { exists = TRUE; break; } } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (tree), &e_iter)); if (exists) p_iter = e_iter; else { gtk_tree_store_append (tree, &p_iter, NULL); gtk_tree_store_set (tree, &p_iter, MENU_NAME_COLUMN, menu->directory, MENU_LIBRARY_COLUMN, NULL, MENU_ENTRY_COLUMN, NULL, -1); } gtk_tree_store_append (tree, &iter, &p_iter); gtk_tree_store_set (tree, &iter, MENU_NAME_COLUMN, menu->Name, MENU_LIBRARY_COLUMN, menu, MENU_ENTRY_COLUMN, NULL, -1); ENTRY_LOOP (menu); { gtk_tree_store_append (tree, &c_iter, &iter); gtk_tree_store_set (tree, &c_iter, MENU_NAME_COLUMN, entry->ListEntry, MENU_LIBRARY_COLUMN, menu, MENU_ENTRY_COLUMN, entry, -1); } END_LOOP; } END_LOOP; return (GtkTreeModel *) tree; }