Index: src/plug_io.c =================================================================== --- src/plug_io.c (revision 2224) +++ src/plug_io.c (revision 2225) @@ -165,8 +165,46 @@ return res; } +typedef struct { + plug_io_t *plug; + int prio; +} find_t; -#warning TODO: when we have multiple io_* plugins: write function should not be run on all available IO hooks but on the IO hook saved in the pcb struct (at load or creation time) so we save with the same format all the time +static int find_prio_cmp(const void *p1, const void *p2) +{ + const find_t *f1 = p1, *f2 = p2; + return f1->prio > f2->prio; +} + +/* Find the plugin that offers the highest write prio for the format */ +static plug_io_t *find_writer(const char *fmt) +{ + find_t available[32]; /* wish we had more than 32 IO plugins... */ + int len = 0; + + if (fmt == NULL) { +#warning TODO: rather save format information on load + fmt = "pcb"; + } + +#define cb_append(pl, pr) \ + do { \ + if (pr > 0) { \ + assert(len < sizeof(available)/sizeof(available[0])); \ + available[len].plug = pl; \ + available[len++].prio = pr; \ + } \ + } while(0) + + HOOK_CALL_ALL(plug_io_t, plug_io_chain, fmt_support_prio, cb_append, 1, fmt); + if (len == 0) + return NULL; + + qsort(available, len, sizeof(available[0]), find_prio_cmp); + return available[0].plug; +#undef cb_append +} + int WriteBuffer(FILE *f, BufferType *buff, const char *fmt) { int res = -1; @@ -186,8 +224,11 @@ int WritePCB(FILE *f, const char *fmt) { - int res = -1; - HOOK_CALL(plug_io_t, plug_io_chain, write_pcb, res, == 0, f); + int res; + plug_io_t *p = find_writer(fmt); + + if (p != NULL) + res = p->write_pcb(p, f); plug_io_err(res, "write pcb", NULL); return res; } Index: src/plugins.h =================================================================== --- src/plugins.h (revision 2224) +++ src/plugins.h (revision 2225) @@ -69,6 +69,16 @@ } \ } while(0) +#define HOOK_CALL_ALL(chain_type, chain, func, cb, ...) \ +do { \ + chain_type *__ch__; \ + for(__ch__ = (chain); __ch__ != NULL; __ch__ = __ch__->next) { \ + if (__ch__->func == NULL) \ + continue; \ + cb(__ch__, __ch__->func(__ch__, __VA_ARGS__)); \ + } \ +} while(0) + #define HOOK_REGISTER(chain_type, chain, hstruct) \ do { \ (hstruct)->next = chain; \