here.c 2.5 KB

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