Skip to content

Instantly share code, notes, and snippets.

@evmar
Created May 14, 2013 16:12
Show Gist options
  • Save evmar/5577207 to your computer and use it in GitHub Desktop.
Save evmar/5577207 to your computer and use it in GitHub Desktop.
commit a9bddead99604b9fb7ee752e1cd4a87d6d52d2d9
Author: Evan Martin <martine@danga.com>
Date: Tue May 14 09:12:07 2013 -0700
make $0 embed a nul
diff --git a/src/lexer.cc b/src/lexer.cc
index 685fe81..0ba78b7 100644
--- a/src/lexer.cc
+++ b/src/lexer.cc
@@ -654,7 +654,7 @@ bool Lexer::ReadEvalString(EvalString* eval, bool path, string* err) {
}
++p;
yych = *p;
- goto yy126;
+ goto yy128;
yy96:
{
eval->AddText(StringPiece(start, p - start));
@@ -675,25 +675,30 @@ yy97:
}
yy99:
++p;
- if ((yych = *p) <= '/') {
- if (yych <= ' ') {
- if (yych == '\n') goto yy115;
- if (yych <= 0x1F) goto yy104;
- goto yy106;
- } else {
- if (yych <= '$') {
- if (yych <= '#') goto yy104;
- goto yy108;
+ if ((yych = *p) <= '0') {
+ if (yych <= '#') {
+ if (yych <= '\n') {
+ if (yych <= '\t') goto yy104;
+ goto yy117;
} else {
- if (yych == '-') goto yy110;
+ if (yych == ' ') goto yy106;
goto yy104;
}
+ } else {
+ if (yych <= ',') {
+ if (yych <= '$') goto yy108;
+ goto yy104;
+ } else {
+ if (yych <= '-') goto yy110;
+ if (yych <= '/') goto yy104;
+ goto yy112;
+ }
}
} else {
if (yych <= '^') {
if (yych <= ':') {
if (yych <= '9') goto yy110;
- goto yy112;
+ goto yy114;
} else {
if (yych <= '@') goto yy104;
if (yych <= 'Z') goto yy110;
@@ -705,7 +710,7 @@ yy99:
goto yy104;
} else {
if (yych <= 'z') goto yy110;
- if (yych <= '{') goto yy114;
+ if (yych <= '{') goto yy116;
goto yy104;
}
}
@@ -746,7 +751,7 @@ yy108:
yy110:
++p;
yych = *p;
- goto yy124;
+ goto yy126;
yy111:
{
eval->AddSpecial(StringPiece(start + 1, p - start - 1));
@@ -754,54 +759,63 @@ yy111:
}
yy112:
++p;
+ if (yybm[0+(yych = *p)] & 64) {
+ goto yy125;
+ }
{
- eval->AddText(StringPiece(":", 1));
+ eval->AddText(StringPiece("\0", 1));
continue;
}
yy114:
+ ++p;
+ {
+ eval->AddText(StringPiece(":", 1));
+ continue;
+ }
+yy116:
yych = *(q = ++p);
if (yybm[0+yych] & 32) {
- goto yy118;
+ goto yy120;
}
goto yy105;
-yy115:
+yy117:
++p;
yych = *p;
if (yybm[0+yych] & 16) {
- goto yy115;
+ goto yy117;
}
{
continue;
}
-yy118:
+yy120:
++p;
yych = *p;
if (yybm[0+yych] & 32) {
- goto yy118;
+ goto yy120;
}
- if (yych == '}') goto yy121;
+ if (yych == '}') goto yy123;
p = q;
goto yy105;
-yy121:
+yy123:
++p;
{
eval->AddSpecial(StringPiece(start + 2, p - start - 3));
continue;
}
-yy123:
+yy125:
++p;
yych = *p;
-yy124:
+yy126:
if (yybm[0+yych] & 64) {
- goto yy123;
+ goto yy125;
}
goto yy111;
-yy125:
+yy127:
++p;
yych = *p;
-yy126:
+yy128:
if (yybm[0+yych] & 128) {
- goto yy125;
+ goto yy127;
}
goto yy96;
}
diff --git a/src/lexer.in.cc b/src/lexer.in.cc
index 93d5540..86c8cf1 100644
--- a/src/lexer.in.cc
+++ b/src/lexer.in.cc
@@ -229,6 +229,10 @@ bool Lexer::ReadEvalString(EvalString* eval, bool path, string* err) {
"$\n"[ ]* {
continue;
}
+ "$0" {
+ eval->AddText(StringPiece("\0", 1));
+ continue;
+ }
"${"varname"}" {
eval->AddSpecial(StringPiece(start + 2, p - start - 3));
continue;
diff --git a/src/lexer_test.cc b/src/lexer_test.cc
index e8a1642..c4dcd87 100644
--- a/src/lexer_test.cc
+++ b/src/lexer_test.cc
@@ -38,6 +38,17 @@ TEST(Lexer, ReadEvalStringEscapes) {
eval.Serialize());
}
+TEST(Lexer, EmbeddedNul) {
+ Lexer lexer("nul is $0 is nul\n");
+ EvalString eval;
+ string err;
+ EXPECT_TRUE(lexer.ReadVarValue(&eval, &err));
+ EXPECT_EQ("", err);
+ string expected = "[nul is 0 is nul]";
+ expected[8] = '\0';
+ EXPECT_EQ(expected, eval.Serialize());
+}
+
TEST(Lexer, ReadIdent) {
Lexer lexer("foo baR baz_123 foo-bar");
string ident;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment