FreeCalypso > hg > ueda-linux
view pads2gpcb/decals.c @ 49:b3b7013d9228
pads2gpcb.c/decals.c: allow underscores in written decal file names
author | Mychaela Falconia <falcon@ivan.Harhan.ORG> |
---|---|
date | Sat, 30 Jan 2016 17:38:47 +0000 |
parents | c977d637f038 |
children | 727d4e56d5c8 |
line wrap: on
line source
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include <strings.h> #include "globals.h" #include "struct.h" extern long convert_input_dim(); static struct part_decal *current_decal; static struct footprint_body fpbody; static struct footprint_pad *pins_array; #define SOLDERMASK_DELTA (600 * 254) #define CLEARANCE_SETTING (2000 * 254) static void enter_decal() { struct part_decal *p, **pp; char *name = input_line_fields[0]; for (pp = &part_decal_list; p = *pp; pp = &p->next) if (!strcmp(p->name, name)) { fprintf(stderr, "%s line %d: decal name \"%s\" already defined\n", input_filename, input_lineno, name); exit(1); } p = malloc(sizeof(struct part_decal) + strlen(name) + 1); if (!p) { perror("malloc of struct part_decal"); exit(1); } p->name = (char *)(p + 1); strcpy(p->name, name); p->body = 0; p->next = 0; *pp = p; current_decal = p; } static void get_line_internal() { if (!get_input_line()) { fprintf(stderr, "error: EOF in the middle of a part decal definition\n"); exit(1); } } static void one_drawing_piece() { int ncoord, i; /* just skip it for now */ get_line_internal(); parse_input_line_fields(); if (input_line_nfields < 2) { fprintf(stderr, "%s line %d: expected piece header line giving # of coords\n", input_filename, input_lineno); exit(1); } ncoord = atoi(input_line_fields[1]); for (i = 0; i < ncoord; i++) get_line_internal(); } static void one_text_item() { /* just skip it for now */ get_line_internal(); get_line_internal(); get_line_internal(); } static void one_attr_label() { /* just skip it for now */ get_line_internal(); get_line_internal(); get_line_internal(); } static void read_pindef_line(idx) { get_line_internal(); if (input_line_buf[0] != 'T') { fprintf(stderr, "%s line %d: 'T' line expected\n", input_filename, input_lineno); exit(1); } parse_input_line_fields(); if (input_line_nfields != 5) { fprintf(stderr, "%s line %d: expected 5 fields in 'T' line\n", input_filename, input_lineno); exit(1); } input_line_fields[0]++; if (atoi(input_line_fields[4]) != idx + 1) { fprintf(stderr, "%s line %d: expected %d in the pin number field\n", input_filename, input_lineno); exit(1); } pins_array[idx].x1 = convert_input_dim(input_line_fields[0]); pins_array[idx].y1 = -convert_input_dim(input_line_fields[1]); } static void process_pad_shape(padptr) struct pad_shape_info *padptr; { padptr->short_dim = convert_input_dim(input_line_fields[1]); if (padptr->short_dim <= 0) { printf("line %d: pad short dim <= 0\n", input_lineno); return; } if (!strcmp(input_line_fields[2], "R")) { padptr->rounded = 1; padptr->elongated = 0; } else if (!strcmp(input_line_fields[2], "S")) { padptr->rounded = 0; padptr->elongated = 0; } else if (!strcmp(input_line_fields[2], "OF")) { padptr->rounded = 1; padptr->elongated = 1; } else if (!strcmp(input_line_fields[2], "RF")) { padptr->rounded = 0; padptr->elongated = 1; } else { printf("line %d: unsupported pad shape %s\n", input_lineno, input_line_fields[2]); return; } if (padptr->elongated) { if (input_line_nfields < 6) { fprintf(stderr, "%s line %d: too few fields in OF/RF pad stack line\n", input_filename, input_lineno); exit(1); } padptr->angle = parse_input_angle_90s(input_line_fields[3]); if (padptr->angle != 0 && padptr->angle != 90) { printf("line %d: unsupported OF/RF angle\n", input_lineno); return; } padptr->long_dim = convert_input_dim(input_line_fields[4]); if (strcmp(input_line_fields[5], "0")) { printf("line %d: unsupported nonzero finoffset\n", input_lineno); return; } if (padptr->long_dim <= padptr->short_dim) { printf("line %d: OF/RF long dim <= short dim\n", input_lineno); return; } } padptr->valid = 1; } static void one_padstack_def() { int pinno, stacklines, i; struct pad_shape_info *padptr; get_line_internal(); parse_input_line_fields(); if (input_line_nfields != 3 || strcmp(input_line_fields[0], "PAD")) { fprintf(stderr, "%s line %d: expected PAD header line\n", input_filename, input_lineno); exit(1); } pinno = atoi(input_line_fields[1]); stacklines = atoi(input_line_fields[2]); if (pinno < 0 || pinno > fpbody.npins) { fprintf(stderr, "%s line %d: PAD pinno field invalid\n", input_filename, input_lineno); exit(1); } if (pinno) padptr = &pins_array[pinno-1].shape; else padptr = &fpbody.default_pad; padptr->defined = 1; for (i = 0; i < stacklines; i++) { get_line_internal(); parse_input_line_fields(); if (input_line_nfields < 3) { fprintf(stderr, "%s line %d: too few fields in pad stack line\n", input_filename, input_lineno); exit(1); } if (!strcmp(input_line_fields[0], "-2")) process_pad_shape(padptr); } } static void apply_default_padstack() { int i; if (!fpbody.default_pad.valid) return; for (i = 0; i < fpbody.npins; i++) if (!pins_array[i].shape.defined) pins_array[i].shape = fpbody.default_pad; } static convert_pad_to_gpcb(pinidx) { struct footprint_pad *pin = pins_array + pinidx; long long_minus_short, delta; if (!pin->shape.valid) { printf("error: no pad shape for pin #%d\n", pinidx + 1); return(-1); } pin->thickness = pin->shape.short_dim; pin->clearance = CLEARANCE_SETTING; pin->mask = pin->thickness + SOLDERMASK_DELTA; pin->x2 = pin->x1; pin->y2 = pin->y1; if (!pin->shape.elongated) return(0); long_minus_short = pin->shape.long_dim - pin->shape.short_dim; delta = long_minus_short / 2; switch (pin->shape.angle) { case 0: pin->x1 -= delta; pin->x2 += delta; return(0); case 90: pin->y1 -= delta; pin->y2 += delta; return(0); } return(-1); } static void write_decal_as_element() { char *filename, *cp, *dp; int c; FILE *outf; filename = malloc(strlen(current_decal->name) * 3 + 8); if (!filename) { perror("malloc for output file name"); exit(1); } strcpy(filename, "decals/"); dp = filename + 7; for (cp = current_decal->name; *cp; ) { c = *cp++; if (isalnum(c) || c == '-' || c == '.' || c == '_') *dp++ = c; else { sprintf(dp, "%%%02X", c); dp += 3; } } *dp = '\0'; outf = fopen(filename, "w"); if (!outf) { perror(filename); exit(1); } write_gpcb_element(outf, current_decal->body, 0, "", "", "", 0); fclose(outf); printf("Written to %s\n", filename); free(filename); } static void process_one_decal() { int num_drawing_pieces, num_padstack_defs; int num_text_items, num_attr_labels; int i, valid; if (input_line_nfields < 7 || input_line_nfields > 9) { fprintf(stderr, "%s line %d: expected beginning of part decal definition, wrong # of fields\n", input_filename, input_lineno); exit(1); } enter_decal(); printf("Processing decal %s\n", current_decal->name); bzero(&fpbody, sizeof fpbody); if (input_line_fields[1][0] != 'I' && input_line_fields[1][0] != 'M' || input_line_fields[1][1]) { fprintf(stderr, "%s line %d: expected 'I' or 'M' in field 1\n", input_filename, input_lineno); exit(1); } fpbody.src_units = input_line_fields[1][0]; if (input_units_global == 'B') input_units_current = 'B'; else input_units_current = fpbody.src_units; fpbody.mark_x = convert_input_dim(input_line_fields[2]); fpbody.mark_y = -convert_input_dim(input_line_fields[3]); num_drawing_pieces = atoi(input_line_fields[4]); fpbody.npins = atoi(input_line_fields[5]); num_padstack_defs = atoi(input_line_fields[6]); if (input_line_nfields > 7) num_text_items = atoi(input_line_fields[7]); else num_text_items = 0; if (input_line_nfields > 8) num_attr_labels = atoi(input_line_fields[8]); else num_attr_labels = 0; /* sanity checks */ if (fpbody.npins < 1) { fprintf(stderr, "%s line %d: # of terminals %d < 1\n", input_filename, input_lineno, fpbody.npins); exit(1); } if (num_padstack_defs < 1) { fprintf(stderr, "%s line %d: # of pad stack defs %d < 1\n", input_filename, input_lineno, num_padstack_defs); exit(1); } /* done parsing the header line, initialize some misc */ fpbody.refdes_scale = 100; /* read and process the miscellany */ for (i = 0; i < num_drawing_pieces; i++) one_drawing_piece(); for (i = 0; i < num_text_items; i++) one_text_item(); for (i = 0; i < num_attr_labels; i++) one_attr_label(); /* the meat: allocate and fill the pins array */ pins_array = malloc(sizeof(struct footprint_pad) * fpbody.npins); if (!pins_array) { perror("malloc of the pins array"); exit(1); } fpbody.pins = pins_array; bzero(pins_array, sizeof(struct footprint_pad) * fpbody.npins); for (i = 0; i < fpbody.npins; i++) read_pindef_line(i); /* read and process the pad stack definitions */ for (i = 0; i < num_padstack_defs; i++) one_padstack_def(); /* post-processing */ apply_default_padstack(); valid = 1; for (i = 0; i < fpbody.npins; i++) if (convert_pad_to_gpcb(i) < 0) valid = 0; if (valid) { /* good, save it */ current_decal->body = malloc(sizeof(struct footprint_body)); if (!current_decal->body) { perror("malloc to save footprint body"); exit(1); } *current_decal->body = fpbody; if (write_decal_files) write_decal_as_element(); } else { printf("decal to gpcb fp conversion FAILED\n"); free(pins_array); } } process_partdecal_section() { for (;;) { if (!get_input_line()) { fprintf(stderr, "error: EOF in PARTDECAL section\n"); exit(1); } if (input_line_buf[0] == '*') { parse_starline(); if (strcmp(input_line_starkw, "REMARK")) break; else continue; } parse_input_line_fields(); if (input_line_nfields) process_one_decal(); } }