static void read_string (tt_Lexer *L, int del) { ttL_save_and_next(L); /* keep delimiter (for error messages) */ while (ttL_current(L) != del) { switch (ttL_current(L)) { case TTL_EOZ: ttL_lexerror(L, "unfinished string", TTK_EOS); break; /* to avoid warnings */ case '\n': case '\r': ttL_lexerror(L, "unfinished string", TTK_STRING); break; /* to avoid warnings */ case '\\': { /* escape sequences */ int c; /* final character to be saved */ ttL_next(L); /* do not ttL_save the `\' */ switch (ttL_current(L)) { case 'a': c = '\a'; goto read_save; case 'b': c = '\b'; goto read_save; case 'f': c = '\f'; goto read_save; case 'n': c = '\n'; goto read_save; case 'r': c = '\r'; goto read_save; case 't': c = '\t'; goto read_save; case 'v': c = '\v'; goto read_save; case 'x': c = readhexaesc(L); goto read_save; case '\n': case '\r': ttL_inclinenumber(L); c = '\n'; goto only_save; case '\\': case '\"': case '\'': c = ttL_current(L); goto read_save; case TTL_EOZ: goto no_save; /* will raise an error ttL_next loop */ case 'z': { /* zap following span of spaces */ ttL_next(L); /* skip the 'z' */ while (isspace(ttL_current(L))) { if (ttL_isnewline(L)) ttL_inclinenumber(L); else ttL_next(L); } goto no_save; } default: { if (!isdigit(ttL_current(L))) { int ch = ttL_current(L); escerror(L, &ch, 1, "invalid escape sequence"); } /* digital escape \ddd */ c = readdecesc(L); goto only_save; } } read_save: ttL_next(L); /* read next character */ only_save: ttL_save(L, c); /* save 'c' */ no_save: break; } default: ttL_save_and_next(L); } } ttL_save_and_next(L); /* skip delimiter */ ttL_movebuffer(L, ttL_buffer(L)+1, ttL_bufflen(L)-2); }
static void read_string (LexState *ls, int del, SemInfo *seminfo) { save_and_next(ls); /* keep delimiter (for error messages) */ while (ls->current != del) { switch (ls->current) { case EOZ: lexerror(ls, "unfinished string", TK_EOS); break; /* to avoid warnings */ case '\n': case '\r': lexerror(ls, "unfinished string", TK_STRING); break; /* to avoid warnings */ case '\\': { /* escape sequences */ int c; /* final character to be saved */ save_and_next(ls); /* keep '\\' for error messages */ switch (ls->current) { case 'a': c = '\a'; goto read_save; case 'b': c = '\b'; goto read_save; case 'f': c = '\f'; goto read_save; case 'n': c = '\n'; goto read_save; case 'r': c = '\r'; goto read_save; case 't': c = '\t'; goto read_save; case 'v': c = '\v'; goto read_save; case 'x': c = readhexaesc(ls); goto read_save; case 'u': utf8esc(ls); goto no_save; case '\n': case '\r': inclinenumber(ls); c = '\n'; goto only_save; case '\\': case '\"': case '\'': c = ls->current; goto read_save; case EOZ: goto no_save; /* will raise an error next loop */ case 'z': { /* zap following span of spaces */ luaZ_buffremove(ls->buff, 1); /* remove '\\' */ next(ls); /* skip the 'z' */ while (lisspace(ls->current)) { if (currIsNewline(ls)) inclinenumber(ls); else next(ls); } goto no_save; } default: { esccheck(ls, lisdigit(ls->current), "invalid escape sequence"); c = readdecesc(ls); /* digital escape '\ddd' */ goto only_save; } } read_save: next(ls); /* go through */ only_save: luaZ_buffremove(ls->buff, 1); /* remove '\\' */ save(ls, c); /* go through */ no_save: break; } default: save_and_next(ls); } } save_and_next(ls); /* skip delimiter */ seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, luaZ_bufflen(ls->buff) - 2); }