github.com/dancsecs/gotomd@v0.0.0-20240310162206-65c4805cf510/cmd_parse.go (about) 1 /* 2 Golang To Github Markdown Utility: gotomd 3 Copyright (C) 2023, 2024 Leslie Dancsecs 4 5 This program is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <https://www.gnu.org/licenses/>. 17 */ 18 19 package main 20 21 import ( 22 "fmt" 23 "os" 24 "path/filepath" 25 "regexp" 26 "strings" 27 ) 28 29 func parseCmd(cmd string) (string, string, error) { 30 if !strings.HasPrefix(cmd, "./") { 31 return "", "", fmt.Errorf("%w: %q", ErrInvalidRelativeDir, cmd) 32 } 33 34 lastSeparatorPos := strings.LastIndex(cmd, string(os.PathSeparator)) 35 dir := strings.TrimSpace(cmd[:lastSeparatorPos]) 36 action := strings.TrimSpace(cmd[lastSeparatorPos+1:]) 37 s, err := os.Stat(dir) 38 39 if err != nil || !s.IsDir() { 40 return "", 41 "", 42 fmt.Errorf("%w: %q", ErrInvalidDirectory, dir) 43 } 44 45 if action == "" { 46 return "", "", ErrMissingAction 47 } 48 49 return dir, action, nil 50 } 51 52 // ParseCmds parses cmd strings into arrays of directories and actions. 53 // Directories are validated while the actions are context sensitive. 54 // The first entry must contain a relative directory component however 55 // subsequent entries that do not specify a directory will default to 56 // the last directory defined. 57 func parseCmds(cmdStr string) ([]string, []string, error) { 58 var ( 59 lastDir string 60 dir, action string 61 err error 62 dirs, actions []string 63 ) 64 65 cmds := regexp.MustCompile(`[\s\t]+`).Split(cmdStr, -1) 66 67 for i, mi := 0, len(cmds); i < mi && err == nil; i++ { 68 cmd := cmds[i] 69 if lastDir != "" && 70 strings.LastIndex(cmd, string(os.PathSeparator)) < 0 { 71 cmd = "." + string(os.PathSeparator) + filepath.Join(lastDir, cmd) 72 } 73 74 dir, action, err = parseCmd(cmd) 75 if err == nil { 76 dirs = append(dirs, dir) 77 actions = append(actions, action) 78 lastDir = dir 79 } 80 } 81 82 if err != nil { 83 return nil, nil, err 84 } 85 86 return dirs, actions, nil 87 }