FreeCalypso > hg > ueda-linux
view ueda/libueda/xga.c @ 139:bf188727e606
donl-rename-parts reader: no tEDAx-style escapes
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 07 Sep 2020 04:25:11 +0000 |
parents | c91e7a30fab3 |
children |
line wrap: on
line source
/* * This module contains the function that implements the reading of PGA/BGA * package description files and some related functions. */ #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include "xga.h" extern char *copystr(); extern FILE *find_symlib_file(); extern char sought_libfile_fullpath[]; parse_xga_pinnumber(desc, pinstr, parsed) register struct grid_pkg_desc *desc; register char *pinstr; struct xga_parsed_pinnum *parsed; { char *rowfind; int col; if (!isupper(pinstr[0]) || !isdigit(pinstr[1])) return(-1); rowfind = index(desc->row_letters, pinstr[0]); if (!rowfind) return(-1); if (!string_is_valid_decnum(pinstr + 1)) return(-1); col = atoi(pinstr + 1); if (col < 1 || col > desc->ncolumns) return(-1); parsed->row_0based = rowfind - desc->row_letters; parsed->col_0based = col - 1; return(0); } static void check_complete(desc) register struct grid_pkg_desc *desc; { register char *array; if (desc->holes_array) /* already allocated */ return; if (!desc->nrows || !desc->ncolumns) /* not specified yet */ return; /* allocate it! */ array = malloc(desc->nrows * desc->ncolumns); if (!array) { perror("malloc"); exit(1); } desc->holes_array = array; bzero(array, desc->nrows * desc->ncolumns); } static void validate_rows_arg(arg, filename, lineno) char *arg, *filename; int lineno; { register char *cp; register int c, prev; prev = 0; for (cp = arg; c = *cp++; prev = c) { if (c < 'A' || c > 'Z') { fprintf(stderr, "%s line %d: rows setting: only uppercase letters are allowed\n", filename, lineno); exit(1); } if (c <= prev) { fprintf(stderr, "%s line %d: rows setting: letters must be increasing\n", filename, lineno); exit(1); } } } static void handle_rows_line(desc, arg, filename, lineno) struct grid_pkg_desc *desc; char *arg, *filename; int lineno; { register char *cp, *np; if (desc->row_letters) { fprintf(stderr, "%s line %d: duplicate rows setting\n", filename, lineno); exit(1); } for (cp = arg; isspace(*cp); cp++) ; if (*cp == '\0' || *cp == '#') { fprintf(stderr, "%s line %d: rows setting has no argument\n", filename, lineno); exit(1); } for (np = cp; *cp && !isspace(*cp); cp++) ; if (*cp) *cp++ = '\0'; validate_rows_arg(np, filename, lineno); desc->row_letters = copystr(np); desc->nrows = strlen(np); check_complete(desc); } static void handle_columns_line(desc, arg, filename, lineno) struct grid_pkg_desc *desc; char *arg, *filename; int lineno; { register char *cp, *np; if (desc->ncolumns) { fprintf(stderr, "%s line %d: duplicate columns setting\n", filename, lineno); exit(1); } for (cp = arg; isspace(*cp); cp++) ; if (*cp == '\0' || *cp == '#') { fprintf(stderr, "%s line %d: columns setting has no argument\n", filename, lineno); exit(1); } for (np = cp; *cp && !isspace(*cp); cp++) ; if (*cp) *cp++ = '\0'; if (!string_is_valid_decnum(np)) { fprintf(stderr, "%s line %d: columns setting must be a number\n", filename, lineno); exit(1); } desc->ncolumns = atoi(np); if (desc->ncolumns < 1) { fprintf(stderr, "%s line %d: columns number must be positive\n", filename, lineno); exit(1); } check_complete(desc); } static void handle_hole_spec(desc, arg, filename, lineno) register struct grid_pkg_desc *desc; char *arg, *filename; int lineno; { char *arg2; struct xga_parsed_pinnum start_parsed, end_parsed; register int r, c; arg2 = index(arg, '-'); if (arg2) *arg2++ = '\0'; else arg2 = arg; if (parse_xga_pinnumber(desc, arg, &start_parsed) < 0) { fprintf(stderr, "%s line %d: \"%s\" is not a valid pin position for this package\n", filename, lineno, arg); exit(1); } if (parse_xga_pinnumber(desc, arg2, &end_parsed) < 0) { fprintf(stderr, "%s line %d: \"%s\" is not a valid pin position for this package\n", filename, lineno, arg2); exit(1); } if (start_parsed.row_0based == end_parsed.row_0based) { r = start_parsed.row_0based; if (start_parsed.col_0based > end_parsed.col_0based) { error_reversed: fprintf(stderr, "%s line %d: hole ranges need to be increasing\n", filename, lineno); exit(1); } for (c = start_parsed.col_0based; c <= end_parsed.col_0based; c++) desc->holes_array[r * desc->ncolumns + c] = 1; } else if (start_parsed.col_0based == end_parsed.col_0based) { c = start_parsed.col_0based; if (start_parsed.row_0based > end_parsed.row_0based) goto error_reversed; for (r = start_parsed.row_0based; r <= end_parsed.row_0based; r++) desc->holes_array[r * desc->ncolumns + c] = 1; } else { fprintf(stderr, "%s line %d: hole ranges must be horizontal or vertical\n", filename, lineno); exit(1); } } static void handle_hole_line(desc, arg, filename, lineno) struct grid_pkg_desc *desc; char *arg, *filename; int lineno; { register char *cp, *np; if (!desc->holes_array) { fprintf(stderr, "%s line %d: rows and columns must be defined before holes\n", filename, lineno); exit(1); } for (cp = arg; ; ) { while (isspace(*cp)) cp++; if (*cp == '\0' || *cp == '#') break; for (np = cp; *cp && !isspace(*cp); cp++) ; if (*cp) *cp++ = '\0'; handle_hole_spec(desc, np, filename, lineno); } } struct grid_pkg_desc * read_grid_pkg_file(filename) char *filename; { FILE *f; char linebuf[1024]; int lineno; register char *cp, *np; struct grid_pkg_desc *desc; f = find_symlib_file(filename, NULL); if (!f) { fprintf(stderr, "Cannot find xGA definition file %s\n", filename); exit(1); } desc = (struct grid_pkg_desc *) malloc(sizeof(struct grid_pkg_desc)); if (!desc) { perror("malloc"); exit(1); } bzero(desc, sizeof(struct grid_pkg_desc)); for (lineno = 1; fgets(linebuf, sizeof linebuf, f); lineno++) { for (cp = linebuf; isspace(*cp); cp++) ; if (*cp == '\0' || *cp == '#') continue; for (np = cp; *cp && !isspace(*cp); cp++) ; if (*cp) *cp++ = '\0'; if (!strcmp(np, "rows")) handle_rows_line(desc, cp, sought_libfile_fullpath, lineno); else if (!strcmp(np, "columns")) handle_columns_line(desc, cp, sought_libfile_fullpath, lineno); else if (!strcmp(np, "hole")) handle_hole_line(desc, cp, sought_libfile_fullpath, lineno); else { fprintf(stderr, "%s line %d: setting \"%s\" not understood\n", sought_libfile_fullpath, lineno, np); exit(1); } } fclose(f); if (!desc->nrows) { fprintf(stderr, "error: %s contains no rows setting\n", sought_libfile_fullpath); exit(1); } if (!desc->ncolumns) { fprintf(stderr, "error: %s contains no columns setting\n", sought_libfile_fullpath); exit(1); } return(desc); } free_grid_pkg_desc(desc) struct grid_pkg_desc *desc; { free(desc->row_letters); free(desc->holes_array); free(desc); }