github.com/richardwilkes/toolbox@v1.121.0/cmdline/parse.go (about) 1 // Copyright (c) 2016-2024 by Richard A. Wilkes. All rights reserved. 2 // 3 // This Source Code Form is subject to the terms of the Mozilla Public 4 // License, version 2.0. If a copy of the MPL was not distributed with 5 // this file, You can obtain one at http://mozilla.org/MPL/2.0/. 6 // 7 // This Source Code Form is "Incompatible With Secondary Licenses", as 8 // defined by the Mozilla Public License, version 2.0. 9 10 package cmdline 11 12 import ( 13 "fmt" 14 15 "github.com/richardwilkes/toolbox/errs" 16 ) 17 18 // Parse a command line string into its component parts. 19 func Parse(command string) ([]string, error) { 20 var args []string 21 var current []rune 22 var lookingForQuote rune 23 var escapeNext bool 24 for _, ch := range command { 25 switch { 26 case escapeNext: 27 current = append(current, ch) 28 escapeNext = false 29 case lookingForQuote == ch: 30 args = append(args, string(current)) 31 current = nil 32 lookingForQuote = 0 33 case lookingForQuote != 0: 34 current = append(current, ch) 35 case ch == '\\': 36 escapeNext = true 37 case ch == '"' || ch == '\'': 38 lookingForQuote = ch 39 case ch == ' ' || ch == '\t': 40 if len(current) != 0 { 41 args = append(args, string(current)) 42 current = nil 43 } 44 default: 45 current = append(current, ch) 46 } 47 } 48 if lookingForQuote != 0 { 49 return nil, errs.New(fmt.Sprintf("unclosed quote in command line:\n%s", command)) 50 } 51 if len(current) != 0 { 52 args = append(args, string(current)) 53 } 54 return args, nil 55 }