13e12c5d1SDavid du Colombier typedef struct Addr Addr; 23e12c5d1SDavid du Colombier typedef struct Cmd Cmd; 33e12c5d1SDavid du Colombier struct Addr 43e12c5d1SDavid du Colombier { 53e12c5d1SDavid du Colombier char type; /* # (char addr), l (line addr), / ? . $ + - , ; */ 63e12c5d1SDavid du Colombier union{ 73e12c5d1SDavid du Colombier String *re; 83e12c5d1SDavid du Colombier Addr *aleft; /* left side of , and ; */ 93e12c5d1SDavid du Colombier } g; 103e12c5d1SDavid du Colombier Posn num; 113e12c5d1SDavid du Colombier Addr *next; /* or right side of , and ; */ 123e12c5d1SDavid du Colombier }; 133e12c5d1SDavid du Colombier 143e12c5d1SDavid du Colombier #define are g.re 153e12c5d1SDavid du Colombier #define left g.aleft 163e12c5d1SDavid du Colombier 173e12c5d1SDavid du Colombier struct Cmd 183e12c5d1SDavid du Colombier { 193e12c5d1SDavid du Colombier Addr *addr; /* address (range of text) */ 203e12c5d1SDavid du Colombier String *re; /* regular expression for e.g. 'x' */ 213e12c5d1SDavid du Colombier union{ 223e12c5d1SDavid du Colombier Cmd *cmd; /* target of x, g, {, etc. */ 233e12c5d1SDavid du Colombier String *text; /* text of a, c, i; rhs of s */ 243e12c5d1SDavid du Colombier Addr *addr; /* address for m, t */ 253e12c5d1SDavid du Colombier } g; 263e12c5d1SDavid du Colombier Cmd *next; /* pointer to next element in {} */ 273e12c5d1SDavid du Colombier short num; 283e12c5d1SDavid du Colombier ushort flag; /* whatever */ 293e12c5d1SDavid du Colombier ushort cmdc; /* command character; 'x' etc. */ 303e12c5d1SDavid du Colombier }; 313e12c5d1SDavid du Colombier 323e12c5d1SDavid du Colombier #define ccmd g.cmd 333e12c5d1SDavid du Colombier #define ctext g.text 343e12c5d1SDavid du Colombier #define caddr g.addr 353e12c5d1SDavid du Colombier 36*5e91980fSDavid du Colombier typedef struct Cmdtab Cmdtab; 37*5e91980fSDavid du Colombier struct Cmdtab 38*5e91980fSDavid du Colombier { 393e12c5d1SDavid du Colombier ushort cmdc; /* command character */ 403e12c5d1SDavid du Colombier uchar text; /* takes a textual argument? */ 413e12c5d1SDavid du Colombier uchar regexp; /* takes a regular expression? */ 423e12c5d1SDavid du Colombier uchar addr; /* takes an address (m or t)? */ 433e12c5d1SDavid du Colombier uchar defcmd; /* default command; 0==>none */ 443e12c5d1SDavid du Colombier uchar defaddr; /* default address */ 453e12c5d1SDavid du Colombier uchar count; /* takes a count e.g. s2/// */ 463e12c5d1SDavid du Colombier char *token; /* takes text terminated by one of these */ 473e12c5d1SDavid du Colombier int (*fn)(File*, Cmd*); /* function to call with parse tree */ 483e12c5d1SDavid du Colombier }cmdtab[]; 493e12c5d1SDavid du Colombier 503e12c5d1SDavid du Colombier enum Defaddr{ /* default addresses */ 513e12c5d1SDavid du Colombier aNo, 523e12c5d1SDavid du Colombier aDot, 533e12c5d1SDavid du Colombier aAll, 543e12c5d1SDavid du Colombier }; 553e12c5d1SDavid du Colombier 563e12c5d1SDavid du Colombier int nl_cmd(File*, Cmd*), a_cmd(File*, Cmd*), b_cmd(File*, Cmd*); 573e12c5d1SDavid du Colombier int c_cmd(File*, Cmd*), cd_cmd(File*, Cmd*), d_cmd(File*, Cmd*); 583e12c5d1SDavid du Colombier int D_cmd(File*, Cmd*), e_cmd(File*, Cmd*); 593e12c5d1SDavid du Colombier int f_cmd(File*, Cmd*), g_cmd(File*, Cmd*), i_cmd(File*, Cmd*); 603e12c5d1SDavid du Colombier int k_cmd(File*, Cmd*), m_cmd(File*, Cmd*), n_cmd(File*, Cmd*); 613e12c5d1SDavid du Colombier int p_cmd(File*, Cmd*), q_cmd(File*, Cmd*); 623e12c5d1SDavid du Colombier int s_cmd(File*, Cmd*), u_cmd(File*, Cmd*), w_cmd(File*, Cmd*); 633e12c5d1SDavid du Colombier int x_cmd(File*, Cmd*), X_cmd(File*, Cmd*), plan9_cmd(File*, Cmd*); 643e12c5d1SDavid du Colombier int eq_cmd(File*, Cmd*); 653e12c5d1SDavid du Colombier 663e12c5d1SDavid du Colombier 673e12c5d1SDavid du Colombier String *getregexp(int); 683e12c5d1SDavid du Colombier Addr *newaddr(void); 693e12c5d1SDavid du Colombier Address address(Addr*, Address, int); 703e12c5d1SDavid du Colombier int cmdexec(File*, Cmd*); 71