X-Git-Url: https://git.distorted.org.uk/~mdw/dvdrip/blobdiff_plain/788fe88a9eaf97fa3956cc3f7894c250c2443c89..72279434156ee961ae3a4fc585ac1d803b1e1905:/dvd-sector-copy.c?ds=inline diff --git a/dvd-sector-copy.c b/dvd-sector-copy.c index 01dd6a5..6e2737a 100644 --- a/dvd-sector-copy.c +++ b/dvd-sector-copy.c @@ -28,23 +28,14 @@ #include #include -#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 = ""; static int status = 0; @@ -59,6 +50,16 @@ static void usage(FILE *fp) 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, ...) { @@ -68,6 +69,7 @@ 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, ...) { @@ -79,6 +81,32 @@ 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) @@ -105,23 +133,6 @@ 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 @@ -141,6 +152,22 @@ struct event { 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]; @@ -237,22 +264,6 @@ static void put_title(dvd_reader_t *dvd, unsigned title) 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) @@ -469,8 +480,7 @@ static void emit(struct source *src, int outfd, secaddr start, secaddr end) 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; } @@ -481,7 +491,7 @@ static void emit(struct source *src, int outfd, secaddr start, secaddr end) 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; @@ -503,9 +513,8 @@ static void emit(struct source *src, int outfd, secaddr start, secaddr end) 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");