123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- #include "mk.h"
- static Word *nextword(char**);
- Word*
- newword(char *s)
- {
- Word *w;
- w = (Word *)Malloc(sizeof(Word));
- w->s = strdup(s);
- w->next = 0;
- return(w);
- }
- Word *
- stow(char *s)
- {
- Word *head, *w, *new;
- w = head = 0;
- while(*s){
- new = nextword(&s);
- if(new == 0)
- break;
- if (w)
- w->next = new;
- else
- head = w = new;
- while(w->next)
- w = w->next;
-
- }
- if (!head)
- head = newword("");
- return(head);
- }
- char *
- wtos(Word *w, int sep)
- {
- Bufblock *buf;
- char *cp;
- buf = newbuf();
- for(; w; w = w->next){
- for(cp = w->s; *cp; cp++)
- insert(buf, *cp);
- if(w->next)
- insert(buf, sep);
- }
- insert(buf, 0);
- cp = strdup(buf->start);
- freebuf(buf);
- return(cp);
- }
- Word*
- wdup(Word *w)
- {
- Word *v, *new, *base;
- v = base = 0;
- while(w){
- new = newword(w->s);
- if(v)
- v->next = new;
- else
- base = new;
- v = new;
- w = w->next;
- }
- return base;
- }
- void
- delword(Word *w)
- {
- Word *v;
- while(v = w){
- w = w->next;
- if(v->s)
- free(v->s);
- free(v);
- }
- }
- /*
- * break out a word from a string handling quotes, executions,
- * and variable expansions.
- */
- static Word*
- nextword(char **s)
- {
- Bufblock *b;
- Word *head, *tail, *w;
- Rune r;
- char *cp;
- int empty;
- cp = *s;
- b = newbuf();
- restart:
- head = tail = 0;
- while(*cp == ' ' || *cp == '\t') /* leading white space */
- cp++;
- empty = 1;
- while(*cp){
- cp += chartorune(&r, cp);
- switch(r)
- {
- case ' ':
- case '\t':
- case '\n':
- goto out;
- case '\\':
- case '\'':
- case '"':
- empty = 0;
- cp = expandquote(cp, r, b);
- if(cp == 0){
- fprint(2, "missing closing quote: %s\n", *s);
- Exit();
- }
- break;
- case '$':
- w = varsub(&cp);
- if(w == 0){
- if(empty)
- goto restart;
- break;
- }
- empty = 0;
- if(b->current != b->start){
- bufcpy(b, w->s, strlen(w->s));
- insert(b, 0);
- free(w->s);
- w->s = strdup(b->start);
- b->current = b->start;
- }
- if(head){
- bufcpy(b, tail->s, strlen(tail->s));
- bufcpy(b, w->s, strlen(w->s));
- insert(b, 0);
- free(tail->s);
- tail->s = strdup(b->start);
- tail->next = w->next;
- free(w->s);
- free(w);
- b->current = b->start;
- } else
- tail = head = w;
- while(tail->next)
- tail = tail->next;
- break;
- default:
- empty = 0;
- rinsert(b, r);
- break;
- }
- }
- out:
- *s = cp;
- if(b->current != b->start){
- if(head){
- cp = b->current;
- bufcpy(b, tail->s, strlen(tail->s));
- bufcpy(b, b->start, cp-b->start);
- insert(b, 0);
- free(tail->s);
- tail->s = strdup(cp);
- } else {
- insert(b, 0);
- head = newword(b->start);
- }
- }
- freebuf(b);
- return head;
- }
- void
- dumpw(char *s, Word *w)
- {
- Bprint(&bout, "%s", s);
- for(; w; w = w->next)
- Bprint(&bout, " '%s'", w->s);
- Bputc(&bout, '\n');
- }
|