comparison src/cmds.c @ 9175:3e2ea5b69605

[gaim-migrate @ 9970] W and S are now implemented for /cmds in core. This means you can do /me with colors again. This was probably the hardest part of cmds that was left to do. So the rest should be fairly easy. Hopefully there's no major bugs in this. There's some inconsist use of g_utf8_isspace vs strchr(s, ' ') I want to clean up yet that will cause some oddness if you use a tab instead of a space as your argument separater. committer: Tailor Script <tailor@pidgin.im>
author Tim Ringenbach <marv@pidgin.im>
date Sat, 05 Jun 2004 07:33:58 +0000
parents 108a0300135d
children 5f6ba17ef9f5
comparison
equal deleted inserted replaced
9174:a839ef5d2f34 9175:3e2ea5b69605
21 */ 21 */
22 22
23 #include <string.h> 23 #include <string.h>
24 24
25 #include "account.h" 25 #include "account.h"
26 #include "util.h"
26 #include "cmds.h" 27 #include "cmds.h"
27 28
28 static GList *cmds = NULL; 29 static GList *cmds = NULL;
29 static guint next_id = 1; 30 static guint next_id = 1;
30 31
104 return; 105 return;
105 } 106 }
106 } 107 }
107 } 108 }
108 109
109 static gboolean gaim_cmd_parse_args(GaimCmd *cmd, const gchar *s, gchar ***args) 110 static gboolean gaim_cmd_parse_args(GaimCmd *cmd, const gchar *s, const gchar *m, gchar ***args)
110 { 111 {
111 int i; 112 int i;
112 const char *end, *cur; 113 const char *end, *cur;
113 114
114 *args = g_new0(char *, strlen(cmd->args) + 1); 115 *args = g_new0(char *, strlen(cmd->args) + 1);
125 (*args)[i] = g_strndup(cur, end - cur); 126 (*args)[i] = g_strndup(cur, end - cur);
126 cur += end - cur; 127 cur += end - cur;
127 break; 128 break;
128 case 'W': 129 case 'W':
129 if (!(end = strchr(cur, ' '))) end = cur + strlen(cur); 130 if (!(end = strchr(cur, ' '))) end = cur + strlen(cur);
130 (*args)[i] = g_strndup(cur, end - cur); /* XXX apply default formatting here */ 131 (*args)[i] = gaim_markup_slice(m, g_utf8_pointer_to_offset(s, cur), g_utf8_pointer_to_offset(s, end));
131 cur += end - cur; 132 cur += end - cur;
132 break; 133 break;
133 case 's': 134 case 's':
134 (*args)[i] = g_strdup(cur); 135 (*args)[i] = g_strdup(cur);
135 cur = cur + strlen(cur); 136 cur = cur + strlen(cur);
136 break; 137 break;
137 case 'S': 138 case 'S':
138 (*args)[i] = g_strdup(cur); /* XXX apply default formatting here */ 139 (*args)[i] = gaim_markup_slice(m, g_utf8_pointer_to_offset(s, cur), g_utf8_strlen(cur, -1) + 1);
139 cur = cur + strlen(cur); 140 cur = cur + strlen(cur);
140 break; 141 break;
141 } 142 }
142 } 143 }
143 144
154 for (i = 0; args[i]; i++) 155 for (i = 0; args[i]; i++)
155 g_free(args[i]); 156 g_free(args[i]);
156 g_free(args); 157 g_free(args);
157 } 158 }
158 159
159 GaimCmdStatus gaim_cmd_do_command(GaimConversation *conv, const gchar *cmdline, gchar **error) 160 static void gaim_cmd_strip_current_char(gunichar c, char *s, guint len)
161 {
162 int bytes;
163
164 bytes = g_unichar_to_utf8(c, NULL);
165 memmove(s, s + bytes, len + 1 - bytes);
166 }
167
168 static void gaim_cmd_strip_cmd_from_markup(char *markup)
169 {
170 guint len = strlen(markup);
171 char *s = markup;
172
173 while (*s) {
174 gunichar c = g_utf8_get_char(s);
175
176 if (c == '<') {
177 s = strchr(s, '>');
178 if (!s)
179 return;
180 } else if (g_unichar_isspace(c)) {
181 gaim_cmd_strip_current_char(c, s, len - (s - markup));
182 return;
183 } else {
184 gaim_cmd_strip_current_char(c, s, len - (s - markup));
185 continue;
186 }
187 s = g_utf8_next_char(s);
188 }
189 }
190 GaimCmdStatus gaim_cmd_do_command(GaimConversation *conv, const gchar *cmdline,
191 const gchar *markup, gchar **error)
160 { 192 {
161 GaimCmd *c; 193 GaimCmd *c;
162 GList *l; 194 GList *l;
163 gchar *err = NULL; 195 gchar *err = NULL;
164 gboolean is_im; 196 gboolean is_im;
165 gboolean found = FALSE, tried_cmd = FALSE, right_type = FALSE, right_prpl = FALSE; 197 gboolean found = FALSE, tried_cmd = FALSE, right_type = FALSE, right_prpl = FALSE;
166 const gchar *prpl_id; 198 const gchar *prpl_id;
167 gchar **args = NULL; 199 gchar **args = NULL;
168 gchar *cmd, *rest; 200 gchar *cmd, *rest, *mrest;
169 GaimCmdRet ret = GAIM_CMD_RET_CONTINUE; 201 GaimCmdRet ret = GAIM_CMD_RET_CONTINUE;
170 202
171 *error = NULL; 203 *error = NULL;
172 prpl_id = gaim_account_get_protocol_id(gaim_conversation_get_account(conv)); 204 prpl_id = gaim_account_get_protocol_id(gaim_conversation_get_account(conv));
173 205
185 } else { 217 } else {
186 cmd = g_strdup(cmdline); 218 cmd = g_strdup(cmdline);
187 rest = ""; 219 rest = "";
188 } 220 }
189 221
222 mrest = g_strdup(markup);
223 gaim_cmd_strip_cmd_from_markup(mrest);
224
190 for (l = cmds; l; l = l->next) { 225 for (l = cmds; l; l = l->next) {
191 c = l->data; 226 c = l->data;
192 227
193 if (strcmp(c->cmd, cmd) != 0) 228 if (strcmp(c->cmd, cmd) != 0)
194 continue; 229 continue;
209 continue; 244 continue;
210 245
211 right_prpl = TRUE; 246 right_prpl = TRUE;
212 247
213 /* this checks the allow bad args flag for us */ 248 /* this checks the allow bad args flag for us */
214 if (!gaim_cmd_parse_args(c, rest, &args)) { 249 if (!gaim_cmd_parse_args(c, rest, mrest, &args)) {
215 gaim_cmd_free_args(args); 250 gaim_cmd_free_args(args);
216 args = NULL; 251 args = NULL;
217 continue; 252 continue;
218 } 253 }
219 254
233 } 268 }
234 269
235 if (args) 270 if (args)
236 gaim_cmd_free_args(args); 271 gaim_cmd_free_args(args);
237 g_free(cmd); 272 g_free(cmd);
273 g_free(mrest);
238 274
239 if (!found) 275 if (!found)
240 return GAIM_CMD_STATUS_NOT_FOUND; 276 return GAIM_CMD_STATUS_NOT_FOUND;
241 277
242 if (!right_type) 278 if (!right_type)