diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/urlglob.c | 118 | ||||
-rw-r--r-- | src/urlglob.h | 16 |
2 files changed, 80 insertions, 54 deletions
diff --git a/src/urlglob.c b/src/urlglob.c index 2843a51f9..0d7b5774a 100644 --- a/src/urlglob.c +++ b/src/urlglob.c @@ -166,78 +166,101 @@ static GlobCode glob_range(URLGlob *glob, char *pattern, URLPattern *pat; char *c; int wordamount=1; + char sep; + char sep2; + int step; + int rc; pat = (URLPattern*)&glob->pattern[glob->size / 2]; /* patterns 0,1,2,... correspond to size=1,3,5,... */ ++glob->size; if (isalpha((int)*pattern)) { /* character range detected */ + char min_c; + char max_c; + pat->type = UPTCharRange; - if (sscanf(pattern, "%c-%c]", &pat->content.CharRange.min_c, - &pat->content.CharRange.max_c) != 2 || - pat->content.CharRange.min_c >= pat->content.CharRange.max_c || - pat->content.CharRange.max_c - pat->content.CharRange.min_c > 'z' - 'a') { + rc = sscanf(pattern, "%c-%c%c%d%c", &min_c, &max_c, &sep, &step, &sep2); + if ((rc < 3) || (min_c >= max_c) || ((max_c - min_c) > ('z' - 'a'))) { /* the pattern is not well-formed */ snprintf(glob->errormsg, sizeof(glob->errormsg), - "illegal pattern or range specification after pos %d\n", pos); + "errpr: bad range specification after pos %d\n", pos); return GLOB_ERROR; } - pat->content.CharRange.ptr_c = pat->content.CharRange.min_c; - /* always check for a literal (may be "") between patterns */ - if(GLOB_ERROR == glob_word(glob, pattern + 4, pos + 4, &wordamount)) - wordamount=1; + /* check the (first) separating character */ + if((sep != ']') && (sep != ':')) { + snprintf(glob->errormsg, sizeof(glob->errormsg), + "error: unsupported character (%c) after range at pos %d\n", + sep, pos); + return GLOB_ERROR; + } - *amount = (pat->content.CharRange.max_c - - pat->content.CharRange.min_c + 1) * - wordamount; + /* if there was a ":[num]" thing, use that as step or else use 1 */ + pat->content.CharRange.step = + ((sep == ':') && (rc == 5) && (sep2 == ']'))?step:1; - return GLOB_OK; + pat->content.CharRange.ptr_c = pat->content.CharRange.min_c = min_c; + pat->content.CharRange.max_c = max_c; } - - if (isdigit((int)*pattern)) { /* numeric range detected */ + else if (isdigit((int)*pattern)) { /* numeric range detected */ + int min_n; + int max_n; pat->type = UPTNumRange; pat->content.NumRange.padlength = 0; - if (sscanf(pattern, "%d-%d]", - &pat->content.NumRange.min_n, - &pat->content.NumRange.max_n) != 2 || - pat->content.NumRange.min_n >= pat->content.NumRange.max_n) { + + rc = sscanf(pattern, "%d-%d%c%d%c", &min_n, &max_n, &sep, &step, &sep2); + + if ((rc < 2) || (min_n >= max_n)) { /* the pattern is not well-formed */ snprintf(glob->errormsg, sizeof(glob->errormsg), - "error: illegal pattern or range specification after pos %d\n", - pos); + "error: bad range specification after pos %d\n", pos); return GLOB_ERROR; } + pat->content.NumRange.ptr_n = pat->content.NumRange.min_n = min_n; + pat->content.NumRange.max_n = max_n; + + /* if there was a ":[num]" thing, use that as step or else use 1 */ + pat->content.NumRange.step = + ((sep == ':') && (rc == 5) && (sep2 == ']'))?step:1; + if (*pattern == '0') { /* leading zero specified */ c = pattern; while (isdigit((int)*c++)) ++pat->content.NumRange.padlength; /* padding length is set for all instances of this pattern */ } - pat->content.NumRange.ptr_n = pat->content.NumRange.min_n; - c = (char*)strchr(pattern, ']'); /* continue after next ']' */ - if(c) - c++; - else { - snprintf(glob->errormsg, sizeof(glob->errormsg), "missing ']'"); - return GLOB_ERROR; /* missing ']' */ - } - /* always check for a literal (may be "") between patterns */ + } + else { + snprintf(glob->errormsg, sizeof(glob->errormsg), + "illegal character in range specification at pos %d\n", pos); + return GLOB_ERROR; + } - if(GLOB_ERROR == glob_word(glob, c, pos + (c - pattern), &wordamount)) - wordamount = 1; + c = (char*)strchr(pattern, ']'); /* continue after next ']' */ + if(c) + c++; + else { + snprintf(glob->errormsg, sizeof(glob->errormsg), "missing ']'"); + return GLOB_ERROR; /* missing ']' */ + } - *amount = (pat->content.NumRange.max_n - - pat->content.NumRange.min_n + 1) * + /* always check for a literal (may be "") between patterns */ + + if(GLOB_ERROR == glob_word(glob, c, pos + (c - pattern), &wordamount)) + wordamount = 1; + + if(pat->type == UPTCharRange) + *amount = (pat->content.CharRange.max_c - + pat->content.CharRange.min_c + 1) * wordamount; + else + *amount = (pat->content.NumRange.max_n - + pat->content.NumRange.min_n + 1) * wordamount; - return GLOB_OK; - } - snprintf(glob->errormsg, sizeof(glob->errormsg), - "illegal character in range specification at pos %d\n", pos); - return GLOB_ERROR; + return GLOB_OK; } static GlobCode glob_word(URLGlob *glob, char *pattern, @@ -374,35 +397,36 @@ char *glob_next_url(URLGlob *glob) char *lit; size_t i; size_t j; - int carry; if (!glob->beenhere) glob->beenhere = 1; else { - carry = 1; + bool carry = TRUE; /* implement a counter over the index ranges of all patterns, starting with the rightmost pattern */ for (i = glob->size / 2 - 1; carry && i < glob->size; --i) { - carry = 0; + carry = FALSE; pat = &glob->pattern[i]; switch (pat->type) { case UPTSet: if (++pat->content.Set.ptr_s == pat->content.Set.size) { pat->content.Set.ptr_s = 0; - carry = 1; + carry = TRUE; } break; case UPTCharRange: - if (++pat->content.CharRange.ptr_c > pat->content.CharRange.max_c) { + pat->content.CharRange.ptr_c += pat->content.CharRange.step; + if (pat->content.CharRange.ptr_c > pat->content.CharRange.max_c) { pat->content.CharRange.ptr_c = pat->content.CharRange.min_c; - carry = 1; + carry = TRUE; } break; case UPTNumRange: - if (++pat->content.NumRange.ptr_n > pat->content.NumRange.max_n) { + pat->content.NumRange.ptr_n += pat->content.NumRange.step; + if (pat->content.NumRange.ptr_n > pat->content.NumRange.max_n) { pat->content.NumRange.ptr_n = pat->content.NumRange.min_n; - carry = 1; + carry = TRUE; } break; default: diff --git a/src/urlglob.h b/src/urlglob.h index fdda41eef..d0818407f 100644 --- a/src/urlglob.h +++ b/src/urlglob.h @@ -1,18 +1,18 @@ #ifndef __URLGLOB_H #define __URLGLOB_H /*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://curl.haxx.se/docs/copyright.html. - * + * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is * furnished to do so, under the terms of the COPYING file. @@ -39,11 +39,13 @@ typedef struct { struct { char min_c, max_c; char ptr_c; + int step; } CharRange; struct { int min_n, max_n; short padlength; int ptr_n; + int step; } NumRange ; } content; } URLPattern; @@ -60,7 +62,7 @@ typedef struct { int glob_url(URLGlob**, char*, int *, FILE *); char* glob_next_url(URLGlob*); -char* glob_match_url(char*, URLGlob *); +char* glob_match_url(char*, URLGlob *); void glob_cleanup(URLGlob* glob); #endif |