Fix bug #6: BL treats a slanted apostrophe ? as a word separator, not as a contraction or possessive
6 struct matching_counter {
10 static struct matching_counter *matching_counter_new(void)
12 return g_slice_new0(struct matching_counter);
15 static void matching_counter_free(struct matching_counter *counter)
17 g_slice_free(struct matching_counter,counter);
20 static gint compar_unichars(gconstpointer a,gconstpointer b,gpointer unused)
23 * Unicode code points only go up to 0x10FFFF and thus this cannot overflow.
25 return GPOINTER_TO_INT(a)-GPOINTER_TO_INT(b);
29 * For matching characters, we maintain a count of the opens and closes.
30 * In the simplest case, we are dealing with a matching pair such as [ and ]
31 * where there is a 1:1 mapping between an instance of [ with an open and
32 * between an instance of ] with a close. matching_ket() is
33 * responsible for selecting an arbitary base character of a matching pair.
35 static gpointer matching_key(gunichar ch)
38 if (g_unichar_get_mirror_char(ch,&mirrored))
40 return GINT_TO_POINTER((gint)ch);
42 return GINT_TO_POINTER((gint)mirrored);
43 else if (ch==CHAR_SQUOTE || ch==CHAR_OPEN_SQUOTE)
44 return GINT_TO_POINTER((gint)CHAR_SQUOTE);
45 else if (ch==CHAR_LS_QUOTE || ch==CHAR_RS_QUOTE)
46 return GINT_TO_POINTER((gint)CHAR_LS_QUOTE);
49 g_warning("Matching pair not found for U+%04"G_GINT32_FORMAT"X",ch);
50 return GINT_TO_POINTER((gint)ch);
54 void increment_matching(struct counters *counters,gunichar ch,gboolean open)
56 gpointer key,orig_key;
57 struct matching_counter *value;
58 if (!counters->matching)
59 counters->matching=g_tree_new_full(compar_unichars,NULL,NULL,
60 (GDestroyNotify)matching_counter_free);
62 if (!g_tree_lookup_extended(counters->matching,key,&orig_key,
65 value=matching_counter_new();
66 g_tree_insert(counters->matching,key,value);
74 int matching_count(const struct counters *counters,gunichar ch,gboolean open)
76 struct matching_counter *value;
77 if (!counters->matching)
79 value=g_tree_lookup(counters->matching,matching_key(ch));
82 return open?value->open:value->close;
86 * Return open count - closed count
88 int matching_difference(const struct counters *counters,gunichar ch)
90 struct matching_counter *value;
91 if (!counters->matching)
93 value=g_tree_lookup(counters->matching,matching_key(ch));
96 return value->open-value->close;
99 void counters_destroy(struct counters *counters)
101 if (counters->matching)
103 g_tree_destroy(counters->matching);
104 counters->matching=NULL;