On Wednesday 19 August 2009, Alexander Larsson wrote:
> On Wed, 2009-08-19 at 10:02 +0200, David Faure wrote:
> > On Wednesday 19 August 2009, Alexander Larsson wrote:
> > > Ugh. Additionally we have to extend the mime.cache format more. Maybe
> > > we can solve this with a hack. What about this:
> > >
> > > All case insensitive globs are converted to lower case in the globs
> > > file. Glob lookup is done by first matching the real filename against
> > > the globs, then (on failure) convert the name to lower case and try
> > > again. This will result in a case insensitive match except for things
> > > marked as case sensitive that has at least one uppercase character.
> > >
> > > We can't do case-sensitive matching of only-lowercase globs, but we
> > > don't currently have any example of this in the databases.
> >
> > But I do want to do one of those, to solve bug 22634: I want
> >    <glob pattern="core"/> to be case-sensitive="true".
> >
> > How about a different hack:
> > we generate in globs2 two lines, in case of case-sensitive:
> > 50:text/x-c++src:*.C
> > 50:text/x-c++src:*.C:cs
> > Old parsers will create an entry for "*.C:cs", which will probably never
> > match any real file, so no big deal, while new parsers will take the
> > second line as an indication that the *.C glob (parsed one line above)
> > should be understood to be case sensitive.
>
> Hmmm. I like this one. Sounds good to me. But lets make it extensible
> when we're doing it, i.e. have  a comma-separated list of flags with
> "cs" being one known one. Unknown flags are ignored, anything after
> another : is ignored.

Good idea.
I made the changes in the spec, in the definition of the two mimetypes,
and in update-mime-database.c (for parsing, and globs2 generation).
Please find patch attached (I can commit if you're ok with it).

I included a suggested format change for the mimeinfo.cache file, but I'll
have to let you implement that part, I don't know all the details about the 
suffix tree etc. Same for the xdgmime implementation.

I like that this is going to improve performance, too: no need to do the two-
step glob matching anymore (case insensitive + case sensitive), it will now be 
one -or- the other, for a given glob.

-- 
David Faure, [email protected], sponsored by Qt Software @ Nokia to work on KDE,
Konqueror (http://www.konqueror.org), and KOffice (http://www.koffice.org).
Index: ChangeLog
===================================================================
RCS file: /cvs/mime/shared-mime-info/ChangeLog,v
retrieving revision 1.551
diff -u -p -r1.551 ChangeLog
--- ChangeLog	31 Jul 2009 15:15:36 -0000	1.551
+++ ChangeLog	19 Aug 2009 19:51:40 -0000
@@ -1,3 +1,16 @@
+2009-08-19  David Faure  <[email protected]>
+
+	* shared-mime-info-spec.xml: Define new case-sensitive attribute, and
+	change the text from the two-step glob match to a single glob match,
+	that is either case sensitive or case insensitive. Add flags field to
+	globs2 file, define the "cs" flag.
+
+	* freedesktop.org.xml.in: Add case-sensitive="true" to the globs *.C,
+	and core (Closes: #22634)
+		
+	* update-mime-database.c (process_freedesktop_node)
+	(write_out_glob2): Process case-sensitive flag, write it out in globs2.
+
 2009-07-31  Bastien Nocera  <[email protected]>
 
 	* tests/list: Fix test suite for those pesky PS files
Index: freedesktop.org.xml.in
===================================================================
RCS file: /cvs/mime/shared-mime-info/freedesktop.org.xml.in,v
retrieving revision 1.416
diff -u -p -r1.416 freedesktop.org.xml.in
--- freedesktop.org.xml.in	31 Jul 2009 15:13:45 -0000	1.416
+++ freedesktop.org.xml.in	19 Aug 2009 19:51:40 -0000
@@ -26,6 +26,7 @@
   <!ELEMENT glob EMPTY>
   <!ATTLIST glob pattern CDATA #REQUIRED>
   <!ATTLIST glob weight CDATA #IMPLIED>
+  <!ATTLIST glob case-sensitive CDATA #IMPLIED>
 
   <!ELEMENT magic (match)+>
   <!ATTLIST magic priority CDATA #IMPLIED>
@@ -1268,7 +1269,7 @@ command to generate the output files.
       <match type="string" value="Core\001" offset="0"/>
       <match type="string" value="Core\002" offset="0"/>
     </magic>
-    <glob pattern="core"/>
+    <glob pattern="core" case-sensitive="true"/>
   </mime-type>
   <mime-type type="application/x-cpio">
     <_comment>CPIO archive</_comment>
@@ -4292,7 +4293,7 @@ command to generate the output files.
     <glob pattern="*.cpp"/>
     <glob pattern="*.cxx"/>
     <glob pattern="*.cc"/>
-    <glob pattern="*.C"/>
+    <glob pattern="*.C" case-sensitive="true"/>
     <glob pattern="*.c++"/>
   </mime-type>
   <mime-type type="text/x-changelog">
Index: shared-mime-info-spec.xml
===================================================================
RCS file: /cvs/mime/shared-mime-info/shared-mime-info-spec.xml,v
retrieving revision 1.67
diff -u -p -r1.67 shared-mime-info-spec.xml
--- shared-mime-info-spec.xml	5 Aug 2009 13:08:17 -0000	1.67
+++ shared-mime-info-spec.xml	19 Aug 2009 19:51:40 -0000
@@ -456,6 +456,7 @@ For example:
 ...
 55:text/x-diff:*.patch
 50:text/x-diff:*.diff
+50:text/x-c++src:*.C:cs
 ...
 ]]></programlisting>
 		</para>
@@ -474,8 +475,8 @@ text/x-diff:*.diff
 ]]></programlisting>
 		</para>
 		<para>
-Applications MUST first try a case-sensitive match, then try again with the
-filename converted to lower-case if that fails.
+Applications MUST match globs case-insensitively, except when the case-sensitive
+attribute is set to true.
 This is so that <filename>main.C</filename> will be seen as a C++ file,
 but <filename>IMAGE.GIF</filename> will still use the *.gif pattern.
 		</para>
@@ -531,6 +532,16 @@ Group's package, which MUST be required 
 specification. Since each application will then only be providing information
 about its own types, conflicts should be rare.
 		</para>
+		<para>
+The fourth field ("cs" in the first globs2 example) contains a list of comma-separated flags.
+The flags currently defined are: cs (for case-sensitive). Implementations should ignore
+unknown flags.
+		</para>
+		<para>
+Implementations should also ignore further fields, so that the syntax of the globs2 file
+can be extended in the future. Example: "50:text/x-c++src:*.C:cs,newflag:newfeature:somethingelse"
+should currently be parsed as "50:text/x-c++src:*.C:cs".
+		</para>
 	</sect2>
 	<sect2>
 		<title>The magic files</title>
@@ -717,21 +728,23 @@ Parents:
 
 LiteralList:
 4			CARD32		N_LITERALS
-12*N_LITERALS		LiteralEntry	
+16*N_LITERALS		LiteralEntry	
 
 LiteralEntry:
 4			CARD32		LITERAL_OFFSET
 4			CARD32		MIME_TYPE_OFFSET
 4			CARD32		WEIGHT
+4			CARD32		FLAGS (0x1: case-sensitive)
 
 GlobList:
 4			CARD32		N_GLOBS
-12*N_GLOBS		GlobEntry	
+16*N_GLOBS		GlobEntry	
 
 GlobEntry:
 4			CARD32		GLOB_OFFSET
 4			CARD32		MIME_TYPE_OFFSET
 4			CARD32		WEIGHT
+4			CARD32		FLAGS (0x1: case-sensitive)
 
 ReverseSuffixTree:
 4			CARD32		N_ROOTS
Index: update-mime-database.c
===================================================================
RCS file: /cvs/mime/shared-mime-info/update-mime-database.c,v
retrieving revision 1.51
diff -u -p -r1.51 update-mime-database.c
--- update-mime-database.c	20 Apr 2009 16:45:43 -0000	1.51
+++ update-mime-database.c	19 Aug 2009 19:51:40 -0000
@@ -94,6 +94,7 @@ struct _Glob {
 	char *pattern;
 	Type *type;
 	gboolean noglob;
+	gboolean case_sensitive;
 };
 
 struct _Magic {
@@ -307,6 +308,24 @@ static int get_weight(xmlNode *node)
        return get_int_attribute (node, "weight");
 }
 
+/* Return the value of a false/true attribute, which defaults to false.
+ * Returns 0 or 1.
+ */
+static gboolean get_boolean_attribute(xmlNode *node, const char* name)
+{
+	char *attr;
+	attr = my_xmlGetNsProp(node, name, NULL);
+	if (attr)
+	{
+	    if (strcmp (attr, "true") == 0) 
+	    {
+		return TRUE;
+	    }
+	    xmlFree(attr);
+	}
+	return FALSE;
+}
+
 /* Process a <root-XML> element by adding a rule to namespace_hash */
 static void add_namespace(Type *type, const char *namespaceURI,
 			  const char *localName, GError **error)
@@ -363,8 +382,10 @@ static gboolean process_freedesktop_node
 	{
 		gchar *pattern;	
 		gint weight;
+		gboolean case_sensitive;
 
 		weight = get_weight(field);
+		case_sensitive = get_boolean_attribute(field, "case-sensitive");
 
 		if (weight == -1)
 		{
@@ -382,6 +403,7 @@ static gboolean process_freedesktop_node
 			glob->pattern = g_strdup (pattern);
 			glob->type = type;
 			glob->weight = weight;
+			glob->case_sensitive = case_sensitive;
 			list = g_list_append (list, glob);
 			g_hash_table_insert(globs_hash, g_strdup (glob->pattern), list);
 			xmlFree(pattern);
@@ -406,6 +428,7 @@ static gboolean process_freedesktop_node
 		glob->type = type;
 		glob->weight = 0;
 		glob->noglob = TRUE;
+		glob->case_sensitive = FALSE;
 		list = g_list_append (list, glob);
 		g_hash_table_insert(globs_hash, g_strdup (glob->pattern), list);
 		copy_to_xml = TRUE;
@@ -847,6 +870,7 @@ static void write_out_glob2(GList *globs
 	GList *list;
 	Glob *glob;
 	Type *type;
+	gboolean need_flags;
 
 	for (list = globs ; list; list = list->next) {
 		glob = (Glob *)list->data;
@@ -855,9 +879,22 @@ static void write_out_glob2(GList *globs
 			g_warning("* Glob patterns can't contain literal newlines "
 				  "(%s in type %s/%s)\n", glob->pattern,
 				  type->media, type->subtype);
-		else
+		else 
+		{
+			/* Always write the line without the flags, for older parsers */
 			g_fprintf(stream, "%d:%s/%s:%s\n",
-				  glob->weight, type->media, type->subtype, glob->pattern);
+					  glob->weight, type->media, type->subtype, glob->pattern);
+		    
+			need_flags = FALSE;
+			if (glob->case_sensitive)
+				need_flags = TRUE;
+
+			if (need_flags) {
+				g_fprintf(stream, "%d:%s/%s:%s%s\n",
+						  glob->weight, type->media, type->subtype, glob->pattern,
+						  glob->case_sensitive ? ":cs" : "");
+			}
+		}
 	}
 }
 
_______________________________________________
xdg mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/xdg

Reply via email to