Richard,
I would kindly ask you to consider this patch for inclusion into
fossil trunk. It allows for characters like *?[] to be used in
filenames. It also adds escaped characters to glob patterns. More
specifically the patch does the following:
(1) Adds configuration setting "filename-xchars" (versionable) that if
enabled allows for characters *?[]\ to be used in filenames. When
disabled the behavior is the same as now.
(2) Glob patterns now recognize escaped characters '\?', '\[', '\*',
'\\' that represent literal chars '?', '[', '*', '\' respectively.
I hope the patch can help all those folks who voiced their support for
this feature in the recent thread
http://lists.fossil-scm.org:8080/pipermail/fossil-users/2012-March/008487.html
Thanks,
--Leo--
Index: src/configure.c
==================================================================
--- src/configure.c
+++ src/configure.c
@@ -85,10 +85,11 @@
{ "manifest", CONFIGSET_PROJ },
{ "ignore-glob", CONFIGSET_PROJ },
{ "crnl-glob", CONFIGSET_PROJ },
{ "empty-dirs", CONFIGSET_PROJ },
{ "allow-symlinks", CONFIGSET_PROJ },
+ { "filename-xchars", CONFIGSET_PROJ },
{ "index-page", CONFIGSET_SKIN },
#ifdef FOSSIL_ENABLE_TCL
{ "tcl", CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },
#endif
{ "timeline-block-markup", CONFIGSET_SKIN },
Index: src/db.c
==================================================================
--- src/db.c
+++ src/db.c
@@ -933,10 +933,13 @@
db_open_or_attach(zDbName, "repository");
g.repositoryOpen = 1;
g.zRepositoryName = mprintf("%s", zDbName);
/* Cache "allow-symlinks" option, because we'll need it on every stat call */
g.allowSymlinks = db_get_boolean("allow-symlinks", 0);
+ /* Cache "filename-xchars" option, because we'll need it on every
+ * file_is_simple_pathname(...) call */
+ g.filenameXchars= db_get_boolean("filename-xchars", 0);
}
/*
** Flags for the db_find_and_open_repository() function.
*/
@@ -1850,10 +1853,11 @@
{ "crnl-glob", 0, 16, 1, "" },
{ "default-perms", 0, 16, 0, "u" },
{ "diff-command", 0, 16, 0, "" },
{ "dont-push", 0, 0, 0, "off" },
{ "editor", 0, 16, 0, "" },
+ { "filename-xchars",0, 0, 1, "off" },
{ "gdiff-command", 0, 16, 0, "gdiff" },
{ "gmerge-command",0, 40, 0, "" },
{ "https-login", 0, 0, 0, "off" },
{ "ignore-glob", 0, 40, 1, "" },
{ "empty-dirs", 0, 40, 1, "" },
@@ -1947,10 +1951,16 @@
** (versionable) update and checkout commands, if no file or directory
** exists with that name, an empty directory will be
** created.
**
** editor Text editor command used for check-in comments.
+**
+** filename-xchars Allow eXtra characters '*', '?', '[' in filenames.
+** (versionable) In glob patterns they have special meaning.
+** In globs escaped chars '\\*', '\\?', '\\[', '\\\\'
+** represent literal '*', '?', '[', '\\' .
+** Default: off
**
** gdiff-command External command to run when performing a graphical
** diff. If undefined, text diff will be used.
**
** gmerge-command A graphical merge conflict resolver command operating
Index: src/file.c
==================================================================
--- src/file.c
+++ src/file.c
@@ -434,11 +434,12 @@
if( c=='.' ){
if( z[1]=='/' || z[1]==0 ) return 0;
if( z[1]=='.' && (z[2]=='/' || z[2]==0) ) return 0;
}
for(i=0; (c=z[i])!=0; i++){
- if( c=='\\' || c=='*' || c=='[' || c==']' || c=='?' ){
+ if( g.filenameXchars==0 &&
+ (c=='\\' || c=='*' || c=='[' || c==']' || c=='?') ){
return 0;
}
if( c=='/' ){
if( z[i+1]=='/' ) return 0;
if( z[i+1]=='.' ){
Index: src/glob.c
==================================================================
--- src/glob.c
+++ src/glob.c
@@ -139,18 +139,20 @@
** Return non-zero if string z matches glob pattern zGlob and zero if the
** pattern does not match.
**
** Globbing rules:
**
-** '*' Matches any sequence of zero or more characters.
+** '*' Matches any sequence of zero or more characters.
+**
+** '?' Matches exactly one character.
**
-** '?' Matches exactly one character.
+** [...] Matches one character from the enclosed list of
+** characters.
**
-** [...] Matches one character from the enclosed list of
-** characters.
+** [^...] Matches one character not in the enclosed list.
**
-** [^...] Matches one character not in the enclosed list.
+** \[ \* \? \\ Match literal [ * ? \ chars, (escape rules)
*/
int strglob(const char *zGlob, const char *z){
int c, c2;
int invert;
int seen;
@@ -165,10 +167,12 @@
}else if( c=='[' ){
while( *z && strglob(zGlob-1,z)==0 ){
z++;
}
return (*z)!=0;
+ }else if( c=='\\' ){
+ c= *(zGlob++);
}
while( (c2 = (*(z++)))!=0 ){
while( c2!=c ){
c2 = *(z++);
if( c2==0 ) return 0;
@@ -205,10 +209,13 @@
prior_c = c2;
}
c2 = *(zGlob++);
}
if( c2==0 || (seen ^ invert)==0 ) return 0;
+ }else if( c=='\\' ){
+ c= *(zGlob++);
+ if( c!=(*(z++)) ) return 0;
}else{
if( c!=(*(z++)) ) return 0;
}
}
return *z==0;
Index: src/json_config.c
==================================================================
--- src/json_config.c
+++ src/json_config.c
@@ -67,10 +67,11 @@
{ "manifest", CONFIGSET_PROJ },
{ "ignore-glob", CONFIGSET_PROJ },
{ "crnl-glob", CONFIGSET_PROJ },
{ "empty-dirs", CONFIGSET_PROJ },
{ "allow-symlinks", CONFIGSET_PROJ },
+{ "filename-xchars", CONFIGSET_PROJ },
{ "ticket-table", CONFIGSET_TKT },
{ "ticket-common", CONFIGSET_TKT },
{ "ticket-change", CONFIGSET_TKT },
{ "ticket-newpage", CONFIGSET_TKT },
Index: src/main.c
==================================================================
--- src/main.c
+++ src/main.c
@@ -192,10 +192,11 @@
const char *azAuxVal[MX_AUX]; /* Value of each aux() or option() value */
const char **azAuxOpt[MX_AUX]; /* Options of each option() value */
int anAuxCols[MX_AUX]; /* Number of columns for option() values */
int allowSymlinks; /* Cached "allow-symlinks" option */
+ int filenameXchars; /* Cached "filename-xchars" option */
#ifdef FOSSIL_ENABLE_JSON
struct FossilJsonBits {
int isJsonMode; /* True if running in JSON mode, else
false. This changes how errors are
_______________________________________________
fossil-users mailing list
[email protected]
http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users