+ overlay.table[ p ].beg = beg;
+ overlay.table[ p ].end = end;
+ overlay_save_count();
+}
+
+/**
+ * Delete the region entry at p by moving the portion [p+1,count]
+ * down.
+ */
+static void overlay_delete(size_t p) {
+ size_t bytes = ( --overlay.count - p ) * sizeof( struct Region );
+ if ( bytes ) {
+ memmove( (char*) &overlay.table[ p ],
+ (char*) &overlay.table[ p+1 ],
+ bytes );
+ }
+}
+
+/**
+ * Mark the given region as updated, i.e. written to the overlay. The
+ * mark region may attach to prior marked regions or be a new,
+ * separate region. If attaching, it causes the prior regions to
+ * expand and the table adjusted by deleting any regions that become
+ * fully contained in other regions.
+ */
+static void overlay_mark(off_t beg,off_t end) {
+#if DEBUG
+ fprintf( stderr, "overlay_mark( %ld, %ld )\n", beg, end );
+#endif
+ int deleted = 0;
+ ssize_t q;
+ ssize_t p = overlay_prior_fragment( beg );
+ // p is the nearest region below or at beg (or -1)
+ if ( p >= 0 && beg <= overlay.table[p].end ) {
+ // p overlaps mark region
+ if ( end <= overlay.table[p].end ) {
+ // region p covers mark region already
+#if DEBUG
+ fprintf( stderr, "overlay covering ( %ld %ld )\n",
+ overlay.table[p].beg, overlay.table[p].end );
+#endif
+ return;
+ }
+ // the new mark region extends region p
+ overlay.table[p].end = end;
+ q = p+1;
+ while ( q < overlay.count &&
+ overlay.table[q].beg <= overlay.table[p].end ) {
+ // Extended region merges with subsequent region
+ if ( overlay.table[p].end < overlay.table[q].end ) {
+ overlay.table[p].end = overlay.table[q].end;
+ }
+ overlay_delete( q );
+ deleted++;
+ }
+ if ( deleted ) {
+ overlay_save_count();
+ q = overlay.count;
+ }
+ overlay_save_table( p, q );
+#if DEBUG
+ fprintf( stderr, "overlay expand ( %ld %ld ) deleted %d\n",
+ overlay.table[p].beg, overlay.table[p].end, deleted );
+#endif
+ return;
+ }
+ // The prior region p does not expand into new mark region
+ p++; // subsequent region
+ if ( p >= overlay.count || end < overlay.table[p].beg ) {
+ // New mark region is a separate region at p
+ overlay_insert( p, beg, end );
+#if DEBUG
+ fprintf( stderr, "overlay new ( %ld %ld )\n",
+ overlay.table[p].beg, overlay.table[p].end );
+#endif
+ overlay_save_table( p, overlay.count );
+ return;
+ }
+ // New marks start before and overlap with region p => change p
+ // and handle any subsequent regions being covered
+ overlay.table[p].beg = beg;
+ q = p+1;
+ if ( overlay.table[p].end < end ) {
+ overlay.table[p].end = end;
+ while ( q < overlay.count &&
+ overlay.table[q].beg <= overlay.table[p].end ) {
+ if ( overlay.table[p].end < overlay.table[q].end ) {
+ overlay.table[p].end = overlay.table[q].end;
+ }
+ overlay_delete( q );
+ deleted++;
+ }
+ if ( deleted ) {
+ overlay_save_count();
+ q = overlay.count;
+ }
+ }
+ overlay_save_table( p, q );
+#if DEBUG
+ fprintf( stderr, "overlay before ( %ld %ld ) deleted %d\n",
+ overlay.table[p].beg, overlay.table[p].end, deleted );
+#endif
+}
+
+static void setup_overlay(char *filename) {
+ overlay.source.filename = filename;
+ overlay.source.fd = open( filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR );
+ if ( overlay.source.fd < 0 ) {
+ perror( filename );
+ usage();
+ }
+}
+
+#if DEBUG
+static void print_source(struct Source *p) {
+ fprintf( stderr, "%p { %s, %ld, %ld, %ld, %d }\n",
+ p, p->filename, p->from, p->to, p->start, p-> fd );
+}
+#endif
+
+static char *range;
+static unsigned int c;
+static int RANGE(int s,int n ) {
+ return ( s == n ) && *(range+c) == 0;