📄 jsscan.c
字号:
if (!ENSURE_STRING_BUFFER(sb, 1)) return; bp = sb->ptr; *bp++ = c; *bp = 0; sb->ptr = bp;}#if JS_HAS_XML_SUPPORTvoidjs_RepeatChar(JSStringBuffer *sb, jschar c, uintN count){ jschar *bp; if (!STRING_BUFFER_OK(sb) || count == 0) return; if (!ENSURE_STRING_BUFFER(sb, count)) return; for (bp = sb->ptr; count; --count) *bp++ = c; *bp = 0; sb->ptr = bp;}voidjs_AppendCString(JSStringBuffer *sb, const char *asciiz){ size_t length; jschar *bp; if (!STRING_BUFFER_OK(sb) || *asciiz == '\0') return; length = strlen(asciiz); if (!ENSURE_STRING_BUFFER(sb, length)) return; for (bp = sb->ptr; length; --length) *bp++ = (jschar) *asciiz++; *bp = 0; sb->ptr = bp;}voidjs_AppendJSString(JSStringBuffer *sb, JSString *str){ size_t length; jschar *bp; if (!STRING_BUFFER_OK(sb)) return; length = JSSTRING_LENGTH(str); if (length == 0 || !ENSURE_STRING_BUFFER(sb, length)) return; bp = sb->ptr; js_strncpy(bp, JSSTRING_CHARS(str), length); bp += length; *bp = 0; sb->ptr = bp;}static JSBoolGetXMLEntity(JSContext *cx, JSTokenStream *ts){ ptrdiff_t offset, length, i; int32 c, d; JSBool ispair; jschar *bp, digit; char *bytes; JSErrNum msg; /* Put the entity, including the '&' already scanned, in ts->tokenbuf. */ offset = PTRDIFF(ts->tokenbuf.ptr, ts->tokenbuf.base, jschar); FastAppendChar(&ts->tokenbuf, '&'); while ((c = GetChar(ts)) != ';') { if (c == EOF || c == '\n') { js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR, JSMSG_END_OF_XML_ENTITY); return JS_FALSE; } FastAppendChar(&ts->tokenbuf, (jschar) c); } /* Let length be the number of jschars after the '&', including the ';'. */ length = PTRDIFF(ts->tokenbuf.ptr, ts->tokenbuf.base, jschar) - offset; bp = ts->tokenbuf.base + offset; c = d = 0; ispair = JS_FALSE; if (length > 2 && bp[1] == '#') { /* Match a well-formed XML Character Reference. */ i = 2; if (length > 3 && JS_TOLOWER(bp[i]) == 'x') { if (length > 9) /* at most 6 hex digits allowed */ goto badncr; while (++i < length) { digit = bp[i]; if (!JS7_ISHEX(digit)) goto badncr; c = (c << 4) + JS7_UNHEX(digit); } } else { while (i < length) { digit = bp[i++]; if (!JS7_ISDEC(digit)) goto badncr; c = (c * 10) + JS7_UNDEC(digit); if (c < 0) goto badncr; } } if (0x10000 <= c && c <= 0x10FFFF) { /* Form a surrogate pair (c, d) -- c is the high surrogate. */ d = 0xDC00 + (c & 0x3FF); c = 0xD7C0 + (c >> 10); ispair = JS_TRUE; } else { /* Enforce the http://www.w3.org/TR/REC-xml/#wf-Legalchar WFC. */ if (c != 0x9 && c != 0xA && c != 0xD && !(0x20 <= c && c <= 0xD7FF) && !(0xE000 <= c && c <= 0xFFFD)) { goto badncr; } } } else { /* Try to match one of the five XML 1.0 predefined entities. */ switch (length) { case 3: if (bp[2] == 't') { if (bp[1] == 'l') c = '<'; else if (bp[1] == 'g') c = '>'; } break; case 4: if (bp[1] == 'a' && bp[2] == 'm' && bp[3] == 'p') c = '&'; break; case 5: if (bp[3] == 'o') { if (bp[1] == 'a' && bp[2] == 'p' && bp[4] == 's') c = '\''; else if (bp[1] == 'q' && bp[2] == 'u' && bp[4] == 't') c = '"'; } break; } if (c == 0) { msg = JSMSG_UNKNOWN_XML_ENTITY; goto bad; } } /* If we matched, retract ts->tokenbuf and store the entity's value. */ *bp++ = (jschar) c; if (ispair) *bp++ = (jschar) d; *bp = 0; ts->tokenbuf.ptr = bp; return JS_TRUE;badncr: msg = JSMSG_BAD_XML_NCR;bad: /* No match: throw a TypeError per ECMA-357 10.3.2.1 step 8(a). */ bytes = js_DeflateString(cx, bp + 1, PTRDIFF(ts->tokenbuf.ptr, bp, jschar) - 1); if (bytes) { js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR, msg, bytes); JS_free(cx, bytes); } return JS_FALSE;}#endif /* JS_HAS_XML_SUPPORT */JSTokenTypejs_PeekToken(JSContext *cx, JSTokenStream *ts){ JSTokenType tt; if (ts->lookahead != 0) { tt = ts->tokens[(ts->cursor + ts->lookahead) & NTOKENS_MASK].type; } else { tt = js_GetToken(cx, ts); js_UngetToken(ts); } return tt;}JSTokenTypejs_PeekTokenSameLine(JSContext *cx, JSTokenStream *ts){ JSTokenType tt; if (!ON_CURRENT_LINE(ts, CURRENT_TOKEN(ts).pos)) return TOK_EOL; ts->flags |= TSF_NEWLINES; tt = js_PeekToken(cx, ts); ts->flags &= ~TSF_NEWLINES; return tt;}/* * We have encountered a '\': check for a Unicode escape sequence after it, * returning the character code value if we found a Unicode escape sequence. * Otherwise, non-destructively return the original '\'. */static int32GetUnicodeEscape(JSTokenStream *ts){ jschar cp[5]; int32 c; if (PeekChars(ts, 5, cp) && cp[0] == 'u' && JS7_ISHEX(cp[1]) && JS7_ISHEX(cp[2]) && JS7_ISHEX(cp[3]) && JS7_ISHEX(cp[4])) { c = (((((JS7_UNHEX(cp[1]) << 4) + JS7_UNHEX(cp[2])) << 4) + JS7_UNHEX(cp[3])) << 4) + JS7_UNHEX(cp[4]); SkipChars(ts, 5); return c; } return '\\';}static JSToken *NewToken(JSTokenStream *ts, ptrdiff_t adjust){ JSToken *tp; ts->cursor = (ts->cursor + 1) & NTOKENS_MASK; tp = &CURRENT_TOKEN(ts); tp->ptr = ts->linebuf.ptr + adjust; tp->pos.begin.index = ts->linepos + PTRDIFF(tp->ptr, ts->linebuf.base, jschar) - ts->ungetpos; tp->pos.begin.lineno = tp->pos.end.lineno = (uint16)ts->lineno; return tp;}JSTokenTypejs_GetToken(JSContext *cx, JSTokenStream *ts){ JSTokenType tt; int32 c, qc; JSToken *tp; JSAtom *atom; JSBool hadUnicodeEscape; const struct keyword *kw;#define INIT_TOKENBUF() (ts->tokenbuf.ptr = ts->tokenbuf.base)#define TOKENBUF_LENGTH() PTRDIFF(ts->tokenbuf.ptr, ts->tokenbuf.base, jschar)#define TOKENBUF_OK() STRING_BUFFER_OK(&ts->tokenbuf)#define TOKENBUF_TO_ATOM() (TOKENBUF_OK() \ ? js_AtomizeChars(cx, \ TOKENBUF_BASE(), \ TOKENBUF_LENGTH(), \ 0) \ : NULL)#define ADD_TO_TOKENBUF(c) FastAppendChar(&ts->tokenbuf, (jschar) (c))/* The following 4 macros should only be used when TOKENBUF_OK() is true. */#define TOKENBUF_BASE() (ts->tokenbuf.base)#define TOKENBUF_CHAR(i) (ts->tokenbuf.base[i])#define TRIM_TOKENBUF(i) (ts->tokenbuf.ptr = ts->tokenbuf.base + i)#define NUL_TERM_TOKENBUF() (*ts->tokenbuf.ptr = 0) /* Check for a pushed-back token resulting from mismatching lookahead. */ while (ts->lookahead != 0) { JS_ASSERT(!(ts->flags & TSF_XMLTEXTMODE)); ts->lookahead--; ts->cursor = (ts->cursor + 1) & NTOKENS_MASK; tt = CURRENT_TOKEN(ts).type; if (tt != TOK_EOL || (ts->flags & TSF_NEWLINES)) return tt; } /* If there was a fatal error, keep returning TOK_ERROR. */ if (ts->flags & TSF_ERROR) return TOK_ERROR;#if JS_HAS_XML_SUPPORT if (ts->flags & TSF_XMLTEXTMODE) { tt = TOK_XMLSPACE; /* veto if non-space, return TOK_XMLTEXT */ tp = NewToken(ts, 0); INIT_TOKENBUF(); qc = (ts->flags & TSF_XMLONLYMODE) ? '<' : '{'; while ((c = GetChar(ts)) != qc && c != '<' && c != EOF) { if (c == '&' && qc == '<') { if (!GetXMLEntity(cx, ts)) goto error; tt = TOK_XMLTEXT; continue; } if (!JS_ISXMLSPACE(c)) tt = TOK_XMLTEXT; ADD_TO_TOKENBUF(c); } UngetChar(ts, c); if (TOKENBUF_LENGTH() == 0) { atom = NULL; } else { atom = TOKENBUF_TO_ATOM(); if (!atom) goto error; } tp->pos.end.lineno = (uint16)ts->lineno; tp->t_op = JSOP_STRING; tp->t_atom = atom; goto out; } if (ts->flags & TSF_XMLTAGMODE) { tp = NewToken(ts, 0); c = GetChar(ts); if (JS_ISXMLSPACE(c)) { do { c = GetChar(ts); } while (JS_ISXMLSPACE(c)); UngetChar(ts, c); tt = TOK_XMLSPACE; goto out; } if (c == EOF) { tt = TOK_EOF; goto out; } INIT_TOKENBUF(); if (JS_ISXMLNSSTART(c)) { JSBool sawColon = JS_FALSE; ADD_TO_TOKENBUF(c); while ((c = GetChar(ts)) != EOF && JS_ISXMLNAME(c)) { if (c == ':') { int nextc; if (sawColon || (nextc = PeekChar(ts), ((ts->flags & TSF_XMLONLYMODE) || nextc != '{') && !JS_ISXMLNAME(nextc))) { js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR, JSMSG_BAD_XML_QNAME); goto error; } sawColon = JS_TRUE; } ADD_TO_TOKENBUF(c); } UngetChar(ts, c); atom = TOKENBUF_TO_ATOM(); if (!atom) goto error; tp->t_op = JSOP_STRING; tp->t_atom = atom; tt = TOK_XMLNAME; goto out; } switch (c) { case '{': if (ts->flags & TSF_XMLONLYMODE) goto bad_xml_char; tt = TOK_LC; goto out; case '=': tt = TOK_ASSIGN; goto out; case '"': case '\'': qc = c; while ((c = GetChar(ts)) != qc) { if (c == EOF) { js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR, JSMSG_UNTERMINATED_STRING); goto error; } /* * XML attribute values are double-quoted when pretty-printed, * so escape " if it is expressed directly in a single-quoted * attribute value. */ if (c == '"' && !(ts->flags & TSF_XMLONLYMODE)) { JS_ASSERT(qc == '\''); js_AppendCString(&ts->tokenbuf, js_quot_entity_str); continue; } if (c == '&' && (ts->flags & TSF_XMLONLYMODE)) { if (!GetXMLEntity(cx, ts)) goto error; continue; } ADD_TO_TOKENBUF(c); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -