here.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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 "rc.h"
  10. #include "exec.h"
  11. #include "io.h"
  12. #include "fns.h"
  13. struct here *here, **ehere;
  14. int ser = 0;
  15. char tmp[] = "/tmp/here0000.0000";
  16. char hex[] = "0123456789abcdef";
  17. void psubst(io*, uint8_t*);
  18. void pstrs(io*, word*);
  19. void
  20. hexnum(char *p, int n)
  21. {
  22. *p++ = hex[(n>>12)&0xF];
  23. *p++ = hex[(n>>8)&0xF];
  24. *p++ = hex[(n>>4)&0xF];
  25. *p = hex[n&0xF];
  26. }
  27. tree*
  28. heredoc(tree *tag)
  29. {
  30. struct here *h = new(struct here);
  31. if(tag->type != WORD)
  32. yyerror("Bad here tag");
  33. h->next = 0;
  34. if(here)
  35. *ehere = h;
  36. else
  37. here = h;
  38. ehere = &h->next;
  39. h->tag = tag;
  40. hexnum(&tmp[9], getpid());
  41. hexnum(&tmp[14], ser++);
  42. h->name = strdup(tmp);
  43. return token(tmp, WORD);
  44. }
  45. /*
  46. * bug: lines longer than NLINE get split -- this can cause spurious
  47. * missubstitution, or a misrecognized EOF marker.
  48. */
  49. #define NLINE 4096
  50. void
  51. readhere(void)
  52. {
  53. int c, subst;
  54. char *s, *tag;
  55. char line[NLINE+1];
  56. io *f;
  57. struct here *h, *nexth;
  58. for(h = here; h; h = nexth){
  59. subst = !h->tag->quoted;
  60. tag = h->tag->str;
  61. c = Creat(h->name);
  62. if(c < 0)
  63. yyerror("can't create here document");
  64. f = openfd(c);
  65. s = line;
  66. pprompt();
  67. while((c = rchr(runq->cmdfd)) != EOF){
  68. if(c == '\n' || s == &line[NLINE]){
  69. *s = '\0';
  70. if(tag && strcmp(line, tag) == 0)
  71. break;
  72. if(subst)
  73. psubst(f, (uint8_t *)line);
  74. else
  75. pstr(f, line);
  76. s = line;
  77. if(c == '\n'){
  78. pprompt();
  79. pchr(f, c);
  80. }else
  81. *s++ = c;
  82. }else
  83. *s++ = c;
  84. }
  85. flush(f);
  86. closeio(f);
  87. cleanhere(h->name);
  88. nexth = h->next;
  89. efree((char *)h);
  90. }
  91. here = 0;
  92. doprompt = 1;
  93. }
  94. void
  95. psubst(io *f, uint8_t *s)
  96. {
  97. int savec, n;
  98. uint8_t *t, *u;
  99. Rune r;
  100. word *star;
  101. while(*s){
  102. if(*s != '$'){ /* copy plain text rune */
  103. if(*s < Runeself)
  104. pchr(f, *s++);
  105. else{
  106. n = chartorune(&r, (char *)s);
  107. while(n-- > 0)
  108. pchr(f, *s++);
  109. }
  110. }else{ /* $something -- perform substitution */
  111. t = ++s;
  112. if(*t == '$')
  113. pchr(f, *t++);
  114. else{
  115. while(*t && idchr(*t))
  116. t++;
  117. savec = *t;
  118. *t = '\0';
  119. n = 0;
  120. for(u = s; *u && '0' <= *u && *u <= '9'; u++)
  121. n = n*10 + *u - '0';
  122. if(n && *u == '\0'){
  123. star = vlook("*")->val;
  124. if(star && 1 <= n && n <= count(star)){
  125. while(--n)
  126. star = star->next;
  127. pstr(f, star->word);
  128. }
  129. }else
  130. pstrs(f, vlook((char *)s)->val);
  131. *t = savec;
  132. if(savec == '^')
  133. t++;
  134. }
  135. s = t;
  136. }
  137. }
  138. }
  139. void
  140. pstrs(io *f, word *a)
  141. {
  142. if(a){
  143. while(a->next && a->next->word){
  144. pstr(f, a->word);
  145. pchr(f, ' ');
  146. a = a->next;
  147. }
  148. pstr(f, a->word);
  149. }
  150. }