Index: hid_cam.c =================================================================== --- hid_cam.c (revision 19419) +++ hid_cam.c (revision 19420) @@ -203,6 +203,74 @@ return 0; } +static char *lp_err = ""; + +/* Parse a layer directive: split at comma, curr will end up holding the + layer name. If there were transformations in (), they are split and + listed in tr up to at most *trc entries. Returns NULL on error or + pointer to the next layer directive. */ +static char *parse_layer(char *curr, char **trk, char **trv, int *trc) +{ + char *s, *lasta, *eq; + int level = 0, trmax = *trc; + *trc = 0; + + for(s = curr; *s != '\0'; s++) { + switch(*s) { + case '(': + if (level == 0) { + *s = '\0'; + lasta = s+1; + } + level++; + break; + case ')': + if (level > 0) + level--; + if (level == 0) + goto append; + break; + case ',': + if (level == 0) + goto out; + append:; + if (*trc >= trmax) + return lp_err; + lasta = strip(lasta); + trk[*trc] = lasta; + eq = strchr(lasta, '='); + if (eq != NULL) { + *eq = '\0'; + eq++; + } + trv[*trc] = eq; + (*trc)++; + *s = '\0'; + lasta = s+1; + } + } + + if (level > 0) + return lp_err; + + out:; + + if (*s != '\0') { + *s = '\0'; + s++; + return s; + } + + return NULL; /* no more layers */ +} + +static void parse_layer_args(char **trk, char **trv, int trc) +{ + int n; + for(n = 0; n < trc; n++) + pcb_trace(" [%d] '%s' '%s'\n", n, trk[n], trv[n]); +} + int pcb_cam_begin(pcb_board_t *pcb, pcb_cam_t *dst, const char *src, const pcb_hid_attribute_t *attr_tbl, int numa, pcb_hid_attr_val_t *options) { char *curr, *next; @@ -226,7 +294,6 @@ *next = '\0'; next++; dst->fn = strip(dst->inst); -pcb_trace("CAM FN='%s'\n", dst->fn); while(isspace(*next)) next++; @@ -233,12 +300,17 @@ /* parse layers */ for(curr = next; curr != NULL; curr = next) { + char *trk[64], *trv[64]; + int trc = sizeof(trk) / sizeof(trk[0]); + next = parse_layer(curr, trk, trv, &trc); + if (next == lp_err) { + pcb_message(PCB_MSG_ERROR, "CAM rule: invalid layer transformation\n"); + goto err; + } - next = strchr(curr, ','); - if (next != NULL) { - *next = '\0'; - next++; - } +{ +} + curr = strip(curr); if (*curr == '@') { /* named layer */ @@ -264,6 +336,8 @@ goto err; #warning TODO: extend the syntax for purpose + parse_layer_args(trk, trv, trc); + vl = pcb_vlayer_get_first(lyt, NULL, -1); if (vl == NULL) { pcb_layergrp_id_t gids[PCB_MAX_LAYERGRP];