[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: gEDA-user: Renumber in PCB/Was/Is List



Mike Hansen wrote:


Is there documentation anywhere on how to get started in developing for PCB/gschem? I am well versed in Windows C++ development but would need quite a bit of time to get up to speed on performing code work in PCB.


as DJ mentioned, no real docs other than the pcb web site says how to get sources from CVS and the file README.cvs talks about what you need to build from CVS sources.

Here is a patch which gets most of the way there.  Basic functionality
is there and works, the big comment at the top of the ActionRenumber()
function lists whats left to do.

-Dan

Index: action.c
===================================================================
RCS file: /cvsroot/pcb/pcb/src/action.c,v
retrieving revision 1.89
diff -u -2 -r1.89 action.c
--- action.c	15 Aug 2006 02:50:42 -0000	1.89
+++ action.c	15 Aug 2006 19:19:58 -0000
@@ -3115,4 +3115,201 @@
 /* --------------------------------------------------------------------------- */
 
+static const char renumber_syntax[] =
+"Renumber()";
+
+static const char renumber_help[] =
+"Renumber all elements.";
+
+/* %start-doc actions Renumber
+
+%end-doc */
+
+/* FIXME
+   - how to specify the file name?  Probably have a option to get one
+   from calling the action directly like Renumber(logfile) and if not
+   specified have the gui prompt for a file name.
+
+  - add option for renumbering direction (top to bottom, left to right
+  is what I coded up).  Numbering happens on a "row by row" basis.
+
+  - add an option to keep or override locked elements.  I have mixed
+  feelings here.  Do we really ever care about keeping the names on
+  some?  But then again, locked is locked right?
+
+  - What to do about elements with no name?  Right now they are
+    ignored.  Maybe they should get names like I1, I2 (for Instance)
+
+  - need to redo the loaded netlist so you can renumber and then hit
+    'o' on a complete layout and have it still show correct connectivity.
+
+  - finalize the file format.  I'd vote for something like
+
+    command data
+
+    where to start with you'd have something like command =
+    {*COMMENT*, *RENAME*, *WARN*}
+
+    and data is whatever the particular command needs.  So for
+    renames, 
+
+    *RENAME* "old" "new"
+
+    Do we need any rules for quoting here?  This file format is
+    simple, similar to the PADS ECO file format, and extensible if we
+    state early on that unrecognized commands should just be ignored
+    (perhaps with a warning) by any tools which use this file.  
+
+*/
+static int
+ActionRenumber (int argc, char **argv, int x, int y)
+{
+  Boolean changed = False;
+  ElementTypePtr *element_list;
+  unsigned int i, j, cnt;
+  unsigned int tmpi;
+  size_t sz;
+  char *tmps;
+  struct _cnt_list {char *name; unsigned int cnt;} *cnt_list;
+
+  /*
+   * Make a first pass through all of the elements and sort them out
+   * by location on the board.
+   *
+   * We'll actually renumber things in the 2nd pass.
+   */
+
+  printf ("Allocate memory for %d elements\n", PCB->Data->ElementN);
+  element_list = calloc( PCB->Data->ElementN, sizeof (ElementTypePtr));
+  if ( element_list == NULL )
+    {
+      fprintf (stderr, "calloc() failed in %s\n", __FUNCTION__);
+      exit (1);
+    }
+  
+
+  cnt = 0;
+  ELEMENT_LOOP (PCB->Data);
+  {
+    cnt++;
+    /*
+      printf("Pass#1: Element name \"%s\" is at %d, %d\n", 
+      UNKNOWN (NAMEONPCB_NAME (element)),
+      element->MarkX, element->MarkY);
+    */
+    /* search for correct position in the list */
+    i = 0;
+    while (element_list[i] && element->MarkY > element_list[i]->MarkY ) 
+      i++;
+    
+    /*
+      printf ("Index (from Y position is %d\n", i);
+    */
+
+    /* 
+     * We have found the position where we have the first element that
+     * has the same Y value or a lower Y value.  Now move forward if
+     * needed through the X values
+     */
+    while (element_list[i] 
+	   && element->MarkY == element_list[i]->MarkY 
+	   && element->MarkX > element_list[i]->MarkX) 
+      i++;
+    
+    /*
+      printf ("Index (from X position is %d\n", i);
+    */
+    for (j = cnt-1; j > i ; j--)
+      {
+	element_list[j] = element_list[j - 1];
+      }
+    element_list[i] = element;
+  }
+  END_LOOP;
+
+  /* 
+   * Now that the elements are sorted by board position, we go through
+   * and renumber them.
+   */
+  /* FIXME -- need to grow the list dynamically, this line is LAME */
+  cnt_list = calloc (100, sizeof (struct _cnt_list));
+  for (i = 0; i < cnt; i++)
+    {
+      printf("Pass#2: Element name \"%s\" is at %d, %d\n", 
+	   UNKNOWN (NAMEONPCB_NAME (element_list[i])),
+	   element_list[i]->MarkX, element_list[i]->MarkY);
+
+      /* If there is no refdes, maybe just spit out a warning */
+      if (NAMEONPCB_NAME (element_list[i]))
+	{
+	  /* figure out the prefix */
+	  tmps = strdup (NAMEONPCB_NAME (element_list[i]));
+	  j = 0;
+	  while (tmps[j] && (tmps[j] < '0' || tmps[j] > '9') && tmps[j] != '?') 
+	    j++;
+	  tmps[j] = '\0';
+	  printf ("Prefix is \"%s\".  ", tmps);
+	  
+	  /* check the counter for this prefix */
+	  for (j = 0; cnt_list[j].name && (strcmp (cnt_list[j].name, tmps) != 0); j++);
+	  if (cnt_list[j].name)
+	    cnt_list[j].cnt++;
+	  else
+	    {
+	      cnt_list[j].name = strdup (tmps);
+	      cnt_list[j].cnt = 1;
+	    }
+	  
+	  printf ("Count is %d\n", cnt_list[j].cnt);
+	  free (tmps);
+
+	  /* space for the prefix plus 1 digit plus the '\0' */
+	  sz = strlen (cnt_list[j].name) + 2;
+
+	  /* and 1 more per extra digit needed to hold the number */
+	  tmpi = cnt_list[j].cnt;
+	  while (tmpi > 10)
+	    {
+	      sz++;
+	      tmpi = tmpi / 10;
+	    }
+	  tmps = malloc (sz * sizeof (char));
+	  sprintf (tmps, "%s%d", cnt_list[j].name, cnt_list[j].cnt);
+	  if (strcmp (tmps, NAMEONPCB_NAME (element_list[i])) != 0)
+	    {
+	      printf ("*RENAME* \"%s\" \"%s\"\n", NAMEONPCB_NAME (element_list[i]), tmps);
+	      AddObjectToChangeNameUndoList (ELEMENT_TYPE, NULL, NULL,
+					     element_list[i], NAMEONPCB_NAME (element_list[i]));
+
+	      /* FIXME -- disable unique name checks and element
+		 locking (maybe?) first and renable right after */
+
+	      /* FIXME - need to update the loaded netlist */
+	      ChangeObjectName (ELEMENT_TYPE, element_list[i], NULL, NULL, tmps);
+	      changed = True;
+	    }
+	  else
+	    free (tmps);
+	}
+      else 
+	{
+	  printf ("*WARN* Element at (%d,%d) has no name.\n", 
+		  element_list[i]->MarkX, element_list[i]->MarkY);
+	}
+
+    }
+
+  if (changed)
+    {
+      IncrementUndoSerialNumber ();
+      SetChangedFlag (True);
+    }
+
+  free (element_list);
+  return 0;
+}
+
+
+/* --------------------------------------------------------------------------- */
+
 static const char ripup_syntax[] =
 "RipUp(All|Selected|Element)";
@@ -6204,4 +6401,6 @@
   {"RemoveSelected", 0, ActionRemoveSelected,
    removeselected_help, removeselected_syntax},
+  {"Renumber", 0, ActionRenumber,
+   renumber_help, renumber_syntax},
   {"RipUp", 0, ActionRipUp,
    ripup_help, ripup_syntax},


_______________________________________________
geda-user mailing list
geda-user@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-user