vendor: make vendor-update

This commit is contained in:
Aliaksandr Valialkin 2022-09-13 16:44:44 +03:00
parent 0ead64b6cf
commit 523ff25077
No known key found for this signature in database
GPG key ID: A72BEC6CD3D0DED1
40 changed files with 1784 additions and 343 deletions

14
go.mod
View file

@ -11,7 +11,7 @@ require (
github.com/VictoriaMetrics/fasthttp v1.1.0 github.com/VictoriaMetrics/fasthttp v1.1.0
github.com/VictoriaMetrics/metrics v1.22.2 github.com/VictoriaMetrics/metrics v1.22.2
github.com/VictoriaMetrics/metricsql v0.44.1 github.com/VictoriaMetrics/metricsql v0.44.1
github.com/aws/aws-sdk-go v1.44.93 github.com/aws/aws-sdk-go v1.44.96
github.com/cespare/xxhash/v2 v2.1.2 github.com/cespare/xxhash/v2 v2.1.2
// TODO: switch back to https://github.com/cheggaaa/pb/v3 when v3-pooling branch // TODO: switch back to https://github.com/cheggaaa/pb/v3 when v3-pooling branch
@ -22,15 +22,15 @@ require (
github.com/influxdata/influxdb v1.10.0 github.com/influxdata/influxdb v1.10.0
github.com/klauspost/compress v1.15.9 github.com/klauspost/compress v1.15.9
github.com/prometheus/prometheus v1.8.2-0.20201119142752-3ad25a6dc3d9 github.com/prometheus/prometheus v1.8.2-0.20201119142752-3ad25a6dc3d9
github.com/urfave/cli/v2 v2.14.1 github.com/urfave/cli/v2 v2.16.3
github.com/valyala/fastjson v1.6.3 github.com/valyala/fastjson v1.6.3
github.com/valyala/fastrand v1.1.0 github.com/valyala/fastrand v1.1.0
github.com/valyala/fasttemplate v1.2.1 github.com/valyala/fasttemplate v1.2.1
github.com/valyala/gozstd v1.17.0 github.com/valyala/gozstd v1.17.0
github.com/valyala/quicktemplate v1.7.0 github.com/valyala/quicktemplate v1.7.0
golang.org/x/net v0.0.0-20220907135653-1e95f45603a7 golang.org/x/net v0.0.0-20220909164309-bea034e7d591
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1
golang.org/x/sys v0.0.0-20220908150016-7ac13a9a928d golang.org/x/sys v0.0.0-20220913120320-3275c407cedc
google.golang.org/api v0.95.0 google.golang.org/api v0.95.0
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
) )
@ -63,7 +63,7 @@ require (
github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect
github.com/rivo/uniseg v0.3.4 // indirect github.com/rivo/uniseg v0.4.2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/histogram v1.2.0 // indirect github.com/valyala/histogram v1.2.0 // indirect
@ -75,7 +75,7 @@ require (
golang.org/x/text v0.3.7 // indirect golang.org/x/text v0.3.7 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220908141613-51c1cc9bc6d0 // indirect google.golang.org/genproto v0.0.0-20220909194730-69f6226f97e5 // indirect
google.golang.org/grpc v1.49.0 // indirect google.golang.org/grpc v1.49.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect google.golang.org/protobuf v1.28.1 // indirect
) )

27
go.sum
View file

@ -148,8 +148,8 @@ github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQ
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
github.com/aws/aws-sdk-go v1.35.31/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.35.31/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/aws/aws-sdk-go v1.44.93 h1:hAgd9fuaptBatSft27/5eBMdcA8+cIMqo96/tZ6rKl8= github.com/aws/aws-sdk-go v1.44.96 h1:S9paaqnJ0AJ95t5AB+iK8RM6YNZN0W0Lek1gOVJsEr8=
github.com/aws/aws-sdk-go v1.44.93/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.96/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@ -765,8 +765,8 @@ github.com/prometheus/prometheus v1.8.2-0.20201119142752-3ad25a6dc3d9/go.mod h1:
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.3.4 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw= github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8=
github.com/rivo/uniseg v0.3.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@ -828,8 +828,8 @@ github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMW
github.com/uber/jaeger-lib v2.4.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/uber/jaeger-lib v2.4.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli/v2 v2.14.1 h1:0Sx+C9404t2+DPuIJ3UpZFOEFhNG3wPxMj7uZHyZKFA= github.com/urfave/cli/v2 v2.16.3 h1:gHoFIwpPjoyIMbJp/VFd+/vuD0dAgFK4B6DpEMFJfQk=
github.com/urfave/cli/v2 v2.14.1/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/urfave/cli/v2 v2.16.3/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus= github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus=
@ -1007,8 +1007,8 @@ golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220907135653-1e95f45603a7 h1:1WGATo9HAhkWMbfyuVU0tEFP88OIkUvwaHFveQPvzCQ= golang.org/x/net v0.0.0-20220909164309-bea034e7d591 h1:D0B/7al0LLrVC8aWF4+oxpv/m8bc7ViFfVS8/gXGdqI=
golang.org/x/net v0.0.0-20220907135653-1e95f45603a7/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -1029,8 +1029,9 @@ golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 h1:2o1E+E8TpNLklK9nHiPiK1uzIYrIHt+cQx3ynCwq9V8=
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 h1:lxqLZaMad/dJHMFZH0NiNpiEZI/nhgWhe4wgzpE+MuA=
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -1141,8 +1142,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908150016-7ac13a9a928d h1:RoyzQTK76Rktm3p4xyZslc8T8I1tBz4UEjZCzeh57mM= golang.org/x/sys v0.0.0-20220913120320-3275c407cedc h1:dpclq5m2YrqPGStKmtw7IcNbKLfbIqKXvNxDJKdIKYc=
golang.org/x/sys v0.0.0-20220908150016-7ac13a9a928d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220913120320-3275c407cedc/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -1382,8 +1383,8 @@ google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP
google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220908141613-51c1cc9bc6d0 h1:bMz0aY2wd9TwUp9M7QfjBWuQqaFD/ZaTtvDpPDCo2Ow= google.golang.org/genproto v0.0.0-20220909194730-69f6226f97e5 h1:ngtP8S8JkBWfJACT9cmj5eTkS9tIWPQI5leBz/7Bq/c=
google.golang.org/genproto v0.0.0-20220908141613-51c1cc9bc6d0/go.mod h1:rQWNQYp1kbHR3+n5cARSTCF5rlJOttUn8yIhRklGAWQ= google.golang.org/genproto v0.0.0-20220909194730-69f6226f97e5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=

View file

@ -6661,12 +6661,21 @@ var awsPartition = partition{
endpointKey{ endpointKey{
Region: "ap-northeast-1", Region: "ap-northeast-1",
}: endpoint{}, }: endpoint{},
endpointKey{
Region: "ap-northeast-2",
}: endpoint{},
endpointKey{
Region: "ap-south-1",
}: endpoint{},
endpointKey{ endpointKey{
Region: "ap-southeast-1", Region: "ap-southeast-1",
}: endpoint{}, }: endpoint{},
endpointKey{ endpointKey{
Region: "ap-southeast-2", Region: "ap-southeast-2",
}: endpoint{}, }: endpoint{},
endpointKey{
Region: "ca-central-1",
}: endpoint{},
endpointKey{ endpointKey{
Region: "eu-central-1", Region: "eu-central-1",
}: endpoint{}, }: endpoint{},
@ -6676,6 +6685,12 @@ var awsPartition = partition{
endpointKey{ endpointKey{
Region: "eu-west-1", Region: "eu-west-1",
}: endpoint{}, }: endpoint{},
endpointKey{
Region: "eu-west-2",
}: endpoint{},
endpointKey{
Region: "eu-west-3",
}: endpoint{},
endpointKey{ endpointKey{
Region: "fips-us-east-1", Region: "fips-us-east-1",
}: endpoint{ }: endpoint{
@ -6703,6 +6718,9 @@ var awsPartition = partition{
}, },
Deprecated: boxedTrue, Deprecated: boxedTrue,
}, },
endpointKey{
Region: "sa-east-1",
}: endpoint{},
endpointKey{ endpointKey{
Region: "us-east-1", Region: "us-east-1",
}: endpoint{}, }: endpoint{},
@ -6721,6 +6739,9 @@ var awsPartition = partition{
}: endpoint{ }: endpoint{
Hostname: "devops-guru-fips.us-east-2.amazonaws.com", Hostname: "devops-guru-fips.us-east-2.amazonaws.com",
}, },
endpointKey{
Region: "us-west-1",
}: endpoint{},
endpointKey{ endpointKey{
Region: "us-west-2", Region: "us-west-2",
}: endpoint{}, }: endpoint{},
@ -30127,6 +30148,13 @@ var awsusgovPartition = partition{
}, },
}, },
}, },
"managedblockchain": service{
Endpoints: serviceEndpoints{
endpointKey{
Region: "us-gov-west-1",
}: endpoint{},
},
},
"mediaconvert": service{ "mediaconvert": service{
Endpoints: serviceEndpoints{ Endpoints: serviceEndpoints{
endpointKey{ endpointKey{

View file

@ -5,4 +5,4 @@ package aws
const SDKName = "aws-sdk-go" const SDKName = "aws-sdk-go"
// SDKVersion is the version of this SDK // SDKVersion is the version of this SDK
const SDKVersion = "1.44.93" const SDKVersion = "1.44.96"

View file

@ -3,13 +3,13 @@
[![Go Reference](https://pkg.go.dev/badge/github.com/rivo/uniseg.svg)](https://pkg.go.dev/github.com/rivo/uniseg) [![Go Reference](https://pkg.go.dev/badge/github.com/rivo/uniseg.svg)](https://pkg.go.dev/github.com/rivo/uniseg)
[![Go Report](https://img.shields.io/badge/go%20report-A%2B-brightgreen.svg)](https://goreportcard.com/report/github.com/rivo/uniseg) [![Go Report](https://img.shields.io/badge/go%20report-A%2B-brightgreen.svg)](https://goreportcard.com/report/github.com/rivo/uniseg)
This Go package implements Unicode Text Segmentation according to [Unicode Standard Annex #29](https://unicode.org/reports/tr29/) and Unicode Line Breaking according to [Unicode Standard Annex #14](https://unicode.org/reports/tr14/) (Unicode version 14.0.0). This Go package implements Unicode Text Segmentation according to [Unicode Standard Annex #29](https://unicode.org/reports/tr29/), Unicode Line Breaking according to [Unicode Standard Annex #14](https://unicode.org/reports/tr14/) (Unicode version 14.0.0), and monospace font string width calculation similar to [wcwidth](https://man7.org/linux/man-pages/man3/wcwidth.3.html).
## Background ## Background
### Grapheme Clusters ### Grapheme Clusters
In Go, [strings are read-only slices of bytes](https://blog.golang.org/strings). They can be turned into Unicode code points using the `for` loop or by casting: `[]rune(str)`. However, multiple code points may be combined into one user-perceived character or what the Unicode specification calls "grapheme cluster". Here are some examples: In Go, [strings are read-only slices of bytes](https://go.dev/blog/strings). They can be turned into Unicode code points using the `for` loop or by casting: `[]rune(str)`. However, multiple code points may be combined into one user-perceived character or what the Unicode specification calls "grapheme cluster". Here are some examples:
|String|Bytes (UTF-8)|Code points (runes)|Grapheme clusters| |String|Bytes (UTF-8)|Code points (runes)|Grapheme clusters|
|-|-|-|-| |-|-|-|-|
@ -31,6 +31,10 @@ Sentence boundaries are often used for triple-click or some other method of sele
Line breaking, also known as word wrapping, is the process of breaking a section of text into lines such that it will fit in the available width of a page, window or other display area. This package provides tools to determine where a string may or may not be broken and where it must be broken (for example after newline characters). Line breaking, also known as word wrapping, is the process of breaking a section of text into lines such that it will fit in the available width of a page, window or other display area. This package provides tools to determine where a string may or may not be broken and where it must be broken (for example after newline characters).
### Monospace Width
Most terminals or text displays / text editors using a monospace font (for example source code editors) use a fixed width for each character. Some characters such as emojis or characters found in Asian and other languages may take up more than one character cell. This package provides tools to determine the number of cells a string will take up when displayed in a monospace font. See [here](https://pkg.go.dev/github.com/rivo/uniseg#hdr-Monospace_Width) for more information.
## Installation ## Installation
```bash ```bash
@ -47,6 +51,14 @@ fmt.Println(n)
// 2 // 2
``` ```
### Calculating the Monospace String Width
```go
width := uniseg.StringWidth("🇩🇪🏳️‍🌈!")
fmt.Println(width)
// 5
```
### Using the [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) Class ### Using the [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) Class
This is the most convenient method of iterating over grapheme clusters: This is the most convenient method of iterating over grapheme clusters:

77
vendor/github.com/rivo/uniseg/doc.go generated vendored
View file

@ -1,8 +1,9 @@
/* /*
Package uniseg implements Unicode Text Segmentation and Unicode Line Breaking. Package uniseg implements Unicode Text Segmentation, Unicode Line Breaking, and
Unicode Text Segmentation conforms to Unicode Standard Annex #29 string width calculation for monospace fonts. Unicode Text Segmentation conforms
(https://unicode.org/reports/tr29/) and Unicode Line Breaking conforms to to Unicode Standard Annex #29 (https://unicode.org/reports/tr29/) and Unicode
Unicode Standard Annex #14 (https://unicode.org/reports/tr14/). Line Breaking conforms to Unicode Standard Annex #14
(https://unicode.org/reports/tr14/).
In short, using this package, you can split a string into grapheme clusters In short, using this package, you can split a string into grapheme clusters
(what people would usually refer to as a "character"), into words, and into (what people would usually refer to as a "character"), into words, and into
@ -12,8 +13,23 @@ as emojis, combining characters, or characters from Asian, Arabic, Hebrew, or
other languages. Additionally, you can use it to implement line breaking (or other languages. Additionally, you can use it to implement line breaking (or
"word wrapping"), that is, to determine where text can be broken over to the "word wrapping"), that is, to determine where text can be broken over to the
next line when the width of the line is not big enough to fit the entire text. next line when the width of the line is not big enough to fit the entire text.
Finally, you can use it to calculate the display width of a string for monospace
fonts.
Grapheme Clusters # Getting Started
If you just want to count the number of characters in a string, you can use
[GraphemeClusterCount]. If you want to determine the display width of a string,
you can use [StringWidth]. If you want to iterate over a string, you can use
[Step], [StepString], or the [Graphemes] class (more convenient but less
performant). This will provide you with all information: grapheme clusters,
word boundaries, sentence boundaries, line breaks, and monospace character
widths. The specialized functions [FirstGraphemeCluster],
[FirstGraphemeClusterInString], [FirstWord], [FirstWordInString],
[FirstSentence], and [FirstSentenceInString] can be used if only one type of
information is needed.
# Grapheme Clusters
Consider the rainbow flag emoji: 🏳🌈. On most modern systems, it appears as one Consider the rainbow flag emoji: 🏳🌈. On most modern systems, it appears as one
character. But its string representation actually has 14 bytes, so counting character. But its string representation actually has 14 bytes, so counting
@ -21,11 +37,11 @@ bytes (or using len("🏳️‍🌈")) will not work as expected. Counting runes
either: The flag has 4 Unicode code points, thus 4 runes. The stdlib function either: The flag has 4 Unicode code points, thus 4 runes. The stdlib function
utf8.RuneCountInString("🏳️‍🌈") and len([]rune("🏳️‍🌈")) will both return 4. utf8.RuneCountInString("🏳️‍🌈") and len([]rune("🏳️‍🌈")) will both return 4.
The uniseg.GraphemeClusterCount(str) function will return 1 for the rainbow flag The [GraphemeClusterCount] function will return 1 for the rainbow flag emoji.
emoji. The Graphemes class and a variety of functions in this package will allow The Graphemes class and a variety of functions in this package will allow you to
you to split strings into its grapheme clusters. split strings into its grapheme clusters.
Word Boundaries # Word Boundaries
Word boundaries are used in a number of different contexts. The most familiar Word boundaries are used in a number of different contexts. The most familiar
ones are selection (double-click mouse selection), cursor movement ("move to ones are selection (double-click mouse selection), cursor movement ("move to
@ -33,7 +49,7 @@ next word" control-arrow keys), and the dialog option "Whole Word Search" for
search and replace. This package provides methods for determining word search and replace. This package provides methods for determining word
boundaries. boundaries.
Sentence Boundaries # Sentence Boundaries
Sentence boundaries are often used for triple-click or some other method of Sentence boundaries are often used for triple-click or some other method of
selecting or iterating through blocks of text that are larger than single words. selecting or iterating through blocks of text that are larger than single words.
@ -41,7 +57,7 @@ They are also used to determine whether words occur within the same sentence in
database queries. This package provides methods for determining sentence database queries. This package provides methods for determining sentence
boundaries. boundaries.
Line Breaking # Line Breaking
Line breaking, also known as word wrapping, is the process of breaking a section Line breaking, also known as word wrapping, is the process of breaking a section
of text into lines such that it will fit in the available width of a page, of text into lines such that it will fit in the available width of a page,
@ -49,5 +65,44 @@ window or other display area. This package provides methods to determine the
positions in a string where a line must be broken, may be broken, or must not be positions in a string where a line must be broken, may be broken, or must not be
broken. broken.
# Monospace Width
Monospace width, as referred to in this package, is the width of a string in a
monospace font. This is commonly used in terminal user interfaces or text
displays or editors that don't support proportional fonts. A width of 1
corresponds to a single character cell. The C function [wcwidth()] and its
implementation in other programming languages is in widespread use for the same
purpose. However, there is no standard for the calculation of such widths, and
this package differs from wcwidth() in a number of ways, presumably to generate
more visually pleasing results.
To start, we assume that every code point has a width of 1, with the following
exceptions:
- Code points with grapheme cluster break properties Control, CR, LF, Extend,
and ZWJ have a width of 0.
- U+2E3A, Two-Em Dash, has a width of 3.
- U+2E3B, Three-Em Dash, has a width of 4.
- Characters with the East-Asian Width properties "Fullwidth" (F) and "Wide"
(W) have a width of 2. (Properties "Ambiguous" (A) and "Neutral" (N) both
have a width of 1.)
- Code points with grapheme cluster break property Regional Indicator have a
width of 2.
- Code points with grapheme cluster break property Extended Pictographic have
a width of 2, unless their Emoji Presentation flag is "No", in which case
the width is 1.
For Hangul grapheme clusters composed of conjoining Jamo and for Regional
Indicators (flags), all code points except the first one have a width of 0. For
grapheme clusters starting with an Extended Pictographic, any additional code
point will force a total width of 2, except if the Variation Selector-15
(U+FE0E) is included, in which case the total width is always 1. Grapheme
clusters ending with Variation Selector-16 (U+FE0F) have a width of 2.
Note that whether these widths appear correct depends on your application's
render engine, to which extent it conforms to the Unicode Standard, and its
choice of font.
[wcwidth()]: https://man7.org/linux/man-pages/man3/wcwidth.3.html
*/ */
package uniseg package uniseg

View file

@ -4,7 +4,10 @@ package uniseg
// eastAsianWidth are taken from // eastAsianWidth are taken from
// https://www.unicode.org/Public/14.0.0/ucd/EastAsianWidth.txt // https://www.unicode.org/Public/14.0.0/ucd/EastAsianWidth.txt
// on July 25, 2022. See https://www.unicode.org/license.html for the Unicode // and
// https://unicode.org/Public/14.0.0/ucd/emoji/emoji-data.txt
// ("Extended_Pictographic" only)
// on September 10, 2022. See https://www.unicode.org/license.html for the Unicode
// license agreement. // license agreement.
var eastAsianWidth = [][3]int{ var eastAsianWidth = [][3]int{
{0x0000, 0x001F, prN}, // Cc [32] <control-0000>..<control-001F> {0x0000, 0x001F, prN}, // Cc [32] <control-0000>..<control-001F>

285
vendor/github.com/rivo/uniseg/emojipresentation.go generated vendored Normal file
View file

@ -0,0 +1,285 @@
package uniseg
// Code generated via go generate from gen_properties.go. DO NOT EDIT.
// emojiPresentation are taken from
//
// and
// https://unicode.org/Public/14.0.0/ucd/emoji/emoji-data.txt
// ("Extended_Pictographic" only)
// on September 10, 2022. See https://www.unicode.org/license.html for the Unicode
// license agreement.
var emojiPresentation = [][3]int{
{0x231A, 0x231B, prEmojiPresentation}, // E0.6 [2] (⌚..⌛) watch..hourglass done
{0x23E9, 0x23EC, prEmojiPresentation}, // E0.6 [4] (⏩..⏬) fast-forward button..fast down button
{0x23F0, 0x23F0, prEmojiPresentation}, // E0.6 [1] (⏰) alarm clock
{0x23F3, 0x23F3, prEmojiPresentation}, // E0.6 [1] (⏳) hourglass not done
{0x25FD, 0x25FE, prEmojiPresentation}, // E0.6 [2] (◽..◾) white medium-small square..black medium-small square
{0x2614, 0x2615, prEmojiPresentation}, // E0.6 [2] (☔..☕) umbrella with rain drops..hot beverage
{0x2648, 0x2653, prEmojiPresentation}, // E0.6 [12] (♈..♓) Aries..Pisces
{0x267F, 0x267F, prEmojiPresentation}, // E0.6 [1] (♿) wheelchair symbol
{0x2693, 0x2693, prEmojiPresentation}, // E0.6 [1] (⚓) anchor
{0x26A1, 0x26A1, prEmojiPresentation}, // E0.6 [1] (⚡) high voltage
{0x26AA, 0x26AB, prEmojiPresentation}, // E0.6 [2] (⚪..⚫) white circle..black circle
{0x26BD, 0x26BE, prEmojiPresentation}, // E0.6 [2] (⚽..⚾) soccer ball..baseball
{0x26C4, 0x26C5, prEmojiPresentation}, // E0.6 [2] (⛄..⛅) snowman without snow..sun behind cloud
{0x26CE, 0x26CE, prEmojiPresentation}, // E0.6 [1] (⛎) Ophiuchus
{0x26D4, 0x26D4, prEmojiPresentation}, // E0.6 [1] (⛔) no entry
{0x26EA, 0x26EA, prEmojiPresentation}, // E0.6 [1] (⛪) church
{0x26F2, 0x26F3, prEmojiPresentation}, // E0.6 [2] (⛲..⛳) fountain..flag in hole
{0x26F5, 0x26F5, prEmojiPresentation}, // E0.6 [1] (⛵) sailboat
{0x26FA, 0x26FA, prEmojiPresentation}, // E0.6 [1] (⛺) tent
{0x26FD, 0x26FD, prEmojiPresentation}, // E0.6 [1] (⛽) fuel pump
{0x2705, 0x2705, prEmojiPresentation}, // E0.6 [1] (✅) check mark button
{0x270A, 0x270B, prEmojiPresentation}, // E0.6 [2] (✊..✋) raised fist..raised hand
{0x2728, 0x2728, prEmojiPresentation}, // E0.6 [1] (✨) sparkles
{0x274C, 0x274C, prEmojiPresentation}, // E0.6 [1] (❌) cross mark
{0x274E, 0x274E, prEmojiPresentation}, // E0.6 [1] (❎) cross mark button
{0x2753, 0x2755, prEmojiPresentation}, // E0.6 [3] (❓..❕) red question mark..white exclamation mark
{0x2757, 0x2757, prEmojiPresentation}, // E0.6 [1] (❗) red exclamation mark
{0x2795, 0x2797, prEmojiPresentation}, // E0.6 [3] (..➗) plus..divide
{0x27B0, 0x27B0, prEmojiPresentation}, // E0.6 [1] (➰) curly loop
{0x27BF, 0x27BF, prEmojiPresentation}, // E1.0 [1] (➿) double curly loop
{0x2B1B, 0x2B1C, prEmojiPresentation}, // E0.6 [2] (⬛..⬜) black large square..white large square
{0x2B50, 0x2B50, prEmojiPresentation}, // E0.6 [1] (⭐) star
{0x2B55, 0x2B55, prEmojiPresentation}, // E0.6 [1] (⭕) hollow red circle
{0x1F004, 0x1F004, prEmojiPresentation}, // E0.6 [1] (🀄) mahjong red dragon
{0x1F0CF, 0x1F0CF, prEmojiPresentation}, // E0.6 [1] (🃏) joker
{0x1F18E, 0x1F18E, prEmojiPresentation}, // E0.6 [1] (🆎) AB button (blood type)
{0x1F191, 0x1F19A, prEmojiPresentation}, // E0.6 [10] (🆑..🆚) CL button..VS button
{0x1F1E6, 0x1F1FF, prEmojiPresentation}, // E0.0 [26] (🇦..🇿) regional indicator symbol letter a..regional indicator symbol letter z
{0x1F201, 0x1F201, prEmojiPresentation}, // E0.6 [1] (🈁) Japanese “here” button
{0x1F21A, 0x1F21A, prEmojiPresentation}, // E0.6 [1] (🈚) Japanese “free of charge” button
{0x1F22F, 0x1F22F, prEmojiPresentation}, // E0.6 [1] (🈯) Japanese “reserved” button
{0x1F232, 0x1F236, prEmojiPresentation}, // E0.6 [5] (🈲..🈶) Japanese “prohibited” button..Japanese “not free of charge” button
{0x1F238, 0x1F23A, prEmojiPresentation}, // E0.6 [3] (🈸..🈺) Japanese “application” button..Japanese “open for business” button
{0x1F250, 0x1F251, prEmojiPresentation}, // E0.6 [2] (🉐..🉑) Japanese “bargain” button..Japanese “acceptable” button
{0x1F300, 0x1F30C, prEmojiPresentation}, // E0.6 [13] (🌀..🌌) cyclone..milky way
{0x1F30D, 0x1F30E, prEmojiPresentation}, // E0.7 [2] (🌍..🌎) globe showing Europe-Africa..globe showing Americas
{0x1F30F, 0x1F30F, prEmojiPresentation}, // E0.6 [1] (🌏) globe showing Asia-Australia
{0x1F310, 0x1F310, prEmojiPresentation}, // E1.0 [1] (🌐) globe with meridians
{0x1F311, 0x1F311, prEmojiPresentation}, // E0.6 [1] (🌑) new moon
{0x1F312, 0x1F312, prEmojiPresentation}, // E1.0 [1] (🌒) waxing crescent moon
{0x1F313, 0x1F315, prEmojiPresentation}, // E0.6 [3] (🌓..🌕) first quarter moon..full moon
{0x1F316, 0x1F318, prEmojiPresentation}, // E1.0 [3] (🌖..🌘) waning gibbous moon..waning crescent moon
{0x1F319, 0x1F319, prEmojiPresentation}, // E0.6 [1] (🌙) crescent moon
{0x1F31A, 0x1F31A, prEmojiPresentation}, // E1.0 [1] (🌚) new moon face
{0x1F31B, 0x1F31B, prEmojiPresentation}, // E0.6 [1] (🌛) first quarter moon face
{0x1F31C, 0x1F31C, prEmojiPresentation}, // E0.7 [1] (🌜) last quarter moon face
{0x1F31D, 0x1F31E, prEmojiPresentation}, // E1.0 [2] (🌝..🌞) full moon face..sun with face
{0x1F31F, 0x1F320, prEmojiPresentation}, // E0.6 [2] (🌟..🌠) glowing star..shooting star
{0x1F32D, 0x1F32F, prEmojiPresentation}, // E1.0 [3] (🌭..🌯) hot dog..burrito
{0x1F330, 0x1F331, prEmojiPresentation}, // E0.6 [2] (🌰..🌱) chestnut..seedling
{0x1F332, 0x1F333, prEmojiPresentation}, // E1.0 [2] (🌲..🌳) evergreen tree..deciduous tree
{0x1F334, 0x1F335, prEmojiPresentation}, // E0.6 [2] (🌴..🌵) palm tree..cactus
{0x1F337, 0x1F34A, prEmojiPresentation}, // E0.6 [20] (🌷..🍊) tulip..tangerine
{0x1F34B, 0x1F34B, prEmojiPresentation}, // E1.0 [1] (🍋) lemon
{0x1F34C, 0x1F34F, prEmojiPresentation}, // E0.6 [4] (🍌..🍏) banana..green apple
{0x1F350, 0x1F350, prEmojiPresentation}, // E1.0 [1] (🍐) pear
{0x1F351, 0x1F37B, prEmojiPresentation}, // E0.6 [43] (🍑..🍻) peach..clinking beer mugs
{0x1F37C, 0x1F37C, prEmojiPresentation}, // E1.0 [1] (🍼) baby bottle
{0x1F37E, 0x1F37F, prEmojiPresentation}, // E1.0 [2] (🍾..🍿) bottle with popping cork..popcorn
{0x1F380, 0x1F393, prEmojiPresentation}, // E0.6 [20] (🎀..🎓) ribbon..graduation cap
{0x1F3A0, 0x1F3C4, prEmojiPresentation}, // E0.6 [37] (🎠..🏄) carousel horse..person surfing
{0x1F3C5, 0x1F3C5, prEmojiPresentation}, // E1.0 [1] (🏅) sports medal
{0x1F3C6, 0x1F3C6, prEmojiPresentation}, // E0.6 [1] (🏆) trophy
{0x1F3C7, 0x1F3C7, prEmojiPresentation}, // E1.0 [1] (🏇) horse racing
{0x1F3C8, 0x1F3C8, prEmojiPresentation}, // E0.6 [1] (🏈) american football
{0x1F3C9, 0x1F3C9, prEmojiPresentation}, // E1.0 [1] (🏉) rugby football
{0x1F3CA, 0x1F3CA, prEmojiPresentation}, // E0.6 [1] (🏊) person swimming
{0x1F3CF, 0x1F3D3, prEmojiPresentation}, // E1.0 [5] (🏏..🏓) cricket game..ping pong
{0x1F3E0, 0x1F3E3, prEmojiPresentation}, // E0.6 [4] (🏠..🏣) house..Japanese post office
{0x1F3E4, 0x1F3E4, prEmojiPresentation}, // E1.0 [1] (🏤) post office
{0x1F3E5, 0x1F3F0, prEmojiPresentation}, // E0.6 [12] (🏥..🏰) hospital..castle
{0x1F3F4, 0x1F3F4, prEmojiPresentation}, // E1.0 [1] (🏴) black flag
{0x1F3F8, 0x1F407, prEmojiPresentation}, // E1.0 [16] (🏸..🐇) badminton..rabbit
{0x1F408, 0x1F408, prEmojiPresentation}, // E0.7 [1] (🐈) cat
{0x1F409, 0x1F40B, prEmojiPresentation}, // E1.0 [3] (🐉..🐋) dragon..whale
{0x1F40C, 0x1F40E, prEmojiPresentation}, // E0.6 [3] (🐌..🐎) snail..horse
{0x1F40F, 0x1F410, prEmojiPresentation}, // E1.0 [2] (🐏..🐐) ram..goat
{0x1F411, 0x1F412, prEmojiPresentation}, // E0.6 [2] (🐑..🐒) ewe..monkey
{0x1F413, 0x1F413, prEmojiPresentation}, // E1.0 [1] (🐓) rooster
{0x1F414, 0x1F414, prEmojiPresentation}, // E0.6 [1] (🐔) chicken
{0x1F415, 0x1F415, prEmojiPresentation}, // E0.7 [1] (🐕) dog
{0x1F416, 0x1F416, prEmojiPresentation}, // E1.0 [1] (🐖) pig
{0x1F417, 0x1F429, prEmojiPresentation}, // E0.6 [19] (🐗..🐩) boar..poodle
{0x1F42A, 0x1F42A, prEmojiPresentation}, // E1.0 [1] (🐪) camel
{0x1F42B, 0x1F43E, prEmojiPresentation}, // E0.6 [20] (🐫..🐾) two-hump camel..paw prints
{0x1F440, 0x1F440, prEmojiPresentation}, // E0.6 [1] (👀) eyes
{0x1F442, 0x1F464, prEmojiPresentation}, // E0.6 [35] (👂..👤) ear..bust in silhouette
{0x1F465, 0x1F465, prEmojiPresentation}, // E1.0 [1] (👥) busts in silhouette
{0x1F466, 0x1F46B, prEmojiPresentation}, // E0.6 [6] (👦..👫) boy..woman and man holding hands
{0x1F46C, 0x1F46D, prEmojiPresentation}, // E1.0 [2] (👬..👭) men holding hands..women holding hands
{0x1F46E, 0x1F4AC, prEmojiPresentation}, // E0.6 [63] (👮..💬) police officer..speech balloon
{0x1F4AD, 0x1F4AD, prEmojiPresentation}, // E1.0 [1] (💭) thought balloon
{0x1F4AE, 0x1F4B5, prEmojiPresentation}, // E0.6 [8] (💮..💵) white flower..dollar banknote
{0x1F4B6, 0x1F4B7, prEmojiPresentation}, // E1.0 [2] (💶..💷) euro banknote..pound banknote
{0x1F4B8, 0x1F4EB, prEmojiPresentation}, // E0.6 [52] (💸..📫) money with wings..closed mailbox with raised flag
{0x1F4EC, 0x1F4ED, prEmojiPresentation}, // E0.7 [2] (📬..📭) open mailbox with raised flag..open mailbox with lowered flag
{0x1F4EE, 0x1F4EE, prEmojiPresentation}, // E0.6 [1] (📮) postbox
{0x1F4EF, 0x1F4EF, prEmojiPresentation}, // E1.0 [1] (📯) postal horn
{0x1F4F0, 0x1F4F4, prEmojiPresentation}, // E0.6 [5] (📰..📴) newspaper..mobile phone off
{0x1F4F5, 0x1F4F5, prEmojiPresentation}, // E1.0 [1] (📵) no mobile phones
{0x1F4F6, 0x1F4F7, prEmojiPresentation}, // E0.6 [2] (📶..📷) antenna bars..camera
{0x1F4F8, 0x1F4F8, prEmojiPresentation}, // E1.0 [1] (📸) camera with flash
{0x1F4F9, 0x1F4FC, prEmojiPresentation}, // E0.6 [4] (📹..📼) video camera..videocassette
{0x1F4FF, 0x1F502, prEmojiPresentation}, // E1.0 [4] (📿..🔂) prayer beads..repeat single button
{0x1F503, 0x1F503, prEmojiPresentation}, // E0.6 [1] (🔃) clockwise vertical arrows
{0x1F504, 0x1F507, prEmojiPresentation}, // E1.0 [4] (🔄..🔇) counterclockwise arrows button..muted speaker
{0x1F508, 0x1F508, prEmojiPresentation}, // E0.7 [1] (🔈) speaker low volume
{0x1F509, 0x1F509, prEmojiPresentation}, // E1.0 [1] (🔉) speaker medium volume
{0x1F50A, 0x1F514, prEmojiPresentation}, // E0.6 [11] (🔊..🔔) speaker high volume..bell
{0x1F515, 0x1F515, prEmojiPresentation}, // E1.0 [1] (🔕) bell with slash
{0x1F516, 0x1F52B, prEmojiPresentation}, // E0.6 [22] (🔖..🔫) bookmark..water pistol
{0x1F52C, 0x1F52D, prEmojiPresentation}, // E1.0 [2] (🔬..🔭) microscope..telescope
{0x1F52E, 0x1F53D, prEmojiPresentation}, // E0.6 [16] (🔮..🔽) crystal ball..downwards button
{0x1F54B, 0x1F54E, prEmojiPresentation}, // E1.0 [4] (🕋..🕎) kaaba..menorah
{0x1F550, 0x1F55B, prEmojiPresentation}, // E0.6 [12] (🕐..🕛) one oclock..twelve oclock
{0x1F55C, 0x1F567, prEmojiPresentation}, // E0.7 [12] (🕜..🕧) one-thirty..twelve-thirty
{0x1F57A, 0x1F57A, prEmojiPresentation}, // E3.0 [1] (🕺) man dancing
{0x1F595, 0x1F596, prEmojiPresentation}, // E1.0 [2] (🖕..🖖) middle finger..vulcan salute
{0x1F5A4, 0x1F5A4, prEmojiPresentation}, // E3.0 [1] (🖤) black heart
{0x1F5FB, 0x1F5FF, prEmojiPresentation}, // E0.6 [5] (🗻..🗿) mount fuji..moai
{0x1F600, 0x1F600, prEmojiPresentation}, // E1.0 [1] (😀) grinning face
{0x1F601, 0x1F606, prEmojiPresentation}, // E0.6 [6] (😁..😆) beaming face with smiling eyes..grinning squinting face
{0x1F607, 0x1F608, prEmojiPresentation}, // E1.0 [2] (😇..😈) smiling face with halo..smiling face with horns
{0x1F609, 0x1F60D, prEmojiPresentation}, // E0.6 [5] (😉..😍) winking face..smiling face with heart-eyes
{0x1F60E, 0x1F60E, prEmojiPresentation}, // E1.0 [1] (😎) smiling face with sunglasses
{0x1F60F, 0x1F60F, prEmojiPresentation}, // E0.6 [1] (😏) smirking face
{0x1F610, 0x1F610, prEmojiPresentation}, // E0.7 [1] (😐) neutral face
{0x1F611, 0x1F611, prEmojiPresentation}, // E1.0 [1] (😑) expressionless face
{0x1F612, 0x1F614, prEmojiPresentation}, // E0.6 [3] (😒..😔) unamused face..pensive face
{0x1F615, 0x1F615, prEmojiPresentation}, // E1.0 [1] (😕) confused face
{0x1F616, 0x1F616, prEmojiPresentation}, // E0.6 [1] (😖) confounded face
{0x1F617, 0x1F617, prEmojiPresentation}, // E1.0 [1] (😗) kissing face
{0x1F618, 0x1F618, prEmojiPresentation}, // E0.6 [1] (😘) face blowing a kiss
{0x1F619, 0x1F619, prEmojiPresentation}, // E1.0 [1] (😙) kissing face with smiling eyes
{0x1F61A, 0x1F61A, prEmojiPresentation}, // E0.6 [1] (😚) kissing face with closed eyes
{0x1F61B, 0x1F61B, prEmojiPresentation}, // E1.0 [1] (😛) face with tongue
{0x1F61C, 0x1F61E, prEmojiPresentation}, // E0.6 [3] (😜..😞) winking face with tongue..disappointed face
{0x1F61F, 0x1F61F, prEmojiPresentation}, // E1.0 [1] (😟) worried face
{0x1F620, 0x1F625, prEmojiPresentation}, // E0.6 [6] (😠..😥) angry face..sad but relieved face
{0x1F626, 0x1F627, prEmojiPresentation}, // E1.0 [2] (😦..😧) frowning face with open mouth..anguished face
{0x1F628, 0x1F62B, prEmojiPresentation}, // E0.6 [4] (😨..😫) fearful face..tired face
{0x1F62C, 0x1F62C, prEmojiPresentation}, // E1.0 [1] (😬) grimacing face
{0x1F62D, 0x1F62D, prEmojiPresentation}, // E0.6 [1] (😭) loudly crying face
{0x1F62E, 0x1F62F, prEmojiPresentation}, // E1.0 [2] (😮..😯) face with open mouth..hushed face
{0x1F630, 0x1F633, prEmojiPresentation}, // E0.6 [4] (😰..😳) anxious face with sweat..flushed face
{0x1F634, 0x1F634, prEmojiPresentation}, // E1.0 [1] (😴) sleeping face
{0x1F635, 0x1F635, prEmojiPresentation}, // E0.6 [1] (😵) face with crossed-out eyes
{0x1F636, 0x1F636, prEmojiPresentation}, // E1.0 [1] (😶) face without mouth
{0x1F637, 0x1F640, prEmojiPresentation}, // E0.6 [10] (😷..🙀) face with medical mask..weary cat
{0x1F641, 0x1F644, prEmojiPresentation}, // E1.0 [4] (🙁..🙄) slightly frowning face..face with rolling eyes
{0x1F645, 0x1F64F, prEmojiPresentation}, // E0.6 [11] (🙅..🙏) person gesturing NO..folded hands
{0x1F680, 0x1F680, prEmojiPresentation}, // E0.6 [1] (🚀) rocket
{0x1F681, 0x1F682, prEmojiPresentation}, // E1.0 [2] (🚁..🚂) helicopter..locomotive
{0x1F683, 0x1F685, prEmojiPresentation}, // E0.6 [3] (🚃..🚅) railway car..bullet train
{0x1F686, 0x1F686, prEmojiPresentation}, // E1.0 [1] (🚆) train
{0x1F687, 0x1F687, prEmojiPresentation}, // E0.6 [1] (🚇) metro
{0x1F688, 0x1F688, prEmojiPresentation}, // E1.0 [1] (🚈) light rail
{0x1F689, 0x1F689, prEmojiPresentation}, // E0.6 [1] (🚉) station
{0x1F68A, 0x1F68B, prEmojiPresentation}, // E1.0 [2] (🚊..🚋) tram..tram car
{0x1F68C, 0x1F68C, prEmojiPresentation}, // E0.6 [1] (🚌) bus
{0x1F68D, 0x1F68D, prEmojiPresentation}, // E0.7 [1] (🚍) oncoming bus
{0x1F68E, 0x1F68E, prEmojiPresentation}, // E1.0 [1] (🚎) trolleybus
{0x1F68F, 0x1F68F, prEmojiPresentation}, // E0.6 [1] (🚏) bus stop
{0x1F690, 0x1F690, prEmojiPresentation}, // E1.0 [1] (🚐) minibus
{0x1F691, 0x1F693, prEmojiPresentation}, // E0.6 [3] (🚑..🚓) ambulance..police car
{0x1F694, 0x1F694, prEmojiPresentation}, // E0.7 [1] (🚔) oncoming police car
{0x1F695, 0x1F695, prEmojiPresentation}, // E0.6 [1] (🚕) taxi
{0x1F696, 0x1F696, prEmojiPresentation}, // E1.0 [1] (🚖) oncoming taxi
{0x1F697, 0x1F697, prEmojiPresentation}, // E0.6 [1] (🚗) automobile
{0x1F698, 0x1F698, prEmojiPresentation}, // E0.7 [1] (🚘) oncoming automobile
{0x1F699, 0x1F69A, prEmojiPresentation}, // E0.6 [2] (🚙..🚚) sport utility vehicle..delivery truck
{0x1F69B, 0x1F6A1, prEmojiPresentation}, // E1.0 [7] (🚛..🚡) articulated lorry..aerial tramway
{0x1F6A2, 0x1F6A2, prEmojiPresentation}, // E0.6 [1] (🚢) ship
{0x1F6A3, 0x1F6A3, prEmojiPresentation}, // E1.0 [1] (🚣) person rowing boat
{0x1F6A4, 0x1F6A5, prEmojiPresentation}, // E0.6 [2] (🚤..🚥) speedboat..horizontal traffic light
{0x1F6A6, 0x1F6A6, prEmojiPresentation}, // E1.0 [1] (🚦) vertical traffic light
{0x1F6A7, 0x1F6AD, prEmojiPresentation}, // E0.6 [7] (🚧..🚭) construction..no smoking
{0x1F6AE, 0x1F6B1, prEmojiPresentation}, // E1.0 [4] (🚮..🚱) litter in bin sign..non-potable water
{0x1F6B2, 0x1F6B2, prEmojiPresentation}, // E0.6 [1] (🚲) bicycle
{0x1F6B3, 0x1F6B5, prEmojiPresentation}, // E1.0 [3] (🚳..🚵) no bicycles..person mountain biking
{0x1F6B6, 0x1F6B6, prEmojiPresentation}, // E0.6 [1] (🚶) person walking
{0x1F6B7, 0x1F6B8, prEmojiPresentation}, // E1.0 [2] (🚷..🚸) no pedestrians..children crossing
{0x1F6B9, 0x1F6BE, prEmojiPresentation}, // E0.6 [6] (🚹..🚾) mens room..water closet
{0x1F6BF, 0x1F6BF, prEmojiPresentation}, // E1.0 [1] (🚿) shower
{0x1F6C0, 0x1F6C0, prEmojiPresentation}, // E0.6 [1] (🛀) person taking bath
{0x1F6C1, 0x1F6C5, prEmojiPresentation}, // E1.0 [5] (🛁..🛅) bathtub..left luggage
{0x1F6CC, 0x1F6CC, prEmojiPresentation}, // E1.0 [1] (🛌) person in bed
{0x1F6D0, 0x1F6D0, prEmojiPresentation}, // E1.0 [1] (🛐) place of worship
{0x1F6D1, 0x1F6D2, prEmojiPresentation}, // E3.0 [2] (🛑..🛒) stop sign..shopping cart
{0x1F6D5, 0x1F6D5, prEmojiPresentation}, // E12.0 [1] (🛕) hindu temple
{0x1F6D6, 0x1F6D7, prEmojiPresentation}, // E13.0 [2] (🛖..🛗) hut..elevator
{0x1F6DD, 0x1F6DF, prEmojiPresentation}, // E14.0 [3] (🛝..🛟) playground slide..ring buoy
{0x1F6EB, 0x1F6EC, prEmojiPresentation}, // E1.0 [2] (🛫..🛬) airplane departure..airplane arrival
{0x1F6F4, 0x1F6F6, prEmojiPresentation}, // E3.0 [3] (🛴..🛶) kick scooter..canoe
{0x1F6F7, 0x1F6F8, prEmojiPresentation}, // E5.0 [2] (🛷..🛸) sled..flying saucer
{0x1F6F9, 0x1F6F9, prEmojiPresentation}, // E11.0 [1] (🛹) skateboard
{0x1F6FA, 0x1F6FA, prEmojiPresentation}, // E12.0 [1] (🛺) auto rickshaw
{0x1F6FB, 0x1F6FC, prEmojiPresentation}, // E13.0 [2] (🛻..🛼) pickup truck..roller skate
{0x1F7E0, 0x1F7EB, prEmojiPresentation}, // E12.0 [12] (🟠..🟫) orange circle..brown square
{0x1F7F0, 0x1F7F0, prEmojiPresentation}, // E14.0 [1] (🟰) heavy equals sign
{0x1F90C, 0x1F90C, prEmojiPresentation}, // E13.0 [1] (🤌) pinched fingers
{0x1F90D, 0x1F90F, prEmojiPresentation}, // E12.0 [3] (🤍..🤏) white heart..pinching hand
{0x1F910, 0x1F918, prEmojiPresentation}, // E1.0 [9] (🤐..🤘) zipper-mouth face..sign of the horns
{0x1F919, 0x1F91E, prEmojiPresentation}, // E3.0 [6] (🤙..🤞) call me hand..crossed fingers
{0x1F91F, 0x1F91F, prEmojiPresentation}, // E5.0 [1] (🤟) love-you gesture
{0x1F920, 0x1F927, prEmojiPresentation}, // E3.0 [8] (🤠..🤧) cowboy hat face..sneezing face
{0x1F928, 0x1F92F, prEmojiPresentation}, // E5.0 [8] (🤨..🤯) face with raised eyebrow..exploding head
{0x1F930, 0x1F930, prEmojiPresentation}, // E3.0 [1] (🤰) pregnant woman
{0x1F931, 0x1F932, prEmojiPresentation}, // E5.0 [2] (🤱..🤲) breast-feeding..palms up together
{0x1F933, 0x1F93A, prEmojiPresentation}, // E3.0 [8] (🤳..🤺) selfie..person fencing
{0x1F93C, 0x1F93E, prEmojiPresentation}, // E3.0 [3] (🤼..🤾) people wrestling..person playing handball
{0x1F93F, 0x1F93F, prEmojiPresentation}, // E12.0 [1] (🤿) diving mask
{0x1F940, 0x1F945, prEmojiPresentation}, // E3.0 [6] (🥀..🥅) wilted flower..goal net
{0x1F947, 0x1F94B, prEmojiPresentation}, // E3.0 [5] (🥇..🥋) 1st place medal..martial arts uniform
{0x1F94C, 0x1F94C, prEmojiPresentation}, // E5.0 [1] (🥌) curling stone
{0x1F94D, 0x1F94F, prEmojiPresentation}, // E11.0 [3] (🥍..🥏) lacrosse..flying disc
{0x1F950, 0x1F95E, prEmojiPresentation}, // E3.0 [15] (🥐..🥞) croissant..pancakes
{0x1F95F, 0x1F96B, prEmojiPresentation}, // E5.0 [13] (🥟..🥫) dumpling..canned food
{0x1F96C, 0x1F970, prEmojiPresentation}, // E11.0 [5] (🥬..🥰) leafy green..smiling face with hearts
{0x1F971, 0x1F971, prEmojiPresentation}, // E12.0 [1] (🥱) yawning face
{0x1F972, 0x1F972, prEmojiPresentation}, // E13.0 [1] (🥲) smiling face with tear
{0x1F973, 0x1F976, prEmojiPresentation}, // E11.0 [4] (🥳..🥶) partying face..cold face
{0x1F977, 0x1F978, prEmojiPresentation}, // E13.0 [2] (🥷..🥸) ninja..disguised face
{0x1F979, 0x1F979, prEmojiPresentation}, // E14.0 [1] (🥹) face holding back tears
{0x1F97A, 0x1F97A, prEmojiPresentation}, // E11.0 [1] (🥺) pleading face
{0x1F97B, 0x1F97B, prEmojiPresentation}, // E12.0 [1] (🥻) sari
{0x1F97C, 0x1F97F, prEmojiPresentation}, // E11.0 [4] (🥼..🥿) lab coat..flat shoe
{0x1F980, 0x1F984, prEmojiPresentation}, // E1.0 [5] (🦀..🦄) crab..unicorn
{0x1F985, 0x1F991, prEmojiPresentation}, // E3.0 [13] (🦅..🦑) eagle..squid
{0x1F992, 0x1F997, prEmojiPresentation}, // E5.0 [6] (🦒..🦗) giraffe..cricket
{0x1F998, 0x1F9A2, prEmojiPresentation}, // E11.0 [11] (🦘..🦢) kangaroo..swan
{0x1F9A3, 0x1F9A4, prEmojiPresentation}, // E13.0 [2] (🦣..🦤) mammoth..dodo
{0x1F9A5, 0x1F9AA, prEmojiPresentation}, // E12.0 [6] (🦥..🦪) sloth..oyster
{0x1F9AB, 0x1F9AD, prEmojiPresentation}, // E13.0 [3] (🦫..🦭) beaver..seal
{0x1F9AE, 0x1F9AF, prEmojiPresentation}, // E12.0 [2] (🦮..🦯) guide dog..white cane
{0x1F9B0, 0x1F9B9, prEmojiPresentation}, // E11.0 [10] (🦰..🦹) red hair..supervillain
{0x1F9BA, 0x1F9BF, prEmojiPresentation}, // E12.0 [6] (🦺..🦿) safety vest..mechanical leg
{0x1F9C0, 0x1F9C0, prEmojiPresentation}, // E1.0 [1] (🧀) cheese wedge
{0x1F9C1, 0x1F9C2, prEmojiPresentation}, // E11.0 [2] (🧁..🧂) cupcake..salt
{0x1F9C3, 0x1F9CA, prEmojiPresentation}, // E12.0 [8] (🧃..🧊) beverage box..ice
{0x1F9CB, 0x1F9CB, prEmojiPresentation}, // E13.0 [1] (🧋) bubble tea
{0x1F9CC, 0x1F9CC, prEmojiPresentation}, // E14.0 [1] (🧌) troll
{0x1F9CD, 0x1F9CF, prEmojiPresentation}, // E12.0 [3] (🧍..🧏) person standing..deaf person
{0x1F9D0, 0x1F9E6, prEmojiPresentation}, // E5.0 [23] (🧐..🧦) face with monocle..socks
{0x1F9E7, 0x1F9FF, prEmojiPresentation}, // E11.0 [25] (🧧..🧿) red envelope..nazar amulet
{0x1FA70, 0x1FA73, prEmojiPresentation}, // E12.0 [4] (🩰..🩳) ballet shoes..shorts
{0x1FA74, 0x1FA74, prEmojiPresentation}, // E13.0 [1] (🩴) thong sandal
{0x1FA78, 0x1FA7A, prEmojiPresentation}, // E12.0 [3] (🩸..🩺) drop of blood..stethoscope
{0x1FA7B, 0x1FA7C, prEmojiPresentation}, // E14.0 [2] (🩻..🩼) x-ray..crutch
{0x1FA80, 0x1FA82, prEmojiPresentation}, // E12.0 [3] (🪀..🪂) yo-yo..parachute
{0x1FA83, 0x1FA86, prEmojiPresentation}, // E13.0 [4] (🪃..🪆) boomerang..nesting dolls
{0x1FA90, 0x1FA95, prEmojiPresentation}, // E12.0 [6] (🪐..🪕) ringed planet..banjo
{0x1FA96, 0x1FAA8, prEmojiPresentation}, // E13.0 [19] (🪖..🪨) military helmet..rock
{0x1FAA9, 0x1FAAC, prEmojiPresentation}, // E14.0 [4] (🪩..🪬) mirror ball..hamsa
{0x1FAB0, 0x1FAB6, prEmojiPresentation}, // E13.0 [7] (🪰..🪶) fly..feather
{0x1FAB7, 0x1FABA, prEmojiPresentation}, // E14.0 [4] (🪷..🪺) lotus..nest with eggs
{0x1FAC0, 0x1FAC2, prEmojiPresentation}, // E13.0 [3] (🫀..🫂) anatomical heart..people hugging
{0x1FAC3, 0x1FAC5, prEmojiPresentation}, // E14.0 [3] (🫃..🫅) pregnant man..person with crown
{0x1FAD0, 0x1FAD6, prEmojiPresentation}, // E13.0 [7] (🫐..🫖) blueberries..teapot
{0x1FAD7, 0x1FAD9, prEmojiPresentation}, // E14.0 [3] (🫗..🫙) pouring liquid..jar
{0x1FAE0, 0x1FAE7, prEmojiPresentation}, // E14.0 [8] (🫠..🫧) melting face..bubbles
{0x1FAF0, 0x1FAF6, prEmojiPresentation}, // E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands
}

View file

@ -3,19 +3,22 @@
// This program generates a property file in Go file from Unicode Character // This program generates a property file in Go file from Unicode Character
// Database auxiliary data files. The command line arguments are as follows: // Database auxiliary data files. The command line arguments are as follows:
// //
// 1. The name of the Unicode data file (just the filename, without extension). // 1. The name of the Unicode data file (just the filename, without extension).
// 2. The name of the locally generated Go file. // Can be "-" (to skip) if the emoji flag is included.
// 3. The name of the slice mapping code points to properties. // 2. The name of the locally generated Go file.
// 4. The name of the generator, for logging purposes. // 3. The name of the slice mapping code points to properties.
// 5. (Optional) Flags, comma-separated. The following flags are available: // 4. The name of the generator, for logging purposes.
// - "emojis": include emoji properties (Extended Pictographic only). // 5. (Optional) Flags, comma-separated. The following flags are available:
// - "gencat": include general category properties. // - "emojis=<property>": include the specified emoji properties (e.g.
// "Extended_Pictographic").
// - "gencat": include general category properties.
// //
//go:generate go run gen_properties.go auxiliary/GraphemeBreakProperty graphemeproperties.go graphemeCodePoints graphemes emojis //go:generate go run gen_properties.go auxiliary/GraphemeBreakProperty graphemeproperties.go graphemeCodePoints graphemes emojis=Extended_Pictographic
//go:generate go run gen_properties.go auxiliary/WordBreakProperty wordproperties.go workBreakCodePoints words emojis //go:generate go run gen_properties.go auxiliary/WordBreakProperty wordproperties.go workBreakCodePoints words emojis=Extended_Pictographic
//go:generate go run gen_properties.go auxiliary/SentenceBreakProperty sentenceproperties.go sentenceBreakCodePoints sentences //go:generate go run gen_properties.go auxiliary/SentenceBreakProperty sentenceproperties.go sentenceBreakCodePoints sentences
//go:generate go run gen_properties.go LineBreak lineproperties.go lineBreakCodePoints lines gencat //go:generate go run gen_properties.go LineBreak lineproperties.go lineBreakCodePoints lines gencat
//go:generate go run gen_properties.go EastAsianWidth eastasianwidth.go eastAsianWidth eastasianwidth //go:generate go run gen_properties.go EastAsianWidth eastasianwidth.go eastAsianWidth eastasianwidth
//go:generate go run gen_properties.go - emojipresentation.go emojiPresentation emojipresentation emojis=Emoji_Presentation
package main package main
import ( import (
@ -38,8 +41,8 @@ import (
// We want to test against a specific version rather than the latest. When the // We want to test against a specific version rather than the latest. When the
// package is upgraded to a new version, change these to generate new tests. // package is upgraded to a new version, change these to generate new tests.
const ( const (
gbpURL = `https://www.unicode.org/Public/14.0.0/ucd/%s.txt` propertyURL = `https://www.unicode.org/Public/14.0.0/ucd/%s.txt`
emojiURL = `https://unicode.org/Public/14.0.0/ucd/emoji/emoji-data.txt` emojiURL = `https://unicode.org/Public/14.0.0/ucd/emoji/emoji-data.txt`
) )
// The regular expression for a line containing a code point range property. // The regular expression for a line containing a code point range property.
@ -55,20 +58,25 @@ func main() {
log.SetFlags(0) log.SetFlags(0)
// Parse flags. // Parse flags.
flags := make(map[string]struct{}) flags := make(map[string]string)
if len(os.Args) >= 6 { if len(os.Args) >= 6 {
for _, flag := range strings.Split(os.Args[5], ",") { for _, flag := range strings.Split(os.Args[5], ",") {
flags[flag] = struct{}{} flagFields := strings.Split(flag, "=")
if len(flagFields) == 1 {
flags[flagFields[0]] = "yes"
} else {
flags[flagFields[0]] = flagFields[1]
}
} }
} }
// Parse the text file and generate Go source code from it. // Parse the text file and generate Go source code from it.
var emojis string
if _, ok := flags["emojis"]; ok {
emojis = emojiURL
}
_, includeGeneralCategory := flags["gencat"] _, includeGeneralCategory := flags["gencat"]
src, err := parse(fmt.Sprintf(gbpURL, os.Args[1]), emojis, includeGeneralCategory) var mainURL string
if os.Args[1] != "-" {
mainURL = fmt.Sprintf(propertyURL, os.Args[1])
}
src, err := parse(mainURL, flags["emojis"], includeGeneralCategory)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -88,49 +96,57 @@ func main() {
// parse parses the Unicode Properties text files located at the given URLs and // parse parses the Unicode Properties text files located at the given URLs and
// returns their equivalent Go source code to be used in the uniseg package. If // returns their equivalent Go source code to be used in the uniseg package. If
// "emojiURL" is an empty string, no emoji code points will be included. If // "emojiProperty" is not an empty string, emoji code points for that emoji
// property (e.g. "Extended_Pictographic") will be included. In those cases, you
// may pass an empty "propertyURL" to skip parsing the main properties file. If
// "includeGeneralCategory" is true, the Unicode General Category property will // "includeGeneralCategory" is true, the Unicode General Category property will
// be extracted from the comments and included in the output. // be extracted from the comments and included in the output.
func parse(gbpURL, emojiURL string, includeGeneralCategory bool) (string, error) { func parse(propertyURL, emojiProperty string, includeGeneralCategory bool) (string, error) {
if propertyURL == "" && emojiProperty == "" {
return "", errors.New("no properties to parse")
}
// Temporary buffer to hold properties. // Temporary buffer to hold properties.
var properties [][4]string var properties [][4]string
// Open the first URL. // Open the first URL.
log.Printf("Parsing %s", gbpURL) if propertyURL != "" {
res, err := http.Get(gbpURL) log.Printf("Parsing %s", propertyURL)
if err != nil { res, err := http.Get(propertyURL)
return "", err
}
in1 := res.Body
defer in1.Close()
// Parse it.
scanner := bufio.NewScanner(in1)
num := 0
for scanner.Scan() {
num++
line := strings.TrimSpace(scanner.Text())
// Skip comments and empty lines.
if strings.HasPrefix(line, "#") || line == "" {
continue
}
// Everything else must be a code point range, a property and a comment.
from, to, property, comment, err := parseProperty(line)
if err != nil { if err != nil {
return "", fmt.Errorf("%s line %d: %v", os.Args[4], num, err) return "", err
}
in1 := res.Body
defer in1.Close()
// Parse it.
scanner := bufio.NewScanner(in1)
num := 0
for scanner.Scan() {
num++
line := strings.TrimSpace(scanner.Text())
// Skip comments and empty lines.
if strings.HasPrefix(line, "#") || line == "" {
continue
}
// Everything else must be a code point range, a property and a comment.
from, to, property, comment, err := parseProperty(line)
if err != nil {
return "", fmt.Errorf("%s line %d: %v", os.Args[4], num, err)
}
properties = append(properties, [4]string{from, to, property, comment})
}
if err := scanner.Err(); err != nil {
return "", err
} }
properties = append(properties, [4]string{from, to, property, comment})
}
if err := scanner.Err(); err != nil {
return "", err
} }
// Open the second URL. // Open the second URL.
if emojiURL != "" { if emojiProperty != "" {
log.Printf("Parsing %s", emojiURL) log.Printf("Parsing %s", emojiURL)
res, err = http.Get(emojiURL) res, err := http.Get(emojiURL)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -138,15 +154,15 @@ func parse(gbpURL, emojiURL string, includeGeneralCategory bool) (string, error)
defer in2.Close() defer in2.Close()
// Parse it. // Parse it.
scanner = bufio.NewScanner(in2) scanner := bufio.NewScanner(in2)
num = 0 num := 0
for scanner.Scan() { for scanner.Scan() {
num++ num++
line := scanner.Text() line := scanner.Text()
// Skip comments, empty lines, and everything not containing // Skip comments, empty lines, and everything not containing
// "Extended_Pictographic". // "Extended_Pictographic".
if strings.HasPrefix(line, "#") || line == "" || !strings.Contains(line, "Extended_Pictographic") { if strings.HasPrefix(line, "#") || line == "" || !strings.Contains(line, emojiProperty) {
continue continue
} }
@ -189,7 +205,7 @@ func parse(gbpURL, emojiURL string, includeGeneralCategory bool) (string, error)
// Code generated via go generate from gen_properties.go. DO NOT EDIT. // Code generated via go generate from gen_properties.go. DO NOT EDIT.
// ` + os.Args[3] + ` are taken from // ` + os.Args[3] + ` are taken from
// ` + gbpURL + emojiComment + ` // ` + propertyURL + emojiComment + `
// on ` + time.Now().Format("January 2, 2006") + `. See https://www.unicode.org/license.html for the Unicode // on ` + time.Now().Format("January 2, 2006") + `. See https://www.unicode.org/license.html for the Unicode
// license agreement. // license agreement.
var ` + os.Args[3] + ` = [][` + strconv.Itoa(columns) + `]int{ var ` + os.Args[3] + ` = [][` + strconv.Itoa(columns) + `]int{

View file

@ -4,12 +4,14 @@ import "unicode/utf8"
// Graphemes implements an iterator over Unicode grapheme clusters, or // Graphemes implements an iterator over Unicode grapheme clusters, or
// user-perceived characters. While iterating, it also provides information // user-perceived characters. While iterating, it also provides information
// about word boundaries, sentence boundaries, and line breaks. // about word boundaries, sentence boundaries, line breaks, and monospace
// character widths.
// //
// After constructing the class via [NewGraphemes] for a given string "str", // After constructing the class via [NewGraphemes] for a given string "str",
// [Next] is called for every grapheme cluster in a loop until it returns false. // [Graphemes.Next] is called for every grapheme cluster in a loop until it
// Inside the loop, information about the grapheme cluster as well as boundary // returns false. Inside the loop, information about the grapheme cluster as
// information is available via the various methods (see examples below). // well as boundary information and character width is available via the various
// methods (see examples below).
// //
// Using this class to iterate over a string is convenient but it is much slower // Using this class to iterate over a string is convenient but it is much slower
// than using this package's [Step] or [StepString] functions or any of the // than using this package's [Step] or [StepString] functions or any of the
@ -28,18 +30,18 @@ type Graphemes struct {
// string. // string.
offset int offset int
// The current boundary information of the Step() parser. // The current boundary information of the [Step] parser.
boundaries int boundaries int
// The current state of the Step() parser. // The current state of the [Step] parser.
state int state int
} }
// NewGraphemes returns a new grapheme cluster iterator. // NewGraphemes returns a new grapheme cluster iterator.
func NewGraphemes(s string) *Graphemes { func NewGraphemes(str string) *Graphemes {
return &Graphemes{ return &Graphemes{
original: s, original: str,
remaining: s, remaining: str,
state: -1, state: -1,
} }
} }
@ -60,8 +62,8 @@ func (g *Graphemes) Next() bool {
} }
// Runes returns a slice of runes (code points) which corresponds to the current // Runes returns a slice of runes (code points) which corresponds to the current
// grapheme cluster. If the iterator is already past the end or [Next] has not // grapheme cluster. If the iterator is already past the end or [Graphemes.Next]
// yet been called, nil is returned. // has not yet been called, nil is returned.
func (g *Graphemes) Runes() []rune { func (g *Graphemes) Runes() []rune {
if g.state < 0 { if g.state < 0 {
return nil return nil
@ -70,15 +72,15 @@ func (g *Graphemes) Runes() []rune {
} }
// Str returns a substring of the original string which corresponds to the // Str returns a substring of the original string which corresponds to the
// current grapheme cluster. If the iterator is already past the end or [Next] // current grapheme cluster. If the iterator is already past the end or
// has not yet been called, an empty string is returned. // [Graphemes.Next] has not yet been called, an empty string is returned.
func (g *Graphemes) Str() string { func (g *Graphemes) Str() string {
return g.cluster return g.cluster
} }
// Bytes returns a byte slice which corresponds to the current grapheme cluster. // Bytes returns a byte slice which corresponds to the current grapheme cluster.
// If the iterator is already past the end or [Next] has not yet been called, // If the iterator is already past the end or [Graphemes.Next] has not yet been
// nil is returned. // called, nil is returned.
func (g *Graphemes) Bytes() []byte { func (g *Graphemes) Bytes() []byte {
if g.state < 0 { if g.state < 0 {
return nil return nil
@ -90,8 +92,8 @@ func (g *Graphemes) Bytes() []byte {
// positions into the original string. The first returned value "from" indexes // positions into the original string. The first returned value "from" indexes
// the first byte and the second returned value "to" indexes the first byte that // the first byte and the second returned value "to" indexes the first byte that
// is not included anymore, i.e. str[from:to] is the current grapheme cluster of // is not included anymore, i.e. str[from:to] is the current grapheme cluster of
// the original string "str". If [Next] has not yet been called, both values are // the original string "str". If [Graphemes.Next] has not yet been called, both
// 0. If the iterator is already past the end, both values are 1. // values are 0. If the iterator is already past the end, both values are 1.
func (g *Graphemes) Positions() (int, int) { func (g *Graphemes) Positions() (int, int) {
if g.state == -1 { if g.state == -1 {
return 0, 0 return 0, 0
@ -133,8 +135,16 @@ func (g *Graphemes) LineBreak() int {
return g.boundaries & MaskLine return g.boundaries & MaskLine
} }
// Width returns the monospace width of the current grapheme cluster.
func (g *Graphemes) Width() int {
if g.state < 0 {
return 0
}
return g.boundaries >> ShiftWidth
}
// Reset puts the iterator into its initial state such that the next call to // Reset puts the iterator into its initial state such that the next call to
// [Next] sets it to the first grapheme cluster again. // [Graphemes.Next] sets it to the first grapheme cluster again.
func (g *Graphemes) Reset() { func (g *Graphemes) Reset() {
g.state = -1 g.state = -1
g.offset = 0 g.offset = 0
@ -153,6 +163,10 @@ func GraphemeClusterCount(s string) (n int) {
return return
} }
// The number of bits the grapheme property must be shifted to make place for
// grapheme states.
const shiftGraphemePropState = 4
// FirstGraphemeCluster returns the first grapheme cluster found in the given // FirstGraphemeCluster returns the first grapheme cluster found in the given
// byte slice according to the rules of Unicode Standard Annex #29, Grapheme // byte slice according to the rules of Unicode Standard Annex #29, Grapheme
// Cluster Boundaries. This function can be called continuously to extract all // Cluster Boundaries. This function can be called continuously to extract all
@ -168,15 +182,15 @@ func GraphemeClusterCount(s string) (n int) {
// "cluster" byte slice is the sub-slice of the input slice containing the // "cluster" byte slice is the sub-slice of the input slice containing the
// identified grapheme cluster. // identified grapheme cluster.
// //
// The returned width is the width of the grapheme cluster for most monospace
// fonts where a value of 1 represents one character cell.
//
// Given an empty byte slice "b", the function returns nil values. // Given an empty byte slice "b", the function returns nil values.
// //
// While slightly less convenient than using the Graphemes class, this function // While slightly less convenient than using the Graphemes class, this function
// has much better performance and makes no allocations. It lends itself well to // has much better performance and makes no allocations. It lends itself well to
// large byte slices. // large byte slices.
// func FirstGraphemeCluster(b []byte, state int) (cluster, rest []byte, width, newState int) {
// The "reserved" return value is a placeholder for future functionality and may
// be ignored for the time being.
func FirstGraphemeCluster(b []byte, state int) (cluster, rest []byte, reserved, newState int) {
// An empty byte slice returns nothing. // An empty byte slice returns nothing.
if len(b) == 0 { if len(b) == 0 {
return return
@ -185,34 +199,60 @@ func FirstGraphemeCluster(b []byte, state int) (cluster, rest []byte, reserved,
// Extract the first rune. // Extract the first rune.
r, length := utf8.DecodeRune(b) r, length := utf8.DecodeRune(b)
if len(b) <= length { // If we're already past the end, there is nothing else to parse. if len(b) <= length { // If we're already past the end, there is nothing else to parse.
return b, nil, 0, grAny var prop int
if state < 0 {
prop = property(graphemeCodePoints, r)
} else {
prop = state >> shiftGraphemePropState
}
return b, nil, runeWidth(r, prop), grAny | (prop << shiftGraphemePropState)
} }
// If we don't know the state, determine it now. // If we don't know the state, determine it now.
var firstProp int
if state < 0 { if state < 0 {
state, _ = transitionGraphemeState(state, r) state, firstProp, _ = transitionGraphemeState(state, r)
} else {
firstProp = state >> shiftGraphemePropState
} }
width += runeWidth(r, firstProp)
// Transition until we find a boundary. // Transition until we find a boundary.
var boundary bool
for { for {
var (
prop int
boundary bool
)
r, l := utf8.DecodeRune(b[length:]) r, l := utf8.DecodeRune(b[length:])
state, boundary = transitionGraphemeState(state, r) state, prop, boundary = transitionGraphemeState(state&maskGraphemeState, r)
if boundary { if boundary {
return b[:length], b[length:], 0, state return b[:length], b[length:], width, state | (prop << shiftGraphemePropState)
}
if r == vs16 {
width = 2
} else if firstProp != prExtendedPictographic && firstProp != prRegionalIndicator && firstProp != prL {
width += runeWidth(r, prop)
} else if firstProp == prExtendedPictographic {
if r == vs15 {
width = 1
} else {
width = 2
}
} }
length += l length += l
if len(b) <= length { if len(b) <= length {
return b, nil, 0, grAny return b, nil, width, grAny | (prop << shiftGraphemePropState)
} }
} }
} }
// FirstGraphemeClusterInString is like [FirstGraphemeCluster] but its input and // FirstGraphemeClusterInString is like [FirstGraphemeCluster] but its input and
// outputs are strings. // outputs are strings.
func FirstGraphemeClusterInString(str string, state int) (cluster, rest string, reserved, newState int) { func FirstGraphemeClusterInString(str string, state int) (cluster, rest string, width, newState int) {
// An empty string returns nothing. // An empty string returns nothing.
if len(str) == 0 { if len(str) == 0 {
return return
@ -221,27 +261,53 @@ func FirstGraphemeClusterInString(str string, state int) (cluster, rest string,
// Extract the first rune. // Extract the first rune.
r, length := utf8.DecodeRuneInString(str) r, length := utf8.DecodeRuneInString(str)
if len(str) <= length { // If we're already past the end, there is nothing else to parse. if len(str) <= length { // If we're already past the end, there is nothing else to parse.
return str, "", 0, grAny var prop int
if state < 0 {
prop = property(graphemeCodePoints, r)
} else {
prop = state >> shiftGraphemePropState
}
return str, "", runeWidth(r, prop), grAny | (prop << shiftGraphemePropState)
} }
// If we don't know the state, determine it now. // If we don't know the state, determine it now.
var firstProp int
if state < 0 { if state < 0 {
state, _ = transitionGraphemeState(state, r) state, firstProp, _ = transitionGraphemeState(state, r)
} else {
firstProp = state >> shiftGraphemePropState
} }
width += runeWidth(r, firstProp)
// Transition until we find a boundary. // Transition until we find a boundary.
var boundary bool
for { for {
var (
prop int
boundary bool
)
r, l := utf8.DecodeRuneInString(str[length:]) r, l := utf8.DecodeRuneInString(str[length:])
state, boundary = transitionGraphemeState(state, r) state, prop, boundary = transitionGraphemeState(state&maskGraphemeState, r)
if boundary { if boundary {
return str[:length], str[length:], 0, state return str[:length], str[length:], width, state | (prop << shiftGraphemePropState)
}
if r == vs16 {
width = 2
} else if firstProp != prExtendedPictographic && firstProp != prRegionalIndicator && firstProp != prL {
width += runeWidth(r, prop)
} else if firstProp == prExtendedPictographic {
if r == vs15 {
width = 1
} else {
width = 2
}
} }
length += l length += l
if len(str) <= length { if len(str) <= length {
return str, "", 0, grAny return str, "", width, grAny | (prop << shiftGraphemePropState)
} }
} }
} }

View file

@ -7,7 +7,7 @@ package uniseg
// and // and
// https://unicode.org/Public/14.0.0/ucd/emoji/emoji-data.txt // https://unicode.org/Public/14.0.0/ucd/emoji/emoji-data.txt
// ("Extended_Pictographic" only) // ("Extended_Pictographic" only)
// on July 25, 2022. See https://www.unicode.org/license.html for the Unicode // on September 10, 2022. See https://www.unicode.org/license.html for the Unicode
// license agreement. // license agreement.
var graphemeCodePoints = [][3]int{ var graphemeCodePoints = [][3]int{
{0x0000, 0x0009, prControl}, // Cc [10] <control-0000>..<control-0009> {0x0000, 0x0009, prControl}, // Cc [10] <control-0000>..<control-0009>

View file

@ -27,14 +27,14 @@ const (
// //
// This map is queried as follows: // This map is queried as follows:
// //
// 1. Find specific state + specific property. Stop if found. // 1. Find specific state + specific property. Stop if found.
// 2. Find specific state + any property. // 2. Find specific state + any property.
// 3. Find any state + specific property. // 3. Find any state + specific property.
// 4. If only (2) or (3) (but not both) was found, stop. // 4. If only (2) or (3) (but not both) was found, stop.
// 5. If both (2) and (3) were found, use state from (3) and breaking instruction // 5. If both (2) and (3) were found, use state from (3) and breaking instruction
// from the transition with the lower rule number, prefer (3) if rule numbers // from the transition with the lower rule number, prefer (3) if rule numbers
// are equal. Stop. // are equal. Stop.
// 6. Assume grAny and grBoundary. // 6. Assume grAny and grBoundary.
// //
// Unicode version 14.0.0. // Unicode version 14.0.0.
var grTransitions = map[[2]int][3]int{ var grTransitions = map[[2]int][3]int{
@ -92,22 +92,23 @@ var grTransitions = map[[2]int][3]int{
} }
// transitionGraphemeState determines the new state of the grapheme cluster // transitionGraphemeState determines the new state of the grapheme cluster
// parser given the current state and the next code point. It also returns // parser given the current state and the next code point. It also returns the
// whether a cluster boundary was detected. // code point's grapheme property (the value mapped by the [graphemeCodePoints]
func transitionGraphemeState(state int, r rune) (newState int, boundary bool) { // table) and whether a cluster boundary was detected.
func transitionGraphemeState(state int, r rune) (newState, prop int, boundary bool) {
// Determine the property of the next character. // Determine the property of the next character.
nextProperty := property(graphemeCodePoints, r) prop = property(graphemeCodePoints, r)
// Find the applicable transition. // Find the applicable transition.
transition, ok := grTransitions[[2]int{state, nextProperty}] transition, ok := grTransitions[[2]int{state, prop}]
if ok { if ok {
// We have a specific transition. We'll use it. // We have a specific transition. We'll use it.
return transition[0], transition[1] == grBoundary return transition[0], prop, transition[1] == grBoundary
} }
// No specific transition found. Try the less specific ones. // No specific transition found. Try the less specific ones.
transAnyProp, okAnyProp := grTransitions[[2]int{state, prAny}] transAnyProp, okAnyProp := grTransitions[[2]int{state, prAny}]
transAnyState, okAnyState := grTransitions[[2]int{grAny, nextProperty}] transAnyState, okAnyState := grTransitions[[2]int{grAny, prop}]
if okAnyProp && okAnyState { if okAnyProp && okAnyState {
// Both apply. We'll use a mix (see comments for grTransitions). // Both apply. We'll use a mix (see comments for grTransitions).
newState = transAnyState[0] newState = transAnyState[0]
@ -120,7 +121,7 @@ func transitionGraphemeState(state int, r rune) (newState int, boundary bool) {
if okAnyProp { if okAnyProp {
// We only have a specific state. // We only have a specific state.
return transAnyProp[0], transAnyProp[1] == grBoundary return transAnyProp[0], prop, transAnyProp[1] == grBoundary
// This branch will probably never be reached because okAnyState will // This branch will probably never be reached because okAnyState will
// always be true given the current transition map. But we keep it here // always be true given the current transition map. But we keep it here
// for future modifications to the transition map where this may not be // for future modifications to the transition map where this may not be
@ -129,9 +130,9 @@ func transitionGraphemeState(state int, r rune) (newState int, boundary bool) {
if okAnyState { if okAnyState {
// We only have a specific property. // We only have a specific property.
return transAnyState[0], transAnyState[1] == grBoundary return transAnyState[0], prop, transAnyState[1] == grBoundary
} }
// No known transition. GB999: Any ÷ Any. // No known transition. GB999: Any ÷ Any.
return grAny, true return grAny, prop, true
} }

View file

@ -13,7 +13,7 @@ import "unicode/utf8"
// //
// The returned "segment" may not be broken into smaller parts, unless no other // The returned "segment" may not be broken into smaller parts, unless no other
// breaking opportunities present themselves, in which case you may break by // breaking opportunities present themselves, in which case you may break by
// grapheme clusters (using the FirstGraphemeCluster() function to determine the // grapheme clusters (using the [FirstGraphemeCluster] function to determine the
// grapheme clusters). // grapheme clusters).
// //
// The "mustBreak" flag indicates whether you MUST break the line after the // The "mustBreak" flag indicates whether you MUST break the line after the
@ -42,7 +42,7 @@ import "unicode/utf8"
// //
// Note also that this algorithm may break within grapheme clusters. This is // Note also that this algorithm may break within grapheme clusters. This is
// addressed in Section 8.2 Example 6 of UAX #14. To avoid this, you can use // addressed in Section 8.2 Example 6 of UAX #14. To avoid this, you can use
// the Step() function instead. // the [Step] function instead.
func FirstLineSegment(b []byte, state int) (segment, rest []byte, mustBreak bool, newState int) { func FirstLineSegment(b []byte, state int) (segment, rest []byte, mustBreak bool, newState int) {
// An empty byte slice returns nothing. // An empty byte slice returns nothing.
if len(b) == 0 { if len(b) == 0 {
@ -114,7 +114,9 @@ func FirstLineSegmentInString(str string, state int) (segment, rest string, must
} }
// HasTrailingLineBreak returns true if the last rune in the given byte slice is // HasTrailingLineBreak returns true if the last rune in the given byte slice is
// one of the hard line break code points as defined in LB4 and LB5 of UAX #14. // one of the hard line break code points defined in LB4 and LB5 of [UAX #14].
//
// [UAX #14]: https://www.unicode.org/reports/tr14/#Algorithm
func HasTrailingLineBreak(b []byte) bool { func HasTrailingLineBreak(b []byte) bool {
r, _ := utf8.DecodeLastRune(b) r, _ := utf8.DecodeLastRune(b)
property, _ := propertyWithGenCat(lineBreakCodePoints, r) property, _ := propertyWithGenCat(lineBreakCodePoints, r)

View file

@ -4,7 +4,10 @@ package uniseg
// lineBreakCodePoints are taken from // lineBreakCodePoints are taken from
// https://www.unicode.org/Public/14.0.0/ucd/LineBreak.txt // https://www.unicode.org/Public/14.0.0/ucd/LineBreak.txt
// on July 25, 2022. See https://www.unicode.org/license.html for the Unicode // and
// https://unicode.org/Public/14.0.0/ucd/emoji/emoji-data.txt
// ("Extended_Pictographic" only)
// on September 10, 2022. See https://www.unicode.org/license.html for the Unicode
// license agreement. // license agreement.
var lineBreakCodePoints = [][4]int{ var lineBreakCodePoints = [][4]int{
{0x0000, 0x0008, prCM, gcCc}, // [9] <control-0000>..<control-0008> {0x0000, 0x0008, prCM, gcCc}, // [9] <control-0000>..<control-0008>

View file

@ -3,9 +3,9 @@ package uniseg
// The Unicode properties as used in the various parsers. Only the ones needed // The Unicode properties as used in the various parsers. Only the ones needed
// in the context of this package are included. // in the context of this package are included.
const ( const (
prXX = 0 // Same as prAny. prXX = 0 // Same as prAny.
prAny = iota // prAny must be 0. prAny = iota // prAny must be 0.
prPrepend prPrepend // Grapheme properties must come first, to reduce the number of bits stored in the state vector.
prCR prCR
prLF prLF
prControl prControl
@ -86,6 +86,7 @@ const (
prW prW
prH prH
prF prF
prEmojiPresentation
) )
// Unicode General Categories. Only the ones needed in the context of this // Unicode General Categories. Only the ones needed in the context of this
@ -124,6 +125,12 @@ const (
gcCo gcCo
) )
// Special code points.
const (
vs15 = 0xfe0e // Variation Selector-15 (text presentation)
vs16 = 0xfe0f // Variation Selector-16 (emoji presentation)
)
// propertySearch performs a binary search on a property slice and returns the // propertySearch performs a binary search on a property slice and returns the
// entry whose range (start = first array element, end = second array element) // entry whose range (start = first array element, end = second array element)
// includes r, or an array of 0's if no such entry was found. // includes r, or an array of 0's if no such entry was found.

View file

@ -4,7 +4,10 @@ package uniseg
// sentenceBreakCodePoints are taken from // sentenceBreakCodePoints are taken from
// https://www.unicode.org/Public/14.0.0/ucd/auxiliary/SentenceBreakProperty.txt // https://www.unicode.org/Public/14.0.0/ucd/auxiliary/SentenceBreakProperty.txt
// on July 25, 2022. See https://www.unicode.org/license.html for the Unicode // and
// https://unicode.org/Public/14.0.0/ucd/emoji/emoji-data.txt
// ("Extended_Pictographic" only)
// on September 10, 2022. See https://www.unicode.org/license.html for the Unicode
// license agreement. // license agreement.
var sentenceBreakCodePoints = [][3]int{ var sentenceBreakCodePoints = [][3]int{
{0x0009, 0x0009, prSp}, // Cc <control-0009> {0x0009, 0x0009, prSp}, // Cc <control-0009>

112
vendor/github.com/rivo/uniseg/step.go generated vendored
View file

@ -2,31 +2,37 @@ package uniseg
import "unicode/utf8" import "unicode/utf8"
// The bit masks used to extract boundary information returned by the Step() // The bit masks used to extract boundary information returned by [Step].
// function.
const ( const (
MaskLine = 3 MaskLine = 3
MaskWord = 4 MaskWord = 4
MaskSentence = 8 MaskSentence = 8
) )
// The bit positions by which boundary flags are shifted by the Step() function. // The number of bits to shift the boundary information returned by [Step] to
// This must correspond to the Mask constants. // obtain the monospace width of the grapheme cluster.
const ShiftWidth = 4
// The bit positions by which boundary flags are shifted by the [Step] function.
// These must correspond to the Mask constants.
const ( const (
shiftWord = 2 shiftWord = 2
shiftSentence = 3 shiftSentence = 3
// shiftwWidth is ShiftWidth above. No mask as these are always the remaining bits.
) )
// The bit positions by which states are shifted by the Step() function. These // The bit positions by which states are shifted by the [Step] function. These
// values must ensure state values defined for each of the boundary algorithms // values must ensure state values defined for each of the boundary algorithms
// don't overlap (and that they all still fit in a single int). // don't overlap (and that they all still fit in a single int). These must
// correspond to the Mask constants.
const ( const (
shiftWordState = 4 shiftWordState = 4
shiftSentenceState = 9 shiftSentenceState = 9
shiftLineState = 13 shiftLineState = 13
shiftPropState = 21 // No mask as these are always the remaining bits.
) )
// The bit mask used to extract the state returned by the Step() function, after // The bit mask used to extract the state returned by the [Step] function, after
// shifting. These values must correspond to the shift constants. // shifting. These values must correspond to the shift constants.
const ( const (
maskGraphemeState = 0xf maskGraphemeState = 0xf
@ -37,10 +43,11 @@ const (
// Step returns the first grapheme cluster (user-perceived character) found in // Step returns the first grapheme cluster (user-perceived character) found in
// the given byte slice. It also returns information about the boundary between // the given byte slice. It also returns information about the boundary between
// that grapheme cluster and the one following it. There are three types of // that grapheme cluster and the one following it as well as the monospace width
// boundary information: word boundaries, sentence boundaries, and line breaks. // of the grapheme cluster. There are three types of boundary information: word
// This function is therefore a combination of FirstGraphemeCluster(), // boundaries, sentence boundaries, and line breaks. This function is therefore
// FirstWord(), FirstSentence(), and FirstLineSegment(). // a combination of [FirstGraphemeCluster], [FirstWord], [FirstSentence], and
// [FirstLineSegment].
// //
// The "boundaries" return value can be evaluated as follows: // The "boundaries" return value can be evaluated as follows:
// //
@ -54,6 +61,8 @@ const (
// boundary. // boundary.
// - boundaries&MaskLine == LineCanBreak: You may or may not break the line at // - boundaries&MaskLine == LineCanBreak: You may or may not break the line at
// the boundary. // the boundary.
// - boundaries >> ShiftWidth: The width of the grapheme cluster for most
// monospace fonts where a value of 1 represents one character cell.
// //
// This function can be called continuously to extract all grapheme clusters // This function can be called continuously to extract all grapheme clusters
// from a byte slice, as illustrated in the examples below. // from a byte slice, as illustrated in the examples below.
@ -87,14 +96,20 @@ func Step(b []byte, state int) (cluster, rest []byte, boundaries int, newState i
// Extract the first rune. // Extract the first rune.
r, length := utf8.DecodeRune(b) r, length := utf8.DecodeRune(b)
if len(b) <= length { // If we're already past the end, there is nothing else to parse. if len(b) <= length { // If we're already past the end, there is nothing else to parse.
return b, nil, LineMustBreak | (1 << shiftWord) | (1 << shiftSentence), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) var prop int
if state < 0 {
prop = property(graphemeCodePoints, r)
} else {
prop = state >> shiftPropState
}
return b, nil, LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (runeWidth(r, prop) << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) | (prop << shiftPropState)
} }
// If we don't know the state, determine it now. // If we don't know the state, determine it now.
var graphemeState, wordState, sentenceState, lineState int var graphemeState, wordState, sentenceState, lineState, firstProp int
remainder := b[length:] remainder := b[length:]
if state < 0 { if state < 0 {
graphemeState, _ = transitionGraphemeState(state, r) graphemeState, firstProp, _ = transitionGraphemeState(state, r)
wordState, _ = transitionWordBreakState(state, r, remainder, "") wordState, _ = transitionWordBreakState(state, r, remainder, "")
sentenceState, _ = transitionSentenceBreakState(state, r, remainder, "") sentenceState, _ = transitionSentenceBreakState(state, r, remainder, "")
lineState, _ = transitionLineBreakState(state, r, remainder, "") lineState, _ = transitionLineBreakState(state, r, remainder, "")
@ -103,36 +118,51 @@ func Step(b []byte, state int) (cluster, rest []byte, boundaries int, newState i
wordState = (state >> shiftWordState) & maskWordState wordState = (state >> shiftWordState) & maskWordState
sentenceState = (state >> shiftSentenceState) & maskSentenceState sentenceState = (state >> shiftSentenceState) & maskSentenceState
lineState = (state >> shiftLineState) & maskLineState lineState = (state >> shiftLineState) & maskLineState
firstProp = state >> shiftPropState
} }
// Transition until we find a grapheme cluster boundary. // Transition until we find a grapheme cluster boundary.
var ( width := runeWidth(r, firstProp)
graphemeBoundary, wordBoundary, sentenceBoundary bool
lineBreak int
)
for { for {
var (
graphemeBoundary, wordBoundary, sentenceBoundary bool
lineBreak, prop int
)
r, l := utf8.DecodeRune(remainder) r, l := utf8.DecodeRune(remainder)
remainder = b[length+l:] remainder = b[length+l:]
graphemeState, graphemeBoundary = transitionGraphemeState(graphemeState, r) graphemeState, prop, graphemeBoundary = transitionGraphemeState(graphemeState, r)
wordState, wordBoundary = transitionWordBreakState(wordState, r, remainder, "") wordState, wordBoundary = transitionWordBreakState(wordState, r, remainder, "")
sentenceState, sentenceBoundary = transitionSentenceBreakState(sentenceState, r, remainder, "") sentenceState, sentenceBoundary = transitionSentenceBreakState(sentenceState, r, remainder, "")
lineState, lineBreak = transitionLineBreakState(lineState, r, remainder, "") lineState, lineBreak = transitionLineBreakState(lineState, r, remainder, "")
if graphemeBoundary { if graphemeBoundary {
boundary := lineBreak boundary := lineBreak | (width << ShiftWidth)
if wordBoundary { if wordBoundary {
boundary |= 1 << shiftWord boundary |= 1 << shiftWord
} }
if sentenceBoundary { if sentenceBoundary {
boundary |= 1 << shiftSentence boundary |= 1 << shiftSentence
} }
return b[:length], b[length:], boundary, graphemeState | (wordState << shiftWordState) | (sentenceState << shiftSentenceState) | (lineState << shiftLineState) return b[:length], b[length:], boundary, graphemeState | (wordState << shiftWordState) | (sentenceState << shiftSentenceState) | (lineState << shiftLineState) | (prop << shiftPropState)
}
if r == vs16 {
width = 2
} else if firstProp != prExtendedPictographic && firstProp != prRegionalIndicator && firstProp != prL {
width += runeWidth(r, prop)
} else if firstProp == prExtendedPictographic {
if r == vs15 {
width = 1
} else {
width = 2
}
} }
length += l length += l
if len(b) <= length { if len(b) <= length {
return b, nil, LineMustBreak | (1 << shiftWord) | (1 << shiftSentence), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) return b, nil, LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (width << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) | (prop << shiftPropState)
} }
} }
} }
@ -147,14 +177,15 @@ func StepString(str string, state int) (cluster, rest string, boundaries int, ne
// Extract the first rune. // Extract the first rune.
r, length := utf8.DecodeRuneInString(str) r, length := utf8.DecodeRuneInString(str)
if len(str) <= length { // If we're already past the end, there is nothing else to parse. if len(str) <= length { // If we're already past the end, there is nothing else to parse.
return str, "", LineMustBreak | (1 << shiftWord) | (1 << shiftSentence), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) prop := property(graphemeCodePoints, r)
return str, "", LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (runeWidth(r, prop) << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState)
} }
// If we don't know the state, determine it now. // If we don't know the state, determine it now.
var graphemeState, wordState, sentenceState, lineState int var graphemeState, wordState, sentenceState, lineState, firstProp int
remainder := str[length:] remainder := str[length:]
if state < 0 { if state < 0 {
graphemeState, _ = transitionGraphemeState(state, r) graphemeState, firstProp, _ = transitionGraphemeState(state, r)
wordState, _ = transitionWordBreakState(state, r, nil, remainder) wordState, _ = transitionWordBreakState(state, r, nil, remainder)
sentenceState, _ = transitionSentenceBreakState(state, r, nil, remainder) sentenceState, _ = transitionSentenceBreakState(state, r, nil, remainder)
lineState, _ = transitionLineBreakState(state, r, nil, remainder) lineState, _ = transitionLineBreakState(state, r, nil, remainder)
@ -163,36 +194,51 @@ func StepString(str string, state int) (cluster, rest string, boundaries int, ne
wordState = (state >> shiftWordState) & maskWordState wordState = (state >> shiftWordState) & maskWordState
sentenceState = (state >> shiftSentenceState) & maskSentenceState sentenceState = (state >> shiftSentenceState) & maskSentenceState
lineState = (state >> shiftLineState) & maskLineState lineState = (state >> shiftLineState) & maskLineState
firstProp = state >> shiftPropState
} }
// Transition until we find a grapheme cluster boundary. // Transition until we find a grapheme cluster boundary.
var ( width := runeWidth(r, firstProp)
graphemeBoundary, wordBoundary, sentenceBoundary bool
lineBreak int
)
for { for {
var (
graphemeBoundary, wordBoundary, sentenceBoundary bool
lineBreak, prop int
)
r, l := utf8.DecodeRuneInString(remainder) r, l := utf8.DecodeRuneInString(remainder)
remainder = str[length+l:] remainder = str[length+l:]
graphemeState, graphemeBoundary = transitionGraphemeState(graphemeState, r) graphemeState, prop, graphemeBoundary = transitionGraphemeState(graphemeState, r)
wordState, wordBoundary = transitionWordBreakState(wordState, r, nil, remainder) wordState, wordBoundary = transitionWordBreakState(wordState, r, nil, remainder)
sentenceState, sentenceBoundary = transitionSentenceBreakState(sentenceState, r, nil, remainder) sentenceState, sentenceBoundary = transitionSentenceBreakState(sentenceState, r, nil, remainder)
lineState, lineBreak = transitionLineBreakState(lineState, r, nil, remainder) lineState, lineBreak = transitionLineBreakState(lineState, r, nil, remainder)
if graphemeBoundary { if graphemeBoundary {
boundary := lineBreak boundary := lineBreak | (width << ShiftWidth)
if wordBoundary { if wordBoundary {
boundary |= 1 << shiftWord boundary |= 1 << shiftWord
} }
if sentenceBoundary { if sentenceBoundary {
boundary |= 1 << shiftSentence boundary |= 1 << shiftSentence
} }
return str[:length], str[length:], boundary, graphemeState | (wordState << shiftWordState) | (sentenceState << shiftSentenceState) | (lineState << shiftLineState) return str[:length], str[length:], boundary, graphemeState | (wordState << shiftWordState) | (sentenceState << shiftSentenceState) | (lineState << shiftLineState) | (prop << shiftPropState)
}
if r == vs16 {
width = 2
} else if firstProp != prExtendedPictographic && firstProp != prRegionalIndicator && firstProp != prL {
width += runeWidth(r, prop)
} else if firstProp == prExtendedPictographic {
if r == vs15 {
width = 1
} else {
width = 2
}
} }
length += l length += l
if len(str) <= length { if len(str) <= length {
return str, "", LineMustBreak | (1 << shiftWord) | (1 << shiftSentence), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) return str, "", LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (width << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) | (prop << shiftPropState)
} }
} }
} }

54
vendor/github.com/rivo/uniseg/width.go generated vendored Normal file
View file

@ -0,0 +1,54 @@
package uniseg
// runeWidth returns the monospace width for the given rune. The provided
// grapheme property is a value mapped by the [graphemeCodePoints] table.
//
// Every rune has a width of 1, except for runes with the following properties
// (evaluated in this order):
//
// - Control, CR, LF, Extend, ZWJ: Width of 0
// - \u2e3a, TWO-EM DASH: Width of 3
// - \u2e3b, THREE-EM DASH: Width of 4
// - East-Asian width Fullwidth and Wide: Width of 2 (Ambiguous and Neutral
// have a width of 1)
// - Regional Indicator: Width of 2
// - Extended Pictographic: Width of 2, unless Emoji Presentation is "No".
func runeWidth(r rune, graphemeProperty int) int {
switch graphemeProperty {
case prControl, prCR, prLF, prExtend, prZWJ:
return 0
case prRegionalIndicator:
return 2
case prExtendedPictographic:
if property(emojiPresentation, r) == prEmojiPresentation {
return 2
}
return 1
}
switch r {
case 0x2e3a:
return 3
case 0x2e3b:
return 4
}
switch property(eastAsianWidth, r) {
case prW, prF:
return 2
}
return 1
}
// StringWidth returns the monospace width for the given string, that is, the
// number of same-size cells to be occupied by the string.
func StringWidth(s string) (width int) {
state := -1
for len(s) > 0 {
var w int
_, s, w, state = FirstGraphemeClusterInString(s, state)
width += w
}
return
}

View file

@ -7,7 +7,7 @@ package uniseg
// and // and
// https://unicode.org/Public/14.0.0/ucd/emoji/emoji-data.txt // https://unicode.org/Public/14.0.0/ucd/emoji/emoji-data.txt
// ("Extended_Pictographic" only) // ("Extended_Pictographic" only)
// on July 25, 2022. See https://www.unicode.org/license.html for the Unicode // on September 10, 2022. See https://www.unicode.org/license.html for the Unicode
// license agreement. // license agreement.
var workBreakCodePoints = [][3]int{ var workBreakCodePoints = [][3]int{
{0x000A, 0x000A, prLF}, // Cc <control-000A> {0x000A, 0x000A, prLF}, // Cc <control-000A>
@ -624,8 +624,8 @@ var workBreakCodePoints = [][3]int{
{0x212A, 0x212D, prALetter}, // L& [4] KELVIN SIGN..BLACK-LETTER CAPITAL C {0x212A, 0x212D, prALetter}, // L& [4] KELVIN SIGN..BLACK-LETTER CAPITAL C
{0x212F, 0x2134, prALetter}, // L& [6] SCRIPT SMALL E..SCRIPT SMALL O {0x212F, 0x2134, prALetter}, // L& [6] SCRIPT SMALL E..SCRIPT SMALL O
{0x2135, 0x2138, prALetter}, // Lo [4] ALEF SYMBOL..DALET SYMBOL {0x2135, 0x2138, prALetter}, // Lo [4] ALEF SYMBOL..DALET SYMBOL
{0x2139, 0x2139, prALetter}, // L& INFORMATION SOURCE
{0x2139, 0x2139, prExtendedPictographic}, // E0.6 [1] () information {0x2139, 0x2139, prExtendedPictographic}, // E0.6 [1] () information
{0x2139, 0x2139, prALetter}, // L& INFORMATION SOURCE
{0x213C, 0x213F, prALetter}, // L& [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI {0x213C, 0x213F, prALetter}, // L& [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI
{0x2145, 0x2149, prALetter}, // L& [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J {0x2145, 0x2149, prALetter}, // L& [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J
{0x214E, 0x214E, prALetter}, // L& TURNED SMALL F {0x214E, 0x214E, prALetter}, // L& TURNED SMALL F

View file

@ -4,8 +4,10 @@
# are very important so that maintainers and contributors can focus their # are very important so that maintainers and contributors can focus their
# attention on files that are primarily Go. # attention on files that are primarily Go.
GO_RUN_BUILD := go run internal/build/build.go
.PHONY: all .PHONY: all
all: generate vet tag-test test check-binary-size tag-check-binary-size gfmrun v2diff all: generate vet tag-test test check-binary-size tag-check-binary-size gfmrun yamlfmt v2diff
# NOTE: this is a special catch-all rule to run any of the commands # NOTE: this is a special catch-all rule to run any of the commands
# defined in internal/build/build.go with optional arguments passed # defined in internal/build/build.go with optional arguments passed
@ -13,28 +15,12 @@ all: generate vet tag-test test check-binary-size tag-check-binary-size gfmrun v
# #
# $ make test GFLAGS='--packages cli' # $ make test GFLAGS='--packages cli'
%: %:
go run internal/build/build.go $(GFLAGS) $* $(FLAGS) $(GO_RUN_BUILD) $(GFLAGS) $* $(FLAGS)
.PHONY: tag-test
tag-test:
go run internal/build/build.go -tags urfave_cli_no_docs test
.PHONY: tag-check-binary-size
tag-check-binary-size:
go run internal/build/build.go -tags urfave_cli_no_docs check-binary-size
.PHONY: gfmrun
gfmrun:
go run internal/build/build.go gfmrun docs/v2/manual.md
.PHONY: docs .PHONY: docs
docs: docs:
mkdocs build mkdocs build
.PHONY: docs-deps
docs-deps:
pip install -r mkdocs-requirements.txt
.PHONY: serve-docs .PHONY: serve-docs
serve-docs: serve-docs:
mkdocs serve mkdocs serve

View file

@ -133,7 +133,6 @@ func compileTime() time.Time {
func NewApp() *App { func NewApp() *App {
return &App{ return &App{
Name: filepath.Base(os.Args[0]), Name: filepath.Base(os.Args[0]),
HelpName: filepath.Base(os.Args[0]),
Usage: "A new cli application", Usage: "A new cli application",
UsageText: "", UsageText: "",
BashComplete: DefaultAppComplete, BashComplete: DefaultAppComplete,

View file

@ -105,6 +105,16 @@ func (cCtx *Context) Lineage() []*Context {
return lineage return lineage
} }
// Count returns the num of occurences of this flag
func (cCtx *Context) Count(name string) int {
if fs := cCtx.lookupFlagSet(name); fs != nil {
if cf, ok := fs.Lookup(name).Value.(Countable); ok {
return cf.Count()
}
}
return 0
}
// Value returns the value of the flag corresponding to `name` // Value returns the value of the flag corresponding to `name`
func (cCtx *Context) Value(name string) interface{} { func (cCtx *Context) Value(name string) interface{} {
if fs := cCtx.lookupFlagSet(name); fs != nil { if fs := cCtx.lookupFlagSet(name); fs != nil {

View file

@ -1,59 +1,74 @@
# NOTE: this file is used by the tool defined in # NOTE: this file is used by the tool defined in
# ./cmd/urfave-cli-genflags/main.go which uses the # ./cmd/urfave-cli-genflags/main.go which uses the
# `Spec` type that maps to this file structure. # `Spec` type that maps to this file structure.
flag_types: flag_types:
bool: {} bool:
float64: {}
int64:
struct_fields: struct_fields:
- { name: Base, type: int } - name: Count
int: type: int
struct_fields: pointer: true
- { name: Base, type: int } float64:
time.Duration: {}
uint64:
struct_fields:
- { name: Base, type: int }
uint:
struct_fields:
- { name: Base, type: int }
string:
struct_fields:
- { name: TakesFile, type: bool }
Generic:
struct_fields:
- { name: TakesFile, type: bool }
Path:
struct_fields:
- { name: TakesFile, type: bool }
Float64Slice: Float64Slice:
value_pointer: true value_pointer: true
skip_interfaces: skip_interfaces:
- fmt.Stringer - fmt.Stringer
Int64Slice: int:
value_pointer: true struct_fields:
skip_interfaces: - name: Base
- fmt.Stringer type: int
IntSlice: IntSlice:
value_pointer: true value_pointer: true
skip_interfaces: skip_interfaces:
- fmt.Stringer - fmt.Stringer
int64:
struct_fields:
- name: Base
type: int
Int64Slice:
value_pointer: true
skip_interfaces:
- fmt.Stringer
uint:
struct_fields:
- name: Base
type: int
UintSlice:
value_pointer: true
skip_interfaces:
- fmt.Stringer
uint64:
struct_fields:
- name: Base
type: int
Uint64Slice:
value_pointer: true
skip_interfaces:
- fmt.Stringer
string:
struct_fields:
- name: TakesFile
type: bool
StringSlice: StringSlice:
value_pointer: true value_pointer: true
skip_interfaces: skip_interfaces:
- fmt.Stringer - fmt.Stringer
struct_fields: struct_fields:
- { name: TakesFile, type: bool } - name: TakesFile
type: bool
time.Duration:
Timestamp: Timestamp:
value_pointer: true value_pointer: true
struct_fields: struct_fields:
- { name: Layout, type: string } - name: Layout
- { name: Timezone, type: "*time.Location" } type: string
- name: Timezone
# TODO: enable UintSlice type: "*time.Location"
# UintSlice: {} Generic:
# TODO: enable Uint64Slice once #1334 lands no_destination_pointer: true
# Uint64Slice: {} struct_fields:
- name: TakesFile
type: bool
Path:
struct_fields:
- name: TakesFile
type: bool

View file

@ -139,6 +139,12 @@ type CategorizableFlag interface {
GetCategory() string GetCategory() string
} }
// Countable is an interface to enable detection of flag values which support
// repetitive flags
type Countable interface {
Count() int
}
func flagSet(name string, flags []Flag) (*flag.FlagSet, error) { func flagSet(name string, flags []Flag) (*flag.FlagSet, error) {
set := flag.NewFlagSet(name, flag.ContinueOnError) set := flag.NewFlagSet(name, flag.ContinueOnError)

View file

@ -1,11 +1,63 @@
package cli package cli
import ( import (
"errors"
"flag" "flag"
"fmt" "fmt"
"strconv" "strconv"
) )
// boolValue needs to implement the boolFlag internal interface in flag
// to be able to capture bool fields and values
//
// type boolFlag interface {
// Value
// IsBoolFlag() bool
// }
type boolValue struct {
destination *bool
count *int
}
func newBoolValue(val bool, p *bool, count *int) *boolValue {
*p = val
return &boolValue{
destination: p,
count: count,
}
}
func (b *boolValue) Set(s string) error {
v, err := strconv.ParseBool(s)
if err != nil {
err = errors.New("parse error")
return err
}
*b.destination = v
if b.count != nil {
*b.count = *b.count + 1
}
return err
}
func (b *boolValue) Get() interface{} { return *b.destination }
func (b *boolValue) String() string {
if b.destination != nil {
return strconv.FormatBool(*b.destination)
}
return strconv.FormatBool(false)
}
func (b *boolValue) IsBoolFlag() bool { return true }
func (b *boolValue) Count() int {
if b.count != nil {
return *b.count
}
return 0
}
// TakesValue returns true of the flag takes a value, otherwise false // TakesValue returns true of the flag takes a value, otherwise false
func (f *BoolFlag) TakesValue() bool { func (f *BoolFlag) TakesValue() bool {
return false return false
@ -60,12 +112,19 @@ func (f *BoolFlag) Apply(set *flag.FlagSet) error {
f.HasBeenSet = true f.HasBeenSet = true
} }
count := f.Count
dest := f.Destination
if count == nil {
count = new(int)
}
if dest == nil {
dest = new(bool)
}
for _, name := range f.Names() { for _, name := range f.Names() {
if f.Destination != nil { value := newBoolValue(f.Value, dest, count)
set.BoolVar(f.Destination, name, f.Value, f.Usage) set.Var(value, name, f.Usage)
continue
}
set.Bool(name, f.Value, f.Usage)
} }
return nil return nil

203
vendor/github.com/urfave/cli/v2/flag_uint64_slice.go generated vendored Normal file
View file

@ -0,0 +1,203 @@
package cli
import (
"encoding/json"
"flag"
"fmt"
"strconv"
"strings"
)
// Uint64Slice wraps []int64 to satisfy flag.Value
type Uint64Slice struct {
slice []uint64
hasBeenSet bool
}
// NewUint64Slice makes an *Uint64Slice with default values
func NewUint64Slice(defaults ...uint64) *Uint64Slice {
return &Uint64Slice{slice: append([]uint64{}, defaults...)}
}
// clone allocate a copy of self object
func (i *Uint64Slice) clone() *Uint64Slice {
n := &Uint64Slice{
slice: make([]uint64, len(i.slice)),
hasBeenSet: i.hasBeenSet,
}
copy(n.slice, i.slice)
return n
}
// Set parses the value into an integer and appends it to the list of values
func (i *Uint64Slice) Set(value string) error {
if !i.hasBeenSet {
i.slice = []uint64{}
i.hasBeenSet = true
}
if strings.HasPrefix(value, slPfx) {
// Deserializing assumes overwrite
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &i.slice)
i.hasBeenSet = true
return nil
}
for _, s := range flagSplitMultiValues(value) {
tmp, err := strconv.ParseUint(strings.TrimSpace(s), 0, 64)
if err != nil {
return err
}
i.slice = append(i.slice, tmp)
}
return nil
}
// String returns a readable representation of this value (for usage defaults)
func (i *Uint64Slice) String() string {
v := i.slice
if v == nil {
// treat nil the same as zero length non-nil
v = make([]uint64, 0)
}
str := fmt.Sprintf("%d", v)
str = strings.Replace(str, " ", ", ", -1)
str = strings.Replace(str, "[", "{", -1)
str = strings.Replace(str, "]", "}", -1)
return fmt.Sprintf("[]uint64%s", str)
}
// Serialize allows Uint64Slice to fulfill Serializer
func (i *Uint64Slice) Serialize() string {
jsonBytes, _ := json.Marshal(i.slice)
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
}
// Value returns the slice of ints set by this flag
func (i *Uint64Slice) Value() []uint64 {
return i.slice
}
// Get returns the slice of ints set by this flag
func (i *Uint64Slice) Get() interface{} {
return *i
}
// String returns a readable representation of this value
// (for usage defaults)
func (f *Uint64SliceFlag) String() string {
return withEnvHint(f.GetEnvVars(), f.stringify())
}
// TakesValue returns true of the flag takes a value, otherwise false
func (f *Uint64SliceFlag) TakesValue() bool {
return true
}
// GetUsage returns the usage string for the flag
func (f *Uint64SliceFlag) GetUsage() string {
return f.Usage
}
// GetCategory returns the category for the flag
func (f *Uint64SliceFlag) GetCategory() string {
return f.Category
}
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
func (f *Uint64SliceFlag) GetValue() string {
if f.Value != nil {
return f.Value.String()
}
return ""
}
// GetDefaultText returns the default text for this flag
func (f *Uint64SliceFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// GetEnvVars returns the env vars for this flag
func (f *Uint64SliceFlag) GetEnvVars() []string {
return f.EnvVars
}
// Apply populates the flag given the flag set and environment
func (f *Uint64SliceFlag) Apply(set *flag.FlagSet) error {
// apply any default
if f.Destination != nil && f.Value != nil {
f.Destination.slice = make([]uint64, len(f.Value.slice))
copy(f.Destination.slice, f.Value.slice)
}
// resolve setValue (what we will assign to the set)
var setValue *Uint64Slice
switch {
case f.Destination != nil:
setValue = f.Destination
case f.Value != nil:
setValue = f.Value.clone()
default:
setValue = new(Uint64Slice)
}
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
for _, s := range flagSplitMultiValues(val) {
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
return fmt.Errorf("could not parse %q as uint64 slice value from %s for flag %s: %s", val, source, f.Name, err)
}
}
// Set this to false so that we reset the slice if we then set values from
// flags that have already been set by the environment.
setValue.hasBeenSet = false
f.HasBeenSet = true
}
for _, name := range f.Names() {
set.Var(setValue, name, f.Usage)
}
return nil
}
// Get returns the flags value in the given Context.
func (f *Uint64SliceFlag) Get(ctx *Context) []uint64 {
return ctx.Uint64Slice(f.Name)
}
func (f *Uint64SliceFlag) stringify() string {
var defaultVals []string
if f.Value != nil && len(f.Value.Value()) > 0 {
for _, i := range f.Value.Value() {
defaultVals = append(defaultVals, strconv.FormatUint(i, 10))
}
}
return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
}
// Uint64Slice looks up the value of a local Uint64SliceFlag, returns
// nil if not found
func (cCtx *Context) Uint64Slice(name string) []uint64 {
if fs := cCtx.lookupFlagSet(name); fs != nil {
return lookupUint64Slice(name, fs)
}
return nil
}
func lookupUint64Slice(name string, set *flag.FlagSet) []uint64 {
f := set.Lookup(name)
if f != nil {
if slice, ok := unwrapFlagValue(f.Value).(*Uint64Slice); ok {
return slice.Value()
}
}
return nil
}

214
vendor/github.com/urfave/cli/v2/flag_uint_slice.go generated vendored Normal file
View file

@ -0,0 +1,214 @@
package cli
import (
"encoding/json"
"flag"
"fmt"
"strconv"
"strings"
)
// UintSlice wraps []int to satisfy flag.Value
type UintSlice struct {
slice []uint
hasBeenSet bool
}
// NewUintSlice makes an *UintSlice with default values
func NewUintSlice(defaults ...uint) *UintSlice {
return &UintSlice{slice: append([]uint{}, defaults...)}
}
// clone allocate a copy of self object
func (i *UintSlice) clone() *UintSlice {
n := &UintSlice{
slice: make([]uint, len(i.slice)),
hasBeenSet: i.hasBeenSet,
}
copy(n.slice, i.slice)
return n
}
// TODO: Consistently have specific Set function for Int64 and Float64 ?
// SetInt directly adds an integer to the list of values
func (i *UintSlice) SetUint(value uint) {
if !i.hasBeenSet {
i.slice = []uint{}
i.hasBeenSet = true
}
i.slice = append(i.slice, value)
}
// Set parses the value into an integer and appends it to the list of values
func (i *UintSlice) Set(value string) error {
if !i.hasBeenSet {
i.slice = []uint{}
i.hasBeenSet = true
}
if strings.HasPrefix(value, slPfx) {
// Deserializing assumes overwrite
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &i.slice)
i.hasBeenSet = true
return nil
}
for _, s := range flagSplitMultiValues(value) {
tmp, err := strconv.ParseUint(strings.TrimSpace(s), 0, 32)
if err != nil {
return err
}
i.slice = append(i.slice, uint(tmp))
}
return nil
}
// String returns a readable representation of this value (for usage defaults)
func (i *UintSlice) String() string {
v := i.slice
if v == nil {
// treat nil the same as zero length non-nil
v = make([]uint, 0)
}
str := fmt.Sprintf("%d", v)
str = strings.Replace(str, " ", ", ", -1)
str = strings.Replace(str, "[", "{", -1)
str = strings.Replace(str, "]", "}", -1)
return fmt.Sprintf("[]uint%s", str)
}
// Serialize allows UintSlice to fulfill Serializer
func (i *UintSlice) Serialize() string {
jsonBytes, _ := json.Marshal(i.slice)
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
}
// Value returns the slice of ints set by this flag
func (i *UintSlice) Value() []uint {
return i.slice
}
// Get returns the slice of ints set by this flag
func (i *UintSlice) Get() interface{} {
return *i
}
// String returns a readable representation of this value
// (for usage defaults)
func (f *UintSliceFlag) String() string {
return withEnvHint(f.GetEnvVars(), f.stringify())
}
// TakesValue returns true of the flag takes a value, otherwise false
func (f *UintSliceFlag) TakesValue() bool {
return true
}
// GetUsage returns the usage string for the flag
func (f *UintSliceFlag) GetUsage() string {
return f.Usage
}
// GetCategory returns the category for the flag
func (f *UintSliceFlag) GetCategory() string {
return f.Category
}
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
func (f *UintSliceFlag) GetValue() string {
if f.Value != nil {
return f.Value.String()
}
return ""
}
// GetDefaultText returns the default text for this flag
func (f *UintSliceFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// GetEnvVars returns the env vars for this flag
func (f *UintSliceFlag) GetEnvVars() []string {
return f.EnvVars
}
// Apply populates the flag given the flag set and environment
func (f *UintSliceFlag) Apply(set *flag.FlagSet) error {
// apply any default
if f.Destination != nil && f.Value != nil {
f.Destination.slice = make([]uint, len(f.Value.slice))
copy(f.Destination.slice, f.Value.slice)
}
// resolve setValue (what we will assign to the set)
var setValue *UintSlice
switch {
case f.Destination != nil:
setValue = f.Destination
case f.Value != nil:
setValue = f.Value.clone()
default:
setValue = new(UintSlice)
}
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
for _, s := range flagSplitMultiValues(val) {
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
return fmt.Errorf("could not parse %q as uint slice value from %s for flag %s: %s", val, source, f.Name, err)
}
}
// Set this to false so that we reset the slice if we then set values from
// flags that have already been set by the environment.
setValue.hasBeenSet = false
f.HasBeenSet = true
}
for _, name := range f.Names() {
set.Var(setValue, name, f.Usage)
}
return nil
}
// Get returns the flags value in the given Context.
func (f *UintSliceFlag) Get(ctx *Context) []uint {
return ctx.UintSlice(f.Name)
}
func (f *UintSliceFlag) stringify() string {
var defaultVals []string
if f.Value != nil && len(f.Value.Value()) > 0 {
for _, i := range f.Value.Value() {
defaultVals = append(defaultVals, strconv.FormatUint(uint64(i), 10))
}
}
return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
}
// UintSlice looks up the value of a local UintSliceFlag, returns
// nil if not found
func (cCtx *Context) UintSlice(name string) []uint {
if fs := cCtx.lookupFlagSet(name); fs != nil {
return lookupUintSlice(name, fs)
}
return nil
}
func lookupUintSlice(name string, set *flag.FlagSet) []uint {
f := set.Lookup(name)
if f != nil {
if slice, ok := unwrapFlagValue(f.Value).(*UintSlice); ok {
return slice.Value()
}
}
return nil
}

View file

@ -49,8 +49,8 @@ AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
COMMANDS:{{range .VisibleCategories}}{{if .Name}} COMMANDS:{{range .VisibleCategories}}{{if .Name}}
{{.Name}}:{{range .VisibleCommands}} {{.Name}}:{{range .VisibleCommands}}
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{range .VisibleCommands}} {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}}
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{end}}{{if .VisibleFlagCategories}} {{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{end}}{{if .VisibleFlagCategories}}
GLOBAL OPTIONS:{{range .VisibleFlagCategories}} GLOBAL OPTIONS:{{range .VisibleFlagCategories}}
{{if .Name}}{{.Name}} {{if .Name}}{{.Name}}
@ -157,8 +157,8 @@ DESCRIPTION:
COMMANDS:{{range .VisibleCategories}}{{if .Name}} COMMANDS:{{range .VisibleCategories}}{{if .Name}}
{{.Name}}:{{range .VisibleCommands}} {{.Name}}:{{range .VisibleCommands}}
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{range .VisibleCommands}} {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}}
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{if .VisibleFlags}} {{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
OPTIONS: OPTIONS:
{{range .VisibleFlags}}{{.}} {{range .VisibleFlags}}{{.}}
@ -300,6 +300,8 @@ type App struct {
CommandNotFound CommandNotFoundFunc CommandNotFound CommandNotFoundFunc
// Execute this function if a usage error occurs // Execute this function if a usage error occurs
OnUsageError OnUsageErrorFunc OnUsageError OnUsageErrorFunc
// Execute this function when an invalid flag is accessed from the context
InvalidFlagAccessHandler InvalidFlagAccessFunc
// Compilation date // Compilation date
Compiled time.Time Compiled time.Time
// List of all authors who contributed // List of all authors who contributed
@ -450,6 +452,8 @@ type BoolFlag struct {
Aliases []string Aliases []string
EnvVars []string EnvVars []string
Count *int
} }
BoolFlag is a flag with type bool BoolFlag is a flag with type bool
@ -629,6 +633,9 @@ func (cCtx *Context) Args() Args
func (cCtx *Context) Bool(name string) bool func (cCtx *Context) Bool(name string) bool
Bool looks up the value of a local BoolFlag, returns false if not found Bool looks up the value of a local BoolFlag, returns false if not found
func (cCtx *Context) Count(name string) int
Count returns the num of occurences of this flag
func (cCtx *Context) Duration(name string) time.Duration func (cCtx *Context) Duration(name string) time.Duration
Duration looks up the value of a local DurationFlag, returns 0 if not found Duration looks up the value of a local DurationFlag, returns 0 if not found
@ -698,9 +705,23 @@ func (cCtx *Context) Uint(name string) uint
func (cCtx *Context) Uint64(name string) uint64 func (cCtx *Context) Uint64(name string) uint64
Uint64 looks up the value of a local Uint64Flag, returns 0 if not found Uint64 looks up the value of a local Uint64Flag, returns 0 if not found
func (cCtx *Context) Uint64Slice(name string) []uint64
Uint64Slice looks up the value of a local Uint64SliceFlag, returns nil if
not found
func (cCtx *Context) UintSlice(name string) []uint
UintSlice looks up the value of a local UintSliceFlag, returns nil if not
found
func (cCtx *Context) Value(name string) interface{} func (cCtx *Context) Value(name string) interface{}
Value returns the value of the flag corresponding to `name` Value returns the value of the flag corresponding to `name`
type Countable interface {
Count() int
}
Countable is an interface to enable detection of flag values which support
repetitive flags
type DocGenerationFlag interface { type DocGenerationFlag interface {
Flag Flag
@ -1064,7 +1085,7 @@ type GenericFlag struct {
HasBeenSet bool HasBeenSet bool
Value Generic Value Generic
Destination *Generic Destination Generic
Aliases []string Aliases []string
EnvVars []string EnvVars []string
@ -1420,6 +1441,10 @@ func (f *IntSliceFlag) String() string
func (f *IntSliceFlag) TakesValue() bool func (f *IntSliceFlag) TakesValue() bool
TakesValue returns true of the flag takes a value, otherwise false TakesValue returns true of the flag takes a value, otherwise false
type InvalidFlagAccessFunc func(*Context, string)
InvalidFlagAccessFunc is executed when an invalid flag is accessed from the
context.
type MultiError interface { type MultiError interface {
error error
Errors() []error Errors() []error
@ -1899,6 +1924,89 @@ func (f *Uint64Flag) String() string
func (f *Uint64Flag) TakesValue() bool func (f *Uint64Flag) TakesValue() bool
TakesValue returns true of the flag takes a value, otherwise false TakesValue returns true of the flag takes a value, otherwise false
type Uint64Slice struct {
// Has unexported fields.
}
Uint64Slice wraps []int64 to satisfy flag.Value
func NewUint64Slice(defaults ...uint64) *Uint64Slice
NewUint64Slice makes an *Uint64Slice with default values
func (i *Uint64Slice) Get() interface{}
Get returns the slice of ints set by this flag
func (i *Uint64Slice) Serialize() string
Serialize allows Uint64Slice to fulfill Serializer
func (i *Uint64Slice) Set(value string) error
Set parses the value into an integer and appends it to the list of values
func (i *Uint64Slice) String() string
String returns a readable representation of this value (for usage defaults)
func (i *Uint64Slice) Value() []uint64
Value returns the slice of ints set by this flag
type Uint64SliceFlag struct {
Name string
Category string
DefaultText string
FilePath string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value *Uint64Slice
Destination *Uint64Slice
Aliases []string
EnvVars []string
}
Uint64SliceFlag is a flag with type *Uint64Slice
func (f *Uint64SliceFlag) Apply(set *flag.FlagSet) error
Apply populates the flag given the flag set and environment
func (f *Uint64SliceFlag) Get(ctx *Context) []uint64
Get returns the flags value in the given Context.
func (f *Uint64SliceFlag) GetCategory() string
GetCategory returns the category for the flag
func (f *Uint64SliceFlag) GetDefaultText() string
GetDefaultText returns the default text for this flag
func (f *Uint64SliceFlag) GetEnvVars() []string
GetEnvVars returns the env vars for this flag
func (f *Uint64SliceFlag) GetUsage() string
GetUsage returns the usage string for the flag
func (f *Uint64SliceFlag) GetValue() string
GetValue returns the flags value as string representation and an empty
string if the flag takes no value at all.
func (f *Uint64SliceFlag) IsRequired() bool
IsRequired returns whether or not the flag is required
func (f *Uint64SliceFlag) IsSet() bool
IsSet returns whether or not the flag has been set through env or file
func (f *Uint64SliceFlag) IsVisible() bool
IsVisible returns true if the flag is not hidden, otherwise false
func (f *Uint64SliceFlag) Names() []string
Names returns the names of the flag
func (f *Uint64SliceFlag) String() string
String returns a readable representation of this value (for usage defaults)
func (f *Uint64SliceFlag) TakesValue() bool
TakesValue returns true of the flag takes a value, otherwise false
type UintFlag struct { type UintFlag struct {
Name string Name string
@ -1961,6 +2069,93 @@ func (f *UintFlag) String() string
func (f *UintFlag) TakesValue() bool func (f *UintFlag) TakesValue() bool
TakesValue returns true of the flag takes a value, otherwise false TakesValue returns true of the flag takes a value, otherwise false
type UintSlice struct {
// Has unexported fields.
}
UintSlice wraps []int to satisfy flag.Value
func NewUintSlice(defaults ...uint) *UintSlice
NewUintSlice makes an *UintSlice with default values
func (i *UintSlice) Get() interface{}
Get returns the slice of ints set by this flag
func (i *UintSlice) Serialize() string
Serialize allows UintSlice to fulfill Serializer
func (i *UintSlice) Set(value string) error
Set parses the value into an integer and appends it to the list of values
func (i *UintSlice) SetUint(value uint)
TODO: Consistently have specific Set function for Int64 and Float64 ? SetInt
directly adds an integer to the list of values
func (i *UintSlice) String() string
String returns a readable representation of this value (for usage defaults)
func (i *UintSlice) Value() []uint
Value returns the slice of ints set by this flag
type UintSliceFlag struct {
Name string
Category string
DefaultText string
FilePath string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value *UintSlice
Destination *UintSlice
Aliases []string
EnvVars []string
}
UintSliceFlag is a flag with type *UintSlice
func (f *UintSliceFlag) Apply(set *flag.FlagSet) error
Apply populates the flag given the flag set and environment
func (f *UintSliceFlag) Get(ctx *Context) []uint
Get returns the flags value in the given Context.
func (f *UintSliceFlag) GetCategory() string
GetCategory returns the category for the flag
func (f *UintSliceFlag) GetDefaultText() string
GetDefaultText returns the default text for this flag
func (f *UintSliceFlag) GetEnvVars() []string
GetEnvVars returns the env vars for this flag
func (f *UintSliceFlag) GetUsage() string
GetUsage returns the usage string for the flag
func (f *UintSliceFlag) GetValue() string
GetValue returns the flags value as string representation and an empty
string if the flag takes no value at all.
func (f *UintSliceFlag) IsRequired() bool
IsRequired returns whether or not the flag is required
func (f *UintSliceFlag) IsSet() bool
IsSet returns whether or not the flag has been set through env or file
func (f *UintSliceFlag) IsVisible() bool
IsVisible returns true if the flag is not hidden, otherwise false
func (f *UintSliceFlag) Names() []string
Names returns the names of the flag
func (f *UintSliceFlag) String() string
String returns a readable representation of this value (for usage defaults)
func (f *UintSliceFlag) TakesValue() bool
TakesValue returns true of the flag takes a value, otherwise false
type VisibleFlag interface { type VisibleFlag interface {
Flag Flag

View file

@ -58,7 +58,7 @@ type GenericFlag struct {
HasBeenSet bool HasBeenSet bool
Value Generic Value Generic
Destination *Generic Destination Generic
Aliases []string Aliases []string
EnvVars []string EnvVars []string
@ -309,6 +309,86 @@ func (f *TimestampFlag) IsVisible() bool {
return !f.Hidden return !f.Hidden
} }
// Uint64SliceFlag is a flag with type *Uint64Slice
type Uint64SliceFlag struct {
Name string
Category string
DefaultText string
FilePath string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value *Uint64Slice
Destination *Uint64Slice
Aliases []string
EnvVars []string
}
// IsSet returns whether or not the flag has been set through env or file
func (f *Uint64SliceFlag) IsSet() bool {
return f.HasBeenSet
}
// Names returns the names of the flag
func (f *Uint64SliceFlag) Names() []string {
return FlagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *Uint64SliceFlag) IsRequired() bool {
return f.Required
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *Uint64SliceFlag) IsVisible() bool {
return !f.Hidden
}
// UintSliceFlag is a flag with type *UintSlice
type UintSliceFlag struct {
Name string
Category string
DefaultText string
FilePath string
Usage string
Required bool
Hidden bool
HasBeenSet bool
Value *UintSlice
Destination *UintSlice
Aliases []string
EnvVars []string
}
// IsSet returns whether or not the flag has been set through env or file
func (f *UintSliceFlag) IsSet() bool {
return f.HasBeenSet
}
// Names returns the names of the flag
func (f *UintSliceFlag) Names() []string {
return FlagNames(f.Name, f.Aliases)
}
// IsRequired returns whether or not the flag is required
func (f *UintSliceFlag) IsRequired() bool {
return f.Required
}
// IsVisible returns true if the flag is not hidden, otherwise false
func (f *UintSliceFlag) IsVisible() bool {
return !f.Hidden
}
// BoolFlag is a flag with type bool // BoolFlag is a flag with type bool
type BoolFlag struct { type BoolFlag struct {
Name string Name string
@ -327,6 +407,8 @@ type BoolFlag struct {
Aliases []string Aliases []string
EnvVars []string EnvVars []string
Count *int
} }
// String returns a readable representation of this value (for usage defaults) // String returns a readable representation of this value (for usage defaults)

View file

@ -32,7 +32,7 @@ var DeadlineExceeded = context.DeadlineExceeded
// call cancel as soon as the operations running in this Context complete. // call cancel as soon as the operations running in this Context complete.
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
ctx, f := context.WithCancel(parent) ctx, f := context.WithCancel(parent)
return ctx, CancelFunc(f) return ctx, f
} }
// WithDeadline returns a copy of the parent context with the deadline adjusted // WithDeadline returns a copy of the parent context with the deadline adjusted
@ -46,7 +46,7 @@ func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
// call cancel as soon as the operations running in this Context complete. // call cancel as soon as the operations running in this Context complete.
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
ctx, f := context.WithDeadline(parent, deadline) ctx, f := context.WithDeadline(parent, deadline)
return ctx, CancelFunc(f) return ctx, f
} }
// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). // WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).

View file

@ -178,5 +178,5 @@ func Verify(token string, key *rsa.PublicKey) error {
h := sha256.New() h := sha256.New()
h.Write([]byte(signedContent)) h.Write([]byte(signedContent))
return rsa.VerifyPKCS1v15(key, crypto.SHA256, h.Sum(nil), []byte(signatureString)) return rsa.VerifyPKCS1v15(key, crypto.SHA256, h.Sum(nil), signatureString)
} }

View file

@ -29,8 +29,6 @@ import (
"bytes" "bytes"
"strings" "strings"
"unsafe" "unsafe"
"golang.org/x/sys/internal/unsafeheader"
) )
// ByteSliceFromString returns a NUL-terminated slice of bytes // ByteSliceFromString returns a NUL-terminated slice of bytes
@ -82,12 +80,7 @@ func BytePtrToString(p *byte) string {
ptr = unsafe.Pointer(uintptr(ptr) + 1) ptr = unsafe.Pointer(uintptr(ptr) + 1)
} }
var s []byte s := unsafe.Slice((*byte)(unsafe.Pointer(p)), n)
h := (*unsafeheader.Slice)(unsafe.Pointer(&s))
h.Data = unsafe.Pointer(p)
h.Len = n
h.Cap = n
return string(s) return string(s)
} }

View file

@ -7,11 +7,7 @@
package unix package unix
import ( import "unsafe"
"unsafe"
"golang.org/x/sys/internal/unsafeheader"
)
//sys closedir(dir uintptr) (err error) //sys closedir(dir uintptr) (err error)
//sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) //sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno)
@ -86,11 +82,7 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
} }
// Copy entry into return buffer. // Copy entry into return buffer.
var s []byte s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&s))
hdr.Data = unsafe.Pointer(&entry)
hdr.Cap = reclen
hdr.Len = reclen
copy(buf, s) copy(buf, s)
buf = buf[reclen:] buf = buf[reclen:]

View file

@ -750,8 +750,8 @@ type EventPort struct {
// we should handle things gracefully. To do so, we need to keep an extra // we should handle things gracefully. To do so, we need to keep an extra
// reference to the cookie around until the event is processed // reference to the cookie around until the event is processed
// thus the otherwise seemingly extraneous "cookies" map // thus the otherwise seemingly extraneous "cookies" map
// The key of this map is a pointer to the corresponding &fCookie.cookie // The key of this map is a pointer to the corresponding fCookie
cookies map[*interface{}]*fileObjCookie cookies map[*fileObjCookie]struct{}
} }
// PortEvent is an abstraction of the port_event C struct. // PortEvent is an abstraction of the port_event C struct.
@ -778,7 +778,7 @@ func NewEventPort() (*EventPort, error) {
port: port, port: port,
fds: make(map[uintptr]*fileObjCookie), fds: make(map[uintptr]*fileObjCookie),
paths: make(map[string]*fileObjCookie), paths: make(map[string]*fileObjCookie),
cookies: make(map[*interface{}]*fileObjCookie), cookies: make(map[*fileObjCookie]struct{}),
} }
return e, nil return e, nil
} }
@ -799,6 +799,7 @@ func (e *EventPort) Close() error {
} }
e.fds = nil e.fds = nil
e.paths = nil e.paths = nil
e.cookies = nil
return nil return nil
} }
@ -826,17 +827,16 @@ func (e *EventPort) AssociatePath(path string, stat os.FileInfo, events int, coo
if _, found := e.paths[path]; found { if _, found := e.paths[path]; found {
return fmt.Errorf("%v is already associated with this Event Port", path) return fmt.Errorf("%v is already associated with this Event Port", path)
} }
fobj, err := createFileObj(path, stat) fCookie, err := createFileObjCookie(path, stat, cookie)
if err != nil { if err != nil {
return err return err
} }
fCookie := &fileObjCookie{fobj, cookie} _, err = port_associate(e.port, PORT_SOURCE_FILE, uintptr(unsafe.Pointer(fCookie.fobj)), events, (*byte)(unsafe.Pointer(fCookie)))
_, err = port_associate(e.port, PORT_SOURCE_FILE, uintptr(unsafe.Pointer(fobj)), events, (*byte)(unsafe.Pointer(&fCookie.cookie)))
if err != nil { if err != nil {
return err return err
} }
e.paths[path] = fCookie e.paths[path] = fCookie
e.cookies[&fCookie.cookie] = fCookie e.cookies[fCookie] = struct{}{}
return nil return nil
} }
@ -858,7 +858,7 @@ func (e *EventPort) DissociatePath(path string) error {
if err == nil { if err == nil {
// dissociate was successful, safe to delete the cookie // dissociate was successful, safe to delete the cookie
fCookie := e.paths[path] fCookie := e.paths[path]
delete(e.cookies, &fCookie.cookie) delete(e.cookies, fCookie)
} }
delete(e.paths, path) delete(e.paths, path)
return err return err
@ -871,13 +871,16 @@ func (e *EventPort) AssociateFd(fd uintptr, events int, cookie interface{}) erro
if _, found := e.fds[fd]; found { if _, found := e.fds[fd]; found {
return fmt.Errorf("%v is already associated with this Event Port", fd) return fmt.Errorf("%v is already associated with this Event Port", fd)
} }
fCookie := &fileObjCookie{nil, cookie} fCookie, err := createFileObjCookie("", nil, cookie)
_, err := port_associate(e.port, PORT_SOURCE_FD, fd, events, (*byte)(unsafe.Pointer(&fCookie.cookie))) if err != nil {
return err
}
_, err = port_associate(e.port, PORT_SOURCE_FD, fd, events, (*byte)(unsafe.Pointer(fCookie)))
if err != nil { if err != nil {
return err return err
} }
e.fds[fd] = fCookie e.fds[fd] = fCookie
e.cookies[&fCookie.cookie] = fCookie e.cookies[fCookie] = struct{}{}
return nil return nil
} }
@ -896,27 +899,31 @@ func (e *EventPort) DissociateFd(fd uintptr) error {
if err == nil { if err == nil {
// dissociate was successful, safe to delete the cookie // dissociate was successful, safe to delete the cookie
fCookie := e.fds[fd] fCookie := e.fds[fd]
delete(e.cookies, &fCookie.cookie) delete(e.cookies, fCookie)
} }
delete(e.fds, fd) delete(e.fds, fd)
return err return err
} }
func createFileObj(name string, stat os.FileInfo) (*fileObj, error) { func createFileObjCookie(name string, stat os.FileInfo, cookie interface{}) (*fileObjCookie, error) {
fobj := new(fileObj) fCookie := new(fileObjCookie)
bs, err := ByteSliceFromString(name) fCookie.cookie = cookie
if err != nil { if name != "" && stat != nil {
return nil, err fCookie.fobj = new(fileObj)
bs, err := ByteSliceFromString(name)
if err != nil {
return nil, err
}
fCookie.fobj.Name = (*int8)(unsafe.Pointer(&bs[0]))
s := stat.Sys().(*syscall.Stat_t)
fCookie.fobj.Atim.Sec = s.Atim.Sec
fCookie.fobj.Atim.Nsec = s.Atim.Nsec
fCookie.fobj.Mtim.Sec = s.Mtim.Sec
fCookie.fobj.Mtim.Nsec = s.Mtim.Nsec
fCookie.fobj.Ctim.Sec = s.Ctim.Sec
fCookie.fobj.Ctim.Nsec = s.Ctim.Nsec
} }
fobj.Name = (*int8)(unsafe.Pointer(&bs[0])) return fCookie, nil
s := stat.Sys().(*syscall.Stat_t)
fobj.Atim.Sec = s.Atim.Sec
fobj.Atim.Nsec = s.Atim.Nsec
fobj.Mtim.Sec = s.Mtim.Sec
fobj.Mtim.Nsec = s.Mtim.Nsec
fobj.Ctim.Sec = s.Ctim.Sec
fobj.Ctim.Nsec = s.Ctim.Nsec
return fobj, nil
} }
// GetOne wraps port_get(3c) and returns a single PortEvent. // GetOne wraps port_get(3c) and returns a single PortEvent.
@ -929,44 +936,50 @@ func (e *EventPort) GetOne(t *Timespec) (*PortEvent, error) {
p := new(PortEvent) p := new(PortEvent)
e.mu.Lock() e.mu.Lock()
defer e.mu.Unlock() defer e.mu.Unlock()
e.peIntToExt(pe, p) err = e.peIntToExt(pe, p)
if err != nil {
return nil, err
}
return p, nil return p, nil
} }
// peIntToExt converts a cgo portEvent struct into the friendlier PortEvent // peIntToExt converts a cgo portEvent struct into the friendlier PortEvent
// NOTE: Always call this function while holding the e.mu mutex // NOTE: Always call this function while holding the e.mu mutex
func (e *EventPort) peIntToExt(peInt *portEvent, peExt *PortEvent) { func (e *EventPort) peIntToExt(peInt *portEvent, peExt *PortEvent) error {
if e.cookies == nil {
return fmt.Errorf("this EventPort is already closed")
}
peExt.Events = peInt.Events peExt.Events = peInt.Events
peExt.Source = peInt.Source peExt.Source = peInt.Source
cookie := (*interface{})(unsafe.Pointer(peInt.User)) fCookie := (*fileObjCookie)(unsafe.Pointer(peInt.User))
peExt.Cookie = *cookie _, found := e.cookies[fCookie]
if !found {
panic("unexpected event port address; may be due to kernel bug; see https://go.dev/issue/54254")
}
peExt.Cookie = fCookie.cookie
delete(e.cookies, fCookie)
switch peInt.Source { switch peInt.Source {
case PORT_SOURCE_FD: case PORT_SOURCE_FD:
delete(e.cookies, cookie)
peExt.Fd = uintptr(peInt.Object) peExt.Fd = uintptr(peInt.Object)
// Only remove the fds entry if it exists and this cookie matches // Only remove the fds entry if it exists and this cookie matches
if fobj, ok := e.fds[peExt.Fd]; ok { if fobj, ok := e.fds[peExt.Fd]; ok {
if &fobj.cookie == cookie { if fobj == fCookie {
delete(e.fds, peExt.Fd) delete(e.fds, peExt.Fd)
} }
} }
case PORT_SOURCE_FILE: case PORT_SOURCE_FILE:
if fCookie, ok := e.cookies[cookie]; ok && uintptr(unsafe.Pointer(fCookie.fobj)) == uintptr(peInt.Object) { peExt.fobj = fCookie.fobj
// Use our stashed reference rather than using unsafe on what we got back
// the unsafe version would be (*fileObj)(unsafe.Pointer(uintptr(peInt.Object)))
peExt.fobj = fCookie.fobj
} else {
panic("unexpected event port address; may be due to kernel bug; see https://go.dev/issue/54254")
}
delete(e.cookies, cookie)
peExt.Path = BytePtrToString((*byte)(unsafe.Pointer(peExt.fobj.Name))) peExt.Path = BytePtrToString((*byte)(unsafe.Pointer(peExt.fobj.Name)))
// Only remove the paths entry if it exists and this cookie matches // Only remove the paths entry if it exists and this cookie matches
if fobj, ok := e.paths[peExt.Path]; ok { if fobj, ok := e.paths[peExt.Path]; ok {
if &fobj.cookie == cookie { if fobj == fCookie {
delete(e.paths, peExt.Path) delete(e.paths, peExt.Path)
} }
} }
} }
return nil
} }
// Pending wraps port_getn(3c) and returns how many events are pending. // Pending wraps port_getn(3c) and returns how many events are pending.
@ -990,7 +1003,7 @@ func (e *EventPort) Get(s []PortEvent, min int, timeout *Timespec) (int, error)
got := uint32(min) got := uint32(min)
max := uint32(len(s)) max := uint32(len(s))
var err error var err error
ps := make([]portEvent, max, max) ps := make([]portEvent, max)
_, err = port_getn(e.port, &ps[0], max, &got, timeout) _, err = port_getn(e.port, &ps[0], max, &got, timeout)
// got will be trustworthy with ETIME, but not any other error. // got will be trustworthy with ETIME, but not any other error.
if err != nil && err != ETIME { if err != nil && err != ETIME {
@ -998,8 +1011,18 @@ func (e *EventPort) Get(s []PortEvent, min int, timeout *Timespec) (int, error)
} }
e.mu.Lock() e.mu.Lock()
defer e.mu.Unlock() defer e.mu.Unlock()
valid := 0
for i := 0; i < int(got); i++ { for i := 0; i < int(got); i++ {
e.peIntToExt(&ps[i], &s[i]) err2 := e.peIntToExt(&ps[i], &s[i])
if err2 != nil {
if valid == 0 && err == nil {
// If err2 is the only error and there are no valid events
// to return, return it to the caller.
err = err2
}
break
}
valid = i + 1
} }
return int(got), err return valid, err
} }

View file

@ -13,8 +13,6 @@ import (
"sync" "sync"
"syscall" "syscall"
"unsafe" "unsafe"
"golang.org/x/sys/internal/unsafeheader"
) )
var ( var (
@ -117,11 +115,7 @@ func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (d
} }
// Use unsafe to convert addr into a []byte. // Use unsafe to convert addr into a []byte.
var b []byte b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), length)
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
hdr.Data = unsafe.Pointer(addr)
hdr.Cap = length
hdr.Len = length
// Register mapping in m and return it. // Register mapping in m and return it.
p := &b[cap(b)-1] p := &b[cap(b)-1]

View file

@ -7,11 +7,7 @@
package unix package unix
import ( import "unsafe"
"unsafe"
"golang.org/x/sys/internal/unsafeheader"
)
// SysvShmAttach attaches the Sysv shared memory segment associated with the // SysvShmAttach attaches the Sysv shared memory segment associated with the
// shared memory identifier id. // shared memory identifier id.
@ -34,12 +30,7 @@ func SysvShmAttach(id int, addr uintptr, flag int) ([]byte, error) {
} }
// Use unsafe to convert addr into a []byte. // Use unsafe to convert addr into a []byte.
// TODO: convert to unsafe.Slice once we can assume Go 1.17 b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), int(info.Segsz))
var b []byte
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
hdr.Data = unsafe.Pointer(addr)
hdr.Cap = int(info.Segsz)
hdr.Len = int(info.Segsz)
return b, nil return b, nil
} }

View file

@ -364,6 +364,15 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) //sys SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error)
//sys GetActiveProcessorCount(groupNumber uint16) (ret uint32) //sys GetActiveProcessorCount(groupNumber uint16) (ret uint32)
//sys GetMaximumProcessorCount(groupNumber uint16) (ret uint32) //sys GetMaximumProcessorCount(groupNumber uint16) (ret uint32)
//sys EnumWindows(enumFunc uintptr, param unsafe.Pointer) (err error) = user32.EnumWindows
//sys EnumChildWindows(hwnd HWND, enumFunc uintptr, param unsafe.Pointer) = user32.EnumChildWindows
//sys GetClassName(hwnd HWND, className *uint16, maxCount int32) (copied int32, err error) = user32.GetClassNameW
//sys GetDesktopWindow() (hwnd HWND) = user32.GetDesktopWindow
//sys GetForegroundWindow() (hwnd HWND) = user32.GetForegroundWindow
//sys IsWindow(hwnd HWND) (isWindow bool) = user32.IsWindow
//sys IsWindowUnicode(hwnd HWND) (isUnicode bool) = user32.IsWindowUnicode
//sys IsWindowVisible(hwnd HWND) (isVisible bool) = user32.IsWindowVisible
//sys GetGUIThreadInfo(thread uint32, info *GUIThreadInfo) (err error) = user32.GetGUIThreadInfo
// Volume Management Functions // Volume Management Functions
//sys DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) = DefineDosDeviceW //sys DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) = DefineDosDeviceW

View file

@ -3213,3 +3213,22 @@ type ModuleInfo struct {
} }
const ALL_PROCESSOR_GROUPS = 0xFFFF const ALL_PROCESSOR_GROUPS = 0xFFFF
type Rect struct {
Left int32
Top int32
Right int32
Bottom int32
}
type GUIThreadInfo struct {
Size uint32
Flags uint32
Active HWND
Focus HWND
Capture HWND
MenuOwner HWND
MoveSize HWND
CaretHandle HWND
CaretRect Rect
}

View file

@ -444,9 +444,18 @@ var (
procCommandLineToArgvW = modshell32.NewProc("CommandLineToArgvW") procCommandLineToArgvW = modshell32.NewProc("CommandLineToArgvW")
procSHGetKnownFolderPath = modshell32.NewProc("SHGetKnownFolderPath") procSHGetKnownFolderPath = modshell32.NewProc("SHGetKnownFolderPath")
procShellExecuteW = modshell32.NewProc("ShellExecuteW") procShellExecuteW = modshell32.NewProc("ShellExecuteW")
procEnumChildWindows = moduser32.NewProc("EnumChildWindows")
procEnumWindows = moduser32.NewProc("EnumWindows")
procExitWindowsEx = moduser32.NewProc("ExitWindowsEx") procExitWindowsEx = moduser32.NewProc("ExitWindowsEx")
procGetClassNameW = moduser32.NewProc("GetClassNameW")
procGetDesktopWindow = moduser32.NewProc("GetDesktopWindow")
procGetForegroundWindow = moduser32.NewProc("GetForegroundWindow")
procGetGUIThreadInfo = moduser32.NewProc("GetGUIThreadInfo")
procGetShellWindow = moduser32.NewProc("GetShellWindow") procGetShellWindow = moduser32.NewProc("GetShellWindow")
procGetWindowThreadProcessId = moduser32.NewProc("GetWindowThreadProcessId") procGetWindowThreadProcessId = moduser32.NewProc("GetWindowThreadProcessId")
procIsWindow = moduser32.NewProc("IsWindow")
procIsWindowUnicode = moduser32.NewProc("IsWindowUnicode")
procIsWindowVisible = moduser32.NewProc("IsWindowVisible")
procMessageBoxW = moduser32.NewProc("MessageBoxW") procMessageBoxW = moduser32.NewProc("MessageBoxW")
procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock") procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock")
procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock") procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock")
@ -3802,6 +3811,19 @@ func ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *ui
return return
} }
func EnumChildWindows(hwnd HWND, enumFunc uintptr, param unsafe.Pointer) {
syscall.Syscall(procEnumChildWindows.Addr(), 3, uintptr(hwnd), uintptr(enumFunc), uintptr(param))
return
}
func EnumWindows(enumFunc uintptr, param unsafe.Pointer) (err error) {
r1, _, e1 := syscall.Syscall(procEnumWindows.Addr(), 2, uintptr(enumFunc), uintptr(param), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func ExitWindowsEx(flags uint32, reason uint32) (err error) { func ExitWindowsEx(flags uint32, reason uint32) (err error) {
r1, _, e1 := syscall.Syscall(procExitWindowsEx.Addr(), 2, uintptr(flags), uintptr(reason), 0) r1, _, e1 := syscall.Syscall(procExitWindowsEx.Addr(), 2, uintptr(flags), uintptr(reason), 0)
if r1 == 0 { if r1 == 0 {
@ -3810,6 +3832,35 @@ func ExitWindowsEx(flags uint32, reason uint32) (err error) {
return return
} }
func GetClassName(hwnd HWND, className *uint16, maxCount int32) (copied int32, err error) {
r0, _, e1 := syscall.Syscall(procGetClassNameW.Addr(), 3, uintptr(hwnd), uintptr(unsafe.Pointer(className)), uintptr(maxCount))
copied = int32(r0)
if copied == 0 {
err = errnoErr(e1)
}
return
}
func GetDesktopWindow() (hwnd HWND) {
r0, _, _ := syscall.Syscall(procGetDesktopWindow.Addr(), 0, 0, 0, 0)
hwnd = HWND(r0)
return
}
func GetForegroundWindow() (hwnd HWND) {
r0, _, _ := syscall.Syscall(procGetForegroundWindow.Addr(), 0, 0, 0, 0)
hwnd = HWND(r0)
return
}
func GetGUIThreadInfo(thread uint32, info *GUIThreadInfo) (err error) {
r1, _, e1 := syscall.Syscall(procGetGUIThreadInfo.Addr(), 2, uintptr(thread), uintptr(unsafe.Pointer(info)), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func GetShellWindow() (shellWindow HWND) { func GetShellWindow() (shellWindow HWND) {
r0, _, _ := syscall.Syscall(procGetShellWindow.Addr(), 0, 0, 0, 0) r0, _, _ := syscall.Syscall(procGetShellWindow.Addr(), 0, 0, 0, 0)
shellWindow = HWND(r0) shellWindow = HWND(r0)
@ -3825,6 +3876,24 @@ func GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) {
return return
} }
func IsWindow(hwnd HWND) (isWindow bool) {
r0, _, _ := syscall.Syscall(procIsWindow.Addr(), 1, uintptr(hwnd), 0, 0)
isWindow = r0 != 0
return
}
func IsWindowUnicode(hwnd HWND) (isUnicode bool) {
r0, _, _ := syscall.Syscall(procIsWindowUnicode.Addr(), 1, uintptr(hwnd), 0, 0)
isUnicode = r0 != 0
return
}
func IsWindowVisible(hwnd HWND) (isVisible bool) {
r0, _, _ := syscall.Syscall(procIsWindowVisible.Addr(), 1, uintptr(hwnd), 0, 0)
isVisible = r0 != 0
return
}
func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) { func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) {
r0, _, e1 := syscall.Syscall6(procMessageBoxW.Addr(), 4, uintptr(hwnd), uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), uintptr(boxtype), 0, 0) r0, _, e1 := syscall.Syscall6(procMessageBoxW.Addr(), 4, uintptr(hwnd), uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), uintptr(boxtype), 0, 0)
ret = int32(r0) ret = int32(r0)

14
vendor/modules.txt vendored
View file

@ -34,7 +34,7 @@ github.com/VictoriaMetrics/metricsql/binaryop
# github.com/VividCortex/ewma v1.2.0 # github.com/VividCortex/ewma v1.2.0
## explicit; go 1.12 ## explicit; go 1.12
github.com/VividCortex/ewma github.com/VividCortex/ewma
# github.com/aws/aws-sdk-go v1.44.93 # github.com/aws/aws-sdk-go v1.44.96
## explicit; go 1.11 ## explicit; go 1.11
github.com/aws/aws-sdk-go/aws github.com/aws/aws-sdk-go/aws
github.com/aws/aws-sdk-go/aws/arn github.com/aws/aws-sdk-go/aws/arn
@ -221,13 +221,13 @@ github.com/prometheus/prometheus/tsdb/record
github.com/prometheus/prometheus/tsdb/tombstones github.com/prometheus/prometheus/tsdb/tombstones
github.com/prometheus/prometheus/tsdb/tsdbutil github.com/prometheus/prometheus/tsdb/tsdbutil
github.com/prometheus/prometheus/tsdb/wal github.com/prometheus/prometheus/tsdb/wal
# github.com/rivo/uniseg v0.3.4 # github.com/rivo/uniseg v0.4.2
## explicit; go 1.18 ## explicit; go 1.18
github.com/rivo/uniseg github.com/rivo/uniseg
# github.com/russross/blackfriday/v2 v2.1.0 # github.com/russross/blackfriday/v2 v2.1.0
## explicit ## explicit
github.com/russross/blackfriday/v2 github.com/russross/blackfriday/v2
# github.com/urfave/cli/v2 v2.14.1 # github.com/urfave/cli/v2 v2.16.3
## explicit; go 1.18 ## explicit; go 1.18
github.com/urfave/cli/v2 github.com/urfave/cli/v2
# github.com/valyala/bytebufferpool v1.0.0 # github.com/valyala/bytebufferpool v1.0.0
@ -279,7 +279,7 @@ go.opencensus.io/trace/tracestate
go.uber.org/atomic go.uber.org/atomic
# go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 # go.uber.org/goleak v1.1.11-0.20210813005559-691160354723
## explicit; go 1.13 ## explicit; go 1.13
# golang.org/x/net v0.0.0-20220907135653-1e95f45603a7 # golang.org/x/net v0.0.0-20220909164309-bea034e7d591
## explicit; go 1.17 ## explicit; go 1.17
golang.org/x/net/context golang.org/x/net/context
golang.org/x/net/context/ctxhttp golang.org/x/net/context/ctxhttp
@ -291,7 +291,7 @@ golang.org/x/net/internal/socks
golang.org/x/net/internal/timeseries golang.org/x/net/internal/timeseries
golang.org/x/net/proxy golang.org/x/net/proxy
golang.org/x/net/trace golang.org/x/net/trace
# golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 # golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1
## explicit; go 1.17 ## explicit; go 1.17
golang.org/x/oauth2 golang.org/x/oauth2
golang.org/x/oauth2/authhandler golang.org/x/oauth2/authhandler
@ -304,7 +304,7 @@ golang.org/x/oauth2/jwt
# golang.org/x/sync v0.0.0-20220907140024-f12130a52804 # golang.org/x/sync v0.0.0-20220907140024-f12130a52804
## explicit ## explicit
golang.org/x/sync/errgroup golang.org/x/sync/errgroup
# golang.org/x/sys v0.0.0-20220908150016-7ac13a9a928d # golang.org/x/sys v0.0.0-20220913120320-3275c407cedc
## explicit; go 1.17 ## explicit; go 1.17
golang.org/x/sys/internal/unsafeheader golang.org/x/sys/internal/unsafeheader
golang.org/x/sys/unix golang.org/x/sys/unix
@ -352,7 +352,7 @@ google.golang.org/appengine/internal/socket
google.golang.org/appengine/internal/urlfetch google.golang.org/appengine/internal/urlfetch
google.golang.org/appengine/socket google.golang.org/appengine/socket
google.golang.org/appengine/urlfetch google.golang.org/appengine/urlfetch
# google.golang.org/genproto v0.0.0-20220908141613-51c1cc9bc6d0 # google.golang.org/genproto v0.0.0-20220909194730-69f6226f97e5
## explicit; go 1.19 ## explicit; go 1.19
google.golang.org/genproto/googleapis/api/annotations google.golang.org/genproto/googleapis/api/annotations
google.golang.org/genproto/googleapis/iam/v1 google.golang.org/genproto/googleapis/iam/v1