#include <dvdread/ifo_read.h>
#include <dvdread/ifo_types.h>
-#define SECTORSZ 2048
-#define SECTORS(n) (((n) + (SECTORSZ - 1))/SECTORSZ)
-
#define CTYPE_HACK(fn, ch) fn((unsigned char)(ch))
#define ISDIGIT(ch) CTYPE_HACK(isdigit, ch)
#define ISSPACE(ch) CTYPE_HACK(isspace, ch)
#define N(v) (sizeof(v)/sizeof((v)[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); }
+#define SECTORSZ 2048
+#define SECTORS(n) (((n) + (SECTORSZ - 1))/SECTORSZ)
static const char *prog = "<unset>";
static int status = 0;
static void vmoan(const char *fmt, va_list ap)
{ fprintf(stderr, "%s: ", prog); vfprintf(stderr, fmt, ap); }
+
+__attribute__((format(printf, 1, 2)))
+static void moan(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt); vmoan(fmt, ap); va_end(ap);
+ fputc('\n', stderr);
+}
+
__attribute__((noreturn, format(printf, 1, 2)))
static void bail(const char *fmt, ...)
{
fputc('\n', stderr);
exit(2);
}
+
__attribute__((noreturn, format(printf, 2, 3)))
static void bail_syserr(int err, const char *fmt, ...)
{
exit(2);
}
+#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); }
+
#define MAXFNSZ (1 + 8 + 1 + 12 + 1)
static void store_filename(char *buf, ident id)
}
}
-#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)
-
typedef uint_least32_t secaddr;
#define PRIuSEC PRIuLEAST32
DEFVEC(event_v, struct event);
static event_v eventq = VEC_INIT;
+static int compare_event(const void *a, const void *b)
+{
+ const struct event *eva = a, *evb = b;
+
+ if (eva->pos < evb->pos) return (-1);
+ else if (eva->pos > evb->pos) return (+1);
+
+ if (eva->ev < evb->ev) return (-1);
+ else if (eva->ev > evb->ev) return (+1);
+
+ if (eva->file < evb->file) return (-1);
+ else if (eva->file > evb->file) return (+1);
+
+ return (0);
+}
+
typedef uint_least32_t bits;
static bits live[(MAXFILES + 31)/32];
start[0], start[npart - 1] + SECTORS(len[npart - 1]));
}
-static int compare_event(const void *a, const void *b)
-{
- const struct event *eva = a, *evb = b;
-
- if (eva->pos < evb->pos) return (-1);
- else if (eva->pos > evb->pos) return (+1);
-
- if (eva->ev < evb->ev) return (-1);
- else if (eva->ev > evb->ev) return (+1);
-
- if (eva->file < evb->file) return (-1);
- else if (eva->file > evb->file) return (+1);
-
- return (0);
-}
-
static int progresslen = 0;
static void clear_progress_internal(void)
n = read_sectors(src, pos, buf, 1);
if (n > 0) {
clear_progress();
- fprintf(stderr, "%s: sector %"PRIuSEC" read ok after retry\n",
- prog, pos);
+ moan("sector %"PRIuSEC" read ok after retry", pos);
bad_lo = bad_hi = pos;
goto recovered;
}
report_bad_blocks_progress(src, bad_lo, bad_hi, errno);
if (bad_hi >= end) {
clear_progress();
- fprintf(stderr, "%s: giving up on this extent\n", prog);
+ moan("giving up on this extent");
n = 0; goto recovered;
}
step *= 2;
recovered:
if (bad_hi > bad_lo) {
clear_progress();
- fprintf(stderr, "%s: skipping %"PRIuSEC" bad sectors "
- "(%"PRIuSEC" .. %"PRIuSEC")\n",
- prog, bad_hi - bad_lo, bad_lo, bad_hi);
+ moan("skipping %"PRIuSEC" bad sectors (%"PRIuSEC" .. %"PRIuSEC")",
+ bad_hi - bad_lo, bad_lo, bad_hi);
if (src->mapfile) {
if (!src->mapfp) {
src->mapfp = fopen(src->mapfile, "w");