/*! * \brief The primary purpose of this action is to rebuild a netlist * from a script, in conjunction with the clear action above. */ static int netlist_add (const char *netname, const char *pinname) { int ni, pi; LibraryType *netlist = &PCB->NetlistLib; LibraryMenuType *net = NULL; LibraryEntryType *pin = NULL; for (ni=0; ni<netlist->MenuN; ni++) if (strcmp (netlist->Menu[ni].Name+2, netname) == 0) { net = & (netlist->Menu[ni]); break; } if (net == NULL) { net = CreateNewNet (netlist, (char *)netname, NULL); } for (pi=0; pi<net->EntryN; pi++) if (strcmp (net->Entry[pi].ListEntry, pinname) == 0) { pin = & (net->Entry[pi]); break; } if (pin == NULL) { pin = CreateNewConnection (net, (char *)pinname); } NetlistChanged (0); return 0; }
static void netlist_norats (LibraryMenuType * net, LibraryEntryType * pin) { net->Name[0] = '*'; net->flag = 0; NetlistChanged (0); }
/*! * \brief Free the memory used by PCB. */ void FreePCBMemory (PCBType *pcb) { int i; if (pcb == NULL) { return; } free (pcb->Name); free (pcb->Filename); free (pcb->PrintFilename); FreeDataMemory (pcb->Data); free (pcb->Data); /* release font symbols */ for (i = 0; i <= MAX_FONTPOSITION; i++) { free (pcb->Font.Symbol[i].Line); } FreeLibraryMemory (&pcb->NetlistLib); NetlistChanged (0); FreeAttributeListMemory (&pcb->Attributes); /* clear struct */ memset (pcb, 0, sizeof (PCBType)); }
/*! * \brief The primary purpose of this action is to remove the netlist * completely so that a new one can be loaded, usually via a gsch2pcb * style script. */ static void netlist_clear (LibraryMenuType * net, LibraryEntryType * pin) { LibraryType *netlist = &PCB->NetlistLib; int ni, pi; if (net == 0) { /* Clear the entire netlist. */ FreeLibraryMemory (&PCB->NetlistLib); } else if (pin == 0) { /* Remove a net from the netlist. */ ni = net - netlist->Menu; if (ni >= 0 && ni < netlist->MenuN) { /* if there is exactly one item, MenuN is 1 and ni is 0 */ if (netlist->MenuN - ni > 1) memmove (net, net+1, (netlist->MenuN - ni - 1) * sizeof (*net)); netlist->MenuN --; } } else { /* Remove a pin from the given net. Note that this may leave an empty net, which is different than removing the net (above). */ pi = pin - net->Entry; if (pi >= 0 && pi < net->EntryN) { /* if there is exactly one item, MenuN is 1 and ni is 0 */ if (net->EntryN - pi > 1) memmove (pin, pin+1, (net->EntryN - pi - 1) * sizeof (*pin)); net->EntryN --; } } NetlistChanged (0); }
static int Netlist (int argc, char **argv, Coord x, Coord y) { NFunc func; int i, j; LibraryMenuType *net; LibraryEntryType *pin; int net_found = 0; int pin_found = 0; #if defined(USE_RE) int use_re = 0; #endif #if defined(HAVE_REGCOMP) regex_t elt_pattern; regmatch_t match; #endif #if defined(HAVE_RE_COMP) char *elt_pattern; #endif if (!PCB) return 1; if (argc == 0) { Message (netlist_syntax); return 1; } if (strcasecmp (argv[0], "find") == 0) func = netlist_find; else if (strcasecmp (argv[0], "select") == 0) func = netlist_select; else if (strcasecmp (argv[0], "rats") == 0) func = netlist_rats; else if (strcasecmp (argv[0], "norats") == 0) func = netlist_norats; else if (strcasecmp (argv[0], "clear") == 0) { func = netlist_clear; if (argc == 1) { netlist_clear (NULL, NULL); return 0; } } else if (strcasecmp (argv[0], "style") == 0) func = (NFunc)netlist_style; else if (strcasecmp (argv[0], "add") == 0) { /* Add is different, because the net/pin won't already exist. */ return netlist_add (ARG(1), ARG(2)); } else if (strcasecmp (argv[0], "sort") == 0) { sort_netlist (); return 0; } else if (strcasecmp (argv[0], "freeze") == 0) { netlist_frozen ++; return 0; } else if (strcasecmp (argv[0], "thaw") == 0) { if (netlist_frozen > 0) { netlist_frozen --; if (netlist_needs_update) NetlistChanged (0); } return 0; } else if (strcasecmp (argv[0], "forcethaw") == 0) { netlist_frozen = 0; if (netlist_needs_update) NetlistChanged (0); return 0; } else { Message (netlist_syntax); return 1; } #if defined(USE_RE) if (argc > 1) { int result; use_re = 1; for (i = 0; i < PCB->NetlistLib.MenuN; i++) { net = PCB->NetlistLib.Menu + i; if (strcasecmp (argv[1], net->Name + 2) == 0) use_re = 0; } if (use_re) { #if defined(HAVE_REGCOMP) result = regcomp (&elt_pattern, argv[1], REG_EXTENDED | REG_ICASE | REG_NOSUB); if (result) { char errorstring[128]; regerror (result, &elt_pattern, errorstring, 128); Message (_("regexp error: %s\n"), errorstring); regfree (&elt_pattern); return (1); } #endif #if defined(HAVE_RE_COMP) if ((elt_pattern = re_comp (argv[1])) != NULL) { Message (_("re_comp error: %s\n"), elt_pattern); return (false); } #endif } } #endif for (i = PCB->NetlistLib.MenuN-1; i >= 0; i--) { net = PCB->NetlistLib.Menu + i; if (argc > 1) { #if defined(USE_RE) if (use_re) { #if defined(HAVE_REGCOMP) if (regexec (&elt_pattern, net->Name + 2, 1, &match, 0) != 0) continue; #endif #if defined(HAVE_RE_COMP) if (re_exec (net->Name + 2) != 1) continue; #endif } else #endif if (strcasecmp (net->Name + 2, argv[1])) continue; } net_found = 1; pin = 0; if (func == (void *)netlist_style) { netlist_style (net, ARG(2)); } else if (argc > 2) { int l = strlen (argv[2]); for (j = net->EntryN-1; j >= 0 ; j--) if (strcasecmp (net->Entry[j].ListEntry, argv[2]) == 0 || (strncasecmp (net->Entry[j].ListEntry, argv[2], l) == 0 && net->Entry[j].ListEntry[l] == '-')) { pin = net->Entry + j; pin_found = 1; func (net, pin); } } else func (net, 0); } if (argc > 2 && !pin_found) { gui->log ("Net %s has no pin %s\n", argv[1], argv[2]); return 1; } else if (!net_found) { gui->log ("No net named %s\n", argv[1]); } #ifdef HAVE_REGCOMP if (use_re) regfree (&elt_pattern); #endif return 0; }
/*! * \brief This function is moved from the original netlist.c as * part of the gui code separation for the Gtk port. */ RatType * AddNet (void) { static int ratDrawn = 0; char name1[256], *name2; Cardinal group1, group2; char ratname[20]; int found; void *ptr1, *ptr2, *ptr3; LibraryMenuType *menu; LibraryEntryType *entry; if (Crosshair.AttachedLine.Point1.X == Crosshair.AttachedLine.Point2.X && Crosshair.AttachedLine.Point1.Y == Crosshair.AttachedLine.Point2.Y) return (NULL); found = SearchObjectByLocation (PAD_TYPE | PIN_TYPE, &ptr1, &ptr2, &ptr3, Crosshair.AttachedLine.Point1.X, Crosshair.AttachedLine.Point1.Y, 5); if (found == NO_TYPE) { Message (_("No pad/pin under rat line\n")); return (NULL); } if (NAMEONPCB_NAME ((ElementType *) ptr1) == NULL || *NAMEONPCB_NAME ((ElementType *) ptr1) == 0) { Message (_("You must name the starting element first\n")); return (NULL); } /* will work for pins to since the FLAG is common */ group1 = GetLayerGroupNumberBySide ( TEST_FLAG (ONSOLDERFLAG, (PadType *) ptr2) ? BOTTOM_SIDE : TOP_SIDE); strcpy (name1, ConnectionName (found, ptr1, ptr2)); found = SearchObjectByLocation (PAD_TYPE | PIN_TYPE, &ptr1, &ptr2, &ptr3, Crosshair.AttachedLine.Point2.X, Crosshair.AttachedLine.Point2.Y, 5); if (found == NO_TYPE) { Message (_("No pad/pin under rat line\n")); return (NULL); } if (NAMEONPCB_NAME ((ElementType *) ptr1) == NULL || *NAMEONPCB_NAME ((ElementType *) ptr1) == 0) { Message (_("You must name the ending element first\n")); return (NULL); } group2 = GetLayerGroupNumberBySide ( TEST_FLAG (ONSOLDERFLAG, (PadType *) ptr2) ? BOTTOM_SIDE : TOP_SIDE); name2 = ConnectionName (found, ptr1, ptr2); menu = netnode_to_netname (name1); if (menu) { if (netnode_to_netname (name2)) { Message (_ ("Both connections already in netlist - cannot merge nets\n")); return (NULL); } entry = GetLibraryEntryMemory (menu); entry->ListEntry = strdup (name2); netnode_to_netname (name2); goto ratIt; } /* ok, the first name did not belong to a net */ menu = netnode_to_netname (name2); if (menu) { entry = GetLibraryEntryMemory (menu); entry->ListEntry = strdup (name1); netnode_to_netname (name1); goto ratIt; } /* * neither belong to a net, so create a new one. * * before creating a new rats here, we need to search * for a unique name. */ sprintf (ratname, " ratDrawn%i", ++ratDrawn); while (rat_used (ratname)) { sprintf (ratname, " ratDrawn%i", ++ratDrawn); } menu = GetLibraryMenuMemory (&PCB->NetlistLib); menu->Name = strdup (ratname); entry = GetLibraryEntryMemory (menu); entry->ListEntry = strdup (name1); entry = GetLibraryEntryMemory (menu); entry->ListEntry = strdup (name2); menu->flag = 1; ratIt: NetlistChanged (0); return (CreateNewRat (PCB->Data, Crosshair.AttachedLine.Point1.X, Crosshair.AttachedLine.Point1.Y, Crosshair.AttachedLine.Point2.X, Crosshair.AttachedLine.Point2.Y, group1, group2, Settings.RatThickness, NoFlags ())); }