22 cmd_handler_t function;
26 /* The list of cmds */
27 static cmd_t *cmd_list = NULL;
30 #define ALIAS_NAME_MAX 32
31 typedef struct cmd_alias_s
33 char name[ALIAS_NAME_MAX];
35 struct cmd_alias_s *next;
38 /* The list of aliases */
39 static cmd_alias_t *cmd_alias_list = NULL;
42 /* add a new console command */
43 void cmd_addcommand(char *cmd_name, cmd_handler_t cmd_func)
47 Assert(cmd_name != NULL);
49 for (cmd = cmd_list; cmd; cmd = cmd->next) {
50 if (!stricmp(cmd_name, cmd->name))
53 con_printf(CON_NORMAL, "command %s already exists, not adding\n", cmd_name);
58 /* create command, insert at front of list */
59 MALLOC(cmd, cmd_t, 1);
61 cmd->function = cmd_func;
63 con_printf(CON_DEBUG, "cmd_addcommand: added %s\n", cmd->name);
68 typedef struct cmd_queue_s
71 struct cmd_queue_s *next;
74 /* The list of commands to be executed */
75 static cmd_queue_t *cmd_queue_head = NULL;
76 static cmd_queue_t *cmd_queue_tail = NULL;
79 void cvar_cmd_set(int argc, char **argv);
82 /* execute a parsed command */
83 void cmd_execute(int argc, char **argv)
88 for (cmd = cmd_list; cmd; cmd = cmd->next) {
89 if (!stricmp(argv[0], cmd->name)) {
90 con_printf(CON_DEBUG, "cmd_execute: executing %s\n", argv[0]);
91 return cmd->function(argc, argv);
95 for (alias = cmd_alias_list; alias; alias = alias->next) {
96 if (!stricmp(argv[0], alias->name)) {
97 con_printf(CON_DEBUG, "cmd_execute: pushing alias \"%s\": %s\n", alias->name, alias->value);
98 cmd_insert(alias->value);
104 { // set value of cvar
105 char *new_argv[argc+1];
109 for (i = 0; i < argc; i++)
110 new_argv[i+1] = argv[i];
111 cvar_cmd_set(argc + 1, new_argv);
113 con_printf(CON_VERBOSE, "%s: %f\n", argv[0], cvar(argv[0]));
117 /* Parse an input string */
118 void cmd_parse(char *input)
120 char buffer[CMD_MAX_LENGTH];
121 char *tokens[CMD_MAX_TOKENS];
125 Assert(input != NULL);
127 /* Strip leading spaces */
128 for (i=0; isspace(input[i]); i++) ;
129 strncpy( buffer, &input[i], CMD_MAX_LENGTH );
131 //printf("lead strip \"%s\"\n",buffer);
133 /* If command is empty, give up */
136 /* Strip trailing spaces */
137 for (i=l-1; i>0 && isspace(buffer[i]); i--) ;
139 //printf("trail strip \"%s\"\n",buffer);
141 /* Split into tokens */
146 for (i=1; i<l; i++) {
147 if (buffer[i] == '"') {
148 tokens[num_tokens - 1] = &buffer[++i];
149 while (i < l && buffer[i] != '"')
154 if (isspace(buffer[i]) || buffer[i] == '=') {
156 while (isspace(buffer[i+1]) && (i+1 < l)) i++;
157 tokens[num_tokens++] = &buffer[i+1];
161 /* Check for matching commands */
162 cmd_execute(num_tokens, tokens);
166 int cmd_queue_wait = 0;
168 int cmd_queue_process(void)
172 while (!cmd_queue_wait && cmd_queue_head) {
173 cmd = cmd_queue_head;
174 cmd_queue_head = cmd_queue_head->next;
176 cmd_queue_tail = NULL;
178 con_printf(CON_DEBUG, "cmd_queue_process: processing %s\n", cmd->command_line);
179 cmd_parse(cmd->command_line); // Note, this may change the queue
181 d_free(cmd->command_line);
185 if (cmd_queue_wait) {
186 con_printf(CON_DEBUG, "cmd_queue_process: waiting\n");
195 /* Add some commands to the queue to be executed */
196 void cmd_enqueue(int insert, char *input)
198 cmd_queue_t *new, *head, *tail;
199 char output[CMD_MAX_LENGTH];
202 Assert(input != NULL);
209 /* Strip leading spaces */
210 while(isspace(*input) || *input == ';')
213 /* If command is empty, give up */
217 /* Find the end of this line (\n, ;, or nul) */
224 } else if ( *input == '\n' || (!quoted && *input == ';') ) {
228 } while ((*optr++ = *input++));
231 /* make a new queue item, add it to list */
232 MALLOC(new, cmd_queue_t, 1);
233 new->command_line = d_strdup(output);
242 con_printf(CON_DEBUG, "cmd_enqueue: adding %s\n", output);
246 /* add our list to the head of the main list */
248 tail->next = cmd_queue_head;
250 cmd_queue_tail = tail;
252 cmd_queue_head = head;
253 con_printf(CON_DEBUG, "cmd_enqueue: added to front of list\n");
255 /* add our list to the tail of the main list */
257 cmd_queue_head = head;
259 cmd_queue_tail->next = head;
261 cmd_queue_tail = tail;
262 con_printf(CON_DEBUG, "cmd_enqueue: added to back of list\n");
266 void cmd_enqueuef(int insert, char *fmt, ...)
269 char buf[CMD_MAX_LENGTH];
271 va_start (arglist, fmt);
272 vsnprintf (buf, CMD_MAX_LENGTH, fmt, arglist);
275 cmd_enqueue(insert, buf);
279 /* Attempt to autocomplete an input string */
280 char *cmd_complete(char *input)
285 int len = strlen(input);
290 for (ptr = cmd_list; ptr != NULL; ptr = ptr->next)
291 if (!strnicmp(input, ptr->name, len))
294 for (aptr = cmd_alias_list; aptr != NULL; aptr = aptr->next)
295 if (!strnicmp(input, aptr->name, len))
298 return cvar_complete(input);
303 void cmd_alias(int argc, char **argv)
306 char buf[CMD_MAX_LENGTH] = "";
309 if (argc == 2 && !stricmp(argv[1], "-h")) {
310 con_printf(CON_NORMAL, "%s <name> <commands>\n", argv[0]);
311 con_printf(CON_NORMAL, " define <name> as an alias for <commands>\n");
312 con_printf(CON_NORMAL, "%s <name>\n", argv[0]);
313 con_printf(CON_NORMAL, " show the current definition of <name>\n");
314 con_printf(CON_NORMAL, "%s\n", argv[0]);
315 con_printf(CON_NORMAL, " show all defined aliases\n");
320 con_printf(CON_NORMAL, "aliases:\n");
321 for (alias = cmd_alias_list; alias; alias = alias->next)
322 con_printf(CON_NORMAL, "%s: %s\n", alias->name, alias->value);
327 for (alias = cmd_alias_list; alias; alias = alias->next)
328 if (!stricmp(argv[1], alias->name)) {
329 con_printf(CON_NORMAL, "%s: %s\n", alias->name, alias->value);
333 con_printf(CON_NORMAL, "alias: %s not found\n", argv[1]);
337 for (i = 2; i < argc; i++) {
339 strncat(buf, " ", CMD_MAX_LENGTH);
340 strncat(buf, argv[i], CMD_MAX_LENGTH);
343 for (alias = cmd_alias_list; alias; alias = alias->next) {
344 if (!stricmp(argv[1], alias->name)) {
345 d_free(alias->value);
346 alias->value = d_strdup(buf);
351 MALLOC(alias, cmd_alias_t, 1);
352 strncpy(alias->name, argv[1], ALIAS_NAME_MAX);
353 alias->value = d_strdup(buf);
354 alias->next = cmd_alias_list;
355 cmd_alias_list = alias;
360 void cmd_unalias(int argc, char **argv)
362 cmd_alias_t *alias, *prev_alias = NULL;
364 if (argc != 2 || (argc == 2 && !stricmp(argv[1], "-h"))) {
365 con_printf(CON_NORMAL, "%s <name>\n", argv[0]);
366 con_printf(CON_NORMAL, " undefine the alias <name>\n");
370 for (alias = cmd_alias_list; alias ; alias = alias->next) {
371 if (!stricmp(argv[1], alias->name))
377 con_printf(CON_NORMAL, "alias: %s not found\n", argv[1]);
382 prev_alias->next = alias->next;
384 cmd_alias_list = alias->next;
386 d_free(alias->value);
391 /* echo to console */
392 void cmd_echo(int argc, char **argv)
394 char buf[CMD_MAX_LENGTH] = "";
397 if (argc == 2 && !stricmp(argv[1], "-h")) {
398 con_printf(CON_NORMAL, "usage: %s [text]\n", argv[0]);
399 con_printf(CON_NORMAL, " write <text> to the console\n");
404 for (i = 1; i < argc; i++) {
406 strncat(buf, " ", CMD_MAX_LENGTH);
407 strncat(buf, argv[i], CMD_MAX_LENGTH);
409 con_printf(CON_NORMAL, "%s\n", buf);
413 void cmd_exec(int argc, char **argv) {
414 cmd_queue_t *new, *head, *tail;
416 char line[CMD_MAX_LENGTH] = "";
418 if (argc != 2 || (argc == 2 && !stricmp(argv[1], "-h"))) {
419 con_printf(CON_NORMAL, "usage: %s <file>\n", argv[0]);
420 con_printf(CON_NORMAL, " execute <file>\n");
427 f = PHYSFSX_openReadBuffered(argv[1]);
429 con_printf(CON_CRITICAL, "exec: %s not found\n", argv[1]);
432 while (PHYSFSX_gets(f, line)) {
433 /* make a new queue item, add it to list */
434 MALLOC(new, cmd_queue_t, 1);
435 new->command_line = d_strdup(line);
444 con_printf(CON_DEBUG, "cmd_exec: adding %s\n", line);
448 /* add our list to the head of the main list */
450 tail->next = cmd_queue_head;
452 cmd_queue_tail = tail;
454 cmd_queue_head = head;
455 con_printf(CON_DEBUG, "cmd_exec: added to front of list\n");
460 void cmd_help(int argc, char **argv)
464 if (argc > 2 || (argc == 2 && !stricmp(argv[1], "-h"))) {
465 con_printf(CON_NORMAL, "usage: %s [command]\n", argv[0]);
466 con_printf(CON_NORMAL, " get help for <command>, or list all commands if not specified.\n");
472 con_printf(CON_NORMAL, "Available commands:\n");
473 for (cmd = cmd_list; cmd; cmd = cmd->next) {
474 con_printf(CON_NORMAL, " %s\n", cmd->name);
480 cmd_insertf("%s -h", argv[1]);
485 void cmd_wait(int argc, char **argv)
487 if (argc > 2 || (argc == 2 && !stricmp(argv[1], "-h"))) {
488 con_printf(CON_NORMAL, "usage: %s [n]\n", argv[0]);
489 con_printf(CON_NORMAL, " stop processing commands, resume in <n> cycles (default 1)\n");
497 cmd_queue_wait = atoi(argv[1]);
508 p = ((cmd_t *)p)->next;
514 d_free(((cmd_alias_t *)p)->value);
516 p = ((cmd_alias_t *)p)->next;
524 cmd_addcommand("alias", cmd_alias);
525 cmd_addcommand("unalias", cmd_unalias);
526 cmd_addcommand("echo", cmd_echo);
527 cmd_addcommand("exec", cmd_exec);
528 cmd_addcommand("help", cmd_help);
529 cmd_addcommand("wait", cmd_wait);