-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support '\r\n' separators when splitting Ninja files into separately ?
?parsed fragments. Closes #10210. PiperOrigin-RevId: 280170780
- Loading branch information
1 parent
ceadf0a
commit 7535d4c
Showing
12 changed files
with
281 additions
and
191 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
78 changes: 78 additions & 0 deletions
78
src/main/java/com/google/devtools/build/lib/bazel/rules/ninja/file/NinjaSeparatorFinder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// Copyright 2019 The Bazel Authors. All rights reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
|
||
package com.google.devtools.build.lib.bazel.rules.ninja.file; | ||
|
||
import com.google.common.base.Preconditions; | ||
|
||
/** | ||
* Implementation of {@link SeparatorFinder} for Ninja files. | ||
* | ||
* <p>The Ninja declaration consists of several text lines; if the line is a part of the previous | ||
* declaration, it starts with some amount of spaces or tabs. If the line is the beginning of the | ||
* new declaration, it starts with non-space symbol. Dollar symbol '$' escapes the newline, i.e. | ||
* "$\nsomething" does not contain a separator. | ||
* | ||
* <p>We support '\r\n' separators in Ninja files and throw {@link IncorrectSeparatorException} in | ||
* case an incorrect separator '\r' is used. | ||
*/ | ||
public class NinjaSeparatorFinder implements SeparatorFinder { | ||
public static final NinjaSeparatorFinder INSTANCE = new NinjaSeparatorFinder(); | ||
|
||
private static final byte DOLLAR_BYTE = '$'; | ||
private static final byte LINEFEED_BYTE = '\r'; | ||
private static final byte NEWLINE_BYTE = '\n'; | ||
private static final byte SPACE_BYTE = ' '; | ||
private static final byte TAB_BYTE = '\t'; | ||
|
||
private NinjaSeparatorFinder() {} | ||
|
||
@Override | ||
public int findNextSeparator(ByteBufferFragment fragment, int startingFrom, int untilExcluded) | ||
throws IncorrectSeparatorException { | ||
Preconditions.checkState(startingFrom < fragment.length()); | ||
Preconditions.checkState(untilExcluded < 0 || untilExcluded <= fragment.length()); | ||
|
||
boolean escaped = DOLLAR_BYTE == fragment.byteAt(startingFrom); | ||
int endExcl = untilExcluded > 0 ? untilExcluded : fragment.length(); | ||
for (int i = startingFrom + 1; i < endExcl - 1; i++) { | ||
byte current = fragment.byteAt(i); | ||
byte next = fragment.byteAt(i + 1); | ||
byte afterNextOrSpace = i < (endExcl - 2) ? fragment.byteAt(i + 2) : SPACE_BYTE; | ||
if (LINEFEED_BYTE == current && NEWLINE_BYTE != next) { | ||
throw new IncorrectSeparatorException( | ||
"Wrong newline separators: \\r should be followed by \\n."); | ||
} | ||
if (!escaped | ||
&& SPACE_BYTE != afterNextOrSpace | ||
&& TAB_BYTE != afterNextOrSpace | ||
&& LINEFEED_BYTE == current) { | ||
// To do not introduce the length of the separator, let us point to the last symbol of it. | ||
return i + 1; | ||
} | ||
if (!escaped && SPACE_BYTE != next && TAB_BYTE != next && NEWLINE_BYTE == current) { | ||
return i; | ||
} | ||
if (escaped && LINEFEED_BYTE == current) { | ||
// Jump over the whole escaped linefeed + newline. | ||
++i; | ||
escaped = false; | ||
} else { | ||
escaped = DOLLAR_BYTE == current; | ||
} | ||
} | ||
return -1; | ||
} | ||
} |
43 changes: 0 additions & 43 deletions
43
...in/java/com/google/devtools/build/lib/bazel/rules/ninja/file/NinjaSeparatorPredicate.java
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.