⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jsscan.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Mozilla Communicator client code, released * March 31, 1998. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** *//* * JS lexical scanner. */#include "jsstddef.h"#include <stdio.h>      /* first to avoid trouble on some systems */#include <errno.h>#include <limits.h>#include <math.h>#ifdef HAVE_MEMORY_H#include <memory.h>#endif#include <stdarg.h>#include <stdlib.h>#include <string.h>#include "jstypes.h"#include "jsarena.h" /* Added by JSIFY */#include "jsutil.h" /* Added by JSIFY */#include "jsdtoa.h"#include "jsprf.h"#include "jsapi.h"#include "jsatom.h"#include "jscntxt.h"#include "jsconfig.h"#include "jsemit.h"#include "jsexn.h"#include "jsnum.h"#include "jsopcode.h"#include "jsregexp.h"#include "jsscan.h"#define RESERVE_JAVA_KEYWORDS#define RESERVE_ECMA_KEYWORDSstatic struct keyword {    const char  *name;    JSTokenType tokentype;      /* JSTokenType */    JSOp        op;             /* JSOp */    JSVersion   version;        /* JSVersion */} keywords[] = {    {"break",           TOK_BREAK,              JSOP_NOP,   JSVERSION_DEFAULT},    {"case",            TOK_CASE,               JSOP_NOP,   JSVERSION_DEFAULT},    {"continue",        TOK_CONTINUE,           JSOP_NOP,   JSVERSION_DEFAULT},    {"default",         TOK_DEFAULT,            JSOP_NOP,   JSVERSION_DEFAULT},    {js_delete_str,     TOK_DELETE,             JSOP_NOP,   JSVERSION_DEFAULT},    {"do",              TOK_DO,                 JSOP_NOP,   JSVERSION_DEFAULT},    {"else",            TOK_ELSE,               JSOP_NOP,   JSVERSION_DEFAULT},    {"export",          TOK_EXPORT,             JSOP_NOP,   JSVERSION_1_2},    {js_false_str,      TOK_PRIMARY,            JSOP_FALSE, JSVERSION_DEFAULT},    {"for",             TOK_FOR,                JSOP_NOP,   JSVERSION_DEFAULT},    {js_function_str,   TOK_FUNCTION,           JSOP_NOP,   JSVERSION_DEFAULT},    {"if",              TOK_IF,                 JSOP_NOP,   JSVERSION_DEFAULT},    {js_in_str,         TOK_IN,                 JSOP_IN,    JSVERSION_DEFAULT},    {js_new_str,        TOK_NEW,                JSOP_NEW,   JSVERSION_DEFAULT},    {js_null_str,       TOK_PRIMARY,            JSOP_NULL,  JSVERSION_DEFAULT},    {"return",          TOK_RETURN,             JSOP_NOP,   JSVERSION_DEFAULT},    {"switch",          TOK_SWITCH,             JSOP_NOP,   JSVERSION_DEFAULT},    {js_this_str,       TOK_PRIMARY,            JSOP_THIS,  JSVERSION_DEFAULT},    {js_true_str,       TOK_PRIMARY,            JSOP_TRUE,  JSVERSION_DEFAULT},    {js_typeof_str,     TOK_UNARYOP,            JSOP_TYPEOF,JSVERSION_DEFAULT},    {"var",             TOK_VAR,                JSOP_DEFVAR,JSVERSION_DEFAULT},    {js_void_str,       TOK_UNARYOP,            JSOP_VOID,  JSVERSION_DEFAULT},    {"while",           TOK_WHILE,              JSOP_NOP,   JSVERSION_DEFAULT},    {"with",            TOK_WITH,               JSOP_NOP,   JSVERSION_DEFAULT},#if JS_HAS_CONST    {js_const_str,      TOK_VAR,                JSOP_DEFCONST,JSVERSION_DEFAULT},#else    {js_const_str,      TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},#endif#if JS_HAS_EXCEPTIONS    {"try",             TOK_TRY,                JSOP_NOP,   JSVERSION_DEFAULT},    {"catch",           TOK_CATCH,              JSOP_NOP,   JSVERSION_DEFAULT},    {"finally",         TOK_FINALLY,            JSOP_NOP,   JSVERSION_DEFAULT},    {"throw",           TOK_THROW,              JSOP_NOP,   JSVERSION_DEFAULT},#else    {"try",             TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"catch",           TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"finally",         TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"throw",           TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},#endif#if JS_HAS_INSTANCEOF    {js_instanceof_str, TOK_INSTANCEOF,         JSOP_INSTANCEOF,JSVERSION_1_4},#else    {js_instanceof_str, TOK_RESERVED,           JSOP_NOP,   JSVERSION_1_4},#endif#ifdef RESERVE_JAVA_KEYWORDS    {"abstract",        TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"boolean",         TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"byte",            TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"char",            TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"class",           TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"double",          TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"extends",         TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"final",           TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"float",           TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"goto",            TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"implements",      TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"import",          TOK_IMPORT,             JSOP_NOP,   JSVERSION_DEFAULT},    {"int",             TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"interface",       TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"long",            TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"native",          TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"package",         TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"private",         TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"protected",       TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"public",          TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"short",           TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"static",          TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"super",           TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"synchronized",    TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"throws",          TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"transient",       TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},    {"volatile",        TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},#endif#ifdef RESERVE_ECMA_KEYWORDS    {"enum",           TOK_RESERVED,            JSOP_NOP,   JSVERSION_1_3},#endif#if JS_HAS_DEBUGGER_KEYWORD    {"debugger",       TOK_DEBUGGER,            JSOP_NOP,   JSVERSION_1_3},#elif defined(RESERVE_ECMA_KEYWORDS)    {"debugger",       TOK_RESERVED,            JSOP_NOP,   JSVERSION_1_3},#endif    {0,                TOK_EOF,                 JSOP_NOP,   JSVERSION_DEFAULT}};JSBooljs_InitScanner(JSContext *cx){    struct keyword *kw;    JSAtom *atom;    for (kw = keywords; kw->name; kw++) {        atom = js_Atomize(cx, kw->name, strlen(kw->name), ATOM_PINNED);        if (!atom)            return JS_FALSE;        ATOM_SET_KEYWORD(atom, kw);    }    return JS_TRUE;}JS_FRIEND_API(void)js_MapKeywords(void (*mapfun)(const char *)){    struct keyword *kw;    for (kw = keywords; kw->name; kw++)        mapfun(kw->name);}JSTokenStream *js_NewTokenStream(JSContext *cx, const jschar *base, size_t length,                  const char *filename, uintN lineno,                  JSPrincipals *principals){    JSTokenStream *ts;    ts = js_NewBufferTokenStream(cx, base, length);    if (!ts)        return NULL;    ts->filename = filename;    ts->lineno = lineno;    if (principals)        JSPRINCIPALS_HOLD(cx, principals);    ts->principals = principals;    return ts;}JS_FRIEND_API(JSTokenStream *)js_NewBufferTokenStream(JSContext *cx, const jschar *base, size_t length){    size_t nb;    JSTokenStream *ts;    nb = sizeof(JSTokenStream) + JS_LINE_LIMIT * sizeof(jschar);    JS_ARENA_ALLOCATE_CAST(ts, JSTokenStream *, &cx->tempPool, nb);    if (!ts) {        JS_ReportOutOfMemory(cx);        return NULL;    }    memset(ts, 0, nb);    ts->lineno = 1;    ts->linebuf.base = ts->linebuf.limit = ts->linebuf.ptr = (jschar *)(ts + 1);    ts->userbuf.base = (jschar *)base;    ts->userbuf.limit = (jschar *)base + length;    ts->userbuf.ptr = (jschar *)base;    ts->listener = cx->runtime->sourceHandler;    ts->listenerData = cx->runtime->sourceHandlerData;    return ts;}JS_FRIEND_API(JSTokenStream *)js_NewFileTokenStream(JSContext *cx, const char *filename, FILE *defaultfp){    jschar *base;    JSTokenStream *ts;    FILE *file;    JS_ARENA_ALLOCATE_CAST(base, jschar *, &cx->tempPool,                           JS_LINE_LIMIT * sizeof(jschar));    if (!base)        return NULL;    ts = js_NewBufferTokenStream(cx, base, JS_LINE_LIMIT);    if (!ts)        return NULL;    if (!filename || strcmp(filename, "-") == 0) {        file = defaultfp;    } else {        file = fopen(filename, "r");        if (!file) {            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_OPEN,                                 filename, "No such file or directory");            return NULL;        }    }    ts->userbuf.ptr = ts->userbuf.limit;    ts->file = file;    ts->filename = filename;    return ts;}JS_FRIEND_API(JSBool)js_CloseTokenStream(JSContext *cx, JSTokenStream *ts){    if (ts->principals)        JSPRINCIPALS_DROP(cx, ts->principals);    return !ts->file || fclose(ts->file) == 0;}static intmy_fgets(char *buf, int size, FILE *file){    int n, i, c;    JSBool crflag;    n = size - 1;    if (n < 0)        return -1;    crflag = JS_FALSE;    for (i = 0; i < n && (c = getc(file)) != EOF; i++) {        buf[i] = c;        if (c == '\n') {        /* any \n ends a line */            i++;                /* keep the \n; we know there is room for \0 */            break;        }        if (crflag) {           /* \r not followed by \n ends line at the \r */            ungetc(c, file);            break;              /* and overwrite c in buf with \0 */        }        crflag = (c == '\r');    }    buf[i] = '\0';    return i;}static int32GetChar(JSTokenStream *ts){    int32 c;    ptrdiff_t i, j, len, olen;    JSBool crflag;    char cbuf[JS_LINE_LIMIT];    jschar *ubuf, *nl;    if (ts->ungetpos != 0) {        c = ts->ungetbuf[--ts->ungetpos];    } else {        do {            if (ts->linebuf.ptr == ts->linebuf.limit) {                len = PTRDIFF(ts->userbuf.limit, ts->userbuf.ptr, jschar);                if (len <= 0) {                    if (!ts->file) {                        ts->flags |= TSF_EOF;                        return EOF;                    }                    /* Fill ts->userbuf so that \r and \r\n convert to \n. */                    crflag = (ts->flags & TSF_CRFLAG) != 0;                    len = my_fgets(cbuf, JS_LINE_LIMIT - crflag, ts->file);                    if (len <= 0) {                        ts->flags |= TSF_EOF;                        return EOF;                    }                    olen = len;                    ubuf = ts->userbuf.base;                    i = 0;                    if (crflag) {                        ts->flags &= ~TSF_CRFLAG;                        if (cbuf[0] != '\n') {                            ubuf[i++] = '\n';                            len++;                            ts->linepos--;                        }                    }                    for (j = 0; i < len; i++, j++)                        ubuf[i] = (jschar) (unsigned char) cbuf[j];                    ts->userbuf.limit = ubuf + len;                    ts->userbuf.ptr = ubuf;                }                if (ts->listener) {                    ts->listener(ts->filename, ts->lineno, ts->userbuf.ptr, len,                                 &ts->listenerTSData, ts->listenerData);                }                nl = ts->saveEOL;                if (!nl) {                    /*                     * Any one of \n, \r, or \r\n ends a line (the longest                     * match wins).  Also allow the Unicode line and paragraph                     * separators.                     */                    for (nl = ts->userbuf.ptr; nl < ts->userbuf.limit; nl++) {                        /*                         * Try to prevent value-testing on most characters by                         * filtering out characters that aren't 000x or 202x.                         */                        if ((*nl & 0xDFD0) == 0) {                            if (*nl == '\n')                                break;                            if (*nl == '\r') {                                if (nl + 1 < ts->userbuf.limit && nl[1] == '\n')                                    nl++;                                break;                            }                            if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR)                                break;                        }                    }                }                /*                 * If there was a line terminator, copy thru it into linebuf.                 * Else copy JS_LINE_LIMIT-1 bytes into linebuf.                 */                if (nl < ts->userbuf.limit)                    len = PTRDIFF(nl, ts->userbuf.ptr, jschar) + 1;                if (len >= JS_LINE_LIMIT) {                    len = JS_LINE_LIMIT - 1;                    ts->saveEOL = nl;                } else {                    ts->saveEOL = NULL;                }                js_strncpy(ts->linebuf.base, ts->userbuf.ptr, len);                ts->userbuf.ptr += len;                olen = len;                /*                 * Make sure linebuf contains \n for EOL (don't do this in                 * userbuf because the user's string might be readonly).                 */                if (nl < ts->userbuf.limit) {                    if (*nl == '\r') {                        if (ts->linebuf.base[len-1] == '\r') {                            /*                             * Does the line segment end in \r?  We must check                             * for a \n at the front of the next segment before                             * storing a \n into linebuf.  This case matters                             * only when we're reading from a file.                             */                            if (nl + 1 == ts->userbuf.limit && ts->file) {                                len--;                                ts->flags |= TSF_CRFLAG; /* clear NLFLAG? */                                if (len == 0) {                                    /*                                     * This can happen when a segment ends in                                     * \r\r.  Start over.  ptr == limit in this                                     * case, so we'll fall into buffer-filling                                     * code.                                     */                                    return GetChar(ts);                                }                            } else {                                ts->linebuf.base[len-1] = '\n';                            }                        }                    } else if (*nl == '\n') {                        if (nl > ts->userbuf.base &&                            nl[-1] == '\r' &&                            ts->linebuf.base[len-2] == '\r') {                            len--;                            JS_ASSERT(ts->linebuf.base[len] == '\n');                            ts->linebuf.base[len-1] = '\n';                        }                    } else if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR) {                        ts->linebuf.base[len-1] = '\n';                    }                }                /* Reset linebuf based on adjusted segment length. */                ts->linebuf.limit = ts->linebuf.base + len;                ts->linebuf.ptr = ts->linebuf.base;                /* Update position of linebuf within physical userbuf line. */                if (!(ts->flags & TSF_NLFLAG))                    ts->linepos += ts->linelen;                else                    ts->linepos = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -