Index: trunk/src_plugins/io_kicad_legacy/Plug.tmpasm =================================================================== --- trunk/src_plugins/io_kicad_legacy/Plug.tmpasm (revision 2662) +++ trunk/src_plugins/io_kicad_legacy/Plug.tmpasm (revision 2663) @@ -1,5 +1,5 @@ put /local/pcb/mod {io_kicad_legacy} -put /local/pcb/mod/OBJS [@ $(PLUGDIR)/io_kicad_legacy/io_kicad_legacy.o $(PLUGDIR)/io_kicad_legacy/write.o @] +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/io_kicad_legacy/io_kicad_legacy.o $(PLUGDIR)/io_kicad_legacy/write.o $(PLUGDIR)/io_kicad_legacy/uniq_name.o @] #put /local/pcb/mod/YACC {$(PLUGDIR)/io_kicad_legacy/parse_y} #put /local/pcb/mod/LEX {$(PLUGDIR)/io_kicad_legacy/parse_l} Index: trunk/src_plugins/io_kicad_legacy/uniq_name.c =================================================================== --- trunk/src_plugins/io_kicad_legacy/uniq_name.c (nonexistent) +++ trunk/src_plugins/io_kicad_legacy/uniq_name.c (revision 2663) @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include "uniq_name.h" +#include "compat_misc.h" + +static const char *unm_default_unnamed = "unnamed"; +static const char *unm_default_suffix_sep = "_dup"; + +void unm_init(unm_t *state) +{ + state->unnamed = unm_default_unnamed; + state->suffix_sep = unm_default_suffix_sep; + htsp_init(&state->seen, strhash, strkeyeq); +} + + +void unm_uninit(unm_t *state) +{ + htsp_entry_t *e; + for (e = htsp_first(&state->seen); e; e = htsp_next(&state->seen, e)) { + free(e->key); + htsp_delentry(&state->seen, e); + } + htsp_uninit(&state->seen); +} + +const char *unm_name(unm_t *state, const char *orig_name) +{ + int l1, l2; + char *name, *end; + const char *head; + + if (orig_name == NULL) { + head = state->unnamed; + l1 = strlen(state->unnamed); + l2 = strlen(state->suffix_sep); + } + else { + if (!htsp_has(&state->seen, (char *)orig_name)) { + name = pcb_strdup(orig_name); + htsp_set(&state->seen, name, name); + return name; + } + else { + head = orig_name; + l1 = strlen(orig_name); + l2 = strlen(state->suffix_sep); + } + } + + /* have to generate a new name, allocate memory and print the static part + leave end to point where the integer part goes + 21 is large enough to store the widest 64 bit integer decimal, and a \0 */ + end = name = malloc(l1+l2+21); + memcpy(end, head, l1); end += l1; + memcpy(end, state->suffix_sep, l2); end += l2; + + /* look for the first unused entry with this suffix. Note: the entries + this function creates won't collide as ctr is a state of the group, but + it is possible that a new name collides with a past unsuffixed orig_name; + all in all, this loop should exit in the first iteration */ + do { + sprintf(end, "%ld", state->ctr++); + } while(htsp_has(&state->seen, name)); + + htsp_set(&state->seen, name, name); + return name; +} + Index: trunk/src_plugins/io_kicad_legacy/uniq_name.h =================================================================== --- trunk/src_plugins/io_kicad_legacy/uniq_name.h (nonexistent) +++ trunk/src_plugins/io_kicad_legacy/uniq_name.h (revision 2663) @@ -0,0 +1,27 @@ +#ifndef PCB_UNIQ_NAME_H +#define PCB_UNIQ_NAME_H + +#include + +typedef struct unm_s { + const char *unnamed; /* name to use when orig_name is NULL */ + const char *suffix_sep; /* separator for the suffix appended to generate unique names */ + htsp_t seen; /* hash for storing names already handed out */ + unsigned long int ctr; /* duplication counter - this will become the suffix for duplicated items */ +} unm_t; + +/* Initialize a new group of unique names */ +void unm_init(unm_t *state); + +/* Free all memory claimed by the group */ +void unm_uninit(unm_t *state); + +/* Generate and return a unique name: + - if orig_name is NULL, generate an unnamed item + - if orig_name is not-NULL and is unseen so far, return a copy of orig_name + - if orig_name is not-NULL and has been already seen, return a modified version + Strings returned are newly allocated and can be used until unm_uninit() + is called on state. */ +const char *unm_name(unm_t *state, const char *orig_name); + +#endif