here.c 2.4 KB

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