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 extern int isatty(int); /* <unistd.h> */
17 int ap;
18 int ac;
19 char **av;
20 char *tmp;
22 void synbad(char *, char *);
23 int fsizep(char *);
24 int isdir(char *);
25 int isreg(char *);
26 int isint(char *, int *);
27 int hasmode(char *, ulong);
28 int tio(char *, int);
29 int e(void), e1(void), e2(void), e3(void);
31 void
32 main(int argc, char *argv[])
33 {
35 ac = argc; av = argv; ap = 1;
36 if(EQ(argv[0],"[")) {
37 if(!EQ(argv[--ac],"]"))
38 synbad("] missing","");
39 }
40 argv[ac] = 0;
41 if (ac<=1) exits("usage");
42 exits(e()?0:"false");
43 }
45 char *
46 nxtarg(int mt)
47 {
48 if(ap>=ac){
49 if(mt){
50 ap++;
51 return(0);
52 }
53 synbad("argument expected","");
54 }
55 return(av[ap++]);
56 }
58 int
59 nxtintarg(int *pans)
60 {
61 if(ap<ac && isint(av[ap], pans)){
62 ap++;
63 return 1;
64 }
65 return 0;
66 }
68 int
69 e(void) {
70 int p1;
72 p1 = e1();
73 if (EQ(nxtarg(1), "-o")) return(p1 || e());
74 ap--;
75 return(p1);
76 }
78 int
79 e1(void) {
80 int p1;
82 p1 = e2();
83 if (EQ(nxtarg(1), "-a")) return (p1 && e1());
84 ap--;
85 return(p1);
86 }
88 int
89 e2(void) {
90 if (EQ(nxtarg(0), "!"))
91 return(!e2());
92 ap--;
93 return(e3());
94 }
96 int
97 e3(void) {
98 int p1;
99 char *a;
100 char *p2;
101 int int1, int2;
103 a = nxtarg(0);
104 if(EQ(a, "(")) {
105 p1 = e();
106 if(!EQ(nxtarg(0), ")")) synbad(") expected","");
107 return(p1);
110 if(EQ(a, "-A"))
111 return(hasmode(nxtarg(0), DMAPPEND));
113 if(EQ(a, "-L"))
114 return(hasmode(nxtarg(0), DMEXCL));
116 if(EQ(a, "-f"))
117 return(isreg(nxtarg(0)));
119 if(EQ(a, "-d"))
120 return(isdir(nxtarg(0)));
122 if(EQ(a, "-r"))
123 return(tio(nxtarg(0), 4));
125 if(EQ(a, "-w"))
126 return(tio(nxtarg(0), 2));
128 if(EQ(a, "-x"))
129 return(tio(nxtarg(0), 1));
131 if(EQ(a, "-e"))
132 return(tio(nxtarg(0), 0));
134 if(EQ(a, "-c"))
135 return(0);
137 if(EQ(a, "-b"))
138 return(0);
140 if(EQ(a, "-u"))
141 return(0);
143 if(EQ(a, "-g"))
144 return(0);
146 if(EQ(a, "-s"))
147 return(fsizep(nxtarg(0)));
149 if(EQ(a, "-t"))
150 if(ap>=ac || !nxtintarg(&int1))
151 return(isatty(1));
152 else
153 return(isatty(int1));
155 if(EQ(a, "-n"))
156 return(!EQ(nxtarg(0), ""));
157 if(EQ(a, "-z"))
158 return(EQ(nxtarg(0), ""));
160 p2 = nxtarg(1);
161 if (p2==0)
162 return(!EQ(a,""));
163 if(EQ(p2, "="))
164 return(EQ(nxtarg(0), a));
166 if(EQ(p2, "!="))
167 return(!EQ(nxtarg(0), a));
169 if(!isint(a, &int1))
170 return(!EQ(a,""));
172 if(nxtintarg(&int2)){
173 if(EQ(p2, "-eq"))
174 return(int1==int2);
175 if(EQ(p2, "-ne"))
176 return(int1!=int2);
177 if(EQ(p2, "-gt"))
178 return(int1>int2);
179 if(EQ(p2, "-lt"))
180 return(int1<int2);
181 if(EQ(p2, "-ge"))
182 return(int1>=int2);
183 if(EQ(p2, "-le"))
184 return(int1<=int2);
187 synbad("unknown operator ",p2);
188 return 0; /* to shut ken up */
191 int
192 tio(char *a, int f)
194 return access (a, f) >= 0;
197 /* copy to local memory; clear names for safety */
198 int
199 localstat(char *f, Dir *dir)
201 Dir *d;
203 d = dirstat(f);
204 if(d == 0)
205 return(-1);
206 *dir = *d;
207 dir->name = 0;
208 dir->uid = 0;
209 dir->gid = 0;
210 dir->muid = 0;
211 return 0;
214 /* copy to local memory; clear names for safety */
215 int
216 localfstat(int f, Dir *dir)
218 Dir *d;
220 d = dirfstat(f);
221 if(d == 0)
222 return(-1);
223 *dir = *d;
224 dir->name = 0;
225 dir->uid = 0;
226 dir->gid = 0;
227 dir->muid = 0;
228 return 0;
231 int
232 hasmode(char *f, ulong m)
234 Dir dir;
236 if(localstat(f,&dir)<0)
237 return(0);
238 return(dir.mode&m);
241 int
242 isdir(char *f)
244 Dir dir;
246 if(localstat(f,&dir)<0)
247 return(0);
248 return(dir.mode&DMDIR);
251 int
252 isreg(char *f)
254 Dir dir;
256 if(localstat(f,&dir)<0)
257 return(0);
258 return(!(dir.mode&DMDIR));
261 int
262 fsizep(char *f)
264 Dir dir;
266 if(localstat(f,&dir)<0)
267 return(0);
268 return(dir.length>0);
271 void
272 synbad(char *s1, char *s2)
274 int len;
276 write(2, "test: ", 6);
277 if ((len = strlen(s1)) != 0)
278 write(2, s1, len);
279 if ((len = strlen(s2)) != 0)
280 write(2, s2, len);
281 write(2, "\n", 1);
282 exits("bad syntax");
285 int
286 isint(char *s, int *pans)
288 char *ep;
290 *pans = strtol(s, &ep, 0);
291 return (*ep == 0);