aliyunpan/cmder/cmdliner/args/args.go
2021-10-10 10:48:53 +08:00

98 lines
2.4 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright (c) 2020 tickstep.
//
// 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 args
import (
"strings"
"unicode"
)
const (
CharEscape = '\\'
CharSingleQuote = '\''
CharDoubleQuote = '"'
CharBackQuote = '`'
)
// IsQuote 是否为引号
func IsQuote(r rune) bool {
return r == CharSingleQuote || r == CharDoubleQuote || r == CharBackQuote
}
// Parse 解析line, 忽略括号
func Parse(line string) (lineArgs []string) { // 在函数中定义的返回值变量,会自动赋为 zero-value即相当于 var lineArgs string[]
var (
rl = []rune(line + " ")
buf = strings.Builder{}
quoteChar rune
nextChar rune
escaped bool
in bool
)
var (
isSpace bool
)
for k, r := range rl {
isSpace = unicode.IsSpace(r)
if !isSpace && !in {
in = true
}
switch {
case escaped: // 已转义, 跳过
escaped = false
//pass
case r == CharEscape: // 转义模式
if k+1+1 < len(rl) { // 不是最后一个字符, 多+1是因为最后一个空格
nextChar = rl[k+1]
// 仅支持转义这些字符, 否则原样输出反斜杠
if unicode.IsSpace(nextChar) || IsQuote(nextChar) || nextChar == CharEscape {
escaped = true
continue
}
}
// pass
case IsQuote(r):
if quoteChar == 0 { //未引
quoteChar = r
continue
}
if quoteChar == r { //取消引
quoteChar = 0
continue
}
case isSpace:
if !in { // 忽略多余的空格
continue
}
if quoteChar == 0 { // 未在引号内
lineArgs = append(lineArgs, buf.String())
buf.Reset()
in = false
continue
}
}
buf.WriteRune(r)
}
// Go 允许在定义函数时,命名返回值,当然这些变量可以在函数中使用。
// 在 return 语句中无需显示的返回这些值Go 会自动将其返回。当然 return 语句还是必须要写的,否则编译器会报错。
// 相当于 return lineArgs
return
}