word.c 3.0 KB

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