Added matching
This commit is contained in:
parent
a91d57c0df
commit
22908f34cb
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Reference in New Issue