1 #include <lib9.h> 2 3 #define Lock Rclock 4 #define Ref Rcref 5 6 typedef union Code Code; 7 typedef struct Tree Tree; 8 typedef struct Thread Thread; 9 typedef struct Word Word; 10 typedef struct Var Var; 11 typedef struct List List; 12 typedef struct Redir Redir; 13 typedef struct Io Io; 14 typedef struct Here Here; 15 typedef struct Ref Ref; 16 typedef struct Lock Lock; 17 typedef struct Direntry Direntry; 18 19 #define EOF (-1) 20 #define NBUF 512 21 22 /* values for Tree->rtype */ 23 #define APPEND 1 24 #define WRITE 2 25 #define READ 3 26 #define HERE 4 27 #define DUPFD 5 28 #define CLOSE 6 29 30 /* 31 * redir types 32 */ 33 #define ROPEN 1 /* dup2(from, to); close(from); */ 34 #define RDUP 2 /* dup2(from, to); */ 35 #define RCLOSE 3 /* close(from); */ 36 37 #define NSTATUS 64 /* length of status (from plan 9) */ 38 39 #define IWS 0x01 /* inter word seperator when word lists are stored in env variables */ 40 41 /* 42 * Glob character escape in strings: 43 * In a string, GLOB must be followed by *?[ or GLOB. 44 * GLOB* matches any string 45 * GLOB? matches any single character 46 * GLOB[...] matches anything in the brackets 47 * GLOBGLOB matches GLOB 48 */ 49 #define GLOB ((char)0x02) 50 51 /* 52 * The first word of any code vector is a reference count. 53 * Always create a new reference to a code vector by calling codecopy(.). 54 * Always call codefree(.) when deleting a reference. 55 */ 56 union Code { 57 void (*f)(void); 58 int i; 59 char *s; 60 }; 61 62 63 struct Tree 64 { 65 int type; 66 int rtype, fd0, fd1; /* details of REDIR PIPE DUP tokens */ 67 char *str; 68 int quoted; 69 int iskw; 70 Tree *child[3]; 71 Tree *next; 72 }; 73 74 struct Thread 75 { 76 Code *code; /* code for this thread */ 77 int pc; /* code[pc] is the next instruction */ 78 List *argv; /* argument stack */ 79 Redir *redir; /* redirection stack */ 80 Redir *startredir; /* redir inheritance point */ 81 Var *local; /* list of local variables */ 82 char *cmdfile; /* file name in Xrdcmd */ 83 Io *cmdfd; /* file descriptor for Xrdcmd */ 84 int iflast; /* static `if not' checking */ 85 int eof; /* is cmdfd at eof? */ 86 int iflag; /* interactive? */ 87 int lineno; /* linenumber */ 88 int pid; /* process for Xpipewait to wait for */ 89 char status[NSTATUS]; /* status for Xpipewait */ 90 Tree *treenodes; /* tree nodes created by this process */ 91 Thread *ret; /* who continues when this finishes */ 92 }; 93 94 struct Io 95 { 96 int fd; 97 char *bufp; 98 char *ebuf; 99 char *strp; 100 char buf[NBUF]; 101 }; 102 103 struct Var 104 { 105 char *name; /* ascii name */ 106 Word *val; /* value */ 107 int changed; 108 Code *fn; /* pointer to function's code vector */ 109 int fnchanged; 110 int pc; /* pc of start of function */ 111 Var *next; /* next on hash or local list */ 112 }; 113 114 struct Word 115 { 116 char *word; 117 Word *next; 118 }; 119 120 struct List 121 { 122 Word *words; 123 List *next; 124 }; 125 126 struct Redir 127 { 128 char type; /* what to do */ 129 short from, to; /* what to do it to */ 130 Redir *next; /* what else to do (reverse order) */ 131 }; 132 133 struct Here{ 134 Tree *tag; 135 char *name; 136 Here *next; 137 }; 138 139 struct Lock { 140 int val; 141 }; 142 143 struct Ref 144 { 145 Lock lk; 146 int ref; 147 }; 148 149 struct Direntry 150 { 151 int isdir; 152 char *name; 153 }; 154 155 /* main.c */ 156 void start(Code *c, int pc, Var *local); 157 158 /* lex.c */ 159 void yyerror(char*); 160 int yylex(void); 161 int yyparse(void); 162 int wordchr(int); 163 int idchr(int); 164 165 /* code.c */ 166 int compile(Tree*); 167 Code *codecopy(Code*); 168 void codefree(Code*); 169 void cleanhere(char *f); 170 171 void skipnl(void); 172 173 void panic(char*, int); 174 175 /* var.c */ 176 void kinit(void); 177 void vinit(void); 178 Var *vlook(char*); 179 Var *gvlook(char*); 180 Var *newvar(char*, Var*); 181 void setvar(char*, Word*); 182 void updenv(void); 183 void kenter(int type, char *name); 184 185 /* glob.c */ 186 void deglob(char*); 187 void globlist(void); 188 int match(char *s, char *p, int stop); 189 190 /* main.c */ 191 void setstatus(char *s); 192 char *getstatus(void); 193 int truestatus(void); 194 void execcmds(Io*); 195 char *concstatus(char *s, char *t); 196 char **procargv(char*, char*, char*, char*, Word *w); 197 198 void freewords(Word*); 199 200 /* tree.c */ 201 Tree *newtree(void); 202 Tree *token(char*, int), *klook(char*), *tree1(int, Tree*); 203 Tree *tree2(int, Tree*, Tree*), *tree3(int, Tree*, Tree*, Tree*); 204 Tree *mung1(Tree*, Tree*), *mung2(Tree*, Tree*, Tree*); 205 Tree *mung3(Tree*, Tree*, Tree*, Tree*), *epimung(Tree*, Tree*); 206 Tree *simplemung(Tree*), *heredoc(Tree*); 207 void freetree(Tree*); 208 void freenodes(void); 209 210 /* here.c */ 211 Tree *heredoc(Tree *tag); 212 213 /* exec.c */ 214 extern void Xappend(void), Xasync(void), Xbackq(void), Xbang(void), Xclose(void); 215 extern void Xconc(void), Xcount(void), Xdelfn(void), Xdol(void), Xqdol(void), Xdup(void); 216 extern void Xexit(void), Xfalse(void), Xfn(void), Xfor(void), Xglob(void); 217 extern void Xjump(void), Xmark(void), Xmatch(void), Xpipe(void), Xread(void); 218 extern void Xunredir(void), Xstar(void), Xreturn(void), Xsubshell(void); 219 extern void Xtrue(void), Xword(void), Xwrite(void), Xpipefd(void), Xcase(void); 220 extern void Xlocal(void), Xunlocal(void), Xassign(void), Xsimple(void), Xpopm(void); 221 extern void Xrdcmds(void), Xwastrue(void), Xif(void), Xifnot(void), Xpipewait(void); 222 extern void Xdelhere(void), Xpopredir(void), Xsub(void), Xeflag(void), Xsettrue(void); 223 extern void Xerror(char*), Xperror(char*); 224 225 /* word.c */ 226 Word *newword(char*, Word*); 227 void pushlist(void); 228 void poplist(void); 229 void pushword(char*); 230 void popword(void); 231 int count(Word*); 232 Word *copywords(Word*, Word*); 233 void pushredir(int, int, int); 234 void turfredir(void); 235 char *list2str(Word*); 236 void freelist(Word*); 237 Word *conclist(Word*, Word*, Word*); 238 Word *subwords(Word*, int, Word*, Word*); 239 240 /* io.c */ 241 #define pchr(b, c) if((b)->bufp==(b)->ebuf)fullbuf((b), (c));else (*(b)->bufp++=(c)) 242 #define rchr(b) ((b)->bufp==(b)->ebuf?emptybuf(b):(*(b)->bufp++&0xff)) 243 244 Io *openfd(int), *openstr(void), *opencore(char*, int); 245 int emptybuf(Io*); 246 void closeio(Io*); 247 void flush(Io*); 248 int fullbuf(Io*, int); 249 250 void pfmt(Io*, char*, ...); 251 void perr(Io*); 252 void pstr(Io*, char*); 253 void pfnc(Io*, Thread*); 254 255 void pprompt(void); 256 257 /* trap.c */ 258 void dotrap(void); 259 void dointr(void); 260 261 void waitfor(uint); 262 263 /* nt.c */ 264 265 Direntry* readdirect(char*); 266 void fatal(char*, ...); 267 uint proc(char**, int, int, int); 268 int procwait(uint); 269 int refinc(Ref*); 270 int refdec(Ref*); 271 int pipe(int*); 272 273 /* 274 * onebyte(c), twobyte(c), threebyte(c) 275 * Is c the first character of a one- two- or three-byte utf sequence? 276 */ 277 #define onebyte(c) ((c&0x80)==0x00) 278 #define twobyte(c) ((c&0xe0)==0xc0) 279 #define threebyte(c) ((c&0xf0)==0xe0) 280 281 #define new(type) ((type *)malloc(sizeof(type))) 282 283 284 extern Tree *cmdtree; 285 extern Thread *runq; 286 extern Io *err; 287 extern int flag[256]; 288 extern int doprompt; 289 extern char *promptstr; 290 extern int ndot; 291 extern int nerror; 292 extern Code *codebuf; 293 extern int eflagok; 294 extern int interrupted; 295 extern Ref ntrap; 296