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;101 cp = *s;102 b = newbuf();103 head = tail = 0;104 while(*cp == ' ' || *cp == '\t') /* leading white space */105 cp++;106 while(*cp){107 cp += chartorune(&r, cp);108 switch(r)109 {110 case ' ':111 case '\t':112 case '\n':113 goto out;114 case '\\':115 case '\'':116 case '"':117 cp = expandquote(cp, r, b);118 if(cp == 0){119 fprint(2, "missing closing quote: %s\n", *s);120 Exit();121 }122 break;123 case '$':124 w = varsub(&cp);125 if(w == 0)126 break;127 if(b->current != b->start){128 bufcpy(b, w->s, strlen(w->s));129 insert(b, 0);130 free(w->s);131 w->s = strdup(b->start);132 b->current = b->start;133 }134 if(head){135 bufcpy(b, tail->s, strlen(tail->s));136 bufcpy(b, w->s, strlen(w->s));137 insert(b, 0);138 free(tail->s);139 tail->s = strdup(b->start);140 tail->next = w->next;141 free(w->s);142 free(w);143 b->current = b->start;144 } else145 tail = head = w;146 while(tail->next)147 tail = tail->next;148 break;149 default:150 rinsert(b, r);151 break;152 }153 }154 out:155 *s = cp;156 if(b->current != b->start){157 if(head){158 cp = b->current;159 bufcpy(b, tail->s, strlen(tail->s));160 bufcpy(b, b->start, cp-b->start);161 insert(b, 0);162 free(tail->s);163 tail->s = strdup(cp);164 } else {165 insert(b, 0);166 head = newword(b->start);167 }168 }169 freebuf(b);170 return head;171 }173 void174 dumpw(char *s, Word *w)175 {176 Bprint(&bout, "%s", s);177 for(; w; w = w->next)178 Bprint(&bout, " '%s'", w->s);179 Bputc(&bout, '\n');180 }