読者です 読者をやめる 読者になる 読者になる

opts-goを使ってみた

前回echoを書いてみたのですが、flagパッケージでは"-en"みたいな指定ができませんでした。それで、opts-goというものを代わりに使ってみました。"POSIX- and GNU-style options for go"って書いてあります。"-en"くらい扱ってくれそうですね。

ところが、ダウンロードしても動かせないので"go fix"したのですが、container/vectorがGo 1にはもう無いということでした。vector.VectorStringはstringに書き換えて、


diff -r 304f35dae25c help.go
--- a/help.go Mon Sep 06 18:46:08 2010 -0400
+++ b/help.go Wed Apr 04 12:37:17 2012 +0900
@@ -6,9 +6,8 @@

import (
"fmt"
- "os"
"strings"
- "tabwriter"
+ "text/tabwriter"
)

var printHelp *bool
@@ -22,7 +21,7 @@
content string
}

-func (w *helpWriter) Write(data byte) (n int, err os.Error) {
+func (w *helpWriter) Write(data byte) (n int, err error) {
n = len(data)
w.content += string(data)
return
@@ -39,12 +38,12 @@
for _, opt := range optionList {
fmt.Print(" ")
if opt.Forms()[0] != "" {
- fmt.Print(opt.Forms()[0]+",")
+ fmt.Print(opt.Forms()[0] + ",")
}
fmt.Print("\t")
}
w.Flush()
- lines = strings.Split(hw.content, "\n", -1)
+ lines = strings.Split(hw.content, "\n")
return lines
}

diff -r 304f35dae25c opts.go
--- a/opts.go Mon Sep 06 18:46:08 2010 -0400
+++ b/opts.go Wed Apr 04 12:37:17 2012 +0900
@@ -11,7 +11,6 @@
"fmt"
"os"
"strings"
- "container/vector"
)

//
@@ -127,7 +126,6 @@

func (o genopt) Description() string { return o.description }

-
type flag struct {
genopt
dest *bool
@@ -171,13 +169,13 @@
type multi struct {
genopt
valuedesc string
- dest *vector.StringVector
+ dest
string
}

func (o multi) ArgName() string { return o.valuedesc }
func (o multi) Arg() int { return REQARG }
func (o multi) Invoke(arg string, _ Parsing) {
- (*o.dest).Push(arg)
+ o.dest = append(o.dest, arg)
}

// Stores an option of any kind
@@ -203,7 +201,7 @@

// Adds -- if there is none.
func makeLong(s string) string {
- s = "--" + strings.TrimLeft(s,"-")
+ s = "--" + strings.TrimLeft(s, "-")
return s
}

@@ -218,8 +216,8 @@
optionList = make(Option, 2*(len(old)+1))
copy(optionList, old)
}
- optionList = optionList[0:l+1]
- optionList[len(optionList)-1]=opt
+ optionList = optionList[0 : l+1]
+ optionList[len(optionList)-1] = opt
}

// Flag creates a new Flag-type option, and adds it, returning the destination.
@@ -301,8 +299,8 @@
}

// Multi creates a new Multi-type option, and adds it, returning the destination.
-func Multi(sform string, lform string, desc string, valuedesc string) *vector.StringVector {
- dest := &vector.StringVector{}
+func Multi(sform string, lform string, desc string, valuedesc string)
string {
+ dest := string{}
o := multi{
genopt: genopt{
shortform: makeShort(sform),
@@ -317,12 +315,12 @@
}

// ShortMulti is like Multi, but no long form is used.
-func ShortMulti(sform string, desc string, valuedesc string) *vector.StringVector {
+func ShortMulti(sform string, desc string, valuedesc string)
string {
return Multi(sform, "", desc, valuedesc)
}

// LongMulti is like Multi, but no short form is used.
-func LongMulti(lform string, desc string, valuedesc string) *vector.StringVector {
+func LongMulti(lform string, desc string, valuedesc string) []string {
return Multi("", lform, desc, valuedesc)
}

@@ -352,7 +350,7 @@
optsOver = true
case arg[1] == '-':
// long option
- argparts := strings.Split(arg, "=", 2)
+ argparts := strings.SplitN(arg, "=", 2)
var val string
if len(argparts) == 2 {
arg, val = argparts[0], argparts[1]
diff -r 304f35dae25c opts_test.go
--- a/opts_test.go Mon Sep 06 18:46:08 2010 -0400
+++ b/opts_test.go Wed Apr 04 12:37:17 2012 +0900
@@ -8,7 +8,7 @@
"os"
"testing"

- . "opts"
+ . "opts-go"
)

func TestXname(t *testing.T) {

echo.goも次のように変えたらうまくいきました。

package main

import (
"bufio"
"bytes"
"io"
flag "opts-go"
"os"
)

func eval(buf *bufio.Reader) string {
s := ""
for {
c, e := buf.ReadByte()
if e == io.EOF {
break
}
if c == '\\' {
n, e := buf.ReadByte()
if e == io.EOF {
break
}
switch {
case n == 'n':
c = '\n'
case c == 'a':
c = '\a'
}
}
s += string(c)
}
return s
}

var omitNewline = flag.Flag("n", "--nonewline", "don't print final newline")
var evalString = flag.Flag("e", "--eval", "eval meta character")

func main() {
flag.Parse()
s := ""
for i := 0; i < len(flag.Args); i++ {
if i > 0 {
s += " "
}
if *evalString {
s += eval(bufio.NewReader(bytes.NewBufferString(flag.Args[i])))
} else {
s += flag.Args[i]
}
}
if !*omitNewline {
s += "\n"
}
os.Stdout.WriteString(s)
}