| |
1 #define GAIM_PLUGINS |
| |
2 #include "gaim.h" |
| |
3 |
| |
4 #include <string.h> |
| |
5 #include <ctype.h> |
| |
6 #include <stdlib.h> |
| |
7 |
| |
8 struct replace_words { |
| |
9 char *bad; |
| |
10 char *good; |
| |
11 }; |
| |
12 |
| |
13 GList *words = NULL; |
| |
14 |
| |
15 int num_words(char *); |
| |
16 int get_word(char *, int); |
| |
17 char *have_word(char *, int); |
| |
18 void substitute(char **, int, int, char *); |
| |
19 |
| |
20 void spell_check(char *who, char **message, void *m) { |
| |
21 int i, l; |
| |
22 int word; |
| |
23 GList *w; |
| |
24 char *tmp; |
| |
25 |
| |
26 if (message == NULL || *message == NULL) |
| |
27 return; |
| |
28 |
| |
29 l = num_words(*message); |
| |
30 for (i = 0; i < l; i++) { |
| |
31 word = get_word(*message, i); |
| |
32 w = words; |
| |
33 while (w) { |
| |
34 struct replace_words *r; |
| |
35 r = (struct replace_words *)(w->data); |
| |
36 tmp = have_word(*message, word); |
| |
37 if (!strcmp(have_word(*message, word), r->bad)) |
| |
38 substitute(message, word, strlen(r->bad), |
| |
39 r->good); |
| |
40 free(tmp); |
| |
41 w = w->next; |
| |
42 } |
| |
43 } |
| |
44 } |
| |
45 |
| |
46 void gaim_plugin_init(void *handle) { |
| |
47 struct replace_words *p; |
| |
48 |
| |
49 p = malloc(sizeof *p); |
| |
50 p->bad = "definately"; |
| |
51 p->good = "definitely"; |
| |
52 words = g_list_append(words, p); |
| |
53 |
| |
54 p = malloc(sizeof *p); |
| |
55 p->bad = "u"; |
| |
56 p->good = "you"; |
| |
57 words = g_list_append(words, p); |
| |
58 |
| |
59 p = malloc(sizeof *p); |
| |
60 p->bad = "r"; |
| |
61 p->good = "are"; |
| |
62 words = g_list_append(words, p); |
| |
63 |
| |
64 p = malloc(sizeof *p); |
| |
65 p->bad = "teh"; |
| |
66 p->good = "the"; |
| |
67 words = g_list_append(words, p); |
| |
68 |
| |
69 gaim_signal_connect(handle, event_im_send, spell_check, NULL); |
| |
70 } |
| |
71 |
| |
72 char *name() { |
| |
73 return "IM Spell Check"; |
| |
74 } |
| |
75 |
| |
76 char *description() { |
| |
77 return "Watches outgoing IM text and corrects common spelling errors."; |
| |
78 } |
| |
79 |
| |
80 int num_words(char *m) { |
| |
81 int count = 0; |
| |
82 int pos; |
| |
83 int state = 0; |
| |
84 |
| |
85 for (pos = 0; pos < strlen(m); pos++) { |
| |
86 switch (state) { |
| |
87 case 0: /* expecting word */ |
| |
88 if (isalnum(m[pos])) { |
| |
89 count++; |
| |
90 state = 1; |
| |
91 } else if (m[pos] == '<') |
| |
92 state = 2; |
| |
93 break; |
| |
94 case 1: /* inside word */ |
| |
95 if (isspace(m[pos])) |
| |
96 state = 0; |
| |
97 break; |
| |
98 case 2: /* inside HTML tag */ |
| |
99 if (m[pos] == '>') |
| |
100 state = 0; |
| |
101 break; |
| |
102 } |
| |
103 } |
| |
104 return count; |
| |
105 } |
| |
106 |
| |
107 int get_word(char *m, int word) { |
| |
108 int count = 0; |
| |
109 int pos = 0; |
| |
110 int state = 0; |
| |
111 |
| |
112 for (pos = 0; pos < strlen(m) && count <= word; pos++) { |
| |
113 switch (state) { |
| |
114 case 0: |
| |
115 if (isalnum(m[pos])) { |
| |
116 count++; |
| |
117 state = 1; |
| |
118 } else if (m[pos] == '<') |
| |
119 state = 2; |
| |
120 break; |
| |
121 case 1: |
| |
122 if (isspace(m[pos])) |
| |
123 state = 0; |
| |
124 break; |
| |
125 case 2: |
| |
126 if (m[pos] == '>') |
| |
127 state = 0; |
| |
128 break; |
| |
129 } |
| |
130 } |
| |
131 return pos - 1; |
| |
132 } |
| |
133 |
| |
134 char *have_word(char *m, int pos) { |
| |
135 char *tmp = strpbrk(&m[pos], "' \t\f\r\n"); |
| |
136 int len = (int)(tmp - &m[pos]); |
| |
137 |
| |
138 if (tmp == NULL) { |
| |
139 tmp = strdup(&m[pos]); |
| |
140 return tmp; |
| |
141 } |
| |
142 |
| |
143 tmp = malloc(len + 1); |
| |
144 tmp[0] = 0; |
| |
145 strncat(tmp, &m[pos], len); |
| |
146 |
| |
147 return tmp; |
| |
148 } |
| |
149 |
| |
150 void substitute(char **mes, int pos, int m, char *text) { |
| |
151 char *new = malloc(strlen(*mes) + strlen(text) + 1); |
| |
152 char *tmp; |
| |
153 new[0] = 0; |
| |
154 |
| |
155 strncat(new, *mes, pos); |
| |
156 strcat(new, text); |
| |
157 |
| |
158 strcat(new, &(*mes)[pos + m]); |
| |
159 tmp = *mes; |
| |
160 *mes = new; |
| |
161 free(tmp); |
| |
162 } |