/* --------------------------------------------------------------------------- * Add a connection to the net */ LibraryEntryTypePtr CreateNewConnection (LibraryMenuTypePtr net, char *conn) { LibraryEntryTypePtr entry = GetLibraryEntryMemory (net); entry->ListEntry = STRDUP (conn); return (entry); }
static int list_cb(void *cookie, const char *subdir, const char *name, pcb_fp_type_t type) { list_st_t *l = (list_st_t *)cookie; LibraryEntryTypePtr entry; /* Pointer to individual menu entry */ size_t len; if (type == PCB_FP_DIR) { list_dir_t *d; /* can not recurse directly from here because that would ruin the menu pointer: GetLibraryMenuMemory (&Library) calls realloc()! Build a list of directories to be visited later, instead. */ d = malloc(sizeof(list_dir_t)); d->subdir = strdup(name); d->parent = strdup(subdir); d->next = l->subdirs; l->subdirs = d; return 0; } l->children++; entry = GetLibraryEntryMemory (l->menu); /* * entry->AllocatedMemory points to abs path to the footprint. * entry->ListEntry points to fp name itself. */ len = strlen(subdir) + strlen("/") + strlen(name) + 8; entry->AllocatedMemory = (char *)calloc (1, len); strcat (entry->AllocatedMemory, subdir); strcat (entry->AllocatedMemory, PCB_DIR_SEPARATOR_S); /* store pointer to start of footprint name */ entry->ListEntry = entry->AllocatedMemory + strlen (entry->AllocatedMemory); /* Now place footprint name into AllocatedMemory */ strcat (entry->AllocatedMemory, name); if (type == PCB_FP_PARAMETRIC) strcat(entry->AllocatedMemory, "()"); entry->Type = type; return 0; }
int ReadNetlist (char *filename) { static char *command = NULL; char inputline[MAX_NETLIST_LINE_LENGTH + 1]; char temp[MAX_NETLIST_LINE_LENGTH + 1]; FILE *fp; LibraryMenuType *menu = NULL; LibraryEntryType *entry; int i, j, lines, kind; bool continued; bool used_popen = false; int retval = 0; if (!filename) return 1; /* nothing to do */ Message (_("Importing PCB netlist %s\n"), filename); if (EMPTY_STRING_P (Settings.RatCommand)) { fp = fopen (filename, "r"); if (!fp) { Message("Cannot open %s for reading", filename); return 1; } } else { used_popen = true; free (command); command = EvaluateFilename (Settings.RatCommand, Settings.RatPath, filename, NULL); /* open pipe to stdout of command */ if (*command == '\0' || (fp = popen (command, "r")) == NULL) { PopenErrorMessage (command); return 1; } } lines = 0; /* kind = 0 is net name * kind = 1 is route style name * kind = 2 is connection */ kind = 0; while (fgets (inputline, MAX_NETLIST_LINE_LENGTH, fp)) { size_t len = strlen (inputline); /* check for maximum length line */ if (len) { if (inputline[--len] != '\n') Message (_("Line length (%i) exceeded in netlist file.\n" "additional characters will be ignored.\n"), MAX_NETLIST_LINE_LENGTH); else inputline[len] = '\0'; } continued = (inputline[len - 1] == '\\') ? true : false; if (continued) inputline[len - 1] = '\0'; lines++; i = 0; while (inputline[i] != '\0') { j = 0; /* skip leading blanks */ while (inputline[i] != '\0' && BLANK (inputline[i])) i++; if (kind == 0) { /* add two spaces for included/unincluded */ temp[j++] = ' '; temp[j++] = ' '; } while (!BLANK (inputline[i])) temp[j++] = inputline[i++]; temp[j] = '\0'; while (inputline[i] != '\0' && BLANK (inputline[i])) i++; if (kind == 0) { menu = GetLibraryMenuMemory (&PCB->NetlistLib); menu->Name = strdup (temp); menu->flag = 1; kind++; } else { if (kind == 1 && strchr (temp, '-') == NULL) { kind++; menu->Style = strdup (temp); } else { entry = GetLibraryEntryMemory (menu); entry->ListEntry = strdup (temp); } } } if (!continued) kind = 0; } if (!lines) { Message (_("Empty netlist file!\n")); retval = 1; } if (used_popen) pclose (fp); else fclose (fp); sort_netlist (); return retval; }
/* --------------------------------------------------------------------------- * Read contents of the library description file (for M4) * and then read in M4 libs. Then call a fcn to read the newlib * footprints. */ int ReadLibraryContents (void) { static char *command = NULL; char inputline[MAX_LIBRARY_LINE_LENGTH + 1]; FILE *resultFP = NULL; LibraryMenuType *menu = NULL; LibraryEntryType *entry; /* If we don't have a command to execute to find the library contents, * skip this. This is used by default on Windows builds (set in main.c), * as we can't normally run shell scripts or expect to have m4 present. */ if (Settings.LibraryContentsCommand != NULL && Settings.LibraryContentsCommand[0] != '\0') { /* First load the M4 stuff. The variable Settings.LibraryPath * points to it. */ free (command); command = EvaluateFilename (Settings.LibraryContentsCommand, Settings.LibraryPath, Settings.LibraryFilename, NULL); #ifdef DEBUG printf("In ReadLibraryContents, about to execute command %s\n", command); #endif /* This uses a pipe to execute a shell script which provides the names of * all M4 libs and footprints. The results are placed in resultFP. */ if (command && *command && (resultFP = popen (command, "r")) == NULL) { PopenErrorMessage (command); } /* the M4 library contents are separated by colons; * template : package : name : description */ while (resultFP != NULL && fgets (inputline, MAX_LIBRARY_LINE_LENGTH, resultFP)) { size_t len = strlen (inputline); /* check for maximum linelength */ if (len) { len--; if (inputline[len] != '\n') Message ("linelength (%i) exceeded; following characters will be ignored\n", MAX_LIBRARY_LINE_LENGTH); else inputline[len] = '\0'; } /* if the line defines a menu */ if (!strncmp (inputline, "TYPE=", 5)) { menu = GetLibraryMenuMemory (&Library); menu->Name = strdup (UNKNOWN (&inputline[5])); menu->directory = strdup (Settings.LibraryFilename); } else { /* allocate a new menu entry if not already done */ if (!menu) { menu = GetLibraryMenuMemory (&Library); menu->Name = strdup (UNKNOWN ((char *) NULL)); menu->directory = strdup (Settings.LibraryFilename); } entry = GetLibraryEntryMemory (menu); entry->AllocatedMemory = strdup (inputline); /* now break the line into pieces separated by colons */ if ((entry->Template = strtok (entry->AllocatedMemory, ":")) != NULL) if ((entry->Package = strtok (NULL, ":")) != NULL) if ((entry->Value = strtok (NULL, ":")) != NULL) entry->Description = strtok (NULL, ":"); /* create the list entry */ len = strlen (EMPTY (entry->Value)) + strlen (EMPTY (entry->Description)) + 4; entry->ListEntry = (char *)calloc (len, sizeof (char)); sprintf (entry->ListEntry, "%s, %s", EMPTY (entry->Value), EMPTY (entry->Description)); } } if (resultFP != NULL) pclose (resultFP); } /* Now after reading in the M4 libs, call a function to * read the newlib footprint libraries. Then sort the whole * library. */ if (ParseLibraryTree () > 0 || resultFP != NULL) { sort_library (&Library); return 0; } return (1); }
/* This is a helper function for ParseLibrary Tree. Given a char *path, * it finds all newlib footprints in that dir and sticks them into the * library menu structure named entry. */ static int LoadNewlibFootprintsFromDir(char *libpath, char *toppath) { char olddir[MAXPATHLEN + 1]; /* The directory we start out in (cwd) */ char subdir[MAXPATHLEN + 1]; /* The directory holding footprints to load */ DIR *subdirobj; /* Interable object holding all subdir entries */ struct dirent *subdirentry; /* Individual subdir entry */ struct stat buffer; /* Buffer used in stat */ LibraryMenuType *menu = NULL; /* Pointer to PCB's library menu structure */ LibraryEntryType *entry; /* Pointer to individual menu entry */ size_t l; size_t len; int n_footprints = 0; /* Running count of footprints found in this subdir */ /* Cache old dir, then cd into subdir because stat is given relative file names. */ memset (subdir, 0, sizeof subdir); memset (olddir, 0, sizeof olddir); if (GetWorkingDirectory (olddir) == NULL) { Message (_("LoadNewlibFootprintsFromDir: Could not determine initial working directory\n")); return 0; } if (strcmp (libpath, "(local)") == 0) strcpy (subdir, "."); else strcpy (subdir, libpath); if (chdir (subdir)) { ChdirErrorMessage (subdir); return 0; } /* Determine subdir is abs path */ if (GetWorkingDirectory (subdir) == NULL) { Message (_("LoadNewlibFootprintsFromDir: Could not determine new working directory\n")); if (chdir (olddir)) ChdirErrorMessage (olddir); return 0; } /* First try opening the directory specified by path */ if ( (subdirobj = opendir (subdir)) == NULL ) { OpendirErrorMessage (subdir); if (chdir (olddir)) ChdirErrorMessage (olddir); return 0; } /* Get pointer to memory holding menu */ menu = GetLibraryMenuMemory (&Library); /* Populate menuname and path vars */ menu->Name = strdup (pcb_basename(subdir)); menu->directory = strdup (pcb_basename(toppath)); /* Now loop over files in this directory looking for files. * We ignore certain files which are not footprints. */ while ((subdirentry = readdir (subdirobj)) != NULL) { #ifdef DEBUG /* printf("... Examining file %s ... \n", subdirentry->d_name); */ #endif /* Ignore non-footprint files found in this directory * We're skipping .png and .html because those * may exist in a library tree to provide an html browsable * index of the library. */ l = strlen (subdirentry->d_name); if (!stat (subdirentry->d_name, &buffer) && S_ISREG (buffer.st_mode) && subdirentry->d_name[0] != '.' && NSTRCMP (subdirentry->d_name, "CVS") != 0 && NSTRCMP (subdirentry->d_name, "Makefile") != 0 && NSTRCMP (subdirentry->d_name, "Makefile.am") != 0 && NSTRCMP (subdirentry->d_name, "Makefile.in") != 0 && (l < 4 || NSTRCMP(subdirentry->d_name + (l - 4), ".png") != 0) && (l < 5 || NSTRCMP(subdirentry->d_name + (l - 5), ".html") != 0) && (l < 4 || NSTRCMP(subdirentry->d_name + (l - 4), ".pcb") != 0) ) { #ifdef DEBUG /* printf("... Found a footprint %s ... \n", subdirentry->d_name); */ #endif n_footprints++; entry = GetLibraryEntryMemory (menu); /* * entry->AllocatedMemory points to abs path to the footprint. * entry->ListEntry points to fp name itself. */ len = strlen(subdir) + strlen("/") + strlen(subdirentry->d_name) + 1; entry->AllocatedMemory = (char *)calloc (1, len); strcat (entry->AllocatedMemory, subdir); strcat (entry->AllocatedMemory, PCB_DIR_SEPARATOR_S); /* store pointer to start of footprint name */ entry->ListEntry = entry->AllocatedMemory + strlen (entry->AllocatedMemory); /* Now place footprint name into AllocatedMemory */ strcat (entry->AllocatedMemory, subdirentry->d_name); /* mark as directory tree (newlib) library */ entry->Template = (char *) -1; } } /* Done. Clean up, cd back into old dir, and return */ closedir (subdirobj); if (chdir (olddir)) ChdirErrorMessage (olddir); return n_footprints; }
/*! * \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 ())); }