Пример #1
0
static int read_pattern (lua_State *L, FILE *f, const char *p) {
  int inskip = 0;  /* {skip} level */
  int c = NEED_OTHER;
  luaL_Buffer b;
  luaL_buffinit(L, &b);
  while (*p != '\0') {
    switch (*p) {
      case '{':
        inskip++;
        p++;
        continue;
      case '}':
        if (!inskip) lua_error(L, "unbalanced braces in read pattern");
        inskip--;
        p++;
        continue;
      default: {
        const char *ep = luaI_classend(L, p);  /* get what is next */
        int m;  /* match result */
        if (c == NEED_OTHER) c = getc(f);
        m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep);
        if (m) {
          if (!inskip) luaL_putchar(&b, c);
          c = NEED_OTHER;
        }
        switch (*ep) {
          case '+':  /* repetition (1 or more) */
            if (!m) goto break_while;  /* pattern fails? */
            /* else go through */
          case '*':  /* repetition (0 or more) */
            while (m) {  /* reads the same item until it fails */
              c = getc(f);
              m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep);
              if (m && !inskip) luaL_putchar(&b, c);
            }
            /* go through to continue reading the pattern */
          case '?':  /* optional */
            p = ep+1;  /* continues reading the pattern */
            continue;
          default:
            if (!m) goto break_while;  /* pattern fails? */
            p = ep;  /* else continues reading the pattern */
        }
      }
    }
  } break_while:
  if (c != NEED_OTHER) ungetc(c, f);
  luaL_pushresult(&b);  /* close buffer */
  return (*p == '\0');
}
Пример #2
0
static const char *matchitem (const char *s, const char *p, struct Capture *cap, const char **ep)
{
  if (*p == ESC) {
    p++;
    if (isdigit((byte)*p)) {  /* capture */
      int32 l = check_cap(*p, cap);
      int32 len = cap->capture[l].len;
      *ep = p+1;
      if (cap->src_end-s >= len && memcmp(cap->capture[l].init, s, len) == 0)
        return s+len;
      else return NULL;
    }
    else if (*p == 'b') {  /* balanced string */
      p++;
      if (*p == 0 || *(p+1) == 0)
        lua_error("unbalanced pattern");
      *ep = p+2;
      return matchbalance(s, *p, *(p+1), cap);
    }
    else p--;  /* and go through */
  }
  /* "luaI_singlematch" sets "ep" (so must be called even when *s == 0) */
  return (luaI_singlematch((byte)*s, p, ep) && s<cap->src_end) ?
                    s+1 : NULL;
}
Пример #3
0
static void io_read() {
	int32 arg = FIRSTARG;
	LuaFile *f = (LuaFile *)getfileparam(FINPUT, &arg);
	char *buff;
	const char *p = luaL_opt_string(arg, "[^\n]*{\n}");
	int inskip = 0;  // to control {skips}
	int c = NEED_OTHER;
	luaL_resetbuffer();
	while (*p) {
		if (*p == '{') {
			inskip++;
			p++;
		} else if (*p == '}') {
			if (inskip == 0)
				lua_error("unbalanced braces in read pattern");
			inskip--;
			p++;
		} else {
			const char *ep;  // get what is next
			int m;  // match result
			if (c == NEED_OTHER) {
				char z;
				if (f->read(&z, 1) != 1)
					c = EOF;
				else
					c = z;
			}
			m = luaI_singlematch((c == EOF) ? 0 : (char)c, p, &ep);
			if (m) {
				if (inskip == 0)
					luaL_addchar(c);
				c = NEED_OTHER;
			}
			switch (*ep) {
			case '*':  // repetition
				if (!m)
					p = ep + 1;  // else stay in (repeat) the same item
				break;
			case '?':  // optional
				p = ep + 1;  // continues reading the pattern
				break;
			default:
				if (m)
					p = ep;  // continues reading the pattern
				else
					goto break_while;   // pattern fails
			}
		}
	}
break_while:
	if (c >= 0) // not EOF nor NEED_OTHER?
		f->seek(-1, SEEK_CUR);
	luaL_addchar(0);
	buff = luaL_buffer();
	if (*buff != 0 || *p == 0)  // read something or did not fail?
		lua_pushstring(buff);
}
Пример #4
0
static const char *match (lua_State *L, const char *s, const char *p,
                          struct Capture *cap) {
init: /* using goto's to optimize tail recursion */
    switch (*p) {
    case '(':  /* start capture */
        return start_capture(L, s, p, cap);
    case ')':  /* end capture */
        return end_capture(L, s, p, cap);
    case ESC:  /* may be %[0-9] or %b */
        if (isdigit((unsigned char)(*(p+1)))) {  /* capture? */
            s = match_capture(L, s, *(p+1), cap);
            if (s == NULL) return NULL;
            p+=2;
            goto init;  /* else return match(L, s, p+2, cap) */
        }
        else if (*(p+1) == 'b') {  /* balanced string? */
            s = matchbalance(L, s, p+2, cap);
            if (s == NULL) return NULL;
            p+=4;
            goto init;  /* else return match(L, s, p+4, cap); */
        }
        else goto dflt;  /* case default */
    case '\0':  /* end of pattern */
        return s;  /* match succeeded */
    case '$':
        if (*(p+1) == '\0')  /* is the '$' the last char in pattern? */
            return (s == cap->src_end) ? s : NULL;  /* check end of string */
        else goto dflt;
    default:
dflt: {  /* it is a pattern item */
            const char *ep = luaI_classend(L, p);  /* points to what is next */
            int m = s<cap->src_end && luaI_singlematch((unsigned char)*s, p, ep);
            switch (*ep) {
            case '?': {  /* optional */
                const char *res;
                if (m && ((res=match(L, s+1, ep+1, cap)) != NULL))
                    return res;
                p=ep+1;
                goto init;  /* else return match(L, s, ep+1, cap); */
            }
            case '*':  /* 0 or more repetitions */
                return max_expand(L, s, p, ep, cap);
            case '+':  /* 1 or more repetitions */
                return (m ? max_expand(L, s+1, p, ep, cap) : NULL);
            case '-':  /* 0 or more repetitions (minimum) */
                return min_expand(L, s, p, ep, cap);
            default:
                if (!m) return NULL;
                s++;
                p=ep;
                goto init;  /* else return match(L, s+1, ep, cap); */
            }
        }
    }
}
Пример #5
0
static const lua_WChar *min_expand (MatchState *ms, const lua_WChar *s,
                                 const lua_WChar *p, const lua_WChar *ep) {
  for (;;) {
    const lua_WChar *res = match(ms, s, ep+1);
    if (res != NULL)
      return res;
    else if (s<ms->src_end && luaI_singlematch(*s, p, ep))
      s++;  /* try with one more repetition */
    else return NULL;
  }
}
Пример #6
0
static const char *min_expand (lua_State *L, const char *s, const char *p,
                               const char *ep, struct Capture *cap) {
    for (;;) {
        const char *res = match(L, s, ep+1, cap);
        if (res != NULL)
            return res;
        else if (s<cap->src_end && luaI_singlematch((unsigned char)*s, p, ep))
            s++;  /* try with one more repetition */
        else return NULL;
    }
}
Пример #7
0
static const lua_WChar *max_expand (MatchState *ms, const lua_WChar *s,
                                 const lua_WChar *p, const lua_WChar *ep) {
  sint32 i = 0;  /* counts maximum expand for item */
  while ((s+i)<ms->src_end && luaI_singlematch(*(s+i), p, ep))
    i++;
  /* keeps trying to match with the maximum repetitions */
  while (i>=0) {
    const lua_WChar *res = match(ms, (s+i), ep+1);
    if (res) return res;
    i--;  /* else didn't match; reduce 1 repetition to try again */
  }
  return NULL;
}
Пример #8
0
static const char *max_expand (lua_State *L, const char *s, const char *p,
                               const char *ep, struct Capture *cap) {
    long i = 0;  /* counts maximum expand for item */
    while ((s+i)<cap->src_end && luaI_singlematch((unsigned char)*(s+i), p, ep))
        i++;
    /* keeps trying to match with the maximum repetitions */
    while (i>=0) {
        const char *res = match(L, (s+i), ep+1, cap);
        if (res) return res;
        i--;  /* else didn't match; reduce 1 repetition to try again */
    }
    return NULL;
}
Пример #9
0
static const lua_WChar *match (MatchState *ms, const lua_WChar *s, const lua_WChar *p) {
  init: /* using goto's to optimize tail recursion */
  switch (*p) {
    case '(':  /* start capture */
      if (*(p+1) == ')')  /* position capture? */
        return start_capture(ms, s, p+2, CAP_POSITION);
      else
        return start_capture(ms, s, p+1, CAP_UNFINISHED);
    case ')':  /* end capture */
      return end_capture(ms, s, p+1);
    case ESC:  /* may be %[0-9] or %b */
      if (iswdigit(*(p+1))) {  /* capture? */
        s = match_capture(ms, s, *(p+1));
        if (s == NULL) return NULL;
        p+=2; goto init;  /* else return match(ms, s, p+2) */
      }
      else if (*(p+1) == 'b') {  /* balanced string? */
        s = matchbalance(ms, s, p+2);
        if (s == NULL) return NULL;
        p+=4; goto init;  /* else return match(ms, s, p+4); */
      }
      else goto dflt;  /* case default */
    case '\0':  /* end of pattern */
      return s;  /* match succeeded */
    case '$':
      if (*(p+1) == '\0')  /* is the `$' the last char in pattern? */
        return (s == ms->src_end) ? s : NULL;  /* check end of string */
      else goto dflt;
    default: dflt: {  /* it is a pattern item */
      const lua_WChar *ep = luaI_classend(ms, p);  /* points to what is next */
      int m = s<ms->src_end && luaI_singlematch(*s, p, ep);
      switch (*ep) {
        case '?': {  /* optional */
          const lua_WChar *res;
          if (m && ((res=match(ms, s+1, ep+1)) != NULL))
            return res;
          p=ep+1; goto init;  /* else return match(ms, s, ep+1); */
        }
        case '*':  /* 0 or more repetitions */
          return max_expand(ms, s, p, ep);
        case '+':  /* 1 or more repetitions */
          return (m ? max_expand(ms, s+1, p, ep) : NULL);
        case '-':  /* 0 or more repetitions (minimum) */
          return min_expand(ms, s, p, ep);
        default:
          if (!m) return NULL;
          s++; p=ep; goto init;  /* else return match(ms, s+1, ep); */
      }
    }
  }
}
Пример #10
0
Файл: liolib.c Проект: jeske/hz
static void io_read (void)
{
  int arg = FIRSTARG;
  FILE *f = getfileparam(FINPUT, &arg);
  char *buff;
  char *p = luaL_opt_string(arg, "[^\n]*{\n}");
  int inskip = 0;  /* to control {skips} */
  int c = NEED_OTHER;
  luaL_resetbuffer();
  while (*p) {
    if (*p == '{') {
      inskip++;
      p++;
    }
    else if (*p == '}') {
      if (inskip == 0)
        lua_error("unbalanced braces in read pattern");
      inskip--;
      p++;
    }
    else {
      char *ep;  /* get what is next */
      int m;  /* match result */
      if (c == NEED_OTHER) c = getc(f);
      m = luaI_singlematch((c == EOF) ? 0 : (char)c, p, &ep);
      if (m) {
        if (inskip == 0) luaL_addchar(c);
        c = NEED_OTHER;
      }
      switch (*ep) {
        case '*':  /* repetition */
          if (!m) p = ep+1;  /* else stay in (repeat) the same item */
          break;
        case '?':  /* optional */
          p = ep+1;  /* continues reading the pattern */
          break;
        default:
          if (m) p = ep;  /* continues reading the pattern */
          else
            goto break_while;   /* pattern fails */
      }
    }
  } break_while:
  if (c >= 0)  /* not EOF nor NEED_OTHER? */
     ungetc(c, f);
  luaL_addchar(0);
  buff = luaL_buffer();
  if (*buff != 0 || *p == 0)  /* read something or did not fail? */
    lua_pushstring(buff);
}
static const char *match (MatchState *ms, const char *s, const char *p) {
  init: /* using goto's to optimize tail recursion */
  switch (*p) {
    case '(': {  /* start capture */
      if (*(p+1) == ')')  /* position capture? */
        return start_capture(ms, s, p+2, CAP_POSITION);
      else
        return start_capture(ms, s, p+1, CAP_UNFINISHED);
    }
    case ')': {  /* end capture */
      return end_capture(ms, s, p+1);
    }
    case ESC: {
      switch (*(p+1)) {
        case 'b': {  /* balanced string? */
          s = matchbalance(ms, s, p+2);
          if (s == NULL) return NULL;
          p+=4; goto init;  /* else return match(ms, s, p+4); */
        }
        case 'f': {  /* frontier? */
          const char *ep; char previous;
          p += 2;
          if (*p != '[')
            luaL_error(ms->L, "missing `[' after `%%f' in pattern");
          ep = luaI_classend(ms, p);  /* points to what is next */
          previous = (s == ms->src_init) ? '\0' : *(s-1);
          if (matchbracketclass(uchar(previous), p, ep-1) ||
             !matchbracketclass(uchar(*s), p, ep-1)) return NULL;
          p=ep; goto init;  /* else return match(ms, s, ep); */
        }
        default: {
          if (isdigit(uchar(*(p+1)))) {  /* capture results (%0-%9)? */
            s = match_capture(ms, s, *(p+1));
            if (s == NULL) return NULL;
            p+=2; goto init;  /* else return match(ms, s, p+2) */
          }
          goto dflt;  /* case default */
        }
      }
    }
    case '\0': {  /* end of pattern */
      return s;  /* match succeeded */
    }
    case '$': {
      if (*(p+1) == '\0')  /* is the `$' the last char in pattern? */
        return (s == ms->src_end) ? s : NULL;  /* check end of string */
      else goto dflt;
    }
    default: dflt: {  /* it is a pattern item */
      const char *ep = luaI_classend(ms, p);  /* points to what is next */
      int m = s<ms->src_end && luaI_singlematch(uchar(*s), p, ep);
      switch (*ep) {
        case '?': {  /* optional */
          const char *res;
          if (m && ((res=match(ms, s+1, ep+1)) != NULL))
            return res;
          p=ep+1; goto init;  /* else return match(ms, s, ep+1); */
        }
        case '*': {  /* 0 or more repetitions */
          return max_expand(ms, s, p, ep);
        }
        case '+': {  /* 1 or more repetitions */
          return (m ? max_expand(ms, s+1, p, ep) : NULL);
        }
        case '-': {  /* 0 or more repetitions (minimum) */
          return min_expand(ms, s, p, ep);
        }
        default: {
          if (!m) return NULL;
          s++; p=ep; goto init;  /* else return match(ms, s+1, ep); */
        }
      }
    }
  }
}