Ejemplo n.º 1
0
static void str_gsub (void)
{
  int32 srcl;
  const char *src = luaL_check_lstr(1, &srcl);
  const char *p = luaL_check_string(2);
  lua_Object newp = lua_getparam(3);
  int32 max_s = (int32)luaL_opt_number(4, srcl+1);
  int32 anchor = (*p == '^') ? (p++, 1) : 0;
  int32 n = 0;
  struct Capture cap;
  luaL_arg_check(lua_isstring(newp) || lua_isfunction(newp), 3,
                 "string or function expected");
  luaL_resetbuffer();
  cap.src_end = src+srcl;
  while (n < max_s) {
    const char *e;
    cap.level = 0;
    e = match(src, p, &cap);
    if (e) {
      n++;
      add_s(newp, &cap);
    }
    if (e && e>src) /* non empty match? */
      src = e;  /* skip it */
    else if (src < cap.src_end)
      luaL_addchar(*src++);
    else break;
    if (anchor) break;
  }
  addnchar(src, cap.src_end-src);
  closeandpush();
  lua_pushnumber(n);  /* number of substitutions */
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
0
static void str_format (void)
{
  int32 arg = 1;
  const char *strfrmt = luaL_check_string(arg);
  struct Capture cap;
  cap.src_end = strfrmt+strlen(strfrmt)+1;
  luaL_resetbuffer();
  while (*strfrmt) {
    if (*strfrmt != '%')
      luaL_addchar(*strfrmt++);
    else if (*++strfrmt == '%')
      luaL_addchar(*strfrmt++);  /* %% */
    else { /* format item */
      char form[MAX_FORMAT];      /* store the format ('%...') */
      char *buff;
      const char *initf = strfrmt;
      form[0] = '%';
      cap.level = 0;
      if (isdigit((byte)initf[0]) && initf[1] == '$') {
        arg = initf[0] - '0';
        initf += 2;  /* skip the 'n$' */
      }
      arg++;
      strfrmt = match(initf, "[-+ #0]*(%d*)%.?(%d*)", &cap);
      if (cap.capture[0].len > 2 || cap.capture[1].len > 2)  /* < 100? */
        lua_error("invalid format (width or precision too long)");
      strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
      form[strfrmt-initf+2] = 0;
      buff = luaL_openspace(1000);  /* to store the formatted value */
      switch (*strfrmt++) {
        case 'q':
          luaI_addquoted(luaL_check_string(arg));
          continue;
        case 's': {
          const char *s = luaL_check_string(arg);
          buff = luaL_openspace(strlen(s));
          sprintf(buff, form, s);
          break;
        }
        case 'c':  case 'd':  case 'i':
          sprintf(buff, form, (int)luaL_check_number(arg));
          break;
        case 'o':  case 'u':  case 'x':  case 'X':
          sprintf(buff, form, (unsigned int)luaL_check_number(arg));
          break;
        case 'e':  case 'E': case 'f': case 'g': case 'G':
          sprintf(buff, form, luaL_check_number(arg));
          break;
        default:  /* also treat cases 'pnLlh' */
          lua_error("invalid option in `format'");
      }
      luaL_addsize(strlen(buff));
    }
  }
  closeandpush();  /* push the result */
}
Ejemplo n.º 4
0
static void str_char (void) {
  int32 i = 0;
  luaL_resetbuffer();
  while (lua_getparam(++i) != LUA_NOOBJECT) {
    double c = luaL_check_number(i);
    luaL_arg_check((byte)c == c, i, "invalid value");
    luaL_addchar((int32)c);
  }
  closeandpush();
}
Ejemplo n.º 5
0
static void str_rep (void)
{
  int32 l;
  const char *s = luaL_check_lstr(1, &l);
  int32 n = (int32)luaL_check_number(2);
  luaL_resetbuffer();
  while (n-- > 0)
    addnchar(s, l);
  closeandpush();
}
Ejemplo n.º 6
0
static void str_upper (void)
{
  int32 l;
  int32 i;
  const char *s = luaL_check_lstr(1, &l);
  luaL_resetbuffer();
  for (i=0; i<l; i++)
    luaL_addchar(toupper((byte)(s[i])));
  closeandpush();
}
Ejemplo n.º 7
0
Archivo: llex.c Proyecto: calandoa/zite
void luaX_setinput (LexState *LS, ZIO *z)
{
  LS->current = '\n';
  LS->linenumber = 0;
  LS->iflevel = 0;
  LS->ifstate[0].skip = 0;
  LS->ifstate[0].elsepart = 1;  /* to avoid a free $else */
  LS->lex_z = z;
  LS->fs = NULL;
  firstline(LS);
  luaL_resetbuffer();
}
Ejemplo n.º 8
0
void luaX_setinput(ZIO *z) {
	LexState *LS = lua_state->lexstate;
	LS->current = '\n';
	LS->linelasttoken = 0;
	LS->linenumber = 0;
	LS->iflevel = 0;
	LS->ifstate[0].skip = 0;
	LS->ifstate[0].elsepart = 1;  // to avoid a free $else
	LS->lex_z = z;
	firstline(LS);
	luaL_resetbuffer();
}
Ejemplo n.º 9
0
Archivo: liolib.c Proyecto: 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);
}
Ejemplo n.º 10
0
Archivo: llex.c Proyecto: calandoa/zite
int luaX_lex (LexState *LS) {
  luaL_resetbuffer();
  for (;;) {
    switch (LS->current) {

      case ' ': case '\t': case '\r':  /* CR: to avoid problems with DOS */
        next(LS);
        continue;

      case '\n':
        inclinenumber(LS);
        continue;

      case '-':
        save_and_next(LS);
        if (LS->current != '-') return '-';
        do { next(LS); } while (LS->current != '\n' && LS->current != EOZ);
        luaL_resetbuffer();
        continue;

      case '[':
        save_and_next(LS);
        if (LS->current != '[') return '[';
        else {
          save_and_next(LS);  /* pass the second '[' */
          return read_long_string(LS);
        }

      case '=':
        save_and_next(LS);
        if (LS->current != '=') return '=';
        else { save_and_next(LS); return EQ; }

      case '<':
        save_and_next(LS);
        if (LS->current != '=') return '<';
        else { save_and_next(LS); return LE; }

      case '>':
        save_and_next(LS);
        if (LS->current != '=') return '>';
        else { save_and_next(LS); return GE; }

      case '~':
        save_and_next(LS);
        if (LS->current != '=') return '~';
        else { save_and_next(LS); return NE; }

      case '"':
      case '\'': {
        int del = LS->current;
        save_and_next(LS);
        while (LS->current != del) {
          switch (LS->current) {
            case EOZ:
            case '\n':
              luaX_error(LS, "unfinished string");
              return EOS;  /* to avoid warnings */
            case '\\':
              next(LS);  /* do not save the '\' */
              switch (LS->current) {
                case 'a': save('\a'); next(LS); break;
                case 'b': save('\b'); next(LS); break;
                case 'f': save('\f'); next(LS); break;
                case 'n': save('\n'); next(LS); break;
                case 'r': save('\r'); next(LS); break;
                case 't': save('\t'); next(LS); break;
                case 'v': save('\v'); next(LS); break;
                case '\n': save('\n'); inclinenumber(LS); break;
                default : {
                  if (isdigit(LS->current)) {
                    int c = 0;
                    int i = 0;
                    do {
                      c = 10*c + (LS->current-'0');
                      next(LS);
                    } while (++i<3 && isdigit(LS->current));
                    if (c != (unsigned char)c)
                      luaX_error(LS, "escape sequence too large");
                    save(c);
                  }
                  else {  /* handles \, ", ', and ? */
                    save(LS->current);
                    next(LS);
                  }
                  break;
                }
              }
              break;
            default:
              save_and_next(LS);
          }
        }
        save_and_next(LS);  /* skip delimiter */
        LS->seminfo.ts = luaS_newlstr(L->Mbuffer+(L->Mbuffbase+1),
                                L->Mbuffnext-L->Mbuffbase-2);
        return STRING;
      }

      case '.':
        save_and_next(LS);
        if (LS->current == '.')
        {
          save_and_next(LS);
          if (LS->current == '.')
          {
            save_and_next(LS);
            return DOTS;   /* ... */
          }
          else return CONC;   /* .. */
        }
        else if (!isdigit(LS->current)) return '.';
        goto fraction;  /* LS->current is a digit: goes through to number */

      case '0': case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9':
        do {
          save_and_next(LS);
        } while (isdigit(LS->current));
        if (LS->current == '.') {
          save_and_next(LS);
          if (LS->current == '.') {
            save('.');
            luaX_error(LS, 
              "ambiguous syntax (decimal point x string concatenation)");
          }
        }
      fraction:
        while (isdigit(LS->current))
          save_and_next(LS);
        if (toupper(LS->current) == 'E') {
          save_and_next(LS);  /* read 'E' */
          save_and_next(LS);  /* read '+', '-' or first digit */
          while (isdigit(LS->current))
            save_and_next(LS);
        }
        save('\0');
        LS->seminfo.r = luaO_str2d(L->Mbuffer+L->Mbuffbase);
        if (LS->seminfo.r < 0)
          luaX_error(LS, "invalid numeric format");
        return NUMBER;

      case EOZ:
        if (LS->iflevel > 0)
          luaX_error(LS, "input ends inside a $if");
        return EOS;

      default:
        if (LS->current != '_' && !isalpha(LS->current)) {
          int c = LS->current;
          if (iscntrl(c))
            luaX_invalidchar(LS, c);
          save_and_next(LS);
          return c;
        }
        else {  /* identifier or reserved word */
          TaggedString *ts;
          do {
            save_and_next(LS);
          } while (isalnum(LS->current) || LS->current == '_');
          save('\0');
          ts = luaS_new(L->Mbuffer+L->Mbuffbase);
          if (ts->head.marked >= FIRST_RESERVED)
            return ts->head.marked;  /* reserved word */
          LS->seminfo.ts = ts;
          return NAME;
        }
    }
  }
}
Ejemplo n.º 11
0
int32 luaY_lex(YYSTYPE *l) {
	LexState *LS = lua_state->lexstate;
	double a;
	luaL_resetbuffer();
	if (lua_debug)
		luaY_codedebugline(LS->linelasttoken);
	LS->linelasttoken = LS->linenumber;
	while (1) {
		switch (LS->current) {
		case ' ':
		case '\t':
		case '\r':  // CR: to avoid problems with DOS
			next(LS);
			continue;
		case '\n':
			inclinenumber(LS);
			LS->linelasttoken = LS->linenumber;
			continue;
		case '-':
			save_and_next(LS);
			if (LS->current != '-')
				return '-';
			do {
				next(LS);
			} while (LS->current != '\n' && LS->current != EOZ);
			luaL_resetbuffer();
			continue;
		case '[':
			save_and_next(LS);
			if (LS->current != '[')
				return '[';
			else {
				save_and_next(LS);  // pass the second '['
				return read_long_string(LS, l);
			}
		case '=':
			save_and_next(LS);
			if (LS->current != '=')
				return '=';
			else {
				save_and_next(LS);
				return EQ;
			}
		case '<':
			save_and_next(LS);
			if (LS->current != '=')
				return '<';
			else {
				save_and_next(LS);
				return LE;
			}
		case '>':
			save_and_next(LS);
			if (LS->current != '=')
				return '>';
			else {
				save_and_next(LS);
				return GE;
			}
		case '~':
			save_and_next(LS);
			if (LS->current != '=')
				return '~';
			else {
				save_and_next(LS);
				return NE;
			}
		case '"':
		case '\'':
			{
				int32 del = LS->current;
				save_and_next(LS);
				while (LS->current != del) {
					switch (LS->current) {
					case EOZ:
					case '\n':
						save(0);
						return WRONGTOKEN;
					case '\\':
						next(LS);  // do not save the '\'
						switch (LS->current) {
						case 'n':
							save('\n');
							next(LS);
							break;
						case 't':
							save('\t');
							next(LS);
							break;
						case 'r':
							save('\r');
							next(LS);
							break;
						case '\n':
							save('\n');
							inclinenumber(LS);
							break;
						default :
							save_and_next(LS); break;
						}
						break;
					default:
						save_and_next(LS);
					}
				}
				next(LS);  // skip delimiter
				save(0);
				l->pTStr = luaS_new(Mbuffbase + 1);
				Mbuffer[Mbuffnext - 1] = del;  // restore delimiter
				return STRING;
			}
		case '.':
			save_and_next(LS);
			if (LS->current == '.') {
				save_and_next(LS);
				if (LS->current == '.') {
					save_and_next(LS);
					return DOTS;   // ...
				} else
					return CONC;   // ..
				} else if (!Common::isDigit(LS->current))
					return '.';
				// LS->current is a digit: goes through to number/
				a = 0.0;
				goto fraction;
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			a = 0.0;
			do {
				a = 10.0 * a + (LS->current - '0');
				save_and_next(LS);
			} while (Common::isDigit(LS->current));
			if (LS->current == '.') {
				save_and_next(LS);
				if (LS->current == '.') {
					save(0);
					luaY_error("ambiguous syntax (decimal point x string concatenation)");
				}
			}
fraction:
			{
				double da = 0.1;
				while (Common::isDigit(LS->current)) {
					a += (LS->current - '0') * da;
					da /= 10.0;
					save_and_next(LS);
				}
				if (toupper(LS->current) == 'E') {
					int32 e = 0;
					int32 neg;
					double ea;
					save_and_next(LS);
					neg = (LS->current == '-');
					if (LS->current == '+' || LS->current == '-')
						save_and_next(LS);
					if (!Common::isDigit(LS->current)) {
						save(0);
						return WRONGTOKEN;
					}
					do {
						e = 10 * e + (LS->current - '0');
						save_and_next(LS);
					} while (Common::isDigit(LS->current));
					for (ea = neg ? 0.1 : 10.0; e > 0; e >>= 1) {
						if (e & 1)
							a *= ea;
						ea *= ea;
					}
				}
				l->vReal = a;
				return NUMBER;
			}
		case EOZ:
			save(0);
			if (LS->iflevel > 0)
				luaY_syntaxerror("input ends inside a $if", "");
			return 0;
		default:
			if (LS->current != '_' && !Common::isAlpha(LS->current)) {
				int32 c = LS->current;
				save_and_next(LS);
				return c;
			} else {  // identifier or reserved word
				TaggedString *ts;
				do {
					save_and_next(LS);
				} while (Common::isAlnum(LS->current) || LS->current == '_');
				save(0);
				ts = luaS_new(Mbuffbase);
				if (ts->head.marked >= 255)
					return ts->head.marked;  // reserved word
				l->pTStr = ts;
				return NAME;
			}
		}
	}