revise argument processing
authorRalph Ronnquist <ralph.ronnquist@gmail.com>
Sun, 17 Jul 2022 01:32:50 +0000 (11:32 +1000)
committerRalph Ronnquist <ralph.ronnquist@gmail.com>
Sun, 17 Jul 2022 01:32:50 +0000 (11:32 +1000)
fusefile.c

index b9d3b2d68b7ee71ba0ab2080187d6f2584c3f52e..5a51066232251a3db09dc310df5abdd4fbb6c043 100644 (file)
@@ -61,49 +61,10 @@ static void print_source(struct Source *p) {
 }
 #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) {
@@ -115,22 +76,56 @@ 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