ref: d0ae2e369e0221e796f4b58255b21ce3592d80dc
dir: /sys/src/cmd/mk/rc.c/
#include "mk.h" char termchars[] = "'= \t"; /*used in parse.c to isolate assignment attribute*/ /* * This file contains functions that depend on rc's syntax. Most * of the routines extract strings observing rc's escape conventions */ /* * skip a token in single quotes. */ static char * squote(char *cp) { Rune r; int n; while(*cp){ n = chartorune(&r, cp); if(r == '\'') { n += chartorune(&r, cp+n); if(r != '\'') return(cp); } cp += n; } SYNERR(-1); /* should never occur */ fprint(2, "missing closing '\n"); return 0; } /* * search a string for characters in a pattern set * characters in quotes and variable generators are escaped */ char * charin(char *cp, char *pat) { Rune r; int n, vargen; vargen = 0; while(*cp){ n = chartorune(&r, cp); switch(r){ case '\'': /* skip quoted string */ cp = squote(cp+1); /* n must = 1 */ if(!cp) return 0; break; case '$': if(*(cp+1) == '{') vargen = 1; break; case '}': if(vargen) vargen = 0; else if(utfrune(pat, r)) return cp; break; default: if(vargen == 0 && utfrune(pat, r)) return cp; break; } cp += n; } if(vargen){ SYNERR(-1); fprint(2, "missing closing } in pattern generator\n"); } return 0; } /* * extract an escaped token. Possible escape chars are single-quote, * double-quote,and backslash. Only the first is valid for rc. the * others are just inserted into the receiving buffer. */ char* expandquote(char *s, Rune r, Bufblock *b) { if (r != '\'') { rinsert(b, r); return s; } while(*s){ s += chartorune(&r, s); if(r == '\'') { if(*s == '\'') s++; else return s; } rinsert(b, r); } return 0; } /* * Input an escaped token. Possible escape chars are single-quote, * double-quote and backslash. Only the first is a valid escape for * rc; the others are just inserted into the receiving buffer. */ int escapetoken(Biobuf *bp, Bufblock *buf, int preserve, int esc) { int c, line; if(esc != '\'') return 1; line = mkinline; while((c = nextrune(bp, 0)) > 0){ if(c == '\''){ if(preserve) rinsert(buf, c); c = Bgetrune(bp); if (c < 0) break; if(c != '\''){ Bungetrune(bp); return 1; } } rinsert(buf, c); } SYNERR(line); fprint(2, "missing closing %c\n", esc); return 0; } /* * copy a single-quoted string; s points to char after opening quote */ static char * copysingle(char *s, Bufblock *buf) { Rune r; while(*s){ s += chartorune(&r, s); rinsert(buf, r); if(r == '\'') break; } return s; } /* * check for quoted strings. backquotes are handled here; single quotes above. * s points to char after opening quote, q. */ char * copyq(char *s, Rune q, Bufblock *buf) { if(q == '\'') /* copy quoted string */ return copysingle(s, buf); if(q != '`') /* not quoted */ return s; while(*s){ /* copy backquoted string */ s += chartorune(&q, s); rinsert(buf, q); if(q == '}') break; if(q == '\'') s = copysingle(s, buf); /* copy quoted string */ } return s; } static int needquotes(char *s) { Rune r; if(*s == 0) return 1; while(*s){ s += chartorune(&r, s); if(needsrcquote(r)) return 1; } return 0; } /* * append string s into buffer buf with rc quoting as neccessary. */ void bufcpyq(Bufblock *buf, char *s) { Rune r; if(!needquotes(s)){ bufcpy(buf, s); return; } insert(buf, '\''); while(*s){ s += chartorune(&r, s); if(r == '\'') rinsert(buf, r); rinsert(buf, r); } insert(buf, '\''); }