func NewServiceRPC(sd ServiceDelegate, log skynet.Logger) (srpc *ServiceRPC) { srpc = &ServiceRPC{ log: log, delegate: sd, methods: make(map[string]reflect.Value), } // scan through methods looking for a method (RequestInfo, something, something) error typ := reflect.TypeOf(srpc.delegate) for i := 0; i < typ.NumMethod(); i++ { m := typ.Method(i) if reservedMethodNames[m.Name] { continue } // this is the check to see if something is exported if m.PkgPath != "" { continue } f := m.Func ftyp := f.Type() // must have four parameters: (receiver, RequestInfo, somethingIn, somethingOut) if ftyp.NumIn() != 4 { goto problem } // don't have to check for the receiver // check the second parameter if ftyp.In(1) != RequestInfoPtrType { goto problem } // the somethingIn can be anything // somethingOut must be a pointer or a map switch ftyp.In(3).Kind() { case reflect.Ptr, reflect.Map: default: goto problem } // must have one return value that is an error if ftyp.NumOut() != 1 { goto problem } if ftyp.Out(0) != ErrorType { goto problem } // we've got a method! srpc.methods[m.Name] = f srpc.MethodNames = append(srpc.MethodNames, m.Name) continue problem: fmt.Println("trying to panic") fmt.Printf("Bad RPC method for %T: %q %v\n", sd, m.Name, f) nicetrace.WriteStacktrace(os.Stdout) panic(fmt.Sprintf("Bad RPC method for %T: %q %v\n", sd, m.Name, f)) } return }
func main() { defer nicetrace.WriteStacktrace(os.Stderr) var err error erf := func(format string, args ...interface{}) { fmt.Fprintf(os.Stderr, format, args...) } defer func() { if err != nil { erf("%v\n", err) } }() flag.StringVar(&LocalRoot, "r", ".", "Local package root") flag.BoolVar(&Usage, "?", false, "Print usage and quit") flag.Parse() norollCmds := map[string]func([]string) error{ "undo": UndoCmd, "scan": ScanCmd, "changes": ChangesCmd, "clear": ClearCmd, } rollCmds := map[string]func([]string) error{ "pkg": PkgCmd, "rename": RenameCmd, "move": MoveCmd, "moveall": MoveAllCmd, "merge": MergeCmd, } foo, ok := norollCmds[flag.Arg(0)] if ok && Usage { fmt.Print(Help(flag.Arg(0))) return } if !ok { foo, ok = rollCmds[flag.Arg(0)] err = RollbackUndos() if err != nil { return } if ok { var out io.Writer out, err = os.Create(filepath.Join(LocalRoot, ".change.0.gorfc")) if err != nil { return } cmdline := strings.Join(flag.Args(), " ") fmt.Fprintf(out, "%s\n", cmdline) } //out.Close() } if !ok || Usage || len(flag.Args()) == 0 { erf(UsageText) erf("flags\n") flag.PrintDefaults() return } err = foo(flag.Args()[1:]) }