rc.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #include "mk.h"
  2. char *termchars = "'= \t"; /*used in parse.c to isolate assignment attribute*/
  3. char *shflags = "-I"; /* rc flag to force non-interactive mode */
  4. int IWS = '\1'; /* inter-word separator in env - not used in plan 9 */
  5. /*
  6. * This file contains functions that depend on rc's syntax. Most
  7. * of the routines extract strings observing rc's escape conventions
  8. */
  9. /*
  10. * skip a token in single quotes.
  11. */
  12. static char *
  13. squote(char *cp)
  14. {
  15. Rune r;
  16. int n;
  17. while(*cp){
  18. n = chartorune(&r, cp);
  19. if(r == '\'') {
  20. n += chartorune(&r, cp+n);
  21. if(r != '\'')
  22. return(cp);
  23. }
  24. cp += n;
  25. }
  26. SYNERR(-1); /* should never occur */
  27. fprint(2, "missing closing '\n");
  28. return 0;
  29. }
  30. /*
  31. * search a string for characters in a pattern set
  32. * characters in quotes and variable generators are escaped
  33. */
  34. char *
  35. charin(char *cp, char *pat)
  36. {
  37. Rune r;
  38. int n, vargen;
  39. vargen = 0;
  40. while(*cp){
  41. n = chartorune(&r, cp);
  42. switch(r){
  43. case '\'': /* skip quoted string */
  44. cp = squote(cp+1); /* n must = 1 */
  45. if(!cp)
  46. return 0;
  47. break;
  48. case '$':
  49. if(*(cp+1) == '{')
  50. vargen = 1;
  51. break;
  52. case '}':
  53. if(vargen)
  54. vargen = 0;
  55. else if(utfrune(pat, r))
  56. return cp;
  57. break;
  58. default:
  59. if(vargen == 0 && utfrune(pat, r))
  60. return cp;
  61. break;
  62. }
  63. cp += n;
  64. }
  65. if(vargen){
  66. SYNERR(-1);
  67. fprint(2, "missing closing } in pattern generator\n");
  68. }
  69. return 0;
  70. }
  71. /*
  72. * extract an escaped token. Possible escape chars are single-quote,
  73. * double-quote,and backslash. Only the first is valid for rc. the
  74. * others are just inserted into the receiving buffer.
  75. */
  76. char*
  77. expandquote(char *s, Rune r, Bufblock *b)
  78. {
  79. if (r != '\'') {
  80. rinsert(b, r);
  81. return s;
  82. }
  83. while(*s){
  84. s += chartorune(&r, s);
  85. if(r == '\'') {
  86. if(*s == '\'')
  87. s++;
  88. else
  89. return s;
  90. }
  91. rinsert(b, r);
  92. }
  93. return 0;
  94. }
  95. /*
  96. * Input an escaped token. Possible escape chars are single-quote,
  97. * double-quote and backslash. Only the first is a valid escape for
  98. * rc; the others are just inserted into the receiving buffer.
  99. */
  100. int
  101. escapetoken(Biobuf *bp, Bufblock *buf, int preserve, int esc)
  102. {
  103. int c, line;
  104. if(esc != '\'')
  105. return 1;
  106. line = mkinline;
  107. while((c = nextrune(bp, 0)) > 0){
  108. if(c == '\''){
  109. if(preserve)
  110. rinsert(buf, c);
  111. c = Bgetrune(bp);
  112. if (c < 0)
  113. break;
  114. if(c != '\''){
  115. Bungetrune(bp);
  116. return 1;
  117. }
  118. }
  119. rinsert(buf, c);
  120. }
  121. SYNERR(line); fprint(2, "missing closing %c\n", esc);
  122. return 0;
  123. }
  124. /*
  125. * copy a single-quoted string; s points to char after opening quote
  126. */
  127. static char *
  128. copysingle(char *s, Bufblock *buf)
  129. {
  130. Rune r;
  131. while(*s){
  132. s += chartorune(&r, s);
  133. rinsert(buf, r);
  134. if(r == '\'')
  135. break;
  136. }
  137. return s;
  138. }
  139. /*
  140. * check for quoted strings. backquotes are handled here; single quotes above.
  141. * s points to char after opening quote, q.
  142. */
  143. char *
  144. copyq(char *s, Rune q, Bufblock *buf)
  145. {
  146. if(q == '\'') /* copy quoted string */
  147. return copysingle(s, buf);
  148. if(q != '`') /* not quoted */
  149. return s;
  150. while(*s){ /* copy backquoted string */
  151. s += chartorune(&q, s);
  152. rinsert(buf, q);
  153. if(q == '}')
  154. break;
  155. if(q == '\'')
  156. s = copysingle(s, buf); /* copy quoted string */
  157. }
  158. return s;
  159. }