9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

pcmd.c (2681B)


      1 #include "rc.h"
      2 #include "io.h"
      3 #include "fns.h"
      4 char nl='\n';		/* change to semicolon for bourne-proofing */
      5 #define	c0	t->child[0]
      6 #define	c1	t->child[1]
      7 #define	c2	t->child[2]
      8 
      9 void
     10 pdeglob(io *f, char *s)
     11 {
     12 	while(*s){
     13 		if(*s==GLOB)
     14 			s++;
     15 		pchr(f, *s++);
     16 	}
     17 }
     18 
     19 void
     20 pcmd(io *f, tree *t)
     21 {
     22 	if(t==0)
     23 		return;
     24 	switch(t->type){
     25 	default:	pfmt(f, "bad %d %p %p %p", t->type, c0, c1, c2);
     26 	break;
     27 	case '$':	pfmt(f, "$%t", c0);
     28 	break;
     29 	case '"':	pfmt(f, "$\"%t", c0);
     30 	break;
     31 	case '&':	pfmt(f, "%t&", c0);
     32 	break;
     33 	case '^':	pfmt(f, "%t^%t", c0, c1);
     34 	break;
     35 	case '`':	pfmt(f, "`%t", c0);
     36 	break;
     37 	case ANDAND:	pfmt(f, "%t && %t", c0, c1);
     38 	break;
     39 	case BANG:	pfmt(f, "! %t", c0);
     40 	break;
     41 	case BRACE:	pfmt(f, "{%t}", c0);
     42 	break;
     43 	case COUNT:	pfmt(f, "$#%t", c0);
     44 	break;
     45 	case FN:	pfmt(f, "fn %t %t", c0, c1);
     46 	break;
     47 	case IF:	pfmt(f, "if%t%t", c0, c1);
     48 	break;
     49 	case NOT:	pfmt(f, "if not %t", c0);
     50 	break;
     51 	case OROR:	pfmt(f, "%t || %t", c0, c1);
     52 	break;
     53 	case PCMD:
     54 	case PAREN:	pfmt(f, "(%t)", c0);
     55 	break;
     56 	case SUB:	pfmt(f, "$%t(%t)", c0, c1);
     57 	break;
     58 	case SIMPLE:	pfmt(f, "%t", c0);
     59 	break;
     60 	case SUBSHELL:	pfmt(f, "@ %t", c0);
     61 	break;
     62 	case SWITCH:	pfmt(f, "switch %t %t", c0, c1);
     63 	break;
     64 	case TWIDDLE:	pfmt(f, "~ %t %t", c0, c1);
     65 	break;
     66 	case WHILE:	pfmt(f, "while %t%t", c0, c1);
     67 	break;
     68 	case ARGLIST:
     69 		if(c0==0)
     70 			pfmt(f, "%t", c1);
     71 		else if(c1==0)
     72 			pfmt(f, "%t", c0);
     73 		else
     74 			pfmt(f, "%t %t", c0, c1);
     75 		break;
     76 	case ';':
     77 		if(c0){
     78 			if(c1)
     79 				pfmt(f, "%t%c%t", c0, nl, c1);
     80 			else pfmt(f, "%t", c0);
     81 		}
     82 		else pfmt(f, "%t", c1);
     83 		break;
     84 	case WORDS:
     85 		if(c0)
     86 			pfmt(f, "%t ", c0);
     87 		pfmt(f, "%t", c1);
     88 		break;
     89 	case FOR:
     90 		pfmt(f, "for(%t", c0);
     91 		if(c1)
     92 			pfmt(f, " in %t", c1);
     93 		pfmt(f, ")%t", c2);
     94 		break;
     95 	case WORD:
     96 		if(t->quoted)
     97 			pfmt(f, "%Q", t->str);
     98 		else pdeglob(f, t->str);
     99 		break;
    100 	case DUP:
    101 		if(t->rtype==DUPFD)
    102 			pfmt(f, ">[%d=%d]", t->fd1, t->fd0); /* yes, fd1, then fd0; read lex.c */
    103 		else
    104 			pfmt(f, ">[%d=]", t->fd0);
    105 		pfmt(f, "%t", c1);
    106 		break;
    107 	case PIPEFD:
    108 	case REDIR:
    109 		switch(t->rtype){
    110 		case HERE:
    111 			pchr(f, '<');
    112 		case READ:
    113 		case RDWR:
    114 			pchr(f, '<');
    115 			if(t->rtype==RDWR)
    116 				pchr(f, '>');
    117 			if(t->fd0!=0)
    118 				pfmt(f, "[%d]", t->fd0);
    119 			break;
    120 		case APPEND:
    121 			pchr(f, '>');
    122 		case WRITE:
    123 			pchr(f, '>');
    124 			if(t->fd0!=1)
    125 				pfmt(f, "[%d]", t->fd0);
    126 			break;
    127 		}
    128 		pfmt(f, "%t", c0);
    129 		if(c1)
    130 			pfmt(f, " %t", c1);
    131 		break;
    132 	case '=':
    133 		pfmt(f, "%t=%t", c0, c1);
    134 		if(c2)
    135 			pfmt(f, " %t", c2);
    136 		break;
    137 	case PIPE:
    138 		pfmt(f, "%t|", c0);
    139 		if(t->fd1==0){
    140 			if(t->fd0!=1)
    141 				pfmt(f, "[%d]", t->fd0);
    142 		}
    143 		else pfmt(f, "[%d=%d]", t->fd0, t->fd1);
    144 		pfmt(f, "%t", c1);
    145 		break;
    146 	}
    147 }