| word.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
| git clone git://git.suckless.org/9base | |
| Log | |
| Files | |
| Refs | |
| README | |
| 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… | |
| 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",… | |
| 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 } |