Blame


1 941e1713 2006-02-15 devnull #include "a.h"
2 941e1713 2006-02-15 devnull
3 941e1713 2006-02-15 devnull Sx *Brdsx1(Biobuf*);
4 941e1713 2006-02-15 devnull
5 941e1713 2006-02-15 devnull Sx*
6 941e1713 2006-02-15 devnull Brdsx(Biobuf *b)
7 941e1713 2006-02-15 devnull {
8 941e1713 2006-02-15 devnull Sx **sx, *x;
9 941e1713 2006-02-15 devnull int nsx;
10 fa325e9b 2020-01-10 cross
11 941e1713 2006-02-15 devnull nsx = 0;
12 941e1713 2006-02-15 devnull sx = nil;
13 941e1713 2006-02-15 devnull while((x = Brdsx1(b)) != nil){
14 941e1713 2006-02-15 devnull sx = erealloc(sx, (nsx+1)*sizeof sx[0]);
15 941e1713 2006-02-15 devnull sx[nsx++] = x;
16 941e1713 2006-02-15 devnull }
17 941e1713 2006-02-15 devnull x = emalloc(sizeof *x);
18 941e1713 2006-02-15 devnull x->sx = sx;
19 941e1713 2006-02-15 devnull x->nsx = nsx;
20 941e1713 2006-02-15 devnull x->type = SxList;
21 941e1713 2006-02-15 devnull return x;
22 941e1713 2006-02-15 devnull }
23 941e1713 2006-02-15 devnull
24 fa325e9b 2020-01-10 cross int
25 941e1713 2006-02-15 devnull sxwalk(Sx *sx)
26 941e1713 2006-02-15 devnull {
27 941e1713 2006-02-15 devnull int i, n;
28 fa325e9b 2020-01-10 cross
29 941e1713 2006-02-15 devnull if(sx == nil)
30 941e1713 2006-02-15 devnull return 1;
31 941e1713 2006-02-15 devnull switch(sx->type){
32 941e1713 2006-02-15 devnull default:
33 941e1713 2006-02-15 devnull case SxAtom:
34 941e1713 2006-02-15 devnull case SxString:
35 941e1713 2006-02-15 devnull case SxNumber:
36 941e1713 2006-02-15 devnull return 1;
37 941e1713 2006-02-15 devnull case SxList:
38 941e1713 2006-02-15 devnull n = 0;
39 941e1713 2006-02-15 devnull for(i=0; i<sx->nsx; i++)
40 941e1713 2006-02-15 devnull n += sxwalk(sx->sx[i]);
41 941e1713 2006-02-15 devnull return n;
42 941e1713 2006-02-15 devnull }
43 941e1713 2006-02-15 devnull }
44 941e1713 2006-02-15 devnull
45 941e1713 2006-02-15 devnull void
46 941e1713 2006-02-15 devnull freesx(Sx *sx)
47 941e1713 2006-02-15 devnull {
48 941e1713 2006-02-15 devnull int i;
49 fa325e9b 2020-01-10 cross
50 941e1713 2006-02-15 devnull if(sx == nil)
51 941e1713 2006-02-15 devnull return;
52 941e1713 2006-02-15 devnull switch(sx->type){
53 941e1713 2006-02-15 devnull case SxAtom:
54 941e1713 2006-02-15 devnull case SxString:
55 941e1713 2006-02-15 devnull free(sx->data);
56 941e1713 2006-02-15 devnull break;
57 941e1713 2006-02-15 devnull case SxList:
58 941e1713 2006-02-15 devnull for(i=0; i<sx->nsx; i++)
59 941e1713 2006-02-15 devnull freesx(sx->sx[i]);
60 941e1713 2006-02-15 devnull free(sx->sx);
61 941e1713 2006-02-15 devnull break;
62 941e1713 2006-02-15 devnull }
63 941e1713 2006-02-15 devnull free(sx);
64 941e1713 2006-02-15 devnull }
65 941e1713 2006-02-15 devnull
66 941e1713 2006-02-15 devnull Sx*
67 941e1713 2006-02-15 devnull Brdsx1(Biobuf *b)
68 941e1713 2006-02-15 devnull {
69 941e1713 2006-02-15 devnull int c, len, nbr;
70 941e1713 2006-02-15 devnull char *s;
71 941e1713 2006-02-15 devnull vlong n;
72 941e1713 2006-02-15 devnull Sx *x;
73 fa325e9b 2020-01-10 cross
74 941e1713 2006-02-15 devnull c = Bgetc(b);
75 941e1713 2006-02-15 devnull if(c == ' ')
76 941e1713 2006-02-15 devnull c = Bgetc(b);
77 941e1713 2006-02-15 devnull if(c < 0)
78 941e1713 2006-02-15 devnull return nil;
79 941e1713 2006-02-15 devnull if(c == '\r')
80 941e1713 2006-02-15 devnull c = Bgetc(b);
81 941e1713 2006-02-15 devnull if(c == '\n')
82 941e1713 2006-02-15 devnull return nil;
83 941e1713 2006-02-15 devnull if(c == ')'){ /* end of list */
84 941e1713 2006-02-15 devnull Bungetc(b);
85 941e1713 2006-02-15 devnull return nil;
86 941e1713 2006-02-15 devnull }
87 941e1713 2006-02-15 devnull if(c == '('){ /* parenthesized list */
88 941e1713 2006-02-15 devnull x = Brdsx(b);
89 941e1713 2006-02-15 devnull c = Bgetc(b);
90 941e1713 2006-02-15 devnull if(c != ')') /* oops! not good */
91 941e1713 2006-02-15 devnull Bungetc(b);
92 941e1713 2006-02-15 devnull return x;
93 941e1713 2006-02-15 devnull }
94 941e1713 2006-02-15 devnull if(c == '{'){ /* length-prefixed string */
95 941e1713 2006-02-15 devnull len = 0;
96 941e1713 2006-02-15 devnull while((c = Bgetc(b)) >= 0 && isdigit(c))
97 941e1713 2006-02-15 devnull len = len*10 + c-'0';
98 941e1713 2006-02-15 devnull if(c != '}') /* oops! not good */
99 941e1713 2006-02-15 devnull Bungetc(b);
100 941e1713 2006-02-15 devnull c = Bgetc(b);
101 941e1713 2006-02-15 devnull if(c != '\r') /* oops! not good */
102 941e1713 2006-02-15 devnull ;
103 941e1713 2006-02-15 devnull c = Bgetc(b);
104 941e1713 2006-02-15 devnull if(c != '\n') /* oops! not good */
105 941e1713 2006-02-15 devnull ;
106 941e1713 2006-02-15 devnull x = emalloc(sizeof *x);
107 941e1713 2006-02-15 devnull x->data = emalloc(len+1);
108 941e1713 2006-02-15 devnull if(Bread(b, x->data, len) != len)
109 941e1713 2006-02-15 devnull ; /* oops! */
110 941e1713 2006-02-15 devnull x->data[len] = 0;
111 941e1713 2006-02-15 devnull x->ndata = len;
112 941e1713 2006-02-15 devnull x->type = SxString;
113 941e1713 2006-02-15 devnull return x;
114 941e1713 2006-02-15 devnull }
115 941e1713 2006-02-15 devnull if(c == '"'){ /* quoted string */
116 941e1713 2006-02-15 devnull s = nil;
117 941e1713 2006-02-15 devnull len = 0;
118 941e1713 2006-02-15 devnull while((c = Bgetc(b)) >= 0 && c != '"'){
119 941e1713 2006-02-15 devnull if(c == '\\')
120 941e1713 2006-02-15 devnull c = Bgetc(b);
121 941e1713 2006-02-15 devnull s = erealloc(s, len+1);
122 941e1713 2006-02-15 devnull s[len++] = c;
123 941e1713 2006-02-15 devnull }
124 941e1713 2006-02-15 devnull s = erealloc(s, len+1);
125 941e1713 2006-02-15 devnull s[len] = 0;
126 941e1713 2006-02-15 devnull x = emalloc(sizeof *x);
127 941e1713 2006-02-15 devnull x->data = s;
128 941e1713 2006-02-15 devnull x->ndata = len;
129 941e1713 2006-02-15 devnull x->type = SxString;
130 941e1713 2006-02-15 devnull return x;
131 941e1713 2006-02-15 devnull }
132 941e1713 2006-02-15 devnull if(isdigit(c)){ /* number */
133 941e1713 2006-02-15 devnull n = c-'0';;
134 941e1713 2006-02-15 devnull while((c = Bgetc(b)) >= 0 && isdigit(c))
135 941e1713 2006-02-15 devnull n = n*10 + c-'0';
136 941e1713 2006-02-15 devnull Bungetc(b);
137 941e1713 2006-02-15 devnull x = emalloc(sizeof *x);
138 941e1713 2006-02-15 devnull x->number = n;
139 941e1713 2006-02-15 devnull x->type = SxNumber;
140 941e1713 2006-02-15 devnull return x;
141 941e1713 2006-02-15 devnull }
142 941e1713 2006-02-15 devnull /* atom */
143 941e1713 2006-02-15 devnull len = 1;
144 941e1713 2006-02-15 devnull s = emalloc(1);
145 941e1713 2006-02-15 devnull s[0] = c;
146 941e1713 2006-02-15 devnull nbr = 0;
147 fa325e9b 2020-01-10 cross while((c = Bgetc(b)) >= 0 && c > ' ' && !strchr("(){}", c)){
148 941e1713 2006-02-15 devnull /* allow embedded brackets as in BODY[] */
149 941e1713 2006-02-15 devnull if(c == '['){
150 941e1713 2006-02-15 devnull if(s[0] == '[')
151 941e1713 2006-02-15 devnull break;
152 941e1713 2006-02-15 devnull else
153 941e1713 2006-02-15 devnull nbr++;
154 941e1713 2006-02-15 devnull }
155 941e1713 2006-02-15 devnull if(c == ']'){
156 941e1713 2006-02-15 devnull if(nbr > 0)
157 941e1713 2006-02-15 devnull nbr--;
158 941e1713 2006-02-15 devnull else
159 941e1713 2006-02-15 devnull break;
160 941e1713 2006-02-15 devnull }
161 941e1713 2006-02-15 devnull s = erealloc(s, len+1);
162 941e1713 2006-02-15 devnull s[len++] = c;
163 941e1713 2006-02-15 devnull }
164 941e1713 2006-02-15 devnull if(c != ' ')
165 941e1713 2006-02-15 devnull Bungetc(b);
166 941e1713 2006-02-15 devnull s = erealloc(s, len+1);
167 941e1713 2006-02-15 devnull s[len] = 0;
168 941e1713 2006-02-15 devnull x = emalloc(sizeof *x);
169 941e1713 2006-02-15 devnull x->type = SxAtom;
170 941e1713 2006-02-15 devnull x->data = s;
171 941e1713 2006-02-15 devnull x->ndata = len;
172 fa325e9b 2020-01-10 cross return x;
173 941e1713 2006-02-15 devnull }
174 941e1713 2006-02-15 devnull
175 941e1713 2006-02-15 devnull int
176 941e1713 2006-02-15 devnull sxfmt(Fmt *fmt)
177 941e1713 2006-02-15 devnull {
178 941e1713 2006-02-15 devnull int i, paren;
179 941e1713 2006-02-15 devnull Sx *sx;
180 fa325e9b 2020-01-10 cross
181 941e1713 2006-02-15 devnull sx = va_arg(fmt->args, Sx*);
182 941e1713 2006-02-15 devnull if(sx == nil)
183 941e1713 2006-02-15 devnull return 0;
184 941e1713 2006-02-15 devnull
185 941e1713 2006-02-15 devnull switch(sx->type){
186 941e1713 2006-02-15 devnull case SxAtom:
187 941e1713 2006-02-15 devnull case SxString:
188 941e1713 2006-02-15 devnull return fmtprint(fmt, "%q", sx->data);
189 941e1713 2006-02-15 devnull
190 941e1713 2006-02-15 devnull case SxNumber:
191 941e1713 2006-02-15 devnull return fmtprint(fmt, "%lld", sx->number);
192 941e1713 2006-02-15 devnull
193 941e1713 2006-02-15 devnull case SxList:
194 941e1713 2006-02-15 devnull paren = !(fmt->flags&FmtSharp);
195 941e1713 2006-02-15 devnull if(paren)
196 941e1713 2006-02-15 devnull fmtrune(fmt, '(');
197 941e1713 2006-02-15 devnull for(i=0; i<sx->nsx; i++){
198 941e1713 2006-02-15 devnull if(i)
199 941e1713 2006-02-15 devnull fmtrune(fmt, ' ');
200 941e1713 2006-02-15 devnull fmtprint(fmt, "%$", sx->sx[i]);
201 941e1713 2006-02-15 devnull }
202 941e1713 2006-02-15 devnull if(paren)
203 941e1713 2006-02-15 devnull return fmtrune(fmt, ')');
204 941e1713 2006-02-15 devnull return 0;
205 941e1713 2006-02-15 devnull
206 941e1713 2006-02-15 devnull default:
207 941e1713 2006-02-15 devnull return fmtstrcpy(fmt, "?");
208 941e1713 2006-02-15 devnull }
209 941e1713 2006-02-15 devnull }
210 941e1713 2006-02-15 devnull
211 941e1713 2006-02-15 devnull int
212 941e1713 2006-02-15 devnull oksx(Sx *sx)
213 941e1713 2006-02-15 devnull {
214 fa325e9b 2020-01-10 cross return sx->nsx >= 2
215 fa325e9b 2020-01-10 cross && sx->sx[1]->type == SxAtom
216 941e1713 2006-02-15 devnull && cistrcmp(sx->sx[1]->data, "OK") == 0;
217 941e1713 2006-02-15 devnull }