FreeCalypso > hg > ueda-linux
diff ueda/unet-utils/unet-destar.c @ 24:7e8a2cb54b6b
started implementing unet-destar
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Thu, 06 Aug 2015 20:20:11 +0000 |
parents | |
children | b2b60ec8d9ca |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ueda/unet-utils/unet-destar.c Thu Aug 06 20:20:11 2015 +0000 @@ -0,0 +1,274 @@ +#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(); + +static char *input_filename, *output_filename; +static struct unetrd_state rdstate; +static struct unetrd_out rdout; +static int total_input_nets; +static struct net *starpoint_head; +static FILE *tempFILE, *outFILE; + +struct netextra { + struct net *squashed_to; + int npoints; +}; + +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_starpoint_head() +{ + register struct net *n; + register struct netextra *nx; + + n = find_net_by_name(rdout.connect_to_net); + for (;;) { + nx = (struct netextra *)(n + 1); + if (!nx->squashed_to) + break; + n = nx->squashed_to; + } + starpoint_head = n; +} + +static void +process_starpoint_arm() +{ + register struct net *n; + register struct netextra *nx; + + n = find_net_by_name(rdout.connect_to_net); + if (n == starpoint_head) { + fprintf(stderr, + "%s line %d: starpoint between net %s and itself!\n", + input_filename, rdstate.lineno, n->name); + exit(1); + } + nx = (struct netextra *)(n + 1); + if (nx->squashed_to) { + fprintf(stderr, + "%s line %d: net %s has already been squashed\n", + input_filename, rdstate.lineno, n->name); + exit(1); + } + nx->squashed_to = starpoint_head; +} + +static void +process_starpoint() +{ + starpoint_head = 0; + for (;;) { + if (!read_unet_line(&rdstate, &rdout)) { + fprintf(stderr, "%s error: EOF in STARPOINT block\n", + input_filename); + exit(1); + } + if (rdout.typecode == UNETOBJ_CLOSINGBRACE) + break; + switch(rdout.typecode) { + case UNETOBJ_PRIMITIVE: + case UNETOBJ_ALTNAME: + continue; + case UNETOBJ_PIN: + if (!rdout.connect_to_net) { + fprintf(stderr, + "%s line %d: no-connect is meaningless for a starpoint arm\n", + input_filename, rdstate.lineno); + exit(1); + } + if (!starpoint_head) + process_starpoint_head(); + else + process_starpoint_arm(); + continue; + case UNETOBJ_PINMAP: + fprintf(stderr, + "%s line %d: PINMAP meaningless in a STARPOINT block\n", + input_filename, rdstate.lineno); + exit(1); + default: + fprintf(stderr, + "%s line %d: object type %s unexpected in STARPOINT block\n", + input_filename, rdstate.lineno, rdout.keyword); + exit(1); + } + } +} + +static void +process_component_pin() +{ + register struct net *n; + register struct netextra *nx; + + if (!rdout.connect_to_net) { + fprintf(tempFILE, " %s %s = NC (%s)\n", rdout.keyword, + rdout.objname, rdout.nc_comment); + return; + } + n = find_net_by_name(rdout.connect_to_net); + for (;;) { + nx = (struct netextra *)(n + 1); + if (!nx->squashed_to) + break; + n = nx->squashed_to; + } + fprintf(tempFILE, " %s %s = NET %s\n", rdout.keyword, rdout.objname, + n->name); + nx->npoints++; +} + +static void +process_component() +{ + fprintf(tempFILE, "\nCOMPONENT %s {\n", 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: + fprintf(tempFILE, " %s %s\n", rdout.keyword, + rdout.objname); + continue; + case UNETOBJ_PIN: + case UNETOBJ_PINMAP: + process_component_pin(); + continue; + default: + fprintf(stderr, + "%s line %d: object type %s unexpected in COMPONENT block\n", + input_filename, rdstate.lineno, rdout.keyword); + exit(1); + } + } + fputs("}\n", tempFILE); +} + +static void +process_input_unet() +{ + struct net *n; + int state = 0; + + 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: + if (state == 0) + state = 1; + else if (state > 1) { + fprintf(stderr, +"error: all input nets must precede all starpoints and components (%s line %d)\n", + input_filename, rdstate.lineno); + exit(1); + } + n = enter_net_object(rdout.objname, + sizeof(struct netextra)); + bzero(n + 1, sizeof(struct netextra)); + total_input_nets++; + continue; + case UNETOBJ_STARPOINT: + if (state < 1) { + fprintf(stderr, + "error (%s line %d): STARPOINT without any preceding NETs\n", + input_filename, rdstate.lineno); + exit(1); + } + if (state > 2) { + fprintf(stderr, + "error: all STARPOINTs must precede all COMPONENTs (%s line %d)\n", + input_filename, rdstate.lineno); + exit(1); + } + state = 2; + process_starpoint(); + continue; + case UNETOBJ_COMPONENT: + if (state < 1) { + fprintf(stderr, + "error (%s line %d): COMPONENT without any preceding NETs\n", + input_filename, rdstate.lineno); + exit(1); + } + if (state < 3) { + tempFILE = tempfile(); + state = 3; + } + process_component(); + continue; + default: + fprintf(stderr, + "%s line %d: unexpected object type %s\n", + input_filename, rdstate.lineno, rdout.keyword); + exit(1); + } + } +} + +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(); + /* output remains to be implemented */ + exit(0); +}