# HG changeset patch # User Space Falcon # Date 1439075219 0 # Node ID 2af4a85daf898c699c01545047d3d7b46f9961e3 # Parent 6c7c79d37eff20a18f5bf7235a8472fb80763c9e unet2pads program written, compiles diff -r 6c7c79d37eff -r 2af4a85daf89 .hgignore --- a/.hgignore Sat Aug 08 21:52:33 2015 +0000 +++ b/.hgignore Sat Aug 08 23:06:59 2015 +0000 @@ -8,5 +8,6 @@ ^ueda/sverp/ueda-sverp$ ^ueda/sverp-bind/unet-bind$ ^ueda/unet-utils/unet-destar$ +^ueda/unet-utils/unet2pads$ ^ueda/utils/cutelements$ ^ueda/utils/instfileelem$ diff -r 6c7c79d37eff -r 2af4a85daf89 ueda/unet-utils/Makefile --- a/ueda/unet-utils/Makefile Sat Aug 08 21:52:33 2015 +0000 +++ b/ueda/unet-utils/Makefile Sat Aug 08 23:06:59 2015 +0000 @@ -1,6 +1,6 @@ CC= gcc CFLAGS= -O2 -PROGS= unet-destar +PROGS= unet-destar unet2pads LIBUNET=../libunet/libunet.a BINDIR= /usr/local/bin @@ -16,3 +16,4 @@ rm -f *.[ao] a.out core errs ${PROGS} unet-destar: unet-destar.o +unet2pads: unet2pads.o diff -r 6c7c79d37eff -r 2af4a85daf89 ueda/unet-utils/unet2pads.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ueda/unet-utils/unet2pads.c Sat Aug 08 23:06:59 2015 +0000 @@ -0,0 +1,255 @@ +#include +#include +#include +#include +#include +#include "../libunet/unetrd.h" +#include "../libunet/nethash.h" + +extern struct net *enter_net_object(); +extern struct net *find_net_by_name(); +extern struct net *net_list_head; + +static char *input_filename, *output_filename; +static struct unetrd_state rdstate; +static struct unetrd_out rdout; +static FILE *tempFILE, *outFILE; +static int no_parttype_errors; + +struct netextra { + struct netmember *head; + struct netmember **tailp; +}; + +struct netmember { + char *name; + struct netmember *next; +}; + +static FILE * +tempfile() +{ + char template[16]; + register int fd; + register FILE *f; + + strcpy(template, "/tmp/uedaXXXXXX"); + fd = mkstemp(template); + if (fd < 0) { + perror("mkstemp"); + exit(1); + } + unlink(template); + f = fdopen(fd, "r+w"); + if (!f) { + perror("fdopen"); + exit(1); + } + return(f); +} + +static void +dump_tempfile() +{ + register FILE *inf = tempFILE; + register FILE *outf = outFILE; + register int c; + + rewind(inf); + while ((c = getc(inf)) != EOF) + putc(c, outf); + fclose(inf); +} + +static void +process_pin_connect(compname) + char *compname; +{ + register struct net *n; + register struct netextra *nx; + register struct netmember *nm; + + n = find_net_by_name(rdout.connect_to_net); + nx = (struct netextra *)(n + 1); + nm = (struct netmember *) malloc(sizeof(struct netmember) + + strlen(compname) + + strlen(rdout.objname) + 2); + if (!nm) { + perror("malloc"); + exit(1); + } + nm->name = (char *)(nm + 1); + sprintf(nm->name, "%s.%s", compname, rdout.objname); + nm->next = 0; + *nx->tailp = nm; + nx->tailp = &nm->next; +} + +static void +process_component() +{ + char compname[64]; + int parttype_seen = 0; + + strcpy(compname, rdout.objname); + for (;;) { + if (!read_unet_line(&rdstate, &rdout)) { + fprintf(stderr, "%s error: EOF in COMPONENT block\n", + input_filename); + exit(1); + } + if (rdout.typecode == UNETOBJ_CLOSINGBRACE) + break; + switch(rdout.typecode) { + case UNETOBJ_PRIMITIVE: + case UNETOBJ_ALTNAME: + continue; + case UNETOBJ_ATTR: + if (strcmp(rdout.objname, "pads_parttype")) + continue; + if (parttype_seen) { + fprintf(stderr, + "%s lind %d: duplicate ATTR pads_parttype for COMPONENT %s\n", + input_filename, rdstate.lineno, + compname); + exit(1); + } + fprintf(tempFILE, "%s %s\n", compname, + rdout.attr_value); + parttype_seen = 1; + continue; + case UNETOBJ_PIN: + if (rdout.connect_to_net) + process_pin_connect(compname); + continue; + case UNETOBJ_PINMAP: + fprintf(stderr, + "%s line %d: PINMAP objects not expected in unet2pads input\n", + input_filename, rdstate.lineno); + exit(1); + default: + fprintf(stderr, + "%s line %d: object type %s unexpected in COMPONENT block\n", + input_filename, rdstate.lineno, rdout.keyword); + exit(1); + } + } + if (!parttype_seen) { + fprintf(stderr, + "error: component %s has no pads_parttype set\n", + compname); + no_parttype_errors++; + } +} + +static void +process_input_unet() +{ + struct net *n; + struct netextra *nx; + + open_unet_input_file(input_filename, &rdstate); + while (read_unet_line(&rdstate, &rdout)) { + switch(rdout.typecode) { + case UNETOBJ_CLOSINGBRACE: + fprintf(stderr, + "%s line %d: unexpected '}' outside of component block\n", + input_filename, rdstate.lineno); + exit(1); + case UNETOBJ_NET: + n = enter_net_object(rdout.objname, + sizeof(struct netextra)); + nx = (struct netextra *)(n + 1); + nx->head = 0; + nx->tailp = &nx->head; + continue; + case UNETOBJ_COMPONENT: + if (!tempFILE) + tempFILE = tempfile(); + process_component(); + continue; + case UNETOBJ_STARPOINT: + fprintf(stderr, +"error: STARPOINT objects not expected in unet2pads input (%s line %d)\n", + input_filename, rdstate.lineno); + exit(1); + default: + fprintf(stderr, + "%s line %d: unexpected object type %s\n", + input_filename, rdstate.lineno, rdout.keyword); + exit(1); + } + } + if (!tempFILE) { + fprintf(stderr, "error: no components found in %s input!\n", + input_filename); + exit(1); + } +} + +static void +output_nets() +{ + struct net *n; + struct netextra *nx; + register struct netmember *nm; + int linelen; + + fputs("*NET*\n", outFILE); + for (n = net_list_head; n; n = n->nextinlist) { + nx = (struct netextra *)(n + 1); + fprintf(outFILE, "*SIG* %s\n", n->name); + linelen = 0; + for (nm = nx->head; nm; nm = nm->next) { + if (linelen && linelen + strlen(nm->name) + 1 > 79) { + putc('\n', outFILE); + linelen = 0; + } + if (linelen) { + putc(' ', outFILE); + linelen++; + } + fputs(nm->name, outFILE); + linelen += strlen(nm->name); + } + if (linelen) + putc('\n', outFILE); + } +} + +static void +generate_output() +{ + if (output_filename) { + outFILE = fopen(output_filename, "w"); + if (!outFILE) { + perror(output_filename); + exit(1); + } + } else + outFILE = stdout; + fputs("!PADS-POWERPCB-V3.0-MILS! DESIGN DATABASE ASCII FILE 2.0\n\n", + outFILE); + fputs("*PART* ITEMS\n", outFILE); + dump_tempfile(); + putc('\n', outFILE); + output_nets(); + fputs("\n*END* OF ASCII OUTPUT FILE\n", outFILE); + if (outFILE != stdout) + fclose(outFILE); +} + +main(argc, argv) + char **argv; +{ + if (argc < 2 || argc > 3) { + fprintf(stderr, "usage: %s input.unet [output.unet]\n", + argv[0]); + exit(1); + } + input_filename = argv[1]; + output_filename = argv[2]; + process_input_unet(); + generate_output(); + exit(0); +}