diff --git a/src/hid/bom/bom.c b/src/hid/bom/bom.c index 756d591e..af67d9f0 100644 --- a/src/hid/bom/bom.c +++ b/src/hid/bom/bom.c @@ -97,12 +97,26 @@ Parameter @code{} can be @samp{km}, @samp{m}, @samp{cm}, @samp{mm}, @end ftable %end-doc */ + {"attrs", "Name of the attributes input file", + HID_String, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_attrs 2 + +/* %start-doc options "80 BOM Creation" +@ftable @code +@item --xy-unit +Unit of XY dimensions. Defaults to mil. +Parameter @code{} can be @samp{km}, @samp{m}, @samp{cm}, @samp{mm}, +@samp{um}, @samp{nm}, @samp{px}, @samp{in}, @samp{mil}, @samp{dmil}, +@samp{cmil}, or @samp{inch}. +@end ftable +%end-doc +*/ {"xy-unit", "XY units", HID_Unit, 0, 0, {-1, 0, 0}, NULL, 0}, -#define HA_unit 2 +#define HA_unit 3 {"xy-in-mm", ATTR_UNDOCUMENTED, HID_Boolean, 0, 0, {0, 0, 0}, 0, 0}, -#define HA_xymm 3 +#define HA_xymm 4 }; #define NUM_OPTIONS (sizeof(bom_options)/sizeof(bom_options[0])) @@ -113,6 +127,10 @@ static const char *bom_filename; static const char *xy_filename; static const Unit *xy_unit; +static char **attr_list = NULL; +static int attr_count = 0; +static int attr_max = 0; + typedef struct _StringList { char *str; @@ -125,6 +143,7 @@ typedef struct _BomList char *value; int num; StringList *refdes; + char **attrs; struct _BomList *next; } BomList; @@ -148,6 +167,9 @@ bom_get_export_options (int *n) derive_default_filename(PCB->Filename, &bom_options[HA_xyfile ], ".xy" , &last_xy_filename ); } + if (!bom_options[HA_attrs].default_val.str_value) + bom_options[HA_attrs].default_val.str_value = strdup("attribs"); + if (n) *n = NUM_OPTIONS; return bom_options; @@ -256,60 +278,72 @@ string_insert (char *str, StringList * list) } static BomList * -bom_insert (char *refdes, char *descr, char *value, BomList * bom) +bom_insert (char *refdes, char *descr, char *value, ElementType *e, BomList * bom) { - BomList *newlist, *cur, *prev = NULL; + BomList *newlist = NULL, *cur = NULL, *prev = NULL; + int i; + char *val; - if (bom == NULL) + if (bom != NULL) { - /* this is the first element so automatically create an entry */ - if ((newlist = (BomList *) malloc (sizeof (BomList))) == NULL) + /* search and see if we already have used one of these + components */ + cur = bom; + while (cur != NULL) { - fprintf (stderr, "malloc() failed in bom_insert()\n"); - exit (1); - } + int attr_mismatch = 0; - newlist->next = NULL; - newlist->descr = strdup (descr); - newlist->value = strdup (value); - newlist->num = 1; - newlist->refdes = string_insert (refdes, NULL); - return (newlist); - } + for (i=0; iattrs[i]) != 0) + attr_mismatch = 1; + } - /* search and see if we already have used one of these - components */ - cur = bom; - while (cur != NULL) - { - if ((NSTRCMP (descr, cur->descr) == 0) && - (NSTRCMP (value, cur->value) == 0)) - { - cur->num++; - cur->refdes = string_insert (refdes, cur->refdes); - break; + if ((NSTRCMP (descr, cur->descr) == 0) && + (NSTRCMP (value, cur->value) == 0) && + ! attr_mismatch) + { + cur->num++; + cur->refdes = string_insert (refdes, cur->refdes); + return (bom); + } + prev = cur; + cur = cur->next; } - prev = cur; - cur = cur->next; } - if (cur == NULL) + if ((newlist = (BomList *) malloc (sizeof (BomList))) == NULL) { - if ((newlist = (BomList *) malloc (sizeof (BomList))) == NULL) - { - fprintf (stderr, "malloc() failed in bom_insert()\n"); - exit (1); - } + fprintf (stderr, "malloc() failed in bom_insert()\n"); + exit (1); + } - prev->next = newlist; + if (prev) + prev->next = newlist; - newlist->next = NULL; - newlist->descr = strdup (descr); - newlist->value = strdup (value); - newlist->num = 1; - newlist->refdes = string_insert (refdes, NULL); + newlist->next = NULL; + newlist->descr = strdup (descr); + newlist->value = strdup (value); + newlist->num = 1; + newlist->refdes = string_insert (refdes, NULL); + + if ((newlist->attrs = (char **) malloc (attr_count * sizeof (char *))) == NULL) + { + fprintf (stderr, "malloc() failed in bom_insert()\n"); + exit (1); + } + + for (i=0; iattrs[i] = val ? val : ""; } + if (bom == NULL) + bom = newlist; + return (bom); } @@ -350,14 +384,64 @@ print_and_free (FILE *fp, BomList *bom) } if (fp) { + int i; + for (i=0; iattrs[i]); fprintf (fp, "\n"); } + free (bom->attrs); lastb = bom; bom = bom->next; free (lastb); } } +static void +fetch_attr_list () +{ + int i; + FILE *f; + char buf[1024]; + char *fname; + + if (attr_list != NULL) + { + for (i=0; i= buf && isspace (*c)) + *c-- = 0; + c = buf; + while (*c && isspace (*c)) + c++; + + if (*c) + { + if (attr_count == attr_max) + { + attr_max += 10; + attr_list = (char **) realloc (attr_list, attr_max * sizeof (char *)); + } + attr_list[attr_count++] = strdup (c); + } + } + fclose (f); +} + /*! * Maximum length of following list. */ @@ -393,6 +477,7 @@ PrintBOM (void) BomList *bom = NULL; char *name, *descr, *value,*fixed_rotation; int rpindex; + int i; fp = fopen (xy_filename, "wb"); if (!fp) @@ -401,6 +486,8 @@ PrintBOM (void) return 1; } + fetch_attr_list (); + /* Create a portable timestamp. */ currenttime = time (NULL); { @@ -437,7 +524,9 @@ PrintBOM (void) /* Insert this component into the bill of materials list. */ bom = bom_insert ((char *)UNKNOWN (NAMEONPCB_NAME (element)), (char *)UNKNOWN (DESCRIPTION_NAME (element)), - (char *)UNKNOWN (VALUE_NAME (element)), bom); + (char *)UNKNOWN (VALUE_NAME (element)), + element, + bom); /* @@ -603,7 +692,10 @@ PrintBOM (void) fprintf (fp, "# Date: %s\n", utcTime); fprintf (fp, "# Author: %s\n", pcb_author ()); fprintf (fp, "# Title: %s - PCB BOM\n", UNKNOWN (PCB->Name)); - fprintf (fp, "# Quantity, Description, Value, RefDes\n"); + fprintf (fp, "# Quantity, Description, Value, RefDes"); + for (i=0; i