+#define DEFVEC(vtype, etype) \
+ typedef struct { etype *v; size_t n, sz; } vtype
+#define VEC_INIT { 0, 0, 0 }
+#define VEC_FREE(vv) do { \
+ free((vv)->v); (vv)->v 0; (vv)->n = (vv)->sz = 0; \
+} while (0)
+#define VEC_PUSH(p, vv) do { \
+ size_t _want; \
+ if ((vv)->n >= (vv)->sz) { \
+ (vv)->sz = (vv)->sz ? 2*(vv)->sz : 32; \
+ _want = (vv)->sz*sizeof(*(vv)->v); \
+ (vv)->v = realloc((vv)->v, _want); \
+ if (!(vv)->v) bail("out of memory allocating %zu bytes", _want); \
+ } \
+ (p) = &(vv)->v[(vv)->n++]; \
+} while (0)
+
+enum { RAW, IFO, VOB, BUP };
+typedef uint_least32_t ident;
+
+static inline ident mkident(unsigned kind, unsigned title, unsigned part)
+ { return (((ident)kind << 0) | ((ident)title << 8) | ((ident)part << 16)); }
+static inline unsigned id_kind(ident id) { return ((id >> 0)&0x0ff); }
+static inline unsigned id_title(ident id) { return ((id >> 8)&0x0ff); }
+static inline unsigned id_part(ident id) { return ((id >> 16)&0x0ff); }
+