Index: fpcb_nl.c =================================================================== --- fpcb_nl.c (revision 18662) +++ fpcb_nl.c (revision 18663) @@ -59,7 +59,104 @@ static int fpcb_nl_load(const char *fn) { + FILE *f; + char *line, *curr, *next, *fp, *tn, buff[8192], signame[512]; + enum { MODE_NONE, MODE_PART, MODE_NET, MODE_SIGNAL } mode = MODE_NONE; + int anon = 0; + f = pcb_fopen(fn, "r"); + if (f == NULL) { + pcb_message(PCB_MSG_ERROR, "Can't open %s for read\n", fn); + return -1; + } + + pcb_actionl("ElementList", "start", NULL); + pcb_actionl("Netlist", "Freeze", NULL); + pcb_actionl("Netlist", "Clear", NULL); + + while((line = fgets(buff, sizeof(buff), f)) != NULL) { + rtrim(line); + + /* parse directive */ + if (*line == '*') { + if (pcb_strcasecmp(line, "*END*") == 0) + break; + else if (pcb_strcasecmp(line, "*PART*") == 0) + mode = MODE_PART; + else if (pcb_strcasecmp(line, "*NET*") == 0) + mode = MODE_NET; + else if (pcb_strncasecmp(line, "*SIGNAL*", 8) == 0) { + *signame = '\0'; + if ((mode == MODE_NET) || (mode == MODE_SIGNAL)) { + int len; + mode = MODE_SIGNAL; + line += 9; + ltrim(line); + len = strlen(line); + if (len == 0) { + pcb_message(PCB_MSG_ERROR, "Empty/missing net name in *SINGAL*\n"); + sprintf(signame, "pcbrndanonymous%d", anon++); + } + else { + if (len > sizeof(signame)-1) { + len = sizeof(signame)-1; + pcb_message(PCB_MSG_ERROR, "Net name %s is too long, truncating.\nThis may result in broken netlist, please use shorter names \n", line); + } + memcpy(signame, line, len); + signame[len] = '\0'; + } + } + else + mode = MODE_NONE; + } + continue; + } + + switch(mode) { + case MODE_PART: + if (*line == '\0') + continue; + fp = strpbrk(line, " \t"); + if (fp != NULL) { + *fp = '\0'; + fp++; + ltrim(fp); + } + if ((fp != NULL) && (*fp != '\0')) { + pcb_actionl("ElementList", "Need", line, fp, "", NULL); + } + else + pcb_message(PCB_MSG_ERROR, "No footprint specified for %s\n", line); + break; + case MODE_SIGNAL: + ltrim(line); + for(curr = line; curr != NULL; curr = next) { + next = strpbrk(curr, " \t"); + if (next != NULL) { + *next = '\0'; + next++; + ltrim(next); + } + if (*curr == '\0') + continue; + tn = strchr(curr, '.'); + if (tn == NULL) { + pcb_message(PCB_MSG_ERROR, "Syntax error in netlist: '%s' in net '%s' should be refdes.termid\n", curr, signame); + continue; + } + *tn = '-'; + pcb_actionl("Netlist", "Add", signame, curr, NULL); + } + break; + default: break; /* ignore line */ + } + } + + pcb_actionl("Netlist", "Sort", NULL); + pcb_actionl("Netlist", "Thaw", NULL); + pcb_actionl("ElementList", "Done", NULL); + + fclose(f); return -1; } @@ -67,10 +164,8 @@ static const char pcb_acth_LoadFpcbnlFrom[] = "Loads the specified freepcb netlist."; fgw_error_t pcb_act_LoadFpcbnlFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) { - const char *fname = NULL, *end; - char *fname_asc, *fname_net, *fname_base; + const char *fname = NULL; static char *default_file = NULL; - int rs; PCB_ACT_MAY_CONVARG(1, FGW_STR, LoadFpcbnlFrom, fname = argv[1].val.str);