Allow multiple values metadata fields with the same key in one table

fixes https://github.com/liblouis/liblouis/issues/1064
diff --git a/liblouis/metadata.c b/liblouis/metadata.c
index 0af6554..eae80fc 100644
--- a/liblouis/metadata.c
+++ b/liblouis/metadata.c
@@ -199,15 +199,24 @@
 	return strcasecmp(f1->key, f2->key);
 }
 
+
+static int
+cmpFeatures(Feature *f1, Feature *f2) {
+	int r = strcasecmp(f1->key, f2->key);
+	if (r == 0)
+		r = strcasecmp(f1->val, f2->val);
+	return r;
+}
+
 /**
  * Compute the match quotient of the features in a query against the features in a table's
  * metadata.
  *
- * The features are assumed to be sorted and to have no duplicate
- * keys. The query's features must be of type FeatureWithImportance.
- * How a feature contributes to the match quotient depends on its
- * importance, on whether the feature is undefined, defined with the
- * same value (positive match), or defined with a different value
+ * The features are assumed to be sorted. The query's features must be
+ * of type FeatureWithImportance and are assumed to have no duplicate
+ * keys. How a feature contributes to the match quotient depends on
+ * its importance, on whether the feature is undefined, defined with
+ * the same value (positive match), or defined with a different value
  * (negative match), and on the `fuzzy' argument. If the `fuzzy'
  * argument evaluates to true, negative matches and undefined features
  * get a lower penalty.
@@ -241,7 +250,10 @@
 		if (!l1) {
 			if (!l2) break;
 			quotient += extra;
-			l2 = l2->tail;
+			const List *l = l2;
+			l = l->tail;
+			while (l && cmpKeys(l->head, l2->head) == 0) l = l->tail;
+			l2 = l;
 		} else if (!l2) {
 			quotient += undefined;
 			l1 = l1->tail;
@@ -252,15 +264,27 @@
 				l1 = l1->tail;
 			} else if (cmp > 0) {
 				quotient += extra;
-				l2 = l2->tail;
+				const List *l = l2;
+				l = l->tail;
+				while (l && cmpKeys(l->head, l2->head) == 0) l = l->tail;
+				l2 = l;
 			} else {
-				if (strcasecmp(((Feature *)l1->head)->val, ((Feature *)l2->head)->val) ==
-						0)
+				int pos = 0;
+				const List *l = l2;
+				while (1) {
+					if (!pos &&
+							strcasecmp(((Feature *)l1->head)->val,
+									((Feature *)l->head)->val) == 0)
+						pos = 1;
+					l = l->tail;
+					if (!l || cmpKeys(l->head, l2->head) != 0) break;
+				}
+				if (pos)
 					quotient += posMatch;
 				else
 					quotient += negMatch;
 				l1 = l1->tail;
-				l2 = l2->tail;
+				l2 = l;
 			}
 		}
 	}
@@ -497,7 +521,7 @@
 		fclose(info.in);
 	} else
 		_lou_logMessage(LOU_LOG_ERROR, "Cannot open table '%s'", info.fileName);
-	return list_sort(features, (int (*)(void *, void *))cmpKeys);
+	return list_sort(features, (int (*)(void *, void *))cmpFeatures);
 compile_error:
 	if (info.linepos < info.linelen)
 		_lou_logMessage(LOU_LOG_ERROR, "Unexpected character '%c' on line %d, column %d",