diff options
| author | Shulhan <ms@kilabit.info> | 2025-10-03 00:15:29 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2025-10-03 00:15:29 +0700 |
| commit | 1003a18b85cffac4b9a92ee787fd8a9bdfca072d (patch) | |
| tree | 2090d7c2b84dbd4cc39956145af3c070ba98f7ee /statement.go | |
| parent | 276096698be34a7c629b3fe7bfd79c48e1c24921 (diff) | |
| download | awwan-1003a18b85cffac4b9a92ee787fd8a9bdfca072d.tar.xz | |
all: add option "$noparse" for magic "#put" command
The "$noparse" option allow copying file without reading and parsing
the input file.
Diffstat (limited to 'statement.go')
| -rw-r--r-- | statement.go | 80 |
1 files changed, 54 insertions, 26 deletions
diff --git a/statement.go b/statement.go index 1d33e8e..69cb60b 100644 --- a/statement.go +++ b/statement.go @@ -11,6 +11,7 @@ import ( "strconv" "strings" + libascii "git.sr.ht/~shulhan/pakakeh.go/lib/ascii" libexec "git.sr.ht/~shulhan/pakakeh.go/lib/os/exec" ) @@ -53,6 +54,10 @@ type Statement struct { raw []byte mode fs.FileMode kind int + + // Option "$noparse" copy the file directly without parsing for + // session variables inside the file. + optNoparse bool } // ParseStatement create and initialize new Statement from raw line. @@ -180,7 +185,7 @@ func parseStatementGetPut(kind int, raw []byte) (stmt *Statement, err error) { } if raw[0] != ' ' && raw[0] != '\t' { - raw, err = stmt.parseOwnerMode(raw) + raw, err = stmt.parseGetPutOptions(raw) if err != nil { return nil, err } @@ -203,49 +208,72 @@ func parseStatementGetPut(kind int, raw []byte) (stmt *Statement, err error) { return stmt, nil } -// parseOwnerMode parse the owner and optionally the file mode for +// parseGetPutOptions parse the owner and optionally the file mode for // destination file. // The owner and mode has the following syntax, // -// [ USER [ ":" GROUP ]][ "+" MODE ] +// [ USER [ ":" GROUP ]][ "+" MODE ][ "$" OPT ] // // The USER and/or GROUP is optional, its accept the value as in "chown". // The MODE also optional, its value must be an octal. -func (stmt *Statement) parseOwnerMode(in []byte) (out []byte, err error) { - var ( - sepSpace = " \t" - sepMode = "+" - - tmp []byte - idx int - ) - - idx = bytes.IndexAny(in, sepSpace) +// The OPT also optional, its affect how the file processed before copying. +func (stmt *Statement) parseGetPutOptions(in []byte) (out []byte, err error) { + var idx = bytes.IndexAny(in, " \t") if idx < 0 { return nil, nil } - tmp = in[:idx] + var tmp = in[:idx] out = in[idx+1:] - idx = bytes.IndexAny(tmp, sepMode) - if idx < 0 { - stmt.owner = string(tmp) - } else { - stmt.owner = string(tmp[:idx]) - - var ( - modeString = string(tmp[idx+1:]) - mode uint64 - ) - + if libascii.IsAlpha(tmp[0]) { + idx = bytes.IndexAny(tmp, "+$") + if idx < 0 { + stmt.owner = string(tmp) + tmp = nil + } else { + stmt.owner = string(tmp[:idx]) + tmp = tmp[idx:] + } + } + if len(tmp) == 0 { + return out, nil + } + if tmp[0] == '+' { + tmp = tmp[1:] + idx = bytes.IndexAny(tmp, "$") + var modeString string + if idx < 0 { + modeString = string(tmp) + tmp = nil + } else { + modeString = string(tmp[:idx]) + tmp = tmp[idx:] + } + var mode uint64 mode, err = strconv.ParseUint(modeString, 8, 32) if err != nil { return nil, err } - stmt.mode = fs.FileMode(mode) } + var opt string + for len(tmp) > 0 { + tmp = tmp[1:] + idx = bytes.IndexAny(tmp, "$") + if idx < 0 { + opt = string(tmp) + tmp = nil + } else { + opt = string(tmp[:idx]) + tmp = tmp[idx:] + } + opt = strings.ToLower(opt) + switch opt { + case "noparse": + stmt.optNoparse = true + } + } return out, nil } |
