rc

[fork] interactive rc shell
git clone https://hhvn.uk/rc
git clone git://hhvn.uk/rc
Log | Files | Refs | README | LICENSE

rc.h (9559B)


      1 #undef NDEBUG
      2 #include "config.h"
      3 #include "proto.h"
      4 
      5 #include <assert.h>
      6 
      7 /* for struct stat */
      8 #include <sys/stat.h>
      9 
     10 #define RC "rc: "
     11 
     12 /* datatypes */
     13 
     14 #define ENV_SEP '\001'
     15 #define ENV_ESC '\002'
     16 
     17 /* braindamaged IBM header files #define true and false */
     18 #undef FALSE
     19 #undef TRUE
     20 
     21 typedef void builtin_t(char **);
     22 typedef struct Block Block;
     23 typedef struct Dup Dup;
     24 typedef struct Estack Estack;
     25 typedef struct rc_Function rc_Function;
     26 typedef struct Hq Hq;
     27 typedef struct Htab Htab;
     28 typedef struct Jbwrap Jbwrap;
     29 typedef struct List List;
     30 typedef struct Node Node;
     31 typedef struct Pipe Pipe;
     32 typedef struct Redir Redir;
     33 typedef struct Rq Rq;
     34 typedef struct Variable Variable;
     35 typedef struct Word Word;
     36 typedef struct Format Format;
     37 typedef union Edata Edata;
     38 
     39 typedef enum nodetype {
     40 	nAndalso, nAssign, nBackq, nBang, nBody, nCbody, nNowait, nBrace,
     41 	nConcat, nCount, nElse, nFlat, nDup, nEpilog, nNewfn, nForin, nIf,
     42 	nIfnot, nOrelse, nPipe, nPre, nRedir, nRmfn, nArgs, nSubshell, nCase,
     43 	nSwitch, nMatch, nVar, nVarsub, nWhile, nWord, nLappend, nNmpipe
     44 } nodetype;
     45 
     46 typedef enum ecodes {
     47 	eError, eBreak, eReturn, eVarstack, eArena, eFifo, eFd, eContinue
     48 } ecodes;
     49 
     50 typedef enum bool {
     51 	FALSE, TRUE
     52 } bool;
     53 
     54 typedef enum redirtype {
     55 	rFrom, rCreate, rAppend, rHeredoc, rHerestring
     56 } redirtype;
     57 
     58 typedef bool (*Conv)(Format *, int);
     59 
     60 union Edata {
     61 	Jbwrap *jb;
     62 	Block *b;
     63 	char *name;
     64 	int fd;
     65 };
     66 
     67 struct Estack {
     68 	ecodes e;
     69 	bool interactive;
     70 	Edata data;
     71 	Estack *prev;
     72 };
     73 
     74 struct List {
     75 	char *w, *m;
     76 	List *n;
     77 };
     78 
     79 struct Node {
     80 	nodetype type;
     81 	union {
     82 		char *s;
     83 		int i;
     84 		Node *p;
     85 	} u[4];
     86 };
     87 
     88 struct Pipe {
     89 	int left, right;
     90 };
     91 
     92 struct Dup {
     93 	redirtype type;
     94 	int left, right;
     95 };
     96 
     97 struct Redir {
     98 	redirtype type;
     99 	int fd;
    100 };
    101 
    102 struct Word {
    103 	char *w, *m;
    104 	bool q;
    105 };
    106 
    107 struct Rq {
    108 	Node *r;
    109 	struct Rq *n;
    110 };
    111 
    112 struct rc_Function {
    113 	Node *def;
    114 	char *extdef;
    115 };
    116 
    117 struct Variable {
    118 	List *def;
    119 	char *extdef;
    120 	Variable *n;
    121 };
    122 
    123 struct Htab {
    124 	char *name;
    125 	void *p;
    126 };
    127 
    128 struct Format {
    129 	/* for the formatting routines */
    130 	va_list args;
    131 	long flags, f1, f2;
    132 	/* for the buffer maintenance routines */
    133 	char *buf, *bufbegin, *bufend;
    134 	int flushed;
    135 	void (*grow)(Format *, size_t);
    136 	union { int n; void *p; } u;
    137 };
    138 
    139 /* Format->flags values */
    140 enum {
    141 	FMT_quad	= 1,		/* %q */
    142 	FMT_long	= 2,		/* %l */
    143 	FMT_unsigned	= 8,		/* %u */
    144 	FMT_zeropad	= 16,		/* %0 */
    145 	FMT_leftside	= 32,		/* %- */
    146 	FMT_altform	= 64,		/* %# */
    147 	FMT_f1set	= 128,		/* %<n> */
    148 	FMT_f2set	= 256		/* %.<n> */
    149 };
    150 
    151 /* macros */
    152 #define EOF (-1)
    153 #ifndef NULL
    154 #define NULL 0
    155 #endif
    156 #define a2u(x) n2u(x, 10)
    157 #define o2u(x) n2u(x, 8)
    158 #define arraysize(a) ((int)(sizeof(a)/sizeof(*a)))
    159 #define memzero(s, n) memset(s, 0, n)
    160 #define enew(x) ((x *) ealloc(sizeof(x)))
    161 #define ecpy(x) strcpy((char *) ealloc(strlen(x) + 1), x)
    162 #define lookup_fn(s) ((rc_Function *) lookup(s, fp))
    163 #define lookup_var(s) ((Variable *) lookup(s, vp))
    164 #define nnew(x) ((x *) nalloc(sizeof(x)))
    165 #define ncpy(x) (strcpy((char *) nalloc(strlen(x) + 1), x))
    166 #ifndef offsetof
    167 #define offsetof(t, m) ((size_t) (((char *) &((t *) 0)->m) - (char *)0))
    168 #endif
    169 #define streq(x, y) (*(x) == *(y) && strcmp(x, y) == 0)
    170 #define conststrlen(x) (sizeof (x) - 1)
    171 
    172 /* rc prototypes */
    173 
    174 /* main.c */
    175 extern Rq *redirq;
    176 extern bool dashdee, dashee, dasheye, dashell, dashen;
    177 extern bool dashpee, dashoh, dashess, dashvee, dashex;
    178 extern bool interactive;
    179 extern char *dashsee[];
    180 extern pid_t rc_pid;
    181 extern int lineno;
    182 
    183 /* builtins.c */
    184 extern builtin_t *isbuiltin(char *);
    185 extern void b_exec(char **), funcall(char **), b_dot(char **), b_builtin(char **);
    186 extern char *compl_builtin(const char *, int);
    187 
    188 /* except.c */
    189 extern bool nl_on_intr;
    190 extern bool outstanding_cmdarg(void);
    191 extern void pop_cmdarg(bool);
    192 extern void rc_raise(ecodes);
    193 extern void except(ecodes, Edata, Estack *);
    194 extern void unexcept(ecodes);
    195 extern void rc_error(char *);
    196 extern void sigint(int);
    197 
    198 /* exec.c */
    199 extern void exec(List *, bool);
    200 
    201 #if HASH_BANG
    202 #define rc_execve execve
    203 #else
    204 /* execve.c */
    205 extern int my_execve(char *, char **, char **);
    206 #endif
    207 
    208 /* footobar.c */
    209 extern char **list2array(List *, bool);
    210 extern char *get_name(char *);
    211 extern List *parse_var(char *);
    212 extern Node *parse_fn(char *);
    213 extern void initprint(void);
    214 extern void rc_exit(int); /* here for odd reasons; user-defined signal handlers are kept in fn.c */
    215 
    216 /* getopt.c */
    217 extern int rc_getopt(int, char **, char *);
    218 
    219 extern int rc_optind, rc_opterr, rc_optopt;
    220 extern char *rc_optarg;
    221 
    222 /* glob.c */
    223 extern bool lmatch(List *, List *);
    224 extern List *glob(List *);
    225 
    226 /* glom.c */
    227 extern void assign(List *, List *, bool);
    228 extern void qredir(Node *);
    229 extern List *append(List *, List*);
    230 extern List *flatten(List *);
    231 extern List *glom(Node *);
    232 extern List *concat(List *, List *);
    233 extern List *varsub(List *, List *);
    234 extern List *word(char *, char *);
    235 
    236 /* hash.c */
    237 extern Htab *fp, *vp;
    238 extern void *lookup(char *, Htab *);
    239 extern rc_Function *get_fn_place(char *);
    240 extern List *varlookup(char *);
    241 extern Node *fnlookup(char *);
    242 extern Variable *get_var_place(char *, bool);
    243 extern bool varassign_string(char *);
    244 extern char **makeenv(void);
    245 extern char *fnlookup_string(char *);
    246 extern char *varlookup_string(char *);
    247 extern void alias(char *, List *, bool);
    248 extern void starassign(char *, char **, bool);
    249 extern void delete_fn(char *);
    250 extern void delete_var(char *, bool);
    251 extern void fnassign(char *, Node *);
    252 extern void fnassign_string(char *);
    253 extern void fnrm(char *);
    254 extern void initenv(char **);
    255 extern void inithash(void);
    256 extern void set_exportable(char *, bool);
    257 extern void setsigdefaults(bool);
    258 extern void inithandler(void);
    259 extern void varassign(char *, List *, bool);
    260 extern void varrm(char *, bool);
    261 extern void whatare_all_vars(bool, bool);
    262 extern void whatare_all_signals(void);
    263 extern void prettyprint_var(int, char *, List *);
    264 extern void prettyprint_fn(int, char *, Node *);
    265 extern char *compl_name(const char *, int, char **, size_t, ssize_t);
    266 extern char *compl_fn(const char *, int);
    267 extern char *compl_var(const char *, int);
    268 
    269 /* heredoc.c */
    270 extern int heredoc(int);
    271 extern int qdoc(Node *, Node *);
    272 extern Hq *hq;
    273 
    274 /* lex.c */
    275 extern bool quotep(char *, bool);
    276 extern int yylex(void);
    277 extern void inityy(void);
    278 extern void yyerror(const char *);
    279 extern void scanerror(char *);
    280 extern const char nw[], dnw[];
    281 
    282 /* list.c */
    283 extern void listfree(List *);
    284 extern List *listcpy(List *, void *(*)(size_t));
    285 extern size_t listlen(List *);
    286 extern int listnel(List *);
    287 
    288 /* match.c */
    289 extern bool match(char *, char *, char *);
    290 
    291 /* alloc.c */
    292 extern void *ealloc(size_t);
    293 extern void *erealloc(void *, size_t);
    294 extern void efree(void *);
    295 extern Block *newblock(void);
    296 extern void *nalloc(size_t);
    297 extern void nfree(void);
    298 extern void restoreblock(Block *);
    299 
    300 /* open.c */
    301 extern int rc_open(const char *, redirtype);
    302 extern bool makeblocking(int);
    303 extern bool makesamepgrp(int);
    304 
    305 /* print.c */
    306 /*
    307    The following prototype should be:
    308 extern Conv fmtinstall(int, Conv);
    309    but this freaks out SGI's compiler under IRIX3.3.2
    310 */
    311 extern bool (*fmtinstall(int, bool (*)(Format *, int)))(Format *, int);
    312 extern int printfmt(Format *, const char *);
    313 extern int fmtprint(Format *, const char *,...);
    314 extern void fmtappend(Format *, const char *, size_t);
    315 extern void fmtcat(Format *, const char *);
    316 extern int fprint(int fd, const char *fmt,...);
    317 extern char *mprint(const char *fmt,...);
    318 extern char *nprint(const char *fmt,...);
    319 /*
    320    the following macro should by rights be coded as an expression, not
    321    a statement, but certain compilers (notably DEC) have trouble with
    322    void expressions inside the ?: operator. (sheesh, give me a break!)
    323 */
    324 #define	fmtputc(f, c) {\
    325 	if ((f)->buf >= (f)->bufend)\
    326 		(*(f)->grow)((f), (size_t)1);\
    327 	*(f)->buf++ = (c);\
    328 }
    329 
    330 /* parse.c (parse.y) */
    331 extern Node *parsetree;
    332 extern int yyparse(void);
    333 extern void initparse(void);
    334 
    335 /* readline */
    336 extern volatile sig_atomic_t rl_active;
    337 extern struct Jbwrap rl_buf;
    338 
    339 /* redir.c */
    340 extern void doredirs(void);
    341 
    342 
    343 /* signal.c */
    344 extern void initsignal(void);
    345 extern void catcher(int);
    346 extern void sigchk(void);
    347 extern void (*rc_signal(int, void (*)(int)))(int);
    348 extern void (*sys_signal(int, void (*)(int)))(int);
    349 extern void (*sighandlers[])(int);
    350 
    351 
    352 /* status.c */
    353 extern int istrue(void);
    354 extern int getstatus(void);
    355 extern void set(bool);
    356 extern void setstatus(pid_t, int);
    357 extern List *sgetstatus(void);
    358 extern void setpipestatus(int [], int);
    359 extern void ssetstatus(char **);
    360 extern char *strstatus(int s);
    361 
    362 
    363 /* system.c or system-bsd.c */
    364 extern void writeall(int, char *, size_t);
    365 
    366 #if HAVE_RESTARTABLE_SYSCALLS
    367 extern int rc_read(int, char *, size_t);
    368 extern pid_t rc_wait(int *);
    369 extern Jbwrap slowbuf;
    370 extern volatile sig_atomic_t slow;
    371 
    372 #else /* HAVE_RESTARTABLE_SYSCALLS */
    373 
    374 #define rc_read read
    375 #define rc_wait wait
    376 #endif /* HAVE_RESTARTABLE_SYSCALLS */
    377 
    378 
    379 /* tree.c */
    380 extern Node *mk(enum nodetype, ...);
    381 extern Node *treecpy(Node *, void *(*)(size_t));
    382 extern void treefree(Node *);
    383 
    384 /* utils.c */
    385 extern bool isabsolute(char *);
    386 extern int n2u(char *, unsigned int);
    387 extern int mvfd(int, int);
    388 extern int starstrcmp(const void *, const void *);
    389 extern void pr_error(char *, int);
    390 extern void panic(char *);
    391 extern void uerror(char *);
    392 
    393 /* wait.c */
    394 extern pid_t rc_fork(void);
    395 extern pid_t rc_wait4(pid_t, int *, bool);
    396 extern List *sgetapids(void);
    397 extern void waitforall(void);
    398 extern bool forked;
    399 
    400 /* walk.c */
    401 extern bool walk(Node *, bool);
    402 extern bool cond;
    403 
    404 /* which.c */
    405 extern bool rc_access(char *, bool, struct stat *);
    406 extern char *which(char *, bool);