Mirror of BoringSSL (grpc依赖)
https://boringssl.googlesource.com/boringssl
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
258 lines
6.9 KiB
258 lines
6.9 KiB
// Copyright (c) 2017, Google Inc. |
|
// |
|
// Permission to use, copy, modify, and/or distribute this software for any |
|
// purpose with or without fee is hereby granted, provided that the above |
|
// copyright notice and this permission notice appear in all copies. |
|
// |
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
|
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
|
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
|
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
|
|
package main |
|
|
|
import ( |
|
"bytes" |
|
"fmt" |
|
"io/ioutil" |
|
"os" |
|
"strings" |
|
) |
|
|
|
// convert_comments.go converts C-style block comments to C++-style line |
|
// comments. A block comment is converted if all of the following are true: |
|
// |
|
// * The comment begins after the first blank line, to leave the license |
|
// blocks alone. |
|
// |
|
// * There are no characters between the '*/' and the end of the line. |
|
// |
|
// * Either one of the following are true: |
|
// |
|
// - The comment fits on one line. |
|
// |
|
// - Each line the comment spans begins with N spaces, followed by '/*' for |
|
// the initial line or ' *' for subsequent lines, where N is the same for |
|
// each line. |
|
// |
|
// This tool is a heuristic. While it gets almost all cases correct, the final |
|
// output should still be looked over and fixed up as needed. |
|
|
|
// allSpaces returns true if |s| consists entirely of spaces. |
|
func allSpaces(s string) bool { |
|
return strings.IndexFunc(s, func(r rune) bool { return r != ' ' }) == -1 |
|
} |
|
|
|
// isContinuation returns true if |s| is a continuation line for a multi-line |
|
// comment indented to the specified column. |
|
func isContinuation(s string, column int) bool { |
|
if len(s) < column+2 { |
|
return false |
|
} |
|
if !allSpaces(s[:column]) { |
|
return false |
|
} |
|
return s[column:column+2] == " *" |
|
} |
|
|
|
// indexFrom behaves like strings.Index but only reports matches starting at |
|
// |idx|. |
|
func indexFrom(s, sep string, idx int) int { |
|
ret := strings.Index(s[idx:], sep) |
|
if ret < 0 { |
|
return -1 |
|
} |
|
return idx + ret |
|
} |
|
|
|
// A lineGroup is a contiguous group of lines with an eligible comment at the |
|
// same column. Any trailing '*/'s will already be removed. |
|
type lineGroup struct { |
|
// column is the column where the eligible comment begins. line[column] |
|
// and line[column+1] will both be replaced with '/'. It is -1 if this |
|
// group is not to be converted. |
|
column int |
|
lines []string |
|
} |
|
|
|
func addLine(groups *[]lineGroup, line string, column int) { |
|
if len(*groups) == 0 || (*groups)[len(*groups)-1].column != column { |
|
*groups = append(*groups, lineGroup{column, nil}) |
|
} |
|
(*groups)[len(*groups)-1].lines = append((*groups)[len(*groups)-1].lines, line) |
|
} |
|
|
|
// writeLine writes |line| to |out|, followed by a newline. |
|
func writeLine(out *bytes.Buffer, line string) { |
|
out.WriteString(line) |
|
out.WriteByte('\n') |
|
} |
|
|
|
func convertComments(path string, in []byte) []byte { |
|
lines := strings.Split(string(in), "\n") |
|
|
|
// Account for the trailing newline. |
|
if len(lines) > 0 && len(lines[len(lines)-1]) == 0 { |
|
lines = lines[:len(lines)-1] |
|
} |
|
|
|
// First pass: identify all comments to be converted. Group them into |
|
// lineGroups with the same column. |
|
var groups []lineGroup |
|
|
|
// Find the license block separator. |
|
for len(lines) > 0 { |
|
line := lines[0] |
|
lines = lines[1:] |
|
addLine(&groups, line, -1) |
|
if len(line) == 0 { |
|
break |
|
} |
|
} |
|
|
|
// inComment is true if we are in the middle of a comment. |
|
var inComment bool |
|
// comment is the currently buffered multi-line comment to convert. If |
|
// |inComment| is true and it is nil, the current multi-line comment is |
|
// not convertable and we copy lines to |out| as-is. |
|
var comment []string |
|
// column is the column offset of |comment|. |
|
var column int |
|
for len(lines) > 0 { |
|
line := lines[0] |
|
lines = lines[1:] |
|
|
|
var idx int |
|
if inComment { |
|
// Stop buffering if this comment isn't eligible. |
|
if comment != nil && !isContinuation(line, column) { |
|
for _, l := range comment { |
|
addLine(&groups, l, -1) |
|
} |
|
comment = nil |
|
} |
|
|
|
// Look for the end of the current comment. |
|
idx = strings.Index(line, "*/") |
|
if idx < 0 { |
|
if comment != nil { |
|
comment = append(comment, line) |
|
} else { |
|
addLine(&groups, line, -1) |
|
} |
|
continue |
|
} |
|
|
|
inComment = false |
|
if comment != nil { |
|
if idx == len(line)-2 { |
|
// This is a convertable multi-line comment. |
|
if idx >= column+2 { |
|
// |idx| may be equal to |
|
// |column| + 1, if the line is |
|
// a '*/' on its own. In that |
|
// case, we discard the line. |
|
comment = append(comment, line[:idx]) |
|
} |
|
for _, l := range comment { |
|
addLine(&groups, l, column) |
|
} |
|
comment = nil |
|
continue |
|
} |
|
|
|
// Flush the buffered comment unmodified. |
|
for _, l := range comment { |
|
addLine(&groups, l, -1) |
|
} |
|
comment = nil |
|
} |
|
idx += 2 |
|
} |
|
|
|
// Parse starting from |idx|, looking for either a convertable |
|
// line comment or a multi-line comment. |
|
for { |
|
idx = indexFrom(line, "/*", idx) |
|
if idx < 0 { |
|
addLine(&groups, line, -1) |
|
break |
|
} |
|
|
|
endIdx := indexFrom(line, "*/", idx) |
|
if endIdx < 0 { |
|
// The comment is, so far, eligible for conversion. |
|
inComment = true |
|
column = idx |
|
comment = []string{line} |
|
break |
|
} |
|
|
|
if endIdx != len(line)-2 { |
|
// Continue parsing for more comments in this line. |
|
idx = endIdx + 2 |
|
continue |
|
} |
|
|
|
addLine(&groups, line[:endIdx], idx) |
|
break |
|
} |
|
} |
|
|
|
// Second pass: convert the lineGroups, adjusting spacing as needed. |
|
var out bytes.Buffer |
|
var lineNo int |
|
for _, group := range groups { |
|
if group.column < 0 { |
|
for _, line := range group.lines { |
|
writeLine(&out, line) |
|
} |
|
} else { |
|
// Google C++ style prefers two spaces before a comment |
|
// if it is on the same line as code, but clang-format |
|
// has been placing one space for block comments. All |
|
// comments within a group should be adjusted by the |
|
// same amount. |
|
var adjust string |
|
for _, line := range group.lines { |
|
if !allSpaces(line[:group.column]) && line[group.column-1] != '(' { |
|
if line[group.column-1] != ' ' { |
|
if len(adjust) < 2 { |
|
adjust = " " |
|
} |
|
} else if line[group.column-2] != ' ' { |
|
if len(adjust) < 1 { |
|
adjust = " " |
|
} |
|
} |
|
} |
|
} |
|
|
|
for i, line := range group.lines { |
|
newLine := fmt.Sprintf("%s%s//%s", line[:group.column], adjust, strings.TrimRight(line[group.column+2:], " ")) |
|
if len(newLine) > 80 { |
|
fmt.Fprintf(os.Stderr, "%s:%d: Line is now longer than 80 characters\n", path, lineNo+i+1) |
|
} |
|
writeLine(&out, newLine) |
|
} |
|
|
|
} |
|
lineNo += len(group.lines) |
|
} |
|
return out.Bytes() |
|
} |
|
|
|
func main() { |
|
for _, arg := range os.Args[1:] { |
|
in, err := ioutil.ReadFile(arg) |
|
if err != nil { |
|
panic(err) |
|
} |
|
if err := ioutil.WriteFile(arg, convertComments(arg, in), 0666); err != nil { |
|
panic(err) |
|
} |
|
} |
|
}
|
|
|