plan9fox/sys/src/cmd/mk/rc.c
2011-03-30 19:35:09 +03:00

176 lines
3.1 KiB
C

#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;
}