URI: 
       shprint.c - 9base - revived minimalist port of Plan 9 userland to Unix
  HTML git clone git://git.suckless.org/9base
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR 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 }