parse.y: magic comment w/o indicators

* parse.y (parser_magic_comment): allow a sole magic comment without
  indicators, neither other non-space comments.  [Feature #8976]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52208 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2015-10-21 09:34:09 +00:00
Родитель 5fe6919344
Коммит a76fdea9fc
3 изменённых файлов: 50 добавлений и 8 удалений

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

@ -1,3 +1,8 @@
Wed Oct 21 18:34:06 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
* parse.y (parser_magic_comment): allow a sole magic comment without
indicators, neither other non-space comments. [Feature #8976]
Tue Oct 20 12:17:56 2015 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
* lib/prime.rb: Add basic argument checking to Prime.prime?

25
parse.y
Просмотреть файл

@ -6978,6 +6978,7 @@ magic_comment_marker(const char *str, long len)
static int
parser_magic_comment(struct parser_params *parser, const char *str, long len)
{
int indicator = 0;
VALUE name = 0, val = 0;
const char *beg, *end, *vbeg, *vend;
#define str_copy(_s, _p, _n) ((_s) \
@ -6986,10 +6987,13 @@ parser_magic_comment(struct parser_params *parser, const char *str, long len)
: (void)((_s) = STR_NEW((_p), (_n))))
if (len <= 7) return FALSE;
if (!(beg = magic_comment_marker(str, len))) return FALSE;
if (!(end = magic_comment_marker(beg, str + len - beg))) return FALSE;
str = beg;
len = end - beg - 3;
if (!!(beg = magic_comment_marker(str, len))) {
if (!(end = magic_comment_marker(beg, str + len - beg)))
return FALSE;
indicator = TRUE;
str = beg;
len = end - beg - 3;
}
/* %r"([^\\s\'\":;]+)\\s*:\\s*(\"(?:\\\\.|[^\"])*\"|[^\"\\s;]+)[\\s;]*" */
while (len > 0) {
@ -7017,7 +7021,10 @@ parser_magic_comment(struct parser_params *parser, const char *str, long len)
}
for (end = str; len > 0 && ISSPACE(*str); str++, --len);
if (!len) break;
if (*str != ':') continue;
if (*str != ':') {
if (!indicator) return FALSE;
continue;
}
do str++; while (--len > 0 && ISSPACE(*str));
if (!len) break;
@ -7038,7 +7045,13 @@ parser_magic_comment(struct parser_params *parser, const char *str, long len)
for (vbeg = str; len > 0 && *str != '"' && *str != ';' && !ISSPACE(*str); --len, str++);
vend = str;
}
while (len > 0 && (*str == ';' || ISSPACE(*str))) --len, str++;
if (indicator) {
while (len > 0 && (*str == ';' || ISSPACE(*str))) --len, str++;
}
else {
while (len > 0 && (ISSPACE(*str))) --len, str++;
if (len) return FALSE;
}
n = end - beg;
str_copy(name, beg, n);

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

@ -123,14 +123,38 @@ class TestRubyLiteral < Test::Unit::TestCase
def test_frozen_string
all_assertions do |a|
a.for("false") do
a.for("false with indicator") do
str = eval("# -*- frozen-string-literal: false -*-\n""'foo'")
assert_not_predicate(str, :frozen?)
end
a.for("true") do
a.for("true with indicator") do
str = eval("# -*- frozen-string-literal: true -*-\n""'foo'")
assert_predicate(str, :frozen?)
end
a.for("false without indicator") do
str = eval("# frozen-string-literal: false\n""'foo'")
assert_not_predicate(str, :frozen?)
end
a.for("true without indicator") do
str = eval("# frozen-string-literal: true\n""'foo'")
assert_predicate(str, :frozen?)
end
a.for("false with preceding garbage") do
str = eval("# x frozen-string-literal: false\n""'foo'")
assert_not_predicate(str, :frozen?)
end
a.for("true with preceding garbage") do
str = eval("# x frozen-string-literal: true\n""'foo'")
assert_not_predicate(str, :frozen?)
end
a.for("false with succeeding garbage") do
str = eval("# frozen-string-literal: false x\n""'foo'")
assert_not_predicate(str, :frozen?)
end
a.for("true with succeeding garbage") do
str = eval("# frozen-string-literal: true x\n""'foo'")
assert_not_predicate(str, :frozen?)
end
end
end