Added matching

This commit is contained in:
Jesse van den Kieboom 2006-01-02 17:56:45 +00:00
parent a91d57c0df
commit 22908f34cb
2 changed files with 212 additions and 38 deletions

View File

@ -199,6 +199,169 @@ gm_trigger_set_actions(GmTrigger *trigger, GList *actions) {
trigger->actions = actions;
}
gboolean
gm_trigger_match_user(GmTrigger *trigger, gchar const *username,
GmTriggerConditionType condition, regmatch_t *matches, gint nmatch) {
GmTriggerData *data;
GList *item;
gint cmatch = 0, offset, ret;
if (!trigger->conditions) {
return FALSE;
}
for (item = trigger->conditions; item; item = item->next) {
data = (GmTriggerData *)(item->data);
if (cmatch >= nmatch) {
return FALSE;
}
if (data->type == condition) {
offset = 0;
ret = regexec(&(data->expr), (char *)(username),
(nmatch - cmatch) - 1, matches + cmatch, 0);
if (ret == 0) {
while (matches[cmatch].rm_so != -1) {
matches[cmatch].rm_eo = matches[cmatch].rm_eo -
matches[cmatch].rm_so;
matches[cmatch].rm_so = matches[cmatch].rm_so + offset;
cmatch++;
}
} else {
return FALSE;
}
} else {
return FALSE;
}
}
return TRUE;
}
gboolean
gm_trigger_match(GmTrigger *trigger, gchar *text, regmatch_t *matches,
gint nmatch) {
GmTriggerData *data;
GList *item;
gchar *tmp;
gboolean istrue;
gint cmatch = 0, ret, offset, len;
if (!trigger->conditions) {
return FALSE;
}
for (item = trigger->conditions; item; item = item->next) {
data = (GmTriggerData *)(item->data);
len = g_utf8_strlen(data->data, -1);
if (cmatch >= nmatch) {
return FALSE;
}
switch (data->type) {
case TCT_CONTAINS: case TCT_NOT_CONTAINS: case TCT_BEGINS:
case TCT_NOT_BEGINS: case TCT_ENDS: case TCT_NOT_ENDS:
tmp = strstr(text, data->data);
switch (data->type) {
case TCT_CONTAINS:
if (tmp != NULL) {
while (tmp != NULL && cmatch < nmatch) {
matches[cmatch].rm_so =
g_utf8_pointer_to_offset(text, tmp);
matches[cmatch].rm_eo = len;
tmp = strstr(tmp + len, data->data);
if (tmp != NULL) {
++cmatch;
}
}
} else {
return FALSE;
}
break;
case TCT_NOT_CONTAINS:
if (tmp == NULL) {
matches[cmatch].rm_so = 0;
matches[cmatch].rm_eo = len;
} else {
return FALSE;
}
break;
case TCT_NOT_BEGINS:
if (tmp != text) {
matches[cmatch].rm_so = 0;
matches[cmatch].rm_eo = g_utf8_strlen(text, -1);
} else {
return FALSE;
}
break;
default:
istrue = (tmp != NULL &&
(g_utf8_pointer_to_offset(text, tmp) + len) ==
g_utf8_strlen(text, -1));
if (istrue && data->type == TCT_ENDS) {
matches[cmatch].rm_so =
g_utf8_pointer_to_offset(text, tmp);
matches[cmatch].rm_eo = len;
} else if (!istrue && data->type == TCT_NOT_ENDS) {
matches[cmatch].rm_so = 0;
matches[cmatch].rm_eo = g_utf8_strlen(text, -1);
} else {
return FALSE;
}
}
cmatch++;
matches[cmatch].rm_so = -1;
break;
case TCT_MATCHES: case TCT_NOT_MATCHES:
offset = 0;
ret = regexec(&(data->expr), (char *)text,
(nmatch - cmatch) - 1, matches + cmatch, 0);
if (ret == 0 && data->type == TCT_MATCHES) {
while (ret == 0) {
while (matches[cmatch].rm_so != -1) {
matches[cmatch].rm_eo = matches[cmatch].rm_eo -
matches[cmatch].rm_so;
matches[cmatch].rm_so = matches[cmatch].rm_so +
offset;
++cmatch;
}
offset = matches[cmatch - 1].rm_so +
matches[cmatch - 1].rm_eo;
if (cmatch < nmatch) {
ret = regexec(&(data->expr),
(char *)(text + offset),
(nmatch - cmatch) - 1,
matches + cmatch,
0);
} else {
ret = 1;
}
}
} else if (ret != 0 && data->type == TCT_NOT_MATCHES) {
matches[cmatch].rm_so = 0;
matches[cmatch].rm_eo = g_utf8_strlen(text, -1);
} else {
return FALSE;
}
break;
default:
return FALSE;
break;
}
}
return TRUE;
}
gint
gm_trigger_type_from_name(const gchar *name,
const trigger_trans *trans_table) {

View File

@ -10,13 +10,19 @@ G_BEGIN_DECLS
/*
* Type checking and casting macros
*/
#define GM_TYPE_TRIGGERS (gm_triggers_get_type())
#define GM_TRIGGERS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GM_TYPE_TRIGGERS, GmTriggers))
#define GM_TRIGGERS_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GM_TYPE_TRIGGERS, GmTriggers const))
#define GM_TRIGGERS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GM_TYPE_TRIGGERS, GmTriggersClass))
#define GM_IS_TRIGGERS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GM_TYPE_TRIGGERS))
#define GM_IS_TRIGGERS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GM_TYPE_TRIGGERS))
#define GM_TRIGGERS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GM_TYPE_TRIGGERS, GmTriggersClass))
#define GM_TYPE_TRIGGERS (gm_triggers_get_type())
#define GM_TRIGGERS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
GM_TYPE_TRIGGERS, GmTriggers))
#define GM_TRIGGERS_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
GM_TYPE_TRIGGERS, GmTriggers const))
#define GM_TRIGGERS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
GM_TYPE_TRIGGERS, GmTriggersClass))
#define GM_IS_TRIGGERS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
GM_TYPE_TRIGGERS))
#define GM_IS_TRIGGERS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
GM_TYPE_TRIGGERS))
#define GM_TRIGGERS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
GM_TYPE_TRIGGERS, GmTriggersClass))
/* Private structure type */
typedef struct _GmTriggersPrivate GmTriggersPrivate;
@ -45,49 +51,49 @@ struct _GmTriggersClass {
};
typedef enum _GmTriggerType {
TT_OUTPUT = 0,
TT_USERS
TT_OUTPUT = 0,
TT_USERS
} GmTriggerType;
typedef enum _GmTriggerConditionType {
TCT_CONTAINS = 0,
TCT_NOT_CONTAINS,
TCT_BEGINS,
TCT_NOT_BEGINS,
TCT_ENDS,
TCT_NOT_ENDS,
TCT_MATCHES,
TCT_NOT_MATCHES,
TCT_USER_ONLINE,
TCT_USER_OFFLINE,
TCT_USER_IDLE,
TCT_USER_IDLE_OFF,
TCT_USER_AWAY,
TCT_USER_AWAY_OFF
TCT_CONTAINS = 0,
TCT_NOT_CONTAINS,
TCT_BEGINS,
TCT_NOT_BEGINS,
TCT_ENDS,
TCT_NOT_ENDS,
TCT_MATCHES,
TCT_NOT_MATCHES,
TCT_USER_ONLINE,
TCT_USER_OFFLINE,
TCT_USER_IDLE,
TCT_USER_IDLE_OFF,
TCT_USER_AWAY,
TCT_USER_AWAY_OFF
} GmTriggerConditionType;
typedef enum _GmTriggerActionType {
TAT_HIGHLIGHT_LINE = 0,
TAT_HIGHLIGHT_MATCH,
TAT_BEEP,
TAT_PLAY_SOUND,
TAT_NOTIFY,
TAT_RUN_SCRIPT,
TAT_RUN
TAT_HIGHLIGHT_LINE = 0,
TAT_HIGHLIGHT_MATCH,
TAT_BEEP,
TAT_PLAY_SOUND,
TAT_NOTIFY,
TAT_RUN_SCRIPT,
TAT_RUN
} GmTriggerActionType;
typedef struct _GmTriggerData {
gint type;
gchar *data;
regex_t expr;
guint type;
gchar *data;
regex_t expr;
} GmTriggerData;
typedef struct _GmTrigger {
gchar *name;
GmTriggerType event;
GList *conditions;
GList *actions;
gchar *name;
GmTriggerType event;
GList *conditions;
GList *actions;
} GmTrigger;
GType gm_triggers_get_type(void) G_GNUC_CONST;
@ -111,6 +117,11 @@ void gm_trigger_add_action(GmTrigger *trigger, GmTriggerData *action);
void gm_trigger_set_conditions(GmTrigger *trigger, GList *conditions);
void gm_trigger_set_actions(GmTrigger *trigger, GList *actions);
gboolean gm_trigger_match_user(GmTrigger *trigger, gchar const *username,
GmTriggerConditionType condition, regmatch_t *matches, gint nmatch);
gboolean gm_trigger_match(GmTrigger *trigger, gchar *text, regmatch_t *matches,
gint nmatch);
GmTriggerData *gm_trigger_data_new(gint type, gchar *data);
void gm_trigger_data_free(GmTriggerData *tdata);