Пример #1
0
func isSpecialStruct(typ sys.Type) func(r *randGen, s *state) (*Arg, []*Call) {
	a, ok := typ.(*sys.StructType)
	if !ok {
		panic("must be a struct")
	}
	switch typ.Name() {
	case "timespec":
		return func(r *randGen, s *state) (*Arg, []*Call) {
			return r.timespec(s, a, false)
		}
	case "timeval":
		return func(r *randGen, s *state) (*Arg, []*Call) {
			return r.timespec(s, a, true)
		}
	}
	return nil
}
Пример #2
0
func isSpecialStruct(typ sys.Type) func(r *randGen, s *state) (*Arg, []*Call) {
	if _, ok := typ.(*sys.StructType); !ok {
		panic("must be a struct")
	}
	switch typ.Name() {
	case "timespec":
		return func(r *randGen, s *state) (*Arg, []*Call) {
			return r.timespec(s, false)
		}
	case "timeval":
		return func(r *randGen, s *state) (*Arg, []*Call) {
			return r.timespec(s, true)
		}
	case "in6_addr":
		return func(r *randGen, s *state) (*Arg, []*Call) {
			return r.in6addr(s)
		}
	case "in_addr_any":
		return func(r *randGen, s *state) (*Arg, []*Call) {
			return r.inaddrany(s)
		}
	}
	return nil
}
Пример #3
0
func parseArg(typ sys.Type, p *parser, vars map[string]*Arg) (*Arg, error) {
	r := ""
	if p.Char() == '<' {
		p.Parse('<')
		r = p.Ident()
		p.Parse('=')
		p.Parse('>')
	}
	var arg *Arg
	switch p.Char() {
	case '0':
		val := p.Ident()
		v, err := strconv.ParseUint(val, 0, 64)
		if err != nil {
			return nil, fmt.Errorf("wrong arg value '%v': %v", val, err)
		}
		arg = constArg(uintptr(v))
	case 'r':
		id := p.Ident()
		v, ok := vars[id]
		if !ok || v == nil {
			return nil, fmt.Errorf("result %v references unknown variable (vars=%+v)", id, vars)
		}
		arg = resultArg(v)
		if p.Char() == '/' {
			p.Parse('/')
			op := p.Ident()
			v, err := strconv.ParseUint(op, 0, 64)
			if err != nil {
				return nil, fmt.Errorf("wrong result div op: '%v'", op)
			}
			arg.OpDiv = uintptr(v)
		}
		if p.Char() == '+' {
			p.Parse('+')
			op := p.Ident()
			v, err := strconv.ParseUint(op, 0, 64)
			if err != nil {
				return nil, fmt.Errorf("wrong result add op: '%v'", op)
			}
			arg.OpAdd = uintptr(v)
		}
	case '&':
		var typ1 sys.Type
		switch t1 := typ.(type) {
		case sys.PtrType:
			typ1 = t1.Type
		case sys.VmaType:
		default:
			return nil, fmt.Errorf("& arg is not a pointer: %#v", typ)
		}
		p.Parse('&')
		page, off, size, err := parseAddr(p, true)
		if err != nil {
			return nil, err
		}
		p.Parse('=')
		inner, err := parseArg(typ1, p, vars)
		if err != nil {
			return nil, err
		}
		arg = pointerArg(page, off, size, inner)
	case '(':
		page, off, _, err := parseAddr(p, false)
		if err != nil {
			return nil, err
		}
		arg = pageSizeArg(page, off)
	case '"':
		p.Parse('"')
		val := ""
		if p.Char() != '"' {
			val = p.Ident()
		}
		p.Parse('"')
		data, err := hex.DecodeString(val)
		if err != nil {
			return nil, fmt.Errorf("data arg has bad value '%v'", val)
		}
		arg = dataArg(data)
	case '{':
		t1, ok := typ.(*sys.StructType)
		if !ok {
			return nil, fmt.Errorf("'{' arg is not a struct: %#v", typ)
		}
		p.Parse('{')
		var inner []*Arg
		for i := 0; p.Char() != '}'; i++ {
			if i >= len(t1.Fields) {
				return nil, fmt.Errorf("wrong struct arg count: %v, want %v", i+1, len(t1.Fields))
			}
			fld := t1.Fields[i]
			if sys.IsPad(fld) {
				inner = append(inner, constArg(0))
			} else {
				arg, err := parseArg(fld, p, vars)
				if err != nil {
					return nil, err
				}
				inner = append(inner, arg)
				if p.Char() != '}' {
					p.Parse(',')
				}
			}
		}
		p.Parse('}')
		if sys.IsPad(t1.Fields[len(t1.Fields)-1]) {
			inner = append(inner, constArg(0))
		}
		arg = groupArg(inner)
	case '[':
		t1, ok := typ.(sys.ArrayType)
		if !ok {
			return nil, fmt.Errorf("'[' arg is not an array: %#v", typ)
		}
		p.Parse('[')
		var inner []*Arg
		for i := 0; p.Char() != ']'; i++ {
			arg, err := parseArg(t1.Type, p, vars)
			if err != nil {
				return nil, err
			}
			inner = append(inner, arg)
			if p.Char() != ']' {
				p.Parse(',')
			}
		}
		p.Parse(']')
		arg = groupArg(inner)
	case '@':
		t1, ok := typ.(*sys.UnionType)
		if !ok {
			return nil, fmt.Errorf("'@' arg is not a union: %#v", typ)
		}
		p.Parse('@')
		name := p.Ident()
		p.Parse('=')
		var optType sys.Type
		for _, t2 := range t1.Options {
			if name == t2.Name() {
				optType = t2
				break
			}
		}
		if optType == nil {
			return nil, fmt.Errorf("union arg %v has unknown option: %v", typ.Name(), name)
		}
		opt, err := parseArg(optType, p, vars)
		if err != nil {
			return nil, err
		}
		arg = unionArg(opt, optType)
	case 'n':
		p.Parse('n')
		p.Parse('i')
		p.Parse('l')
		if r != "" {
			return nil, fmt.Errorf("named nil argument")
		}
	default:
		return nil, fmt.Errorf("failed to parse argument at %v (line #%v/%v: %v)", int(p.Char()), p.l, p.i, p.s)
	}
	if r != "" {
		vars[r] = arg
	}
	return arg, nil
}