...

Source file src/github.com/godbus/dbus/v5/variant_parser.go

Documentation: github.com/godbus/dbus/v5

     1  package dbus
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"io"
     8  	"reflect"
     9  	"strconv"
    10  	"strings"
    11  	"unicode/utf8"
    12  )
    13  
    14  type varParser struct {
    15  	tokens []varToken
    16  	i      int
    17  }
    18  
    19  func (p *varParser) backup() {
    20  	p.i--
    21  }
    22  
    23  func (p *varParser) next() varToken {
    24  	if p.i < len(p.tokens) {
    25  		t := p.tokens[p.i]
    26  		p.i++
    27  		return t
    28  	}
    29  	return varToken{typ: tokEOF}
    30  }
    31  
    32  type varNode interface {
    33  	Infer() (Signature, error)
    34  	String() string
    35  	Sigs() sigSet
    36  	Value(Signature) (interface{}, error)
    37  }
    38  
    39  func varMakeNode(p *varParser) (varNode, error) {
    40  	var sig Signature
    41  
    42  	for {
    43  		t := p.next()
    44  		switch t.typ {
    45  		case tokEOF:
    46  			return nil, io.ErrUnexpectedEOF
    47  		case tokError:
    48  			return nil, errors.New(t.val)
    49  		case tokNumber:
    50  			return varMakeNumNode(t, sig)
    51  		case tokString:
    52  			return varMakeStringNode(t, sig)
    53  		case tokBool:
    54  			if sig.str != "" && sig.str != "b" {
    55  				return nil, varTypeError{t.val, sig}
    56  			}
    57  			b, err := strconv.ParseBool(t.val)
    58  			if err != nil {
    59  				return nil, err
    60  			}
    61  			return boolNode(b), nil
    62  		case tokArrayStart:
    63  			return varMakeArrayNode(p, sig)
    64  		case tokVariantStart:
    65  			return varMakeVariantNode(p, sig)
    66  		case tokDictStart:
    67  			return varMakeDictNode(p, sig)
    68  		case tokType:
    69  			if sig.str != "" {
    70  				return nil, errors.New("unexpected type annotation")
    71  			}
    72  			if t.val[0] == '@' {
    73  				sig.str = t.val[1:]
    74  			} else {
    75  				sig.str = varTypeMap[t.val]
    76  			}
    77  		case tokByteString:
    78  			if sig.str != "" && sig.str != "ay" {
    79  				return nil, varTypeError{t.val, sig}
    80  			}
    81  			b, err := varParseByteString(t.val)
    82  			if err != nil {
    83  				return nil, err
    84  			}
    85  			return byteStringNode(b), nil
    86  		default:
    87  			return nil, fmt.Errorf("unexpected %q", t.val)
    88  		}
    89  	}
    90  }
    91  
    92  type varTypeError struct {
    93  	val string
    94  	sig Signature
    95  }
    96  
    97  func (e varTypeError) Error() string {
    98  	return fmt.Sprintf("dbus: can't parse %q as type %q", e.val, e.sig.str)
    99  }
   100  
   101  type sigSet map[Signature]bool
   102  
   103  func (s sigSet) Empty() bool {
   104  	return len(s) == 0
   105  }
   106  
   107  func (s sigSet) Intersect(s2 sigSet) sigSet {
   108  	r := make(sigSet)
   109  	for k := range s {
   110  		if s2[k] {
   111  			r[k] = true
   112  		}
   113  	}
   114  	return r
   115  }
   116  
   117  func (s sigSet) Single() (Signature, bool) {
   118  	if len(s) == 1 {
   119  		for k := range s {
   120  			return k, true
   121  		}
   122  	}
   123  	return Signature{}, false
   124  }
   125  
   126  func (s sigSet) ToArray() sigSet {
   127  	r := make(sigSet, len(s))
   128  	for k := range s {
   129  		r[Signature{"a" + k.str}] = true
   130  	}
   131  	return r
   132  }
   133  
   134  type numNode struct {
   135  	sig Signature
   136  	str string
   137  	val interface{}
   138  }
   139  
   140  var numSigSet = sigSet{
   141  	Signature{"y"}: true,
   142  	Signature{"n"}: true,
   143  	Signature{"q"}: true,
   144  	Signature{"i"}: true,
   145  	Signature{"u"}: true,
   146  	Signature{"x"}: true,
   147  	Signature{"t"}: true,
   148  	Signature{"d"}: true,
   149  }
   150  
   151  func (n numNode) Infer() (Signature, error) {
   152  	if strings.ContainsAny(n.str, ".e") {
   153  		return Signature{"d"}, nil
   154  	}
   155  	return Signature{"i"}, nil
   156  }
   157  
   158  func (n numNode) String() string {
   159  	return n.str
   160  }
   161  
   162  func (n numNode) Sigs() sigSet {
   163  	if n.sig.str != "" {
   164  		return sigSet{n.sig: true}
   165  	}
   166  	if strings.ContainsAny(n.str, ".e") {
   167  		return sigSet{Signature{"d"}: true}
   168  	}
   169  	return numSigSet
   170  }
   171  
   172  func (n numNode) Value(sig Signature) (interface{}, error) {
   173  	if n.sig.str != "" && n.sig != sig {
   174  		return nil, varTypeError{n.str, sig}
   175  	}
   176  	if n.val != nil {
   177  		return n.val, nil
   178  	}
   179  	return varNumAs(n.str, sig)
   180  }
   181  
   182  func varMakeNumNode(tok varToken, sig Signature) (varNode, error) {
   183  	if sig.str == "" {
   184  		return numNode{str: tok.val}, nil
   185  	}
   186  	num, err := varNumAs(tok.val, sig)
   187  	if err != nil {
   188  		return nil, err
   189  	}
   190  	return numNode{sig: sig, val: num}, nil
   191  }
   192  
   193  func varNumAs(s string, sig Signature) (interface{}, error) {
   194  	isUnsigned := false
   195  	size := 32
   196  	switch sig.str {
   197  	case "n":
   198  		size = 16
   199  	case "i":
   200  	case "x":
   201  		size = 64
   202  	case "y":
   203  		size = 8
   204  		isUnsigned = true
   205  	case "q":
   206  		size = 16
   207  		isUnsigned = true
   208  	case "u":
   209  		isUnsigned = true
   210  	case "t":
   211  		size = 64
   212  		isUnsigned = true
   213  	case "d":
   214  		d, err := strconv.ParseFloat(s, 64)
   215  		if err != nil {
   216  			return nil, err
   217  		}
   218  		return d, nil
   219  	default:
   220  		return nil, varTypeError{s, sig}
   221  	}
   222  	base := 10
   223  	if strings.HasPrefix(s, "0x") {
   224  		base = 16
   225  		s = s[2:]
   226  	}
   227  	if strings.HasPrefix(s, "0") && len(s) != 1 {
   228  		base = 8
   229  		s = s[1:]
   230  	}
   231  	if isUnsigned {
   232  		i, err := strconv.ParseUint(s, base, size)
   233  		if err != nil {
   234  			return nil, err
   235  		}
   236  		var v interface{} = i
   237  		switch sig.str {
   238  		case "y":
   239  			v = byte(i)
   240  		case "q":
   241  			v = uint16(i)
   242  		case "u":
   243  			v = uint32(i)
   244  		}
   245  		return v, nil
   246  	}
   247  	i, err := strconv.ParseInt(s, base, size)
   248  	if err != nil {
   249  		return nil, err
   250  	}
   251  	var v interface{} = i
   252  	switch sig.str {
   253  	case "n":
   254  		v = int16(i)
   255  	case "i":
   256  		v = int32(i)
   257  	}
   258  	return v, nil
   259  }
   260  
   261  type stringNode struct {
   262  	sig Signature
   263  	str string      // parsed
   264  	val interface{} // has correct type
   265  }
   266  
   267  var stringSigSet = sigSet{
   268  	Signature{"s"}: true,
   269  	Signature{"g"}: true,
   270  	Signature{"o"}: true,
   271  }
   272  
   273  func (n stringNode) Infer() (Signature, error) {
   274  	return Signature{"s"}, nil
   275  }
   276  
   277  func (n stringNode) String() string {
   278  	return n.str
   279  }
   280  
   281  func (n stringNode) Sigs() sigSet {
   282  	if n.sig.str != "" {
   283  		return sigSet{n.sig: true}
   284  	}
   285  	return stringSigSet
   286  }
   287  
   288  func (n stringNode) Value(sig Signature) (interface{}, error) {
   289  	if n.sig.str != "" && n.sig != sig {
   290  		return nil, varTypeError{n.str, sig}
   291  	}
   292  	if n.val != nil {
   293  		return n.val, nil
   294  	}
   295  	switch {
   296  	case sig.str == "g":
   297  		return Signature{n.str}, nil
   298  	case sig.str == "o":
   299  		return ObjectPath(n.str), nil
   300  	case sig.str == "s":
   301  		return n.str, nil
   302  	default:
   303  		return nil, varTypeError{n.str, sig}
   304  	}
   305  }
   306  
   307  func varMakeStringNode(tok varToken, sig Signature) (varNode, error) {
   308  	if sig.str != "" && sig.str != "s" && sig.str != "g" && sig.str != "o" {
   309  		return nil, fmt.Errorf("invalid type %q for string", sig.str)
   310  	}
   311  	s, err := varParseString(tok.val)
   312  	if err != nil {
   313  		return nil, err
   314  	}
   315  	n := stringNode{str: s}
   316  	if sig.str == "" {
   317  		return stringNode{str: s}, nil
   318  	}
   319  	n.sig = sig
   320  	switch sig.str {
   321  	case "o":
   322  		n.val = ObjectPath(s)
   323  	case "g":
   324  		n.val = Signature{s}
   325  	case "s":
   326  		n.val = s
   327  	}
   328  	return n, nil
   329  }
   330  
   331  func varParseString(s string) (string, error) {
   332  	// quotes are guaranteed to be there
   333  	s = s[1 : len(s)-1]
   334  	buf := new(bytes.Buffer)
   335  	for len(s) != 0 {
   336  		r, size := utf8.DecodeRuneInString(s)
   337  		if r == utf8.RuneError && size == 1 {
   338  			return "", errors.New("invalid UTF-8")
   339  		}
   340  		s = s[size:]
   341  		if r != '\\' {
   342  			buf.WriteRune(r)
   343  			continue
   344  		}
   345  		r, size = utf8.DecodeRuneInString(s)
   346  		if r == utf8.RuneError && size == 1 {
   347  			return "", errors.New("invalid UTF-8")
   348  		}
   349  		s = s[size:]
   350  		switch r {
   351  		case 'a':
   352  			buf.WriteRune(0x7)
   353  		case 'b':
   354  			buf.WriteRune(0x8)
   355  		case 'f':
   356  			buf.WriteRune(0xc)
   357  		case 'n':
   358  			buf.WriteRune('\n')
   359  		case 'r':
   360  			buf.WriteRune('\r')
   361  		case 't':
   362  			buf.WriteRune('\t')
   363  		case '\n':
   364  		case 'u':
   365  			if len(s) < 4 {
   366  				return "", errors.New("short unicode escape")
   367  			}
   368  			r, err := strconv.ParseUint(s[:4], 16, 32)
   369  			if err != nil {
   370  				return "", err
   371  			}
   372  			buf.WriteRune(rune(r))
   373  			s = s[4:]
   374  		case 'U':
   375  			if len(s) < 8 {
   376  				return "", errors.New("short unicode escape")
   377  			}
   378  			r, err := strconv.ParseUint(s[:8], 16, 32)
   379  			if err != nil {
   380  				return "", err
   381  			}
   382  			buf.WriteRune(rune(r))
   383  			s = s[8:]
   384  		default:
   385  			buf.WriteRune(r)
   386  		}
   387  	}
   388  	return buf.String(), nil
   389  }
   390  
   391  var boolSigSet = sigSet{Signature{"b"}: true}
   392  
   393  type boolNode bool
   394  
   395  func (boolNode) Infer() (Signature, error) {
   396  	return Signature{"b"}, nil
   397  }
   398  
   399  func (b boolNode) String() string {
   400  	if b {
   401  		return "true"
   402  	}
   403  	return "false"
   404  }
   405  
   406  func (boolNode) Sigs() sigSet {
   407  	return boolSigSet
   408  }
   409  
   410  func (b boolNode) Value(sig Signature) (interface{}, error) {
   411  	if sig.str != "b" {
   412  		return nil, varTypeError{b.String(), sig}
   413  	}
   414  	return bool(b), nil
   415  }
   416  
   417  type arrayNode struct {
   418  	set      sigSet
   419  	children []varNode
   420  	val      interface{}
   421  }
   422  
   423  func (n arrayNode) Infer() (Signature, error) {
   424  	for _, v := range n.children {
   425  		csig, err := varInfer(v)
   426  		if err != nil {
   427  			continue
   428  		}
   429  		return Signature{"a" + csig.str}, nil
   430  	}
   431  	return Signature{}, fmt.Errorf("can't infer type for %q", n.String())
   432  }
   433  
   434  func (n arrayNode) String() string {
   435  	s := "["
   436  	for i, v := range n.children {
   437  		s += v.String()
   438  		if i != len(n.children)-1 {
   439  			s += ", "
   440  		}
   441  	}
   442  	return s + "]"
   443  }
   444  
   445  func (n arrayNode) Sigs() sigSet {
   446  	return n.set
   447  }
   448  
   449  func (n arrayNode) Value(sig Signature) (interface{}, error) {
   450  	if n.set.Empty() {
   451  		// no type information whatsoever, so this must be an empty slice
   452  		return reflect.MakeSlice(typeFor(sig.str), 0, 0).Interface(), nil
   453  	}
   454  	if !n.set[sig] {
   455  		return nil, varTypeError{n.String(), sig}
   456  	}
   457  	s := reflect.MakeSlice(typeFor(sig.str), len(n.children), len(n.children))
   458  	for i, v := range n.children {
   459  		rv, err := v.Value(Signature{sig.str[1:]})
   460  		if err != nil {
   461  			return nil, err
   462  		}
   463  		s.Index(i).Set(reflect.ValueOf(rv))
   464  	}
   465  	return s.Interface(), nil
   466  }
   467  
   468  func varMakeArrayNode(p *varParser, sig Signature) (varNode, error) {
   469  	var n arrayNode
   470  	if sig.str != "" {
   471  		n.set = sigSet{sig: true}
   472  	}
   473  	if t := p.next(); t.typ == tokArrayEnd {
   474  		return n, nil
   475  	} else {
   476  		p.backup()
   477  	}
   478  Loop:
   479  	for {
   480  		t := p.next()
   481  		switch t.typ {
   482  		case tokEOF:
   483  			return nil, io.ErrUnexpectedEOF
   484  		case tokError:
   485  			return nil, errors.New(t.val)
   486  		}
   487  		p.backup()
   488  		cn, err := varMakeNode(p)
   489  		if err != nil {
   490  			return nil, err
   491  		}
   492  		if cset := cn.Sigs(); !cset.Empty() {
   493  			if n.set.Empty() {
   494  				n.set = cset.ToArray()
   495  			} else {
   496  				nset := cset.ToArray().Intersect(n.set)
   497  				if nset.Empty() {
   498  					return nil, fmt.Errorf("can't parse %q with given type information", cn.String())
   499  				}
   500  				n.set = nset
   501  			}
   502  		}
   503  		n.children = append(n.children, cn)
   504  		switch t := p.next(); t.typ {
   505  		case tokEOF:
   506  			return nil, io.ErrUnexpectedEOF
   507  		case tokError:
   508  			return nil, errors.New(t.val)
   509  		case tokArrayEnd:
   510  			break Loop
   511  		case tokComma:
   512  			continue
   513  		default:
   514  			return nil, fmt.Errorf("unexpected %q", t.val)
   515  		}
   516  	}
   517  	return n, nil
   518  }
   519  
   520  type variantNode struct {
   521  	n varNode
   522  }
   523  
   524  var variantSet = sigSet{
   525  	Signature{"v"}: true,
   526  }
   527  
   528  func (variantNode) Infer() (Signature, error) {
   529  	return Signature{"v"}, nil
   530  }
   531  
   532  func (n variantNode) String() string {
   533  	return "<" + n.n.String() + ">"
   534  }
   535  
   536  func (variantNode) Sigs() sigSet {
   537  	return variantSet
   538  }
   539  
   540  func (n variantNode) Value(sig Signature) (interface{}, error) {
   541  	if sig.str != "v" {
   542  		return nil, varTypeError{n.String(), sig}
   543  	}
   544  	sig, err := varInfer(n.n)
   545  	if err != nil {
   546  		return nil, err
   547  	}
   548  	v, err := n.n.Value(sig)
   549  	if err != nil {
   550  		return nil, err
   551  	}
   552  	return MakeVariant(v), nil
   553  }
   554  
   555  func varMakeVariantNode(p *varParser, sig Signature) (varNode, error) {
   556  	n, err := varMakeNode(p)
   557  	if err != nil {
   558  		return nil, err
   559  	}
   560  	if t := p.next(); t.typ != tokVariantEnd {
   561  		return nil, fmt.Errorf("unexpected %q", t.val)
   562  	}
   563  	vn := variantNode{n}
   564  	if sig.str != "" && sig.str != "v" {
   565  		return nil, varTypeError{vn.String(), sig}
   566  	}
   567  	return variantNode{n}, nil
   568  }
   569  
   570  type dictEntry struct {
   571  	key, val varNode
   572  }
   573  
   574  type dictNode struct {
   575  	kset, vset sigSet
   576  	children   []dictEntry
   577  	val        interface{}
   578  }
   579  
   580  func (n dictNode) Infer() (Signature, error) {
   581  	for _, v := range n.children {
   582  		ksig, err := varInfer(v.key)
   583  		if err != nil {
   584  			continue
   585  		}
   586  		vsig, err := varInfer(v.val)
   587  		if err != nil {
   588  			continue
   589  		}
   590  		return Signature{"a{" + ksig.str + vsig.str + "}"}, nil
   591  	}
   592  	return Signature{}, fmt.Errorf("can't infer type for %q", n.String())
   593  }
   594  
   595  func (n dictNode) String() string {
   596  	s := "{"
   597  	for i, v := range n.children {
   598  		s += v.key.String() + ": " + v.val.String()
   599  		if i != len(n.children)-1 {
   600  			s += ", "
   601  		}
   602  	}
   603  	return s + "}"
   604  }
   605  
   606  func (n dictNode) Sigs() sigSet {
   607  	r := sigSet{}
   608  	for k := range n.kset {
   609  		for v := range n.vset {
   610  			sig := "a{" + k.str + v.str + "}"
   611  			r[Signature{sig}] = true
   612  		}
   613  	}
   614  	return r
   615  }
   616  
   617  func (n dictNode) Value(sig Signature) (interface{}, error) {
   618  	set := n.Sigs()
   619  	if set.Empty() {
   620  		// no type information -> empty dict
   621  		return reflect.MakeMap(typeFor(sig.str)).Interface(), nil
   622  	}
   623  	if !set[sig] {
   624  		return nil, varTypeError{n.String(), sig}
   625  	}
   626  	m := reflect.MakeMap(typeFor(sig.str))
   627  	ksig := Signature{sig.str[2:3]}
   628  	vsig := Signature{sig.str[3 : len(sig.str)-1]}
   629  	for _, v := range n.children {
   630  		kv, err := v.key.Value(ksig)
   631  		if err != nil {
   632  			return nil, err
   633  		}
   634  		vv, err := v.val.Value(vsig)
   635  		if err != nil {
   636  			return nil, err
   637  		}
   638  		m.SetMapIndex(reflect.ValueOf(kv), reflect.ValueOf(vv))
   639  	}
   640  	return m.Interface(), nil
   641  }
   642  
   643  func varMakeDictNode(p *varParser, sig Signature) (varNode, error) {
   644  	var n dictNode
   645  
   646  	if sig.str != "" {
   647  		if len(sig.str) < 5 {
   648  			return nil, fmt.Errorf("invalid signature %q for dict type", sig)
   649  		}
   650  		ksig := Signature{string(sig.str[2])}
   651  		vsig := Signature{sig.str[3 : len(sig.str)-1]}
   652  		n.kset = sigSet{ksig: true}
   653  		n.vset = sigSet{vsig: true}
   654  	}
   655  	if t := p.next(); t.typ == tokDictEnd {
   656  		return n, nil
   657  	} else {
   658  		p.backup()
   659  	}
   660  Loop:
   661  	for {
   662  		t := p.next()
   663  		switch t.typ {
   664  		case tokEOF:
   665  			return nil, io.ErrUnexpectedEOF
   666  		case tokError:
   667  			return nil, errors.New(t.val)
   668  		}
   669  		p.backup()
   670  		kn, err := varMakeNode(p)
   671  		if err != nil {
   672  			return nil, err
   673  		}
   674  		if kset := kn.Sigs(); !kset.Empty() {
   675  			if n.kset.Empty() {
   676  				n.kset = kset
   677  			} else {
   678  				n.kset = kset.Intersect(n.kset)
   679  				if n.kset.Empty() {
   680  					return nil, fmt.Errorf("can't parse %q with given type information", kn.String())
   681  				}
   682  			}
   683  		}
   684  		t = p.next()
   685  		switch t.typ {
   686  		case tokEOF:
   687  			return nil, io.ErrUnexpectedEOF
   688  		case tokError:
   689  			return nil, errors.New(t.val)
   690  		case tokColon:
   691  		default:
   692  			return nil, fmt.Errorf("unexpected %q", t.val)
   693  		}
   694  		t = p.next()
   695  		switch t.typ {
   696  		case tokEOF:
   697  			return nil, io.ErrUnexpectedEOF
   698  		case tokError:
   699  			return nil, errors.New(t.val)
   700  		}
   701  		p.backup()
   702  		vn, err := varMakeNode(p)
   703  		if err != nil {
   704  			return nil, err
   705  		}
   706  		if vset := vn.Sigs(); !vset.Empty() {
   707  			if n.vset.Empty() {
   708  				n.vset = vset
   709  			} else {
   710  				n.vset = n.vset.Intersect(vset)
   711  				if n.vset.Empty() {
   712  					return nil, fmt.Errorf("can't parse %q with given type information", vn.String())
   713  				}
   714  			}
   715  		}
   716  		n.children = append(n.children, dictEntry{kn, vn})
   717  		t = p.next()
   718  		switch t.typ {
   719  		case tokEOF:
   720  			return nil, io.ErrUnexpectedEOF
   721  		case tokError:
   722  			return nil, errors.New(t.val)
   723  		case tokDictEnd:
   724  			break Loop
   725  		case tokComma:
   726  			continue
   727  		default:
   728  			return nil, fmt.Errorf("unexpected %q", t.val)
   729  		}
   730  	}
   731  	return n, nil
   732  }
   733  
   734  type byteStringNode []byte
   735  
   736  var byteStringSet = sigSet{
   737  	Signature{"ay"}: true,
   738  }
   739  
   740  func (byteStringNode) Infer() (Signature, error) {
   741  	return Signature{"ay"}, nil
   742  }
   743  
   744  func (b byteStringNode) String() string {
   745  	return string(b)
   746  }
   747  
   748  func (b byteStringNode) Sigs() sigSet {
   749  	return byteStringSet
   750  }
   751  
   752  func (b byteStringNode) Value(sig Signature) (interface{}, error) {
   753  	if sig.str != "ay" {
   754  		return nil, varTypeError{b.String(), sig}
   755  	}
   756  	return []byte(b), nil
   757  }
   758  
   759  func varParseByteString(s string) ([]byte, error) {
   760  	// quotes and b at start are guaranteed to be there
   761  	b := make([]byte, 0, 1)
   762  	s = s[2 : len(s)-1]
   763  	for len(s) != 0 {
   764  		c := s[0]
   765  		s = s[1:]
   766  		if c != '\\' {
   767  			b = append(b, c)
   768  			continue
   769  		}
   770  		c = s[0]
   771  		s = s[1:]
   772  		switch c {
   773  		case 'a':
   774  			b = append(b, 0x7)
   775  		case 'b':
   776  			b = append(b, 0x8)
   777  		case 'f':
   778  			b = append(b, 0xc)
   779  		case 'n':
   780  			b = append(b, '\n')
   781  		case 'r':
   782  			b = append(b, '\r')
   783  		case 't':
   784  			b = append(b, '\t')
   785  		case 'x':
   786  			if len(s) < 2 {
   787  				return nil, errors.New("short escape")
   788  			}
   789  			n, err := strconv.ParseUint(s[:2], 16, 8)
   790  			if err != nil {
   791  				return nil, err
   792  			}
   793  			b = append(b, byte(n))
   794  			s = s[2:]
   795  		case '0':
   796  			if len(s) < 3 {
   797  				return nil, errors.New("short escape")
   798  			}
   799  			n, err := strconv.ParseUint(s[:3], 8, 8)
   800  			if err != nil {
   801  				return nil, err
   802  			}
   803  			b = append(b, byte(n))
   804  			s = s[3:]
   805  		default:
   806  			b = append(b, c)
   807  		}
   808  	}
   809  	return append(b, 0), nil
   810  }
   811  
   812  func varInfer(n varNode) (Signature, error) {
   813  	if sig, ok := n.Sigs().Single(); ok {
   814  		return sig, nil
   815  	}
   816  	return n.Infer()
   817  }
   818  

View as plain text