9base

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

shprint.c (1963B)


      1 #include	"mk.h"
      2 
      3 static char *vexpand(char*, Envy*, Bufblock*);
      4 
      5 #define getfields mkgetfields
      6 
      7 static int
      8 getfields(char *str, char **args, int max, int mflag, char *set)
      9 {
     10 	Rune r;
     11 	int nr, intok, narg;
     12 
     13 	if(max <= 0)
     14 		return 0;
     15 
     16 	narg = 0;
     17 	args[narg] = str;
     18 	if(!mflag)
     19 		narg++;
     20 	intok = 0;
     21 	for(;; str += nr) {
     22 		nr = chartorune(&r, str);
     23 		if(r == 0)
     24 			break;
     25 		if(utfrune(set, r)) {
     26 			if(narg >= max)
     27 				break;
     28 			*str = 0;
     29 			intok = 0;
     30 			args[narg] = str + nr;
     31 			if(!mflag)
     32 				narg++;
     33 		} else {
     34 			if(!intok && mflag)
     35 				narg++;
     36 			intok = 1;
     37 		}
     38 	}
     39 	return narg;
     40 }
     41 
     42 void
     43 shprint(char *s, Envy *env, Bufblock *buf, Shell *sh)
     44 {
     45 	int n;
     46 	Rune r;
     47 
     48 	while(*s) {
     49 		n = chartorune(&r, s);
     50 		if (r == '$')
     51 			s = vexpand(s, env, buf);
     52 		else {
     53 			rinsert(buf, r);
     54 			s += n;
     55 			s = sh->copyq(s, r, buf);	/*handle quoted strings*/
     56 		}
     57 	}
     58 	insert(buf, 0);
     59 }
     60 
     61 static char *
     62 mygetenv(char *name, Envy *env)
     63 {
     64 	if (!env)
     65 		return 0;
     66 	if (symlook(name, S_WESET, 0) == 0 && symlook(name, S_INTERNAL, 0) == 0)
     67 		return 0;
     68 		/* only resolve internal variables and variables we've set */
     69 	for(; env->name; env++){
     70 		if (strcmp(env->name, name) == 0)
     71 			return wtos(env->values, ' ');
     72 	}
     73 	return 0;
     74 }
     75 
     76 static char *
     77 vexpand(char *w, Envy *env, Bufblock *buf)
     78 {
     79 	char *s, carry, *p, *q;
     80 
     81 	assert("vexpand no $", *w == '$');
     82 	p = w+1;	/* skip dollar sign */
     83 	if(*p == '{') {
     84 		p++;
     85 		q = utfrune(p, '}');
     86 		if (!q)
     87 			q = strchr(p, 0);
     88 	} else
     89 		q = shname(p);
     90 	carry = *q;
     91 	*q = 0;
     92 	s = mygetenv(p, env);
     93 	*q = carry;
     94 	if (carry == '}')
     95 		q++;
     96 	if (s) {
     97 		bufcpy(buf, s, strlen(s));
     98 		free(s);
     99 	} else 		/* copy name intact*/
    100 		bufcpy(buf, w, q-w);
    101 	return(q);
    102 }
    103 
    104 void
    105 front(char *s)
    106 {
    107 	char *t, *q;
    108 	int i, j;
    109 	char *flds[512];
    110 
    111 	q = strdup(s);
    112 	i = getfields(q, flds, 512, 0, " \t\n");
    113 	if(i > 5){
    114 		flds[4] = flds[i-1];
    115 		flds[3] = "...";
    116 		i = 5;
    117 	}
    118 	t = s;
    119 	for(j = 0; j < i; j++){
    120 		for(s = flds[j]; *s; *t++ = *s++);
    121 		*t++ = ' ';
    122 	}
    123 	*t = 0;
    124 	free(q);
    125 }