Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include	"u.h"
2
#include	"../port/lib.h"
3
#include	"mem.h"
4
#include	"dat.h"
5
#include	"fns.h"
6
#include	"../port/error.h"
7
 
8
/*
9
 * Generous estimate of number of fields, including terminal nil pointer
10
 */
11
static int
12
ncmdfield(char *p, int n)
13
{
14
	int white, nwhite;
15
	char *ep;
16
	int nf;
17
 
18
	if(p == nil)
19
		return 1;
20
 
21
	nf = 0;
22
	ep = p+n;
23
	white = 1;	/* first text will start field */
24
	while(p < ep){
25
		nwhite = (strchr(" \t\r\n", *p++ & 0xFF) != 0);	/* UTF is irrelevant */
26
		if(white && !nwhite)	/* beginning of field */
27
			nf++;
28
		white = nwhite;
29
	}
30
	return nf+1;	/* +1 for nil */
31
}
32
 
33
/*
34
 *  parse a command written to a device
35
 */
36
Cmdbuf*
37
parsecmd(char *p, int n)
38
{
39
	Cmdbuf *volatile cb;
40
	int nf;
41
	char *sp;
42
 
43
	nf = ncmdfield(p, n);
44
 
45
	/* allocate Cmdbuf plus string pointers plus copy of string including \0 */
46
	sp = smalloc(sizeof(*cb) + nf * sizeof(char*) + n + 1);
47
	cb = (Cmdbuf*)sp;
48
	cb->f = (char**)(&cb[1]);
49
	cb->buf = (char*)(&cb->f[nf]);
50
 
51
	if(up!=nil && waserror()){
52
		free(cb);
53
		nexterror();
54
	}
55
	memmove(cb->buf, p, n);
56
	if(up != nil)
57
		poperror();
58
 
59
	/* dump new line and null terminate */
60
	if(n > 0 && cb->buf[n-1] == '\n')
61
		n--;
62
	cb->buf[n] = '\0';
63
 
64
	cb->nf = tokenize(cb->buf, cb->f, nf-1);
65
	cb->f[cb->nf] = nil;
66
 
67
	return cb;
68
}
69
 
70
/*
71
 * Reconstruct original message, for error diagnostic
72
 */
73
void
74
cmderror(Cmdbuf *cb, char *s)
75
{
76
	int i;
77
	char *p, *e;
78
 
79
	p = up->genbuf;
80
	e = p+ERRMAX-10;
81
	p = seprint(p, e, "%s \"", s);
82
	for(i=0; i<cb->nf; i++){
83
		if(i > 0)
84
			p = seprint(p, e, " ");
85
		p = seprint(p, e, "%q", cb->f[i]);
86
	}
87
	strcpy(p, "\"");
88
	error(up->genbuf);
89
}
90
 
91
/*
92
 * Look up entry in table
93
 */
94
Cmdtab*
95
lookupcmd(Cmdbuf *cb, Cmdtab *ctab, int nctab)
96
{
97
	int i;
98
	Cmdtab *ct;
99
 
100
	if(cb->nf == 0)
101
		error("empty control message");
102
 
103
	for(ct = ctab, i=0; i<nctab; i++, ct++){
104
		if(strcmp(ct->cmd, "*") !=0)	/* wildcard always matches */
105
		if(strcmp(ct->cmd, cb->f[0]) != 0)
106
			continue;
107
		if(ct->narg != 0 && ct->narg != cb->nf)
108
			cmderror(cb, Ecmdargs);
109
		return ct;
110
	}
111
 
112
	cmderror(cb, "unknown control message");
113
	return nil;
114
}