#include "mk.h" char *termchars = "'= \t"; /*used in parse.c to isolate assignment attribute*/char *shflags = "-I"; /* rc flag to force non-interactive mode */int IWS = '\1'; /* inter-word separator in env - not used in plan 9 */ /* * 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. */intescapetoken(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;}
#include "mk.h"
char *termchars = "'= \t"; /*used in parse.c to isolate assignment attribute*/
char *shflags = "-I"; /* rc flag to force non-interactive mode */
int IWS = '\1'; /* inter-word separator in env - not used in plan 9 */
/*
* 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;
}