Blob


1 /*
2 * POSIX standard
3 * test expression
4 * [ expression ]
5 *
6 * Plan 9 additions:
7 * -A file exists and is append-only
8 * -L file exists and is exclusive-use
9 */
11 #include <u.h>
12 #include <libc.h>
13 #define EQ(a,b) ((tmp=a)==0?0:(strcmp(tmp,b)==0))
15 int ap;
16 int ac;
17 char **av;
18 char *tmp;
20 void synbad(char *, char *);
21 int fsizep(char *);
22 int isdir(char *);
23 int isreg(char *);
24 int isatty(int);
25 int isint(char *, int *);
26 int hasmode(char *, ulong);
27 int tio(char *, int);
28 int e(void), e1(void), e2(void), e3(void);
30 void
31 main(int argc, char *argv[])
32 {
34 ac = argc; av = argv; ap = 1;
35 if(EQ(argv[0],"[")) {
36 if(!EQ(argv[--ac],"]"))
37 synbad("] missing","");
38 }
39 argv[ac] = 0;
40 if (ac<=1) exits("usage");
41 exits(e()?0:"false");
42 }
44 char *
45 nxtarg(int mt)
46 {
47 if(ap>=ac){
48 if(mt){
49 ap++;
50 return(0);
51 }
52 synbad("argument expected","");
53 }
54 return(av[ap++]);
55 }
57 int
58 nxtintarg(int *pans)
59 {
60 if(ap<ac && isint(av[ap], pans)){
61 ap++;
62 return 1;
63 }
64 return 0;
65 }
67 int
68 e(void) {
69 int p1;
71 p1 = e1();
72 if (EQ(nxtarg(1), "-o")) return(p1 || e());
73 ap--;
74 return(p1);
75 }
77 int
78 e1(void) {
79 int p1;
81 p1 = e2();
82 if (EQ(nxtarg(1), "-a")) return (p1 && e1());
83 ap--;
84 return(p1);
85 }
87 int
88 e2(void) {
89 if (EQ(nxtarg(0), "!"))
90 return(!e2());
91 ap--;
92 return(e3());
93 }
95 int
96 e3(void) {
97 int p1;
98 char *a;
99 char *p2;
100 int int1, int2;
102 a = nxtarg(0);
103 if(EQ(a, "(")) {
104 p1 = e();
105 if(!EQ(nxtarg(0), ")")) synbad(") expected","");
106 return(p1);
109 if(EQ(a, "-A"))
110 return(hasmode(nxtarg(0), DMAPPEND));
112 if(EQ(a, "-L"))
113 return(hasmode(nxtarg(0), DMEXCL));
115 if(EQ(a, "-f"))
116 return(isreg(nxtarg(0)));
118 if(EQ(a, "-d"))
119 return(isdir(nxtarg(0)));
121 if(EQ(a, "-r"))
122 return(tio(nxtarg(0), 4));
124 if(EQ(a, "-w"))
125 return(tio(nxtarg(0), 2));
127 if(EQ(a, "-x"))
128 return(tio(nxtarg(0), 1));
130 if(EQ(a, "-e"))
131 return(tio(nxtarg(0), 0));
133 if(EQ(a, "-c"))
134 return(0);
136 if(EQ(a, "-b"))
137 return(0);
139 if(EQ(a, "-u"))
140 return(0);
142 if(EQ(a, "-g"))
143 return(0);
145 if(EQ(a, "-s"))
146 return(fsizep(nxtarg(0)));
148 if(EQ(a, "-t"))
149 if(ap>=ac || !nxtintarg(&int1))
150 return(isatty(1));
151 else
152 return(isatty(int1));
154 if(EQ(a, "-n"))
155 return(!EQ(nxtarg(0), ""));
156 if(EQ(a, "-z"))
157 return(EQ(nxtarg(0), ""));
159 p2 = nxtarg(1);
160 if (p2==0)
161 return(!EQ(a,""));
162 if(EQ(p2, "="))
163 return(EQ(nxtarg(0), a));
165 if(EQ(p2, "!="))
166 return(!EQ(nxtarg(0), a));
168 if(!isint(a, &int1))
169 return(!EQ(a,""));
171 if(nxtintarg(&int2)){
172 if(EQ(p2, "-eq"))
173 return(int1==int2);
174 if(EQ(p2, "-ne"))
175 return(int1!=int2);
176 if(EQ(p2, "-gt"))
177 return(int1>int2);
178 if(EQ(p2, "-lt"))
179 return(int1<int2);
180 if(EQ(p2, "-ge"))
181 return(int1>=int2);
182 if(EQ(p2, "-le"))
183 return(int1<=int2);
186 synbad("unknown operator ",p2);
187 return 0; /* to shut ken up */
190 int
191 tio(char *a, int f)
193 return access (a, f) >= 0;
196 /* copy to local memory; clear names for safety */
197 int
198 localstat(char *f, Dir *dir)
200 Dir *d;
202 d = dirstat(f);
203 if(d == 0)
204 return(-1);
205 *dir = *d;
206 dir->name = 0;
207 dir->uid = 0;
208 dir->gid = 0;
209 dir->muid = 0;
210 return 0;
213 /* copy to local memory; clear names for safety */
214 int
215 localfstat(int f, Dir *dir)
217 Dir *d;
219 d = dirfstat(f);
220 if(d == 0)
221 return(-1);
222 *dir = *d;
223 dir->name = 0;
224 dir->uid = 0;
225 dir->gid = 0;
226 dir->muid = 0;
227 return 0;
230 int
231 hasmode(char *f, ulong m)
233 Dir dir;
235 if(localstat(f,&dir)<0)
236 return(0);
237 return(dir.mode&m);
240 int
241 isdir(char *f)
243 Dir dir;
245 if(localstat(f,&dir)<0)
246 return(0);
247 return(dir.mode&DMDIR);
250 int
251 isreg(char *f)
253 Dir dir;
255 if(localstat(f,&dir)<0)
256 return(0);
257 return(!(dir.mode&DMDIR));
260 int
261 isatty(int fd)
263 Dir d1, d2;
265 if(localfstat(fd, &d1) < 0)
266 return 0;
267 if(localstat("/dev/cons", &d2) < 0)
268 return 0;
269 return d1.type==d2.type && d1.dev==d2.dev && d1.qid.path==d2.qid.path;
272 int
273 fsizep(char *f)
275 Dir dir;
277 if(localstat(f,&dir)<0)
278 return(0);
279 return(dir.length>0);
282 void
283 synbad(char *s1, char *s2)
285 int len;
287 write(2, "test: ", 6);
288 if ((len = strlen(s1)) != 0)
289 write(2, s1, len);
290 if ((len = strlen(s2)) != 0)
291 write(2, s2, len);
292 write(2, "\n", 1);
293 exits("bad syntax");
296 int
297 isint(char *s, int *pans)
299 char *ep;
301 *pans = strtol(s, &ep, 0);
302 return (*ep == 0);