}
#endif
-// Scan the source specification, and return the length of the
-// inclusion. "filename/from,to"
-// filename
-// filename/from
-// filename/-to
-// filename/from-to
-static size_t scan_source(char *in,struct Source *p) {
- int e = strlen( in );
- int i = e-1;
- int s = -1;
- int m = -1;
- // scan for last '/' and last '-'
- for ( ; i >= 0; i-- ) {
- if ( in[i] == '/' ) {
- s = i;
- break;
- }
- if ( in[i] == '-' ) {
- m = i;
- }
- }
-#if DEBUG
- fprintf( stderr, "m=%d s=%d\n", m, s );
-#endif
- // Copy the filename, and set from and to
- p->filename = strndup( in, ( s < 0 )? e : s );
- struct stat buf;
- if ( stat( p->filename, & buf ) ) {
- perror( p->filename );
- return 1;
- }
- p->from = ( s < 0 )? 0 : atol( in+s+1 );
- if ( p->from < 0 ) {
- p->from = 0;
- }
-#if DEBUG
- fprintf( stderr, "p->from=%ld\n", p->from );
-#endif
- p->to = ( m < 0 )? buf.st_size : atol( in+m+1 );
- if ( p->from > p->to || p->to > buf.st_size ) {
- return 1;
- }
- return 0;
+static char *range;
+static unsigned int c;
+static int RANGE(int SCAN,int N ) {
+ return ( SCAN == N ) && *(range+c) == 0;
}
static int setup_sources(char **argv,int i,int n) {
int j = 0;
sources.size = 0;
for ( ; j < n; i++, j++ ) {
+ struct stat filestat;
struct Source *p = sources.array + j;
- if ( scan_source( argv[i], p ) ) {
- // should free everything malloc-ed
- return 1;
- }
- p->start = sources.size;
- sources.size += p->to - p->from;
+ // Open the fragment file rw if possible, else ro
+ range = strrchr( argv[i], '/' ); // last '/'
+ p->filename = range? strndup( argv[i], range - argv[i] ) : argv[i];
p->fd = open( p->filename, O_RDWR );
+ int rdonly = 0;
if ( p->fd < 0 ) {
- fprintf( stderr, "** %s opened read-only\n", p->filename );
+ rdonly = 1;
p->fd = open( p->filename, O_RDONLY );
}
if ( p->fd < 0 ) {
perror( p->filename );
- return 1;
+ return 1; // Error return
+ }
+ if ( stat( p->filename, &filestat ) ) {
+ perror( p->filename );
+ return 1;
}
+ if ( rdonly ) {
+ fprintf( stderr, "** %s opened read-only\n", p->filename );
+ }
+ p->from = 0;
+ p->to = filestat.st_size;
+ // Process any range variation
+ if ( range && *(++range) ) {
+ unsigned int a,b;
+ if ( RANGE( sscanf( range, "%u-%u%n", &a, &b, &c ), 2 ) ) {
+ p->from = a;
+ p->to = b;
+ } else if ( RANGE( sscanf( range, "%u--%u%n", &a, &b, &c ), 2 ) ) {
+ p->from = a;
+ p->to -= b;
+ } else if ( RANGE( sscanf( range, "%u-%n", &a, &c ), 1 ) ) {
+ p->from = a;
+ } else if ( RANGE( sscanf( range, "%u%n", &a, &c ), 1 ) ) {
+ p->from = a;
+ } else if ( RANGE( sscanf( range, "-%u%n", &b, &c ), 1 ) ) {
+ p->to = b;
+ } else if ( RANGE( sscanf( range, "--%u%n", &b, &c ), 1 ) ) {
+ p->to -= b;
+ } else if ( RANGE( sscanf( range, "-%n", &c), 0 ) ) {
+ // Acceptable as "start-end" range
+ } else {
+ fprintf( stderr, "** BAD RANGE: %s\n", argv[i] );
+ return 1;
+ }
+ }
+ p->start = sources.size; // the fusefile position of fragment
+ sources.size += p->to - p->from;
#if DEBUG
print_source( p );
#endif