Logo Search packages:      
Sourcecode: 9base version File versions  Download package

rc.c

#include    "mk.h"

/*
 *    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 *
rccharin(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*
rcexpandquote(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
rcescapetoken(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 *
rccopyq(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
rcmatchname(char *name)
{
      char *p;

      if((p = strchr(name, '/')) != nil)
            name = p+1;
      if(name[0] == 'r' && name[1] == 'c')
            return 1;
      return 0;
}

Shell rcshell = {
      "rc",
      "'= \t",
      '\1',
      rccharin,
      rcexpandquote,
      rcescapetoken,
      rccopyq,
      rcmatchname,
};

Generated by  Doxygen 1.6.0   Back to index