Example #1
0
func parseListOut(pkgType, line string, re *regexp.Regexp) (Pkg, error) {
	match := re.FindStringSubmatch(line)
	if match == nil || len(match) < 3 {
		return nil, fmt.Errorf("Unable to parse List package info")
	}
	return NewPackage(pkgType, match[1], match[2])
}
Example #2
0
func ParseDatabaseDSN(urlRegexp *regexp.Regexp, url string) DatabaseDSN {
	defer func() {
		_ = recover()
	}()

	dsn := DatabaseDSN{}

	match := urlRegexp.FindStringSubmatch(url)

	for i, name := range urlRegexp.SubexpNames() {
		if i != 0 {
			if name == "host" {
				dsn.Host = match[i]
			}

			if name == "port" {
				dsn.Port = match[i]
			}

			if name == "user" {
				dsn.User = match[i]
			}

			if name == "password" {
				dsn.Password = match[i]
			}

			if name == "name" {
				dsn.Name = match[i]
			}
		}
	}

	return dsn
}
Example #3
0
// match regexp with string, and return a named group map
// Example:
//   regexp: "(?P<name>[A-Za-z]+)-(?P<age>\\d+)"
//   string: "CGC-30"
//   return: map[string][]string{ "name":["CGC"], "age":["30"] }
func NamedUrlValuesRegexpGroup(str string, reg *regexp.Regexp) (ng url.Values, matched bool) {
	rst := reg.FindStringSubmatch(str)
	if len(rst) < 1 {
		return
	}
	//for i,s :=range rst{
	//	fmt.Printf("%d => %s\n",i,s)
	//}
	ng = url.Values{}
	lenRst := len(rst)
	sn := reg.SubexpNames()
	for k, v := range sn {
		// SubexpNames contain the none named group,
		// so must filter v == ""
		//fmt.Printf("%s => %s\n",k,v)
		if k == 0 || v == "" {
			continue
		}
		if k+1 > lenRst {
			break
		}
		ng.Add(v, rst[k])
	}
	matched = true
	return
}
Example #4
0
func getString(s string, r *regexp.Regexp) (m string) {
	if r.MatchString(s) {
		m = r.FindStringSubmatch(s)[1]
		m = trimSpaces(m)
	}
	return
}
Example #5
0
// Tries to parse a ClientEntry from stream
func ParseCEntry(str string) *raft.ClientEntry {
	var pat *regexp.Regexp
	var matches []string
	pat = regexp.MustCompile("^read (0x[0-9a-f]+)$")
	matches = pat.FindStringSubmatch(str)
	if len(matches) > 0 {
		uid, _ := strconv.ParseUint(matches[1], 0, 64)
		return &raft.ClientEntry{
			UID:  uid,
			Data: &MachnRead{},
		}
	}

	pat = regexp.MustCompile("^update (0x[0-9a-f]+) ([0-9]+)$")
	matches = pat.FindStringSubmatch(str)
	if len(matches) > 0 {
		uid, _ := strconv.ParseUint(matches[1], 0, 64)
		val, _ := strconv.ParseInt(matches[2], 0, 64)
		return &raft.ClientEntry{
			UID:  uid,
			Data: &MachnUpdate{val},
		}
	}

	return nil
}
func processLines(results chan<- map[string]int, getRx *regexp.Regexp,
	filename string, offset, chunkSize int64) {
	file, err := os.Open(filename)
	if err != nil {
		log.Fatal("failed to open the file:", err)
	}
	defer file.Close()
	file.Seek(offset, 0)
	var bytesRead int64
	reader := bufio.NewReader(file)
	if offset > 0 { // Find first whole line
		line, err := reader.ReadString('\n')
		if err != nil {
			log.Fatal("failed to read the file:", err)
		}
		bytesRead = int64(len(line))
	}
	countForPage := make(map[string]int)
	for bytesRead < chunkSize {
		line, err := reader.ReadString('\n')
		if line != "" {
			bytesRead += int64(len(line))
			if matches := getRx.FindStringSubmatch(line); matches != nil {
				countForPage[matches[1]]++
			}
		}
		if err != nil {
			if err != io.EOF {
				log.Println("failed to finish reading the file:", err)
			}
			break
		}
	}
	results <- countForPage
}
Example #7
0
File: db.go Project: woremacx/kocha
func (mig *Migration) collectInfos(r *regexp.Regexp, isTarget func(string) bool) ([]migrationInfo, error) {
	v := reflect.ValueOf(mig.m)
	t := v.Type()
	var minfos []migrationInfo
	for i := 0; i < t.NumMethod(); i++ {
		meth := t.Method(i)
		name := meth.Name
		matches := r.FindStringSubmatch(name)
		if matches == nil || !isTarget(matches[1]) {
			continue
		}
		if meth.Type.NumIn() != 2 {
			return nil, fmt.Errorf("kocha: migrate: %v: arguments number must be 1", meth.Name)
		}
		argType := meth.Type.In(1)
		tx := mig.findTransactioner(argType)
		if tx == nil {
			return nil, fmt.Errorf("kocha: migrate: argument type `%v' is undefined", argType)
		}
		minfos = append(minfos, migrationInfo{
			methodName: name,
			version:    matches[1],
			tx:         tx,
		})
	}
	return minfos, nil
}
Example #8
0
func (s *processedAsset) requiredPaths(rx *regexp.Regexp) ([]string, error) {
	f, err := os.Open(s.static.pathname)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	buf := bufio.NewReader(f)
	paths := make([]string, 0)
	for {
		line, err := buf.ReadString('\n')
		if err == io.EOF {
			break
		} else if err != nil {
			return nil, err
		}
		if strings.TrimSpace(line) != "" && !strings.HasPrefix(line, "//") {
			break
		}
		matches := rx.FindStringSubmatch(line)
		if len(matches) > 1 {
			match := matches[1]
			if path.Ext(match) == "" {
				match += path.Ext(s.static.logical)
			}
			paths = append(paths, match)
		}
	}
	return paths, nil
}
Example #9
0
func findSubmatch(r *regexp.Regexp, code string, tokenType string) Token {
	if m := r.FindStringSubmatch(code); len(m) > 0 {
		return Token{tokenType, m[1], len(m[1]), true}
	}

	return Token{"", "", 0, false}
}
Example #10
0
func parseUrl(url string) (protocol, host string, port int, err error) {
	pattern1 := "^(.+)://(.+):([0-9].+)/$"
	pattern2 := "^(.+)://(.+)$"

	var r *regexp.Regexp
	r, err = regexp.Compile(pattern1)
	err = cliutils.CheckError(err)
	if err != nil {
		return
	}
	groups := r.FindStringSubmatch(url)
	if len(groups) == 4 {
		protocol = groups[1]
		host = groups[2]
		port, err = strconv.Atoi(groups[3])
		if err != nil {
			err = cliutils.CheckError(errors.New("URL: " + url + " is invalid. Expecting ssh://<host>:<port> or http(s)://..."))
		}
		return
	}

	r, err = regexp.Compile(pattern2)
	err = cliutils.CheckError(err)
	if err != nil {
		return
	}
	groups = r.FindStringSubmatch(url)
	if len(groups) == 3 {
		protocol = groups[1]
		host = groups[2]
		port = 80
	}
	return
}
Example #11
0
func (nc *Netcoupe) getRegexpField(re *regexp.Regexp, content string) string {
	result := re.FindStringSubmatch(content)
	if len(result) < 2 {
		return "UNKNOWN"
	}
	return strings.TrimSpace(result[1])
}
Example #12
0
func (m *Module) AddResponse(reg *regexp.Regexp, f func(*Response), permission permissions.Permission) error {
	name := reg.String()
	wrap := func(message *irc.Message) {
		switch message.Command {
		case "PRIVMSG", "NOTICE":
			nick := message.Server.CurrentNick()
			text := strings.Join(message.Arguments[1:], " ")
			if message.Arguments[0] == nick { //direct privmsg
				if reg.MatchString(strings.Trim(text, " ")) {
					f(&Response{message, text, reg.FindStringSubmatch(text)})
				}
			} else { //asked from channel
				current, err := regexp.Compile("^" + nick + "[ ,;:]")
				if err != nil {
					log.Error("Failed to compile nick regexp: ", err)
				} else if current.MatchString(text) {
					nl := len(nick) + 1
					if len(text) > nl {
						just_text := strings.Trim(text[nl:], " ")
						if reg.MatchString(just_text) {
							f(&Response{message, text, reg.FindStringSubmatch(just_text)})
						}
					}
				}
			}
		}
	}

	if _, ok := m.handlers[name]; ok {
		return errors.New("Response with same regexp already exist's!")
	}

	m.handlers[name] = m.connection.AddHandler(wrap, permission)
	return nil
}
Example #13
0
func reFindSubmatch(re *regexp.Regexp) lua.Function {
	return func(l *lua.State) int {
		s := lua.CheckString(l, 1)
		allSubmatch := re.FindStringSubmatch(s)
		return util.DeepPush(l, allSubmatch)
	}
}
Example #14
0
func (r *SSHConfigReader) readFile(c SSHConfig, re *regexp.Regexp, f string) error {
	file, err := os.Open(f)
	if err != nil {
		return err
	}
	defer file.Close()

	hosts := []string{"*"}
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := scanner.Text()
		match := re.FindStringSubmatch(line)
		if match == nil {
			continue
		}

		names := strings.Fields(match[2])
		if strings.EqualFold(match[1], "host") {
			hosts = names
		} else {
			for _, host := range hosts {
				for _, name := range names {
					c[host] = name
				}
			}
		}
	}

	return scanner.Err()
}
Example #15
0
File: wok.go Project: novag/wok
func handleMessage(e *irc.Event) {
	_channel := e.Arguments[0]
	_sender := e.Nick
	_line := e.Message()
	isPrivate := 0
	if _channel == config.Nick {
		isPrivate = 1
	}

	if _, ok := blockedNicks[_sender]; ok {
		return
	}

	// Validate message
	var re *regexp.Regexp
	if isPrivate == 1 {
		re = regexp.MustCompile(`^!?([a-zA-Z1-9]+)(?:$|\s)(.*)$`)
	} else {
		re = regexp.MustCompile(`^!([a-zA-Z1-9]+)(?:$|\s)(.*)$`)
	}
	match := re.FindStringSubmatch(_line)
	if match == nil {
		return
	}

	_cmd := match[1]
	_args := match[2]

	if info := registry[isPrivate][_cmd]; info != nil {
		fmt.Printf("Received message: channel=\"%s\" sender=\"%s\" command=\"%s\" arguments=\"%s\"\n", _channel, _sender, _cmd, _args)
		info.Callback(_channel, _sender, _args)
	}
}
Example #16
0
func verifySwaggerMultiArgSwaggerTag(t *testing.T, matcher *regexp.Regexp, prefixes, validParams, invalidParams []string) {
	var actualParams []string
	for i := 0; i < len(validParams); i++ {
		var vp []string
		for j := 0; j < (i + 1); j++ {
			vp = append(vp, validParams[j])
		}
		actualParams = append(actualParams, strings.Join(vp, " "))
	}
	for _, pref := range prefixes {
		for _, param := range actualParams {
			line := pref + param
			matches := matcher.FindStringSubmatch(line)
			// fmt.Printf("matching %q with %q, matches (%d): %v\n", line, matcher, len(matches), matches)
			assert.Len(t, matches, 2)
			assert.Equal(t, strings.TrimSpace(param), matches[1])
		}
	}

	for _, pref := range prefixes {
		for _, param := range invalidParams {
			line := pref + param
			matches := matcher.FindStringSubmatch(line)
			assert.Empty(t, matches)
		}
	}
}
Example #17
0
// Expand '~'-based homedif from the given path
func ExpandHomedir(s string) (string, error) {
	const (
		slash = string(os.PathSeparator)
		re1   = "~%s"            // regex: /~\//
		re2   = "~([\\w\\-]+)%s" // regex: /~([\w\-]+)\//
	)
	var (
		err error
		re  *regexp.Regexp
		u   *user.User
		rv  string
	)

	if strings.HasPrefix(s, fmt.Sprintf(re1, slash)) {
		u, _ = user.Current()
		rv = fmt.Sprintf("%s", u.HomeDir+s[1:])
		err = nil
	} else if re = regexp.MustCompile(fmt.Sprintf(re2, slash)); re.MatchString(s) {
		uname := re.FindStringSubmatch(s)[0]
		uname = uname[1 : len(uname)-1]
		if u, _ = user.Lookup(uname); u == nil {
			rv = s
			err = nil
		} else {
			rv = u.HomeDir + slash + strings.Join(strings.Split(s, slash)[1:], slash)
			err = nil
		}
	} else if err != nil {
		rv = s
	} else {
		rv = s
		err = nil
	}
	return rv, err
}
Example #18
0
func extractOwnerAndRepo(text string, re *regexp.Regexp) (string, string, error) {
	m := re.FindStringSubmatch(text)
	if m == nil || len(m) < 3 {
		return "", "", &repoError{text}
	}
	return m[1], m[2], nil
}
Example #19
0
func parseUnix(s string) *time.Time {
	var (
		r       *regexp.Regexp
		matched []string
	)

	// parse unix time with nanoseconds
	r = regexp.MustCompile(`^(\d+)\.(\d+)$`)
	matched = r.FindStringSubmatch(s)
	if len(matched) > 0 {
		sec, _ := strconv.ParseInt(matched[1], 10, 64)
		nanosec, _ := strconv.ParseInt(matched[2], 10, 64)
		t := time.Unix(sec, nanosec)
		return &t
	}

	// parse unix time
	r = regexp.MustCompile(`^(\d+)$`)
	matched = r.FindStringSubmatch(s)
	if len(matched) > 0 {
		sec, _ := strconv.ParseInt(matched[1], 10, 64)
		t := time.Unix(sec, 0)
		return &t
	}

	return nil
}
Example #20
0
// FromPattern takes a pattern and if it matches 's' with two exactly two valid
// submatches, returns a BlobRef, else returns nil.
func FromPattern(r *regexp.Regexp, s string) *BlobRef {
	matches := r.FindStringSubmatch(s)
	if len(matches) != 3 {
		return nil
	}
	return blobIfValid(matches[1], matches[2])
}
Example #21
0
// This function extracts the IP address and the port number from a string that represents a transport address.
// The string should be "IP:port".
//
// INPUT
// - in_inet: the transport address.
//            The given transport address could be IPV4 or IPV6.
//            Example for IPV4: "192.168.0.1:1456"
//            Example for IPV6: "[2001:0DB8:0000:85a3:0000:0000:ac1f:8001]:16547"
//
// OUTPUT
// - The IP address.
// - The port number.
// - The error flag.
func InetSplit(in_inet string) (out_ip string, out_port int, out_err error) {
	var err error
	var port int
	var data []string
	var ipv4, ipv6 *regexp.Regexp

	ipv4, err = regexp.Compile("^(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}):(\\d{1,5})$")
	if nil != err {
		panic("Internal error.")
	}

	ipv6, err = regexp.Compile("^\\[([0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4})\\]:(\\d{1,5})$")
	if nil != err {
		panic("Internal error.")
	}

	// Is it IPV4 or IPV6?
	data = ipv4.FindStringSubmatch(in_inet)
	if nil == data {
		data = ipv6.FindStringSubmatch(in_inet)
		if nil == data {
			return "", -1, errors.New(fmt.Sprintf("Invalid IP address \"%s\". Can not determine the address' family.", in_inet))
		}
	}

	port, err = strconv.Atoi(data[2])
	if nil != err {
		return "", -1, errors.New(fmt.Sprintf("Invalid INET address \"%s\". The port number is not valid (\"%s\"). It is not an integer.", in_inet, data[2]))
	}
	return data[1], port, nil
}
Example #22
0
func rewriteFilters(query url.Values, filtersRe *regexp.Regexp) url.Values {
	qstr := query.Get("q")
	// Using a regexp so the start/end indices of each match are easily
	// available for subsequent slicing of the query string.  The performance
	// (regexp @ 0.011 ms vs. string @ 0.004 ms) is minimal enough that the
	// extra hit for regexp is acceptable, given the simpler code.
	matches := filtersRe.FindStringSubmatch(qstr)
	for matches != nil {
		// matches is [entire_match, filter_name, filter_value]
		filter := strings.ToLower(matches[1])
		value := matches[2]

		filter = strings.Replace(filter, "pkg", "package", 1)
		if filter == "-file" {
			filter = "npath"
		} else if strings.HasPrefix(filter, "-") {
			filter = "n" + filter[1:]
		}
		if strings.HasSuffix(filter, "filetype") {
			value = strings.ToLower(value)
		}
		query.Add(filter, value)

		if filtersRe == start {
			qstr = strings.TrimPrefix(qstr, matches[0])
		} else {
			qstr = strings.TrimSuffix(qstr, matches[0])
		}
		matches = filtersRe.FindStringSubmatch(qstr)
	}

	query.Set("q", qstr)
	return query
}
Example #23
0
// ServeHTTP parses the path parameters, calls SetPathParameters of
// the corresponding hander, then directs traffic to it.
func (r *RouteHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	glog.Infof("%s: '%s'", req.Method, req.URL.String())
	pathstr := req.URL.Path[len(r.path):]
	var match []string
	var pattern *regexp.Regexp
	var handler Handler
	for e := r.patternHandlers.Front(); e != nil; e = e.Next() {
		h := e.Value.(*patternHandler)
		pattern = h.Regexp
		handler = h.Handler
		match = pattern.FindStringSubmatch(pathstr)
		if match != nil {
			break
		}
	}
	if match == nil {
		glog.Warningf("Cannot find a matching pattern for Path `%s'",
			pathstr)
		http.NotFound(w, req)
		return
	}
	kvpairs := make(map[string]string)
	for i, name := range pattern.SubexpNames() {
		// ignore full match and unnamed submatch
		if i == 0 || name == "" {
			continue
		}
		kvpairs[name] = match[i]
	}
	glog.V(1).Infof("Parsed path parameters: %s", kvpairs)
	handler.ServeHTTP(w, req, kvpairs)
}
Example #24
0
func parseClass(s string) (res PKUClass, err error) {
	err = nil

	match := reName.FindStringSubmatch(s)
	if match == nil {
		err = wrongFormatException(1, "Error when parsing class name")
		return
	}
	res.Name = match[1]

	match = reThGr.FindStringSubmatch(s)
	if match == nil {
		err = wrongFormatException(2, "Error when parsing teacher name and group id")
		return
	}
	res.Teacher = match[1]
	res.GroupID = match[2]

	match = reUbound.FindStringSubmatch(s)
	if match == nil {
		err = wrongFormatException(6, "Error when parsing upper bound")
		return
	}
	res.UBound, err = strconv.Atoi(match[1])
	if err != nil {
		return
	}

	match = reTime.FindStringSubmatch(s)
	if match == nil {
		err = wrongFormatException(7, "Error when parsing message")
		return
	}
	res.Msg = strings.Replace(match[1], "<br>", " ", -1)

	match = reCommand.FindStringSubmatch(s)
	if match == nil {
		err = wrongFormatException(3, "Error when checking status")
		return
	}

	var reIS *regexp.Regexp
	if match[1] == "h" {
		res.IsFull = false
		reIS = reElect
	} else {
		res.IsFull = true
		reIS = reRefresh
	}
	match = reIS.FindStringSubmatch(s)
	if match == nil {
		err = wrongFormatException(4, "Error when extracting index and sequence number.")
		return
	}
	res.Index = match[1]
	res.Seq = match[2]

	return
}
Example #25
0
func processQueryAndSearch(message string, regex *regexp.Regexp, animated bool) string {
	searchExpression := regex.FindStringSubmatch(message)

	if len(searchExpression) > 0 {
		return imageSearch(searchExpression[2], animated, false, 1)
	}
	return ""
}
Example #26
0
func findSubmatchInLines(p *regexp.Regexp, lines []string) []string {
	for _, line := range lines {
		if m := p.FindStringSubmatch(line); len(m) > 0 {
			return m[1:]
		}
	}
	return nil
}
Example #27
0
func extractFromInfobox(wikiText string, r *regexp.Regexp) string {
	s := r.FindStringSubmatch(wikiText)
	if s != nil {
		return strings.TrimSpace(s[len(s)-1])
	} else {
		return ""
	}
}
Example #28
0
func processLines(done chan<- struct{}, getRx *regexp.Regexp, safeMap *safeMap, lines <-chan string) {
	for line := range lines {
		if matches := getRx.FindStringSubmatch(line); matches != nil {
			safeMap.Increment(matches[1])
		}
	}
	done <- struct{}{}
}
Example #29
0
func verifyBoolean(t *testing.T, matcher *regexp.Regexp, names, names2 []string) {
	extraSpaces := []string{"", " ", "  ", "     "}
	prefixes := []string{"//", "*", ""}
	validArgs := []string{"true", "false"}
	invalidArgs := []string{"TRUE", "FALSE", "t", "f", "1", "0", "True", "False", "true*", "false*"}
	var nms []string
	for _, nm := range names {
		nms = append(nms, nm, strings.Title(nm))
	}

	var nms2 []string
	for _, nm := range names2 {
		nms2 = append(nms2, nm, strings.Title(nm))
	}

	var rnms []string
	if len(nms2) > 0 {
		for _, nm := range nms {
			for _, es := range append(extraSpaces, "-") {
				for _, nm2 := range nms2 {
					rnms = append(rnms, strings.Join([]string{nm, es, nm2}, ""))
				}
			}
		}
	} else {
		rnms = nms
	}

	var cnt int
	for _, pref := range prefixes {
		for _, es1 := range extraSpaces {
			for _, nm := range rnms {
				for _, es2 := range extraSpaces {
					for _, es3 := range extraSpaces {
						for _, vv := range validArgs {
							line := strings.Join([]string{pref, es1, nm, es2, ":", es3, vv}, "")
							matches := matcher.FindStringSubmatch(line)
							assert.Len(t, matches, 2)
							assert.Equal(t, vv, matches[1])
							cnt++
						}
						for _, iv := range invalidArgs {
							line := strings.Join([]string{pref, es1, nm, es2, ":", es3, iv}, "")
							matches := matcher.FindStringSubmatch(line)
							assert.Empty(t, matches)
							cnt++
						}
					}
				}
			}
		}
	}
	var nm2 string
	if len(names2) > 0 {
		nm2 = " " + names2[0]
	}
	fmt.Printf("tested %d %s%s combinations\n", cnt, names[0], nm2)
}
func ParseStructFileContent(content string) (sdList []StructDescription, prop Property) {
	var structFirstLineRegex *regexp.Regexp
	structFirstLineRegex, _ = regexp.Compile("^type ([A-Za-z0-9_]+) struct[ \t]?{")
	var isStartingParseStruct bool
	var sd StructDescription

	content = strings.Replace(content, "\r", "", -1) //
	lines := strings.Split(content, "\n")
	lines = removeEmptyLineAndCommentLine(lines)
	for _, line := range lines {
		if prop.PackageName == "" {
			idx := strings.Index(line, "package ")
			if idx == 0 {
				prop.PackageName = strings.TrimSpace(line[len("package ")+idx:])
			}
			continue
		}
		line = removeCommentPart(line)
		if !isStartingParseStruct {
			matched := structFirstLineRegex.FindStringSubmatch(line)
			if len(matched) >= 2 {
				sd.Reset()
				sd.StructName = matched[1]
				isStartingParseStruct = true
			}
			continue
		}
		if line == "}" { // 解析完一个struct
			isStartingParseStruct = false
			if sd.StructName != "" && len(sd.Fields) != 0 {
				sdList = append(sdList, sd)
				sd.Reset()
			}

			continue
		}
		if isStartingParseStruct { // 在解析field 中
			fd := FieldDescriptoin{}
			tagStartIdx := strings.Index(line, "`")
			tagEndIdx := strings.LastIndex(line, "`")
			if tagStartIdx != -1 && tagEndIdx != -1 && tagEndIdx != tagStartIdx {
				fd.TagString = line[tagStartIdx+1 : tagEndIdx]
				fd.MysqlTagFieldList = parseTag(reflect.StructTag(fd.TagString).Get("mysql"))
				line = line[:tagStartIdx]
			}
			tokens := strings.Fields(line)
			if len(tokens) < 2 {
				continue
			}
			fd.FieldName = tokens[0]
			fd.FieldGoType = tokens[1]
			sd.Fields = append(sd.Fields, fd)
		}

	}

	return
}