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

sh.c

#include    "mk.h"

/*
 *    This file contains functions that depend on the shell's syntax.  Most
 *    of the routines extract strings observing the shell's escape conventions.
 */


/*
 *    skip a token in quotes.
 */
static char *
squote(char *cp, int c)
{
      Rune r;
      int n;

      while(*cp){
            n = chartorune(&r, cp);
            if(r == c)
                  return cp;
            if(r == '\\')
                  n += chartorune(&r, cp+n);
            cp += n;
      }
      SYNERR(-1);       /* should never occur */
      fprint(2, "missing closing '\n");
      return 0;
}
/*
 *    search a string for unescaped characters in a pattern set
 */
static char *
shcharin(char *cp, char *pat)
{
      Rune r;
      int n, vargen;

      vargen = 0;
      while(*cp){
            n = chartorune(&r, cp);
            switch(r){
            case '\\':              /* skip escaped char */
                  cp += n;
                  n = chartorune(&r, cp);
                  break;
            case '\'':              /* skip quoted string */
            case '"':
                  cp = squote(cp+1, r);   /* 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.
 */
static char*
shexpandquote(char *s, Rune esc, Bufblock *b)
{
      Rune r;

      if (esc == '\\') {
            s += chartorune(&r, s);
            rinsert(b, r);
            return s;
      }

      while(*s){
            s += chartorune(&r, s);
            if(r == esc)
                  return s;
            if (r == '\\') {
                  rinsert(b, r);
                  s += chartorune(&r, s);
            }
            rinsert(b, r);
      }
      return 0;
}

/*
 *    Input an escaped token.  Possible escape chars are single-quote,
 *    double-quote and backslash.
 */
static int
shescapetoken(Biobuf *bp, Bufblock *buf, int preserve, int esc)
{
      int c, line;

      if(esc == '\\') {
            c = Bgetrune(bp);
            if(c == '\r')
                  c = Bgetrune(bp);
            if (c == '\n')
                  mkinline++;
            rinsert(buf, c);
            return 1;
      }

      line = mkinline;
      while((c = nextrune(bp, 0)) >= 0){
            if(c == esc){
                  if(preserve)
                        rinsert(buf, c);
                  return 1;
            }
            if(c == '\\') {
                  rinsert(buf, c);
                  c = Bgetrune(bp);
                  if(c == '\r')
                        c = Bgetrune(bp);
                  if (c < 0)
                        break;
                  if (c == '\n')
                        mkinline++;
            }
            rinsert(buf, c);
      }
      SYNERR(line); fprint(2, "missing closing %c\n", esc);
      return 0;
}

/*
 *    copy a quoted string; s points to char after opening quote
 */
static char *
copysingle(char *s, Rune q, Bufblock *buf)
{
      Rune r;

      while(*s){
            s += chartorune(&r, s);
            rinsert(buf, r);
            if(r == q)
                  break;
      }
      return s;
}
/*
 *    check for quoted strings.  backquotes are handled here; single quotes above.
 *    s points to char after opening quote, q.
 */
static char *
shcopyq(char *s, Rune q, Bufblock *buf)
{
      if(q == '\'' || q == '"')           /* copy quoted string */
            return copysingle(s, q, buf);

      if(q != '`')                        /* not quoted */
            return s;

      while(*s){                    /* copy backquoted string */
            s += chartorune(&q, s);
            rinsert(buf, q);
            if(q == '`')
                  break;
            if(q == '\'' || q == '"')
                  s = copysingle(s, q, buf);    /* copy quoted string */
      }
      return s;
}

static int
shmatchname(char *name)
{
      USED(name);

      return 1;
}


Shell shshell = {
      "sh",
      "\"'= \t",  /*used in parse.c to isolate assignment attribute*/
      ' ',  /* inter-word separator in env */
      shcharin,
      shexpandquote,
      shescapetoken,
      shcopyq,
      shmatchname,
};


Generated by  Doxygen 1.6.0   Back to index