URI: 
       word.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
       ---
       word.c (2717B)
       ---
            1 #include        "mk.h"
            2 
            3 static        Word        *nextword(char**);
            4 
            5 Word*
            6 newword(char *s)
            7 {
            8         Word *w;
            9 
           10         w = (Word *)Malloc(sizeof(Word));
           11         w->s = strdup(s);
           12         w->next = 0;
           13         return(w);
           14 }
           15 
           16 Word *
           17 stow(char *s)
           18 {
           19         Word *head, *w, *new;
           20 
           21         w = head = 0;
           22         while(*s){
           23                 new = nextword(&s);
           24                 if(new == 0)
           25                         break;
           26                 if (w)
           27                         w->next = new;
           28                 else
           29                         head = w = new;
           30                 while(w->next)
           31                         w = w->next;
           32                 
           33         }
           34         if (!head)
           35                 head = newword("");
           36         return(head);
           37 }
           38 
           39 char *
           40 wtos(Word *w, int sep)
           41 {
           42         Bufblock *buf;
           43         char *cp;
           44 
           45         buf = newbuf();
           46         for(; w; w = w->next){
           47                 for(cp = w->s; *cp; cp++)
           48                         insert(buf, *cp);
           49                 if(w->next)
           50                         insert(buf, sep);
           51         }
           52         insert(buf, 0);
           53         cp = strdup(buf->start);
           54         freebuf(buf);
           55         return(cp);
           56 }
           57 
           58 Word*
           59 wdup(Word *w)
           60 {
           61         Word *v, *new, *base;
           62 
           63         v = base = 0;
           64         while(w){
           65                 new = newword(w->s);
           66                 if(v)
           67                         v->next = new;
           68                 else
           69                         base = new;
           70                 v = new;
           71                 w = w->next;
           72         }
           73         return base;
           74 }
           75 
           76 void
           77 delword(Word *w)
           78 {
           79         Word *v;
           80 
           81         while(v = w){
           82                 w = w->next;
           83                 if(v->s)
           84                         free(v->s);
           85                 free(v);
           86         }
           87 }
           88 
           89 /*
           90  *        break out a word from a string handling quotes, executions,
           91  *        and variable expansions.
           92  */
           93 static Word*
           94 nextword(char **s)
           95 {
           96         Bufblock *b;
           97         Word *head, *tail, *w;
           98         Rune r;
           99         char *cp;
          100         int empty;
          101 
          102         cp = *s;
          103         b = newbuf();
          104 restart:
          105         head = tail = 0;
          106         while(*cp == ' ' || *cp == '\t')                /* leading white space */
          107                 cp++;
          108         empty = 1;
          109         while(*cp){
          110                 cp += chartorune(&r, cp);
          111                 switch(r)
          112                 {
          113                 case ' ':
          114                 case '\t':
          115                 case '\n':
          116                         goto out;
          117                 case '\\':
          118                 case '\'':
          119                 case '"':
          120                         empty = 0;
          121                         cp = shellt->expandquote(cp, r, b);
          122                         if(cp == 0){
          123                                 fprint(2, "missing closing quote: %s\n", *s);
          124                                 Exit();
          125                         }
          126                         break;
          127                 case '$':
          128                         w = varsub(&cp);
          129                         if(w == 0){
          130                                 if(empty)
          131                                         goto restart;
          132                                 break;
          133                         }
          134                         empty = 0;
          135                         if(b->current != b->start){
          136                                 bufcpy(b, w->s, strlen(w->s));
          137                                 insert(b, 0);
          138                                 free(w->s);
          139                                 w->s = strdup(b->start);
          140                                 b->current = b->start;
          141                         }
          142                         if(head){
          143                                 bufcpy(b, tail->s, strlen(tail->s));
          144                                 bufcpy(b, w->s, strlen(w->s));
          145                                 insert(b, 0);
          146                                 free(tail->s);
          147                                 tail->s = strdup(b->start);
          148                                 tail->next = w->next;
          149                                 free(w->s);
          150                                 free(w);
          151                                 b->current = b->start;
          152                         } else
          153                                 tail = head = w;
          154                         while(tail->next)
          155                                 tail = tail->next;
          156                         break;
          157                 default:
          158                         empty = 0;
          159                         rinsert(b, r);
          160                         break;
          161                 }
          162         }
          163 out:
          164         *s = cp;
          165         if(b->current != b->start){
          166                 if(head){
          167                         cp = b->current;
          168                         bufcpy(b, tail->s, strlen(tail->s));
          169                         bufcpy(b, b->start, cp-b->start);
          170                         insert(b, 0);
          171                         free(tail->s);
          172                         tail->s = strdup(cp);
          173                 } else {
          174                         insert(b, 0);
          175                         head = newword(b->start);
          176                 }
          177         }
          178         freebuf(b);
          179         return head;
          180 }
          181 
          182 void
          183 dumpw(char *s, Word *w)
          184 {
          185         Bprint(&bout, "%s", s);
          186         for(; w; w = w->next)
          187                 Bprint(&bout, " '%s'", w->s);
          188         Bputc(&bout, '\n');
          189 }