File: cmd.c

package info (click to toggle)
hx 0.7.14-7
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k, sarge
  • size: 564 kB
  • ctags: 834
  • sloc: ansic: 7,901; sh: 152; makefile: 81
file content (84 lines) | stat: -rw-r--r-- 1,762 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include "hx_types.h"
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "cmd.h"
#include "screen.h"
#include "hxlib.h"
#include "xmalloc.h"
#include "auto_array.h"

#define isquote(c) (c == '\'' || c == '\"')
#define killspace(_ptr) \
	while (isspace(*(_ptr)))\
		strcpy((_ptr), &((_ptr)[1]));
#define add_arg(_ptr) \
{ argv[argc++] = _ptr;\
if (argc >= 16) {\
	if (argc == 16) {\
		argv = xmalloc(sizeof(char *) * 17);\
		memcpy(argv, auto_argv, sizeof(char *) * 16);\
	} else\
		argv = xrealloc(argv, ((sizeof(char *) * argc) + 1));\
} }

extern void chrexpand (char *p);

int
cmd_exec (char *str_ptr, int xpnd)
{
	register char *p, *cur, c, quote = 0;
	register int ret = 0, argc = 0, str_len = strlen(str_ptr);
	char *auto_argv[16], **argv = auto_argv;
	struct cmd *cmd;
	auto_array(str_ptr, str, str_len);

	killspace(str);
	for (cur = p = str; (c = *p); p++) {
		if (c == '\\' && xpnd) {
			if (p[1])
				chrexpand(p);
			continue;
		}
		if (isquote(c)) {
			if (quote == c) {
				*p = 0;
				add_arg(cur);
				killspace(&(p[1]));
				quote = 0;
				cur = &(p[1]);
			} else if (!quote) {
				quote = c;
				cur = &(p[1]);
			}
		} else if (!quote && isspace(c)) {
			*p = 0;
			add_arg(cur);
			killspace(&(p[1]));
			cur = &(p[1]);
		}
	}
	if (p != cur)
		add_arg(cur);
	argv[argc] = 0;
	if (!argv[0])
		return -1;
	cmd = cmd_lookup(argv[0]);
	if (cmd == (struct cmd *)-1)
		curscr_printf("\n%s: ambiguous command", argv[0]);
	else if (!cmd)
		curscr_printf("\n%s: command not found", argv[0]);
	else if (cmd->main) {
		auto_array(str_ptr, full_str, str_len);
		if (xpnd)
			strexpand(full_str);
		ret = cmd->main(argc, argv, full_str);
		auto_free(full_str);
	}
	if (argv != auto_argv)
		xfree(argv);
	auto_free(str);

	return ret;
}