FreeCalypso > hg > ueda-linux
view ueda/unet-utils/unet2pads.c @ 115:a7276a03289d
M4 library: new metric QFP footprints
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 12 Jun 2020 07:25:04 +0000 |
parents | a0d227fc9569 |
children |
line wrap: on
line source
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include <unistd.h> #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-file]\n", argv[0]); exit(1); } input_filename = argv[1]; output_filename = argv[2]; process_input_unet(); if (no_parttype_errors) exit(1); generate_output(); exit(0); }