aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2005-11-10 22:11:01 +0000
committerDaniel Stenberg <daniel@haxx.se>2005-11-10 22:11:01 +0000
commitbd8baed13879d30614065379cca6e2b559b4b0fa (patch)
tree17d868ef3c0bf6ee0093e185b26a42f4c5524856 /src
parent00a7dda273af92f0e58d2d7f0f6e56209919de18 (diff)
Introducing range stepping to the curl globbing support. Now you can specify
step counter by adding :[num] within the brackets when specifying a range.
Diffstat (limited to 'src')
-rw-r--r--src/urlglob.c118
-rw-r--r--src/urlglob.h16
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