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

📄 jsscan.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 5 页
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim: set sw=4 ts=8 et tw=78: * * ***** 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"#include "jsscript.h"#if JS_HAS_XML_SUPPORT#include "jsparse.h"#include "jsxml.h"#endif#define JS_KEYWORD(keyword, type, op, version) \    const char js_##keyword##_str[] = #keyword;#include "jskeyword.tbl"#undef JS_KEYWORDstruct keyword {    const char  *chars;         /* C string with keyword text */    JSTokenType tokentype;      /* JSTokenType */    JSOp        op;             /* JSOp */    JSVersion   version;        /* JSVersion */};static const struct keyword keyword_defs[] = {#define JS_KEYWORD(keyword, type, op, version) \    {js_##keyword##_str, type, op, version},#include "jskeyword.tbl"#undef JS_KEYWORD};#define KEYWORD_COUNT (sizeof keyword_defs / sizeof keyword_defs[0])static const struct keyword *FindKeyword(const jschar *s, size_t length){    register size_t i;    const struct keyword *kw;    const char *chars;    JS_ASSERT(length != 0);#define JSKW_LENGTH()           length#define JSKW_AT(column)         s[column]#define JSKW_GOT_MATCH(index)   i = (index); goto got_match;#define JSKW_TEST_GUESS(index)  i = (index); goto test_guess;#define JSKW_NO_MATCH()         goto no_match;#include "jsautokw.h"#undef JSKW_NO_MATCH#undef JSKW_TEST_GUESS#undef JSKW_GOT_MATCH#undef JSKW_AT#undef JSKW_LENGTH  got_match:    return &keyword_defs[i];  test_guess:    kw = &keyword_defs[i];    chars = kw->chars;    do {        if (*s++ != (unsigned char)(*chars++))            goto no_match;    } while (--length != 0);    return kw;  no_match:    return NULL;}JSTokenTypejs_CheckKeyword(const jschar *str, size_t length){    const struct keyword *kw;    JS_ASSERT(length != 0);    kw = FindKeyword(str, length);    return kw ? kw->tokentype : TOK_EOF;}JS_FRIEND_API(void)js_MapKeywords(void (*mapfun)(const char *)){    size_t i;    for (i = 0; i != KEYWORD_COUNT; ++i)        mapfun(keyword_defs[i].chars);}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;}#define TBMIN   64static JSBoolGrowTokenBuf(JSStringBuffer *sb, size_t newlength){    JSContext *cx;    jschar *base;    ptrdiff_t offset, length;    size_t tbsize;    JSArenaPool *pool;    cx = sb->data;    base = sb->base;    offset = PTRDIFF(sb->ptr, base, jschar);    pool = &cx->tempPool;    if (!base) {        tbsize = TBMIN * sizeof(jschar);        length = TBMIN - 1;        JS_ARENA_ALLOCATE_CAST(base, jschar *, pool, tbsize);    } else {        length = PTRDIFF(sb->limit, base, jschar);        if ((size_t)length >= ~(size_t)0 / sizeof(jschar)) {            base = NULL;        } else {            tbsize = (length + 1) * sizeof(jschar);            length += length + 1;            JS_ARENA_GROW_CAST(base, jschar *, pool, tbsize, tbsize);        }    }    if (!base) {        JS_ReportOutOfMemory(cx);        sb->base = STRING_BUFFER_ERROR_BASE;        return JS_FALSE;    }    sb->base = base;    sb->limit = base + length;    sb->ptr = base + offset;    return JS_TRUE;}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->tokenbuf.grow = GrowTokenBuf;    ts->tokenbuf.data = cx;    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->flags & TSF_OWNFILENAME)        JS_free(cx, (void *) ts->filename);    if (ts->principals)        JSPRINCIPALS_DROP(cx, ts->principals);    return !ts->file || fclose(ts->file) == 0;}JS_FRIEND_API(int)js_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 = js_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) {                                    /*

⌨️ 快捷键说明

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