Index: src/glob.c ================================================================== --- src/glob.c +++ src/glob.c @@ -29,16 +29,17 @@ ** zVal: "x" ** zGlobList: "*.o,*.obj" ** ** Result: "(x GLOB '*.o' OR x GLOB '*.obj')" ** -** Each element of the GLOB list may optionally be enclosed in either '...' -** or "...". This allows commas in the expression. Whitespace at the -** beginning and end of each GLOB pattern is ignored, except when enclosed -** within '...' or "...". +** Commas and whitespace are considered to be element delimters. Each +** element of the GLOB list may optionally be enclosed in either '...' or +** "...". This allows commas and/or whitespace to be used in the elements +** themselves. ** -** This routine makes no effort to free the memory space it uses. +** This routine makes no effort to free the memory space it uses, which +** currently consists of a blob object and its contents. */ char *glob_expr(const char *zVal, const char *zGlobList){ Blob expr; char *zSep = "("; int nTerm = 0; @@ -46,21 +47,24 @@ int cTerm; if( zGlobList==0 || zGlobList[0]==0 ) return "0"; blob_zero(&expr); while( zGlobList[0] ){ - while( fossil_isspace(zGlobList[0]) || zGlobList[0]==',' ) zGlobList++; + while( fossil_isspace(zGlobList[0]) || zGlobList[0]==',' ){ + zGlobList++; /* Skip leading commas, spaces, and newlines */ + } if( zGlobList[0]==0 ) break; if( zGlobList[0]=='\'' || zGlobList[0]=='"' ){ cTerm = zGlobList[0]; zGlobList++; }else{ cTerm = ','; } - for(i=0; zGlobList[i] && zGlobList[i]!=cTerm && zGlobList[i]!='\n'; i++){} - if( cTerm==',' ){ - while( i>0 && fossil_isspace(zGlobList[i-1]) ){ i--; } + /* Find the next delimter (or the end of the string). */ + for(i=0; zGlobList[i] && zGlobList[i]!=cTerm; i++){ + if( cTerm!=',' ) continue; /* If quoted, keep going. */ + if( fossil_isspace(zGlobList[i]) ) break; /* If space, stop. */ } blob_appendf(&expr, "%s%s GLOB '%#q'", zSep, zVal, i, zGlobList); zSep = " OR "; if( cTerm!=',' && zGlobList[i] ) i++; zGlobList += i; @@ -85,24 +89,24 @@ char **azPattern; /* Array of pointers to patterns */ }; #endif /* INTERFACE */ /* -** zPatternList is a comma-separate list of glob patterns. Parse up +** zPatternList is a comma-separated list of glob patterns. Parse up ** that list and use it to create a new Glob object. ** ** Elements of the glob list may be optionally enclosed in single our -** double-quotes. This allows a comma to be part of a glob. +** double-quotes. This allows a comma to be part of a glob pattern. ** ** Leading and trailing spaces on unquoted glob patterns are ignored. ** ** An empty or null pattern list results in a null glob, which will ** match nothing. */ Glob *glob_create(const char *zPatternList){ int nList; /* Size of zPatternList in bytes */ - int i, j; /* Loop counters */ + int i; /* Loop counters */ Glob *p; /* The glob being created */ char *z; /* Copy of the pattern list */ char delimiter; /* '\'' or '\"' or 0 */ if( zPatternList==0 || zPatternList[0]==0 ) return 0; @@ -110,27 +114,26 @@ p = fossil_malloc( sizeof(*p) + nList+1 ); memset(p, 0, sizeof(*p)); z = (char*)&p[1]; memcpy(z, zPatternList, nList+1); while( z[0] ){ - while( z[0]==',' || z[0]==' ' || z[0]=='\n' || z[0]=='\r' ){ - z++; /* Skip leading spaces and newlines */ + while( fossil_isspace(z[0]) || z[0]==',' ){ + z++; /* Skip leading commas, spaces, and newlines */ } + if( z[0]==0 ) break; if( z[0]=='\'' || z[0]=='"' ){ delimiter = z[0]; z++; }else{ delimiter = ','; } - if( z[0]==0 ) break; p->azPattern = fossil_realloc(p->azPattern, (p->nPattern+1)*sizeof(char*) ); p->azPattern[p->nPattern++] = z; - for(i=0; z[i] && z[i]!=delimiter && z[i]!='\n' && z[i]!='\r'; i++){} - if( delimiter==',' ){ - /* Remove trailing spaces / newlines on a comma-delimited pattern */ - for(j=i; j>1 && (z[j-1]==' ' || z[j-1]=='\n' || z[j-1]=='\r'); j--){} - if( jnPattern; i++){ fossil_print("pattern[%d] = [%s]\n", i, pGlob->azPattern[i]); } for(i=3; i