here.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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. struct here *h, *nexth;
  46. io *f;
  47. char *s, *tag;
  48. int c, subst;
  49. char line[NLINE+1];
  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) break;
  63. if(subst)
  64. psubst(f, (uchar *)line);
  65. else
  66. pstr(f, line);
  67. s = line;
  68. if(c=='\n'){
  69. pprompt();
  70. pchr(f, c);
  71. }
  72. else *s++=c;
  73. }
  74. else *s++=c;
  75. }
  76. flush(f);
  77. closeio(f);
  78. cleanhere(h->name);
  79. nexth = h->next;
  80. efree((char *)h);
  81. }
  82. here = 0;
  83. doprompt = 1;
  84. }
  85. void
  86. psubst(io *f, uchar *s)
  87. {
  88. int savec, n;
  89. uchar *t, *u;
  90. word *star;
  91. while(*s){
  92. if(*s!='$'){
  93. if(0xa0 <= *s && *s <= 0xf5){
  94. pchr(f, *s++);
  95. if(*s=='\0')
  96. break;
  97. }
  98. else if(0xf6 <= *s && *s <= 0xf7){
  99. pchr(f, *s++);
  100. if(*s=='\0')
  101. break;
  102. pchr(f, *s++);
  103. if(*s=='\0')
  104. break;
  105. }
  106. pchr(f, *s++);
  107. }
  108. else{
  109. t=++s;
  110. if(*t=='$')
  111. pchr(f, *t++);
  112. else{
  113. while(*t && idchr(*t)) t++;
  114. savec=*t;
  115. *t='\0';
  116. n = 0;
  117. for(u = s;*u && '0'<=*u && *u<='9';u++) n = n*10+*u-'0';
  118. if(n && *u=='\0'){
  119. star = vlook("*")->val;
  120. if(star && 1<=n && n<=count(star)){
  121. while(--n) star = star->next;
  122. pstr(f, star->word);
  123. }
  124. }
  125. else
  126. pstrs(f, vlook((char *)s)->val);
  127. *t = savec;
  128. if(savec=='^')
  129. t++;
  130. }
  131. s = t;
  132. }
  133. }
  134. }
  135. void
  136. pstrs(io *f, word *a)
  137. {
  138. if(a){
  139. while(a->next && a->next->word){
  140. pstr(f, a->word);
  141. pchr(f, ' ');
  142. a = a->next;
  143. }
  144. pstr(f, a->word);
  145. }
  146. }