7 struct matching_counter {
11 static struct matching_counter *matching_counter_new(void)
13 return g_slice_new0(struct matching_counter);
16 static void matching_counter_free(struct matching_counter *counter)
18 g_slice_free(struct matching_counter,counter);
21 static gint compar_unichars(gconstpointer a,gconstpointer b,gpointer unused)
24 * Unicode code points only go up to 0x10FFFF and thus this cannot overflow.
26 return GPOINTER_TO_INT(a)-GPOINTER_TO_INT(b);
30 * For matching characters, we maintain a count of the opens and closes.
31 * In the simplest case, we are dealing with a matching pair such as [ and ]
32 * where there is a 1:1 mapping between an instance of [ with an open and
33 * between an instance of ] with a close. matching_ket() is
34 * responsible for selecting an arbitary base character of a matching pair.
36 static gpointer matching_key(gunichar ch)
39 if (g_unichar_get_mirror_char(ch,&mirrored))
41 return GINT_TO_POINTER((gint)ch);
43 return GINT_TO_POINTER((gint)mirrored);
44 else if (ch==CHAR_SQUOTE || ch==CHAR_OPEN_SQUOTE)
45 return GINT_TO_POINTER((gint)CHAR_SQUOTE);
46 else if (ch==CHAR_LS_QUOTE || ch==CHAR_RS_QUOTE)
47 return GINT_TO_POINTER((gint)CHAR_LS_QUOTE);
48 else if (ch<0x4000 || ch-0x4000>=NO_SPECIAL_COUNTERS)
50 g_warning("Matching pair not found for U+%04" G_GINT32_MODIFIER "X",ch);
51 return GINT_TO_POINTER((gint)ch);
55 void increment_matching(struct counters *counters,gunichar ch,gboolean open)
57 gpointer key,orig_key;
58 struct matching_counter *value;
59 if (!counters->matching)
60 counters->matching=g_tree_new_full(compar_unichars,NULL,NULL,
61 (GDestroyNotify)matching_counter_free);
63 if (!g_tree_lookup_extended(counters->matching,key,&orig_key,
66 value=matching_counter_new();
67 g_tree_insert(counters->matching,key,value);
75 int matching_count(const struct counters *counters,gunichar ch,gboolean open)
77 struct matching_counter *value;
78 if (!counters->matching)
80 value=g_tree_lookup(counters->matching,matching_key(ch));
83 return open?value->open:value->close;
87 * Return open count - closed count
89 int matching_difference(const struct counters *counters,gunichar ch)
91 struct matching_counter *value;
92 if (!counters->matching)
94 value=g_tree_lookup(counters->matching,matching_key(ch));
97 return value->open-value->close;
100 void counters_reset(struct counters *counters)
102 if (counters->matching)
103 g_tree_destroy(counters->matching);
104 memset(counters,0,sizeof(*counters));
107 void counters_destroy(struct counters *counters)
109 if (counters->matching)
111 g_tree_destroy(counters->matching);
112 counters->matching=NULL;