func parse(scan *scanner, s string) (t Tag, err error) { t = und var end int if n := len(scan.token); n <= 1 { scan.toLower(0, len(scan.b)) if n == 0 || scan.token[0] != 'x' { return t, errSyntax } end = parseExtensions(scan) } else if n >= 4 { return und, errSyntax } else { // the usual case t, end = parseTag(scan) if n := len(scan.token); n == 1 { t.pExt = uint16(end) end = parseExtensions(scan) } else if end < len(scan.b) { scan.setError(errSyntax) scan.b = scan.b[:end] } } if int(t.pVariant) < len(scan.b) { if end < len(s) { s = s[:end] } if len(s) > 0 && tag.Compare(s, scan.b) == 0 { t.str = s } else { t.str = string(scan.b) } } else { t.pVariant, t.pExt = 0, 0 } return t, scan.err }
func TestScan(t *testing.T) { for i, tt := range tests { scan := makeScannerString(tt.in) for j := 0; !scan.done; j++ { if j >= len(tt.tok) { t.Errorf("%d: extra token %q", i, scan.token) } else if tag.Compare(tt.tok[j], scan.token) != 0 { t.Errorf("%d: token %d: found %q; want %q", i, j, scan.token, tt.tok[j]) break } scan.scan() } if s := strings.Join(tt.tok, "-"); tag.Compare(s, bytes.Replace(scan.b, b("_"), b("-"), -1)) != 0 { t.Errorf("%d: input: found %q; want %q", i, scan.b, s) } if (scan.err == nil) != tt.ok { t.Errorf("%d: ok: found %v; want %v", i, scan.err == nil, tt.ok) } } }
// getRegionISO3 returns the regionID for the given 3-letter ISO country code // or unknownRegion if this does not exist. func getRegionISO3(s []byte) (regionID, error) { if tag.FixCase("ZZZ", s) { for i := regionISO.Index(s[:1]); i != -1; i = regionISO.Next(s[:1], i) { if e := regionISO.Elem(i); e[2] == s[1] && e[3] == s[2] { return regionID(i) + isoRegionOffset, nil } } for i := 0; i < len(altRegionISO3); i += 3 { if tag.Compare(altRegionISO3[i:i+3], s) == 0 { return regionID(altRegionIDs[i/3]), nil } } return 0, mkErrInvalid(s) } return 0, errSyntax }