4 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/types.h>
26 cmd_list_parse(int argc
, char **argv
, char **cause
)
28 struct cmd_list
*cmdlist
;
31 size_t arglen
, new_argc
;
32 char **copy_argv
, **new_argv
;
34 copy_argv
= cmd_copy_argv(argc
, argv
);
36 cmdlist
= xmalloc(sizeof *cmdlist
);
37 cmdlist
->references
= 1;
38 TAILQ_INIT(&cmdlist
->list
);
41 for (i
= 0; i
< argc
; i
++) {
42 arglen
= strlen(copy_argv
[i
]);
43 if (arglen
== 0 || copy_argv
[i
][arglen
- 1] != ';')
45 copy_argv
[i
][arglen
- 1] = '\0';
47 if (arglen
> 1 && copy_argv
[i
][arglen
- 2] == '\\') {
48 copy_argv
[i
][arglen
- 2] = ';';
52 new_argc
= i
- lastsplit
;
53 new_argv
= copy_argv
+ lastsplit
;
57 cmd
= cmd_parse(new_argc
, new_argv
, cause
);
60 TAILQ_INSERT_TAIL(&cmdlist
->list
, cmd
, qentry
);
65 if (lastsplit
!= argc
) {
66 cmd
= cmd_parse(argc
- lastsplit
, copy_argv
+ lastsplit
, cause
);
69 TAILQ_INSERT_TAIL(&cmdlist
->list
, cmd
, qentry
);
72 cmd_free_argv(argc
, copy_argv
);
76 cmd_list_free(cmdlist
);
77 cmd_free_argv(argc
, copy_argv
);
82 cmd_list_exec(struct cmd_list
*cmdlist
, struct cmd_ctx
*ctx
)
88 TAILQ_FOREACH(cmd
, &cmdlist
->list
, qentry
) {
89 if ((n
= cmd_exec(cmd
, ctx
)) == -1)
93 * A 1 return value means the command client is being attached
100 * The command client has been attached, so mangle the
101 * context to treat any following commands as if they
102 * were called from inside.
104 if (ctx
->curclient
== NULL
) {
105 ctx
->curclient
= ctx
->cmdclient
;
106 ctx
->cmdclient
= NULL
;
108 ctx
->error
= key_bindings_error
;
109 ctx
->print
= key_bindings_print
;
110 ctx
->info
= key_bindings_info
;
118 cmd_list_free(struct cmd_list
*cmdlist
)
122 if (--cmdlist
->references
!= 0)
125 while (!TAILQ_EMPTY(&cmdlist
->list
)) {
126 cmd
= TAILQ_FIRST(&cmdlist
->list
);
127 TAILQ_REMOVE(&cmdlist
->list
, cmd
, qentry
);
134 cmd_list_print(struct cmd_list
*cmdlist
, char *buf
, size_t len
)
140 TAILQ_FOREACH(cmd
, &cmdlist
->list
, qentry
) {
143 off
+= cmd_print(cmd
, buf
+ off
, len
- off
);
146 if (TAILQ_NEXT(cmd
, qentry
) != NULL
)
147 off
+= xsnprintf(buf
+ off
, len
- off
, " ; ");