Add support for XUL preprocessor line/file coercion (243359, r=bryner).

This commit is contained in:
brendan%mozilla.org 2004-06-11 00:55:59 +00:00
Родитель 41f7ad6178
Коммит 7184dfb8b0
5 изменённых файлов: 84 добавлений и 1 удалений

Просмотреть файл

@ -586,6 +586,7 @@ static struct {
} js_options[] = {
{"strict", JSOPTION_STRICT},
{"werror", JSOPTION_WERROR},
{"atline", JSOPTION_ATLINE},
{0, 0}
};

Просмотреть файл

@ -442,6 +442,10 @@ JS_StringToVersion(const char *string);
script once only; enables
compile-time scope chain
resolution of consts. */
#define JSOPTION_ATLINE JS_BIT(5) /* //@line number ["filename"]
option supported for the
XUL preprocessor and kindred
beasts. */
extern JS_PUBLIC_API(uint32)
JS_GetOptions(JSContext *cx);

Просмотреть файл

@ -421,6 +421,7 @@ struct JSContext {
#define JS_HAS_STRICT_OPTION(cx) ((cx)->options & JSOPTION_STRICT)
#define JS_HAS_WERROR_OPTION(cx) ((cx)->options & JSOPTION_WERROR)
#define JS_HAS_COMPILE_N_GO_OPTION(cx) ((cx)->options & JSOPTION_COMPILE_N_GO)
#define JS_HAS_ATLINE_OPTION(cx) ((cx)->options & JSOPTION_ATLINE)
extern JSContext *
js_NewContext(JSRuntime *rt, size_t stackChunkSize);

Просмотреть файл

@ -265,6 +265,8 @@ js_NewFileTokenStream(JSContext *cx, const char *filename, FILE *defaultfp)
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;
@ -738,6 +740,8 @@ GetUnicodeEscape(JSTokenStream *ts)
return '\\';
}
#define JS_FILENAME_MAX 1024
JSTokenType
js_GetToken(JSContext *cx, JSTokenStream *ts)
{
@ -1128,6 +1132,78 @@ retry:
case '/':
if (MatchChar(ts, '/')) {
/*
* Hack for source filters such as the Mozilla XUL preprocessor:
* "//@line 123\n" sets the line number to 123 of the *next* line
* after the comment to 123.
*/
if (JS_HAS_ATLINE_OPTION(cx)) {
jschar cp[5];
uintN i, line, temp;
char filename[JS_FILENAME_MAX];
if (PeekChars(ts, 5, cp) &&
cp[0] == '@' &&
cp[1] == 'l' &&
cp[2] == 'i' &&
cp[3] == 'n' &&
cp[4] == 'e') {
SkipChars(ts, 5);
while ((c = GetChar(ts)) != EOF && JS_ISSPACE(c)) {
if (c == '\n')
break;
}
if (JS7_ISDEC(c)) {
line = JS7_UNDEC(c);
while ((c = GetChar(ts)) != EOF && JS7_ISDEC(c)) {
temp = 10 * line + JS7_UNDEC(c);
if (temp < line) {
/* Ignore overlarge line numbers. */
goto skipline;
}
line = temp;
}
while (JS_ISSPACE(c) && c != '\n') {
c = GetChar(ts);
if (c == EOF)
break;
}
i = 0;
if (c == '"') {
while ((c = GetChar(ts)) != EOF && c != '"') {
if (c == '\n') {
UngetChar(ts, c);
goto skipline;
}
if ((c >> 8) != 0 || i >= JS_FILENAME_MAX)
goto skipline;
filename[i++] = (char) c;
}
if (c == '"') {
while ((c = GetChar(ts)) != EOF &&
JS_ISSPACE(c)) {
if (c == '\n')
break;
}
}
}
filename[i] = '\0';
if (c == '\n') {
if (filename[0]) {
if (ts->flags & TSF_OWNFILENAME)
JS_free(cx, (void *) ts->filename);
ts->filename = JS_strdup(cx, filename);
if (!ts->filename)
RETURN(TOK_ERROR);
ts->flags |= TSF_OWNFILENAME;
}
ts->lineno = line;
}
}
UngetChar(ts, c);
}
}
skipline:
while ((c = GetChar(ts)) != EOF && c != '\n')
/* skip to end of line */;

Просмотреть файл

@ -185,7 +185,8 @@ struct JSTokenStream {
#define TSF_REGEXP 0x08 /* looking for a regular expression */
#define TSF_NLFLAG 0x20 /* last linebuf ended with \n */
#define TSF_CRFLAG 0x40 /* linebuf would have ended with \r */
#define TSF_DIRTYLINE 0x80 /* stuff other than whitespace since start of line */
#define TSF_DIRTYLINE 0x80 /* non-whitespace since start of line */
#define TSF_OWNFILENAME 0x100 /* ts->filename is malloc'd */
/* Unicode separators that are treated as line terminators, in addition to \n, \r */
#define LINE_SEPARATOR 0x2028