github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/lang/expressions/statement.go (about) 1 package expressions 2 3 import ( 4 "errors" 5 6 "github.com/lmorg/murex/lang/expressions/noglob" 7 "github.com/lmorg/murex/utils/lists" 8 ) 9 10 type StatementT struct { 11 command []rune 12 parameters [][]rune 13 paramTemp []rune 14 namedPipes []string 15 cast []rune 16 17 // parser states 18 canHaveZeroLenStr bool // to get around $VARS being empty or unset 19 possibleGlob bool // to signal to NextParameter of a possible glob 20 asStatement bool // force murex to parse expression as statement 21 ignoreCrLf bool // allow '\' to escape a new line 22 validFunction bool // allow function(parameters...) in statement 23 } 24 25 func (st *StatementT) String() string { 26 if st == nil { 27 return "<nil>" 28 } 29 return string(st.command) 30 } 31 32 func (st *StatementT) Parameters() []string { 33 if st == nil { 34 return nil 35 } 36 37 params := make([]string, len(st.parameters)) 38 39 for i := range st.parameters { 40 params[i] = string(st.parameters[i]) 41 } 42 43 return params 44 } 45 46 func (tree *ParserT) nextParameter() error { 47 st := tree.statement 48 49 switch { 50 51 case len(st.command) == 0: 52 // no command yet so this must be a command 53 st.command = st.paramTemp 54 st.possibleGlob = false 55 st.validFunction = true 56 57 case st.possibleGlob: 58 // glob 59 st.possibleGlob = false 60 st.canHaveZeroLenStr = false 61 st.validFunction = true 62 63 if !tree.ExpandGlob() || lists.Match(noglob.GetNoGlobCmds(), st.String()) { 64 st.parameters = append(st.parameters, st.paramTemp) 65 break 66 } 67 v, err := tree.parseGlob(st.paramTemp) 68 if err != nil { 69 return err 70 } 71 if v == nil { 72 st.parameters = append(st.parameters, st.paramTemp) 73 break 74 } 75 for i := range v { 76 st.parameters = append(st.parameters, []rune(v[i])) 77 } 78 79 case st.canHaveZeroLenStr: 80 // variable, possibly zero length 81 st.parameters = append(st.parameters, st.paramTemp) 82 st.canHaveZeroLenStr = false 83 st.validFunction = true 84 85 case len(st.paramTemp) == 0: 86 // just empty space. Nothing to do 87 return nil 88 89 default: 90 // just a regular old parameter 91 st.parameters = append(st.parameters, st.paramTemp) 92 st.validFunction = true 93 } 94 95 st.paramTemp = []rune{} 96 return nil 97 } 98 99 func (st *StatementT) validate() error { 100 switch { 101 102 case len(st.command) == 0: 103 return errors.New("no command specified (empty command property)") 104 105 case st.command[0] == '$': 106 return errors.New("commands cannot begin with '$'. Please quote or escape this character") 107 108 case st.command[0] == '@' && len(st.command) > 1 && st.command[1] != '[': 109 return errors.New("commands cannot begin with '@'. Please quote or escape this character") 110 111 case st.command[0] == '%': 112 return errors.New("commands cannot begin with '%'. Please quote or escape this character") 113 114 default: 115 return nil 116 } 117 }