Blob
1 #include "mk.h"3 static Word *nextword(char**);5 Word*6 newword(char *s)7 {8 Word *w;10 w = (Word *)Malloc(sizeof(Word));11 w->s = strdup(s);12 w->next = 0;13 return(w);14 }16 Word *17 stow(char *s)18 {19 Word *head, *w, *new;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 else29 head = w = new;30 while(w->next)31 w = w->next;33 }34 if (!head)35 head = newword("");36 return(head);37 }39 char *40 wtos(Word *w, int sep)41 {42 Bufblock *buf;43 char *cp;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 }58 Word*59 wdup(Word *w)60 {61 Word *v, *new, *base;63 v = base = 0;64 while(w){65 new = newword(w->s);66 if(v)67 v->next = new;68 else69 base = new;70 v = new;71 w = w->next;72 }73 return base;74 }76 void77 delword(Word *w)78 {79 Word *v;81 while(v = w){82 w = w->next;83 if(v->s)84 free(v->s);85 free(v);86 }87 }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;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 } else153 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 }182 void183 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 }