dvd-sector-copy.c: Truncate the event list before processing a lost `stop'.
[dvdrip] / dvd-sector-copy.c
index cb43588..fe8da21 100644 (file)
@@ -335,7 +335,7 @@ static ssize_t read_sectors(secaddr pos, void *buf, secaddr want)
   if (badblocks.n) {
     best = 0; lo = 0; hi = badblocks.n;
 #ifdef DEBUG
-    progress_clear();
+    progress_clear(&progress);
     printf(";; searching badblocks for %"PRIuSEC" .. %"PRIuSEC"\n",
           pos, pos + want);
 #endif
@@ -455,7 +455,7 @@ static PRINTF_LIKE(2, 3)
   va_list ap;
 
   va_start(ap, what);
-  progress_clear();
+  progress_clear(&progress);
   printf(";; recovery buffer (");
   vprintf(what, ap);
   printf("): "
@@ -488,7 +488,7 @@ static ssize_t recovery_read_buffer(struct recoverybuf *r,
   ssize_t n;
 
 #ifdef DEBUG
-  progress_clear();
+  progress_clear(&progress);
   show_recovery_buffer_map(r, "begin(%"PRIuSEC", %"PRIuSEC")", pos, want);
 #endif
 
@@ -510,7 +510,7 @@ static ssize_t recovery_read_buffer(struct recoverybuf *r,
   } else if (pos > r->pos + r->end) {
       r->pos = pos; r->start = r->end = 0;
 #ifdef DEBUG
-p      show_recovery_buffer_map(r, "cleared; beyond previous region");
+      show_recovery_buffer_map(r, "cleared; beyond previous region");
 #endif
   } else if (pos + want > r->pos + r->sz) {
     diff = (pos + want) - (r->pos + r->sz);
@@ -936,6 +936,39 @@ end:
   return (rc);
 }
 
+#ifdef DEBUG
+static void dump_eventq(const char *what)
+{
+  unsigned i;
+  const struct event *ev;
+  char fn[MAXFNSZ];
+
+  printf("\n;; event dump (%s):\n", what);
+  for (i = 0; i < eventq.n; i++) {
+    ev = &eventq.v[i];
+    switch (ev->ev) {
+      case EV_BEGIN:
+       store_filename(fn, filetab.v[ev->file].id);
+       printf(";; %8"PRIuSEC": begin %s\n", ev->pos, fn);
+       break;
+      case EV_END:
+       store_filename(fn, filetab.v[ev->file].id);
+       printf(";; %8"PRIuSEC": end %s\n", ev->pos, fn);
+       break;
+      case EV_WRITE:
+       printf(";; %8"PRIuSEC": write\n", ev->pos);
+       break;
+      case EV_STOP:
+       printf(";; %8"PRIuSEC": stop\n", ev->pos);
+       break;
+      default:
+       printf(";; %8"PRIuSEC": ?%u\n", ev->pos, ev->ev);
+       break;
+    }
+  }
+}
+#endif
+
 int main(int argc, char *argv[])
 {
   unsigned f = 0;
@@ -948,7 +981,6 @@ int main(int argc, char *argv[])
   const char *device, *outfile;
   struct badblock *bad;
   int opt, blksz;
-  unsigned n;
   size_t i;
   FILE *fp;
   struct buf buf = BUF_INIT;
@@ -1148,7 +1180,7 @@ int main(int argc, char *argv[])
 
   qsort(eventq.v, eventq.n, sizeof(struct event), compare_event);
 
-  f &= ~f_write; start = 0; n = 0;
+  f &= ~f_write; start = 0;
   for (i = 0; i < eventq.n; i++) {
     ev = &eventq.v[i];
     switch (ev->ev) {
@@ -1156,7 +1188,7 @@ int main(int argc, char *argv[])
        if (f&f_write)
          bail("overlapping ranges: range from %"PRIuSEC" still open at %"PRIuSEC"",
               start, ev->pos);
-       n++; f |= f_write; start = ev->pos;
+       f |= f_write; start = ev->pos;
        break;
       case EV_STOP:
        f &= ~f_write;
@@ -1164,25 +1196,32 @@ int main(int argc, char *argv[])
     }
   }
 
+#ifdef DEBUG
+  dump_eventq("initial");
+#endif
   f &= ~f_write; start = 0;
   for (i = 0; i < eventq.n; i++) {
     ev = &eventq.v[i];
-    switch (ev->ev) {
-      case EV_WRITE: start = ev->pos; f |= f_write; break;
-      case EV_STOP: nsectors += ev->pos - start; f &= ~f_write; break;
-    }
+    if (ev->ev == EV_WRITE) { start = ev->pos; f |= f_write; }
     if (ev->pos >= limit) break;
+    if (ev->ev == EV_STOP) { nsectors += ev->pos - start; f &= ~f_write; }
     if (f&f_fixup) start = ev->pos;
   }
   eventq.n = i;
+#ifdef DEBUG
+  dump_eventq("trimmed");
+#endif
   if (f&f_fixup) {
     put_event(EV_WRITE, 0, start);
-    n++; f |= f_write;
+    f |= f_write;
   }
   if (f&f_write) {
     nsectors += limit - start;
     put_event(EV_STOP, 0, limit);
   }
+#ifdef DEBUG
+  dump_eventq("final");
+#endif
 
   copy_progress.render = render_copy_progress;
   progress_additem(&progress, &copy_progress);
@@ -1257,7 +1296,7 @@ int main(int argc, char *argv[])
 
   if (f&f_stats) {
     gettimeofday(&tv1, 0); t = tvdiff(&tv0, &tv1);
-    if (nsectors == limit - start) { ndone -= start; nsectors -= start; }
+    if (nsectors == limit) { ndone -= start; nsectors -= start; }
     tot = scale_bytes((double)nsectors*SECTORSZ, &totunit);
     rate = scale_bytes((double)nsectors*SECTORSZ/t, &rateunit);
     moan("all done: %.1f %sB in %s -- %.1f %sB/s",