forked from ebhomengo/niki
usecase added
This commit is contained in:
parent
c0aa3a0b36
commit
f63a574778
14
go.mod
14
go.mod
|
|
@ -18,7 +18,7 @@ require (
|
||||||
github.com/stretchr/testify v1.11.1
|
github.com/stretchr/testify v1.11.1
|
||||||
github.com/swaggo/echo-swagger v1.5.2
|
github.com/swaggo/echo-swagger v1.5.2
|
||||||
github.com/swaggo/swag v1.16.6
|
github.com/swaggo/swag v1.16.6
|
||||||
golang.org/x/crypto v0.46.0
|
golang.org/x/crypto v0.48.0
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -77,13 +77,13 @@ require (
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||||
go.uber.org/atomic v1.11.0 // indirect
|
go.uber.org/atomic v1.11.0 // indirect
|
||||||
golang.org/x/mod v0.30.0 // indirect
|
golang.org/x/mod v0.33.0 // indirect
|
||||||
golang.org/x/net v0.48.0 // indirect
|
golang.org/x/net v0.50.0 // indirect
|
||||||
golang.org/x/sync v0.19.0 // indirect
|
golang.org/x/sync v0.20.0 // indirect
|
||||||
golang.org/x/sys v0.39.0 // indirect
|
golang.org/x/sys v0.41.0 // indirect
|
||||||
golang.org/x/text v0.32.0 // indirect
|
golang.org/x/text v0.35.0 // indirect
|
||||||
golang.org/x/time v0.14.0 // indirect
|
golang.org/x/time v0.14.0 // indirect
|
||||||
golang.org/x/tools v0.39.0 // indirect
|
golang.org/x/tools v0.42.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||||
|
|
|
||||||
28
go.sum
28
go.sum
|
|
@ -404,8 +404,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
|
||||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
|
|
@ -415,8 +415,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
|
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
|
||||||
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
|
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
|
@ -434,8 +434,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
|
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
|
||||||
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
|
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
|
||||||
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
|
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
|
||||||
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-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
|
@ -448,8 +448,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
|
@ -483,8 +483,8 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
|
@ -492,8 +492,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
|
||||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
||||||
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||||
|
|
@ -508,8 +508,8 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK
|
||||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
|
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
|
||||||
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
|
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fmt.Println(" Staffapp Server Starting...")
|
|
||||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
fmt.Fprintf(w, "Staffapp OK!")
|
|
||||||
})
|
|
||||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
|
||||||
}
|
|
||||||
|
|
@ -1 +1,13 @@
|
||||||
package service
|
package service
|
||||||
|
|
||||||
|
type Staff struct {
|
||||||
|
ID int
|
||||||
|
Name string
|
||||||
|
LastName string
|
||||||
|
PhoneNumber string
|
||||||
|
}
|
||||||
|
|
||||||
|
type StaffService struct {
|
||||||
|
Staffs []Staff
|
||||||
|
NextID int
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
package service
|
|
||||||
|
|
@ -1 +1,49 @@
|
||||||
package service
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *StaffService) RegisterStaff(id int, name string, lastname string, phonenumber string) (Staff, error) {
|
||||||
|
|
||||||
|
for _, staff := range s.Staffs {
|
||||||
|
if staff.PhoneNumber == phonenumber {
|
||||||
|
return Staff{}, errors.New("This number is already in use")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newID := s.NextID
|
||||||
|
s.NextID++
|
||||||
|
|
||||||
|
newStaff := Staff{
|
||||||
|
ID: newID,
|
||||||
|
Name: name,
|
||||||
|
LastName: lastname,
|
||||||
|
PhoneNumber: phonenumber,
|
||||||
|
}
|
||||||
|
s.Staffs = append(s.Staffs, newStaff)
|
||||||
|
return newStaff, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StaffService) DeleteStaff(phoneNumber string) {
|
||||||
|
for i, n := range s.Staffs {
|
||||||
|
if phoneNumber == n.PhoneNumber {
|
||||||
|
s.Staffs = append(s.Staffs[:i], s.Staffs[i+1:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StaffService) ListStaff() []Staff {
|
||||||
|
return s.Staffs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StaffService) PrintStaffs() {
|
||||||
|
if len(s.Staffs) == 0 {
|
||||||
|
fmt.Println("There is no staff yet")
|
||||||
|
}
|
||||||
|
for _, staff := range s.Staffs {
|
||||||
|
fmt.Printf("ID: %d, Name:%s %s,Phone number:%s", staff.ID, staff.Name, staff.LastName, staff.PhoneNumber)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
package service
|
|
||||||
|
|
@ -802,8 +802,8 @@ func MatchPrefixPatterns(globs, target string) bool {
|
||||||
for globs != "" {
|
for globs != "" {
|
||||||
// Extract next non-empty glob in comma-separated list.
|
// Extract next non-empty glob in comma-separated list.
|
||||||
var glob string
|
var glob string
|
||||||
if i := strings.Index(globs, ","); i >= 0 {
|
if before, after, ok := strings.Cut(globs, ","); ok {
|
||||||
glob, globs = globs[:i], globs[i+1:]
|
glob, globs = before, after
|
||||||
} else {
|
} else {
|
||||||
glob, globs = globs, ""
|
glob, globs = globs, ""
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2026 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !go1.27
|
||||||
|
|
||||||
|
package http2
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
|
// Support for go.dev/issue/75500 is added in Go 1.27. In case anyone uses
|
||||||
|
// x/net with versions before Go 1.27, we return true here so that their write
|
||||||
|
// scheduler will still be the round-robin write scheduler rather than the RFC
|
||||||
|
// 9218 write scheduler. That way, older users of Go will not see a sudden
|
||||||
|
// change of behavior just from importing x/net.
|
||||||
|
//
|
||||||
|
// TODO(nsh): remove this file after x/net go.mod is at Go 1.27.
|
||||||
|
func clientPriorityDisabled(_ *http.Server) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
// Copyright 2026 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build go1.27
|
||||||
|
|
||||||
|
package http2
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
|
func clientPriorityDisabled(s *http.Server) bool {
|
||||||
|
return s.DisableClientPriority
|
||||||
|
}
|
||||||
|
|
@ -11,11 +11,13 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"golang.org/x/net/http/httpguts"
|
"golang.org/x/net/http/httpguts"
|
||||||
"golang.org/x/net/http2/hpack"
|
"golang.org/x/net/http2/hpack"
|
||||||
|
"golang.org/x/net/internal/httpsfv"
|
||||||
)
|
)
|
||||||
|
|
||||||
const frameHeaderLen = 9
|
const frameHeaderLen = 9
|
||||||
|
|
@ -23,7 +25,8 @@ const frameHeaderLen = 9
|
||||||
var padZeros = make([]byte, 255) // zeros for padding
|
var padZeros = make([]byte, 255) // zeros for padding
|
||||||
|
|
||||||
// A FrameType is a registered frame type as defined in
|
// A FrameType is a registered frame type as defined in
|
||||||
// https://httpwg.org/specs/rfc7540.html#rfc.section.11.2
|
// https://httpwg.org/specs/rfc7540.html#rfc.section.11.2 and other future
|
||||||
|
// RFCs.
|
||||||
type FrameType uint8
|
type FrameType uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -37,6 +40,7 @@ const (
|
||||||
FrameGoAway FrameType = 0x7
|
FrameGoAway FrameType = 0x7
|
||||||
FrameWindowUpdate FrameType = 0x8
|
FrameWindowUpdate FrameType = 0x8
|
||||||
FrameContinuation FrameType = 0x9
|
FrameContinuation FrameType = 0x9
|
||||||
|
FramePriorityUpdate FrameType = 0x10
|
||||||
)
|
)
|
||||||
|
|
||||||
var frameNames = [...]string{
|
var frameNames = [...]string{
|
||||||
|
|
@ -50,6 +54,7 @@ var frameNames = [...]string{
|
||||||
FrameGoAway: "GOAWAY",
|
FrameGoAway: "GOAWAY",
|
||||||
FrameWindowUpdate: "WINDOW_UPDATE",
|
FrameWindowUpdate: "WINDOW_UPDATE",
|
||||||
FrameContinuation: "CONTINUATION",
|
FrameContinuation: "CONTINUATION",
|
||||||
|
FramePriorityUpdate: "PRIORITY_UPDATE",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t FrameType) String() string {
|
func (t FrameType) String() string {
|
||||||
|
|
@ -135,6 +140,7 @@ var frameParsers = [...]frameParser{
|
||||||
FrameGoAway: parseGoAwayFrame,
|
FrameGoAway: parseGoAwayFrame,
|
||||||
FrameWindowUpdate: parseWindowUpdateFrame,
|
FrameWindowUpdate: parseWindowUpdateFrame,
|
||||||
FrameContinuation: parseContinuationFrame,
|
FrameContinuation: parseContinuationFrame,
|
||||||
|
FramePriorityUpdate: parsePriorityUpdateFrame,
|
||||||
}
|
}
|
||||||
|
|
||||||
func typeFrameParser(t FrameType) frameParser {
|
func typeFrameParser(t FrameType) frameParser {
|
||||||
|
|
@ -1180,9 +1186,34 @@ type PriorityFrame struct {
|
||||||
PriorityParam
|
PriorityParam
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultRFC9218Priority = PriorityParam{
|
// defaultRFC9218Priority determines what priority we should use as the default
|
||||||
incremental: 0,
|
// value.
|
||||||
|
//
|
||||||
|
// According to RFC 9218, by default, streams should be given an urgency of 3
|
||||||
|
// and should be non-incremental. However, making streams non-incremental by
|
||||||
|
// default would be a huge change to our historical behavior where we would
|
||||||
|
// round-robin writes across streams. When streams are non-incremental, we
|
||||||
|
// would process streams of the same urgency one-by-one to completion instead.
|
||||||
|
//
|
||||||
|
// To avoid such a sudden change which might break some HTTP/2 users, this
|
||||||
|
// function allows the caller to specify whether they can actually use the
|
||||||
|
// default value as specified in RFC 9218. If not, this function will return a
|
||||||
|
// priority value where streams are incremental by default instead: effectively
|
||||||
|
// a round-robin between stream of the same urgency.
|
||||||
|
//
|
||||||
|
// As an example, a server might not be able to use the RFC 9218 default value
|
||||||
|
// when it's not sure that the client it is serving is aware of RFC 9218.
|
||||||
|
func defaultRFC9218Priority(canUseDefault bool) PriorityParam {
|
||||||
|
if canUseDefault {
|
||||||
|
return PriorityParam{
|
||||||
urgency: 3,
|
urgency: 3,
|
||||||
|
incremental: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PriorityParam{
|
||||||
|
urgency: 3,
|
||||||
|
incremental: 1,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that HTTP/2 has had two different prioritization schemes, and
|
// Note that HTTP/2 has had two different prioritization schemes, and
|
||||||
|
|
@ -1266,6 +1297,74 @@ func (f *Framer) WritePriority(streamID uint32, p PriorityParam) error {
|
||||||
return f.endWrite()
|
return f.endWrite()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PriorityUpdateFrame is a PRIORITY_UPDATE frame as described in
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9218.html#name-the-priority_update-frame.
|
||||||
|
type PriorityUpdateFrame struct {
|
||||||
|
FrameHeader
|
||||||
|
Priority string
|
||||||
|
PrioritizedStreamID uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseRFC9218Priority(s string, canUseDefault bool) (p PriorityParam, ok bool) {
|
||||||
|
p = defaultRFC9218Priority(canUseDefault)
|
||||||
|
ok = httpsfv.ParseDictionary(s, func(key, val, _ string) {
|
||||||
|
switch key {
|
||||||
|
case "u":
|
||||||
|
if u, ok := httpsfv.ParseInteger(val); ok && u >= 0 && u <= 7 {
|
||||||
|
p.urgency = uint8(u)
|
||||||
|
}
|
||||||
|
case "i":
|
||||||
|
if i, ok := httpsfv.ParseBoolean(val); ok {
|
||||||
|
if i {
|
||||||
|
p.incremental = 1
|
||||||
|
} else {
|
||||||
|
p.incremental = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if !ok {
|
||||||
|
return defaultRFC9218Priority(canUseDefault), ok
|
||||||
|
}
|
||||||
|
return p, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func parsePriorityUpdateFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {
|
||||||
|
if fh.StreamID != 0 {
|
||||||
|
countError("frame_priority_update_non_zero_stream")
|
||||||
|
return nil, connError{ErrCodeProtocol, "PRIORITY_UPDATE frame with non-zero stream ID"}
|
||||||
|
}
|
||||||
|
if len(payload) < 4 {
|
||||||
|
countError("frame_priority_update_bad_length")
|
||||||
|
return nil, connError{ErrCodeFrameSize, fmt.Sprintf("PRIORITY_UPDATE frame payload size was %d; want at least 4", len(payload))}
|
||||||
|
}
|
||||||
|
v := binary.BigEndian.Uint32(payload[:4])
|
||||||
|
streamID := v & 0x7fffffff // mask off high bit
|
||||||
|
if streamID == 0 {
|
||||||
|
countError("frame_priority_update_prioritizing_zero_stream")
|
||||||
|
return nil, connError{ErrCodeProtocol, "PRIORITY_UPDATE frame with prioritized stream ID of zero"}
|
||||||
|
}
|
||||||
|
return &PriorityUpdateFrame{
|
||||||
|
FrameHeader: fh,
|
||||||
|
PrioritizedStreamID: streamID,
|
||||||
|
Priority: string(payload[4:]),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WritePriorityUpdate writes a PRIORITY_UPDATE frame.
|
||||||
|
//
|
||||||
|
// It will perform exactly one Write to the underlying Writer.
|
||||||
|
// It is the caller's responsibility to not call other Write methods concurrently.
|
||||||
|
func (f *Framer) WritePriorityUpdate(streamID uint32, priority string) error {
|
||||||
|
if !validStreamID(streamID) && !f.AllowIllegalWrites {
|
||||||
|
return errStreamID
|
||||||
|
}
|
||||||
|
f.startWrite(FramePriorityUpdate, 0, 0)
|
||||||
|
f.writeUint32(streamID)
|
||||||
|
f.writeBytes([]byte(priority))
|
||||||
|
return f.endWrite()
|
||||||
|
}
|
||||||
|
|
||||||
// A RSTStreamFrame allows for abnormal termination of a stream.
|
// A RSTStreamFrame allows for abnormal termination of a stream.
|
||||||
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.4
|
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.4
|
||||||
type RSTStreamFrame struct {
|
type RSTStreamFrame struct {
|
||||||
|
|
@ -1547,6 +1646,23 @@ func (mh *MetaHeadersFrame) PseudoFields() []hpack.HeaderField {
|
||||||
return mh.Fields
|
return mh.Fields
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mh *MetaHeadersFrame) rfc9218Priority(priorityAware bool) (p PriorityParam, priorityAwareAfter, hasIntermediary bool) {
|
||||||
|
var s string
|
||||||
|
for _, field := range mh.Fields {
|
||||||
|
if field.Name == "priority" {
|
||||||
|
s = field.Value
|
||||||
|
priorityAware = true
|
||||||
|
}
|
||||||
|
if slices.Contains([]string{"via", "forwarded", "x-forwarded-for"}, field.Name) {
|
||||||
|
hasIntermediary = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// No need to check for ok. parseRFC9218Priority will return a default
|
||||||
|
// value if there is no priority field or if the field cannot be parsed.
|
||||||
|
p, _ = parseRFC9218Priority(s, priorityAware && !hasIntermediary)
|
||||||
|
return p, priorityAware, hasIntermediary
|
||||||
|
}
|
||||||
|
|
||||||
func (mh *MetaHeadersFrame) checkPseudos() error {
|
func (mh *MetaHeadersFrame) checkPseudos() error {
|
||||||
var isRequest, isResponse bool
|
var isRequest, isResponse bool
|
||||||
pf := mh.PseudoFields()
|
pf := mh.PseudoFields()
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,7 @@ const (
|
||||||
SettingMaxFrameSize SettingID = 0x5
|
SettingMaxFrameSize SettingID = 0x5
|
||||||
SettingMaxHeaderListSize SettingID = 0x6
|
SettingMaxHeaderListSize SettingID = 0x6
|
||||||
SettingEnableConnectProtocol SettingID = 0x8
|
SettingEnableConnectProtocol SettingID = 0x8
|
||||||
|
SettingNoRFC7540Priorities SettingID = 0x9
|
||||||
)
|
)
|
||||||
|
|
||||||
var settingName = map[SettingID]string{
|
var settingName = map[SettingID]string{
|
||||||
|
|
@ -179,6 +180,7 @@ var settingName = map[SettingID]string{
|
||||||
SettingMaxFrameSize: "MAX_FRAME_SIZE",
|
SettingMaxFrameSize: "MAX_FRAME_SIZE",
|
||||||
SettingMaxHeaderListSize: "MAX_HEADER_LIST_SIZE",
|
SettingMaxHeaderListSize: "MAX_HEADER_LIST_SIZE",
|
||||||
SettingEnableConnectProtocol: "ENABLE_CONNECT_PROTOCOL",
|
SettingEnableConnectProtocol: "ENABLE_CONNECT_PROTOCOL",
|
||||||
|
SettingNoRFC7540Priorities: "NO_RFC7540_PRIORITIES",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s SettingID) String() string {
|
func (s SettingID) String() string {
|
||||||
|
|
|
||||||
|
|
@ -472,10 +472,13 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon
|
||||||
sc.conn.SetWriteDeadline(time.Time{})
|
sc.conn.SetWriteDeadline(time.Time{})
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.NewWriteScheduler != nil {
|
switch {
|
||||||
|
case s.NewWriteScheduler != nil:
|
||||||
sc.writeSched = s.NewWriteScheduler()
|
sc.writeSched = s.NewWriteScheduler()
|
||||||
} else {
|
case clientPriorityDisabled(http1srv):
|
||||||
sc.writeSched = newRoundRobinWriteScheduler()
|
sc.writeSched = newRoundRobinWriteScheduler()
|
||||||
|
default:
|
||||||
|
sc.writeSched = newPriorityWriteSchedulerRFC9218()
|
||||||
}
|
}
|
||||||
|
|
||||||
// These start at the RFC-specified defaults. If there is a higher
|
// These start at the RFC-specified defaults. If there is a higher
|
||||||
|
|
@ -648,6 +651,23 @@ type serverConn struct {
|
||||||
|
|
||||||
// Used by startGracefulShutdown.
|
// Used by startGracefulShutdown.
|
||||||
shutdownOnce sync.Once
|
shutdownOnce sync.Once
|
||||||
|
|
||||||
|
// Used for RFC 9218 prioritization.
|
||||||
|
hasIntermediary bool // connection is done via an intermediary / proxy
|
||||||
|
priorityAware bool // the client has sent priority signal, meaning that it is aware of it.
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *serverConn) writeSchedIgnoresRFC7540() bool {
|
||||||
|
switch sc.writeSched.(type) {
|
||||||
|
case *priorityWriteSchedulerRFC9218:
|
||||||
|
return true
|
||||||
|
case *randomWriteScheduler:
|
||||||
|
return true
|
||||||
|
case *roundRobinWriteScheduler:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sc *serverConn) maxHeaderListSize() uint32 {
|
func (sc *serverConn) maxHeaderListSize() uint32 {
|
||||||
|
|
@ -938,6 +958,9 @@ func (sc *serverConn) serve(conf http2Config) {
|
||||||
if !disableExtendedConnectProtocol {
|
if !disableExtendedConnectProtocol {
|
||||||
settings = append(settings, Setting{SettingEnableConnectProtocol, 1})
|
settings = append(settings, Setting{SettingEnableConnectProtocol, 1})
|
||||||
}
|
}
|
||||||
|
if sc.writeSchedIgnoresRFC7540() {
|
||||||
|
settings = append(settings, Setting{SettingNoRFC7540Priorities, 1})
|
||||||
|
}
|
||||||
sc.writeFrame(FrameWriteRequest{
|
sc.writeFrame(FrameWriteRequest{
|
||||||
write: settings,
|
write: settings,
|
||||||
})
|
})
|
||||||
|
|
@ -1623,6 +1646,8 @@ func (sc *serverConn) processFrame(f Frame) error {
|
||||||
// A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE
|
// A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE
|
||||||
// frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
|
// frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
|
||||||
return sc.countError("push_promise", ConnectionError(ErrCodeProtocol))
|
return sc.countError("push_promise", ConnectionError(ErrCodeProtocol))
|
||||||
|
case *PriorityUpdateFrame:
|
||||||
|
return sc.processPriorityUpdate(f)
|
||||||
default:
|
default:
|
||||||
sc.vlogf("http2: server ignoring frame: %v", f.Header())
|
sc.vlogf("http2: server ignoring frame: %v", f.Header())
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -1803,6 +1828,10 @@ func (sc *serverConn) processSetting(s Setting) error {
|
||||||
case SettingEnableConnectProtocol:
|
case SettingEnableConnectProtocol:
|
||||||
// Receipt of this parameter by a server does not
|
// Receipt of this parameter by a server does not
|
||||||
// have any impact
|
// have any impact
|
||||||
|
case SettingNoRFC7540Priorities:
|
||||||
|
if s.Val > 1 {
|
||||||
|
return ConnectionError(ErrCodeProtocol)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
// Unknown setting: "An endpoint that receives a SETTINGS
|
// Unknown setting: "An endpoint that receives a SETTINGS
|
||||||
// frame with any unknown or unsupported identifier MUST
|
// frame with any unknown or unsupported identifier MUST
|
||||||
|
|
@ -2073,14 +2102,34 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
|
||||||
if f.StreamEnded() {
|
if f.StreamEnded() {
|
||||||
initialState = stateHalfClosedRemote
|
initialState = stateHalfClosedRemote
|
||||||
}
|
}
|
||||||
st := sc.newStream(id, 0, initialState)
|
|
||||||
|
// We are handling two special cases here:
|
||||||
|
// 1. When a request is sent via an intermediary, we force priority to be
|
||||||
|
// u=3,i. This is essentially a round-robin behavior, and is done to ensure
|
||||||
|
// fairness between, for example, multiple clients using the same proxy.
|
||||||
|
// 2. Until a client has shown that it is aware of RFC 9218, we make its
|
||||||
|
// streams non-incremental by default. This is done to preserve the
|
||||||
|
// historical behavior of handling streams in a round-robin manner, rather
|
||||||
|
// than one-by-one to completion.
|
||||||
|
initialPriority := defaultRFC9218Priority(sc.priorityAware && !sc.hasIntermediary)
|
||||||
|
if _, ok := sc.writeSched.(*priorityWriteSchedulerRFC9218); ok && !sc.hasIntermediary {
|
||||||
|
headerPriority, priorityAware, hasIntermediary := f.rfc9218Priority(sc.priorityAware)
|
||||||
|
initialPriority = headerPriority
|
||||||
|
sc.hasIntermediary = hasIntermediary
|
||||||
|
if priorityAware {
|
||||||
|
sc.priorityAware = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
st := sc.newStream(id, 0, initialState, initialPriority)
|
||||||
|
|
||||||
if f.HasPriority() {
|
if f.HasPriority() {
|
||||||
if err := sc.checkPriority(f.StreamID, f.Priority); err != nil {
|
if err := sc.checkPriority(f.StreamID, f.Priority); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if !sc.writeSchedIgnoresRFC7540() {
|
||||||
sc.writeSched.AdjustStream(st.id, f.Priority)
|
sc.writeSched.AdjustStream(st.id, f.Priority)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rw, req, err := sc.newWriterAndRequest(st, f)
|
rw, req, err := sc.newWriterAndRequest(st, f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -2120,7 +2169,7 @@ func (sc *serverConn) upgradeRequest(req *http.Request) {
|
||||||
sc.serveG.check()
|
sc.serveG.check()
|
||||||
id := uint32(1)
|
id := uint32(1)
|
||||||
sc.maxClientStreamID = id
|
sc.maxClientStreamID = id
|
||||||
st := sc.newStream(id, 0, stateHalfClosedRemote)
|
st := sc.newStream(id, 0, stateHalfClosedRemote, defaultRFC9218Priority(sc.priorityAware && !sc.hasIntermediary))
|
||||||
st.reqTrailer = req.Trailer
|
st.reqTrailer = req.Trailer
|
||||||
if st.reqTrailer != nil {
|
if st.reqTrailer != nil {
|
||||||
st.trailer = make(http.Header)
|
st.trailer = make(http.Header)
|
||||||
|
|
@ -2185,11 +2234,32 @@ func (sc *serverConn) processPriority(f *PriorityFrame) error {
|
||||||
if err := sc.checkPriority(f.StreamID, f.PriorityParam); err != nil {
|
if err := sc.checkPriority(f.StreamID, f.PriorityParam); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// We need to avoid calling AdjustStream when using the RFC 9218 write
|
||||||
|
// scheduler. Otherwise, incremental's zero value in PriorityParam will
|
||||||
|
// unexpectedly make all streams non-incremental. This causes us to process
|
||||||
|
// streams one-by-one to completion rather than doing it in a round-robin
|
||||||
|
// manner (the historical behavior), which might be unexpected to users.
|
||||||
|
if sc.writeSchedIgnoresRFC7540() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
sc.writeSched.AdjustStream(f.StreamID, f.PriorityParam)
|
sc.writeSched.AdjustStream(f.StreamID, f.PriorityParam)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream {
|
func (sc *serverConn) processPriorityUpdate(f *PriorityUpdateFrame) error {
|
||||||
|
sc.priorityAware = true
|
||||||
|
if _, ok := sc.writeSched.(*priorityWriteSchedulerRFC9218); !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
p, ok := parseRFC9218Priority(f.Priority, sc.priorityAware)
|
||||||
|
if !ok {
|
||||||
|
return sc.countError("unparsable_priority_update", streamError(f.PrioritizedStreamID, ErrCodeProtocol))
|
||||||
|
}
|
||||||
|
sc.writeSched.AdjustStream(f.PrioritizedStreamID, p)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *serverConn) newStream(id, pusherID uint32, state streamState, priority PriorityParam) *stream {
|
||||||
sc.serveG.check()
|
sc.serveG.check()
|
||||||
if id == 0 {
|
if id == 0 {
|
||||||
panic("internal error: cannot create stream with id 0")
|
panic("internal error: cannot create stream with id 0")
|
||||||
|
|
@ -2212,7 +2282,7 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream
|
||||||
}
|
}
|
||||||
|
|
||||||
sc.streams[id] = st
|
sc.streams[id] = st
|
||||||
sc.writeSched.OpenStream(st.id, OpenStreamOptions{PusherID: pusherID})
|
sc.writeSched.OpenStream(st.id, OpenStreamOptions{PusherID: pusherID, priority: priority})
|
||||||
if st.isPushed() {
|
if st.isPushed() {
|
||||||
sc.curPushedStreams++
|
sc.curPushedStreams++
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -3218,7 +3288,7 @@ func (sc *serverConn) startPush(msg *startPushRequest) {
|
||||||
// transition to "half closed (remote)" after sending the initial HEADERS, but
|
// transition to "half closed (remote)" after sending the initial HEADERS, but
|
||||||
// we start in "half closed (remote)" for simplicity.
|
// we start in "half closed (remote)" for simplicity.
|
||||||
// See further comments at the definition of stateHalfClosedRemote.
|
// See further comments at the definition of stateHalfClosedRemote.
|
||||||
promised := sc.newStream(promisedID, msg.parent.id, stateHalfClosedRemote)
|
promised := sc.newStream(promisedID, msg.parent.id, stateHalfClosedRemote, defaultRFC9218Priority(sc.priorityAware && !sc.hasIntermediary))
|
||||||
rw, req, err := sc.newWriterAndRequestNoBody(promised, httpcommon.ServerRequestParam{
|
rw, req, err := sc.newWriterAndRequestNoBody(promised, httpcommon.ServerRequestParam{
|
||||||
Method: msg.method,
|
Method: msg.method,
|
||||||
Scheme: msg.url.Scheme,
|
Scheme: msg.url.Scheme,
|
||||||
|
|
|
||||||
|
|
@ -2779,6 +2779,11 @@ func (rl *clientConnReadLoop) endStreamError(cs *clientStream, err error) {
|
||||||
cs.abortStream(err)
|
cs.abortStream(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rl *clientConnReadLoop) endStreamErrorLocked(cs *clientStream, err error) {
|
||||||
|
cs.readAborted = true
|
||||||
|
cs.abortStreamLocked(err)
|
||||||
|
}
|
||||||
|
|
||||||
// Constants passed to streamByID for documentation purposes.
|
// Constants passed to streamByID for documentation purposes.
|
||||||
const (
|
const (
|
||||||
headerOrDataFrame = true
|
headerOrDataFrame = true
|
||||||
|
|
@ -2946,7 +2951,7 @@ func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error {
|
||||||
if !fl.add(int32(f.Increment)) {
|
if !fl.add(int32(f.Increment)) {
|
||||||
// For stream, the sender sends RST_STREAM with an error code of FLOW_CONTROL_ERROR
|
// For stream, the sender sends RST_STREAM with an error code of FLOW_CONTROL_ERROR
|
||||||
if cs != nil {
|
if cs != nil {
|
||||||
rl.endStreamError(cs, StreamError{
|
rl.endStreamErrorLocked(cs, StreamError{
|
||||||
StreamID: f.StreamID,
|
StreamID: f.StreamID,
|
||||||
Code: ErrCodeFlowControl,
|
Code: ErrCodeFlowControl,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,10 @@ type PriorityWriteSchedulerConfig struct {
|
||||||
// frames by following HTTP/2 priorities as described in RFC 7540 Section 5.3.
|
// frames by following HTTP/2 priorities as described in RFC 7540 Section 5.3.
|
||||||
// If cfg is nil, default options are used.
|
// If cfg is nil, default options are used.
|
||||||
func NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler {
|
func NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler {
|
||||||
|
return newPriorityWriteSchedulerRFC7540(cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newPriorityWriteSchedulerRFC7540(cfg *PriorityWriteSchedulerConfig) WriteScheduler {
|
||||||
if cfg == nil {
|
if cfg == nil {
|
||||||
// For justification of these defaults, see:
|
// For justification of these defaults, see:
|
||||||
// https://docs.google.com/document/d/1oLhNg1skaWD4_DtaoCxdSRN5erEXrH-KnLrMwEpOtFY
|
// https://docs.google.com/document/d/1oLhNg1skaWD4_DtaoCxdSRN5erEXrH-KnLrMwEpOtFY
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,15 @@ type priorityWriteSchedulerRFC9218 struct {
|
||||||
// incremental streams or not, when urgency is the same in a given Pop()
|
// incremental streams or not, when urgency is the same in a given Pop()
|
||||||
// call.
|
// call.
|
||||||
prioritizeIncremental bool
|
prioritizeIncremental bool
|
||||||
|
|
||||||
|
// priorityUpdateBuf is used to buffer the most recent PRIORITY_UPDATE we
|
||||||
|
// receive per https://www.rfc-editor.org/rfc/rfc9218.html#name-the-priority_update-frame.
|
||||||
|
priorityUpdateBuf struct {
|
||||||
|
// streamID being 0 means that the buffer is empty. This is a safe
|
||||||
|
// assumption as PRIORITY_UPDATE for stream 0 is a PROTOCOL_ERROR.
|
||||||
|
streamID uint32
|
||||||
|
priority PriorityParam
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPriorityWriteSchedulerRFC9218() WriteScheduler {
|
func newPriorityWriteSchedulerRFC9218() WriteScheduler {
|
||||||
|
|
@ -50,6 +59,10 @@ func (ws *priorityWriteSchedulerRFC9218) OpenStream(streamID uint32, opt OpenStr
|
||||||
if ws.streams[streamID].location != nil {
|
if ws.streams[streamID].location != nil {
|
||||||
panic(fmt.Errorf("stream %d already opened", streamID))
|
panic(fmt.Errorf("stream %d already opened", streamID))
|
||||||
}
|
}
|
||||||
|
if streamID == ws.priorityUpdateBuf.streamID {
|
||||||
|
ws.priorityUpdateBuf.streamID = 0
|
||||||
|
opt.priority = ws.priorityUpdateBuf.priority
|
||||||
|
}
|
||||||
q := ws.queuePool.get()
|
q := ws.queuePool.get()
|
||||||
ws.streams[streamID] = streamMetadata{
|
ws.streams[streamID] = streamMetadata{
|
||||||
location: q,
|
location: q,
|
||||||
|
|
@ -95,6 +108,8 @@ func (ws *priorityWriteSchedulerRFC9218) AdjustStream(streamID uint32, priority
|
||||||
metadata := ws.streams[streamID]
|
metadata := ws.streams[streamID]
|
||||||
q, u, i := metadata.location, metadata.priority.urgency, metadata.priority.incremental
|
q, u, i := metadata.location, metadata.priority.urgency, metadata.priority.incremental
|
||||||
if q == nil {
|
if q == nil {
|
||||||
|
ws.priorityUpdateBuf.streamID = streamID
|
||||||
|
ws.priorityUpdateBuf.priority = priority
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,665 @@
|
||||||
|
// Copyright 2025 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package httpsfv provides functionality for dealing with HTTP Structured
|
||||||
|
// Field Values.
|
||||||
|
package httpsfv
|
||||||
|
|
||||||
|
import (
|
||||||
|
"slices"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
func isLCAlpha(b byte) bool {
|
||||||
|
return (b >= 'a' && b <= 'z')
|
||||||
|
}
|
||||||
|
|
||||||
|
func isAlpha(b byte) bool {
|
||||||
|
return isLCAlpha(b) || (b >= 'A' && b <= 'Z')
|
||||||
|
}
|
||||||
|
|
||||||
|
func isDigit(b byte) bool {
|
||||||
|
return b >= '0' && b <= '9'
|
||||||
|
}
|
||||||
|
|
||||||
|
func isVChar(b byte) bool {
|
||||||
|
return b >= 0x21 && b <= 0x7e
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSP(b byte) bool {
|
||||||
|
return b == 0x20
|
||||||
|
}
|
||||||
|
|
||||||
|
func isTChar(b byte) bool {
|
||||||
|
if isAlpha(b) || isDigit(b) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return slices.Contains([]byte{'!', '#', '$', '%', '&', '\'', '*', '+', '-', '.', '^', '_', '`', '|', '~'}, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func countLeftWhitespace(s string) int {
|
||||||
|
i := 0
|
||||||
|
for _, ch := range []byte(s) {
|
||||||
|
if ch != ' ' && ch != '\t' {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc4648#section-8.
|
||||||
|
func decOctetHex(ch1, ch2 byte) (ch byte, ok bool) {
|
||||||
|
decBase16 := func(in byte) (out byte, ok bool) {
|
||||||
|
if !isDigit(in) && !(in >= 'a' && in <= 'f') {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
if isDigit(in) {
|
||||||
|
return in - '0', true
|
||||||
|
}
|
||||||
|
return in - 'a' + 10, true
|
||||||
|
}
|
||||||
|
|
||||||
|
if ch1, ok = decBase16(ch1); !ok {
|
||||||
|
return 0, ok
|
||||||
|
}
|
||||||
|
if ch2, ok = decBase16(ch2); !ok {
|
||||||
|
return 0, ok
|
||||||
|
}
|
||||||
|
return ch1<<4 | ch2, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseList parses a list from a given HTTP Structured Field Values.
|
||||||
|
//
|
||||||
|
// Given an HTTP SFV string that represents a list, it will call the given
|
||||||
|
// function using each of the members and parameters contained in the list.
|
||||||
|
// This allows the caller to extract information out of the list.
|
||||||
|
//
|
||||||
|
// This function will return once it encounters the end of the string, or
|
||||||
|
// something that is not a list. If it cannot consume the entire given
|
||||||
|
// string, the ok value returned will be false.
|
||||||
|
//
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-a-list.
|
||||||
|
func ParseList(s string, f func(member, param string)) (ok bool) {
|
||||||
|
for len(s) != 0 {
|
||||||
|
var member, param string
|
||||||
|
if len(s) != 0 && s[0] == '(' {
|
||||||
|
if member, s, ok = consumeBareInnerList(s, nil); !ok {
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if member, s, ok = consumeBareItem(s); !ok {
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if param, s, ok = consumeParameter(s, nil); !ok {
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
if f != nil {
|
||||||
|
f(member, param)
|
||||||
|
}
|
||||||
|
|
||||||
|
s = s[countLeftWhitespace(s):]
|
||||||
|
if len(s) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if s[0] != ',' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
s = s[1:]
|
||||||
|
s = s[countLeftWhitespace(s):]
|
||||||
|
if len(s) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// consumeBareInnerList consumes an inner list
|
||||||
|
// (https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-an-inner-list),
|
||||||
|
// except for the inner list's top-most parameter.
|
||||||
|
// For example, given `(a;b c;d);e`, it will consume only `(a;b c;d)`.
|
||||||
|
func consumeBareInnerList(s string, f func(bareItem, param string)) (consumed, rest string, ok bool) {
|
||||||
|
if len(s) == 0 || s[0] != '(' {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
rest = s[1:]
|
||||||
|
for len(rest) != 0 {
|
||||||
|
var bareItem, param string
|
||||||
|
rest = rest[countLeftWhitespace(rest):]
|
||||||
|
if len(rest) != 0 && rest[0] == ')' {
|
||||||
|
rest = rest[1:]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if bareItem, rest, ok = consumeBareItem(rest); !ok {
|
||||||
|
return "", s, ok
|
||||||
|
}
|
||||||
|
if param, rest, ok = consumeParameter(rest, nil); !ok {
|
||||||
|
return "", s, ok
|
||||||
|
}
|
||||||
|
if len(rest) == 0 || (rest[0] != ')' && !isSP(rest[0])) {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
if f != nil {
|
||||||
|
f(bareItem, param)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s[:len(s)-len(rest)], rest, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseBareInnerList parses a bare inner list from a given HTTP Structured
|
||||||
|
// Field Values.
|
||||||
|
//
|
||||||
|
// We define a bare inner list as an inner list
|
||||||
|
// (https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-an-inner-list),
|
||||||
|
// without the top-most parameter of the inner list. For example, given the
|
||||||
|
// inner list `(a;b c;d);e`, the bare inner list would be `(a;b c;d)`.
|
||||||
|
//
|
||||||
|
// Given an HTTP SFV string that represents a bare inner list, it will call the
|
||||||
|
// given function using each of the bare item and parameter within the bare
|
||||||
|
// inner list. This allows the caller to extract information out of the bare
|
||||||
|
// inner list.
|
||||||
|
//
|
||||||
|
// This function will return once it encounters the end of the bare inner list,
|
||||||
|
// or something that is not a bare inner list. If it cannot consume the entire
|
||||||
|
// given string, the ok value returned will be false.
|
||||||
|
func ParseBareInnerList(s string, f func(bareItem, param string)) (ok bool) {
|
||||||
|
_, rest, ok := consumeBareInnerList(s, f)
|
||||||
|
return rest == "" && ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-an-item.
|
||||||
|
func consumeItem(s string, f func(bareItem, param string)) (consumed, rest string, ok bool) {
|
||||||
|
var bareItem, param string
|
||||||
|
if bareItem, rest, ok = consumeBareItem(s); !ok {
|
||||||
|
return "", s, ok
|
||||||
|
}
|
||||||
|
if param, rest, ok = consumeParameter(rest, nil); !ok {
|
||||||
|
return "", s, ok
|
||||||
|
}
|
||||||
|
if f != nil {
|
||||||
|
f(bareItem, param)
|
||||||
|
}
|
||||||
|
return s[:len(s)-len(rest)], rest, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseItem parses an item from a given HTTP Structured Field Values.
|
||||||
|
//
|
||||||
|
// Given an HTTP SFV string that represents an item, it will call the given
|
||||||
|
// function once, with the bare item and the parameter of the item. This allows
|
||||||
|
// the caller to extract information out of the item.
|
||||||
|
//
|
||||||
|
// This function will return once it encounters the end of the string, or
|
||||||
|
// something that is not an item. If it cannot consume the entire given
|
||||||
|
// string, the ok value returned will be false.
|
||||||
|
//
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-an-item.
|
||||||
|
func ParseItem(s string, f func(bareItem, param string)) (ok bool) {
|
||||||
|
_, rest, ok := consumeItem(s, f)
|
||||||
|
return rest == "" && ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseDictionary parses a dictionary from a given HTTP Structured Field
|
||||||
|
// Values.
|
||||||
|
//
|
||||||
|
// Given an HTTP SFV string that represents a dictionary, it will call the
|
||||||
|
// given function using each of the keys, values, and parameters contained in
|
||||||
|
// the dictionary. This allows the caller to extract information out of the
|
||||||
|
// dictionary.
|
||||||
|
//
|
||||||
|
// This function will return once it encounters the end of the string, or
|
||||||
|
// something that is not a dictionary. If it cannot consume the entire given
|
||||||
|
// string, the ok value returned will be false.
|
||||||
|
//
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-a-dictionary.
|
||||||
|
func ParseDictionary(s string, f func(key, val, param string)) (ok bool) {
|
||||||
|
for len(s) != 0 {
|
||||||
|
var key, val, param string
|
||||||
|
val = "?1" // Default value for empty val is boolean true.
|
||||||
|
if key, s, ok = consumeKey(s); !ok {
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
if len(s) != 0 && s[0] == '=' {
|
||||||
|
s = s[1:]
|
||||||
|
if len(s) != 0 && s[0] == '(' {
|
||||||
|
if val, s, ok = consumeBareInnerList(s, nil); !ok {
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if val, s, ok = consumeBareItem(s); !ok {
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if param, s, ok = consumeParameter(s, nil); !ok {
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
if f != nil {
|
||||||
|
f(key, val, param)
|
||||||
|
}
|
||||||
|
s = s[countLeftWhitespace(s):]
|
||||||
|
if len(s) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if s[0] == ',' {
|
||||||
|
s = s[1:]
|
||||||
|
}
|
||||||
|
s = s[countLeftWhitespace(s):]
|
||||||
|
if len(s) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#parse-param.
|
||||||
|
func consumeParameter(s string, f func(key, val string)) (consumed, rest string, ok bool) {
|
||||||
|
rest = s
|
||||||
|
for len(rest) != 0 {
|
||||||
|
var key, val string
|
||||||
|
val = "?1" // Default value for empty val is boolean true.
|
||||||
|
if rest[0] != ';' {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
rest = rest[1:]
|
||||||
|
rest = rest[countLeftWhitespace(rest):]
|
||||||
|
key, rest, ok = consumeKey(rest)
|
||||||
|
if !ok {
|
||||||
|
return "", s, ok
|
||||||
|
}
|
||||||
|
if len(rest) != 0 && rest[0] == '=' {
|
||||||
|
rest = rest[1:]
|
||||||
|
val, rest, ok = consumeBareItem(rest)
|
||||||
|
if !ok {
|
||||||
|
return "", s, ok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if f != nil {
|
||||||
|
f(key, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s[:len(s)-len(rest)], rest, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseParameter parses a parameter from a given HTTP Structured Field Values.
|
||||||
|
//
|
||||||
|
// Given an HTTP SFV string that represents a parameter, it will call the given
|
||||||
|
// function using each of the keys and values contained in the parameter. This
|
||||||
|
// allows the caller to extract information out of the parameter.
|
||||||
|
//
|
||||||
|
// This function will return once it encounters the end of the string, or
|
||||||
|
// something that is not a parameter. If it cannot consume the entire given
|
||||||
|
// string, the ok value returned will be false.
|
||||||
|
//
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#parse-param.
|
||||||
|
func ParseParameter(s string, f func(key, val string)) (ok bool) {
|
||||||
|
_, rest, ok := consumeParameter(s, f)
|
||||||
|
return rest == "" && ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-a-key.
|
||||||
|
func consumeKey(s string) (consumed, rest string, ok bool) {
|
||||||
|
if len(s) == 0 || (!isLCAlpha(s[0]) && s[0] != '*') {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
i := 0
|
||||||
|
for _, ch := range []byte(s) {
|
||||||
|
if !isLCAlpha(ch) && !isDigit(ch) && !slices.Contains([]byte("_-.*"), ch) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return s[:i], s[i:], true
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-an-integer-or-decim.
|
||||||
|
func consumeIntegerOrDecimal(s string) (consumed, rest string, ok bool) {
|
||||||
|
var i, signOffset, periodIndex int
|
||||||
|
var isDecimal bool
|
||||||
|
if i < len(s) && s[i] == '-' {
|
||||||
|
i++
|
||||||
|
signOffset++
|
||||||
|
}
|
||||||
|
if i >= len(s) {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
if !isDigit(s[i]) {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
for i < len(s) {
|
||||||
|
ch := s[i]
|
||||||
|
if isDigit(ch) {
|
||||||
|
i++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !isDecimal && ch == '.' {
|
||||||
|
if i-signOffset > 12 {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
periodIndex = i
|
||||||
|
isDecimal = true
|
||||||
|
i++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if !isDecimal && i-signOffset > 15 {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
if isDecimal {
|
||||||
|
if i-signOffset > 16 {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
if s[i-1] == '.' {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
if i-periodIndex-1 > 3 {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s[:i], s[i:], true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseInteger parses an integer from a given HTTP Structured Field Values.
|
||||||
|
//
|
||||||
|
// The entire HTTP SFV string must consist of a valid integer. It returns the
|
||||||
|
// parsed integer and an ok boolean value, indicating success or not.
|
||||||
|
//
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-an-integer-or-decim.
|
||||||
|
func ParseInteger(s string) (parsed int64, ok bool) {
|
||||||
|
if _, rest, ok := consumeIntegerOrDecimal(s); !ok || rest != "" {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
if n, err := strconv.ParseInt(s, 10, 64); err == nil {
|
||||||
|
return n, true
|
||||||
|
}
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseDecimal parses a decimal from a given HTTP Structured Field Values.
|
||||||
|
//
|
||||||
|
// The entire HTTP SFV string must consist of a valid decimal. It returns the
|
||||||
|
// parsed decimal and an ok boolean value, indicating success or not.
|
||||||
|
//
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-an-integer-or-decim.
|
||||||
|
func ParseDecimal(s string) (parsed float64, ok bool) {
|
||||||
|
if _, rest, ok := consumeIntegerOrDecimal(s); !ok || rest != "" {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
if !strings.Contains(s, ".") {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
if n, err := strconv.ParseFloat(s, 64); err == nil {
|
||||||
|
return n, true
|
||||||
|
}
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-a-string.
|
||||||
|
func consumeString(s string) (consumed, rest string, ok bool) {
|
||||||
|
if len(s) == 0 || s[0] != '"' {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
for i := 1; i < len(s); i++ {
|
||||||
|
switch ch := s[i]; ch {
|
||||||
|
case '\\':
|
||||||
|
if i+1 >= len(s) {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
if ch = s[i]; ch != '"' && ch != '\\' {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
case '"':
|
||||||
|
return s[:i+1], s[i+1:], true
|
||||||
|
default:
|
||||||
|
if !isVChar(ch) && !isSP(ch) {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseString parses a Go string from a given HTTP Structured Field Values.
|
||||||
|
//
|
||||||
|
// The entire HTTP SFV string must consist of a valid string. It returns the
|
||||||
|
// parsed string and an ok boolean value, indicating success or not.
|
||||||
|
//
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-a-string.
|
||||||
|
func ParseString(s string) (parsed string, ok bool) {
|
||||||
|
if _, rest, ok := consumeString(s); !ok || rest != "" {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
return s[1 : len(s)-1], true
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-a-token
|
||||||
|
func consumeToken(s string) (consumed, rest string, ok bool) {
|
||||||
|
if len(s) == 0 || (!isAlpha(s[0]) && s[0] != '*') {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
i := 0
|
||||||
|
for _, ch := range []byte(s) {
|
||||||
|
if !isTChar(ch) && !slices.Contains([]byte(":/"), ch) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return s[:i], s[i:], true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseToken parses a token from a given HTTP Structured Field Values.
|
||||||
|
//
|
||||||
|
// The entire HTTP SFV string must consist of a valid token. It returns the
|
||||||
|
// parsed token and an ok boolean value, indicating success or not.
|
||||||
|
//
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-a-token
|
||||||
|
func ParseToken(s string) (parsed string, ok bool) {
|
||||||
|
if _, rest, ok := consumeToken(s); !ok || rest != "" {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
return s, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-a-byte-sequence.
|
||||||
|
func consumeByteSequence(s string) (consumed, rest string, ok bool) {
|
||||||
|
if len(s) == 0 || s[0] != ':' {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
for i := 1; i < len(s); i++ {
|
||||||
|
if ch := s[i]; ch == ':' {
|
||||||
|
return s[:i+1], s[i+1:], true
|
||||||
|
}
|
||||||
|
if ch := s[i]; !isAlpha(ch) && !isDigit(ch) && !slices.Contains([]byte("+/="), ch) {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseByteSequence parses a byte sequence from a given HTTP Structured Field
|
||||||
|
// Values.
|
||||||
|
//
|
||||||
|
// The entire HTTP SFV string must consist of a valid byte sequence. It returns
|
||||||
|
// the parsed byte sequence and an ok boolean value, indicating success or not.
|
||||||
|
//
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-a-byte-sequence.
|
||||||
|
func ParseByteSequence(s string) (parsed []byte, ok bool) {
|
||||||
|
if _, rest, ok := consumeByteSequence(s); !ok || rest != "" {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return []byte(s[1 : len(s)-1]), true
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-a-boolean.
|
||||||
|
func consumeBoolean(s string) (consumed, rest string, ok bool) {
|
||||||
|
if len(s) >= 2 && (s[:2] == "?0" || s[:2] == "?1") {
|
||||||
|
return s[:2], s[2:], true
|
||||||
|
}
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseBoolean parses a boolean from a given HTTP Structured Field Values.
|
||||||
|
//
|
||||||
|
// The entire HTTP SFV string must consist of a valid boolean. It returns the
|
||||||
|
// parsed boolean and an ok boolean value, indicating success or not.
|
||||||
|
//
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-a-boolean.
|
||||||
|
func ParseBoolean(s string) (parsed bool, ok bool) {
|
||||||
|
if _, rest, ok := consumeBoolean(s); !ok || rest != "" {
|
||||||
|
return false, false
|
||||||
|
}
|
||||||
|
return s == "?1", true
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-a-date.
|
||||||
|
func consumeDate(s string) (consumed, rest string, ok bool) {
|
||||||
|
if len(s) == 0 || s[0] != '@' {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
if _, rest, ok = consumeIntegerOrDecimal(s[1:]); !ok {
|
||||||
|
return "", s, ok
|
||||||
|
}
|
||||||
|
consumed = s[:len(s)-len(rest)]
|
||||||
|
if slices.Contains([]byte(consumed), '.') {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
return consumed, rest, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseDate parses a date from a given HTTP Structured Field Values.
|
||||||
|
//
|
||||||
|
// The entire HTTP SFV string must consist of a valid date. It returns the
|
||||||
|
// parsed date and an ok boolean value, indicating success or not.
|
||||||
|
//
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-a-date.
|
||||||
|
func ParseDate(s string) (parsed time.Time, ok bool) {
|
||||||
|
if _, rest, ok := consumeDate(s); !ok || rest != "" {
|
||||||
|
return time.Time{}, false
|
||||||
|
}
|
||||||
|
if n, ok := ParseInteger(s[1:]); !ok {
|
||||||
|
return time.Time{}, false
|
||||||
|
} else {
|
||||||
|
return time.Unix(n, 0), true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-a-display-string.
|
||||||
|
func consumeDisplayString(s string) (consumed, rest string, ok bool) {
|
||||||
|
// To prevent excessive allocation, especially when input is large, we
|
||||||
|
// maintain a buffer of 4 bytes to keep track of the last rune we
|
||||||
|
// encounter. This way, we can validate that the display string conforms to
|
||||||
|
// UTF-8 without actually building the whole string.
|
||||||
|
var lastRune [4]byte
|
||||||
|
var runeLen int
|
||||||
|
isPartOfValidRune := func(ch byte) bool {
|
||||||
|
lastRune[runeLen] = ch
|
||||||
|
runeLen++
|
||||||
|
if utf8.FullRune(lastRune[:runeLen]) {
|
||||||
|
r, s := utf8.DecodeRune(lastRune[:runeLen])
|
||||||
|
if r == utf8.RuneError {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
copy(lastRune[:], lastRune[s:runeLen])
|
||||||
|
runeLen -= s
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return runeLen <= 4
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(s) <= 1 || s[:2] != `%"` {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
i := 2
|
||||||
|
for i < len(s) {
|
||||||
|
ch := s[i]
|
||||||
|
if !isVChar(ch) && !isSP(ch) {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
switch ch {
|
||||||
|
case '"':
|
||||||
|
if runeLen > 0 {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
return s[:i+1], s[i+1:], true
|
||||||
|
case '%':
|
||||||
|
if i+2 >= len(s) {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
if ch, ok = decOctetHex(s[i+1], s[i+2]); !ok {
|
||||||
|
return "", s, ok
|
||||||
|
}
|
||||||
|
if ok = isPartOfValidRune(ch); !ok {
|
||||||
|
return "", s, ok
|
||||||
|
}
|
||||||
|
i += 3
|
||||||
|
default:
|
||||||
|
if ok = isPartOfValidRune(ch); !ok {
|
||||||
|
return "", s, ok
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseDisplayString parses a display string from a given HTTP Structured
|
||||||
|
// Field Values.
|
||||||
|
//
|
||||||
|
// The entire HTTP SFV string must consist of a valid display string. It
|
||||||
|
// returns the parsed display string and an ok boolean value, indicating
|
||||||
|
// success or not.
|
||||||
|
//
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#name-parsing-a-display-string.
|
||||||
|
func ParseDisplayString(s string) (parsed string, ok bool) {
|
||||||
|
if _, rest, ok := consumeDisplayString(s); !ok || rest != "" {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
// consumeDisplayString() already validates that we have a valid display
|
||||||
|
// string. Therefore, we can just construct the display string, without
|
||||||
|
// validating it again.
|
||||||
|
s = s[2 : len(s)-1]
|
||||||
|
var b strings.Builder
|
||||||
|
for i := 0; i < len(s); {
|
||||||
|
if s[i] == '%' {
|
||||||
|
decoded, _ := decOctetHex(s[i+1], s[i+2])
|
||||||
|
b.WriteByte(decoded)
|
||||||
|
i += 3
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
b.WriteByte(s[i])
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return b.String(), true
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc9651.html#parse-bare-item.
|
||||||
|
func consumeBareItem(s string) (consumed, rest string, ok bool) {
|
||||||
|
if len(s) == 0 {
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
ch := s[0]
|
||||||
|
switch {
|
||||||
|
case ch == '-' || isDigit(ch):
|
||||||
|
return consumeIntegerOrDecimal(s)
|
||||||
|
case ch == '"':
|
||||||
|
return consumeString(s)
|
||||||
|
case ch == '*' || isAlpha(ch):
|
||||||
|
return consumeToken(s)
|
||||||
|
case ch == ':':
|
||||||
|
return consumeByteSequence(s)
|
||||||
|
case ch == '?':
|
||||||
|
return consumeBoolean(s)
|
||||||
|
case ch == '@':
|
||||||
|
return consumeDate(s)
|
||||||
|
case ch == '%':
|
||||||
|
return consumeDisplayString(s)
|
||||||
|
default:
|
||||||
|
return "", s, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,9 +6,7 @@
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
import (
|
import "unsafe"
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ioctl itself should not be exposed directly, but additional get/set
|
// ioctl itself should not be exposed directly, but additional get/set
|
||||||
// functions for specific types are permissible.
|
// functions for specific types are permissible.
|
||||||
|
|
@ -28,6 +26,13 @@ func IoctlSetPointerInt(fd int, req int, value int) error {
|
||||||
return ioctlPtr(fd, req, unsafe.Pointer(&v))
|
return ioctlPtr(fd, req, unsafe.Pointer(&v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IoctlSetString performs an ioctl operation which sets a string value
|
||||||
|
// on fd, using the specified request number.
|
||||||
|
func IoctlSetString(fd int, req int, value string) error {
|
||||||
|
bs := append([]byte(value), 0)
|
||||||
|
return ioctlPtr(fd, req, unsafe.Pointer(&bs[0]))
|
||||||
|
}
|
||||||
|
|
||||||
// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
|
// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
|
||||||
//
|
//
|
||||||
// To change fd's window size, the req argument should be TIOCSWINSZ.
|
// To change fd's window size, the req argument should be TIOCSWINSZ.
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,7 @@
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
import (
|
import "unsafe"
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ioctl itself should not be exposed directly, but additional get/set
|
// ioctl itself should not be exposed directly, but additional get/set
|
||||||
// functions for specific types are permissible.
|
// functions for specific types are permissible.
|
||||||
|
|
@ -28,6 +26,13 @@ func IoctlSetPointerInt(fd int, req uint, value int) error {
|
||||||
return ioctlPtr(fd, req, unsafe.Pointer(&v))
|
return ioctlPtr(fd, req, unsafe.Pointer(&v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IoctlSetString performs an ioctl operation which sets a string value
|
||||||
|
// on fd, using the specified request number.
|
||||||
|
func IoctlSetString(fd int, req uint, value string) error {
|
||||||
|
bs := append([]byte(value), 0)
|
||||||
|
return ioctlPtr(fd, req, unsafe.Pointer(&bs[0]))
|
||||||
|
}
|
||||||
|
|
||||||
// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
|
// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
|
||||||
//
|
//
|
||||||
// To change fd's window size, the req argument should be TIOCSWINSZ.
|
// To change fd's window size, the req argument should be TIOCSWINSZ.
|
||||||
|
|
|
||||||
|
|
@ -1052,14 +1052,6 @@ func IoctlSetIntRetInt(fd int, req int, arg int) (int, error) {
|
||||||
return ioctlRet(fd, req, uintptr(arg))
|
return ioctlRet(fd, req, uintptr(arg))
|
||||||
}
|
}
|
||||||
|
|
||||||
func IoctlSetString(fd int, req int, val string) error {
|
|
||||||
bs := make([]byte, len(val)+1)
|
|
||||||
copy(bs[:len(bs)-1], val)
|
|
||||||
err := ioctlPtr(fd, req, unsafe.Pointer(&bs[0]))
|
|
||||||
runtime.KeepAlive(&bs[0])
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lifreq Helpers
|
// Lifreq Helpers
|
||||||
|
|
||||||
func (l *Lifreq) SetName(name string) error {
|
func (l *Lifreq) SetName(name string) error {
|
||||||
|
|
|
||||||
|
|
@ -367,7 +367,9 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
|
||||||
iov[0].SetLen(len(p))
|
iov[0].SetLen(len(p))
|
||||||
}
|
}
|
||||||
var rsa RawSockaddrAny
|
var rsa RawSockaddrAny
|
||||||
n, oobn, recvflags, err = recvmsgRaw(fd, iov[:], oob, flags, &rsa)
|
if n, oobn, recvflags, err = recvmsgRaw(fd, iov[:], oob, flags, &rsa); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
// source address is only specified if the socket is unconnected
|
// source address is only specified if the socket is unconnected
|
||||||
if rsa.Addr.Family != AF_UNSPEC {
|
if rsa.Addr.Family != AF_UNSPEC {
|
||||||
from, err = anyToSockaddr(fd, &rsa)
|
from, err = anyToSockaddr(fd, &rsa)
|
||||||
|
|
@ -389,8 +391,10 @@ func RecvmsgBuffers(fd int, buffers [][]byte, oob []byte, flags int) (n, oobn in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var rsa RawSockaddrAny
|
var rsa RawSockaddrAny
|
||||||
n, oobn, recvflags, err = recvmsgRaw(fd, iov, oob, flags, &rsa)
|
if n, oobn, recvflags, err = recvmsgRaw(fd, iov, oob, flags, &rsa); err != nil {
|
||||||
if err == nil && rsa.Addr.Family != AF_UNSPEC {
|
return
|
||||||
|
}
|
||||||
|
if rsa.Addr.Family != AF_UNSPEC {
|
||||||
from, err = anyToSockaddr(fd, &rsa)
|
from, err = anyToSockaddr(fd, &rsa)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -900,6 +900,7 @@ const socket_error = uintptr(^uint32(0))
|
||||||
//sys NotifyRouteChange2(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyRouteChange2
|
//sys NotifyRouteChange2(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyRouteChange2
|
||||||
//sys NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyUnicastIpAddressChange
|
//sys NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyUnicastIpAddressChange
|
||||||
//sys CancelMibChangeNotify2(notificationHandle Handle) (errcode error) = iphlpapi.CancelMibChangeNotify2
|
//sys CancelMibChangeNotify2(notificationHandle Handle) (errcode error) = iphlpapi.CancelMibChangeNotify2
|
||||||
|
//sys IsProcessorFeaturePresent(ProcessorFeature uint32) (ret bool) = kernel32.IsProcessorFeaturePresent
|
||||||
|
|
||||||
// For testing: clients can set this flag to force
|
// For testing: clients can set this flag to force
|
||||||
// creation of IPv6 sockets to return EAFNOSUPPORT.
|
// creation of IPv6 sockets to return EAFNOSUPPORT.
|
||||||
|
|
|
||||||
|
|
@ -3938,3 +3938,88 @@ const (
|
||||||
MOUSE_EVENT = 0x0002
|
MOUSE_EVENT = 0x0002
|
||||||
WINDOW_BUFFER_SIZE_EVENT = 0x0004
|
WINDOW_BUFFER_SIZE_EVENT = 0x0004
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// The processor features to be tested for IsProcessorFeaturePresent, see
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent
|
||||||
|
const (
|
||||||
|
PF_ARM_64BIT_LOADSTORE_ATOMIC = 25
|
||||||
|
PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE = 24
|
||||||
|
PF_ARM_EXTERNAL_CACHE_AVAILABLE = 26
|
||||||
|
PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE = 27
|
||||||
|
PF_ARM_VFP_32_REGISTERS_AVAILABLE = 18
|
||||||
|
PF_3DNOW_INSTRUCTIONS_AVAILABLE = 7
|
||||||
|
PF_CHANNELS_ENABLED = 16
|
||||||
|
PF_COMPARE_EXCHANGE_DOUBLE = 2
|
||||||
|
PF_COMPARE_EXCHANGE128 = 14
|
||||||
|
PF_COMPARE64_EXCHANGE128 = 15
|
||||||
|
PF_FASTFAIL_AVAILABLE = 23
|
||||||
|
PF_FLOATING_POINT_EMULATED = 1
|
||||||
|
PF_FLOATING_POINT_PRECISION_ERRATA = 0
|
||||||
|
PF_MMX_INSTRUCTIONS_AVAILABLE = 3
|
||||||
|
PF_NX_ENABLED = 12
|
||||||
|
PF_PAE_ENABLED = 9
|
||||||
|
PF_RDTSC_INSTRUCTION_AVAILABLE = 8
|
||||||
|
PF_RDWRFSGSBASE_AVAILABLE = 22
|
||||||
|
PF_SECOND_LEVEL_ADDRESS_TRANSLATION = 20
|
||||||
|
PF_SSE3_INSTRUCTIONS_AVAILABLE = 13
|
||||||
|
PF_SSSE3_INSTRUCTIONS_AVAILABLE = 36
|
||||||
|
PF_SSE4_1_INSTRUCTIONS_AVAILABLE = 37
|
||||||
|
PF_SSE4_2_INSTRUCTIONS_AVAILABLE = 38
|
||||||
|
PF_AVX_INSTRUCTIONS_AVAILABLE = 39
|
||||||
|
PF_AVX2_INSTRUCTIONS_AVAILABLE = 40
|
||||||
|
PF_AVX512F_INSTRUCTIONS_AVAILABLE = 41
|
||||||
|
PF_VIRT_FIRMWARE_ENABLED = 21
|
||||||
|
PF_XMMI_INSTRUCTIONS_AVAILABLE = 6
|
||||||
|
PF_XMMI64_INSTRUCTIONS_AVAILABLE = 10
|
||||||
|
PF_XSAVE_ENABLED = 17
|
||||||
|
PF_ARM_V8_INSTRUCTIONS_AVAILABLE = 29
|
||||||
|
PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE = 30
|
||||||
|
PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE = 31
|
||||||
|
PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE = 34
|
||||||
|
PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE = 43
|
||||||
|
PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE = 44
|
||||||
|
PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE = 45
|
||||||
|
PF_ARM_SVE_INSTRUCTIONS_AVAILABLE = 46
|
||||||
|
PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE = 47
|
||||||
|
PF_ARM_SVE2_1_INSTRUCTIONS_AVAILABLE = 48
|
||||||
|
PF_ARM_SVE_AES_INSTRUCTIONS_AVAILABLE = 49
|
||||||
|
PF_ARM_SVE_PMULL128_INSTRUCTIONS_AVAILABLE = 50
|
||||||
|
PF_ARM_SVE_BITPERM_INSTRUCTIONS_AVAILABLE = 51
|
||||||
|
PF_ARM_SVE_BF16_INSTRUCTIONS_AVAILABLE = 52
|
||||||
|
PF_ARM_SVE_EBF16_INSTRUCTIONS_AVAILABLE = 53
|
||||||
|
PF_ARM_SVE_B16B16_INSTRUCTIONS_AVAILABLE = 54
|
||||||
|
PF_ARM_SVE_SHA3_INSTRUCTIONS_AVAILABLE = 55
|
||||||
|
PF_ARM_SVE_SM4_INSTRUCTIONS_AVAILABLE = 56
|
||||||
|
PF_ARM_SVE_I8MM_INSTRUCTIONS_AVAILABLE = 57
|
||||||
|
PF_ARM_SVE_F32MM_INSTRUCTIONS_AVAILABLE = 58
|
||||||
|
PF_ARM_SVE_F64MM_INSTRUCTIONS_AVAILABLE = 59
|
||||||
|
PF_BMI2_INSTRUCTIONS_AVAILABLE = 60
|
||||||
|
PF_MOVDIR64B_INSTRUCTION_AVAILABLE = 61
|
||||||
|
PF_ARM_LSE2_AVAILABLE = 62
|
||||||
|
PF_ARM_SHA3_INSTRUCTIONS_AVAILABLE = 64
|
||||||
|
PF_ARM_SHA512_INSTRUCTIONS_AVAILABLE = 65
|
||||||
|
PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE = 66
|
||||||
|
PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE = 67
|
||||||
|
PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE = 68
|
||||||
|
PF_ARM_V86_EBF16_INSTRUCTIONS_AVAILABLE = 69
|
||||||
|
PF_ARM_SME_INSTRUCTIONS_AVAILABLE = 70
|
||||||
|
PF_ARM_SME2_INSTRUCTIONS_AVAILABLE = 71
|
||||||
|
PF_ARM_SME2_1_INSTRUCTIONS_AVAILABLE = 72
|
||||||
|
PF_ARM_SME2_2_INSTRUCTIONS_AVAILABLE = 73
|
||||||
|
PF_ARM_SME_AES_INSTRUCTIONS_AVAILABLE = 74
|
||||||
|
PF_ARM_SME_SBITPERM_INSTRUCTIONS_AVAILABLE = 75
|
||||||
|
PF_ARM_SME_SF8MM4_INSTRUCTIONS_AVAILABLE = 76
|
||||||
|
PF_ARM_SME_SF8MM8_INSTRUCTIONS_AVAILABLE = 77
|
||||||
|
PF_ARM_SME_SF8DP2_INSTRUCTIONS_AVAILABLE = 78
|
||||||
|
PF_ARM_SME_SF8DP4_INSTRUCTIONS_AVAILABLE = 79
|
||||||
|
PF_ARM_SME_SF8FMA_INSTRUCTIONS_AVAILABLE = 80
|
||||||
|
PF_ARM_SME_F8F32_INSTRUCTIONS_AVAILABLE = 81
|
||||||
|
PF_ARM_SME_F8F16_INSTRUCTIONS_AVAILABLE = 82
|
||||||
|
PF_ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE = 83
|
||||||
|
PF_ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE = 84
|
||||||
|
PF_ARM_SME_F64F64_INSTRUCTIONS_AVAILABLE = 85
|
||||||
|
PF_ARM_SME_I16I64_INSTRUCTIONS_AVAILABLE = 86
|
||||||
|
PF_ARM_SME_LUTv2_INSTRUCTIONS_AVAILABLE = 87
|
||||||
|
PF_ARM_SME_FA64_INSTRUCTIONS_AVAILABLE = 88
|
||||||
|
PF_UMONITOR_INSTRUCTION_AVAILABLE = 89
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -320,6 +320,7 @@ var (
|
||||||
procGetVolumePathNamesForVolumeNameW = modkernel32.NewProc("GetVolumePathNamesForVolumeNameW")
|
procGetVolumePathNamesForVolumeNameW = modkernel32.NewProc("GetVolumePathNamesForVolumeNameW")
|
||||||
procGetWindowsDirectoryW = modkernel32.NewProc("GetWindowsDirectoryW")
|
procGetWindowsDirectoryW = modkernel32.NewProc("GetWindowsDirectoryW")
|
||||||
procInitializeProcThreadAttributeList = modkernel32.NewProc("InitializeProcThreadAttributeList")
|
procInitializeProcThreadAttributeList = modkernel32.NewProc("InitializeProcThreadAttributeList")
|
||||||
|
procIsProcessorFeaturePresent = modkernel32.NewProc("IsProcessorFeaturePresent")
|
||||||
procIsWow64Process = modkernel32.NewProc("IsWow64Process")
|
procIsWow64Process = modkernel32.NewProc("IsWow64Process")
|
||||||
procIsWow64Process2 = modkernel32.NewProc("IsWow64Process2")
|
procIsWow64Process2 = modkernel32.NewProc("IsWow64Process2")
|
||||||
procLoadLibraryExW = modkernel32.NewProc("LoadLibraryExW")
|
procLoadLibraryExW = modkernel32.NewProc("LoadLibraryExW")
|
||||||
|
|
@ -2786,6 +2787,12 @@ func initializeProcThreadAttributeList(attrlist *ProcThreadAttributeList, attrco
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsProcessorFeaturePresent(ProcessorFeature uint32) (ret bool) {
|
||||||
|
r0, _, _ := syscall.SyscallN(procIsProcessorFeaturePresent.Addr(), uintptr(ProcessorFeature))
|
||||||
|
ret = r0 != 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func IsWow64Process(handle Handle, isWow64 *bool) (err error) {
|
func IsWow64Process(handle Handle, isWow64 *bool) (err error) {
|
||||||
var _p0 uint32
|
var _p0 uint32
|
||||||
if *isWow64 {
|
if *isWow64 {
|
||||||
|
|
|
||||||
|
|
@ -334,3 +334,7 @@ func (t *Transformer) advanceString(s string) (n int, ok bool) {
|
||||||
}
|
}
|
||||||
return n, true
|
return n, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Transformer) isFinal() bool {
|
||||||
|
return t.state == ruleLTRFinal || t.state == ruleRTLFinal || t.state == ruleInitial
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
//go:build go1.10
|
|
||||||
|
|
||||||
package bidirule
|
|
||||||
|
|
||||||
func (t *Transformer) isFinal() bool {
|
|
||||||
return t.state == ruleLTRFinal || t.state == ruleRTLFinal || t.state == ruleInitial
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
//go:build !go1.10
|
|
||||||
|
|
||||||
package bidirule
|
|
||||||
|
|
||||||
func (t *Transformer) isFinal() bool {
|
|
||||||
if !t.isRTL() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return t.state == ruleLTRFinal || t.state == ruleRTLFinal || t.state == ruleInitial
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||||
|
|
||||||
//go:build go1.21
|
//go:build !go1.27
|
||||||
|
|
||||||
package bidi
|
package bidi
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -13,15 +13,18 @@ import "encoding/binary"
|
||||||
// a rune to a uint16. The values take two forms. For v >= 0x8000:
|
// a rune to a uint16. The values take two forms. For v >= 0x8000:
|
||||||
// bits
|
// bits
|
||||||
// 15: 1 (inverse of NFD_QC bit of qcInfo)
|
// 15: 1 (inverse of NFD_QC bit of qcInfo)
|
||||||
// 13..7: qcInfo (see below). isYesD is always true (no decomposition).
|
// 12..7: qcInfo (see below). isYesD is always true (no decomposition).
|
||||||
// 6..0: ccc (compressed CCC value).
|
// 6..0: ccc (compressed CCC value).
|
||||||
// For v < 0x8000, the respective rune has a decomposition and v is an index
|
// For v < 0x8000, the respective rune has a decomposition and v is an index
|
||||||
// into a byte array of UTF-8 decomposition sequences and additional info and
|
// into a byte array of UTF-8 decomposition sequences and additional info and
|
||||||
// has the form:
|
// has the form:
|
||||||
// <header> <decomp_byte>* [<tccc> [<lccc>]]
|
// <header> <decomp_byte>* [<tccc> [<lccc>]]
|
||||||
// The header contains the number of bytes in the decomposition (excluding this
|
// The header contains the number of bytes in the decomposition (excluding this
|
||||||
// length byte). The two most significant bits of this length byte correspond
|
// length byte), with 33 mapped to 31 to fit in 5 bits.
|
||||||
// to bit 5 and 4 of qcInfo (see below). The byte sequence itself starts at v+1.
|
// (If any 31- or 32-byte decompositions come along, we could switch to using
|
||||||
|
// use a general lookup table as long as there are at most 32 distinct lengths.)
|
||||||
|
// The three most significant bits of this length byte correspond
|
||||||
|
// to bit 5, 4, and 3 of qcInfo (see below). The byte sequence itself starts at v+1.
|
||||||
// The byte sequence is followed by a trailing and leading CCC if the values
|
// The byte sequence is followed by a trailing and leading CCC if the values
|
||||||
// for these are not zero. The value of v determines which ccc are appended
|
// for these are not zero. The value of v determines which ccc are appended
|
||||||
// to the sequences. For v < firstCCC, there are none, for v >= firstCCC,
|
// to the sequences. For v < firstCCC, there are none, for v >= firstCCC,
|
||||||
|
|
@ -32,8 +35,8 @@ import "encoding/binary"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
qcInfoMask = 0x3F // to clear all but the relevant bits in a qcInfo
|
qcInfoMask = 0x3F // to clear all but the relevant bits in a qcInfo
|
||||||
headerLenMask = 0x3F // extract the length value from the header byte
|
headerLenMask = 0x1F // extract the length value from the header byte (31 => 33)
|
||||||
headerFlagsMask = 0xC0 // extract the qcInfo bits from the header byte
|
headerFlagsMask = 0xE0 // extract the qcInfo bits from the header byte
|
||||||
)
|
)
|
||||||
|
|
||||||
// Properties provides access to normalization properties of a rune.
|
// Properties provides access to normalization properties of a rune.
|
||||||
|
|
@ -109,14 +112,14 @@ func (p Properties) BoundaryAfter() bool {
|
||||||
return p.isInert()
|
return p.isInert()
|
||||||
}
|
}
|
||||||
|
|
||||||
// We pack quick check data in 4 bits:
|
// We pack quick check data in 6 bits:
|
||||||
//
|
//
|
||||||
// 5: Combines forward (0 == false, 1 == true)
|
// 5: Combines forward (0 == false, 1 == true)
|
||||||
// 4..3: NFC_QC Yes(00), No (10), or Maybe (11)
|
// 4..3: NFC_QC Yes(00), No (10), or Maybe (11)
|
||||||
// 2: NFD_QC Yes (0) or No (1). No also means there is a decomposition.
|
// 2: NFD_QC Yes (0) or No (1). No also means there is a decomposition.
|
||||||
// 1..0: Number of trailing non-starters.
|
// 1..0: Number of trailing non-starters.
|
||||||
//
|
//
|
||||||
// When all 4 bits are zero, the character is inert, meaning it is never
|
// When all 6 bits are zero, the character is inert, meaning it is never
|
||||||
// influenced by normalization.
|
// influenced by normalization.
|
||||||
type qcInfo uint8
|
type qcInfo uint8
|
||||||
|
|
||||||
|
|
@ -152,6 +155,9 @@ func (p Properties) Decomposition() []byte {
|
||||||
}
|
}
|
||||||
i := p.index
|
i := p.index
|
||||||
n := decomps[i] & headerLenMask
|
n := decomps[i] & headerLenMask
|
||||||
|
if n == 31 {
|
||||||
|
n = 33
|
||||||
|
}
|
||||||
i++
|
i++
|
||||||
return decomps[i : i+uint16(n)]
|
return decomps[i : i+uint16(n)]
|
||||||
}
|
}
|
||||||
|
|
@ -260,7 +266,11 @@ func compInfo(v uint16, sz int) Properties {
|
||||||
f := (qcInfo(h&headerFlagsMask) >> 2) | 0x4
|
f := (qcInfo(h&headerFlagsMask) >> 2) | 0x4
|
||||||
p := Properties{size: uint8(sz), flags: f, index: v}
|
p := Properties{size: uint8(sz), flags: f, index: v}
|
||||||
if v >= firstCCC {
|
if v >= firstCCC {
|
||||||
v += uint16(h&headerLenMask) + 1
|
n := uint16(h & headerLenMask)
|
||||||
|
if n == 31 {
|
||||||
|
n = 33
|
||||||
|
}
|
||||||
|
v += n + 1
|
||||||
c := decomps[v]
|
c := decomps[v]
|
||||||
p.tccc = c >> 2
|
p.tccc = c >> 2
|
||||||
p.flags |= qcInfo(c & 0x3)
|
p.flags |= qcInfo(c & 0x3)
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
|
"reflect"
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -149,7 +150,7 @@ func AddNamedImport(fset *token.FileSet, f *ast.File, name, path string) (added
|
||||||
if newImport.Name != nil {
|
if newImport.Name != nil {
|
||||||
newImport.Name.NamePos = pos
|
newImport.Name.NamePos = pos
|
||||||
}
|
}
|
||||||
newImport.Path.ValuePos = pos
|
updateBasicLitPos(newImport.Path, pos)
|
||||||
newImport.EndPos = pos
|
newImport.EndPos = pos
|
||||||
|
|
||||||
// Clean up parens. impDecl contains at least one spec.
|
// Clean up parens. impDecl contains at least one spec.
|
||||||
|
|
@ -184,7 +185,7 @@ func AddNamedImport(fset *token.FileSet, f *ast.File, name, path string) (added
|
||||||
first.Lparen = first.Pos()
|
first.Lparen = first.Pos()
|
||||||
// Move the imports of the other import declaration to the first one.
|
// Move the imports of the other import declaration to the first one.
|
||||||
for _, spec := range gen.Specs {
|
for _, spec := range gen.Specs {
|
||||||
spec.(*ast.ImportSpec).Path.ValuePos = first.Pos()
|
updateBasicLitPos(spec.(*ast.ImportSpec).Path, first.Pos())
|
||||||
first.Specs = append(first.Specs, spec)
|
first.Specs = append(first.Specs, spec)
|
||||||
}
|
}
|
||||||
f.Decls = slices.Delete(f.Decls, i, i+1)
|
f.Decls = slices.Delete(f.Decls, i, i+1)
|
||||||
|
|
@ -470,3 +471,17 @@ func Imports(fset *token.FileSet, f *ast.File) [][]*ast.ImportSpec {
|
||||||
|
|
||||||
return groups
|
return groups
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// updateBasicLitPos updates lit.Pos,
|
||||||
|
// ensuring that lit.End (if set) is displaced by the same amount.
|
||||||
|
// (See https://go.dev/issue/76395.)
|
||||||
|
func updateBasicLitPos(lit *ast.BasicLit, pos token.Pos) {
|
||||||
|
len := lit.End() - lit.Pos()
|
||||||
|
lit.ValuePos = pos
|
||||||
|
// TODO(adonovan): after go1.26, simplify to:
|
||||||
|
// lit.ValueEnd = pos + len
|
||||||
|
v := reflect.ValueOf(lit).Elem().FieldByName("ValueEnd")
|
||||||
|
if v.IsValid() && v.Int() != 0 {
|
||||||
|
v.SetInt(int64(pos + len))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"iter"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/tools/internal/event/label"
|
"golang.org/x/tools/internal/event/label"
|
||||||
|
|
@ -34,11 +35,9 @@ func (ev Event) Format(f fmt.State, r rune) {
|
||||||
if !ev.at.IsZero() {
|
if !ev.at.IsZero() {
|
||||||
fmt.Fprint(f, ev.at.Format("2006/01/02 15:04:05 "))
|
fmt.Fprint(f, ev.at.Format("2006/01/02 15:04:05 "))
|
||||||
}
|
}
|
||||||
for index := 0; ev.Valid(index); index++ {
|
for l := range ev.Labels() {
|
||||||
if l := ev.Label(index); l.Valid() {
|
|
||||||
fmt.Fprintf(f, "\n\t%v", l)
|
fmt.Fprintf(f, "\n\t%v", l)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ev Event) Valid(index int) bool {
|
func (ev Event) Valid(index int) bool {
|
||||||
|
|
@ -52,6 +51,22 @@ func (ev Event) Label(index int) label.Label {
|
||||||
return ev.dynamic[index-len(ev.static)]
|
return ev.dynamic[index-len(ev.static)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Labels returns an iterator over the event's valid labels.
|
||||||
|
func (ev Event) Labels() iter.Seq[label.Label] {
|
||||||
|
return func(yield func(label.Label) bool) {
|
||||||
|
for _, l := range ev.static {
|
||||||
|
if l.Valid() && !yield(l) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, l := range ev.dynamic {
|
||||||
|
if l.Valid() && !yield(l) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (ev Event) Find(key label.Key) label.Label {
|
func (ev Event) Find(key label.Key) label.Label {
|
||||||
for _, l := range ev.static {
|
for _, l := range ev.static {
|
||||||
if l.Key() == key {
|
if l.Key() == key {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"golang.org/x/tools/internal/event/label"
|
"golang.org/x/tools/internal/event/label"
|
||||||
)
|
)
|
||||||
|
|
@ -17,23 +16,21 @@ import (
|
||||||
// It may return a modified context and event.
|
// It may return a modified context and event.
|
||||||
type Exporter func(context.Context, Event, label.Map) context.Context
|
type Exporter func(context.Context, Event, label.Map) context.Context
|
||||||
|
|
||||||
var (
|
var exporter atomic.Pointer[Exporter]
|
||||||
exporter unsafe.Pointer
|
|
||||||
)
|
|
||||||
|
|
||||||
// SetExporter sets the global exporter function that handles all events.
|
// SetExporter sets the global exporter function that handles all events.
|
||||||
// The exporter is called synchronously from the event call site, so it should
|
// The exporter is called synchronously from the event call site, so it should
|
||||||
// return quickly so as not to hold up user code.
|
// return quickly so as not to hold up user code.
|
||||||
func SetExporter(e Exporter) {
|
func SetExporter(e Exporter) {
|
||||||
p := unsafe.Pointer(&e)
|
|
||||||
if e == nil {
|
if e == nil {
|
||||||
// &e is always valid, and so p is always valid, but for the early abort
|
// &e is always valid, and so p is always valid, but for the early abort
|
||||||
// of ProcessEvent to be efficient it needs to make the nil check on the
|
// of ProcessEvent to be efficient it needs to make the nil check on the
|
||||||
// pointer without having to dereference it, so we make the nil function
|
// pointer without having to dereference it, so we make the nil function
|
||||||
// also a nil pointer
|
// also a nil pointer
|
||||||
p = nil
|
exporter.Store(nil)
|
||||||
|
} else {
|
||||||
|
exporter.Store(&e)
|
||||||
}
|
}
|
||||||
atomic.StorePointer(&exporter, p)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// deliver is called to deliver an event to the supplied exporter.
|
// deliver is called to deliver an event to the supplied exporter.
|
||||||
|
|
@ -48,7 +45,7 @@ func deliver(ctx context.Context, exporter Exporter, ev Event) context.Context {
|
||||||
// Export is called to deliver an event to the global exporter if set.
|
// Export is called to deliver an event to the global exporter if set.
|
||||||
func Export(ctx context.Context, ev Event) context.Context {
|
func Export(ctx context.Context, ev Event) context.Context {
|
||||||
// get the global exporter and abort early if there is not one
|
// get the global exporter and abort early if there is not one
|
||||||
exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter))
|
exporterPtr := exporter.Load()
|
||||||
if exporterPtr == nil {
|
if exporterPtr == nil {
|
||||||
return ctx
|
return ctx
|
||||||
}
|
}
|
||||||
|
|
@ -61,7 +58,7 @@ func Export(ctx context.Context, ev Event) context.Context {
|
||||||
// It will fill in the time.
|
// It will fill in the time.
|
||||||
func ExportPair(ctx context.Context, begin, end Event) (context.Context, func()) {
|
func ExportPair(ctx context.Context, begin, end Event) (context.Context, func()) {
|
||||||
// get the global exporter and abort early if there is not one
|
// get the global exporter and abort early if there is not one
|
||||||
exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter))
|
exporterPtr := exporter.Load()
|
||||||
if exporterPtr == nil {
|
if exporterPtr == nil {
|
||||||
return ctx, func() {}
|
return ctx, func() {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,13 @@ package keys
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"math"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"golang.org/x/tools/internal/event/label"
|
"golang.org/x/tools/internal/event/label"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Value represents a key for untyped values.
|
// Value is a [label.Key] for untyped values.
|
||||||
type Value struct {
|
type Value struct {
|
||||||
name string
|
name string
|
||||||
description string
|
description string
|
||||||
|
|
@ -27,11 +26,11 @@ func New(name, description string) *Value {
|
||||||
func (k *Value) Name() string { return k.name }
|
func (k *Value) Name() string { return k.name }
|
||||||
func (k *Value) Description() string { return k.description }
|
func (k *Value) Description() string { return k.description }
|
||||||
|
|
||||||
func (k *Value) Format(w io.Writer, buf []byte, l label.Label) {
|
func (k *Value) Append(buf []byte, l label.Label) []byte {
|
||||||
fmt.Fprint(w, k.From(l))
|
return fmt.Append(buf, k.From(l))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get can be used to get a label for the key from a label.Map.
|
// Get returns the label for the key of a label.Map.
|
||||||
func (k *Value) Get(lm label.Map) any {
|
func (k *Value) Get(lm label.Map) any {
|
||||||
if t := lm.Find(k); t.Valid() {
|
if t := lm.Find(k); t.Valid() {
|
||||||
return k.From(t)
|
return k.From(t)
|
||||||
|
|
@ -39,7 +38,7 @@ func (k *Value) Get(lm label.Map) any {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// From can be used to get a value from a Label.
|
// From returns the value of a Label.
|
||||||
func (k *Value) From(t label.Label) any { return t.UnpackValue() }
|
func (k *Value) From(t label.Label) any { return t.UnpackValue() }
|
||||||
|
|
||||||
// Of creates a new Label with this key and the supplied value.
|
// Of creates a new Label with this key and the supplied value.
|
||||||
|
|
@ -54,7 +53,7 @@ type Tag struct {
|
||||||
description string
|
description string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTag creates a new Key for tagging labels.
|
// NewTag creates a new [label.Key] for tagging labels.
|
||||||
func NewTag(name, description string) *Tag {
|
func NewTag(name, description string) *Tag {
|
||||||
return &Tag{name: name, description: description}
|
return &Tag{name: name, description: description}
|
||||||
}
|
}
|
||||||
|
|
@ -62,18 +61,18 @@ func NewTag(name, description string) *Tag {
|
||||||
func (k *Tag) Name() string { return k.name }
|
func (k *Tag) Name() string { return k.name }
|
||||||
func (k *Tag) Description() string { return k.description }
|
func (k *Tag) Description() string { return k.description }
|
||||||
|
|
||||||
func (k *Tag) Format(w io.Writer, buf []byte, l label.Label) {}
|
func (k *Tag) Append(buf []byte, l label.Label) []byte { return buf }
|
||||||
|
|
||||||
// New creates a new Label with this key.
|
// New creates a new Label with this key.
|
||||||
func (k *Tag) New() label.Label { return label.OfValue(k, nil) }
|
func (k *Tag) New() label.Label { return label.OfValue(k, nil) }
|
||||||
|
|
||||||
// Int represents a key
|
// Int is a [label.Key] for signed integers.
|
||||||
type Int struct {
|
type Int struct {
|
||||||
name string
|
name string
|
||||||
description string
|
description string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInt creates a new Key for int values.
|
// NewInt returns a new [label.Key] for int64 values.
|
||||||
func NewInt(name, description string) *Int {
|
func NewInt(name, description string) *Int {
|
||||||
return &Int{name: name, description: description}
|
return &Int{name: name, description: description}
|
||||||
}
|
}
|
||||||
|
|
@ -81,381 +80,92 @@ func NewInt(name, description string) *Int {
|
||||||
func (k *Int) Name() string { return k.name }
|
func (k *Int) Name() string { return k.name }
|
||||||
func (k *Int) Description() string { return k.description }
|
func (k *Int) Description() string { return k.description }
|
||||||
|
|
||||||
func (k *Int) Format(w io.Writer, buf []byte, l label.Label) {
|
func (k *Int) Append(buf []byte, l label.Label) []byte {
|
||||||
w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
|
return strconv.AppendInt(buf, k.From(l), 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Of creates a new Label with this key and the supplied value.
|
// Of creates a new Label with this key and the supplied value.
|
||||||
func (k *Int) Of(v int) label.Label { return label.Of64(k, uint64(v)) }
|
func (k *Int) Of(v int) label.Label { return k.Of64(int64(v)) }
|
||||||
|
|
||||||
// Get can be used to get a label for the key from a label.Map.
|
// Of64 creates a new Label with this key and the supplied value.
|
||||||
func (k *Int) Get(lm label.Map) int {
|
func (k *Int) Of64(v int64) label.Label { return label.Of64(k, uint64(v)) }
|
||||||
|
|
||||||
|
// Get returns the label for the key of a label.Map.
|
||||||
|
func (k *Int) Get(lm label.Map) int64 {
|
||||||
if t := lm.Find(k); t.Valid() {
|
if t := lm.Find(k); t.Valid() {
|
||||||
return k.From(t)
|
return k.From(t)
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// From can be used to get a value from a Label.
|
// From returns the value of a Label.
|
||||||
func (k *Int) From(t label.Label) int { return int(t.Unpack64()) }
|
func (k *Int) From(t label.Label) int64 { return int64(t.Unpack64()) }
|
||||||
|
|
||||||
// Int8 represents a key
|
// Uint is a [label.Key] for unsigned integers.
|
||||||
type Int8 struct {
|
type Uint struct {
|
||||||
name string
|
name string
|
||||||
description string
|
description string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInt8 creates a new Key for int8 values.
|
// NewUint creates a new [label.Key] for unsigned values.
|
||||||
func NewInt8(name, description string) *Int8 {
|
func NewUint(name, description string) *Uint {
|
||||||
return &Int8{name: name, description: description}
|
return &Uint{name: name, description: description}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *Int8) Name() string { return k.name }
|
func (k *Uint) Name() string { return k.name }
|
||||||
func (k *Int8) Description() string { return k.description }
|
func (k *Uint) Description() string { return k.description }
|
||||||
|
|
||||||
func (k *Int8) Format(w io.Writer, buf []byte, l label.Label) {
|
func (k *Uint) Append(buf []byte, l label.Label) []byte {
|
||||||
w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
|
return strconv.AppendUint(buf, k.From(l), 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Of creates a new Label with this key and the supplied value.
|
// Of creates a new Label with this key and the supplied value.
|
||||||
func (k *Int8) Of(v int8) label.Label { return label.Of64(k, uint64(v)) }
|
func (k *Uint) Of(v uint64) label.Label { return label.Of64(k, v) }
|
||||||
|
|
||||||
// Get can be used to get a label for the key from a label.Map.
|
// Get returns the label for the key of a label.Map.
|
||||||
func (k *Int8) Get(lm label.Map) int8 {
|
func (k *Uint) Get(lm label.Map) uint64 {
|
||||||
if t := lm.Find(k); t.Valid() {
|
if t := lm.Find(k); t.Valid() {
|
||||||
return k.From(t)
|
return k.From(t)
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// From can be used to get a value from a Label.
|
// From returns the value of a Label.
|
||||||
func (k *Int8) From(t label.Label) int8 { return int8(t.Unpack64()) }
|
func (k *Uint) From(t label.Label) uint64 { return t.Unpack64() }
|
||||||
|
|
||||||
// Int16 represents a key
|
// Float is a label.Key for floating-point values.
|
||||||
type Int16 struct {
|
type Float struct {
|
||||||
name string
|
name string
|
||||||
description string
|
description string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInt16 creates a new Key for int16 values.
|
// NewFloat creates a new [label.Key] for floating-point values.
|
||||||
func NewInt16(name, description string) *Int16 {
|
func NewFloat(name, description string) *Float {
|
||||||
return &Int16{name: name, description: description}
|
return &Float{name: name, description: description}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *Int16) Name() string { return k.name }
|
func (k *Float) Name() string { return k.name }
|
||||||
func (k *Int16) Description() string { return k.description }
|
func (k *Float) Description() string { return k.description }
|
||||||
|
|
||||||
func (k *Int16) Format(w io.Writer, buf []byte, l label.Label) {
|
func (k *Float) Append(buf []byte, l label.Label) []byte {
|
||||||
w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
|
return strconv.AppendFloat(buf, k.From(l), 'E', -1, 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Of creates a new Label with this key and the supplied value.
|
// Of creates a new Label with this key and the supplied value.
|
||||||
func (k *Int16) Of(v int16) label.Label { return label.Of64(k, uint64(v)) }
|
func (k *Float) Of(v float64) label.Label {
|
||||||
|
|
||||||
// Get can be used to get a label for the key from a label.Map.
|
|
||||||
func (k *Int16) Get(lm label.Map) int16 {
|
|
||||||
if t := lm.Find(k); t.Valid() {
|
|
||||||
return k.From(t)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// From can be used to get a value from a Label.
|
|
||||||
func (k *Int16) From(t label.Label) int16 { return int16(t.Unpack64()) }
|
|
||||||
|
|
||||||
// Int32 represents a key
|
|
||||||
type Int32 struct {
|
|
||||||
name string
|
|
||||||
description string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewInt32 creates a new Key for int32 values.
|
|
||||||
func NewInt32(name, description string) *Int32 {
|
|
||||||
return &Int32{name: name, description: description}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Int32) Name() string { return k.name }
|
|
||||||
func (k *Int32) Description() string { return k.description }
|
|
||||||
|
|
||||||
func (k *Int32) Format(w io.Writer, buf []byte, l label.Label) {
|
|
||||||
w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Of creates a new Label with this key and the supplied value.
|
|
||||||
func (k *Int32) Of(v int32) label.Label { return label.Of64(k, uint64(v)) }
|
|
||||||
|
|
||||||
// Get can be used to get a label for the key from a label.Map.
|
|
||||||
func (k *Int32) Get(lm label.Map) int32 {
|
|
||||||
if t := lm.Find(k); t.Valid() {
|
|
||||||
return k.From(t)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// From can be used to get a value from a Label.
|
|
||||||
func (k *Int32) From(t label.Label) int32 { return int32(t.Unpack64()) }
|
|
||||||
|
|
||||||
// Int64 represents a key
|
|
||||||
type Int64 struct {
|
|
||||||
name string
|
|
||||||
description string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewInt64 creates a new Key for int64 values.
|
|
||||||
func NewInt64(name, description string) *Int64 {
|
|
||||||
return &Int64{name: name, description: description}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Int64) Name() string { return k.name }
|
|
||||||
func (k *Int64) Description() string { return k.description }
|
|
||||||
|
|
||||||
func (k *Int64) Format(w io.Writer, buf []byte, l label.Label) {
|
|
||||||
w.Write(strconv.AppendInt(buf, k.From(l), 10))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Of creates a new Label with this key and the supplied value.
|
|
||||||
func (k *Int64) Of(v int64) label.Label { return label.Of64(k, uint64(v)) }
|
|
||||||
|
|
||||||
// Get can be used to get a label for the key from a label.Map.
|
|
||||||
func (k *Int64) Get(lm label.Map) int64 {
|
|
||||||
if t := lm.Find(k); t.Valid() {
|
|
||||||
return k.From(t)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// From can be used to get a value from a Label.
|
|
||||||
func (k *Int64) From(t label.Label) int64 { return int64(t.Unpack64()) }
|
|
||||||
|
|
||||||
// UInt represents a key
|
|
||||||
type UInt struct {
|
|
||||||
name string
|
|
||||||
description string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUInt creates a new Key for uint values.
|
|
||||||
func NewUInt(name, description string) *UInt {
|
|
||||||
return &UInt{name: name, description: description}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *UInt) Name() string { return k.name }
|
|
||||||
func (k *UInt) Description() string { return k.description }
|
|
||||||
|
|
||||||
func (k *UInt) Format(w io.Writer, buf []byte, l label.Label) {
|
|
||||||
w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Of creates a new Label with this key and the supplied value.
|
|
||||||
func (k *UInt) Of(v uint) label.Label { return label.Of64(k, uint64(v)) }
|
|
||||||
|
|
||||||
// Get can be used to get a label for the key from a label.Map.
|
|
||||||
func (k *UInt) Get(lm label.Map) uint {
|
|
||||||
if t := lm.Find(k); t.Valid() {
|
|
||||||
return k.From(t)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// From can be used to get a value from a Label.
|
|
||||||
func (k *UInt) From(t label.Label) uint { return uint(t.Unpack64()) }
|
|
||||||
|
|
||||||
// UInt8 represents a key
|
|
||||||
type UInt8 struct {
|
|
||||||
name string
|
|
||||||
description string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUInt8 creates a new Key for uint8 values.
|
|
||||||
func NewUInt8(name, description string) *UInt8 {
|
|
||||||
return &UInt8{name: name, description: description}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *UInt8) Name() string { return k.name }
|
|
||||||
func (k *UInt8) Description() string { return k.description }
|
|
||||||
|
|
||||||
func (k *UInt8) Format(w io.Writer, buf []byte, l label.Label) {
|
|
||||||
w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Of creates a new Label with this key and the supplied value.
|
|
||||||
func (k *UInt8) Of(v uint8) label.Label { return label.Of64(k, uint64(v)) }
|
|
||||||
|
|
||||||
// Get can be used to get a label for the key from a label.Map.
|
|
||||||
func (k *UInt8) Get(lm label.Map) uint8 {
|
|
||||||
if t := lm.Find(k); t.Valid() {
|
|
||||||
return k.From(t)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// From can be used to get a value from a Label.
|
|
||||||
func (k *UInt8) From(t label.Label) uint8 { return uint8(t.Unpack64()) }
|
|
||||||
|
|
||||||
// UInt16 represents a key
|
|
||||||
type UInt16 struct {
|
|
||||||
name string
|
|
||||||
description string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUInt16 creates a new Key for uint16 values.
|
|
||||||
func NewUInt16(name, description string) *UInt16 {
|
|
||||||
return &UInt16{name: name, description: description}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *UInt16) Name() string { return k.name }
|
|
||||||
func (k *UInt16) Description() string { return k.description }
|
|
||||||
|
|
||||||
func (k *UInt16) Format(w io.Writer, buf []byte, l label.Label) {
|
|
||||||
w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Of creates a new Label with this key and the supplied value.
|
|
||||||
func (k *UInt16) Of(v uint16) label.Label { return label.Of64(k, uint64(v)) }
|
|
||||||
|
|
||||||
// Get can be used to get a label for the key from a label.Map.
|
|
||||||
func (k *UInt16) Get(lm label.Map) uint16 {
|
|
||||||
if t := lm.Find(k); t.Valid() {
|
|
||||||
return k.From(t)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// From can be used to get a value from a Label.
|
|
||||||
func (k *UInt16) From(t label.Label) uint16 { return uint16(t.Unpack64()) }
|
|
||||||
|
|
||||||
// UInt32 represents a key
|
|
||||||
type UInt32 struct {
|
|
||||||
name string
|
|
||||||
description string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUInt32 creates a new Key for uint32 values.
|
|
||||||
func NewUInt32(name, description string) *UInt32 {
|
|
||||||
return &UInt32{name: name, description: description}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *UInt32) Name() string { return k.name }
|
|
||||||
func (k *UInt32) Description() string { return k.description }
|
|
||||||
|
|
||||||
func (k *UInt32) Format(w io.Writer, buf []byte, l label.Label) {
|
|
||||||
w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Of creates a new Label with this key and the supplied value.
|
|
||||||
func (k *UInt32) Of(v uint32) label.Label { return label.Of64(k, uint64(v)) }
|
|
||||||
|
|
||||||
// Get can be used to get a label for the key from a label.Map.
|
|
||||||
func (k *UInt32) Get(lm label.Map) uint32 {
|
|
||||||
if t := lm.Find(k); t.Valid() {
|
|
||||||
return k.From(t)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// From can be used to get a value from a Label.
|
|
||||||
func (k *UInt32) From(t label.Label) uint32 { return uint32(t.Unpack64()) }
|
|
||||||
|
|
||||||
// UInt64 represents a key
|
|
||||||
type UInt64 struct {
|
|
||||||
name string
|
|
||||||
description string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUInt64 creates a new Key for uint64 values.
|
|
||||||
func NewUInt64(name, description string) *UInt64 {
|
|
||||||
return &UInt64{name: name, description: description}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *UInt64) Name() string { return k.name }
|
|
||||||
func (k *UInt64) Description() string { return k.description }
|
|
||||||
|
|
||||||
func (k *UInt64) Format(w io.Writer, buf []byte, l label.Label) {
|
|
||||||
w.Write(strconv.AppendUint(buf, k.From(l), 10))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Of creates a new Label with this key and the supplied value.
|
|
||||||
func (k *UInt64) Of(v uint64) label.Label { return label.Of64(k, v) }
|
|
||||||
|
|
||||||
// Get can be used to get a label for the key from a label.Map.
|
|
||||||
func (k *UInt64) Get(lm label.Map) uint64 {
|
|
||||||
if t := lm.Find(k); t.Valid() {
|
|
||||||
return k.From(t)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// From can be used to get a value from a Label.
|
|
||||||
func (k *UInt64) From(t label.Label) uint64 { return t.Unpack64() }
|
|
||||||
|
|
||||||
// Float32 represents a key
|
|
||||||
type Float32 struct {
|
|
||||||
name string
|
|
||||||
description string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFloat32 creates a new Key for float32 values.
|
|
||||||
func NewFloat32(name, description string) *Float32 {
|
|
||||||
return &Float32{name: name, description: description}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Float32) Name() string { return k.name }
|
|
||||||
func (k *Float32) Description() string { return k.description }
|
|
||||||
|
|
||||||
func (k *Float32) Format(w io.Writer, buf []byte, l label.Label) {
|
|
||||||
w.Write(strconv.AppendFloat(buf, float64(k.From(l)), 'E', -1, 32))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Of creates a new Label with this key and the supplied value.
|
|
||||||
func (k *Float32) Of(v float32) label.Label {
|
|
||||||
return label.Of64(k, uint64(math.Float32bits(v)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get can be used to get a label for the key from a label.Map.
|
|
||||||
func (k *Float32) Get(lm label.Map) float32 {
|
|
||||||
if t := lm.Find(k); t.Valid() {
|
|
||||||
return k.From(t)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// From can be used to get a value from a Label.
|
|
||||||
func (k *Float32) From(t label.Label) float32 {
|
|
||||||
return math.Float32frombits(uint32(t.Unpack64()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64 represents a key
|
|
||||||
type Float64 struct {
|
|
||||||
name string
|
|
||||||
description string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFloat64 creates a new Key for int64 values.
|
|
||||||
func NewFloat64(name, description string) *Float64 {
|
|
||||||
return &Float64{name: name, description: description}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Float64) Name() string { return k.name }
|
|
||||||
func (k *Float64) Description() string { return k.description }
|
|
||||||
|
|
||||||
func (k *Float64) Format(w io.Writer, buf []byte, l label.Label) {
|
|
||||||
w.Write(strconv.AppendFloat(buf, k.From(l), 'E', -1, 64))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Of creates a new Label with this key and the supplied value.
|
|
||||||
func (k *Float64) Of(v float64) label.Label {
|
|
||||||
return label.Of64(k, math.Float64bits(v))
|
return label.Of64(k, math.Float64bits(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get can be used to get a label for the key from a label.Map.
|
// Get returns the label for the key of a label.Map.
|
||||||
func (k *Float64) Get(lm label.Map) float64 {
|
func (k *Float) Get(lm label.Map) float64 {
|
||||||
if t := lm.Find(k); t.Valid() {
|
if t := lm.Find(k); t.Valid() {
|
||||||
return k.From(t)
|
return k.From(t)
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// From can be used to get a value from a Label.
|
// From returns the value of a Label.
|
||||||
func (k *Float64) From(t label.Label) float64 {
|
func (k *Float) From(t label.Label) float64 {
|
||||||
return math.Float64frombits(t.Unpack64())
|
return math.Float64frombits(t.Unpack64())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -473,14 +183,14 @@ func NewString(name, description string) *String {
|
||||||
func (k *String) Name() string { return k.name }
|
func (k *String) Name() string { return k.name }
|
||||||
func (k *String) Description() string { return k.description }
|
func (k *String) Description() string { return k.description }
|
||||||
|
|
||||||
func (k *String) Format(w io.Writer, buf []byte, l label.Label) {
|
func (k *String) Append(buf []byte, l label.Label) []byte {
|
||||||
w.Write(strconv.AppendQuote(buf, k.From(l)))
|
return strconv.AppendQuote(buf, k.From(l))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Of creates a new Label with this key and the supplied value.
|
// Of creates a new Label with this key and the supplied value.
|
||||||
func (k *String) Of(v string) label.Label { return label.OfString(k, v) }
|
func (k *String) Of(v string) label.Label { return label.OfString(k, v) }
|
||||||
|
|
||||||
// Get can be used to get a label for the key from a label.Map.
|
// Get returns the label for the key of a label.Map.
|
||||||
func (k *String) Get(lm label.Map) string {
|
func (k *String) Get(lm label.Map) string {
|
||||||
if t := lm.Find(k); t.Valid() {
|
if t := lm.Find(k); t.Valid() {
|
||||||
return k.From(t)
|
return k.From(t)
|
||||||
|
|
@ -488,53 +198,16 @@ func (k *String) Get(lm label.Map) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// From can be used to get a value from a Label.
|
// From returns the value of a Label.
|
||||||
func (k *String) From(t label.Label) string { return t.UnpackString() }
|
func (k *String) From(t label.Label) string { return t.UnpackString() }
|
||||||
|
|
||||||
// Boolean represents a key
|
|
||||||
type Boolean struct {
|
|
||||||
name string
|
|
||||||
description string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBoolean creates a new Key for bool values.
|
|
||||||
func NewBoolean(name, description string) *Boolean {
|
|
||||||
return &Boolean{name: name, description: description}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Boolean) Name() string { return k.name }
|
|
||||||
func (k *Boolean) Description() string { return k.description }
|
|
||||||
|
|
||||||
func (k *Boolean) Format(w io.Writer, buf []byte, l label.Label) {
|
|
||||||
w.Write(strconv.AppendBool(buf, k.From(l)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Of creates a new Label with this key and the supplied value.
|
|
||||||
func (k *Boolean) Of(v bool) label.Label {
|
|
||||||
if v {
|
|
||||||
return label.Of64(k, 1)
|
|
||||||
}
|
|
||||||
return label.Of64(k, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get can be used to get a label for the key from a label.Map.
|
|
||||||
func (k *Boolean) Get(lm label.Map) bool {
|
|
||||||
if t := lm.Find(k); t.Valid() {
|
|
||||||
return k.From(t)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// From can be used to get a value from a Label.
|
|
||||||
func (k *Boolean) From(t label.Label) bool { return t.Unpack64() > 0 }
|
|
||||||
|
|
||||||
// Error represents a key
|
// Error represents a key
|
||||||
type Error struct {
|
type Error struct {
|
||||||
name string
|
name string
|
||||||
description string
|
description string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewError creates a new Key for int64 values.
|
// NewError returns a new [label.Key] for error values.
|
||||||
func NewError(name, description string) *Error {
|
func NewError(name, description string) *Error {
|
||||||
return &Error{name: name, description: description}
|
return &Error{name: name, description: description}
|
||||||
}
|
}
|
||||||
|
|
@ -542,14 +215,14 @@ func NewError(name, description string) *Error {
|
||||||
func (k *Error) Name() string { return k.name }
|
func (k *Error) Name() string { return k.name }
|
||||||
func (k *Error) Description() string { return k.description }
|
func (k *Error) Description() string { return k.description }
|
||||||
|
|
||||||
func (k *Error) Format(w io.Writer, buf []byte, l label.Label) {
|
func (k *Error) Append(buf []byte, l label.Label) []byte {
|
||||||
io.WriteString(w, k.From(l).Error())
|
return append(buf, k.From(l).Error()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Of creates a new Label with this key and the supplied value.
|
// Of returns a new Label with this key and the supplied value.
|
||||||
func (k *Error) Of(v error) label.Label { return label.OfValue(k, v) }
|
func (k *Error) Of(v error) label.Label { return label.OfValue(k, v) }
|
||||||
|
|
||||||
// Get can be used to get a label for the key from a label.Map.
|
// Get returns the label for the key of a label.Map.
|
||||||
func (k *Error) Get(lm label.Map) error {
|
func (k *Error) Get(lm label.Map) error {
|
||||||
if t := lm.Find(k); t.Valid() {
|
if t := lm.Find(k); t.Valid() {
|
||||||
return k.From(t)
|
return k.From(t)
|
||||||
|
|
@ -557,7 +230,7 @@ func (k *Error) Get(lm label.Map) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// From can be used to get a value from a Label.
|
// From returns the value of a Label.
|
||||||
func (k *Error) From(t label.Label) error {
|
func (k *Error) From(t label.Label) error {
|
||||||
err, _ := t.UnpackValue().(error)
|
err, _ := t.UnpackValue().(error)
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ package label
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
|
||||||
"slices"
|
"slices"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
@ -20,12 +19,8 @@ type Key interface {
|
||||||
Name() string
|
Name() string
|
||||||
// Description returns a string that can be used to describe the value.
|
// Description returns a string that can be used to describe the value.
|
||||||
Description() string
|
Description() string
|
||||||
|
// Append appends the formatted value of the label to the supplied buffer.
|
||||||
// Format is used in formatting to append the value of the label to the
|
Append(buf []byte, l Label) []byte
|
||||||
// supplied buffer.
|
|
||||||
// The formatter may use the supplied buf as a scratch area to avoid
|
|
||||||
// allocations.
|
|
||||||
Format(w io.Writer, buf []byte, l Label)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Label holds a key and value pair.
|
// Label holds a key and value pair.
|
||||||
|
|
@ -103,11 +98,10 @@ type stringptr unsafe.Pointer
|
||||||
// This method is for implementing new key types, label creation should
|
// This method is for implementing new key types, label creation should
|
||||||
// normally be done with the Of method of the key.
|
// normally be done with the Of method of the key.
|
||||||
func OfString(k Key, v string) Label {
|
func OfString(k Key, v string) Label {
|
||||||
hdr := (*reflect.StringHeader)(unsafe.Pointer(&v))
|
|
||||||
return Label{
|
return Label{
|
||||||
key: k,
|
key: k,
|
||||||
packed: uint64(hdr.Len),
|
packed: uint64(len(v)),
|
||||||
untyped: stringptr(hdr.Data),
|
untyped: stringptr(unsafe.StringData(v)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,11 +110,7 @@ func OfString(k Key, v string) Label {
|
||||||
// This method is for implementing new key types, for type safety normal
|
// This method is for implementing new key types, for type safety normal
|
||||||
// access should be done with the From method of the key.
|
// access should be done with the From method of the key.
|
||||||
func (t Label) UnpackString() string {
|
func (t Label) UnpackString() string {
|
||||||
var v string
|
return unsafe.String((*byte)(t.untyped.(stringptr)), int(t.packed))
|
||||||
hdr := (*reflect.StringHeader)(unsafe.Pointer(&v))
|
|
||||||
hdr.Data = uintptr(t.untyped.(stringptr))
|
|
||||||
hdr.Len = int(t.packed)
|
|
||||||
return v
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Valid returns true if the Label is a valid one (it has a key).
|
// Valid returns true if the Label is a valid one (it has a key).
|
||||||
|
|
@ -137,8 +127,7 @@ func (t Label) Format(f fmt.State, r rune) {
|
||||||
}
|
}
|
||||||
io.WriteString(f, t.Key().Name())
|
io.WriteString(f, t.Key().Name())
|
||||||
io.WriteString(f, "=")
|
io.WriteString(f, "=")
|
||||||
var buf [128]byte
|
f.Write(t.Key().Append(nil, t)) // ignore error
|
||||||
t.Key().Format(f, buf[:0], t)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *list) Valid(index int) bool {
|
func (l *list) Valid(index int) bool {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
"log"
|
"log"
|
||||||
|
"reflect"
|
||||||
"slices"
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
@ -65,7 +66,7 @@ func sortImports(localPrefix string, tokFile *token.File, f *ast.File) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// mergeImports merges all the import declarations into the first one.
|
// mergeImports merges all the import declarations into the first one.
|
||||||
// Taken from golang.org/x/tools/ast/astutil.
|
// Taken from golang.org/x/tools/go/ast/astutil.
|
||||||
// This does not adjust line numbers properly
|
// This does not adjust line numbers properly
|
||||||
func mergeImports(f *ast.File) {
|
func mergeImports(f *ast.File) {
|
||||||
if len(f.Decls) <= 1 {
|
if len(f.Decls) <= 1 {
|
||||||
|
|
@ -89,7 +90,7 @@ func mergeImports(f *ast.File) {
|
||||||
first.Lparen = first.Pos()
|
first.Lparen = first.Pos()
|
||||||
// Move the imports of the other import declaration to the first one.
|
// Move the imports of the other import declaration to the first one.
|
||||||
for _, spec := range gen.Specs {
|
for _, spec := range gen.Specs {
|
||||||
spec.(*ast.ImportSpec).Path.ValuePos = first.Pos()
|
updateBasicLitPos(spec.(*ast.ImportSpec).Path, first.Pos())
|
||||||
first.Specs = append(first.Specs, spec)
|
first.Specs = append(first.Specs, spec)
|
||||||
}
|
}
|
||||||
f.Decls = slices.Delete(f.Decls, i, i+1)
|
f.Decls = slices.Delete(f.Decls, i, i+1)
|
||||||
|
|
@ -98,7 +99,7 @@ func mergeImports(f *ast.File) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// declImports reports whether gen contains an import of path.
|
// declImports reports whether gen contains an import of path.
|
||||||
// Taken from golang.org/x/tools/ast/astutil.
|
// Taken from golang.org/x/tools/go/ast/astutil.
|
||||||
func declImports(gen *ast.GenDecl, path string) bool {
|
func declImports(gen *ast.GenDecl, path string) bool {
|
||||||
if gen.Tok != token.IMPORT {
|
if gen.Tok != token.IMPORT {
|
||||||
return false
|
return false
|
||||||
|
|
@ -221,7 +222,7 @@ func sortSpecs(localPrefix string, tokFile *token.File, f *ast.File, specs []ast
|
||||||
if s.Name != nil {
|
if s.Name != nil {
|
||||||
s.Name.NamePos = pos[i].Start
|
s.Name.NamePos = pos[i].Start
|
||||||
}
|
}
|
||||||
s.Path.ValuePos = pos[i].Start
|
updateBasicLitPos(s.Path, pos[i].Start)
|
||||||
s.EndPos = pos[i].End
|
s.EndPos = pos[i].End
|
||||||
nextSpecPos := pos[i].End
|
nextSpecPos := pos[i].End
|
||||||
|
|
||||||
|
|
@ -296,3 +297,17 @@ type byCommentPos []*ast.CommentGroup
|
||||||
func (x byCommentPos) Len() int { return len(x) }
|
func (x byCommentPos) Len() int { return len(x) }
|
||||||
func (x byCommentPos) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
func (x byCommentPos) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||||
func (x byCommentPos) Less(i, j int) bool { return x[i].Pos() < x[j].Pos() }
|
func (x byCommentPos) Less(i, j int) bool { return x[i].Pos() < x[j].Pos() }
|
||||||
|
|
||||||
|
// updateBasicLitPos updates lit.Pos,
|
||||||
|
// ensuring that lit.End (if set) is displaced by the same amount.
|
||||||
|
// (See https://go.dev/issue/76395.)
|
||||||
|
func updateBasicLitPos(lit *ast.BasicLit, pos token.Pos) {
|
||||||
|
len := lit.End() - lit.Pos()
|
||||||
|
lit.ValuePos = pos
|
||||||
|
// TODO(adonovan): after go1.26, simplify to:
|
||||||
|
// lit.ValueEnd = pos + len
|
||||||
|
v := reflect.ValueOf(lit).Elem().FieldByName("ValueEnd")
|
||||||
|
if v.IsValid() && v.Int() != 0 {
|
||||||
|
v.SetInt(int64(pos + len))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import (
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
@ -107,14 +106,14 @@ var IndexDir string = func() string {
|
||||||
var err error
|
var err error
|
||||||
dir, err = os.UserCacheDir()
|
dir, err = os.UserCacheDir()
|
||||||
// shouldn't happen, but TempDir is better than
|
// shouldn't happen, but TempDir is better than
|
||||||
// creating ./go/imports
|
// creating ./goimports
|
||||||
if err != nil {
|
if err != nil {
|
||||||
dir = os.TempDir()
|
dir = os.TempDir()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dir = filepath.Join(dir, "goimports")
|
dir = filepath.Join(dir, "goimports")
|
||||||
if err := os.MkdirAll(dir, 0777); err != nil {
|
if err := os.MkdirAll(dir, 0777); err != nil {
|
||||||
log.Printf("failed to create modcache index dir: %v", err)
|
dir = "" // #75505, people complain about the error message
|
||||||
}
|
}
|
||||||
return dir
|
return dir
|
||||||
}()
|
}()
|
||||||
|
|
@ -127,6 +126,9 @@ func Read(gomodcache string) (*Index, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if IndexDir == "" {
|
||||||
|
return nil, os.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
// Read the "link" file for the specified gomodcache directory.
|
// Read the "link" file for the specified gomodcache directory.
|
||||||
// It names the payload file.
|
// It names the payload file.
|
||||||
|
|
@ -227,6 +229,9 @@ func readIndexFrom(gomodcache string, r io.Reader) (*Index, error) {
|
||||||
|
|
||||||
// write writes the index file and updates the index directory to refer to it.
|
// write writes the index file and updates the index directory to refer to it.
|
||||||
func write(gomodcache string, ix *Index) error {
|
func write(gomodcache string, ix *Index) error {
|
||||||
|
if IndexDir == "" {
|
||||||
|
return os.ErrNotExist
|
||||||
|
}
|
||||||
// Write the index into a payload file with a fresh name.
|
// Write the index into a payload file with a fresh name.
|
||||||
f, err := os.CreateTemp(IndexDir, fmt.Sprintf("index-%d-*", CurrentVersion))
|
f, err := os.CreateTemp(IndexDir, fmt.Sprintf("index-%d-*", CurrentVersion))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ import (
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/mod/module"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Candidate struct {
|
type Candidate struct {
|
||||||
|
|
@ -104,11 +106,15 @@ func (ix *Index) Lookup(pkgName, name string, prefix bool) []Candidate {
|
||||||
if len(flds) < 2 {
|
if len(flds) < 2 {
|
||||||
continue // should never happen
|
continue // should never happen
|
||||||
}
|
}
|
||||||
|
impPath, err := module.UnescapePath(e.ImportPath)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
px := Candidate{
|
px := Candidate{
|
||||||
PkgName: pkgName,
|
PkgName: pkgName,
|
||||||
Name: flds[0],
|
Name: flds[0],
|
||||||
Dir: string(e.Dir),
|
Dir: string(e.Dir),
|
||||||
ImportPath: e.ImportPath,
|
ImportPath: impPath,
|
||||||
Type: asLexType(flds[1][0]),
|
Type: asLexType(flds[1][0]),
|
||||||
Deprecated: len(flds[1]) > 1 && flds[1][1] == 'D',
|
Deprecated: len(flds[1]) > 1 && flds[1][1] == 'D',
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,360 +12,366 @@ type pkginfo struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var deps = [...]pkginfo{
|
var deps = [...]pkginfo{
|
||||||
{"archive/tar", "\x03n\x03E<\x01\n\x01$\x01\x01\x02\x05\b\x02\x01\x02\x02\f"},
|
{"archive/tar", "\x03q\x03F=\x01\n\x01$\x01\x01\x02\x05\b\x02\x01\x02\x02\r"},
|
||||||
{"archive/zip", "\x02\x04d\a\x03\x12\x021<\x01+\x05\x01\x0f\x03\x02\x0e\x04"},
|
{"archive/zip", "\x02\x04g\a\x03\x13\x021=\x01+\x05\x01\x0f\x03\x02\x0f\x04"},
|
||||||
{"bufio", "\x03n\x84\x01D\x14"},
|
{"bufio", "\x03q\x86\x01D\x15"},
|
||||||
{"bytes", "q*Z\x03\fG\x02\x02"},
|
{"bytes", "t+[\x03\fH\x02\x02"},
|
||||||
{"cmp", ""},
|
{"cmp", ""},
|
||||||
{"compress/bzip2", "\x02\x02\xf1\x01A"},
|
{"compress/bzip2", "\x02\x02\xf6\x01A"},
|
||||||
{"compress/flate", "\x02o\x03\x81\x01\f\x033\x01\x03"},
|
{"compress/flate", "\x02r\x03\x83\x01\f\x033\x01\x03"},
|
||||||
{"compress/gzip", "\x02\x04d\a\x03\x14mT"},
|
{"compress/gzip", "\x02\x04g\a\x03\x15nU"},
|
||||||
{"compress/lzw", "\x02o\x03\x81\x01"},
|
{"compress/lzw", "\x02r\x03\x83\x01"},
|
||||||
{"compress/zlib", "\x02\x04d\a\x03\x12\x01n"},
|
{"compress/zlib", "\x02\x04g\a\x03\x13\x01o"},
|
||||||
{"container/heap", "\xb7\x02"},
|
{"container/heap", "\xbc\x02"},
|
||||||
{"container/list", ""},
|
{"container/list", ""},
|
||||||
{"container/ring", ""},
|
{"container/ring", ""},
|
||||||
{"context", "q[o\x01\r"},
|
{"context", "t\\p\x01\x0e"},
|
||||||
{"crypto", "\x86\x01oC"},
|
{"crypto", "\x8a\x01pC"},
|
||||||
{"crypto/aes", "\x10\n\t\x95\x02"},
|
{"crypto/aes", "\x10\v\t\x99\x02"},
|
||||||
{"crypto/cipher", "\x03 \x01\x01\x1f\x11\x1c+Y"},
|
{"crypto/cipher", "\x03!\x01\x01 \x12\x1c,Z"},
|
||||||
{"crypto/des", "\x10\x15\x1f-+\x9c\x01\x03"},
|
{"crypto/des", "\x10\x16 .,\x9d\x01\x03"},
|
||||||
{"crypto/dsa", "D\x04)\x84\x01\r"},
|
{"crypto/dsa", "F\x03+\x86\x01\r"},
|
||||||
{"crypto/ecdh", "\x03\v\f\x10\x04\x16\x04\r\x1c\x84\x01"},
|
{"crypto/ecdh", "\x03\v\r\x10\x04\x17\x03\x0f\x1c\x86\x01"},
|
||||||
{"crypto/ecdsa", "\x0e\x05\x03\x04\x01\x10\a\v\x06\x01\x04\f\x01\x1c\x84\x01\r\x05K\x01"},
|
{"crypto/ecdsa", "\x0e\x05\x03\x05\x01\x10\b\v\x06\x01\x03\x0e\x01\x1c\x86\x01\r\x05L\x01"},
|
||||||
{"crypto/ed25519", "\x0e\x1e\x11\a\n\a\x1c\x84\x01C"},
|
{"crypto/ed25519", "\x0e\x1f\x12\a\x03\b\a\x1cI=C"},
|
||||||
{"crypto/elliptic", "2?\x84\x01\r9"},
|
{"crypto/elliptic", "4@\x86\x01\r9"},
|
||||||
{"crypto/fips140", "\"\x05"},
|
{"crypto/fips140", "#\x05\x95\x01\x98\x01"},
|
||||||
{"crypto/hkdf", "/\x14\x01-\x15"},
|
{"crypto/hkdf", "0\x15\x01.\x16"},
|
||||||
{"crypto/hmac", "\x1a\x16\x13\x01\x111"},
|
{"crypto/hmac", "\x1b\x16\x14\x01\x122"},
|
||||||
{"crypto/internal/boring", "\x0e\x02\ri"},
|
{"crypto/hpke", "\x03\v\x02\x03\x04\x01\f\x01\x05\x1f\x05\a\x01\x01\x1d\x03\x13\x16\x9b\x01\x1c"},
|
||||||
{"crypto/internal/boring/bbig", "\x1a\xe8\x01M"},
|
{"crypto/internal/boring", "\x0e\x02\x0el"},
|
||||||
{"crypto/internal/boring/bcache", "\xbc\x02\x13"},
|
{"crypto/internal/boring/bbig", "\x1b\xec\x01N"},
|
||||||
|
{"crypto/internal/boring/bcache", "\xc1\x02\x14"},
|
||||||
{"crypto/internal/boring/sig", ""},
|
{"crypto/internal/boring/sig", ""},
|
||||||
{"crypto/internal/constanttime", ""},
|
{"crypto/internal/constanttime", ""},
|
||||||
{"crypto/internal/cryptotest", "\x03\r\n\b%\x0e\x19\x06\x12\x12 \x04\x06\t\x18\x01\x11\x11\x1b\x01\a\x05\b\x03\x05\v"},
|
{"crypto/internal/cryptotest", "\x03\r\v\b%\x10\x19\x06\x13\x12 \x04\x06\t\x19\x01\x11\x11\x1b\x01\a\x05\b\x03\x05\f"},
|
||||||
{"crypto/internal/entropy", "I"},
|
{"crypto/internal/entropy", "K"},
|
||||||
{"crypto/internal/entropy/v1.0.0", "B/\x93\x018\x13"},
|
{"crypto/internal/entropy/v1.0.0", "D0\x95\x018\x14"},
|
||||||
{"crypto/internal/fips140", "A0\xbd\x01\v\x16"},
|
{"crypto/internal/fips140", "C1\xbf\x01\v\x17"},
|
||||||
{"crypto/internal/fips140/aes", "\x03\x1f\x03\x02\x13\x05\x01\x01\x06*\x93\x014"},
|
{"crypto/internal/fips140/aes", "\x03 \x03\x02\x14\x05\x01\x01\x05,\x95\x014"},
|
||||||
{"crypto/internal/fips140/aes/gcm", "\"\x01\x02\x02\x02\x11\x05\x01\a*\x90\x01"},
|
{"crypto/internal/fips140/aes/gcm", "#\x01\x02\x02\x02\x12\x05\x01\x06,\x92\x01"},
|
||||||
{"crypto/internal/fips140/alias", "\xcf\x02"},
|
{"crypto/internal/fips140/alias", "\xd5\x02"},
|
||||||
{"crypto/internal/fips140/bigmod", "'\x18\x01\a*\x93\x01"},
|
{"crypto/internal/fips140/bigmod", "(\x19\x01\x06,\x95\x01"},
|
||||||
{"crypto/internal/fips140/check", "\"\x0e\x06\t\x02\xb4\x01Z"},
|
{"crypto/internal/fips140/check", "#\x0e\a\t\x02\xb7\x01["},
|
||||||
{"crypto/internal/fips140/check/checktest", "'\x87\x02!"},
|
{"crypto/internal/fips140/check/checktest", "(\x8b\x02\""},
|
||||||
{"crypto/internal/fips140/drbg", "\x03\x1e\x01\x01\x04\x13\x05\t\x01(\x84\x01\x0f7\x01"},
|
{"crypto/internal/fips140/drbg", "\x03\x1f\x01\x01\x04\x14\x05\n)\x86\x01\x0f7\x01"},
|
||||||
{"crypto/internal/fips140/ecdh", "\x03\x1f\x05\x02\t\r2\x84\x01\x0f7"},
|
{"crypto/internal/fips140/ecdh", "\x03 \x05\x02\n\r3\x86\x01\x0f7"},
|
||||||
{"crypto/internal/fips140/ecdsa", "\x03\x1f\x04\x01\x02\a\x02\x069\x15oF"},
|
{"crypto/internal/fips140/ecdsa", "\x03 \x04\x01\x02\a\x03\x06:\x16pF"},
|
||||||
{"crypto/internal/fips140/ed25519", "\x03\x1f\x05\x02\x04\v9\xc7\x01\x03"},
|
{"crypto/internal/fips140/ed25519", "\x03 \x05\x02\x04\f:\xc9\x01\x03"},
|
||||||
{"crypto/internal/fips140/edwards25519", "\x1e\t\a\x112\x93\x017"},
|
{"crypto/internal/fips140/edwards25519", "\x1f\t\a\x123\x95\x017"},
|
||||||
{"crypto/internal/fips140/edwards25519/field", "'\x13\x052\x93\x01"},
|
{"crypto/internal/fips140/edwards25519/field", "(\x14\x053\x95\x01"},
|
||||||
{"crypto/internal/fips140/hkdf", "\x03\x1f\x05\t\x06;\x15"},
|
{"crypto/internal/fips140/hkdf", "\x03 \x05\t\a<\x16"},
|
||||||
{"crypto/internal/fips140/hmac", "\x03\x1f\x14\x01\x019\x15"},
|
{"crypto/internal/fips140/hmac", "\x03 \x15\x01\x01:\x16"},
|
||||||
{"crypto/internal/fips140/mlkem", "\x03\x1f\x05\x02\x0e\x03\x052\xca\x01"},
|
{"crypto/internal/fips140/mldsa", "\x03\x1c\x04\x05\x02\x0e\x01\x03\x053\x95\x017"},
|
||||||
{"crypto/internal/fips140/nistec", "\x1e\t\f\f2\x93\x01*\r\x14"},
|
{"crypto/internal/fips140/mlkem", "\x03 \x05\x02\x0f\x03\x053\xcc\x01"},
|
||||||
{"crypto/internal/fips140/nistec/fiat", "'\x137\x93\x01"},
|
{"crypto/internal/fips140/nistec", "\x1f\t\r\f3\x95\x01*\r\x15"},
|
||||||
{"crypto/internal/fips140/pbkdf2", "\x03\x1f\x05\t\x06;\x15"},
|
{"crypto/internal/fips140/nistec/fiat", "(\x148\x95\x01"},
|
||||||
{"crypto/internal/fips140/rsa", "\x03\x1b\x04\x04\x01\x02\r\x01\x01\x027\x15oF"},
|
{"crypto/internal/fips140/pbkdf2", "\x03 \x05\t\a<\x16"},
|
||||||
{"crypto/internal/fips140/sha256", "\x03\x1f\x1d\x01\a*\x15~"},
|
{"crypto/internal/fips140/rsa", "\x03\x1c\x04\x04\x01\x02\x0e\x01\x01\x028\x16pF"},
|
||||||
{"crypto/internal/fips140/sha3", "\x03\x1f\x18\x05\x011\x93\x01K"},
|
{"crypto/internal/fips140/sha256", "\x03 \x1e\x01\x06,\x16\x7f"},
|
||||||
{"crypto/internal/fips140/sha512", "\x03\x1f\x1d\x01\a*\x15~"},
|
{"crypto/internal/fips140/sha3", "\x03 \x19\x05\x012\x95\x01L"},
|
||||||
{"crypto/internal/fips140/ssh", "'_"},
|
{"crypto/internal/fips140/sha512", "\x03 \x1e\x01\x06,\x16\x7f"},
|
||||||
{"crypto/internal/fips140/subtle", "\x1e\a\x1a\xc5\x01"},
|
{"crypto/internal/fips140/ssh", "(b"},
|
||||||
{"crypto/internal/fips140/tls12", "\x03\x1f\x05\t\x06\x029\x15"},
|
{"crypto/internal/fips140/subtle", "\x1f\a\x1b\xc8\x01"},
|
||||||
{"crypto/internal/fips140/tls13", "\x03\x1f\x05\b\a\t2\x15"},
|
{"crypto/internal/fips140/tls12", "\x03 \x05\t\a\x02:\x16"},
|
||||||
{"crypto/internal/fips140cache", "\xae\x02\r&"},
|
{"crypto/internal/fips140/tls13", "\x03 \x05\b\b\t3\x16"},
|
||||||
|
{"crypto/internal/fips140cache", "\xb3\x02\r'"},
|
||||||
{"crypto/internal/fips140deps", ""},
|
{"crypto/internal/fips140deps", ""},
|
||||||
{"crypto/internal/fips140deps/byteorder", "\x9c\x01"},
|
{"crypto/internal/fips140deps/byteorder", "\xa0\x01"},
|
||||||
{"crypto/internal/fips140deps/cpu", "\xb1\x01\a"},
|
{"crypto/internal/fips140deps/cpu", "\xb5\x01\a"},
|
||||||
{"crypto/internal/fips140deps/godebug", "\xb9\x01"},
|
{"crypto/internal/fips140deps/godebug", "\xbd\x01"},
|
||||||
{"crypto/internal/fips140deps/time", "\xc9\x02"},
|
{"crypto/internal/fips140deps/time", "\xcf\x02"},
|
||||||
{"crypto/internal/fips140hash", "7\x1c3\xc9\x01"},
|
{"crypto/internal/fips140hash", "9\x1d4\xcb\x01"},
|
||||||
{"crypto/internal/fips140only", ")\r\x01\x01N3<"},
|
{"crypto/internal/fips140only", "\x17\x13\x0e\x01\x01Pp"},
|
||||||
{"crypto/internal/fips140test", ""},
|
{"crypto/internal/fips140test", ""},
|
||||||
{"crypto/internal/hpke", "\x0e\x01\x01\x03\x056#+hM"},
|
{"crypto/internal/impl", "\xbe\x02"},
|
||||||
{"crypto/internal/impl", "\xb9\x02"},
|
{"crypto/internal/rand", "\x1b\x0f s=["},
|
||||||
{"crypto/internal/randutil", "\xf5\x01\x12"},
|
{"crypto/internal/randutil", "\xfa\x01\x12"},
|
||||||
{"crypto/internal/sysrand", "qo! \r\r\x01\x01\f\x06"},
|
{"crypto/internal/sysrand", "tq! \r\r\x01\x01\r\x06"},
|
||||||
{"crypto/internal/sysrand/internal/seccomp", "q"},
|
{"crypto/internal/sysrand/internal/seccomp", "t"},
|
||||||
{"crypto/md5", "\x0e6-\x15\x16h"},
|
{"crypto/md5", "\x0e8.\x16\x16i"},
|
||||||
{"crypto/mlkem", "1"},
|
{"crypto/mlkem", "\x0e%"},
|
||||||
{"crypto/pbkdf2", "4\x0f\x01-\x15"},
|
{"crypto/mlkem/mlkemtest", "3\x13\b&"},
|
||||||
{"crypto/rand", "\x1a\b\a\x1b\x04\x01(\x84\x01\rM"},
|
{"crypto/pbkdf2", "6\x0f\x01.\x16"},
|
||||||
{"crypto/rc4", "%\x1f-\xc7\x01"},
|
{"crypto/rand", "\x1b\x0f\x1c\x03+\x86\x01\rN"},
|
||||||
{"crypto/rsa", "\x0e\f\x01\v\x0f\x0e\x01\x04\x06\a\x1c\x03\x123<\f\x01"},
|
{"crypto/rc4", "& .\xc9\x01"},
|
||||||
{"crypto/sha1", "\x0e\f*\x03*\x15\x16\x15S"},
|
{"crypto/rsa", "\x0e\r\x01\v\x10\x0e\x01\x03\b\a\x1c\x03\x133=\f\x01"},
|
||||||
{"crypto/sha256", "\x0e\f\x1cP"},
|
{"crypto/sha1", "\x0e\r+\x02,\x16\x16\x15T"},
|
||||||
{"crypto/sha3", "\x0e)O\xc9\x01"},
|
{"crypto/sha256", "\x0e\r\x1dR"},
|
||||||
{"crypto/sha512", "\x0e\f\x1eN"},
|
{"crypto/sha3", "\x0e+Q\xcb\x01"},
|
||||||
{"crypto/subtle", "\x1e\x1c\x9c\x01X"},
|
{"crypto/sha512", "\x0e\r\x1fP"},
|
||||||
{"crypto/tls", "\x03\b\x02\x01\x01\x01\x01\x02\x01\x01\x01\x02\x01\x01\t\x01\r\n\x01\n\x05\x03\x01\x01\x01\x01\x02\x01\x02\x01\x17\x02\x03\x12\x16\x15\b<\x16\x16\r\b\x01\x01\x01\x02\x01\r\x06\x02\x01\x0f"},
|
{"crypto/subtle", "\x1f\x1d\x9f\x01z"},
|
||||||
{"crypto/tls/internal/fips140tls", "\x17\xa5\x02"},
|
{"crypto/tls", "\x03\b\x02\x01\x01\x01\x01\x02\x01\x01\x01\x02\x01\x01\x01\t\x01\x18\x01\x0f\x01\x03\x01\x01\x01\x01\x02\x01\x02\x01\x17\x02\x03\x13\x16\x15\b=\x16\x16\r\b\x01\x01\x01\x02\x01\x0e\x06\x02\x01\x0f"},
|
||||||
{"crypto/x509", "\x03\v\x01\x01\x01\x01\x01\x01\x01\x015\x05\x01\x01\x02\x05\x0e\x06\x02\x02\x03E\x039\x01\x02\b\x01\x01\x02\a\x10\x05\x01\x06\x02\x05\b\x02\x01\x02\x0e\x02\x01\x01\x02\x03\x01"},
|
{"crypto/tls/internal/fips140tls", "\x17\xaa\x02"},
|
||||||
{"crypto/x509/pkix", "g\x06\a\x8e\x01G"},
|
{"crypto/x509", "\x03\v\x01\x01\x01\x01\x01\x01\x01\x017\x06\x01\x01\x02\x05\x0e\x06\x02\x02\x03F\x03:\x01\x02\b\x01\x01\x02\a\x10\x05\x01\x06\a\b\x02\x01\x02\x0f\x02\x01\x01\x02\x03\x01"},
|
||||||
{"database/sql", "\x03\nN\x16\x03\x81\x01\v\a\"\x05\b\x02\x03\x01\r\x02\x02\x02"},
|
{"crypto/x509/pkix", "j\x06\a\x90\x01H"},
|
||||||
{"database/sql/driver", "\rd\x03\xb5\x01\x0f\x11"},
|
{"database/sql", "\x03\nQ\x16\x03\x83\x01\v\a\"\x05\b\x02\x03\x01\x0e\x02\x02\x02"},
|
||||||
{"debug/buildinfo", "\x03[\x02\x01\x01\b\a\x03e\x1a\x02\x01+\x0f\x1f"},
|
{"database/sql/driver", "\rg\x03\xb7\x01\x0f\x12"},
|
||||||
{"debug/dwarf", "\x03g\a\x03\x81\x011\x11\x01\x01"},
|
{"debug/buildinfo", "\x03^\x02\x01\x01\b\a\x03g\x1a\x02\x01+\x0f "},
|
||||||
{"debug/elf", "\x03\x06T\r\a\x03e\x1b\x01\f \x17\x01\x16"},
|
{"debug/dwarf", "\x03j\a\x03\x83\x011\x11\x01\x01"},
|
||||||
{"debug/gosym", "\x03g\n\xc3\x01\x01\x01\x02"},
|
{"debug/elf", "\x03\x06W\r\a\x03g\x1b\x01\f \x17\x01\x17"},
|
||||||
{"debug/macho", "\x03\x06T\r\ne\x1c,\x17\x01"},
|
{"debug/gosym", "\x03j\n$\xa1\x01\x01\x01\x02"},
|
||||||
{"debug/pe", "\x03\x06T\r\a\x03e\x1c,\x17\x01\x16"},
|
{"debug/macho", "\x03\x06W\r\ng\x1c,\x17\x01"},
|
||||||
{"debug/plan9obj", "j\a\x03e\x1c,"},
|
{"debug/pe", "\x03\x06W\r\a\x03g\x1c,\x17\x01\x17"},
|
||||||
{"embed", "q*A\x19\x01S"},
|
{"debug/plan9obj", "m\a\x03g\x1c,"},
|
||||||
|
{"embed", "t+B\x19\x01T"},
|
||||||
{"embed/internal/embedtest", ""},
|
{"embed/internal/embedtest", ""},
|
||||||
{"encoding", ""},
|
{"encoding", ""},
|
||||||
{"encoding/ascii85", "\xf5\x01C"},
|
{"encoding/ascii85", "\xfa\x01C"},
|
||||||
{"encoding/asn1", "\x03n\x03e(\x01'\r\x02\x01\x10\x03\x01"},
|
{"encoding/asn1", "\x03q\x03g(\x01'\r\x02\x01\x11\x03\x01"},
|
||||||
{"encoding/base32", "\xf5\x01A\x02"},
|
{"encoding/base32", "\xfa\x01A\x02"},
|
||||||
{"encoding/base64", "\x9c\x01YA\x02"},
|
{"encoding/base64", "\xa0\x01ZA\x02"},
|
||||||
{"encoding/binary", "q\x84\x01\f(\r\x05"},
|
{"encoding/binary", "t\x86\x01\f(\r\x05"},
|
||||||
{"encoding/csv", "\x02\x01n\x03\x81\x01D\x12\x02"},
|
{"encoding/csv", "\x02\x01q\x03\x83\x01D\x13\x02"},
|
||||||
{"encoding/gob", "\x02c\x05\a\x03e\x1c\v\x01\x03\x1d\b\x12\x01\x0f\x02"},
|
{"encoding/gob", "\x02f\x05\a\x03g\x1c\v\x01\x03\x1d\b\x12\x01\x10\x02"},
|
||||||
{"encoding/hex", "q\x03\x81\x01A\x03"},
|
{"encoding/hex", "t\x03\x83\x01A\x03"},
|
||||||
{"encoding/json", "\x03\x01a\x04\b\x03\x81\x01\f(\r\x02\x01\x02\x10\x01\x01\x02"},
|
{"encoding/json", "\x03\x01d\x04\b\x03\x83\x01\f(\r\x02\x01\x02\x11\x01\x01\x02"},
|
||||||
{"encoding/pem", "\x03f\b\x84\x01A\x03"},
|
{"encoding/pem", "\x03i\b\x86\x01A\x03"},
|
||||||
{"encoding/xml", "\x02\x01b\f\x03\x81\x014\x05\n\x01\x02\x10\x02"},
|
{"encoding/xml", "\x02\x01e\f\x03\x83\x014\x05\n\x01\x02\x11\x02"},
|
||||||
{"errors", "\xcc\x01\x83\x01"},
|
{"errors", "\xd0\x01\x85\x01"},
|
||||||
{"expvar", "nK@\b\v\x15\r\b\x02\x03\x01\x11"},
|
{"expvar", "qLA\b\v\x15\r\b\x02\x03\x01\x12"},
|
||||||
{"flag", "e\f\x03\x81\x01,\b\x05\b\x02\x01\x10"},
|
{"flag", "h\f\x03\x83\x01,\b\x05\b\x02\x01\x11"},
|
||||||
{"fmt", "qE&\x19\f \b\r\x02\x03\x12"},
|
{"fmt", "tF'\x19\f \b\r\x02\x03\x13"},
|
||||||
{"go/ast", "\x03\x01p\x0e\x01r\x03)\b\r\x02\x01\x12\x02"},
|
{"go/ast", "\x03\x01s\x0f\x01s\x03)\b\r\x02\x01\x13\x02"},
|
||||||
{"go/build", "\x02\x01n\x03\x01\x02\x02\a\x02\x01\x17\x1f\x04\x02\b\x1b\x13\x01+\x01\x04\x01\a\b\x02\x01\x12\x02\x02"},
|
{"go/build", "\x02\x01q\x03\x01\x02\x02\b\x02\x01\x17\x1f\x04\x02\b\x1c\x13\x01+\x01\x04\x01\a\b\x02\x01\x13\x02\x02"},
|
||||||
{"go/build/constraint", "q\xc7\x01\x01\x12\x02"},
|
{"go/build/constraint", "t\xc9\x01\x01\x13\x02"},
|
||||||
{"go/constant", "t\x0f~\x01\x024\x01\x02\x12"},
|
{"go/constant", "w\x10\x7f\x01\x024\x01\x02\x13"},
|
||||||
{"go/doc", "\x04p\x01\x05\t=51\x10\x02\x01\x12\x02"},
|
{"go/doc", "\x04s\x01\x05\n=61\x10\x02\x01\x13\x02"},
|
||||||
{"go/doc/comment", "\x03q\xc2\x01\x01\x01\x01\x12\x02"},
|
{"go/doc/comment", "\x03t\xc4\x01\x01\x01\x01\x13\x02"},
|
||||||
{"go/format", "\x03q\x01\v\x01\x02rD"},
|
{"go/format", "\x03t\x01\f\x01\x02sD"},
|
||||||
{"go/importer", "v\a\x01\x01\x04\x01q9"},
|
{"go/importer", "y\a\x01\x02\x04\x01r9"},
|
||||||
{"go/internal/gccgoimporter", "\x02\x01[\x13\x03\x04\v\x01o\x02,\x01\x05\x11\x01\f\b"},
|
{"go/internal/gccgoimporter", "\x02\x01^\x13\x03\x04\f\x01p\x02,\x01\x05\x11\x01\r\b"},
|
||||||
{"go/internal/gcimporter", "\x02r\x0f\x010\x05\r/,\x15\x03\x02"},
|
{"go/internal/gcimporter", "\x02u\x10\x010\x05\r0,\x15\x03\x02"},
|
||||||
{"go/internal/srcimporter", "t\x01\x01\n\x03\x01q,\x01\x05\x12\x02\x14"},
|
{"go/internal/scannerhooks", "\x87\x01"},
|
||||||
{"go/parser", "\x03n\x03\x01\x02\v\x01r\x01+\x06\x12"},
|
{"go/internal/srcimporter", "w\x01\x01\v\x03\x01r,\x01\x05\x12\x02\x15"},
|
||||||
{"go/printer", "t\x01\x02\x03\tr\f \x15\x02\x01\x02\v\x05\x02"},
|
{"go/parser", "\x03q\x03\x01\x02\b\x04\x01s\x01+\x06\x12"},
|
||||||
{"go/scanner", "\x03q\x0fr2\x10\x01\x13\x02"},
|
{"go/printer", "w\x01\x02\x03\ns\f \x15\x02\x01\x02\f\x05\x02"},
|
||||||
{"go/token", "\x04p\x84\x01>\x02\x03\x01\x0f\x02"},
|
{"go/scanner", "\x03t\v\x05s2\x10\x01\x14\x02"},
|
||||||
{"go/types", "\x03\x01\x06g\x03\x01\x03\b\x03\x024\x062\x04\x03\t \x06\a\b\x01\x01\x01\x02\x01\x0f\x02\x02"},
|
{"go/token", "\x04s\x86\x01>\x02\x03\x01\x10\x02"},
|
||||||
{"go/version", "\xbe\x01{"},
|
{"go/types", "\x03\x01\x06j\x03\x01\x03\t\x03\x024\x063\x04\x03\t \x06\a\b\x01\x01\x01\x02\x01\x10\x02\x02"},
|
||||||
{"hash", "\xf5\x01"},
|
{"go/version", "\xc2\x01|"},
|
||||||
{"hash/adler32", "q\x15\x16"},
|
{"hash", "\xfa\x01"},
|
||||||
{"hash/crc32", "q\x15\x16\x15\x8a\x01\x01\x13"},
|
{"hash/adler32", "t\x16\x16"},
|
||||||
{"hash/crc64", "q\x15\x16\x9f\x01"},
|
{"hash/crc32", "t\x16\x16\x15\x8b\x01\x01\x14"},
|
||||||
{"hash/fnv", "q\x15\x16h"},
|
{"hash/crc64", "t\x16\x16\xa0\x01"},
|
||||||
{"hash/maphash", "\x86\x01\x11<|"},
|
{"hash/fnv", "t\x16\x16i"},
|
||||||
{"html", "\xb9\x02\x02\x12"},
|
{"hash/maphash", "\x8a\x01\x11<~"},
|
||||||
{"html/template", "\x03k\x06\x18-<\x01\n!\x05\x01\x02\x03\f\x01\x02\f\x01\x03\x02"},
|
{"html", "\xbe\x02\x02\x13"},
|
||||||
{"image", "\x02o\x1ef\x0f4\x03\x01"},
|
{"html/template", "\x03n\x06\x19-=\x01\n!\x05\x01\x02\x03\f\x01\x02\r\x01\x03\x02"},
|
||||||
|
{"image", "\x02r\x1fg\x0f4\x03\x01"},
|
||||||
{"image/color", ""},
|
{"image/color", ""},
|
||||||
{"image/color/palette", "\x8f\x01"},
|
{"image/color/palette", "\x93\x01"},
|
||||||
{"image/draw", "\x8e\x01\x01\x04"},
|
{"image/draw", "\x92\x01\x01\x04"},
|
||||||
{"image/gif", "\x02\x01\x05i\x03\x1a\x01\x01\x01\vY"},
|
{"image/gif", "\x02\x01\x05l\x03\x1b\x01\x01\x01\vZ\x0f"},
|
||||||
{"image/internal/imageutil", "\x8e\x01"},
|
{"image/internal/imageutil", "\x92\x01"},
|
||||||
{"image/jpeg", "\x02o\x1d\x01\x04b"},
|
{"image/jpeg", "\x02r\x1e\x01\x04c"},
|
||||||
{"image/png", "\x02\aa\n\x12\x02\x06\x01fC"},
|
{"image/png", "\x02\ad\n\x13\x02\x06\x01gC"},
|
||||||
{"index/suffixarray", "\x03g\a\x84\x01\f+\n\x01"},
|
{"index/suffixarray", "\x03j\a\x86\x01\f+\n\x01"},
|
||||||
{"internal/abi", "\xb8\x01\x97\x01"},
|
{"internal/abi", "\xbc\x01\x99\x01"},
|
||||||
{"internal/asan", "\xcf\x02"},
|
{"internal/asan", "\xd5\x02"},
|
||||||
{"internal/bisect", "\xae\x02\r\x01"},
|
{"internal/bisect", "\xb3\x02\r\x01"},
|
||||||
{"internal/buildcfg", "tGf\x06\x02\x05\n\x01"},
|
{"internal/buildcfg", "wHg\x06\x02\x05\n\x01"},
|
||||||
{"internal/bytealg", "\xb1\x01\x9e\x01"},
|
{"internal/bytealg", "\xb5\x01\xa0\x01"},
|
||||||
{"internal/byteorder", ""},
|
{"internal/byteorder", ""},
|
||||||
{"internal/cfg", ""},
|
{"internal/cfg", ""},
|
||||||
{"internal/cgrouptest", "tZS\x06\x0f\x02\x01\x04\x01"},
|
{"internal/cgrouptest", "w[T\x06\x0f\x02\x01\x04\x01"},
|
||||||
{"internal/chacha8rand", "\x9c\x01\x15\a\x97\x01"},
|
{"internal/chacha8rand", "\xa0\x01\x15\a\x99\x01"},
|
||||||
{"internal/copyright", ""},
|
{"internal/copyright", ""},
|
||||||
{"internal/coverage", ""},
|
{"internal/coverage", ""},
|
||||||
{"internal/coverage/calloc", ""},
|
{"internal/coverage/calloc", ""},
|
||||||
{"internal/coverage/cfile", "n\x06\x16\x17\x01\x02\x01\x01\x01\x01\x01\x01\x01\"\x02&,\x06\a\n\x01\x03\r\x06"},
|
{"internal/coverage/cfile", "q\x06\x17\x17\x01\x02\x01\x01\x01\x01\x01\x01\x01\"\x02',\x06\a\n\x01\x03\x0e\x06"},
|
||||||
{"internal/coverage/cformat", "\x04p-\x04P\v6\x01\x02\r"},
|
{"internal/coverage/cformat", "\x04s.\x04Q\v6\x01\x02\x0e"},
|
||||||
{"internal/coverage/cmerge", "t-`"},
|
{"internal/coverage/cmerge", "w.a"},
|
||||||
{"internal/coverage/decodecounter", "j\n-\v\x02G,\x17\x17"},
|
{"internal/coverage/decodecounter", "m\n.\v\x02H,\x17\x18"},
|
||||||
{"internal/coverage/decodemeta", "\x02h\n\x16\x17\v\x02G,"},
|
{"internal/coverage/decodemeta", "\x02k\n\x17\x17\v\x02H,"},
|
||||||
{"internal/coverage/encodecounter", "\x02h\n-\f\x01\x02E\v!\x15"},
|
{"internal/coverage/encodecounter", "\x02k\n.\f\x01\x02F\v!\x15"},
|
||||||
{"internal/coverage/encodemeta", "\x02\x01g\n\x12\x04\x17\r\x02E,."},
|
{"internal/coverage/encodemeta", "\x02\x01j\n\x13\x04\x17\r\x02F,/"},
|
||||||
{"internal/coverage/pods", "\x04p-\x80\x01\x06\x05\n\x02\x01"},
|
{"internal/coverage/pods", "\x04s.\x81\x01\x06\x05\n\x02\x01"},
|
||||||
{"internal/coverage/rtcov", "\xcf\x02"},
|
{"internal/coverage/rtcov", "\xd5\x02"},
|
||||||
{"internal/coverage/slicereader", "j\n\x81\x01Z"},
|
{"internal/coverage/slicereader", "m\n\x83\x01["},
|
||||||
{"internal/coverage/slicewriter", "t\x81\x01"},
|
{"internal/coverage/slicewriter", "w\x83\x01"},
|
||||||
{"internal/coverage/stringtab", "t8\x04E"},
|
{"internal/coverage/stringtab", "w9\x04F"},
|
||||||
{"internal/coverage/test", ""},
|
{"internal/coverage/test", ""},
|
||||||
{"internal/coverage/uleb128", ""},
|
{"internal/coverage/uleb128", ""},
|
||||||
{"internal/cpu", "\xcf\x02"},
|
{"internal/cpu", "\xd5\x02"},
|
||||||
{"internal/dag", "\x04p\xc2\x01\x03"},
|
{"internal/dag", "\x04s\xc4\x01\x03"},
|
||||||
{"internal/diff", "\x03q\xc3\x01\x02"},
|
{"internal/diff", "\x03t\xc5\x01\x02"},
|
||||||
{"internal/exportdata", "\x02\x01n\x03\x02c\x1c,\x01\x05\x11\x01\x02"},
|
{"internal/exportdata", "\x02\x01q\x03\x02e\x1c,\x01\x05\x11\x01\x02"},
|
||||||
{"internal/filepathlite", "q*A\x1a@"},
|
{"internal/filepathlite", "t+B\x1a@"},
|
||||||
{"internal/fmtsort", "\x04\xa5\x02\r"},
|
{"internal/fmtsort", "\x04\xaa\x02\r"},
|
||||||
{"internal/fuzz", "\x03\nE\x18\x04\x03\x03\x01\v\x036<\f\x03\x1d\x01\x05\x02\x05\n\x01\x02\x01\x01\f\x04\x02"},
|
{"internal/fuzz", "\x03\nH\x18\x04\x03\x03\x01\f\x036=\f\x03\x1d\x01\x05\x02\x05\n\x01\x02\x01\x01\r\x04\x02"},
|
||||||
{"internal/goarch", ""},
|
{"internal/goarch", ""},
|
||||||
{"internal/godebug", "\x99\x01!\x81\x01\x01\x13"},
|
{"internal/godebug", "\x9d\x01!\x82\x01\x01\x14"},
|
||||||
{"internal/godebugs", ""},
|
{"internal/godebugs", ""},
|
||||||
{"internal/goexperiment", ""},
|
{"internal/goexperiment", ""},
|
||||||
{"internal/goos", ""},
|
{"internal/goos", ""},
|
||||||
{"internal/goroot", "\xa1\x02\x01\x05\x12\x02"},
|
{"internal/goroot", "\xa6\x02\x01\x05\x12\x02"},
|
||||||
{"internal/gover", "\x04"},
|
{"internal/gover", "\x04"},
|
||||||
{"internal/goversion", ""},
|
{"internal/goversion", ""},
|
||||||
{"internal/lazyregexp", "\xa1\x02\v\r\x02"},
|
{"internal/lazyregexp", "\xa6\x02\v\r\x02"},
|
||||||
{"internal/lazytemplate", "\xf5\x01,\x18\x02\f"},
|
{"internal/lazytemplate", "\xfa\x01,\x18\x02\r"},
|
||||||
{"internal/msan", "\xcf\x02"},
|
{"internal/msan", "\xd5\x02"},
|
||||||
{"internal/nettrace", ""},
|
{"internal/nettrace", ""},
|
||||||
{"internal/obscuretestdata", "i\x8c\x01,"},
|
{"internal/obscuretestdata", "l\x8e\x01,"},
|
||||||
{"internal/oserror", "q"},
|
{"internal/oserror", "t"},
|
||||||
{"internal/pkgbits", "\x03O\x18\a\x03\x04\vr\r\x1f\r\n\x01"},
|
{"internal/pkgbits", "\x03R\x18\a\x03\x04\fs\r\x1f\r\n\x01"},
|
||||||
{"internal/platform", ""},
|
{"internal/platform", ""},
|
||||||
{"internal/poll", "qj\x05\x159\r\x01\x01\f\x06"},
|
{"internal/poll", "tl\x05\x159\r\x01\x01\r\x06"},
|
||||||
{"internal/profile", "\x03\x04j\x03\x81\x017\n\x01\x01\x01\x10"},
|
{"internal/profile", "\x03\x04m\x03\x83\x017\n\x01\x01\x01\x11"},
|
||||||
{"internal/profilerecord", ""},
|
{"internal/profilerecord", ""},
|
||||||
{"internal/race", "\x97\x01\xb8\x01"},
|
{"internal/race", "\x9b\x01\xba\x01"},
|
||||||
{"internal/reflectlite", "\x97\x01!:<!"},
|
{"internal/reflectlite", "\x9b\x01!;<\""},
|
||||||
{"internal/runtime/atomic", "\xb8\x01\x97\x01"},
|
{"internal/runtime/atomic", "\xbc\x01\x99\x01"},
|
||||||
{"internal/runtime/cgroup", "\x9b\x01<\x04t"},
|
{"internal/runtime/cgroup", "\x9f\x01=\x04u"},
|
||||||
{"internal/runtime/exithook", "\xcd\x01\x82\x01"},
|
{"internal/runtime/exithook", "\xd1\x01\x84\x01"},
|
||||||
{"internal/runtime/gc", "\xb8\x01"},
|
{"internal/runtime/gc", "\xbc\x01"},
|
||||||
{"internal/runtime/gc/internal/gen", "\n`\n\x17j\x04\v\x1d\b\x10\x02"},
|
{"internal/runtime/gc/internal/gen", "\nc\n\x18k\x04\v\x1d\b\x10\x02"},
|
||||||
{"internal/runtime/gc/scan", "\xb1\x01\a\x18\x06y"},
|
{"internal/runtime/gc/scan", "\xb5\x01\a\x18\az"},
|
||||||
{"internal/runtime/maps", "\x97\x01\x01 \n\t\t\x02y"},
|
{"internal/runtime/maps", "\x9b\x01\x01 \n\t\t\x03z"},
|
||||||
{"internal/runtime/math", "\xb8\x01"},
|
{"internal/runtime/math", "\xbc\x01"},
|
||||||
|
{"internal/runtime/pprof/label", ""},
|
||||||
{"internal/runtime/startlinetest", ""},
|
{"internal/runtime/startlinetest", ""},
|
||||||
{"internal/runtime/sys", "\xb8\x01\x04"},
|
{"internal/runtime/sys", "\xbc\x01\x04"},
|
||||||
{"internal/runtime/syscall/linux", "\xb8\x01\x97\x01"},
|
{"internal/runtime/syscall/linux", "\xbc\x01\x99\x01"},
|
||||||
{"internal/runtime/wasitest", ""},
|
{"internal/runtime/wasitest", ""},
|
||||||
{"internal/saferio", "\xf5\x01Z"},
|
{"internal/saferio", "\xfa\x01["},
|
||||||
{"internal/singleflight", "\xbb\x02"},
|
{"internal/singleflight", "\xc0\x02"},
|
||||||
{"internal/strconv", "\x84\x02K"},
|
{"internal/strconv", "\x89\x02L"},
|
||||||
{"internal/stringslite", "\x9b\x01\xb4\x01"},
|
{"internal/stringslite", "\x9f\x01\xb6\x01"},
|
||||||
{"internal/sync", "\x97\x01!\x13q\x13"},
|
{"internal/sync", "\x9b\x01!\x13r\x14"},
|
||||||
{"internal/synctest", "\x97\x01\xb8\x01"},
|
{"internal/synctest", "\x9b\x01\xba\x01"},
|
||||||
{"internal/syscall/execenv", "\xbd\x02"},
|
{"internal/syscall/execenv", "\xc2\x02"},
|
||||||
{"internal/syscall/unix", "\xae\x02\x0e\x01\x12"},
|
{"internal/syscall/unix", "\xb3\x02\x0e\x01\x13"},
|
||||||
{"internal/sysinfo", "\x02\x01\xae\x01D,\x18\x02"},
|
{"internal/sysinfo", "\x02\x01\xb2\x01E,\x18\x02"},
|
||||||
{"internal/syslist", ""},
|
{"internal/syslist", ""},
|
||||||
{"internal/testenv", "\x03\nd\x02\x01)\x1b\x0f/+\x01\x05\a\n\x01\x02\x02\x01\v"},
|
{"internal/testenv", "\x03\ng\x02\x01*\x1b\x0f0+\x01\x05\a\n\x01\x02\x02\x01\f"},
|
||||||
{"internal/testhash", "\x03\x83\x01o\x118\v"},
|
{"internal/testhash", "\x03\x87\x01p\x118\f"},
|
||||||
{"internal/testlog", "\xbb\x02\x01\x13"},
|
{"internal/testlog", "\xc0\x02\x01\x14"},
|
||||||
{"internal/testpty", "q\x03\xad\x01"},
|
{"internal/testpty", "t\x03\xaf\x01"},
|
||||||
{"internal/trace", "\x02\x01\x01\x06`\a\x03u\x03\x03\x06\x03\t5\x01\x01\x01\x10\x06"},
|
{"internal/trace", "\x02\x01\x01\x06c\a\x03w\x03\x03\x06\x03\t+\n\x01\x01\x01\x11\x06"},
|
||||||
{"internal/trace/internal/testgen", "\x03g\ns\x03\x02\x03\x011\v\r\x10"},
|
{"internal/trace/internal/testgen", "\x03j\nu\x03\x02\x03\x011\v\r\x11"},
|
||||||
{"internal/trace/internal/tracev1", "\x03\x01f\a\x03{\x06\f5\x01"},
|
{"internal/trace/internal/tracev1", "\x03\x01i\a\x03}\x06\f5\x01"},
|
||||||
{"internal/trace/raw", "\x02h\nx\x03\x06C\x01\x12"},
|
{"internal/trace/raw", "\x02k\nz\x03\x06C\x01\x13"},
|
||||||
{"internal/trace/testtrace", "\x02\x01n\x03o\x04\x03\x05\x01\x05,\v\x02\b\x02\x01\x05"},
|
{"internal/trace/testtrace", "\x02\x01q\x03q\x04\x03\x05\x01\x05,\v\x02\b\x02\x01\x05"},
|
||||||
{"internal/trace/tracev2", ""},
|
{"internal/trace/tracev2", ""},
|
||||||
{"internal/trace/traceviewer", "\x02a\v\x06\x19<\x1e\a\a\x04\b\v\x15\x01\x05\a\n\x01\x02\x0e"},
|
{"internal/trace/traceviewer", "\x02d\v\x06\x1a<\x1f\a\a\x04\b\v\x15\x01\x05\a\n\x01\x02\x0f"},
|
||||||
{"internal/trace/traceviewer/format", ""},
|
{"internal/trace/traceviewer/format", ""},
|
||||||
{"internal/trace/version", "tx\t"},
|
{"internal/trace/version", "wz\t"},
|
||||||
{"internal/txtar", "\x03q\xad\x01\x18"},
|
{"internal/txtar", "\x03t\xaf\x01\x18"},
|
||||||
{"internal/types/errors", "\xb8\x02"},
|
{"internal/types/errors", "\xbd\x02"},
|
||||||
{"internal/unsafeheader", "\xcf\x02"},
|
{"internal/unsafeheader", "\xd5\x02"},
|
||||||
{"internal/xcoff", "]\r\a\x03e\x1c,\x17\x01"},
|
{"internal/xcoff", "`\r\a\x03g\x1c,\x17\x01"},
|
||||||
{"internal/zstd", "j\a\x03\x81\x01\x0f"},
|
{"internal/zstd", "m\a\x03\x83\x01\x0f"},
|
||||||
{"io", "q\xca\x01"},
|
{"io", "t\xcc\x01"},
|
||||||
{"io/fs", "q**01\x10\x13\x04"},
|
{"io/fs", "t+*11\x10\x14\x04"},
|
||||||
{"io/ioutil", "\xf5\x01\x01+\x15\x03"},
|
{"io/ioutil", "\xfa\x01\x01+\x15\x03"},
|
||||||
{"iter", "\xcb\x01c!"},
|
{"iter", "\xcf\x01d\""},
|
||||||
{"log", "t\x81\x01\x05'\r\r\x01\r"},
|
{"log", "w\x83\x01\x05'\r\r\x01\x0e"},
|
||||||
{"log/internal", ""},
|
{"log/internal", ""},
|
||||||
{"log/slog", "\x03\nX\t\x03\x03\x81\x01\x04\x01\x02\x02\x03(\x05\b\x02\x01\x02\x01\r\x02\x02\x02"},
|
{"log/slog", "\x03\n[\t\x03\x03\x83\x01\x04\x01\x02\x02\x03(\x05\b\x02\x01\x02\x01\x0e\x02\x02\x02"},
|
||||||
{"log/slog/internal", ""},
|
{"log/slog/internal", ""},
|
||||||
{"log/slog/internal/benchmarks", "\rd\x03\x81\x01\x06\x03:\x11"},
|
{"log/slog/internal/benchmarks", "\rg\x03\x83\x01\x06\x03:\x12"},
|
||||||
{"log/slog/internal/buffer", "\xbb\x02"},
|
{"log/slog/internal/buffer", "\xc0\x02"},
|
||||||
{"log/syslog", "q\x03\x85\x01\x12\x16\x18\x02\x0e"},
|
{"log/syslog", "t\x03\x87\x01\x12\x16\x18\x02\x0f"},
|
||||||
{"maps", "\xf8\x01W"},
|
{"maps", "\xfd\x01X"},
|
||||||
{"math", "\xb1\x01SK"},
|
{"math", "\xb5\x01TL"},
|
||||||
{"math/big", "\x03n\x03(\x15D\f\x03\x020\x02\x01\x02\x14"},
|
{"math/big", "\x03q\x03)\x15E\f\x03\x020\x02\x01\x02\x15"},
|
||||||
{"math/big/internal/asmgen", "\x03\x01p\x90\x012\x03"},
|
{"math/big/internal/asmgen", "\x03\x01s\x92\x012\x03"},
|
||||||
{"math/bits", "\xcf\x02"},
|
{"math/bits", "\xd5\x02"},
|
||||||
{"math/cmplx", "\x81\x02\x03"},
|
{"math/cmplx", "\x86\x02\x03"},
|
||||||
{"math/rand", "\xb9\x01H:\x01\x13"},
|
{"math/rand", "\xbd\x01I:\x01\x14"},
|
||||||
{"math/rand/v2", "q+\x03b\x03K"},
|
{"math/rand/v2", "t,\x03c\x03L"},
|
||||||
{"mime", "\x02\x01f\b\x03\x81\x01\v!\x15\x03\x02\x10\x02"},
|
{"mime", "\x02\x01i\b\x03\x83\x01\v!\x15\x03\x02\x11\x02"},
|
||||||
{"mime/multipart", "\x02\x01K#\x03E<\v\x01\a\x02\x15\x02\x06\x0f\x02\x01\x16"},
|
{"mime/multipart", "\x02\x01N#\x03F=\v\x01\a\x02\x15\x02\x06\x0f\x02\x01\x17"},
|
||||||
{"mime/quotedprintable", "\x02\x01q\x81\x01"},
|
{"mime/quotedprintable", "\x02\x01t\x83\x01"},
|
||||||
{"net", "\x04\td*\x1e\n\x05\x12\x01\x01\x04\x15\x01%\x06\r\b\x05\x01\x01\f\x06\a"},
|
{"net", "\x04\tg+\x1e\n\x05\x13\x01\x01\x04\x15\x01%\x06\r\b\x05\x01\x01\r\x06\a"},
|
||||||
{"net/http", "\x02\x01\x03\x01\x04\x02A\b\x13\x01\a\x03E<\x01\x03\a\x01\x03\x02\x02\x01\x02\x06\x02\x01\x01\n\x01\x01\x05\x01\x02\x05\b\x01\x01\x01\x02\x01\r\x02\x02\x02\b\x01\x01\x01"},
|
{"net/http", "\x02\x01\x03\x01\x04\x02D\b\x13\x01\a\x03F=\x01\x03\a\x01\x03\x02\x02\x01\x02\x06\x02\x01\x01\n\x01\x01\x05\x01\x02\x05\b\x01\x01\x01\x02\x01\x0e\x02\x02\x02\b\x01\x01\x01"},
|
||||||
{"net/http/cgi", "\x02T\x1b\x03\x81\x01\x04\a\v\x01\x13\x01\x01\x01\x04\x01\x05\x02\b\x02\x01\x10\x0e"},
|
{"net/http/cgi", "\x02W\x1b\x03\x83\x01\x04\a\v\x01\x13\x01\x01\x01\x04\x01\x05\x02\b\x02\x01\x11\x0e"},
|
||||||
{"net/http/cookiejar", "\x04m\x03\x97\x01\x01\b\f\x16\x03\x02\x0e\x04"},
|
{"net/http/cookiejar", "\x04p\x03\x99\x01\x01\b\a\x05\x16\x03\x02\x0f\x04"},
|
||||||
{"net/http/fcgi", "\x02\x01\n]\a\x03\x81\x01\x16\x01\x01\x14\x18\x02\x0e"},
|
{"net/http/fcgi", "\x02\x01\n`\a\x03\x83\x01\x16\x01\x01\x14\x18\x02\x0f"},
|
||||||
{"net/http/httptest", "\x02\x01\nI\x02\x1b\x01\x81\x01\x04\x12\x01\n\t\x02\x17\x01\x02\x0e\x0e"},
|
{"net/http/httptest", "\x02\x01\nL\x02\x1b\x01\x83\x01\x04\x12\x01\n\t\x02\x17\x01\x02\x0f\x0e"},
|
||||||
{"net/http/httptrace", "\rImH\x14\n "},
|
{"net/http/httptrace", "\rLnI\x14\n!"},
|
||||||
{"net/http/httputil", "\x02\x01\nd\x03\x81\x01\x04\x0f\x03\x01\x05\x02\x01\v\x01\x19\x02\x0e\x0e"},
|
{"net/http/httputil", "\x02\x01\ng\x03\x83\x01\x04\x0f\x03\x01\x05\x02\x01\v\x01\x19\x02\x01\x0e\x0e"},
|
||||||
{"net/http/internal", "\x02\x01n\x03\x81\x01"},
|
{"net/http/internal", "\x02\x01q\x03\x83\x01"},
|
||||||
{"net/http/internal/ascii", "\xb9\x02\x12"},
|
{"net/http/internal/ascii", "\xbe\x02\x13"},
|
||||||
{"net/http/internal/httpcommon", "\rd\x03\x9d\x01\x0e\x01\x17\x01\x01\x02\x1c\x02"},
|
{"net/http/internal/httpcommon", "\rg\x03\x9f\x01\x0e\x01\x17\x01\x01\x02\x1d\x02"},
|
||||||
{"net/http/internal/testcert", "\xb9\x02"},
|
{"net/http/internal/testcert", "\xbe\x02"},
|
||||||
{"net/http/pprof", "\x02\x01\ng\x18-\x02\x0e,\x04\x13\x14\x01\r\x04\x03\x01\x02\x01\x10"},
|
{"net/http/pprof", "\x02\x01\nj\x19-\x02\x0e-\x04\x13\x14\x01\r\x04\x03\x01\x02\x01\x11"},
|
||||||
{"net/internal/cgotest", ""},
|
{"net/internal/cgotest", ""},
|
||||||
{"net/internal/socktest", "t\xc7\x01\x02"},
|
{"net/internal/socktest", "w\xc9\x01\x02"},
|
||||||
{"net/mail", "\x02o\x03\x81\x01\x04\x0f\x03\x14\x1a\x02\x0e\x04"},
|
{"net/mail", "\x02r\x03\x83\x01\x04\x0f\x03\x14\x1a\x02\x0f\x04"},
|
||||||
{"net/netip", "\x04m*\x01e\x034\x16"},
|
{"net/netip", "\x04p+\x01f\x034\x17"},
|
||||||
{"net/rpc", "\x02j\x05\x03\x0f\nh\x04\x12\x01\x1d\r\x03\x02"},
|
{"net/rpc", "\x02m\x05\x03\x10\ni\x04\x12\x01\x1d\r\x03\x02"},
|
||||||
{"net/rpc/jsonrpc", "n\x03\x03\x81\x01\x16\x11\x1f"},
|
{"net/rpc/jsonrpc", "q\x03\x03\x83\x01\x16\x11\x1f"},
|
||||||
{"net/smtp", "\x192\v\x13\b\x03\x81\x01\x16\x14\x1a"},
|
{"net/smtp", "\x194\f\x13\b\x03\x83\x01\x16\x14\x1a"},
|
||||||
{"net/textproto", "\x02\x01n\x03\x81\x01\f\n-\x01\x02\x14"},
|
{"net/textproto", "\x02\x01q\x03\x83\x01\f\n-\x01\x02\x15"},
|
||||||
{"net/url", "q\x03\xa7\x01\v\x10\x02\x01\x16"},
|
{"net/url", "t\x03Fc\v\x10\x02\x01\x17"},
|
||||||
{"os", "q*\x01\x19\x03\x10\x13\x01\x03\x01\x05\x10\x018\b\x05\x01\x01\f\x06"},
|
{"os", "t+\x01\x19\x03\x10\x14\x01\x03\x01\x05\x10\x018\b\x05\x01\x01\r\x06"},
|
||||||
{"os/exec", "\x03\ndH&\x01\x15\x01+\x06\a\n\x01\x04\f"},
|
{"os/exec", "\x03\ngI'\x01\x15\x01+\x06\a\n\x01\x03\x01\r"},
|
||||||
{"os/exec/internal/fdtest", "\xbd\x02"},
|
{"os/exec/internal/fdtest", "\xc2\x02"},
|
||||||
{"os/signal", "\r\x94\x02\x15\x05\x02"},
|
{"os/signal", "\r\x99\x02\x15\x05\x02"},
|
||||||
{"os/user", "\x02\x01n\x03\x81\x01,\r\n\x01\x02"},
|
{"os/user", "\x02\x01q\x03\x83\x01,\r\n\x01\x02"},
|
||||||
{"path", "q*\xb2\x01"},
|
{"path", "t+\xb4\x01"},
|
||||||
{"path/filepath", "q*\x1aA+\r\b\x03\x04\x10"},
|
{"path/filepath", "t+\x1aB+\r\b\x03\x04\x11"},
|
||||||
{"plugin", "q"},
|
{"plugin", "t"},
|
||||||
{"reflect", "q&\x04\x1d\x13\b\x03\x05\x17\x06\t-\n\x03\x10\x02\x02"},
|
{"reflect", "t'\x04\x1d\x13\b\x04\x05\x17\x06\t-\n\x03\x11\x02\x02"},
|
||||||
{"reflect/internal/example1", ""},
|
{"reflect/internal/example1", ""},
|
||||||
{"reflect/internal/example2", ""},
|
{"reflect/internal/example2", ""},
|
||||||
{"regexp", "\x03\xf2\x018\t\x02\x01\x02\x10\x02"},
|
{"regexp", "\x03\xf7\x018\t\x02\x01\x02\x11\x02"},
|
||||||
{"regexp/syntax", "\xb6\x02\x01\x01\x01\x02\x10\x02"},
|
{"regexp/syntax", "\xbb\x02\x01\x01\x01\x02\x11\x02"},
|
||||||
{"runtime", "\x97\x01\x04\x01\x03\f\x06\a\x02\x01\x01\x0e\x03\x01\x01\x01\x02\x01\x01\x02\x01\x04\x01\x10c"},
|
{"runtime", "\x9b\x01\x04\x01\x03\f\x06\a\x02\x01\x01\x0e\x03\x01\x01\x01\x02\x01\x01\x01\x02\x01\x04\x01\x10\x18L"},
|
||||||
{"runtime/coverage", "\xa3\x01R"},
|
{"runtime/coverage", "\xa7\x01S"},
|
||||||
{"runtime/debug", "tTY\r\b\x02\x01\x10\x06"},
|
{"runtime/debug", "wUZ\r\b\x02\x01\x11\x06"},
|
||||||
{"runtime/metrics", "\xba\x01G-!"},
|
{"runtime/metrics", "\xbe\x01H-\""},
|
||||||
{"runtime/pprof", "\x02\x01\x01\x03\x06]\a\x03#$\x0f+\f \r\b\x01\x01\x01\x02\x02\t\x03\x06"},
|
{"runtime/pprof", "\x02\x01\x01\x03\x06`\a\x03$$\x0f\v!\f \r\b\x01\x01\x01\x02\x02\n\x03\x06"},
|
||||||
{"runtime/race", "\xb4\x02"},
|
{"runtime/race", "\xb9\x02"},
|
||||||
{"runtime/race/internal/amd64v1", ""},
|
{"runtime/race/internal/amd64v1", ""},
|
||||||
{"runtime/trace", "\rd\x03x\t9\b\x05\x01\r\x06"},
|
{"runtime/trace", "\rg\x03z\t9\b\x05\x01\x0e\x06"},
|
||||||
{"slices", "\x04\xf4\x01\fK"},
|
{"slices", "\x04\xf9\x01\fL"},
|
||||||
{"sort", "\xcc\x0182"},
|
{"sort", "\xd0\x0192"},
|
||||||
{"strconv", "q*@\x01q"},
|
{"strconv", "t+A\x01r"},
|
||||||
{"strings", "q&\x04A\x19\x03\f7\x10\x02\x02"},
|
{"strings", "t'\x04B\x19\x03\f7\x11\x02\x02"},
|
||||||
{"structs", ""},
|
{"structs", ""},
|
||||||
{"sync", "\xcb\x01\x12\x01P\x0e\x13"},
|
{"sync", "\xcf\x01\x13\x01P\x0e\x14"},
|
||||||
{"sync/atomic", "\xcf\x02"},
|
{"sync/atomic", "\xd5\x02"},
|
||||||
{"syscall", "q'\x03\x01\x1c\n\x03\x06\f\x04S\b\x05\x01\x13"},
|
{"syscall", "t(\x03\x01\x1c\n\x03\x06\r\x04S\b\x05\x01\x14"},
|
||||||
{"testing", "\x03\nd\x02\x01W\x16\x14\f\x05\x1b\x06\x02\x05\x02\x05\x01\x02\x01\x02\x01\r\x02\x04"},
|
{"testing", "\x03\ng\x02\x01X\x17\x14\f\x05\x1b\x06\x02\x05\x02\x05\x01\x02\x01\x02\x01\x0e\x02\x04"},
|
||||||
{"testing/fstest", "q\x03\x81\x01\x01\n&\x10\x03\b\b"},
|
{"testing/cryptotest", "QOZ\x124\x03\x12"},
|
||||||
{"testing/internal/testdeps", "\x02\v\xaa\x01.\x10,\x03\x05\x03\x06\a\x02\x0e"},
|
{"testing/fstest", "t\x03\x83\x01\x01\n&\x10\x03\t\b"},
|
||||||
{"testing/iotest", "\x03n\x03\x81\x01\x04"},
|
{"testing/internal/testdeps", "\x02\v\xae\x01/\x10,\x03\x05\x03\x06\a\x02\x0f"},
|
||||||
{"testing/quick", "s\x01\x8d\x01\x05#\x10\x10"},
|
{"testing/iotest", "\x03q\x03\x83\x01\x04"},
|
||||||
{"testing/slogtest", "\rd\x03\x87\x01.\x05\x10\v"},
|
{"testing/quick", "v\x01\x8f\x01\x05#\x10\x11"},
|
||||||
{"testing/synctest", "\xde\x01`\x11"},
|
{"testing/slogtest", "\rg\x03\x89\x01.\x05\x10\f"},
|
||||||
{"text/scanner", "\x03q\x81\x01,*\x02"},
|
{"testing/synctest", "\xe3\x01`\x12"},
|
||||||
{"text/tabwriter", "t\x81\x01X"},
|
{"text/scanner", "\x03t\x83\x01,+\x02"},
|
||||||
{"text/template", "q\x03B?\x01\n \x01\x05\x01\x02\x05\v\x02\r\x03\x02"},
|
{"text/tabwriter", "w\x83\x01Y"},
|
||||||
{"text/template/parse", "\x03q\xba\x01\n\x01\x12\x02"},
|
{"text/template", "t\x03C@\x01\n \x01\x05\x01\x02\x05\v\x02\x0e\x03\x02"},
|
||||||
{"time", "q*\x1e#(*\r\x02\x12"},
|
{"text/template/parse", "\x03t\xbc\x01\n\x01\x13\x02"},
|
||||||
{"time/tzdata", "q\xcc\x01\x12"},
|
{"time", "t+\x1e$(*\r\x02\x13"},
|
||||||
|
{"time/tzdata", "t\xce\x01\x13"},
|
||||||
{"unicode", ""},
|
{"unicode", ""},
|
||||||
{"unicode/utf16", ""},
|
{"unicode/utf16", ""},
|
||||||
{"unicode/utf8", ""},
|
{"unicode/utf8", ""},
|
||||||
{"unique", "\x97\x01!$\x01Q\r\x01\x13\x12"},
|
{"unique", "\x9b\x01!%\x01Q\r\x01\x14\x12"},
|
||||||
{"unsafe", ""},
|
{"unsafe", ""},
|
||||||
{"vendor/golang.org/x/crypto/chacha20", "\x10Z\a\x93\x01*&"},
|
{"vendor/golang.org/x/crypto/chacha20", "\x10]\a\x95\x01*'"},
|
||||||
{"vendor/golang.org/x/crypto/chacha20poly1305", "\x10Z\a\xdf\x01\x04\x01\a"},
|
{"vendor/golang.org/x/crypto/chacha20poly1305", "\x10\aV\a\xe2\x01\x04\x01\a"},
|
||||||
{"vendor/golang.org/x/crypto/cryptobyte", "g\n\x03\x8e\x01' \n"},
|
{"vendor/golang.org/x/crypto/cryptobyte", "j\n\x03\x90\x01'!\n"},
|
||||||
{"vendor/golang.org/x/crypto/cryptobyte/asn1", ""},
|
{"vendor/golang.org/x/crypto/cryptobyte/asn1", ""},
|
||||||
{"vendor/golang.org/x/crypto/internal/alias", "\xcf\x02"},
|
{"vendor/golang.org/x/crypto/internal/alias", "\xd5\x02"},
|
||||||
{"vendor/golang.org/x/crypto/internal/poly1305", "U\x15\x9a\x01"},
|
{"vendor/golang.org/x/crypto/internal/poly1305", "X\x15\x9c\x01"},
|
||||||
{"vendor/golang.org/x/net/dns/dnsmessage", "q"},
|
{"vendor/golang.org/x/net/dns/dnsmessage", "t\xc7\x01"},
|
||||||
{"vendor/golang.org/x/net/http/httpguts", "\x8b\x02\x14\x1a\x14\r"},
|
{"vendor/golang.org/x/net/http/httpguts", "\x90\x02\x14\x1a\x15\r"},
|
||||||
{"vendor/golang.org/x/net/http/httpproxy", "q\x03\x97\x01\x10\x05\x01\x18\x14\r"},
|
{"vendor/golang.org/x/net/http/httpproxy", "t\x03\x99\x01\x10\x05\x01\x18\x15\r"},
|
||||||
{"vendor/golang.org/x/net/http2/hpack", "\x03n\x03\x81\x01F"},
|
{"vendor/golang.org/x/net/http2/hpack", "\x03q\x03\x83\x01F"},
|
||||||
{"vendor/golang.org/x/net/idna", "t\x8d\x018\x14\x10\x02\x01"},
|
{"vendor/golang.org/x/net/idna", "w\x8f\x018\x15\x10\x02\x01"},
|
||||||
{"vendor/golang.org/x/net/nettest", "\x03g\a\x03\x81\x01\x11\x05\x16\x01\f\n\x01\x02\x02\x01\v"},
|
{"vendor/golang.org/x/net/nettest", "\x03j\a\x03\x83\x01\x11\x05\x16\x01\f\n\x01\x02\x02\x01\f"},
|
||||||
{"vendor/golang.org/x/sys/cpu", "\xa1\x02\r\n\x01\x16"},
|
{"vendor/golang.org/x/sys/cpu", "\xa6\x02\r\n\x01\x17"},
|
||||||
{"vendor/golang.org/x/text/secure/bidirule", "q\xdc\x01\x11\x01"},
|
{"vendor/golang.org/x/text/secure/bidirule", "t\xdf\x01\x11\x01"},
|
||||||
{"vendor/golang.org/x/text/transform", "\x03n\x84\x01X"},
|
{"vendor/golang.org/x/text/transform", "\x03q\x86\x01Y"},
|
||||||
{"vendor/golang.org/x/text/unicode/bidi", "\x03\bi\x85\x01>\x16"},
|
{"vendor/golang.org/x/text/unicode/bidi", "\x03\bl\x87\x01>\x17"},
|
||||||
{"vendor/golang.org/x/text/unicode/norm", "j\n\x81\x01F\x12\x11"},
|
{"vendor/golang.org/x/text/unicode/norm", "m\n\x83\x01F\x13\x11"},
|
||||||
{"weak", "\x97\x01\x97\x01!"},
|
{"weak", "\x9b\x01\x98\x01\""},
|
||||||
}
|
}
|
||||||
|
|
||||||
// bootstrap is the list of bootstrap packages extracted from cmd/dist.
|
// bootstrap is the list of bootstrap packages extracted from cmd/dist.
|
||||||
|
|
@ -385,6 +391,7 @@ var bootstrap = map[string]bool{
|
||||||
"cmd/compile/internal/arm64": true,
|
"cmd/compile/internal/arm64": true,
|
||||||
"cmd/compile/internal/base": true,
|
"cmd/compile/internal/base": true,
|
||||||
"cmd/compile/internal/bitvec": true,
|
"cmd/compile/internal/bitvec": true,
|
||||||
|
"cmd/compile/internal/bloop": true,
|
||||||
"cmd/compile/internal/compare": true,
|
"cmd/compile/internal/compare": true,
|
||||||
"cmd/compile/internal/coverage": true,
|
"cmd/compile/internal/coverage": true,
|
||||||
"cmd/compile/internal/deadlocals": true,
|
"cmd/compile/internal/deadlocals": true,
|
||||||
|
|
@ -413,6 +420,7 @@ var bootstrap = map[string]bool{
|
||||||
"cmd/compile/internal/riscv64": true,
|
"cmd/compile/internal/riscv64": true,
|
||||||
"cmd/compile/internal/rttype": true,
|
"cmd/compile/internal/rttype": true,
|
||||||
"cmd/compile/internal/s390x": true,
|
"cmd/compile/internal/s390x": true,
|
||||||
|
"cmd/compile/internal/slice": true,
|
||||||
"cmd/compile/internal/ssa": true,
|
"cmd/compile/internal/ssa": true,
|
||||||
"cmd/compile/internal/ssagen": true,
|
"cmd/compile/internal/ssagen": true,
|
||||||
"cmd/compile/internal/staticdata": true,
|
"cmd/compile/internal/staticdata": true,
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -39,7 +39,7 @@ const (
|
||||||
Var // "EOF"
|
Var // "EOF"
|
||||||
Const // "Pi"
|
Const // "Pi"
|
||||||
Field // "Point.X"
|
Field // "Point.X"
|
||||||
Method // "(*Buffer).Grow"
|
Method // "(*Buffer).Grow" or "(Reader).Read"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (kind Kind) String() string {
|
func (kind Kind) String() string {
|
||||||
|
|
|
||||||
|
|
@ -285,18 +285,18 @@ github.com/xeipuuv/gojsonschema
|
||||||
# go.uber.org/atomic v1.11.0
|
# go.uber.org/atomic v1.11.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
go.uber.org/atomic
|
go.uber.org/atomic
|
||||||
# golang.org/x/crypto v0.46.0
|
# golang.org/x/crypto v0.48.0
|
||||||
## explicit; go 1.24.0
|
## explicit; go 1.24.0
|
||||||
golang.org/x/crypto/acme
|
golang.org/x/crypto/acme
|
||||||
golang.org/x/crypto/acme/autocert
|
golang.org/x/crypto/acme/autocert
|
||||||
golang.org/x/crypto/bcrypt
|
golang.org/x/crypto/bcrypt
|
||||||
golang.org/x/crypto/blowfish
|
golang.org/x/crypto/blowfish
|
||||||
# golang.org/x/mod v0.30.0
|
# golang.org/x/mod v0.33.0
|
||||||
## explicit; go 1.24.0
|
## explicit; go 1.24.0
|
||||||
golang.org/x/mod/internal/lazyregexp
|
golang.org/x/mod/internal/lazyregexp
|
||||||
golang.org/x/mod/module
|
golang.org/x/mod/module
|
||||||
golang.org/x/mod/semver
|
golang.org/x/mod/semver
|
||||||
# golang.org/x/net v0.48.0
|
# golang.org/x/net v0.50.0
|
||||||
## explicit; go 1.24.0
|
## explicit; go 1.24.0
|
||||||
golang.org/x/net/http/httpguts
|
golang.org/x/net/http/httpguts
|
||||||
golang.org/x/net/http2
|
golang.org/x/net/http2
|
||||||
|
|
@ -304,15 +304,16 @@ golang.org/x/net/http2/h2c
|
||||||
golang.org/x/net/http2/hpack
|
golang.org/x/net/http2/hpack
|
||||||
golang.org/x/net/idna
|
golang.org/x/net/idna
|
||||||
golang.org/x/net/internal/httpcommon
|
golang.org/x/net/internal/httpcommon
|
||||||
# golang.org/x/sync v0.19.0
|
golang.org/x/net/internal/httpsfv
|
||||||
## explicit; go 1.24.0
|
# golang.org/x/sync v0.20.0
|
||||||
|
## explicit; go 1.25.0
|
||||||
golang.org/x/sync/errgroup
|
golang.org/x/sync/errgroup
|
||||||
# golang.org/x/sys v0.39.0
|
# golang.org/x/sys v0.41.0
|
||||||
## explicit; go 1.24.0
|
## explicit; go 1.24.0
|
||||||
golang.org/x/sys/unix
|
golang.org/x/sys/unix
|
||||||
golang.org/x/sys/windows
|
golang.org/x/sys/windows
|
||||||
# golang.org/x/text v0.32.0
|
# golang.org/x/text v0.35.0
|
||||||
## explicit; go 1.24.0
|
## explicit; go 1.25.0
|
||||||
golang.org/x/text/secure/bidirule
|
golang.org/x/text/secure/bidirule
|
||||||
golang.org/x/text/transform
|
golang.org/x/text/transform
|
||||||
golang.org/x/text/unicode/bidi
|
golang.org/x/text/unicode/bidi
|
||||||
|
|
@ -320,7 +321,7 @@ golang.org/x/text/unicode/norm
|
||||||
# golang.org/x/time v0.14.0
|
# golang.org/x/time v0.14.0
|
||||||
## explicit; go 1.24.0
|
## explicit; go 1.24.0
|
||||||
golang.org/x/time/rate
|
golang.org/x/time/rate
|
||||||
# golang.org/x/tools v0.39.0
|
# golang.org/x/tools v0.42.0
|
||||||
## explicit; go 1.24.0
|
## explicit; go 1.24.0
|
||||||
golang.org/x/tools/go/ast/astutil
|
golang.org/x/tools/go/ast/astutil
|
||||||
golang.org/x/tools/go/buildutil
|
golang.org/x/tools/go/buildutil
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue