14 Commits

Author SHA1 Message Date
Thanh Nguyen
b6d53e5807 Merge 9740e5ee12 into a895145586 2023-10-01 00:25:37 +02:00
Thanh Nguyen
9740e5ee12 Add explanation for ./sw.js 2023-09-24 15:28:37 +07:00
Thanh Nguyen
4bc71acc67 Remove redundant embed manifest.json 2023-09-24 15:15:23 +07:00
Thanh Nguyen
183e7cecb0 Make service worker works 2023-09-24 15:11:42 +07:00
Thanh Nguyen
bd6b77bcc2 Add larger icon (144x144) to manifest.json 2023-09-24 15:11:31 +07:00
Thanh Nguyen
628bde1527 Fix absolute links of index.html 2023-09-24 15:08:35 +07:00
Thanh Nguyen
976bbfd245 Fix manifest.json in routes.go 2023-09-24 14:05:53 +07:00
Thanh Nguyen
b79a542ed7 Remove redundant static files 2023-09-24 14:05:40 +07:00
Thanh Nguyen
c32bd7e415 Revert "Remove handling /manifest.json"
This reverts commit dadadeb066.
2023-09-24 13:50:16 +07:00
Thanh Nguyen
e9676491ee Fix edge case where HTTP Auth is used 2023-09-23 03:01:36 +07:00
Thanh Nguyen
1a545bb2a1 Fix links in index.html 2023-09-23 02:58:53 +07:00
Thanh Nguyen
1e128a7cd8 Add manifest.json to static assets 2023-09-23 02:51:50 +07:00
Thanh Nguyen
5dbb6a710c Add manifest.json to index.html 2023-09-23 02:38:02 +07:00
Thanh Nguyen
dadadeb066 Remove handling /manifest.json 2023-09-23 02:37:31 +07:00
79 changed files with 3163 additions and 4624 deletions

View File

@@ -1,38 +0,0 @@
name: Publish Docker Image
on:
push:
tags: [ 'v*.*.*', 'v*.*', 'v*', 'latest' ]
env:
REGISTRY: ghcr.io
IMAGE_NAME: nkanaev/yarr
jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Log in to the Container registry
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Build and push Docker image
uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a
with:
context: .
file: ./etc/dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View File

@@ -1,14 +1,8 @@
name: Build
name: build
on:
push:
tags:
- v*
workflow_dispatch:
workflow_run:
workflows: [Test]
types:
- completed
tags: ['v*', 'test*']
jobs:
build_macos:
@@ -24,7 +18,7 @@ jobs:
with:
go-version: '^1.17'
- name: Cache Go Modules
uses: actions/cache@v4
uses: actions/cache@v2
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
@@ -33,7 +27,7 @@ jobs:
- name: "Build"
run: make build_macos
- name: Upload
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v2
with:
name: macos
path: _output/macos/yarr.app
@@ -51,7 +45,7 @@ jobs:
with:
go-version: '^1.17'
- name: Cache Go Modules
uses: actions/cache@v4
uses: actions/cache@v2
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
@@ -60,7 +54,7 @@ jobs:
- name: "Build"
run: make build_windows
- name: Upload
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v2
with:
name: windows
path: _output/windows/yarr.exe
@@ -78,99 +72,38 @@ jobs:
with:
go-version: '^1.17'
- name: Cache Go Modules
uses: actions/cache@v4
uses: actions/cache@v2
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-amd64-go-${{ hashFiles('**/go.sum') }}
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-amd64
${{ runner.os }}-go-
- name: "Build"
run: make build_linux
- name: Upload
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v2
with:
name: linux
path: _output/linux/yarr
build_linux-arm:
name: Build for Linux ARM
runs-on: ubuntu-22.04
steps:
- name: Install dependencies
run: >
sudo apt-get install -y
gcc-arm-linux-gnueabihf
libc6-dev-armhf-cross
- name: "Checkout"
uses: actions/checkout@v2
with:
submodules: 'recursive'
- name: "Setup Go"
uses: actions/setup-go@v2
with:
go-version: '^1.17'
- name: Cache Go Modules
uses: actions/cache@v4
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-armv7-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-armv7
- name: "Build"
env:
CC: arm-linux-gnueabihf-gcc
GOARCH: arm
GOARM: 7
run: make build_linux
- name: Upload
uses: actions/upload-artifact@v4
with:
name: linux_arm
path: _output/linux/yarr
build_linux-arm64:
name: Build for Linux ARM64
runs-on: ubuntu-22.04
steps:
- name: Install dependencies
run: >
sudo apt-get install -y
gcc-aarch64-linux-gnu
libc6-dev-arm64-cross
- name: "Checkout"
uses: actions/checkout@v2
with:
submodules: 'recursive'
- name: "Setup Go"
uses: actions/setup-go@v2
with:
go-version: '^1.17'
- name: Cache Go Modules
uses: actions/cache@v4
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-arm64-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-arm64
- name: "Build"
env:
CC: aarch64-linux-gnu-gcc
GOARCH: arm64
run: make build_linux
- name: Upload
uses: actions/upload-artifact@v4
with:
name: linux_arm64
path: _output/linux/yarr
create_release:
name: Create Release
runs-on: ubuntu-latest
if: ${{ startsWith(github.ref, 'refs/tags/') && !contains(github.ref, 'test') }}
needs: [build_macos, build_windows, build_linux, build_linux-arm, build_linux-arm64]
if: ${{ !contains(github.ref, 'test') }}
needs: [build_macos, build_windows, build_linux]
steps:
- name: Create Release
uses: actions/create-release@v1
id: create_release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ${{ github.ref }}
draft: true
prerelease: true
- name: Download Artifacts
uses: actions/download-artifact@v4.1.7
uses: actions/download-artifact@v2
with:
path: .
- name: Preparation
@@ -178,24 +111,34 @@ jobs:
ls -R
chmod u+x macos/Contents/MacOS/yarr
chmod u+x linux/yarr
chmod u+x linux_arm/yarr
chmod u+x linux_arm64/yarr
mv macos yarr.app && zip -r yarr-${GITHUB_REF_NAME}-macos64.zip yarr.app
( cd windows && zip ../yarr-${GITHUB_REF_NAME}-windows64.zip yarr.exe )
( cd linux && zip ../yarr-${GITHUB_REF_NAME}-linux64.zip yarr )
( cd linux_arm && zip ../yarr-${GITHUB_REF_NAME}-linux_arm.zip yarr )
( cd linux_arm64 && zip ../yarr-${GITHUB_REF_NAME}-linux_arm64.zip yarr )
- name: Upload Release
uses: softprops/action-gh-release@v2
mv macos yarr.app && zip -r yarr-macos.zip yarr.app
mv windows/yarr.exe . && zip yarr-windows.zip yarr.exe
mv linux/yarr . && zip yarr-linux.zip yarr
- name: Upload MacOS
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
draft: true
prerelease: true
files: |
yarr-${{ github.ref_name }}-macos64.zip
yarr-${{ github.ref_name }}-windows64.zip
yarr-${{ github.ref_name }}-linux64.zip
yarr-${{ github.ref_name }}-linux_arm.zip
yarr-${{ github.ref_name }}-linux_arm64.zip
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./yarr-macos.zip
asset_name: yarr-${{ github.ref }}-macos64.zip
asset_content_type: application/zip
- name: Upload Windows
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./yarr-windows.zip
asset_name: yarr-${{ github.ref }}-windows64.zip
asset_content_type: application/zip
- name: Upload Linux
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./yarr-linux.zip
asset_name: yarr-${{ github.ref }}-linux64.zip
asset_content_type: application/zip

View File

@@ -1,19 +0,0 @@
name: Test
on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '^1.18'
- name: Run tests
run: make test

2
.gitignore vendored
View File

@@ -1,7 +1,5 @@
/_output
/yarr
*.db
*.db-shm
*.db-wal
*.syso
versioninfo.rc

View File

@@ -13,7 +13,6 @@ import (
"github.com/nkanaev/yarr/src/platform"
"github.com/nkanaev/yarr/src/server"
"github.com/nkanaev/yarr/src/storage"
"github.com/nkanaev/yarr/src/worker"
)
var Version string = "0.0"
@@ -90,12 +89,12 @@ func main() {
log.SetOutput(os.Stdout)
}
if db == "" {
configPath, err := os.UserConfigDir()
if err != nil {
log.Fatal("Failed to get config dir: ", err)
}
configPath, err := os.UserConfigDir()
if err != nil {
log.Fatal("Failed to get config dir: ", err)
}
if db == "" {
storagePath := filepath.Join(configPath, "yarr")
if err := os.MkdirAll(storagePath, 0755); err != nil {
log.Fatal("Failed to create app config dir: ", err)
@@ -106,7 +105,6 @@ func main() {
log.Printf("using db file %s", db)
var username, password string
var err error
if authfile != "" {
f, err := os.Open(authfile)
if err != nil {
@@ -133,7 +131,6 @@ func main() {
log.Fatal("Failed to initialise database: ", err)
}
worker.SetVersion(Version)
srv := server.NewServer(store, addr)
if basepath != "" {

View File

@@ -1,22 +1,11 @@
# upcoming
- (new) Fever API support (thanks to @icefed)
- (new) editable feed link (thanks to @adaszko)
- (new) switch to feed by clicking the title in the article page (thanks to @tarasglek for suggestion)
- (new) support multiple media links
- (fix) duplicate articles caused by the same feed addition (thanks to @adaszko)
- (fix) relative article links (thanks to @adazsko for the report)
- (fix) atom article links stored in id element (thanks to @adazsko for the report)
- (fix) parsing atom feed titles (thanks to @wnh)
- (fix) sorting same-day batch articles (thanks to @lamescholar for the report)
- (fix) showing login page in the selected theme (thanks to @feddiriko for the report)
- (fix) parsing atom feeds with html elements (thanks to @tillcash & @toBeOfUse for the report, @krkk for the fix)
- (fix) parsing feeds with missing guids (thanks to @hoyii for the report)
- (fix) sending actual client version to servers (thanks to @aidanholm)
- (fix) error caused by missing config dir (thanks to @timster)
- (etc) load external images with no-referrer policy (thanks to @tillcash for the report)
- (etc) open external links with no-referrer policy (thanks to @donovanglover)
- (etc) show article content in the list if title is missing (thanks to @asimpson for suggestion)
# v2.4 (2023-08-15)

View File

@@ -1,68 +0,0 @@
- site: https://vimeo.com/channels/staffpicks/videos
feed: https://vimeo.com/channels/staffpicks/videos/rss
tags: [vimeo, image]
- site: https://www.youtube.com/@everyframeapainting/videos
feed: https://www.youtube.com/feeds/videos.xml?channel_id=UCjFqcJQXGZ6T6sxyFB-5i6A"
tags: [youtube, image]
- site: https://iwdrm.tumblr.com/
feed: https://iwdrm.tumblr.com/rss
tags: [tumblr, image]
- site: https://falseknees.tumblr.com/
feed: https://falseknees.tumblr.com/rss
tags: [tumblr, image]
- site: https://accidentallyquadratic.tumblr.com/
feed: https://accidentallyquadratic.tumblr.com/rss
info: text blog with code sections
tags: [tumblr, text, code]
- site: https://www.flickr.com/photos/maratsafin/
feed: https://www.flickr.com/services/feeds/photos_public.gne?id=59021497@N07&lang=en-us&format=atom
tags: [flickr, image]
- site: https://www.reddit.com/r/comics
feed: https://www.reddit.com/r/comics.rss
tags: [reddit, image]
- site: https://www.reddit.com/r/AITAH
feed: https://www.reddit.com/r/AITAH.rss
tags: [reddit, text]
- site: https://idothei.wordpress.com/
feed: https://idothei.wordpress.com/feed/
tags: [wordpress, text]
- site: https://www.vidarholen.net/contents/blog/
feed: https://www.vidarholen.net/contents/blog/?feed=rss2
tags: [wordpress, text]
- site: https://blog.posthaven.com/
feed: https://blog.posthaven.com/posts.atom
tags: [posthaven, text]
- site: https://medium.com/@dailynewsletter
feed: https://medium.com/feed/@dailynewsletter
tags: [medium, text]
- site: https://thereveal.substack.com/
feed: https://thereveal.substack.com/feed
tags: [substack, text]
- site: https://tema.livejournal.com/
feed: https://tema.livejournal.com/data/rss
tags: [livejournal, text]
- site: https://mametter.hatenablog.com/
feed: https://mametter.hatenablog.com/feed
tags: [hatena, text]
- site: https://juliepowell.blogspot.com/
feed: https://juliepowell.blogspot.com/feeds/posts/default
tags: [blogger, text]
- site: https://micro.blog/val
feed: https://micro.blog/posts/val
tags: [json, microblog]

View File

@@ -1,14 +1,12 @@
FROM golang:alpine3.18 AS build
FROM golang:alpine AS build
RUN apk add build-base git
WORKDIR /src
COPY . .
RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/root/go/pkg \
make build_linux
RUN make build_linux
FROM alpine:latest
RUN apk add --no-cache ca-certificates && \
update-ca-certificates
COPY --from=build /src/_output/linux/yarr /usr/local/bin/yarr
EXPOSE 7070
ENTRYPOINT ["/usr/local/bin/yarr"]
CMD ["-addr", "0.0.0.0:7070", "-db", "/data/yarr.db"]
CMD ["/usr/local/bin/yarr", "-addr", "0.0.0.0:7070", "-db", "/data/yarr.db"]

View File

@@ -1,9 +1,5 @@
#!/bin/bash
if [[ ! -d "$HOME/.local/share/applications" ]]; then
mkdir -p "$HOME/.local/share/applications"
fi
cat >"$HOME/.local/share/applications/yarr.desktop" <<END
[Desktop Entry]
Name=yarr
@@ -13,10 +9,6 @@ Type=Application
Categories=Internet;
END
if [[ ! -d "$HOME/.local/share/icons" ]]; then
mkdir -p "$HOME/.local/share/icons"
fi
cat >"$HOME/.local/share/icons/yarr.svg" <<END
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-anchor-favicon">

8
go.mod
View File

@@ -1,11 +1,11 @@
module github.com/nkanaev/yarr
go 1.18
go 1.17
require (
github.com/mattn/go-sqlite3 v1.14.7
golang.org/x/net v0.33.0
golang.org/x/sys v0.28.0
golang.org/x/net v0.8.0
golang.org/x/sys v0.6.0
)
require golang.org/x/text v0.21.0 // indirect
require golang.org/x/text v0.8.0 // indirect

45
go.sum
View File

@@ -1,70 +1,39 @@
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA=
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@@ -1,34 +1,33 @@
VERSION=2.4
GITHASH=$(shell git rev-parse --short=8 HEAD)
GO_TAGS = sqlite_foreign_keys sqlite_json
GO_LDFLAGS = -s -w -X 'main.Version=$(VERSION)' -X 'main.GitHash=$(GITHASH)'
CGO_ENABLED=1
export GOARCH ?= amd64
export CGO_ENABLED = 1
GO_LDFLAGS = -s -w
GO_LDFLAGS := $(GO_LDFLAGS) -X 'main.Version=$(VERSION)' -X 'main.GitHash=$(GITHASH)'
build_default:
mkdir -p _output
go build -tags "$(GO_TAGS)" -ldflags="$(GO_LDFLAGS)" -o _output/yarr ./cmd/yarr
go build -tags "sqlite_foreign_keys" -ldflags="$(GO_LDFLAGS)" -o _output/yarr ./cmd/yarr
build_macos:
mkdir -p _output/macos
GOOS=darwin go build -tags "$(GO_TAGS) macos" -ldflags="$(GO_LDFLAGS)" -o _output/macos/yarr ./cmd/yarr
GOOS=darwin GOARCH=amd64 go build -tags "sqlite_foreign_keys macos" -ldflags="$(GO_LDFLAGS)" -o _output/macos/yarr ./cmd/yarr
cp src/platform/icon.png _output/macos/icon.png
go run ./cmd/package_macos -outdir _output/macos -version "$(VERSION)"
build_linux:
mkdir -p _output/linux
GOOS=linux go build -tags "$(GO_TAGS) linux" -ldflags="$(GO_LDFLAGS)" -o _output/linux/yarr ./cmd/yarr
GOOS=linux GOARCH=amd64 go build -tags "sqlite_foreign_keys linux" -ldflags="$(GO_LDFLAGS)" -o _output/linux/yarr ./cmd/yarr
build_windows:
mkdir -p _output/windows
go run ./cmd/generate_versioninfo -version "$(VERSION)" -outfile src/platform/versioninfo.rc
windres -i src/platform/versioninfo.rc -O coff -o src/platform/versioninfo.syso
GOOS=windows go build -tags "$(GO_TAGS) windows" -ldflags="$(GO_LDFLAGS) -H windowsgui" -o _output/windows/yarr.exe ./cmd/yarr
GOOS=windows GOARCH=amd64 go build -tags "sqlite_foreign_keys windows" -ldflags="$(GO_LDFLAGS) -H windowsgui" -o _output/windows/yarr.exe ./cmd/yarr
serve:
go run -tags "$(GO_TAGS)" ./cmd/yarr -db local.db
go run -tags "sqlite_foreign_keys" ./cmd/yarr -db local.db
test:
go test -tags "$(GO_TAGS)" ./...
cd src && go test -tags "sqlite_foreign_keys" ./...

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@@ -3,16 +3,22 @@
<head>
<meta charset="UTF-8">
<title>yarr!</title>
<link rel="stylesheet" href="./static/stylesheets/bootstrap.min.css">
<link rel="stylesheet" href="./static/stylesheets/app.css">
<link rel="icon" href="./static/graphicarts/favicon.svg" type="image/svg+xml">
<link rel="alternate icon" href="./static/graphicarts/favicon.png" type="image/png">
<link rel="manifest" href="./manifest.json" />
<link rel="stylesheet" href="./static/stylesheets/bootstrap.min.css" crossorigin="use-credentials">
<link rel="stylesheet" href="./static/stylesheets/app.css" crossorigin="use-credentials">
<link rel="icon" href="./static/graphicarts/favicon.svg" type="image/svg+xml" crossorigin="use-credentials">
<link rel="alternate icon" href="./static/graphicarts/favicon.png" type="image/png" crossorigin="use-credentials">
<link rel="manifest" href="./manifest.json" crossorigin="use-credentials"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<script>
window.app = window.app || {}
window.app.settings = {% .settings %}
window.app.authenticated = {% .authenticated %}
if ("serviceWorker" in navigator) {
// we use `./sw.js` instead of `./static/javascripts/sw.js` since the latter would not work with
// `./manifest.json`, and it leads to uninstallable PWA
navigator.serviceWorker.register("./sw.js")
}
</script>
</head>
<body class="theme-{% .settings.theme_name %}">
@@ -25,21 +31,18 @@
<div class="flex-grow-1"></div>
<button class="toolbar-item"
:class="{active: filterSelected == 'unread'}"
:aria-pressed="filterSelected == 'unread'"
title="Unread"
@click="filterSelected = 'unread'">
<span class="icon">{% inline "circle-full.svg" %}</span>
</button>
<button class="toolbar-item"
:class="{active: filterSelected == 'starred'}"
:aria-pressed="filterSelected == 'starred'"
title="Starred"
@click="filterSelected = 'starred'">
<span class="icon">{% inline "star-full.svg" %}</span>
</button>
<button class="toolbar-item"
:class="{active: filterSelected == ''}"
:aria-pressed="filterSelected == ''"
title="All"
@click="filterSelected = ''">
<span class="icon">{% inline "assorted.svg" %}</span>
@@ -62,12 +65,10 @@
<div class="dropdown-divider"></div>
<header class="dropdown-header" role="heading" aria-level="2">Theme</header>
<header class="dropdown-header">Theme</header>
<div class="row text-center m-0">
<button class="btn btn-link col-4 px-0 rounded-0"
:class="'theme-'+t"
:aria-label="t"
:aria-pressed="theme.name == t"
@click.stop="theme.name = t"
v-for="t in ['light', 'sepia', 'night']">
<span class="icon" v-if="theme.name == t">{% inline "check.svg" %}</span>
@@ -76,25 +77,25 @@
<div class="dropdown-divider"></div>
<header class="dropdown-header" role="heading" aria-level="2">Auto Refresh</header>
<header class="dropdown-header">Auto Refresh</header>
<div class="row text-center m-0">
<button class="dropdown-item col-4 px-0" :aria-pressed="!refreshRate" :class="{active: !refreshRate}" @click.stop="refreshRate = 0">0</button>
<button class="dropdown-item col-4 px-0" :aria-pressed="refreshRate == 10" :class="{active: refreshRate == 10}" @click.stop="refreshRate = 10">10m</button>
<button class="dropdown-item col-4 px-0" :aria-pressed="refreshRate == 30" :class="{active: refreshRate == 30}" @click.stop="refreshRate = 30">30m</button>
<button class="dropdown-item col-4 px-0" :aria-pressed="refreshRate == 60" :class="{active: refreshRate == 60}" @click.stop="refreshRate = 60">1h</button>
<button class="dropdown-item col-4 px-0" :aria-pressed="refreshRate == 120" :class="{active: refreshRate == 120}" @click.stop="refreshRate = 120">2h</button>
<button class="dropdown-item col-4 px-0" :aria-pressed="refreshRate == 240" :class="{active: refreshRate == 240}" @click.stop="refreshRate = 240">4h</button>
<button class="dropdown-item col-4 px-0" :class="{active: !refreshRate}" @click.stop="refreshRate = 0">0</button>
<button class="dropdown-item col-4 px-0" :class="{active: refreshRate == 10}" @click.stop="refreshRate = 10">10m</button>
<button class="dropdown-item col-4 px-0" :class="{active: refreshRate == 30}" @click.stop="refreshRate = 30">30m</button>
<button class="dropdown-item col-4 px-0" :class="{active: refreshRate == 60}" @click.stop="refreshRate = 60">1h</button>
<button class="dropdown-item col-4 px-0" :class="{active: refreshRate == 120}" @click.stop="refreshRate = 120">2h</button>
<button class="dropdown-item col-4 px-0" :class="{active: refreshRate == 240}" @click.stop="refreshRate = 240">4h</button>
</div>
<div class="dropdown-divider"></div>
<header class="dropdown-header" role="heading" aria-level="2">Show first</header>
<header class="dropdown-header">Show first</header>
<div class="d-flex text-center">
<button class="dropdown-item px-0" :aria-pressed="itemSortNewestFirst" :class="{active: itemSortNewestFirst}" @click.stop="itemSortNewestFirst=true">New</button>
<button class="dropdown-item px-0" :aria-pressed="!itemSortNewestFirst" :class="{active: !itemSortNewestFirst}" @click.stop="itemSortNewestFirst=false">Old</button>
<button class="dropdown-item px-0" :class="{active: itemSortNewestFirst}" @click.stop="itemSortNewestFirst=true">New</button>
<button class="dropdown-item px-0" :class="{active: !itemSortNewestFirst}" @click.stop="itemSortNewestFirst=false">Old</button>
</div>
<div class="dropdown-divider"></div>
<header class="dropdown-header" role="heading" aria-level="2">Subscriptions</header>
<header class="dropdown-header">Subscriptions</header>
<form id="opml-import-form" enctype="multipart/form-data" tabindex="-1">
<input type="file"
id="opml-import"
@@ -211,12 +212,12 @@
<template v-slot:button>
<span class="icon">{% inline "more-horizontal.svg" %}</span>
</template>
<header class="dropdown-header" role="heading" aria-level="2">{{ current.feed.title }}</header>
<a class="dropdown-item" :href="current.feed.link" rel="noopener noreferrer" target="_blank" referrerpolicy="no-referrer" v-if="current.feed.link">
<header class="dropdown-header">{{ current.feed.title }}</header>
<a class="dropdown-item" :href="current.feed.link" target="_blank" v-if="current.feed.link">
<span class="icon mr-1">{% inline "globe.svg" %}</span>
Website
</a>
<a class="dropdown-item" :href="current.feed.feed_link" rel="noopener noreferrer" target="_blank" referrerpolicy="no-referrer" v-if="current.feed.feed_link">
<a class="dropdown-item" :href="current.feed.feed_link" target="_blank" v-if="current.feed.feed_link">
<span class="icon mr-1">{% inline "rss.svg" %}</span>
Feed Link
</a>
@@ -225,12 +226,8 @@
<span class="icon mr-1">{% inline "edit.svg" %}</span>
Rename
</button>
<button class="dropdown-item" @click="updateFeedLink(current.feed)" v-if="current.feed.feed_link">
<span class="icon mr-1">{% inline "edit.svg" %}</span>
Change Link
</button>
<div class="dropdown-divider"></div>
<header class="dropdown-header" role="heading" aria-level="2">Move to...</header>
<header class="dropdown-header">Move to...</header>
<button class="dropdown-item"
v-if="folder.id != current.feed.folder_id"
v-for="folder in folders"
@@ -260,7 +257,7 @@
<template v-slot:button>
<span class="icon">{% inline "more-horizontal.svg" %}</span>
</template>
<header class="dropdown-header" role="heading" aria-level="2">{{ current.folder.title }}</header>
<header class="dropdown-header">{{ current.folder.title }}</header>
<button class="dropdown-item" @click="renameFolder(current.folder)">
<span class="icon mr-1">{% inline "edit.svg" %}</span>
Rename
@@ -331,16 +328,10 @@
title="Read Here">
<span class="icon" :class="{'icon-loading': loading.readability}">{% inline "book-open.svg" %}</span>
</button>
<a class="toolbar-item" :href="itemSelectedDetails.link" rel="noopener noreferrer" target="_blank" referrerpolicy="no-referrer" title="Open Link">
<a class="toolbar-item" :href="itemSelectedDetails.link" target="_blank" title="Open Link">
<span class="icon">{% inline "external-link.svg" %}</span>
</a>
<div class="flex-grow-1"></div>
<button class="toolbar-item" @click="navigateToItem(-1)" title="Previous Article" :disabled="itemSelected == items[0].id">
<span class="icon">{% inline "chevron-left.svg" %}</span>
</button>
<button class="toolbar-item" @click="navigateToItem(+1)" title="Next Article" :disabled="itemSelected == items[items.length - 1].id">
<span class="icon">{% inline "chevron-right.svg" %}</span>
</button>
<button class="toolbar-item" @click="itemSelected=null" title="Close Article">
<span class="icon">{% inline "x.svg" %}</span>
</button>
@@ -353,23 +344,13 @@
<div class="content-wrapper">
<h1><b>{{ itemSelectedDetails.title || 'untitled' }}</b></h1>
<div class="text-muted">
<div>
<span class="cursor-pointer" @click="feedSelected = 'feed:'+(feedsById[itemSelectedDetails.feed_id] || {}).id">
{{ (feedsById[itemSelectedDetails.feed_id] || {}).title }}
</span>
</div>
<div>{{ (feedsById[itemSelectedDetails.feed_id] || {}).title }}</div>
<time>{{ formatDate(itemSelectedDetails.date) }}</time>
</div>
<hr>
<div v-if="!itemSelectedReadability">
<div v-if="contentImages.length">
<figure v-for="media in contentImages">
<img :src="media.url" loading="lazy">
<figcaption v-if="media.description" v-html="media.description"></figcaption>
</figure>
</div>
<audio class="w-100" controls v-for="media in contentAudios" :src="media.url"></audio>
<video class="w-100" controls v-for="media in contentVideos" :src="media.url"></video>
<img :src="itemSelectedDetails.image" v-if="itemSelectedDetails.image" class="mb-3">
<audio class="w-100" controls v-if="itemSelectedDetails.podcast_url" :src="itemSelectedDetails.podcast_url"></audio>
</div>
<div v-html="itemSelectedContent"></div>
</div>

View File

@@ -2,26 +2,6 @@
var TITLE = document.title
function scrollto(target, scroll) {
var padding = 10
var targetRect = target.getBoundingClientRect()
var scrollRect = scroll.getBoundingClientRect()
// target
var relativeOffset = targetRect.y - scrollRect.y
var absoluteOffset = relativeOffset + scroll.scrollTop
if (padding <= relativeOffset && relativeOffset + targetRect.height <= scrollRect.height - padding) return
var newPos = scroll.scrollTop
if (relativeOffset < padding) {
newPos = absoluteOffset - padding
} else {
newPos = absoluteOffset - scrollRect.height + targetRect.height + padding
}
scroll.scrollTop = Math.round(newPos)
}
var debounce = function(callback, wait) {
var timeout
return function() {
@@ -298,18 +278,6 @@ var vm = new Vue({
return this.itemSelectedDetails.content || ''
},
contentImages: function() {
if (!this.itemSelectedDetails) return []
return (this.itemSelectedDetails.media_links || []).filter(l => l.type === 'image')
},
contentAudios: function() {
if (!this.itemSelectedDetails) return []
return (this.itemSelectedDetails.media_links || []).filter(l => l.type === 'audio')
},
contentVideos: function() {
if (!this.itemSelectedDetails) return []
return (this.itemSelectedDetails.media_links || []).filter(l => l.type === 'video')
}
},
watch: {
'theme': {
@@ -439,7 +407,7 @@ var vm = new Vue({
vm.feeds = values[1]
})
},
refreshItems: function(loadMore = false) {
refreshItems: function(loadMore) {
if (this.feedSelected === null) {
vm.items = []
vm.itemsHasMore = false
@@ -452,7 +420,7 @@ var vm = new Vue({
}
this.loading.items = true
return api.items.list(query).then(function(data) {
api.items.list(query).then(function(data) {
if (loadMore) {
vm.items = vm.items.concat(data.list)
} else {
@@ -475,17 +443,13 @@ var vm = new Vue({
var scale = (parseFloat(getComputedStyle(document.documentElement).fontSize) || 16) / 16
var el = this.$refs.itemlist
if (el.scrollHeight === 0) return false // element is invisible (responsive design)
var closeToBottom = (el.scrollHeight - el.scrollTop - el.offsetHeight) < bottomSpace * scale
return closeToBottom
},
loadMoreItems: function(event, el) {
if (!this.itemsHasMore) return
if (this.loading.items) return
if (this.itemListCloseToBottom()) return this.refreshItems(true)
if (this.itemSelected && this.itemSelected === this.items[this.items.length - 1].id) return this.refreshItems(true)
if (this.itemListCloseToBottom()) this.refreshItems(true)
},
markItemsRead: function() {
var query = this.getItemsQuery()
@@ -559,14 +523,6 @@ var vm = new Vue({
})
}
},
updateFeedLink: function(feed) {
var newLink = prompt('Enter feed link', feed.feed_link)
if (newLink) {
api.feeds.update(feed.id, {feed_link: newLink}).then(function() {
feed.feed_link = newLink
})
}
},
renameFeed: function(feed) {
var newTitle = prompt('Enter new title', feed.title)
if (newTitle) {
@@ -719,65 +675,6 @@ var vm = new Vue({
this.filteredFolderStats = statsFolders
this.filteredTotalStats = statsTotal
},
// navigation helper, navigate relative to selected item
navigateToItem: function(relativePosition) {
let vm = this
if (vm.itemSelected == null) {
// if no item is selected, select first
if (vm.items.length !== 0) vm.itemSelected = vm.items[0].id
return
}
var itemPosition = vm.items.findIndex(function(x) { return x.id === vm.itemSelected })
if (itemPosition === -1) {
if (vm.items.length !== 0) vm.itemSelected = vm.items[0].id
return
}
var newPosition = itemPosition + relativePosition
if (newPosition < 0 || newPosition >= vm.items.length) return
vm.itemSelected = vm.items[newPosition].id
vm.$nextTick(function() {
var scroll = document.querySelector('#item-list-scroll')
var handle = scroll.querySelector('input[type=radio]:checked')
var target = handle && handle.parentElement
if (target && scroll) scrollto(target, scroll)
vm.loadMoreItems()
})
},
// navigation helper, navigate relative to selected feed
navigateToFeed: function(relativePosition) {
let vm = this
var navigationList = Array.from(document.querySelectorAll('#col-feed-list input[name=feed]'))
.filter(function(r) { return r.offsetParent !== null && r.value !== 'folder:null' })
.map(function(r) { return r.value })
var currentFeedPosition = navigationList.indexOf(vm.feedSelected)
if (currentFeedPosition == -1) {
vm.feedSelected = ''
return
}
var newPosition = currentFeedPosition+relativePosition
if (newPosition < 0 || newPosition >= navigationList.length) return
vm.feedSelected = navigationList[newPosition]
vm.$nextTick(function() {
var scroll = document.querySelector('#feed-list-scroll')
var handle = scroll.querySelector('input[type=radio]:checked')
var target = handle && handle.parentElement
if (target && scroll) scrollto(target, scroll)
})
},
}
})

View File

@@ -1,4 +1,79 @@
function scrollto(target, scroll) {
var padding = 10
var targetRect = target.getBoundingClientRect()
var scrollRect = scroll.getBoundingClientRect()
// target
var relativeOffset = targetRect.y - scrollRect.y
var absoluteOffset = relativeOffset + scroll.scrollTop
if (padding <= relativeOffset && relativeOffset + targetRect.height <= scrollRect.height - padding) return
var newPos = scroll.scrollTop
if (relativeOffset < padding) {
newPos = absoluteOffset - padding
} else {
newPos = absoluteOffset - scrollRect.height + targetRect.height + padding
}
scroll.scrollTop = Math.round(newPos)
}
var helperFunctions = {
// navigation helper, navigate relative to selected item
navigateToItem: function(relativePosition) {
if (vm.itemSelected == null) {
// if no item is selected, select first
if (vm.items.length !== 0) vm.itemSelected = vm.items[0].id
return
}
var itemPosition = vm.items.findIndex(function(x) { return x.id === vm.itemSelected })
if (itemPosition === -1) {
if (vm.items.length !== 0) vm.itemSelected = vm.items[0].id
return
}
var newPosition = itemPosition + relativePosition
if (newPosition < 0 || newPosition >= vm.items.length) return
vm.itemSelected = vm.items[newPosition].id
vm.$nextTick(function() {
var scroll = document.querySelector('#item-list-scroll')
var handle = scroll.querySelector('input[type=radio]:checked')
var target = handle && handle.parentElement
if (target && scroll) scrollto(target, scroll)
})
},
// navigation helper, navigate relative to selected feed
navigateToFeed: function(relativePosition) {
var navigationList = Array.from(document.querySelectorAll('#col-feed-list input[name=feed]'))
.filter(function(r) { return r.offsetParent !== null && r.value !== 'folder:null' })
.map(function(r) { return r.value })
var currentFeedPosition = navigationList.indexOf(vm.feedSelected)
if (currentFeedPosition == -1) {
vm.feedSelected = ''
return
}
var newPosition = currentFeedPosition+relativePosition
if (newPosition < 0 || newPosition >= navigationList.length) return
vm.feedSelected = navigationList[newPosition]
vm.$nextTick(function() {
var scroll = document.querySelector('#feed-list-scroll')
var handle = scroll.querySelector('input[type=radio]:checked')
var target = handle && handle.parentElement
if (target && scroll) scrollto(target, scroll)
})
},
scrollContent: function(direction) {
var padding = 40
var scroll = document.querySelector('.content')
@@ -17,7 +92,7 @@ var helperFunctions = {
var shortcutFunctions = {
openItemLink: function() {
if (vm.itemSelectedDetails && vm.itemSelectedDetails.link) {
window.open(vm.itemSelectedDetails.link, '_blank', 'noopener,noreferrer')
window.open(vm.itemSelectedDetails.link, '_blank')
}
},
toggleReadability: function() {
@@ -43,16 +118,16 @@ var shortcutFunctions = {
document.getElementById("searchbar").focus()
},
nextItem(){
vm.navigateToItem(+1)
helperFunctions.navigateToItem(+1)
},
previousItem() {
vm.navigateToItem(-1)
helperFunctions.navigateToItem(-1)
},
nextFeed(){
vm.navigateToFeed(+1)
helperFunctions.navigateToFeed(+1)
},
previousFeed() {
vm.navigateToFeed(-1)
helperFunctions.navigateToFeed(-1)
},
scrollForward: function() {
helperFunctions.scrollContent(+1)

View File

@@ -0,0 +1,34 @@
const VERSION = "v2.4"
const APP_STATIC_RESOURCES = [
"/",
"/static/stylesheets/bootstrap.min.css",
"/static/stylesheets/app.css",
"/static/graphicarts/favicon.svg",
"/static/graphicarts/favicon.png",
]
const CACHE_NAME = `yarr-${VERSION}`;
self.addEventListener("install", (e) => {
e.waitUntil((async () => {
const cache = await caches.open(CACHE_NAME)
await cache.addAll(APP_STATIC_RESOURCES)
})()
)
})
// delete old caches on activate
self.addEventListener("activate", (event) => {
event.waitUntil(
(async () => {
const names = await caches.keys()
await Promise.all(
names.map((name) => {
if (name !== CACHE_NAME) {
return caches.delete(name)
}
}),
)
await clients.claim()
})(),
)
})

View File

@@ -22,7 +22,7 @@
}
</style>
</head>
<body class="theme-{% .settings.theme_name %}">
<body>
<form action="" method="post">
<img src="./static/graphicarts/anchor.svg" alt="">
{% if .error %}

View File

@@ -4,7 +4,6 @@ import (
"bytes"
"regexp"
"strings"
"unicode"
"golang.org/x/net/html"
)
@@ -62,16 +61,3 @@ func ExtractText(content string) string {
text = whitespaceRegex.ReplaceAllLiteralString(text, " ")
return text
}
func TruncateText(input string, size int) string {
runes := []rune(input)
if len(runes) <= size {
return input
}
for i := size - 1; i > 0; i-- {
if unicode.IsSpace(runes[i]) {
return string(runes[:i]) + " ..."
}
}
return input
}

View File

@@ -24,21 +24,3 @@ func TestExtractText(t *testing.T) {
}
}
}
func TestTruncateText(t *testing.T) {
input := "Lorem ipsum — классический текст-«рыба»"
size := 30
want := "Lorem ipsum — классический ..."
have := TruncateText(input, size)
if want != have {
t.Errorf("\nsize: %d\nwant: %#v\nhave: %#v", size, want, have)
}
size = 1000
want = input
have = TruncateText(input, size)
if want != have {
t.Errorf("\nsize: %d\nwant: %#v\nhave: %#v", size, want, have)
}
}

View File

@@ -167,7 +167,7 @@ func getExtraAttributes(tagName string) ([]string, []string) {
case "iframe":
return []string{"sandbox", "loading"}, []string{`sandbox="allow-scripts allow-same-origin allow-popups"`, `loading="lazy"`}
case "img":
return []string{"loading"}, []string{`loading="lazy"`, `referrerpolicy="no-referrer"`}
return []string{"loading"}, []string{`loading="lazy"`}
default:
return nil, nil
}

View File

@@ -8,11 +8,10 @@ import "testing"
func TestValidInput(t *testing.T) {
input := `<p>This is a <strong>text</strong> with an image: <img src="http://example.org/" alt="Test" loading="lazy">.</p>`
want := `<p>This is a <strong>text</strong> with an image: <img src="http://example.org/" alt="Test" loading="lazy" referrerpolicy="no-referrer">.</p>`
have := Sanitize("http://example.org/", input)
output := Sanitize("http://example.org/", input)
if have != want {
t.Errorf("Wrong output: \nwant: %#v\nhave: %#v", want, have)
if input != output {
t.Errorf(`Wrong output: "%s" != "%s"`, input, output)
}
}
@@ -28,31 +27,31 @@ func TestImgWithTextDataURL(t *testing.T) {
func TestImgWithDataURL(t *testing.T) {
input := `<img src="data:image/gif;base64,test" alt="Example">`
want := `<img src="data:image/gif;base64,test" alt="Example" loading="lazy" referrerpolicy="no-referrer">`
have := Sanitize("http://example.org/", input)
expected := `<img src="data:image/gif;base64,test" alt="Example" loading="lazy">`
output := Sanitize("http://example.org/", input)
if have != want {
t.Errorf("Wrong output:\nwant: %s\nhave: %s", want, have)
if output != expected {
t.Errorf(`Wrong output: %s`, output)
}
}
func TestImgWithSrcset(t *testing.T) {
input := `<img srcset="example-320w.jpg, example-480w.jpg 1.5x, example-640w.jpg 2x, example-640w.jpg 640w" src="example-640w.jpg" alt="Example">`
want := `<img srcset="http://example.org/example-320w.jpg, http://example.org/example-480w.jpg 1.5x, http://example.org/example-640w.jpg 2x, http://example.org/example-640w.jpg 640w" src="http://example.org/example-640w.jpg" alt="Example" loading="lazy" referrerpolicy="no-referrer">`
have := Sanitize("http://example.org/", input)
expected := `<img srcset="http://example.org/example-320w.jpg, http://example.org/example-480w.jpg 1.5x, http://example.org/example-640w.jpg 2x, http://example.org/example-640w.jpg 640w" src="http://example.org/example-640w.jpg" alt="Example" loading="lazy">`
output := Sanitize("http://example.org/", input)
if have != want {
t.Errorf("Wrong output:\nwant: %s\nhave: %s", want, have)
if output != expected {
t.Errorf(`Wrong output: %s`, output)
}
}
func TestImgWithSrcsetAndDataURL(t *testing.T) {
input := `<img srcset="data:image/gif;base64,test" src="http://example.org/example-320w.jpg" alt="Example">`
want := `<img srcset="data:image/gif;base64,test" src="http://example.org/example-320w.jpg" alt="Example" loading="lazy" referrerpolicy="no-referrer">`
have := Sanitize("http://example.org/", input)
expected := `<img srcset="data:image/gif;base64,test" src="http://example.org/example-320w.jpg" alt="Example" loading="lazy">`
output := Sanitize("http://example.org/", input)
if have != want {
t.Errorf("Wrong output:\nwant: %s\nhave: %s", want, have)
if output != expected {
t.Errorf(`Wrong output: %s`, output)
}
}
@@ -68,16 +67,16 @@ func TestSourceWithSrcsetAndMedia(t *testing.T) {
func TestMediumImgWithSrcset(t *testing.T) {
input := `<img alt="Image for post" class="t u v ef aj" src="https://miro.medium.com/max/5460/1*aJ9JibWDqO81qMfNtqgqrw.jpeg" srcset="https://miro.medium.com/max/552/1*aJ9JibWDqO81qMfNtqgqrw.jpeg 276w, https://miro.medium.com/max/1000/1*aJ9JibWDqO81qMfNtqgqrw.jpeg 500w" sizes="500px" width="2730" height="3407">`
want := `<img alt="Image for post" src="https://miro.medium.com/max/5460/1*aJ9JibWDqO81qMfNtqgqrw.jpeg" srcset="https://miro.medium.com/max/552/1*aJ9JibWDqO81qMfNtqgqrw.jpeg 276w, https://miro.medium.com/max/1000/1*aJ9JibWDqO81qMfNtqgqrw.jpeg 500w" sizes="500px" loading="lazy" referrerpolicy="no-referrer">`
have := Sanitize("http://example.org/", input)
expected := `<img alt="Image for post" src="https://miro.medium.com/max/5460/1*aJ9JibWDqO81qMfNtqgqrw.jpeg" srcset="https://miro.medium.com/max/552/1*aJ9JibWDqO81qMfNtqgqrw.jpeg 276w, https://miro.medium.com/max/1000/1*aJ9JibWDqO81qMfNtqgqrw.jpeg 500w" sizes="500px" loading="lazy">`
output := Sanitize("http://example.org/", input)
if have != want {
t.Errorf("Wrong output:\nwant: %s\nhave: %s", want, have)
if output != expected {
t.Errorf(`Wrong output: %s`, output)
}
}
func TestSelfClosingTags(t *testing.T) {
input := `<p>This <br> is a <strong>text</strong><br/>.</p>`
input := `<p>This <br> is a <strong>text</strong> <br/>with an image: <img src="http://example.org/" alt="Test" loading="lazy"/>.</p>`
output := Sanitize("http://example.org/", input)
if input != output {
@@ -96,11 +95,11 @@ func TestTable(t *testing.T) {
func TestRelativeURL(t *testing.T) {
input := `This <a href="/test.html">link is relative</a> and this image: <img src="../folder/image.png"/>`
want := `This <a href="http://example.org/test.html" rel="noopener noreferrer" target="_blank" referrerpolicy="no-referrer">link is relative</a> and this image: <img src="http://example.org/folder/image.png" loading="lazy" referrerpolicy="no-referrer"/>`
have := Sanitize("http://example.org/", input)
expected := `This <a href="http://example.org/test.html" rel="noopener noreferrer" target="_blank" referrerpolicy="no-referrer">link is relative</a> and this image: <img src="http://example.org/folder/image.png" loading="lazy"/>`
output := Sanitize("http://example.org/", input)
if want != have {
t.Errorf("Wrong output:\nwant: %s\nhave: %s", want, have)
if expected != output {
t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
}
}
@@ -166,11 +165,11 @@ func TestInvalidNestedTag(t *testing.T) {
func TestValidIFrame(t *testing.T) {
input := `<iframe src="http://example.org/"></iframe>`
want := `<iframe src="http://example.org/" sandbox="allow-scripts allow-same-origin allow-popups" loading="lazy"></iframe>`
have := Sanitize("http://example.org/", input)
expected := `<iframe src="http://example.org/" sandbox="allow-scripts allow-same-origin allow-popups" loading="lazy"></iframe>`
output := Sanitize("http://example.org/", input)
if want != have {
t.Errorf("Wrong output:\nwant: %s\nhave: %s", want, have)
if expected != output {
t.Errorf("Wrong output:\nwant: %s\nhave: %s", expected, output)
}
}

View File

@@ -1,7 +1,6 @@
package scraper
import (
"net/url"
"strings"
"github.com/nkanaev/yarr/src/content/htmlutil"
@@ -36,18 +35,6 @@ func FindFeeds(body string, base string) map[string]string {
link := htmlutil.AbsoluteUrl(href, base)
if link != "" {
candidates[link] = name
l, err := url.Parse(link)
if err == nil && l.Host == "www.youtube.com" && l.Path == "/feeds/videos.xml" {
// https://wiki.archiveteam.org/index.php/YouTube/Technical_details#Playlists
channelID, found := strings.CutPrefix(l.Query().Get("channel_id"), "UC")
if found {
const url string = "https://www.youtube.com/feeds/videos.xml?playlist_id="
candidates[url+"UULF"+channelID] = name + " - Videos"
candidates[url+"UULV"+channelID] = name + " - Live Streams"
candidates[url+"UUSH"+channelID] = name + " - Short videos"
}
}
}
}

View File

@@ -3,6 +3,7 @@ package parser
import (
"encoding/xml"
"html"
"io"
"strings"
@@ -57,7 +58,7 @@ func (a *atomText) String() string {
if a.Type == "xhtml" {
data = a.XML
}
return strings.TrimSpace(data)
return html.UnescapeString(strings.TrimSpace(data))
}
func (links atomLinks) First(rel string) string {
@@ -89,16 +90,15 @@ func ParseAtom(r io.Reader) (*Feed, error) {
guidFromID = srcitem.ID + "::" + srcitem.Updated
}
mediaLinks := srcitem.mediaLinks()
link := firstNonEmpty(srcitem.OrigLink, srcitem.Links.First("alternate"), srcitem.Links.First(""), linkFromID)
dstfeed.Items = append(dstfeed.Items, Item{
GUID: firstNonEmpty(guidFromID, srcitem.ID, link),
Date: dateParse(firstNonEmpty(srcitem.Published, srcitem.Updated)),
URL: link,
Title: srcitem.Title.Text(),
Content: firstNonEmpty(srcitem.Content.String(), srcitem.Summary.String(), srcitem.firstMediaDescription()),
MediaLinks: mediaLinks,
GUID: firstNonEmpty(guidFromID, srcitem.ID, link),
Date: dateParse(firstNonEmpty(srcitem.Published, srcitem.Updated)),
URL: link,
Title: srcitem.Title.Text(),
Content: firstNonEmpty(srcitem.Content.String(), srcitem.Summary.String(), srcitem.firstMediaDescription()),
ImageURL: srcitem.firstMediaThumbnail(),
AudioURL: "",
})
}
return dstfeed, nil

View File

@@ -40,11 +40,13 @@ func TestAtom(t *testing.T) {
SiteURL: "http://example.org/",
Items: []Item{
{
GUID: "urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a",
Date: time.Unix(1071340202, 0).UTC(),
URL: "http://example.org/2003/12/13/atom03.html",
Title: "Atom-Powered Robots Run Amok",
Content: `<div xmlns="http://www.w3.org/1999/xhtml"><p>This is the entry content.</p></div>`,
GUID: "urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a",
Date: time.Unix(1071340202, 0).UTC(),
URL: "http://example.org/2003/12/13/atom03.html",
Title: "Atom-Powered Robots Run Amok",
Content: `<div xmlns="http://www.w3.org/1999/xhtml"><p>This is the entry content.</p></div>`,
ImageURL: "",
AudioURL: "",
},
},
}
@@ -139,15 +141,9 @@ func TestAtomImageLink(t *testing.T) {
</entry>
</feed>
`))
if len(feed.Items[0].MediaLinks) != 1 {
t.Fatalf("Expected 1 media link, got: %#v", feed.Items[0].MediaLinks)
}
have := feed.Items[0].MediaLinks[0]
want := MediaLink{
URL: `https://example.com/image.png?width=100&height=100`,
Type: "image",
}
if !reflect.DeepEqual(want, have) {
have := feed.Items[0].ImageURL
want := `https://example.com/image.png?width=100&height=100`
if want != have {
t.Fatalf("item.image_url doesn't match\nwant: %#v\nhave: %#v\n", want, have)
}
}
@@ -169,8 +165,8 @@ func TestAtomImageLinkDuplicated(t *testing.T) {
if want != have {
t.Fatalf("want: %#v\nhave: %#v\n", want, have)
}
if len(feed.Items[0].MediaLinks) != 0 {
t.Fatal("item media link must be excluded if present in the content")
if feed.Items[0].ImageURL != "" {
t.Fatal("item.image_url must be unset if present in the content")
}
}
@@ -196,41 +192,25 @@ func TestAtomLinkInID(t *testing.T) {
have := feed.Items
want := []Item{
Item{
GUID: "https://example.com/posts/1::2003-12-13T09:17:51",
Date: time.Date(2003, time.December, 13, 9, 17, 51, 0, time.UTC),
URL: "https://example.com/posts/1",
Title: "one updated",
},
GUID: "https://example.com/posts/1::2003-12-13T09:17:51",
Date: time.Date(2003, time.December, 13, 9, 17, 51, 0, time.UTC),
URL: "https://example.com/posts/1",
Title: "one updated",
},
Item{
GUID: "urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6",
Date: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC), URL: "",
Title: "two",
},
Item{
GUID: "https://example.com/posts/1::",
Date: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
URL: "https://example.com/posts/1",
Title: "one",
Content: "",
},
Date: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC), URL: "",
Title: "two",
},
Item{
GUID: "https://example.com/posts/1::",
Date: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),
URL: "https://example.com/posts/1",
Title: "one",
Content: "",
},
}
if !reflect.DeepEqual(want, have) {
t.Fatalf("\nwant: %#v\nhave: %#v\n", want, have)
}
}
func TestAtomDoesntEscapeHTMLTags(t *testing.T) {
feed, _ := Parse(strings.NewReader(`
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<entry><summary type="html">&amp;lt;script&amp;gt;alert(1);&amp;lt;/script&amp;gt;</summary></entry>
</feed>
`))
have := feed.Items[0].Content
want := "&lt;script&gt;alert(1);&lt;/script&gt;"
if !reflect.DeepEqual(want, have) {
t.Logf("want: %#v", want)
t.Logf("have: %#v", have)
t.FailNow()
}
}

View File

@@ -2,7 +2,6 @@ package parser
import (
"bytes"
"crypto/sha256"
"encoding/xml"
"errors"
"fmt"
@@ -120,7 +119,6 @@ func ParseAndFix(r io.Reader, baseURL, fallbackEncoding string) (*Feed, error) {
}
feed.TranslateURLs(baseURL)
feed.SetMissingDatesTo(time.Now())
feed.SetMissingGUIDs()
return feed, nil
}
@@ -134,14 +132,11 @@ func (feed *Feed) cleanup() {
feed.Items[i].Title = strings.TrimSpace(htmlutil.ExtractText(item.Title))
feed.Items[i].Content = strings.TrimSpace(item.Content)
if len(feed.Items[i].MediaLinks) > 0 {
mediaLinks := make([]MediaLink, 0)
for _, link := range item.MediaLinks {
if !strings.Contains(item.Content, link.URL) {
mediaLinks = append(mediaLinks, link)
}
}
feed.Items[i].MediaLinks = mediaLinks
if item.ImageURL != "" && strings.Contains(item.Content, item.ImageURL) {
feed.Items[i].ImageURL = ""
}
if item.AudioURL != "" && strings.Contains(item.Content, item.AudioURL) {
feed.Items[i].AudioURL = ""
}
}
}
@@ -173,12 +168,3 @@ func (feed *Feed) TranslateURLs(base string) error {
}
return nil
}
func (feed *Feed) SetMissingGUIDs() {
for i, item := range feed.Items {
if item.GUID == "" {
id := strings.Join([]string{item.Title, item.Date.Format(time.RFC3339), item.URL}, ";;")
feed.Items[i].GUID = fmt.Sprintf("%x", sha256.Sum256([]byte(id)))
}
}
}

View File

@@ -150,32 +150,3 @@ func TestParseCleanIllegalCharsInNonUTF8(t *testing.T) {
t.Fatalf("invalid feed, got: %v", feed)
}
}
func TestParseMissingGUID(t *testing.T) {
data := `
<?xml version="1.0" encoding="windows-1251"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
<item>
<title>foo</title>
</item>
<item>
<title>bar</title>
</item>
</channel>
</rss>
`
feed, err := ParseAndFix(strings.NewReader(data), "", "")
if err != nil {
t.Fatal(err)
}
if len(feed.Items) != 2 {
t.Fatalf("expected 2 items, got %d", len(feed.Items))
}
if feed.Items[0].GUID == "" || feed.Items[1].GUID == "" {
t.Fatalf("item GUIDs are missing, got %#v", feed.Items)
}
if feed.Items[0].GUID == feed.Items[1].GUID {
t.Fatalf("item GUIDs are not unique, got %#v", feed.Items)
}
}

View File

@@ -1,9 +1,5 @@
package parser
import (
"strings"
)
type media struct {
MediaGroups []mediaGroup `xml:"http://search.yahoo.com/mrss/ group"`
MediaContents []mediaContent `xml:"http://search.yahoo.com/mrss/ content"`
@@ -12,17 +8,12 @@ type media struct {
}
type mediaGroup struct {
MediaContent []mediaContent `xml:"http://search.yahoo.com/mrss/ content"`
MediaThumbnails []mediaThumbnail `xml:"http://search.yahoo.com/mrss/ thumbnail"`
MediaDescriptions []mediaDescription `xml:"http://search.yahoo.com/mrss/ description"`
}
type mediaContent struct {
MediaThumbnails []mediaThumbnail `xml:"http://search.yahoo.com/mrss/ thumbnail"`
MediaType string `xml:"type,attr"`
MediaMedium string `xml:"medium,attr"`
MediaURL string `xml:"url,attr"`
MediaDescription mediaDescription `xml:"http://search.yahoo.com/mrss/ description"`
MediaThumbnails []mediaThumbnail `xml:"http://search.yahoo.com/mrss/ thumbnail"`
}
type mediaThumbnail struct {
@@ -30,8 +21,8 @@ type mediaThumbnail struct {
}
type mediaDescription struct {
Type string `xml:"type,attr"`
Text string `xml:",chardata"`
Type string `xml:"type,attr"`
Description string `xml:",chardata"`
}
func (m *media) firstMediaThumbnail() string {
@@ -53,59 +44,12 @@ func (m *media) firstMediaThumbnail() string {
func (m *media) firstMediaDescription() string {
for _, d := range m.MediaDescriptions {
return plain2html(d.Text)
return plain2html(d.Description)
}
for _, g := range m.MediaGroups {
for _, d := range g.MediaDescriptions {
return plain2html(d.Text)
return plain2html(d.Description)
}
}
return ""
}
func (m *media) mediaLinks() []MediaLink {
links := make([]MediaLink, 0)
for _, thumbnail := range m.MediaThumbnails {
links = append(links, MediaLink{URL: thumbnail.URL, Type: "image"})
}
for _, group := range m.MediaGroups {
for _, thumbnail := range group.MediaThumbnails {
links = append(links, MediaLink{
URL: thumbnail.URL,
Type: "image",
})
}
}
for _, content := range m.MediaContents {
if content.MediaURL != "" {
url := content.MediaURL
description := content.MediaDescription.Text
if strings.HasPrefix(content.MediaType, "image/") {
links = append(links, MediaLink{URL: url, Type: "image", Description: description})
} else if strings.HasPrefix(content.MediaType, "audio/") {
links = append(links, MediaLink{URL: url, Type: "audio", Description: description})
} else if strings.HasPrefix(content.MediaType, "video/") {
links = append(links, MediaLink{URL: url, Type: "video", Description: description})
} else if content.MediaMedium == "image" || content.MediaMedium == "audio" || content.MediaMedium == "video" {
links = append(links, MediaLink{URL: url, Type: content.MediaMedium, Description: description})
} else {
if len(content.MediaThumbnails) > 0 {
links = append(links, MediaLink{
URL: content.MediaThumbnails[0].URL,
Type: "image",
})
}
}
}
for _, thumbnail := range content.MediaThumbnails {
links = append(links, MediaLink{
URL: thumbnail.URL,
Type: "image",
})
}
}
if len(links) == 0 {
return nil
}
return links
}

View File

@@ -14,12 +14,7 @@ type Item struct {
URL string
Title string
Content string
MediaLinks []MediaLink
}
type MediaLink struct {
URL string
Type string
Description string
Content string
ImageURL string
AudioURL string
}

View File

@@ -74,14 +74,14 @@ func ParseRSS(r io.Reader) (*Feed, error) {
SiteURL: srcfeed.Link,
}
for _, srcitem := range srcfeed.Items {
mediaLinks := srcitem.mediaLinks()
podcastURL := ""
for _, e := range srcitem.Enclosures {
if strings.HasPrefix(e.Type, "audio/") {
podcastURL := e.URL
podcastURL = e.URL
if srcitem.OrigEnclosureLink != "" && strings.Contains(podcastURL, path.Base(srcitem.OrigEnclosureLink)) {
podcastURL = srcitem.OrigEnclosureLink
}
mediaLinks = append(mediaLinks, MediaLink{URL: podcastURL, Type: "audio"})
break
}
}
@@ -92,12 +92,13 @@ func ParseRSS(r io.Reader) (*Feed, error) {
}
dstfeed.Items = append(dstfeed.Items, Item{
GUID: firstNonEmpty(srcitem.GUID.GUID, srcitem.Link),
Date: dateParse(firstNonEmpty(srcitem.DublinCoreDate, srcitem.PubDate)),
URL: firstNonEmpty(srcitem.OrigLink, srcitem.Link, permalink),
Title: srcitem.Title,
Content: firstNonEmpty(srcitem.ContentEncoded, srcitem.Description, srcitem.firstMediaDescription()),
MediaLinks: mediaLinks,
GUID: firstNonEmpty(srcitem.GUID.GUID, srcitem.Link),
Date: dateParse(firstNonEmpty(srcitem.DublinCoreDate, srcitem.PubDate)),
URL: firstNonEmpty(srcitem.OrigLink, srcitem.Link, permalink),
Title: srcitem.Title,
Content: firstNonEmpty(srcitem.ContentEncoded, srcitem.Description),
AudioURL: podcastURL,
ImageURL: srcitem.firstMediaThumbnail(),
})
}
return dstfeed, nil

View File

@@ -75,15 +75,9 @@ func TestRSSMediaContentThumbnail(t *testing.T) {
</channel>
</rss>
`))
if len(feed.Items[0].MediaLinks) != 1 {
t.Fatalf("Expected 1 media link, got %#v", feed.Items[0].MediaLinks)
}
have := feed.Items[0].MediaLinks[0]
want := MediaLink{
URL: "https://i.vimeocdn.com/video/1092705247_960.jpg",
Type: "image",
}
if !reflect.DeepEqual(want, have) {
have := feed.Items[0].ImageURL
want := "https://i.vimeocdn.com/video/1092705247_960.jpg"
if have != want {
t.Logf("want: %#v", want)
t.Logf("have: %#v", have)
t.FailNow()
@@ -133,15 +127,9 @@ func TestRSSPodcast(t *testing.T) {
</channel>
</rss>
`))
if len(feed.Items[0].MediaLinks) != 1 {
t.Fatal("Invalid media links")
}
have := feed.Items[0].MediaLinks[0]
want := MediaLink{
URL: "http://example.com/audio.ext",
Type: "audio",
}
if !reflect.DeepEqual(want, have) {
have := feed.Items[0].AudioURL
want := "http://example.com/audio.ext"
if want != have {
t.Logf("want: %#v", want)
t.Logf("have: %#v", have)
t.FailNow()
@@ -159,15 +147,9 @@ func TestRSSOpusPodcast(t *testing.T) {
</channel>
</rss>
`))
if len(feed.Items[0].MediaLinks) != 1 {
t.Fatal("Invalid media links")
}
have := feed.Items[0].MediaLinks[0]
want := MediaLink{
URL: "http://example.com/audio.ext",
Type: "audio",
}
if !reflect.DeepEqual(want, have) {
have := feed.Items[0].AudioURL
want := "http://example.com/audio.ext"
if want != have {
t.Logf("want: %#v", want)
t.Logf("have: %#v", have)
t.FailNow()
@@ -194,9 +176,8 @@ func TestRSSPodcastDuplicated(t *testing.T) {
if want != have {
t.Fatalf("content doesn't match\nwant: %#v\nhave: %#v\n", want, have)
}
if len(feed.Items[0].MediaLinks) != 0 {
t.Fatal("item media must be excluded if present in the content")
if feed.Items[0].AudioURL != "" {
t.Fatal("item.audio_url must be unset if present in the content")
}
}
@@ -242,47 +223,8 @@ func TestRSSIsPermalink(t *testing.T) {
},
}
for i := 0; i < len(want); i++ {
if !reflect.DeepEqual(want, have) {
if want[i] != have[i] {
t.Errorf("Failed to handle isPermalink\nwant: %#v\nhave: %#v\n", want[i], have[i])
}
}
}
func TestRSSMultipleMedia(t *testing.T) {
feed, _ := Parse(strings.NewReader(`
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/">
<channel>
<item>
<guid isPermaLink="true">http://example.com/posts/1</guid>
<media:content url="https://example.com/path/to/image1.png" type="image/png" fileSize="1000" medium="image">
<media:description type="plain">description 1</media:description>
</media:content>
<media:content url="https://example.com/path/to/image2.png" type="image/png" fileSize="2000" medium="image">
<media:description type="plain">description 2</media:description>
</media:content>
<media:content url="https://example.com/path/to/video1.mp4" type="video/mp4" fileSize="2000" medium="image">
<media:description type="plain">video description</media:description>
</media:content>
</item>
</channel>
</rss>
`))
have := feed.Items
want := []Item{
{
GUID: "http://example.com/posts/1",
URL: "http://example.com/posts/1",
MediaLinks: []MediaLink{
{URL:"https://example.com/path/to/image1.png", Type:"image", Description:"description 1"},
{URL:"https://example.com/path/to/image2.png", Type:"image", Description:"description 2"},
{URL:"https://example.com/path/to/video1.mp4", Type:"video", Description:"video description"},
},
},
}
if !reflect.DeepEqual(want, have) {
t.Logf("want: %#v", want)
t.Logf("have: %#v", have)
t.Fatal("invalid rss")
}
}

View File

@@ -11,7 +11,6 @@ import (
func Start(s *server.Server) {
systrayOnReady := func() {
systray.SetIcon(Icon)
systray.SetTooltip("yarr")
menuOpen := systray.AddMenuItem("Open", "")
systray.AddSeparator()

View File

@@ -6,7 +6,6 @@ import (
"github.com/nkanaev/yarr/src/assets"
"github.com/nkanaev/yarr/src/server/router"
"github.com/nkanaev/yarr/src/storage"
)
type Middleware struct {
@@ -14,7 +13,6 @@ type Middleware struct {
Password string
BasePath string
Public []string
DB *storage.Storage
}
func unsafeMethod(method string) bool {
@@ -48,15 +46,12 @@ func (m *Middleware) Handler(c *router.Context) {
c.Redirect(rootUrl)
return
} else {
c.HTML(http.StatusOK, assets.Template("login.html"), map[string]interface{}{
c.HTML(http.StatusOK, assets.Template("login.html"), map[string]string{
"username": username,
"error": "Invalid username/password",
"settings": m.DB.GetSettings(),
})
return
}
}
c.HTML(http.StatusOK, assets.Template("login.html"), map[string]interface{}{
"settings": m.DB.GetSettings(),
})
c.HTML(http.StatusOK, assets.Template("login.html"), nil)
}

View File

@@ -35,13 +35,13 @@ func (s *Server) handler() http.Handler {
Username: s.Username,
Password: s.Password,
Public: []string{"/static", "/fever"},
DB: s.db,
}
r.Use(a.Handler)
}
r.For("/", s.handleIndex)
r.For("/manifest.json", s.handleManifest)
r.For("/sw.js", s.handleServiceWorker)
r.For("/static/*path", s.handleStatic)
r.For("/api/status", s.handleStatus)
r.For("/api/folders", s.handleFolderList)
@@ -87,17 +87,31 @@ func (s *Server) handleManifest(c *router.Context) {
"short_name": "yarr",
"description": "yet another rss reader",
"display": "standalone",
"start_url": "/" + strings.TrimPrefix(s.BasePath, "/"),
"start_url": s.BasePath,
"icons": []map[string]interface{}{
{
"src": s.BasePath + "/static/graphicarts/favicon.png",
"sizes": "64x64",
"type": "image/png",
},
{
"src": s.BasePath + "/static/graphicarts/favicon-144.png",
"sizes": "144x144",
"type": "image/png",
},
{
"src": s.BasePath + "/static/graphicarts/favicon.svg",
"sizes": "any",
"type": "image/svg",
},
},
})
}
func (s *Server) handleServiceWorker(c *router.Context) {
http.ServeFile(c.Out, c.Req, "src/assets/javascripts/sw.js")
}
func (s *Server) handleStatus(c *router.Context) {
c.JSON(http.StatusOK, map[string]interface{}{
"running": s.worker.FeedsPending(),
@@ -294,11 +308,6 @@ func (s *Server) handleFeed(c *router.Context) {
s.db.UpdateFeedFolder(id, &folderId)
}
}
if link, ok := body["feed_link"]; ok {
if reflect.TypeOf(link).Kind() == reflect.String {
s.db.UpdateFeedLink(id, link.(string))
}
}
c.Out.WriteHeader(http.StatusOK)
} else if c.Req.Method == "DELETE" {
s.db.DeleteFeed(id)
@@ -329,9 +338,6 @@ func (s *Server) handleItem(c *router.Context) {
}
item.Content = sanitizer.Sanitize(item.Link, item.Content)
for i, link := range item.MediaLinks {
item.MediaLinks[i].Description = sanitizer.Sanitize(item.Link, link.Description)
}
c.JSON(http.StatusOK, item)
} else if c.Req.Method == "PUT" {
@@ -374,19 +380,12 @@ func (s *Server) handleItemList(c *router.Context) {
}
newestFirst := query.Get("oldest_first") != "true"
items := s.db.ListItems(filter, perPage+1, newestFirst, true)
items := s.db.ListItems(filter, perPage+1, newestFirst, false)
hasMore := false
if len(items) == perPage+1 {
hasMore = true
items = items[:perPage]
}
for i, item := range items {
if item.Title == "" {
text := htmlutil.ExtractText(item.Content)
items[i].Title = htmlutil.TruncateText(text, 140)
}
}
c.JSON(http.StatusOK, map[string]interface{}{
"list": items,
"has_more": hasMore,

View File

@@ -71,11 +71,6 @@ func (s *Storage) UpdateFeedFolder(feedId int64, newFolderId *int64) bool {
return err == nil
}
func (s *Storage) UpdateFeedLink(feedId int64, newLink string) bool {
_, err := s.db.Exec(`update feeds set feed_link = ? where id = ?`, newLink, feedId)
return err == nil
}
func (s *Storage) UpdateFeedIcon(feedId int64, icon *[]byte) bool {
_, err := s.db.Exec(`update feeds set icon = ? where id = ?`, icon, feedId)
return err == nil

View File

@@ -1,7 +1,6 @@
package storage
import (
"database/sql/driver"
"encoding/json"
"fmt"
"log"
@@ -45,35 +44,17 @@ func (s *ItemStatus) UnmarshalJSON(b []byte) error {
return nil
}
type MediaLink struct {
URL string `json:"url"`
Type string `json:"type"`
Description string `json:"description,omitempty"`
}
type MediaLinks []MediaLink
func (m *MediaLinks) Scan(src any) error {
if data, ok := src.([]byte); ok {
return json.Unmarshal(data, m)
}
return nil
}
func (m MediaLinks) Value() (driver.Value, error) {
return json.Marshal(m)
}
type Item struct {
Id int64 `json:"id"`
GUID string `json:"guid"`
FeedId int64 `json:"feed_id"`
Title string `json:"title"`
Link string `json:"link"`
Content string `json:"content,omitempty"`
Date time.Time `json:"date"`
Status ItemStatus `json:"status"`
MediaLinks MediaLinks `json:"media_links"`
Id int64 `json:"id"`
GUID string `json:"guid"`
FeedId int64 `json:"feed_id"`
Title string `json:"title"`
Link string `json:"link"`
Content string `json:"content,omitempty"`
Date time.Time `json:"date"`
Status ItemStatus `json:"status"`
ImageURL *string `json:"image"`
AudioURL *string `json:"podcast_url"`
}
type ItemFilter struct {
@@ -98,21 +79,22 @@ type MarkFilter struct {
type ItemList []Item
func (list ItemList) Len() int {
return len(list)
return len(list)
}
func (list ItemList) SortKey(i int) string {
return list[i].Date.Format(time.RFC3339) + "::" + list[i].GUID
return list[i].Date.Format(time.RFC3339) + "::" + list[i].GUID
}
func (list ItemList) Less(i, j int) bool {
return list.SortKey(i) < list.SortKey(j)
return list.SortKey(i) < list.SortKey(j)
}
func (list ItemList) Swap(i, j int) {
list[i], list[j] = list[j], list[i]
list[i], list[j] = list[j], list[i]
}
func (s *Storage) CreateItems(items []Item) bool {
tx, err := s.db.Begin()
if err != nil {
@@ -122,24 +104,20 @@ func (s *Storage) CreateItems(items []Item) bool {
now := time.Now().UTC()
itemsSorted := ItemList(items)
sort.Sort(itemsSorted)
itemsSorted := ItemList(items)
sort.Sort(itemsSorted)
for _, item := range itemsSorted {
_, err = tx.Exec(`
insert into items (
guid, feed_id, title, link, date,
content, media_links,
content, image, podcast_url,
date_arrived, status
)
values (
?, ?, ?, ?, strftime('%Y-%m-%d %H:%M:%f', ?),
?, ?,
?, ?
)
values (?, ?, ?, ?, strftime('%Y-%m-%d %H:%M:%f', ?), ?, ?, ?, ?, ?)
on conflict (feed_id, guid) do nothing`,
item.GUID, item.FeedId, item.Title, item.Link, item.Date,
item.Content, item.MediaLinks,
item.Content, item.ImageURL, item.AudioURL,
now, UNREAD,
)
if err != nil {
@@ -254,7 +232,7 @@ func (s *Storage) ListItems(filter ItemFilter, limit int, newestFirst bool, with
order = "i.id desc"
}
selectCols := "i.id, i.guid, i.feed_id, i.title, i.link, i.date, i.status, i.media_links"
selectCols := "i.id, i.guid, i.feed_id, i.title, i.link, i.date, i.status, i.image, i.podcast_url"
if withContent {
selectCols += ", i.content"
} else {
@@ -277,7 +255,7 @@ func (s *Storage) ListItems(filter ItemFilter, limit int, newestFirst bool, with
err = rows.Scan(
&x.Id, &x.GUID, &x.FeedId,
&x.Title, &x.Link, &x.Date,
&x.Status, &x.MediaLinks, &x.Content,
&x.Status, &x.ImageURL, &x.AudioURL, &x.Content,
)
if err != nil {
log.Print(err)
@@ -293,12 +271,12 @@ func (s *Storage) GetItem(id int64) *Item {
err := s.db.QueryRow(`
select
i.id, i.guid, i.feed_id, i.title, i.link, i.content,
i.date, i.status, i.media_links
i.date, i.status, i.image, i.podcast_url
from items i
where i.id = ?
`, id).Scan(
&i.Id, &i.GUID, &i.FeedId, &i.Title, &i.Link, &i.Content,
&i.Date, &i.Status, &i.MediaLinks,
&i.Date, &i.Status, &i.ImageURL, &i.AudioURL,
)
if err != nil {
log.Print(err)

View File

@@ -77,12 +77,12 @@ func getItem(db *Storage, guid string) *Item {
err := db.db.QueryRow(`
select
i.id, i.guid, i.feed_id, i.title, i.link, i.content,
i.date, i.status, i.media_links
i.date, i.status, i.image, i.podcast_url
from items i
where i.guid = ?
`, guid).Scan(
&i.Id, &i.GUID, &i.FeedId, &i.Title, &i.Link, &i.Content,
&i.Date, &i.Status, &i.MediaLinks,
&i.Date, &i.Status, &i.ImageURL, &i.AudioURL,
)
if err != nil {
log.Fatal(err)

View File

@@ -16,17 +16,13 @@ var migrations = []func(*sql.Tx) error{
m06_fill_missing_dates,
m07_add_feed_size,
m08_normalize_datetime,
m09_change_item_index,
m10_add_item_medialinks,
}
var maxVersion = int64(len(migrations))
func migrate(db *sql.DB) error {
var version int64
if err := db.QueryRow("pragma user_version").Scan(&version); err != nil {
return err
}
db.QueryRow("pragma user_version").Scan(&version)
if version >= maxVersion {
return nil
@@ -298,37 +294,3 @@ func m08_normalize_datetime(tx *sql.Tx) error {
_, err = tx.Exec(`update items set date = strftime('%Y-%m-%d %H:%M:%f', date);`)
return err
}
func m09_change_item_index(tx *sql.Tx) error {
sql := `
drop index if exists idx_item_status;
create index if not exists idx_item__date_id_status on items(date,id,status);
`
_, err := tx.Exec(sql)
return err
}
func m10_add_item_medialinks(tx *sql.Tx) error {
sql := `
alter table items add column media_links blob;
update items set media_links =
iif(
coalesce(image, '') != '' and coalesce(podcast_url, '') != '',
json_array(json_object('type', 'image', 'url', image), json_object('type', 'audio', 'url', podcast_url)),
iif(
coalesce(image, '') != '',
json_array(json_object('type', 'image', 'url', image)),
iif(
coalesce(podcast_url, '') != '',
json_array(json_object('type', 'audio', 'url', podcast_url)),
null
)
)
);
alter table items drop column image;
alter table items drop column podcast_url;
`
_, err := tx.Exec(sql)
return err
}

View File

@@ -2,9 +2,6 @@ package storage
import (
"database/sql"
"log"
"strings"
_ "github.com/mattn/go-sqlite3"
)
@@ -13,17 +10,14 @@ type Storage struct {
}
func New(path string) (*Storage, error) {
if pos := strings.IndexRune(path, '?'); pos == -1 {
params := "_journal=WAL&_sync=NORMAL&_busy_timeout=5000&cache=shared"
log.Printf("opening db with params: %s", params)
path = path + "?" + params
}
db, err := sql.Open("sqlite3", path)
if err != nil {
return nil, err
}
// TODO: https://foxcpp.dev/articles/the-right-way-to-use-go-sqlite3
db.SetMaxOpenConns(1)
if err = migrate(db); err != nil {
return nil, err
}

View File

@@ -1,4 +1,3 @@
//go:build darwin || windows
// +build darwin windows
/*

View File

@@ -1,4 +1,3 @@
//go:build never
// +build never
package systray

View File

@@ -1,4 +1,3 @@
//go:build darwin
// +build darwin
package systray

View File

@@ -1,4 +1,3 @@
//go:build windows
// +build windows
package systray

View File

@@ -1,4 +1,3 @@
//go:build windows
// +build windows
package systray

View File

@@ -32,10 +32,6 @@ func (c *Client) getConditional(url, lastModified, etag string) (*http.Response,
var client *Client
func SetVersion(num string) {
client.userAgent = "Yarr/" + num
}
func init() {
transport := &http.Transport{
Proxy: http.ProxyFromEnvironment,

View File

@@ -143,19 +143,24 @@ func ConvertItems(items []parser.Item, feed storage.Feed) []storage.Item {
result := make([]storage.Item, len(items))
for i, item := range items {
item := item
mediaLinks := make(storage.MediaLinks, 0)
for _, link := range item.MediaLinks {
mediaLinks = append(mediaLinks, storage.MediaLink(link))
var audioURL *string = nil
if item.AudioURL != "" {
audioURL = &item.AudioURL
}
var imageURL *string = nil
if item.ImageURL != "" {
imageURL = &item.ImageURL
}
result[i] = storage.Item{
GUID: item.GUID,
FeedId: feed.Id,
Title: item.Title,
Link: item.URL,
Content: item.Content,
Date: item.Date,
Status: storage.UNREAD,
MediaLinks: mediaLinks,
GUID: item.GUID,
FeedId: feed.Id,
Title: item.Title,
Link: item.URL,
Content: item.Content,
Date: item.Date,
Status: storage.UNREAD,
ImageURL: imageURL,
AudioURL: audioURL,
}
}
return result

4
vendor/golang.org/x/net/LICENSE generated vendored
View File

@@ -1,4 +1,4 @@
Copyright 2009 The Go Authors.
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer.
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google LLC nor the names of its
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

27
vendor/golang.org/x/net/html/doc.go generated vendored
View File

@@ -78,11 +78,16 @@ example, to process each anchor node in depth-first order:
if err != nil {
// ...
}
for n := range doc.Descendants() {
var f func(*html.Node)
f = func(n *html.Node) {
if n.Type == html.ElementNode && n.Data == "a" {
// Do something with n...
}
for c := n.FirstChild; c != nil; c = c.NextSibling {
f(c)
}
}
f(doc)
The relevant specifications include:
https://html.spec.whatwg.org/multipage/syntax.html and
@@ -94,20 +99,14 @@ Care should be taken when parsing and interpreting HTML, whether full documents
or fragments, within the framework of the HTML specification, especially with
regard to untrusted inputs.
This package provides both a tokenizer and a parser, which implement the
tokenization, and tokenization and tree construction stages of the WHATWG HTML
parsing specification respectively. While the tokenizer parses and normalizes
individual HTML tokens, only the parser constructs the DOM tree from the
tokenized HTML, as described in the tree construction stage of the
specification, dynamically modifying or extending the document's DOM tree.
This package provides both a tokenizer and a parser. Only the parser constructs
a DOM according to the HTML specification, resolving malformed and misplaced
tags where appropriate. The tokenizer simply tokenizes the HTML presented to it,
and as such does not resolve issues that may exist in the processed HTML,
producing a literal interpretation of the input.
If your use case requires semantically well-formed HTML documents, as defined by
the WHATWG specification, the parser should be used rather than the tokenizer.
In security contexts, if trust decisions are being made using the tokenized or
parsed content, the input must be re-serialized (for instance by using Render or
Token.String) in order for those trust decisions to hold, as the process of
tokenization or parsing may alter the content.
If your use case requires semantically well-formed HTML, as defined by the
WHATWG specifiction, the parser should be used rather than the tokenizer.
*/
package html // import "golang.org/x/net/html"

View File

@@ -87,7 +87,7 @@ func parseDoctype(s string) (n *Node, quirks bool) {
}
}
if lastAttr := n.Attr[len(n.Attr)-1]; lastAttr.Key == "system" &&
strings.EqualFold(lastAttr.Val, "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd") {
strings.ToLower(lastAttr.Val) == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd" {
quirks = true
}
}

View File

@@ -40,7 +40,8 @@ func htmlIntegrationPoint(n *Node) bool {
if n.Data == "annotation-xml" {
for _, a := range n.Attr {
if a.Key == "encoding" {
if strings.EqualFold(a.Val, "text/html") || strings.EqualFold(a.Val, "application/xhtml+xml") {
val := strings.ToLower(a.Val)
if val == "text/html" || val == "application/xhtml+xml" {
return true
}
}

56
vendor/golang.org/x/net/html/iter.go generated vendored
View File

@@ -1,56 +0,0 @@
// Copyright 2024 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.23
package html
import "iter"
// Ancestors returns an iterator over the ancestors of n, starting with n.Parent.
//
// Mutating a Node or its parents while iterating may have unexpected results.
func (n *Node) Ancestors() iter.Seq[*Node] {
_ = n.Parent // eager nil check
return func(yield func(*Node) bool) {
for p := n.Parent; p != nil && yield(p); p = p.Parent {
}
}
}
// ChildNodes returns an iterator over the immediate children of n,
// starting with n.FirstChild.
//
// Mutating a Node or its children while iterating may have unexpected results.
func (n *Node) ChildNodes() iter.Seq[*Node] {
_ = n.FirstChild // eager nil check
return func(yield func(*Node) bool) {
for c := n.FirstChild; c != nil && yield(c); c = c.NextSibling {
}
}
}
// Descendants returns an iterator over all nodes recursively beneath
// n, excluding n itself. Nodes are visited in depth-first preorder.
//
// Mutating a Node or its descendants while iterating may have unexpected results.
func (n *Node) Descendants() iter.Seq[*Node] {
_ = n.FirstChild // eager nil check
return func(yield func(*Node) bool) {
n.descendants(yield)
}
}
func (n *Node) descendants(yield func(*Node) bool) bool {
for c := range n.ChildNodes() {
if !yield(c) || !c.descendants(yield) {
return false
}
}
return true
}

View File

@@ -38,10 +38,6 @@ var scopeMarker = Node{Type: scopeMarkerNode}
// that it looks like "a<b" rather than "a&lt;b". For element nodes, DataAtom
// is the atom for Data, or zero if Data is not a known tag name.
//
// Node trees may be navigated using the link fields (Parent,
// FirstChild, and so on) or a range loop over iterators such as
// [Node.Descendants].
//
// An empty Namespace implies a "http://www.w3.org/1999/xhtml" namespace.
// Similarly, "math" is short for "http://www.w3.org/1998/Math/MathML", and
// "svg" is short for "http://www.w3.org/2000/svg".

View File

@@ -840,10 +840,6 @@ func afterHeadIM(p *parser) bool {
p.parseImpliedToken(StartTagToken, a.Body, a.Body.String())
p.framesetOK = true
if p.tok.Type == ErrorToken {
// Stop parsing.
return true
}
return false
}
@@ -1035,7 +1031,7 @@ func inBodyIM(p *parser) bool {
if p.tok.DataAtom == a.Input {
for _, t := range p.tok.Attr {
if t.Key == "type" {
if strings.EqualFold(t.Val, "hidden") {
if strings.ToLower(t.Val) == "hidden" {
// Skip setting framesetOK = false
return true
}
@@ -1463,7 +1459,7 @@ func inTableIM(p *parser) bool {
return inHeadIM(p)
case a.Input:
for _, t := range p.tok.Attr {
if t.Key == "type" && strings.EqualFold(t.Val, "hidden") {
if t.Key == "type" && strings.ToLower(t.Val) == "hidden" {
p.addElement()
p.oe.pop()
return true

View File

@@ -194,8 +194,9 @@ func render1(w writer, n *Node) error {
}
}
// Render any child nodes
if childTextNodesAreLiteral(n) {
// Render any child nodes.
switch n.Data {
case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "xmp":
for c := n.FirstChild; c != nil; c = c.NextSibling {
if c.Type == TextNode {
if _, err := w.WriteString(c.Data); err != nil {
@@ -212,7 +213,7 @@ func render1(w writer, n *Node) error {
// last element in the file, with no closing tag.
return plaintextAbort
}
} else {
default:
for c := n.FirstChild; c != nil; c = c.NextSibling {
if err := render1(w, c); err != nil {
return err
@@ -230,27 +231,6 @@ func render1(w writer, n *Node) error {
return w.WriteByte('>')
}
func childTextNodesAreLiteral(n *Node) bool {
// Per WHATWG HTML 13.3, if the parent of the current node is a style,
// script, xmp, iframe, noembed, noframes, or plaintext element, and the
// current node is a text node, append the value of the node's data
// literally. The specification is not explicit about it, but we only
// enforce this if we are in the HTML namespace (i.e. when the namespace is
// "").
// NOTE: we also always include noscript elements, although the
// specification states that they should only be rendered as such if
// scripting is enabled for the node (which is not something we track).
if n.Namespace != "" {
return false
}
switch n.Data {
case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "xmp":
return true
default:
return false
}
}
// writeQuoted writes s to w surrounded by quotes. Normally it will use double
// quotes, but if s contains a double quote, it will use single quotes.
// It is used for writing the identifiers in a doctype declaration.

View File

@@ -910,16 +910,10 @@ func (z *Tokenizer) readTagAttrKey() {
return
}
switch c {
case '=':
if z.pendingAttr[0].start+1 == z.raw.end {
// WHATWG 13.2.5.32, if we see an equals sign before the attribute name
// begins, we treat it as a character in the attribute name and continue.
continue
}
fallthrough
case ' ', '\n', '\r', '\t', '\f', '/', '>':
// WHATWG 13.2.5.33 Attribute name state
// We need to reconsume the char in the after attribute name state to support the / character
case ' ', '\n', '\r', '\t', '\f', '/':
z.pendingAttr[0].end = z.raw.end - 1
return
case '=', '>':
z.raw.end--
z.pendingAttr[0].end = z.raw.end
return
@@ -938,11 +932,6 @@ func (z *Tokenizer) readTagAttrVal() {
if z.err != nil {
return
}
if c == '/' {
// WHATWG 13.2.5.34 After attribute name state
// U+002F SOLIDUS (/) - Switch to the self-closing start tag state.
return
}
if c != '=' {
z.raw.end--
return

4
vendor/golang.org/x/sys/LICENSE generated vendored
View File

@@ -1,4 +1,4 @@
Copyright 2009 The Go Authors.
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer.
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google LLC nor the names of its
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

View File

@@ -0,0 +1,30 @@
// Copyright 2020 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 unsafeheader contains header declarations for the Go runtime's
// slice and string implementations.
//
// This package allows x/sys to use types equivalent to
// reflect.SliceHeader and reflect.StringHeader without introducing
// a dependency on the (relatively heavy) "reflect" package.
package unsafeheader
import (
"unsafe"
)
// Slice is the runtime representation of a slice.
// It cannot be used safely or portably and its representation may change in a later release.
type Slice struct {
Data unsafe.Pointer
Len int
Cap int
}
// String is the runtime representation of a string.
// It cannot be used safely or portably and its representation may change in a later release.
type String struct {
Data unsafe.Pointer
Len int
}

View File

@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build windows
//go:build windows && go1.9
// +build windows,go1.9
package windows

View File

@@ -65,7 +65,7 @@ func LoadDLL(name string) (dll *DLL, err error) {
return d, nil
}
// MustLoadDLL is like LoadDLL but panics if load operation fails.
// MustLoadDLL is like LoadDLL but panics if load operation failes.
func MustLoadDLL(name string) *DLL {
d, e := LoadDLL(name)
if e != nil {

9
vendor/golang.org/x/sys/windows/empty.s generated vendored Normal file
View File

@@ -0,0 +1,9 @@
// Copyright 2019 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.12
// +build !go1.12
// This file is here to allow bodyless functions with go:linkname for Go 1.11
// and earlier (see https://golang.org/issue/23311).

View File

@@ -37,17 +37,14 @@ func (token Token) Environ(inheritExisting bool) (env []string, err error) {
return nil, err
}
defer DestroyEnvironmentBlock(block)
size := unsafe.Sizeof(*block)
for *block != 0 {
// find NUL terminator
end := unsafe.Pointer(block)
for *(*uint16)(end) != 0 {
end = unsafe.Add(end, size)
blockp := uintptr(unsafe.Pointer(block))
for {
entry := UTF16PtrToString((*uint16)(unsafe.Pointer(blockp)))
if len(entry) == 0 {
break
}
entry := unsafe.Slice(block, (uintptr(end)-uintptr(unsafe.Pointer(block)))/size)
env = append(env, UTF16ToString(entry))
block = (*uint16)(unsafe.Add(end, size))
env = append(env, entry)
blockp += 2 * (uintptr(len(entry)) + 1)
}
return env, nil
}

View File

@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.
//go:build windows
// +build windows
package windows

View File

@@ -22,7 +22,7 @@ import (
// but only if there is space or tab inside s.
func EscapeArg(s string) string {
if len(s) == 0 {
return `""`
return "\"\""
}
n := len(s)
hasSpace := false
@@ -35,7 +35,7 @@ func EscapeArg(s string) string {
}
}
if hasSpace {
n += 2 // Reserve space for quotes.
n += 2
}
if n == len(s) {
return s
@@ -82,106 +82,36 @@ func EscapeArg(s string) string {
// in CreateProcess's CommandLine argument, CreateService/ChangeServiceConfig's BinaryPathName argument,
// or any program that uses CommandLineToArgv.
func ComposeCommandLine(args []string) string {
if len(args) == 0 {
return ""
}
// Per https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw:
// “This function accepts command lines that contain a program name; the
// program name can be enclosed in quotation marks or not.”
//
// Unfortunately, it provides no means of escaping interior quotation marks
// within that program name, and we have no way to report them here.
prog := args[0]
mustQuote := len(prog) == 0
for i := 0; i < len(prog); i++ {
c := prog[i]
if c <= ' ' || (c == '"' && i == 0) {
// Force quotes for not only the ASCII space and tab as described in the
// MSDN article, but also ASCII control characters.
// The documentation for CommandLineToArgvW doesn't say what happens when
// the first argument is not a valid program name, but it empirically
// seems to drop unquoted control characters.
mustQuote = true
break
var commandLine string
for i := range args {
if i > 0 {
commandLine += " "
}
commandLine += EscapeArg(args[i])
}
var commandLine []byte
if mustQuote {
commandLine = make([]byte, 0, len(prog)+2)
commandLine = append(commandLine, '"')
for i := 0; i < len(prog); i++ {
c := prog[i]
if c == '"' {
// This quote would interfere with our surrounding quotes.
// We have no way to report an error, so just strip out
// the offending character instead.
continue
}
commandLine = append(commandLine, c)
}
commandLine = append(commandLine, '"')
} else {
if len(args) == 1 {
// args[0] is a valid command line representing itself.
// No need to allocate a new slice or string for it.
return prog
}
commandLine = []byte(prog)
}
for _, arg := range args[1:] {
commandLine = append(commandLine, ' ')
// TODO(bcmills): since we're already appending to a slice, it would be nice
// to avoid the intermediate allocations of EscapeArg.
// Perhaps we can factor out an appendEscapedArg function.
commandLine = append(commandLine, EscapeArg(arg)...)
}
return string(commandLine)
return commandLine
}
// DecomposeCommandLine breaks apart its argument command line into unescaped parts using CommandLineToArgv,
// as gathered from GetCommandLine, QUERY_SERVICE_CONFIG's BinaryPathName argument, or elsewhere that
// command lines are passed around.
// DecomposeCommandLine returns an error if commandLine contains NUL.
func DecomposeCommandLine(commandLine string) ([]string, error) {
if len(commandLine) == 0 {
return []string{}, nil
}
utf16CommandLine, err := UTF16FromString(commandLine)
if err != nil {
return nil, errorspkg.New("string with NUL passed to DecomposeCommandLine")
}
var argc int32
argv, err := commandLineToArgv(&utf16CommandLine[0], &argc)
argv, err := CommandLineToArgv(StringToUTF16Ptr(commandLine), &argc)
if err != nil {
return nil, err
}
defer LocalFree(Handle(unsafe.Pointer(argv)))
var args []string
for _, p := range unsafe.Slice(argv, argc) {
args = append(args, UTF16PtrToString(p))
for _, v := range (*argv)[:argc] {
args = append(args, UTF16ToString((*v)[:]))
}
return args, nil
}
// CommandLineToArgv parses a Unicode command line string and sets
// argc to the number of parsed arguments.
//
// The returned memory should be freed using a single call to LocalFree.
//
// Note that although the return type of CommandLineToArgv indicates 8192
// entries of up to 8192 characters each, the actual count of parsed arguments
// may exceed 8192, and the documentation for CommandLineToArgvW does not mention
// any bound on the lengths of the individual argument strings.
// (See https://go.dev/issue/63236.)
func CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) {
argp, err := commandLineToArgv(cmd, argc)
argv = (*[8192]*[8192]uint16)(unsafe.Pointer(argp))
return argv, err
}
func CloseOnExec(fd Handle) {
SetHandleInformation(Handle(fd), HANDLE_FLAG_INHERIT, 0)
}

View File

@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.
//go:build generate
// +build generate
package windows

View File

@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.
//go:build windows && race
// +build windows,race
package windows

View File

@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.
//go:build windows && !race
// +build windows,!race
package windows

View File

@@ -7,6 +7,8 @@ package windows
import (
"syscall"
"unsafe"
"golang.org/x/sys/internal/unsafeheader"
)
const (
@@ -68,7 +70,6 @@ type UserInfo10 struct {
//sys NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
//sys NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation
//sys NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
//sys NetUserEnum(serverName *uint16, level uint32, filter uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32, resumeHandle *uint32) (neterr error) = netapi32.NetUserEnum
const (
// do not reorder
@@ -894,7 +895,7 @@ type ACL struct {
aclRevision byte
sbz1 byte
aclSize uint16
AceCount uint16
aceCount uint16
sbz2 uint16
}
@@ -1087,27 +1088,6 @@ type EXPLICIT_ACCESS struct {
Trustee TRUSTEE
}
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
type ACE_HEADER struct {
AceType uint8
AceFlags uint8
AceSize uint16
}
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_ace
type ACCESS_ALLOWED_ACE struct {
Header ACE_HEADER
Mask ACCESS_MASK
SidStart uint32
}
const (
// Constants for AceType
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
ACCESS_ALLOWED_ACE_TYPE = 0
ACCESS_DENIED_ACE_TYPE = 1
)
// This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions.
type TrusteeValue uintptr
@@ -1179,7 +1159,6 @@ type OBJECTS_AND_NAME struct {
//sys makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) = advapi32.MakeSelfRelativeSD
//sys setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) = advapi32.SetEntriesInAclW
//sys GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (err error) = advapi32.GetAce
// Control returns the security descriptor control bits.
func (sd *SECURITY_DESCRIPTOR) Control() (control SECURITY_DESCRIPTOR_CONTROL, revision uint32, err error) {
@@ -1362,14 +1341,21 @@ func (selfRelativeSD *SECURITY_DESCRIPTOR) copySelfRelativeSecurityDescriptor()
sdLen = min
}
src := unsafe.Slice((*byte)(unsafe.Pointer(selfRelativeSD)), sdLen)
// SECURITY_DESCRIPTOR has pointers in it, which means checkptr expects for it to
// be aligned properly. When we're copying a Windows-allocated struct to a
// Go-allocated one, make sure that the Go allocation is aligned to the
// pointer size.
var src []byte
h := (*unsafeheader.Slice)(unsafe.Pointer(&src))
h.Data = unsafe.Pointer(selfRelativeSD)
h.Len = sdLen
h.Cap = sdLen
const psize = int(unsafe.Sizeof(uintptr(0)))
var dst []byte
h = (*unsafeheader.Slice)(unsafe.Pointer(&dst))
alloc := make([]uintptr, (sdLen+psize-1)/psize)
dst := unsafe.Slice((*byte)(unsafe.Pointer(&alloc[0])), sdLen)
h.Data = (*unsafeheader.Slice)(unsafe.Pointer(&alloc)).Data
h.Len = sdLen
h.Cap = sdLen
copy(dst, src)
return (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&dst[0]))
}

View File

@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.
//go:build windows
// +build windows
package windows
@@ -140,12 +141,6 @@ const (
SERVICE_DYNAMIC_INFORMATION_LEVEL_START_REASON = 1
)
type ENUM_SERVICE_STATUS struct {
ServiceName *uint16
DisplayName *uint16
ServiceStatus SERVICE_STATUS
}
type SERVICE_STATUS struct {
ServiceType uint32
CurrentState uint32
@@ -217,10 +212,6 @@ type SERVICE_FAILURE_ACTIONS struct {
Actions *SC_ACTION
}
type SERVICE_FAILURE_ACTIONS_FLAG struct {
FailureActionsOnNonCrashFailures int32
}
type SC_ACTION struct {
Type uint32
Delay uint32
@@ -254,4 +245,3 @@ type QUERY_SERVICE_LOCK_STATUS struct {
//sys UnsubscribeServiceChangeNotifications(subscription uintptr) = sechost.UnsubscribeServiceChangeNotifications?
//sys RegisterServiceCtrlHandlerEx(serviceName *uint16, handlerProc uintptr, context uintptr) (handle Handle, err error) = advapi32.RegisterServiceCtrlHandlerExW
//sys QueryServiceDynamicInformation(service Handle, infoLevel uint32, dynamicInfo unsafe.Pointer) (err error) = advapi32.QueryServiceDynamicInformation?
//sys EnumDependentServices(service Handle, activityState uint32, services *ENUM_SERVICE_STATUS, buffSize uint32, bytesNeeded *uint32, servicesReturned *uint32) (err error) = advapi32.EnumDependentServicesW

View File

@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.
//go:build windows
// +build windows
package windows

View File

@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.
//go:build windows
// +build windows
// Package windows contains an interface to the low-level operating system
// primitives. OS details vary depending on the underlying system, and

View File

@@ -15,12 +15,12 @@ import (
"time"
"unicode/utf16"
"unsafe"
"golang.org/x/sys/internal/unsafeheader"
)
type (
Handle uintptr
HWND uintptr
)
type Handle uintptr
type HWND uintptr
const (
InvalidHandle = ^Handle(0)
@@ -127,21 +127,22 @@ func UTF16PtrToString(p *uint16) string {
for ptr := unsafe.Pointer(p); *(*uint16)(ptr) != 0; n++ {
ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p))
}
return UTF16ToString(unsafe.Slice(p, n))
return string(utf16.Decode(unsafe.Slice(p, n)))
}
func Getpagesize() int { return 4096 }
// NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention.
// This is useful when interoperating with Windows code requiring callbacks.
// The argument is expected to be a function with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr.
// The argument is expected to be a function with with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr.
func NewCallback(fn interface{}) uintptr {
return syscall.NewCallback(fn)
}
// NewCallbackCDecl converts a Go function to a function pointer conforming to the cdecl calling convention.
// This is useful when interoperating with Windows code requiring callbacks.
// The argument is expected to be a function with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr.
// The argument is expected to be a function with with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr.
func NewCallbackCDecl(fn interface{}) uintptr {
return syscall.NewCallbackCDecl(fn)
}
@@ -156,8 +157,6 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys GetModuleFileName(module Handle, filename *uint16, size uint32) (n uint32, err error) = kernel32.GetModuleFileNameW
//sys GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err error) = kernel32.GetModuleHandleExW
//sys SetDefaultDllDirectories(directoryFlags uint32) (err error)
//sys AddDllDirectory(path *uint16) (cookie uintptr, err error) = kernel32.AddDllDirectory
//sys RemoveDllDirectory(cookie uintptr) (err error) = kernel32.RemoveDllDirectory
//sys SetDllDirectory(path string) (err error) = kernel32.SetDllDirectoryW
//sys GetVersion() (ver uint32, err error)
//sys FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW
@@ -167,9 +166,6 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile Handle) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW
//sys CreateNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *SecurityAttributes) (handle Handle, err error) [failretval==InvalidHandle] = CreateNamedPipeW
//sys ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error)
//sys DisconnectNamedPipe(pipe Handle) (err error)
//sys GetNamedPipeClientProcessId(pipe Handle, clientProcessID *uint32) (err error)
//sys GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err error)
//sys GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error)
//sys GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
//sys SetNamedPipeHandleState(pipe Handle, state *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32) (err error) = SetNamedPipeHandleState
@@ -198,7 +194,6 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW
//sys GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW
//sys SetEndOfFile(handle Handle) (err error)
//sys SetFileValidData(handle Handle, validDataLength int64) (err error)
//sys GetSystemTimeAsFileTime(time *Filetime)
//sys GetSystemTimePreciseAsFileTime(time *Filetime)
//sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff]
@@ -215,17 +210,13 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) (handle Handle, err error)
//sys ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) [failretval<=32] = shell32.ShellExecuteW
//sys GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) = user32.GetWindowThreadProcessId
//sys LoadKeyboardLayout(name *uint16, flags uint32) (hkl Handle, err error) [failretval==0] = user32.LoadKeyboardLayoutW
//sys UnloadKeyboardLayout(hkl Handle) (err error) = user32.UnloadKeyboardLayout
//sys GetKeyboardLayout(tid uint32) (hkl Handle) = user32.GetKeyboardLayout
//sys ToUnicodeEx(vkey uint32, scancode uint32, keystate *byte, pwszBuff *uint16, cchBuff int32, flags uint32, hkl Handle) (ret int32) = user32.ToUnicodeEx
//sys GetShellWindow() (shellWindow HWND) = user32.GetShellWindow
//sys MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) [failretval==0] = user32.MessageBoxW
//sys ExitWindowsEx(flags uint32, reason uint32) (err error) = user32.ExitWindowsEx
//sys shGetKnownFolderPath(id *KNOWNFOLDERID, flags uint32, token Token, path **uint16) (ret error) = shell32.SHGetKnownFolderPath
//sys TerminateProcess(handle Handle, exitcode uint32) (err error)
//sys GetExitCodeProcess(handle Handle, exitcode *uint32) (err error)
//sys getStartupInfo(startupInfo *StartupInfo) = GetStartupInfoW
//sys GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW
//sys GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error)
//sys DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error)
//sys WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff]
@@ -244,13 +235,12 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys CreateEnvironmentBlock(block **uint16, token Token, inheritExisting bool) (err error) = userenv.CreateEnvironmentBlock
//sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock
//sys getTickCount64() (ms uint64) = kernel32.GetTickCount64
//sys GetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error)
//sys SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error)
//sys GetFileAttributes(name *uint16) (attrs uint32, err error) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.GetFileAttributesW
//sys SetFileAttributes(name *uint16, attrs uint32) (err error) = kernel32.SetFileAttributesW
//sys GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) = kernel32.GetFileAttributesExW
//sys GetCommandLine() (cmd *uint16) = kernel32.GetCommandLineW
//sys commandLineToArgv(cmd *uint16, argc *int32) (argv **uint16, err error) [failretval==nil] = shell32.CommandLineToArgvW
//sys CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) [failretval==nil] = shell32.CommandLineToArgvW
//sys LocalFree(hmem Handle) (handle Handle, err error) [failretval!=0]
//sys LocalAlloc(flags uint32, length uint32) (ptr uintptr, err error)
//sys SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error)
@@ -309,19 +299,12 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys RegNotifyChangeKeyValue(key Handle, watchSubtree bool, notifyFilter uint32, event Handle, asynchronous bool) (regerrno error) = advapi32.RegNotifyChangeKeyValue
//sys GetCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId
//sys ProcessIdToSessionId(pid uint32, sessionid *uint32) (err error) = kernel32.ProcessIdToSessionId
//sys ClosePseudoConsole(console Handle) = kernel32.ClosePseudoConsole
//sys createPseudoConsole(size uint32, in Handle, out Handle, flags uint32, pconsole *Handle) (hr error) = kernel32.CreatePseudoConsole
//sys GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode
//sys SetConsoleMode(console Handle, mode uint32) (err error) = kernel32.SetConsoleMode
//sys GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) = kernel32.GetConsoleScreenBufferInfo
//sys setConsoleCursorPosition(console Handle, position uint32) (err error) = kernel32.SetConsoleCursorPosition
//sys GetConsoleCP() (cp uint32, err error) = kernel32.GetConsoleCP
//sys GetConsoleOutputCP() (cp uint32, err error) = kernel32.GetConsoleOutputCP
//sys SetConsoleCP(cp uint32) (err error) = kernel32.SetConsoleCP
//sys SetConsoleOutputCP(cp uint32) (err error) = kernel32.SetConsoleOutputCP
//sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW
//sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW
//sys resizePseudoConsole(pconsole Handle, size uint32) (hr error) = kernel32.ResizePseudoConsole
//sys CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot
//sys Module32First(snapshot Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32FirstW
//sys Module32Next(snapshot Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32NextW
@@ -361,19 +344,8 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys SetProcessPriorityBoost(process Handle, disable bool) (err error) = kernel32.SetProcessPriorityBoost
//sys GetProcessWorkingSetSizeEx(hProcess Handle, lpMinimumWorkingSetSize *uintptr, lpMaximumWorkingSetSize *uintptr, flags *uint32)
//sys SetProcessWorkingSetSizeEx(hProcess Handle, dwMinimumWorkingSetSize uintptr, dwMaximumWorkingSetSize uintptr, flags uint32) (err error)
//sys ClearCommBreak(handle Handle) (err error)
//sys ClearCommError(handle Handle, lpErrors *uint32, lpStat *ComStat) (err error)
//sys EscapeCommFunction(handle Handle, dwFunc uint32) (err error)
//sys GetCommState(handle Handle, lpDCB *DCB) (err error)
//sys GetCommModemStatus(handle Handle, lpModemStat *uint32) (err error)
//sys GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error)
//sys PurgeComm(handle Handle, dwFlags uint32) (err error)
//sys SetCommBreak(handle Handle) (err error)
//sys SetCommMask(handle Handle, dwEvtMask uint32) (err error)
//sys SetCommState(handle Handle, lpDCB *DCB) (err error)
//sys SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error)
//sys SetupComm(handle Handle, dwInQueue uint32, dwOutQueue uint32) (err error)
//sys WaitCommEvent(handle Handle, lpEvtMask *uint32, lpOverlapped *Overlapped) (err error)
//sys GetActiveProcessorCount(groupNumber uint16) (ret uint32)
//sys GetMaximumProcessorCount(groupNumber uint16) (ret uint32)
//sys EnumWindows(enumFunc uintptr, param unsafe.Pointer) (err error) = user32.EnumWindows
@@ -433,7 +405,7 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys VerQueryValue(block unsafe.Pointer, subBlock string, pointerToBufferPointer unsafe.Pointer, bufSize *uint32) (err error) = version.VerQueryValueW
// Process Status API (PSAPI)
//sys enumProcesses(processIds *uint32, nSize uint32, bytesReturned *uint32) (err error) = psapi.EnumProcesses
//sys EnumProcesses(processIds []uint32, bytesReturned *uint32) (err error) = psapi.EnumProcesses
//sys EnumProcessModules(process Handle, module *Handle, cb uint32, cbNeeded *uint32) (err error) = psapi.EnumProcessModules
//sys EnumProcessModulesEx(process Handle, module *Handle, cb uint32, cbNeeded *uint32, filterFlag uint32) (err error) = psapi.EnumProcessModulesEx
//sys GetModuleInformation(process Handle, module Handle, modinfo *ModuleInfo, cb uint32) (err error) = psapi.GetModuleInformation
@@ -465,10 +437,6 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys DwmGetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) = dwmapi.DwmGetWindowAttribute
//sys DwmSetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) = dwmapi.DwmSetWindowAttribute
// Windows Multimedia API
//sys TimeBeginPeriod (period uint32) (err error) [failretval != 0] = winmm.timeBeginPeriod
//sys TimeEndPeriod (period uint32) (err error) [failretval != 0] = winmm.timeEndPeriod
// syscall interface implementation for other packages
// GetCurrentProcess returns the handle for the current process.
@@ -727,12 +695,20 @@ func DurationSinceBoot() time.Duration {
}
func Ftruncate(fd Handle, length int64) (err error) {
type _FILE_END_OF_FILE_INFO struct {
EndOfFile int64
curoffset, e := Seek(fd, 0, 1)
if e != nil {
return e
}
var info _FILE_END_OF_FILE_INFO
info.EndOfFile = length
return SetFileInformationByHandle(fd, FileEndOfFileInfo, (*byte)(unsafe.Pointer(&info)), uint32(unsafe.Sizeof(info)))
defer Seek(fd, curoffset, 0)
_, e = Seek(fd, length, 0)
if e != nil {
return e
}
e = SetEndOfFile(fd)
if e != nil {
return e
}
return nil
}
func Gettimeofday(tv *Timeval) (err error) {
@@ -888,11 +864,6 @@ const socket_error = uintptr(^uint32(0))
//sys GetACP() (acp uint32) = kernel32.GetACP
//sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar
//sys getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcode error) = iphlpapi.GetBestInterfaceEx
//sys GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) = iphlpapi.GetIfEntry2Ex
//sys GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) = iphlpapi.GetUnicastIpAddressEntry
//sys NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyIpInterfaceChange
//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
// For testing: clients can set this flag to force
// creation of IPv6 sockets to return EAFNOSUPPORT.
@@ -993,8 +964,7 @@ func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) {
if n > 0 {
sl += int32(n) + 1
}
if sa.raw.Path[0] == '@' || (sa.raw.Path[0] == 0 && sl > 3) {
// Check sl > 3 so we don't change unnamed socket behavior.
if sa.raw.Path[0] == '@' {
sa.raw.Path[0] = 0
// Don't count trailing NUL for abstract address.
sl--
@@ -1377,26 +1347,13 @@ func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) {
func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) {
return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4)
}
func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) {
return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq)))
}
func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) {
return syscall.EWINDOWS
}
func EnumProcesses(processIds []uint32, bytesReturned *uint32) error {
// EnumProcesses syscall expects the size parameter to be in bytes, but the code generated with mksyscall uses
// the length of the processIds slice instead. Hence, this wrapper function is added to fix the discrepancy.
var p *uint32
if len(processIds) > 0 {
p = &processIds[0]
}
size := uint32(len(processIds) * 4)
return enumProcesses(p, size, bytesReturned)
}
func Getpid() (pid int) { return int(GetCurrentProcessId()) }
func FindFirstFile(name *uint16, data *Win32finddata) (handle Handle, err error) {
@@ -1656,11 +1613,6 @@ func SetConsoleCursorPosition(console Handle, position Coord) error {
return setConsoleCursorPosition(console, *((*uint32)(unsafe.Pointer(&position))))
}
func GetStartupInfo(startupInfo *StartupInfo) error {
getStartupInfo(startupInfo)
return nil
}
func (s NTStatus) Errno() syscall.Errno {
return rtlNtStatusToDosErrorNoTeb(s)
}
@@ -1684,22 +1636,23 @@ func (s NTStatus) Error() string {
// do not use NTUnicodeString, and instead UTF16PtrFromString should be used for
// the more common *uint16 string type.
func NewNTUnicodeString(s string) (*NTUnicodeString, error) {
s16, err := UTF16FromString(s)
var u NTUnicodeString
s16, err := UTF16PtrFromString(s)
if err != nil {
return nil, err
}
n := uint16(len(s16) * 2)
return &NTUnicodeString{
Length: n - 2, // subtract 2 bytes for the NULL terminator
MaximumLength: n,
Buffer: &s16[0],
}, nil
RtlInitUnicodeString(&u, s16)
return &u, nil
}
// Slice returns a uint16 slice that aliases the data in the NTUnicodeString.
func (s *NTUnicodeString) Slice() []uint16 {
slice := unsafe.Slice(s.Buffer, s.MaximumLength)
return slice[:s.Length]
var slice []uint16
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&slice))
hdr.Data = unsafe.Pointer(s.Buffer)
hdr.Len = int(s.Length)
hdr.Cap = int(s.MaximumLength)
return slice
}
func (s *NTUnicodeString) String() string {
@@ -1722,8 +1675,12 @@ func NewNTString(s string) (*NTString, error) {
// Slice returns a byte slice that aliases the data in the NTString.
func (s *NTString) Slice() []byte {
slice := unsafe.Slice(s.Buffer, s.MaximumLength)
return slice[:s.Length]
var slice []byte
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&slice))
hdr.Data = unsafe.Pointer(s.Buffer)
hdr.Len = int(s.Length)
hdr.Cap = int(s.MaximumLength)
return slice
}
func (s *NTString) String() string {
@@ -1775,7 +1732,10 @@ func LoadResourceData(module, resInfo Handle) (data []byte, err error) {
if err != nil {
return
}
data = unsafe.Slice((*byte)(unsafe.Pointer(ptr)), size)
h := (*unsafeheader.Slice)(unsafe.Pointer(&data))
h.Data = unsafe.Pointer(ptr)
h.Len = int(size)
h.Cap = int(size)
return
}
@@ -1846,87 +1806,3 @@ type PSAPI_WORKING_SET_EX_INFORMATION struct {
// A PSAPI_WORKING_SET_EX_BLOCK union that indicates the attributes of the page at VirtualAddress.
VirtualAttributes PSAPI_WORKING_SET_EX_BLOCK
}
// CreatePseudoConsole creates a windows pseudo console.
func CreatePseudoConsole(size Coord, in Handle, out Handle, flags uint32, pconsole *Handle) error {
// We need this wrapper to manually cast Coord to uint32. The autogenerated wrappers only
// accept arguments that can be casted to uintptr, and Coord can't.
return createPseudoConsole(*((*uint32)(unsafe.Pointer(&size))), in, out, flags, pconsole)
}
// ResizePseudoConsole resizes the internal buffers of the pseudo console to the width and height specified in `size`.
func ResizePseudoConsole(pconsole Handle, size Coord) error {
// We need this wrapper to manually cast Coord to uint32. The autogenerated wrappers only
// accept arguments that can be casted to uintptr, and Coord can't.
return resizePseudoConsole(pconsole, *((*uint32)(unsafe.Pointer(&size))))
}
// DCB constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-dcb.
const (
CBR_110 = 110
CBR_300 = 300
CBR_600 = 600
CBR_1200 = 1200
CBR_2400 = 2400
CBR_4800 = 4800
CBR_9600 = 9600
CBR_14400 = 14400
CBR_19200 = 19200
CBR_38400 = 38400
CBR_57600 = 57600
CBR_115200 = 115200
CBR_128000 = 128000
CBR_256000 = 256000
DTR_CONTROL_DISABLE = 0x00000000
DTR_CONTROL_ENABLE = 0x00000010
DTR_CONTROL_HANDSHAKE = 0x00000020
RTS_CONTROL_DISABLE = 0x00000000
RTS_CONTROL_ENABLE = 0x00001000
RTS_CONTROL_HANDSHAKE = 0x00002000
RTS_CONTROL_TOGGLE = 0x00003000
NOPARITY = 0
ODDPARITY = 1
EVENPARITY = 2
MARKPARITY = 3
SPACEPARITY = 4
ONESTOPBIT = 0
ONE5STOPBITS = 1
TWOSTOPBITS = 2
)
// EscapeCommFunction constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-escapecommfunction.
const (
SETXOFF = 1
SETXON = 2
SETRTS = 3
CLRRTS = 4
SETDTR = 5
CLRDTR = 6
SETBREAK = 8
CLRBREAK = 9
)
// PurgeComm constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-purgecomm.
const (
PURGE_TXABORT = 0x0001
PURGE_RXABORT = 0x0002
PURGE_TXCLEAR = 0x0004
PURGE_RXCLEAR = 0x0008
)
// SetCommMask constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setcommmask.
const (
EV_RXCHAR = 0x0001
EV_RXFLAG = 0x0002
EV_TXEMPTY = 0x0004
EV_CTS = 0x0008
EV_DSR = 0x0010
EV_RLSD = 0x0020
EV_BREAK = 0x0040
EV_ERR = 0x0080
EV_RING = 0x0100
)

View File

@@ -176,7 +176,6 @@ const (
WAIT_FAILED = 0xFFFFFFFF
// Access rights for process.
PROCESS_ALL_ACCESS = 0xFFFF
PROCESS_CREATE_PROCESS = 0x0080
PROCESS_CREATE_THREAD = 0x0002
PROCESS_DUP_HANDLE = 0x0040
@@ -248,7 +247,6 @@ const (
PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY = 0x00020007
PROC_THREAD_ATTRIBUTE_UMS_THREAD = 0x00030006
PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL = 0x0002000b
PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE = 0x00020016
)
const (
@@ -1061,7 +1059,6 @@ const (
SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_INOUT | IOC_WS2 | 6
SIO_KEEPALIVE_VALS = IOC_IN | IOC_VENDOR | 4
SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12
SIO_UDP_NETRESET = IOC_IN | IOC_VENDOR | 15
// cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460
@@ -1096,33 +1093,7 @@ const (
SOMAXCONN = 0x7fffffff
TCP_NODELAY = 1
TCP_EXPEDITED_1122 = 2
TCP_KEEPALIVE = 3
TCP_MAXSEG = 4
TCP_MAXRT = 5
TCP_STDURG = 6
TCP_NOURG = 7
TCP_ATMARK = 8
TCP_NOSYNRETRIES = 9
TCP_TIMESTAMPS = 10
TCP_OFFLOAD_PREFERENCE = 11
TCP_CONGESTION_ALGORITHM = 12
TCP_DELAY_FIN_ACK = 13
TCP_MAXRTMS = 14
TCP_FASTOPEN = 15
TCP_KEEPCNT = 16
TCP_KEEPIDLE = TCP_KEEPALIVE
TCP_KEEPINTVL = 17
TCP_FAIL_CONNECT_ON_ICMP_ERROR = 18
TCP_ICMP_ERROR_INFO = 19
UDP_NOCHECKSUM = 1
UDP_SEND_MSG_SIZE = 2
UDP_RECV_MAX_COALESCED_SIZE = 3
UDP_CHECKSUM_COVERAGE = 20
UDP_COALESCED_INFO = 3
TCP_NODELAY = 1
SHUT_RD = 0
SHUT_WR = 1
@@ -2005,21 +1976,7 @@ const (
MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20
)
// Flags for GetAdaptersAddresses, see
// https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersaddresses.
const (
GAA_FLAG_SKIP_UNICAST = 0x1
GAA_FLAG_SKIP_ANYCAST = 0x2
GAA_FLAG_SKIP_MULTICAST = 0x4
GAA_FLAG_SKIP_DNS_SERVER = 0x8
GAA_FLAG_INCLUDE_PREFIX = 0x10
GAA_FLAG_SKIP_FRIENDLY_NAME = 0x20
GAA_FLAG_INCLUDE_WINS_INFO = 0x40
GAA_FLAG_INCLUDE_GATEWAYS = 0x80
GAA_FLAG_INCLUDE_ALL_INTERFACES = 0x100
GAA_FLAG_INCLUDE_ALL_COMPARTMENTS = 0x200
GAA_FLAG_INCLUDE_TUNNEL_BINDINGORDER = 0x400
)
const GAA_FLAG_INCLUDE_PREFIX = 0x00000010
const (
IF_TYPE_OTHER = 1
@@ -2033,50 +1990,6 @@ const (
IF_TYPE_IEEE1394 = 144
)
// Enum NL_PREFIX_ORIGIN for [IpAdapterUnicastAddress], see
// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_prefix_origin
const (
IpPrefixOriginOther = 0
IpPrefixOriginManual = 1
IpPrefixOriginWellKnown = 2
IpPrefixOriginDhcp = 3
IpPrefixOriginRouterAdvertisement = 4
IpPrefixOriginUnchanged = 1 << 4
)
// Enum NL_SUFFIX_ORIGIN for [IpAdapterUnicastAddress], see
// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_suffix_origin
const (
NlsoOther = 0
NlsoManual = 1
NlsoWellKnown = 2
NlsoDhcp = 3
NlsoLinkLayerAddress = 4
NlsoRandom = 5
IpSuffixOriginOther = 0
IpSuffixOriginManual = 1
IpSuffixOriginWellKnown = 2
IpSuffixOriginDhcp = 3
IpSuffixOriginLinkLayerAddress = 4
IpSuffixOriginRandom = 5
IpSuffixOriginUnchanged = 1 << 4
)
// Enum NL_DAD_STATE for [IpAdapterUnicastAddress], see
// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_dad_state
const (
NldsInvalid = 0
NldsTentative = 1
NldsDuplicate = 2
NldsDeprecated = 3
NldsPreferred = 4
IpDadStateInvalid = 0
IpDadStateTentative = 1
IpDadStateDuplicate = 2
IpDadStateDeprecated = 3
IpDadStatePreferred = 4
)
type SocketAddress struct {
Sockaddr *syscall.RawSockaddrAny
SockaddrLength int32
@@ -2204,132 +2117,6 @@ const (
IfOperStatusLowerLayerDown = 7
)
const (
IF_MAX_PHYS_ADDRESS_LENGTH = 32
IF_MAX_STRING_SIZE = 256
)
// MIB_IF_ENTRY_LEVEL enumeration from netioapi.h or
// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-getifentry2ex.
const (
MibIfEntryNormal = 0
MibIfEntryNormalWithoutStatistics = 2
)
// MIB_NOTIFICATION_TYPE enumeration from netioapi.h or
// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ne-netioapi-mib_notification_type.
const (
MibParameterNotification = 0
MibAddInstance = 1
MibDeleteInstance = 2
MibInitialNotification = 3
)
// MibIfRow2 stores information about a particular interface. See
// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_if_row2.
type MibIfRow2 struct {
InterfaceLuid uint64
InterfaceIndex uint32
InterfaceGuid GUID
Alias [IF_MAX_STRING_SIZE + 1]uint16
Description [IF_MAX_STRING_SIZE + 1]uint16
PhysicalAddressLength uint32
PhysicalAddress [IF_MAX_PHYS_ADDRESS_LENGTH]uint8
PermanentPhysicalAddress [IF_MAX_PHYS_ADDRESS_LENGTH]uint8
Mtu uint32
Type uint32
TunnelType uint32
MediaType uint32
PhysicalMediumType uint32
AccessType uint32
DirectionType uint32
InterfaceAndOperStatusFlags uint8
OperStatus uint32
AdminStatus uint32
MediaConnectState uint32
NetworkGuid GUID
ConnectionType uint32
TransmitLinkSpeed uint64
ReceiveLinkSpeed uint64
InOctets uint64
InUcastPkts uint64
InNUcastPkts uint64
InDiscards uint64
InErrors uint64
InUnknownProtos uint64
InUcastOctets uint64
InMulticastOctets uint64
InBroadcastOctets uint64
OutOctets uint64
OutUcastPkts uint64
OutNUcastPkts uint64
OutDiscards uint64
OutErrors uint64
OutUcastOctets uint64
OutMulticastOctets uint64
OutBroadcastOctets uint64
OutQLen uint64
}
// MIB_UNICASTIPADDRESS_ROW stores information about a unicast IP address. See
// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_unicastipaddress_row.
type MibUnicastIpAddressRow struct {
Address RawSockaddrInet6 // SOCKADDR_INET union
InterfaceLuid uint64
InterfaceIndex uint32
PrefixOrigin uint32
SuffixOrigin uint32
ValidLifetime uint32
PreferredLifetime uint32
OnLinkPrefixLength uint8
SkipAsSource uint8
DadState uint32
ScopeId uint32
CreationTimeStamp Filetime
}
const ScopeLevelCount = 16
// MIB_IPINTERFACE_ROW stores interface management information for a particular IP address family on a network interface.
// See https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipinterface_row.
type MibIpInterfaceRow struct {
Family uint16
InterfaceLuid uint64
InterfaceIndex uint32
MaxReassemblySize uint32
InterfaceIdentifier uint64
MinRouterAdvertisementInterval uint32
MaxRouterAdvertisementInterval uint32
AdvertisingEnabled uint8
ForwardingEnabled uint8
WeakHostSend uint8
WeakHostReceive uint8
UseAutomaticMetric uint8
UseNeighborUnreachabilityDetection uint8
ManagedAddressConfigurationSupported uint8
OtherStatefulConfigurationSupported uint8
AdvertiseDefaultRoute uint8
RouterDiscoveryBehavior uint32
DadTransmits uint32
BaseReachableTime uint32
RetransmitTime uint32
PathMtuDiscoveryTimeout uint32
LinkLocalAddressBehavior uint32
LinkLocalAddressTimeout uint32
ZoneIndices [ScopeLevelCount]uint32
SitePrefixLength uint32
Metric uint32
NlMtu uint32
Connected uint8
SupportsWakeUpPatterns uint8
SupportsNeighborDiscovery uint8
SupportsRouterDiscovery uint8
ReachableTime uint32
TransmitOffload uint32
ReceiveOffload uint32
DisableDefaultRoutes uint8
}
// Console related constants used for the mode parameter to SetConsoleMode. See
// https://docs.microsoft.com/en-us/windows/console/setconsolemode for details.
@@ -2352,12 +2139,6 @@ const (
ENABLE_LVB_GRID_WORLDWIDE = 0x10
)
// Pseudo console related constants used for the flags parameter to
// CreatePseudoConsole. See: https://learn.microsoft.com/en-us/windows/console/createpseudoconsole
const (
PSEUDOCONSOLE_INHERIT_CURSOR = 0x1
)
type Coord struct {
X int16
Y int16
@@ -2439,23 +2220,19 @@ type JOBOBJECT_BASIC_UI_RESTRICTIONS struct {
}
const (
// JobObjectInformationClass for QueryInformationJobObject and SetInformationJobObject
// JobObjectInformationClass
JobObjectAssociateCompletionPortInformation = 7
JobObjectBasicAccountingInformation = 1
JobObjectBasicAndIoAccountingInformation = 8
JobObjectBasicLimitInformation = 2
JobObjectBasicProcessIdList = 3
JobObjectBasicUIRestrictions = 4
JobObjectCpuRateControlInformation = 15
JobObjectEndOfJobTimeInformation = 6
JobObjectExtendedLimitInformation = 9
JobObjectGroupInformation = 11
JobObjectGroupInformationEx = 14
JobObjectLimitViolationInformation = 13
JobObjectLimitViolationInformation2 = 34
JobObjectLimitViolationInformation2 = 35
JobObjectNetRateControlInformation = 32
JobObjectNotificationLimitInformation = 12
JobObjectNotificationLimitInformation2 = 33
JobObjectNotificationLimitInformation2 = 34
JobObjectSecurityLimitInformation = 5
)
@@ -3566,38 +3343,3 @@ type BLOB struct {
Size uint32
BlobData *byte
}
type ComStat struct {
Flags uint32
CBInQue uint32
CBOutQue uint32
}
type DCB struct {
DCBlength uint32
BaudRate uint32
Flags uint32
wReserved uint16
XonLim uint16
XoffLim uint16
ByteSize uint8
Parity uint8
StopBits uint8
XonChar byte
XoffChar byte
ErrorChar byte
EofChar byte
EvtChar byte
wReserved1 uint16
}
// Keyboard Layout Flags.
// See https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadkeyboardlayoutw
const (
KLF_ACTIVATE = 0x00000001
KLF_SUBSTITUTE_OK = 0x00000002
KLF_REORDER = 0x00000008
KLF_REPLACELANG = 0x00000010
KLF_NOTELLSHELL = 0x00000080
KLF_SETFORPROCESS = 0x00000100
)

View File

@@ -55,7 +55,6 @@ var (
moduser32 = NewLazySystemDLL("user32.dll")
moduserenv = NewLazySystemDLL("userenv.dll")
modversion = NewLazySystemDLL("version.dll")
modwinmm = NewLazySystemDLL("winmm.dll")
modwintrust = NewLazySystemDLL("wintrust.dll")
modws2_32 = NewLazySystemDLL("ws2_32.dll")
modwtsapi32 = NewLazySystemDLL("wtsapi32.dll")
@@ -87,11 +86,9 @@ var (
procDeleteService = modadvapi32.NewProc("DeleteService")
procDeregisterEventSource = modadvapi32.NewProc("DeregisterEventSource")
procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx")
procEnumDependentServicesW = modadvapi32.NewProc("EnumDependentServicesW")
procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW")
procEqualSid = modadvapi32.NewProc("EqualSid")
procFreeSid = modadvapi32.NewProc("FreeSid")
procGetAce = modadvapi32.NewProc("GetAce")
procGetLengthSid = modadvapi32.NewProc("GetLengthSid")
procGetNamedSecurityInfoW = modadvapi32.NewProc("GetNamedSecurityInfoW")
procGetSecurityDescriptorControl = modadvapi32.NewProc("GetSecurityDescriptorControl")
@@ -181,23 +178,14 @@ var (
procDnsRecordListFree = moddnsapi.NewProc("DnsRecordListFree")
procDwmGetWindowAttribute = moddwmapi.NewProc("DwmGetWindowAttribute")
procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute")
procCancelMibChangeNotify2 = modiphlpapi.NewProc("CancelMibChangeNotify2")
procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses")
procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo")
procGetBestInterfaceEx = modiphlpapi.NewProc("GetBestInterfaceEx")
procGetIfEntry = modiphlpapi.NewProc("GetIfEntry")
procGetIfEntry2Ex = modiphlpapi.NewProc("GetIfEntry2Ex")
procGetUnicastIpAddressEntry = modiphlpapi.NewProc("GetUnicastIpAddressEntry")
procNotifyIpInterfaceChange = modiphlpapi.NewProc("NotifyIpInterfaceChange")
procNotifyUnicastIpAddressChange = modiphlpapi.NewProc("NotifyUnicastIpAddressChange")
procAddDllDirectory = modkernel32.NewProc("AddDllDirectory")
procAssignProcessToJobObject = modkernel32.NewProc("AssignProcessToJobObject")
procCancelIo = modkernel32.NewProc("CancelIo")
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
procClearCommBreak = modkernel32.NewProc("ClearCommBreak")
procClearCommError = modkernel32.NewProc("ClearCommError")
procCloseHandle = modkernel32.NewProc("CloseHandle")
procClosePseudoConsole = modkernel32.NewProc("ClosePseudoConsole")
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
procCreateDirectoryW = modkernel32.NewProc("CreateDirectoryW")
procCreateEventExW = modkernel32.NewProc("CreateEventExW")
@@ -212,7 +200,6 @@ var (
procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
procCreatePipe = modkernel32.NewProc("CreatePipe")
procCreateProcessW = modkernel32.NewProc("CreateProcessW")
procCreatePseudoConsole = modkernel32.NewProc("CreatePseudoConsole")
procCreateSymbolicLinkW = modkernel32.NewProc("CreateSymbolicLinkW")
procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot")
procDefineDosDeviceW = modkernel32.NewProc("DefineDosDeviceW")
@@ -220,9 +207,7 @@ var (
procDeleteProcThreadAttributeList = modkernel32.NewProc("DeleteProcThreadAttributeList")
procDeleteVolumeMountPointW = modkernel32.NewProc("DeleteVolumeMountPointW")
procDeviceIoControl = modkernel32.NewProc("DeviceIoControl")
procDisconnectNamedPipe = modkernel32.NewProc("DisconnectNamedPipe")
procDuplicateHandle = modkernel32.NewProc("DuplicateHandle")
procEscapeCommFunction = modkernel32.NewProc("EscapeCommFunction")
procExitProcess = modkernel32.NewProc("ExitProcess")
procExpandEnvironmentStringsW = modkernel32.NewProc("ExpandEnvironmentStringsW")
procFindClose = modkernel32.NewProc("FindClose")
@@ -246,15 +231,11 @@ var (
procGenerateConsoleCtrlEvent = modkernel32.NewProc("GenerateConsoleCtrlEvent")
procGetACP = modkernel32.NewProc("GetACP")
procGetActiveProcessorCount = modkernel32.NewProc("GetActiveProcessorCount")
procGetCommModemStatus = modkernel32.NewProc("GetCommModemStatus")
procGetCommState = modkernel32.NewProc("GetCommState")
procGetCommTimeouts = modkernel32.NewProc("GetCommTimeouts")
procGetCommandLineW = modkernel32.NewProc("GetCommandLineW")
procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW")
procGetComputerNameW = modkernel32.NewProc("GetComputerNameW")
procGetConsoleCP = modkernel32.NewProc("GetConsoleCP")
procGetConsoleMode = modkernel32.NewProc("GetConsoleMode")
procGetConsoleOutputCP = modkernel32.NewProc("GetConsoleOutputCP")
procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo")
procGetCurrentDirectoryW = modkernel32.NewProc("GetCurrentDirectoryW")
procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId")
@@ -268,7 +249,6 @@ var (
procGetFileAttributesW = modkernel32.NewProc("GetFileAttributesW")
procGetFileInformationByHandle = modkernel32.NewProc("GetFileInformationByHandle")
procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx")
procGetFileTime = modkernel32.NewProc("GetFileTime")
procGetFileType = modkernel32.NewProc("GetFileType")
procGetFinalPathNameByHandleW = modkernel32.NewProc("GetFinalPathNameByHandleW")
procGetFullPathNameW = modkernel32.NewProc("GetFullPathNameW")
@@ -280,10 +260,8 @@ var (
procGetMaximumProcessorCount = modkernel32.NewProc("GetMaximumProcessorCount")
procGetModuleFileNameW = modkernel32.NewProc("GetModuleFileNameW")
procGetModuleHandleExW = modkernel32.NewProc("GetModuleHandleExW")
procGetNamedPipeClientProcessId = modkernel32.NewProc("GetNamedPipeClientProcessId")
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
procGetNamedPipeServerProcessId = modkernel32.NewProc("GetNamedPipeServerProcessId")
procGetOverlappedResult = modkernel32.NewProc("GetOverlappedResult")
procGetPriorityClass = modkernel32.NewProc("GetPriorityClass")
procGetProcAddress = modkernel32.NewProc("GetProcAddress")
@@ -338,7 +316,6 @@ var (
procProcess32NextW = modkernel32.NewProc("Process32NextW")
procProcessIdToSessionId = modkernel32.NewProc("ProcessIdToSessionId")
procPulseEvent = modkernel32.NewProc("PulseEvent")
procPurgeComm = modkernel32.NewProc("PurgeComm")
procQueryDosDeviceW = modkernel32.NewProc("QueryDosDeviceW")
procQueryFullProcessImageNameW = modkernel32.NewProc("QueryFullProcessImageNameW")
procQueryInformationJobObject = modkernel32.NewProc("QueryInformationJobObject")
@@ -348,18 +325,11 @@ var (
procReadProcessMemory = modkernel32.NewProc("ReadProcessMemory")
procReleaseMutex = modkernel32.NewProc("ReleaseMutex")
procRemoveDirectoryW = modkernel32.NewProc("RemoveDirectoryW")
procRemoveDllDirectory = modkernel32.NewProc("RemoveDllDirectory")
procResetEvent = modkernel32.NewProc("ResetEvent")
procResizePseudoConsole = modkernel32.NewProc("ResizePseudoConsole")
procResumeThread = modkernel32.NewProc("ResumeThread")
procSetCommBreak = modkernel32.NewProc("SetCommBreak")
procSetCommMask = modkernel32.NewProc("SetCommMask")
procSetCommState = modkernel32.NewProc("SetCommState")
procSetCommTimeouts = modkernel32.NewProc("SetCommTimeouts")
procSetConsoleCP = modkernel32.NewProc("SetConsoleCP")
procSetConsoleCursorPosition = modkernel32.NewProc("SetConsoleCursorPosition")
procSetConsoleMode = modkernel32.NewProc("SetConsoleMode")
procSetConsoleOutputCP = modkernel32.NewProc("SetConsoleOutputCP")
procSetCurrentDirectoryW = modkernel32.NewProc("SetCurrentDirectoryW")
procSetDefaultDllDirectories = modkernel32.NewProc("SetDefaultDllDirectories")
procSetDllDirectoryW = modkernel32.NewProc("SetDllDirectoryW")
@@ -372,7 +342,6 @@ var (
procSetFileInformationByHandle = modkernel32.NewProc("SetFileInformationByHandle")
procSetFilePointer = modkernel32.NewProc("SetFilePointer")
procSetFileTime = modkernel32.NewProc("SetFileTime")
procSetFileValidData = modkernel32.NewProc("SetFileValidData")
procSetHandleInformation = modkernel32.NewProc("SetHandleInformation")
procSetInformationJobObject = modkernel32.NewProc("SetInformationJobObject")
procSetNamedPipeHandleState = modkernel32.NewProc("SetNamedPipeHandleState")
@@ -383,7 +352,6 @@ var (
procSetStdHandle = modkernel32.NewProc("SetStdHandle")
procSetVolumeLabelW = modkernel32.NewProc("SetVolumeLabelW")
procSetVolumeMountPointW = modkernel32.NewProc("SetVolumeMountPointW")
procSetupComm = modkernel32.NewProc("SetupComm")
procSizeofResource = modkernel32.NewProc("SizeofResource")
procSleepEx = modkernel32.NewProc("SleepEx")
procTerminateJobObject = modkernel32.NewProc("TerminateJobObject")
@@ -402,7 +370,6 @@ var (
procVirtualQueryEx = modkernel32.NewProc("VirtualQueryEx")
procVirtualUnlock = modkernel32.NewProc("VirtualUnlock")
procWTSGetActiveConsoleSessionId = modkernel32.NewProc("WTSGetActiveConsoleSessionId")
procWaitCommEvent = modkernel32.NewProc("WaitCommEvent")
procWaitForMultipleObjects = modkernel32.NewProc("WaitForMultipleObjects")
procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject")
procWriteConsoleW = modkernel32.NewProc("WriteConsoleW")
@@ -413,7 +380,6 @@ var (
procTransmitFile = modmswsock.NewProc("TransmitFile")
procNetApiBufferFree = modnetapi32.NewProc("NetApiBufferFree")
procNetGetJoinInformation = modnetapi32.NewProc("NetGetJoinInformation")
procNetUserEnum = modnetapi32.NewProc("NetUserEnum")
procNetUserGetInfo = modnetapi32.NewProc("NetUserGetInfo")
procNtCreateFile = modntdll.NewProc("NtCreateFile")
procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile")
@@ -489,24 +455,18 @@ var (
procGetDesktopWindow = moduser32.NewProc("GetDesktopWindow")
procGetForegroundWindow = moduser32.NewProc("GetForegroundWindow")
procGetGUIThreadInfo = moduser32.NewProc("GetGUIThreadInfo")
procGetKeyboardLayout = moduser32.NewProc("GetKeyboardLayout")
procGetShellWindow = moduser32.NewProc("GetShellWindow")
procGetWindowThreadProcessId = moduser32.NewProc("GetWindowThreadProcessId")
procIsWindow = moduser32.NewProc("IsWindow")
procIsWindowUnicode = moduser32.NewProc("IsWindowUnicode")
procIsWindowVisible = moduser32.NewProc("IsWindowVisible")
procLoadKeyboardLayoutW = moduser32.NewProc("LoadKeyboardLayoutW")
procMessageBoxW = moduser32.NewProc("MessageBoxW")
procToUnicodeEx = moduser32.NewProc("ToUnicodeEx")
procUnloadKeyboardLayout = moduser32.NewProc("UnloadKeyboardLayout")
procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock")
procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock")
procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW")
procGetFileVersionInfoSizeW = modversion.NewProc("GetFileVersionInfoSizeW")
procGetFileVersionInfoW = modversion.NewProc("GetFileVersionInfoW")
procVerQueryValueW = modversion.NewProc("VerQueryValueW")
proctimeBeginPeriod = modwinmm.NewProc("timeBeginPeriod")
proctimeEndPeriod = modwinmm.NewProc("timeEndPeriod")
procWinVerifyTrustEx = modwintrust.NewProc("WinVerifyTrustEx")
procFreeAddrInfoW = modws2_32.NewProc("FreeAddrInfoW")
procGetAddrInfoW = modws2_32.NewProc("GetAddrInfoW")
@@ -774,14 +734,6 @@ func DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes
return
}
func EnumDependentServices(service Handle, activityState uint32, services *ENUM_SERVICE_STATUS, buffSize uint32, bytesNeeded *uint32, servicesReturned *uint32) (err error) {
r1, _, e1 := syscall.Syscall6(procEnumDependentServicesW.Addr(), 6, uintptr(service), uintptr(activityState), uintptr(unsafe.Pointer(services)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned)))
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) {
r1, _, e1 := syscall.Syscall12(procEnumServicesStatusExW.Addr(), 10, uintptr(mgr), uintptr(infoLevel), uintptr(serviceType), uintptr(serviceState), uintptr(unsafe.Pointer(services)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned)), uintptr(unsafe.Pointer(resumeHandle)), uintptr(unsafe.Pointer(groupName)), 0, 0)
if r1 == 0 {
@@ -804,14 +756,6 @@ func FreeSid(sid *SID) (err error) {
return
}
func GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (err error) {
r1, _, e1 := syscall.Syscall(procGetAce.Addr(), 3, uintptr(unsafe.Pointer(acl)), uintptr(aceIndex), uintptr(unsafe.Pointer(pAce)))
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func GetLengthSid(sid *SID) (len uint32) {
r0, _, _ := syscall.Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
len = uint32(r0)
@@ -1613,14 +1557,6 @@ func DwmSetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, si
return
}
func CancelMibChangeNotify2(notificationHandle Handle) (errcode error) {
r0, _, _ := syscall.Syscall(procCancelMibChangeNotify2.Addr(), 1, uintptr(notificationHandle), 0, 0)
if r0 != 0 {
errcode = syscall.Errno(r0)
}
return
}
func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) {
r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0)
if r0 != 0 {
@@ -1653,55 +1589,6 @@ func GetIfEntry(pIfRow *MibIfRow) (errcode error) {
return
}
func GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) {
r0, _, _ := syscall.Syscall(procGetIfEntry2Ex.Addr(), 2, uintptr(level), uintptr(unsafe.Pointer(row)), 0)
if r0 != 0 {
errcode = syscall.Errno(r0)
}
return
}
func GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) {
r0, _, _ := syscall.Syscall(procGetUnicastIpAddressEntry.Addr(), 1, uintptr(unsafe.Pointer(row)), 0, 0)
if r0 != 0 {
errcode = syscall.Errno(r0)
}
return
}
func NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) {
var _p0 uint32
if initialNotification {
_p0 = 1
}
r0, _, _ := syscall.Syscall6(procNotifyIpInterfaceChange.Addr(), 5, uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle)), 0)
if r0 != 0 {
errcode = syscall.Errno(r0)
}
return
}
func NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) {
var _p0 uint32
if initialNotification {
_p0 = 1
}
r0, _, _ := syscall.Syscall6(procNotifyUnicastIpAddressChange.Addr(), 5, uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle)), 0)
if r0 != 0 {
errcode = syscall.Errno(r0)
}
return
}
func AddDllDirectory(path *uint16) (cookie uintptr, err error) {
r0, _, e1 := syscall.Syscall(procAddDllDirectory.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
cookie = uintptr(r0)
if cookie == 0 {
err = errnoErr(e1)
}
return
}
func AssignProcessToJobObject(job Handle, process Handle) (err error) {
r1, _, e1 := syscall.Syscall(procAssignProcessToJobObject.Addr(), 2, uintptr(job), uintptr(process), 0)
if r1 == 0 {
@@ -1726,22 +1613,6 @@ func CancelIoEx(s Handle, o *Overlapped) (err error) {
return
}
func ClearCommBreak(handle Handle) (err error) {
r1, _, e1 := syscall.Syscall(procClearCommBreak.Addr(), 1, uintptr(handle), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func ClearCommError(handle Handle, lpErrors *uint32, lpStat *ComStat) (err error) {
r1, _, e1 := syscall.Syscall(procClearCommError.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(lpErrors)), uintptr(unsafe.Pointer(lpStat)))
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func CloseHandle(handle Handle) (err error) {
r1, _, e1 := syscall.Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0)
if r1 == 0 {
@@ -1750,11 +1621,6 @@ func CloseHandle(handle Handle) (err error) {
return
}
func ClosePseudoConsole(console Handle) {
syscall.Syscall(procClosePseudoConsole.Addr(), 1, uintptr(console), 0, 0)
return
}
func ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error) {
r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(overlapped)), 0)
if r1 == 0 {
@@ -1884,14 +1750,6 @@ func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityA
return
}
func createPseudoConsole(size uint32, in Handle, out Handle, flags uint32, pconsole *Handle) (hr error) {
r0, _, _ := syscall.Syscall6(procCreatePseudoConsole.Addr(), 5, uintptr(size), uintptr(in), uintptr(out), uintptr(flags), uintptr(unsafe.Pointer(pconsole)), 0)
if r0 != 0 {
hr = syscall.Errno(r0)
}
return
}
func CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) {
r1, _, e1 := syscall.Syscall(procCreateSymbolicLinkW.Addr(), 3, uintptr(unsafe.Pointer(symlinkfilename)), uintptr(unsafe.Pointer(targetfilename)), uintptr(flags))
if r1&0xff == 0 {
@@ -1946,14 +1804,6 @@ func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBuff
return
}
func DisconnectNamedPipe(pipe Handle) (err error) {
r1, _, e1 := syscall.Syscall(procDisconnectNamedPipe.Addr(), 1, uintptr(pipe), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) {
var _p0 uint32
if bInheritHandle {
@@ -1966,14 +1816,6 @@ func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetP
return
}
func EscapeCommFunction(handle Handle, dwFunc uint32) (err error) {
r1, _, e1 := syscall.Syscall(procEscapeCommFunction.Addr(), 2, uintptr(handle), uintptr(dwFunc), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func ExitProcess(exitcode uint32) {
syscall.Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0)
return
@@ -2175,22 +2017,6 @@ func GetActiveProcessorCount(groupNumber uint16) (ret uint32) {
return
}
func GetCommModemStatus(handle Handle, lpModemStat *uint32) (err error) {
r1, _, e1 := syscall.Syscall(procGetCommModemStatus.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(lpModemStat)), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func GetCommState(handle Handle, lpDCB *DCB) (err error) {
r1, _, e1 := syscall.Syscall(procGetCommState.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(lpDCB)), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) {
r1, _, e1 := syscall.Syscall(procGetCommTimeouts.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(timeouts)), 0)
if r1 == 0 {
@@ -2221,15 +2047,6 @@ func GetComputerName(buf *uint16, n *uint32) (err error) {
return
}
func GetConsoleCP() (cp uint32, err error) {
r0, _, e1 := syscall.Syscall(procGetConsoleCP.Addr(), 0, 0, 0, 0)
cp = uint32(r0)
if cp == 0 {
err = errnoErr(e1)
}
return
}
func GetConsoleMode(console Handle, mode *uint32) (err error) {
r1, _, e1 := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0)
if r1 == 0 {
@@ -2238,15 +2055,6 @@ func GetConsoleMode(console Handle, mode *uint32) (err error) {
return
}
func GetConsoleOutputCP() (cp uint32, err error) {
r0, _, e1 := syscall.Syscall(procGetConsoleOutputCP.Addr(), 0, 0, 0, 0)
cp = uint32(r0)
if cp == 0 {
err = errnoErr(e1)
}
return
}
func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) {
r1, _, e1 := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(info)), 0)
if r1 == 0 {
@@ -2349,14 +2157,6 @@ func GetFileInformationByHandleEx(handle Handle, class uint32, outBuffer *byte,
return
}
func GetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) {
r1, _, e1 := syscall.Syscall6(procGetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func GetFileType(filehandle Handle) (n uint32, err error) {
r0, _, e1 := syscall.Syscall(procGetFileType.Addr(), 1, uintptr(filehandle), 0, 0)
n = uint32(r0)
@@ -2448,14 +2248,6 @@ func GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err er
return
}
func GetNamedPipeClientProcessId(pipe Handle, clientProcessID *uint32) (err error) {
r1, _, e1 := syscall.Syscall(procGetNamedPipeClientProcessId.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(clientProcessID)), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {
r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)
if r1 == 0 {
@@ -2472,14 +2264,6 @@ func GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint3
return
}
func GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err error) {
r1, _, e1 := syscall.Syscall(procGetNamedPipeServerProcessId.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(serverProcessID)), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wait bool) (err error) {
var _p0 uint32
if wait {
@@ -2574,8 +2358,11 @@ func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uin
return
}
func getStartupInfo(startupInfo *StartupInfo) {
syscall.Syscall(procGetStartupInfoW.Addr(), 1, uintptr(unsafe.Pointer(startupInfo)), 0, 0)
func GetStartupInfo(startupInfo *StartupInfo) (err error) {
r1, _, e1 := syscall.Syscall(procGetStartupInfoW.Addr(), 1, uintptr(unsafe.Pointer(startupInfo)), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
@@ -2977,14 +2764,6 @@ func PulseEvent(event Handle) (err error) {
return
}
func PurgeComm(handle Handle, dwFlags uint32) (err error) {
r1, _, e1 := syscall.Syscall(procPurgeComm.Addr(), 2, uintptr(handle), uintptr(dwFlags), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) {
r0, _, e1 := syscall.Syscall(procQueryDosDeviceW.Addr(), 3, uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath)), uintptr(max))
n = uint32(r0)
@@ -3066,14 +2845,6 @@ func RemoveDirectory(path *uint16) (err error) {
return
}
func RemoveDllDirectory(cookie uintptr) (err error) {
r1, _, e1 := syscall.Syscall(procRemoveDllDirectory.Addr(), 1, uintptr(cookie), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func ResetEvent(event Handle) (err error) {
r1, _, e1 := syscall.Syscall(procResetEvent.Addr(), 1, uintptr(event), 0, 0)
if r1 == 0 {
@@ -3082,14 +2853,6 @@ func ResetEvent(event Handle) (err error) {
return
}
func resizePseudoConsole(pconsole Handle, size uint32) (hr error) {
r0, _, _ := syscall.Syscall(procResizePseudoConsole.Addr(), 2, uintptr(pconsole), uintptr(size), 0)
if r0 != 0 {
hr = syscall.Errno(r0)
}
return
}
func ResumeThread(thread Handle) (ret uint32, err error) {
r0, _, e1 := syscall.Syscall(procResumeThread.Addr(), 1, uintptr(thread), 0, 0)
ret = uint32(r0)
@@ -3099,30 +2862,6 @@ func ResumeThread(thread Handle) (ret uint32, err error) {
return
}
func SetCommBreak(handle Handle) (err error) {
r1, _, e1 := syscall.Syscall(procSetCommBreak.Addr(), 1, uintptr(handle), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func SetCommMask(handle Handle, dwEvtMask uint32) (err error) {
r1, _, e1 := syscall.Syscall(procSetCommMask.Addr(), 2, uintptr(handle), uintptr(dwEvtMask), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func SetCommState(handle Handle, lpDCB *DCB) (err error) {
r1, _, e1 := syscall.Syscall(procSetCommState.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(lpDCB)), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) {
r1, _, e1 := syscall.Syscall(procSetCommTimeouts.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(timeouts)), 0)
if r1 == 0 {
@@ -3131,14 +2870,6 @@ func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) {
return
}
func SetConsoleCP(cp uint32) (err error) {
r1, _, e1 := syscall.Syscall(procSetConsoleCP.Addr(), 1, uintptr(cp), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func setConsoleCursorPosition(console Handle, position uint32) (err error) {
r1, _, e1 := syscall.Syscall(procSetConsoleCursorPosition.Addr(), 2, uintptr(console), uintptr(position), 0)
if r1 == 0 {
@@ -3155,14 +2886,6 @@ func SetConsoleMode(console Handle, mode uint32) (err error) {
return
}
func SetConsoleOutputCP(cp uint32) (err error) {
r1, _, e1 := syscall.Syscall(procSetConsoleOutputCP.Addr(), 1, uintptr(cp), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func SetCurrentDirectory(path *uint16) (err error) {
r1, _, e1 := syscall.Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
if r1 == 0 {
@@ -3267,14 +2990,6 @@ func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetim
return
}
func SetFileValidData(handle Handle, validDataLength int64) (err error) {
r1, _, e1 := syscall.Syscall(procSetFileValidData.Addr(), 2, uintptr(handle), uintptr(validDataLength), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) {
r1, _, e1 := syscall.Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags))
if r1 == 0 {
@@ -3360,14 +3075,6 @@ func SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err erro
return
}
func SetupComm(handle Handle, dwInQueue uint32, dwOutQueue uint32) (err error) {
r1, _, e1 := syscall.Syscall(procSetupComm.Addr(), 3, uintptr(handle), uintptr(dwInQueue), uintptr(dwOutQueue))
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func SizeofResource(module Handle, resInfo Handle) (size uint32, err error) {
r0, _, e1 := syscall.Syscall(procSizeofResource.Addr(), 2, uintptr(module), uintptr(resInfo), 0)
size = uint32(r0)
@@ -3514,14 +3221,6 @@ func WTSGetActiveConsoleSessionId() (sessionID uint32) {
return
}
func WaitCommEvent(handle Handle, lpEvtMask *uint32, lpOverlapped *Overlapped) (err error) {
r1, _, e1 := syscall.Syscall(procWaitCommEvent.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(lpEvtMask)), uintptr(unsafe.Pointer(lpOverlapped)))
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func waitForMultipleObjects(count uint32, handles uintptr, waitAll bool, waitMilliseconds uint32) (event uint32, err error) {
var _p0 uint32
if waitAll {
@@ -3609,14 +3308,6 @@ func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (nete
return
}
func NetUserEnum(serverName *uint16, level uint32, filter uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32, resumeHandle *uint32) (neterr error) {
r0, _, _ := syscall.Syscall9(procNetUserEnum.Addr(), 8, uintptr(unsafe.Pointer(serverName)), uintptr(level), uintptr(filter), uintptr(unsafe.Pointer(buf)), uintptr(prefMaxLen), uintptr(unsafe.Pointer(entriesRead)), uintptr(unsafe.Pointer(totalEntries)), uintptr(unsafe.Pointer(resumeHandle)), 0)
if r0 != 0 {
neterr = syscall.Errno(r0)
}
return
}
func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) {
r0, _, _ := syscall.Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0)
if r0 != 0 {
@@ -3816,8 +3507,12 @@ func EnumProcessModulesEx(process Handle, module *Handle, cb uint32, cbNeeded *u
return
}
func enumProcesses(processIds *uint32, nSize uint32, bytesReturned *uint32) (err error) {
r1, _, e1 := syscall.Syscall(procEnumProcesses.Addr(), 3, uintptr(unsafe.Pointer(processIds)), uintptr(nSize), uintptr(unsafe.Pointer(bytesReturned)))
func EnumProcesses(processIds []uint32, bytesReturned *uint32) (err error) {
var _p0 *uint32
if len(processIds) > 0 {
_p0 = &processIds[0]
}
r1, _, e1 := syscall.Syscall(procEnumProcesses.Addr(), 3, uintptr(unsafe.Pointer(_p0)), uintptr(len(processIds)), uintptr(unsafe.Pointer(bytesReturned)))
if r1 == 0 {
err = errnoErr(e1)
}
@@ -4120,9 +3815,9 @@ func setupUninstallOEMInf(infFileName *uint16, flags SUOI, reserved uintptr) (er
return
}
func commandLineToArgv(cmd *uint16, argc *int32) (argv **uint16, err error) {
func CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) {
r0, _, e1 := syscall.Syscall(procCommandLineToArgvW.Addr(), 2, uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc)), 0)
argv = (**uint16)(unsafe.Pointer(r0))
argv = (*[8192]*[8192]uint16)(unsafe.Pointer(r0))
if argv == nil {
err = errnoErr(e1)
}
@@ -4195,12 +3890,6 @@ func GetGUIThreadInfo(thread uint32, info *GUIThreadInfo) (err error) {
return
}
func GetKeyboardLayout(tid uint32) (hkl Handle) {
r0, _, _ := syscall.Syscall(procGetKeyboardLayout.Addr(), 1, uintptr(tid), 0, 0)
hkl = Handle(r0)
return
}
func GetShellWindow() (shellWindow HWND) {
r0, _, _ := syscall.Syscall(procGetShellWindow.Addr(), 0, 0, 0, 0)
shellWindow = HWND(r0)
@@ -4234,15 +3923,6 @@ func IsWindowVisible(hwnd HWND) (isVisible bool) {
return
}
func LoadKeyboardLayout(name *uint16, flags uint32) (hkl Handle, err error) {
r0, _, e1 := syscall.Syscall(procLoadKeyboardLayoutW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(flags), 0)
hkl = Handle(r0)
if hkl == 0 {
err = errnoErr(e1)
}
return
}
func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) {
r0, _, e1 := syscall.Syscall6(procMessageBoxW.Addr(), 4, uintptr(hwnd), uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), uintptr(boxtype), 0, 0)
ret = int32(r0)
@@ -4252,20 +3932,6 @@ func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret i
return
}
func ToUnicodeEx(vkey uint32, scancode uint32, keystate *byte, pwszBuff *uint16, cchBuff int32, flags uint32, hkl Handle) (ret int32) {
r0, _, _ := syscall.Syscall9(procToUnicodeEx.Addr(), 7, uintptr(vkey), uintptr(scancode), uintptr(unsafe.Pointer(keystate)), uintptr(unsafe.Pointer(pwszBuff)), uintptr(cchBuff), uintptr(flags), uintptr(hkl), 0, 0)
ret = int32(r0)
return
}
func UnloadKeyboardLayout(hkl Handle) (err error) {
r1, _, e1 := syscall.Syscall(procUnloadKeyboardLayout.Addr(), 1, uintptr(hkl), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func CreateEnvironmentBlock(block **uint16, token Token, inheritExisting bool) (err error) {
var _p0 uint32
if inheritExisting {
@@ -4346,22 +4012,6 @@ func _VerQueryValue(block unsafe.Pointer, subBlock *uint16, pointerToBufferPoint
return
}
func TimeBeginPeriod(period uint32) (err error) {
r1, _, e1 := syscall.Syscall(proctimeBeginPeriod.Addr(), 1, uintptr(period), 0, 0)
if r1 != 0 {
err = errnoErr(e1)
}
return
}
func TimeEndPeriod(period uint32) (err error) {
r1, _, e1 := syscall.Syscall(proctimeEndPeriod.Addr(), 1, uintptr(period), 0, 0)
if r1 != 0 {
err = errnoErr(e1)
}
return
}
func WinVerifyTrustEx(hwnd HWND, actionId *GUID, data *WinTrustData) (ret error) {
r0, _, _ := syscall.Syscall(procWinVerifyTrustEx.Addr(), 3, uintptr(hwnd), uintptr(unsafe.Pointer(actionId)), uintptr(unsafe.Pointer(data)))
if r0 != 0 {

4
vendor/golang.org/x/text/LICENSE generated vendored
View File

@@ -1,4 +1,4 @@
Copyright 2009 The Go Authors.
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer.
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google LLC nor the names of its
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

View File

@@ -790,226 +790,226 @@ const (
var coreTags = []language.CompactCoreInfo{ // 773 elements
// Entry 0 - 1F
0x00000000, 0x01600000, 0x016000d3, 0x01600162,
0x01c00000, 0x01c00052, 0x02100000, 0x02100081,
0x02700000, 0x02700070, 0x03a00000, 0x03a00001,
0x03a00023, 0x03a00039, 0x03a00063, 0x03a00068,
0x03a0006c, 0x03a0006d, 0x03a0006e, 0x03a00098,
0x03a0009c, 0x03a000a2, 0x03a000a9, 0x03a000ad,
0x03a000b1, 0x03a000ba, 0x03a000bb, 0x03a000ca,
0x03a000e2, 0x03a000ee, 0x03a000f4, 0x03a00109,
0x00000000, 0x01600000, 0x016000d2, 0x01600161,
0x01c00000, 0x01c00052, 0x02100000, 0x02100080,
0x02700000, 0x0270006f, 0x03a00000, 0x03a00001,
0x03a00023, 0x03a00039, 0x03a00062, 0x03a00067,
0x03a0006b, 0x03a0006c, 0x03a0006d, 0x03a00097,
0x03a0009b, 0x03a000a1, 0x03a000a8, 0x03a000ac,
0x03a000b0, 0x03a000b9, 0x03a000ba, 0x03a000c9,
0x03a000e1, 0x03a000ed, 0x03a000f3, 0x03a00108,
// Entry 20 - 3F
0x03a0010c, 0x03a00116, 0x03a00118, 0x03a0011d,
0x03a00121, 0x03a00129, 0x03a0015f, 0x04000000,
0x04300000, 0x0430009a, 0x04400000, 0x04400130,
0x04800000, 0x0480006f, 0x05800000, 0x05820000,
0x05820032, 0x0585b000, 0x0585b032, 0x05e00000,
0x03a0010b, 0x03a00115, 0x03a00117, 0x03a0011c,
0x03a00120, 0x03a00128, 0x03a0015e, 0x04000000,
0x04300000, 0x04300099, 0x04400000, 0x0440012f,
0x04800000, 0x0480006e, 0x05800000, 0x05820000,
0x05820032, 0x0585a000, 0x0585a032, 0x05e00000,
0x05e00052, 0x07100000, 0x07100047, 0x07500000,
0x07500163, 0x07900000, 0x07900130, 0x07e00000,
0x07e00038, 0x08200000, 0x0a000000, 0x0a0000c4,
0x07500162, 0x07900000, 0x0790012f, 0x07e00000,
0x07e00038, 0x08200000, 0x0a000000, 0x0a0000c3,
// Entry 40 - 5F
0x0a500000, 0x0a500035, 0x0a50009a, 0x0a900000,
0x0a900053, 0x0a90009a, 0x0b200000, 0x0b200079,
0x0b500000, 0x0b50009a, 0x0b700000, 0x0b720000,
0x0b720033, 0x0b75b000, 0x0b75b033, 0x0d700000,
0x0d700022, 0x0d70006f, 0x0d700079, 0x0d70009f,
0x0db00000, 0x0db00035, 0x0db0009a, 0x0dc00000,
0x0dc00107, 0x0df00000, 0x0df00132, 0x0e500000,
0x0e500136, 0x0e900000, 0x0e90009c, 0x0e90009d,
0x0a500000, 0x0a500035, 0x0a500099, 0x0a900000,
0x0a900053, 0x0a900099, 0x0b200000, 0x0b200078,
0x0b500000, 0x0b500099, 0x0b700000, 0x0b720000,
0x0b720033, 0x0b75a000, 0x0b75a033, 0x0d700000,
0x0d700022, 0x0d70006e, 0x0d700078, 0x0d70009e,
0x0db00000, 0x0db00035, 0x0db00099, 0x0dc00000,
0x0dc00106, 0x0df00000, 0x0df00131, 0x0e500000,
0x0e500135, 0x0e900000, 0x0e90009b, 0x0e90009c,
// Entry 60 - 7F
0x0fa00000, 0x0fa0005f, 0x0fe00000, 0x0fe00107,
0x10000000, 0x1000007c, 0x10100000, 0x10100064,
0x10100083, 0x10800000, 0x108000a5, 0x10d00000,
0x10d0002e, 0x10d00036, 0x10d0004e, 0x10d00061,
0x10d0009f, 0x10d000b3, 0x10d000b8, 0x11700000,
0x117000d5, 0x11f00000, 0x11f00061, 0x12400000,
0x12400052, 0x12800000, 0x12b00000, 0x12b00115,
0x12d00000, 0x12d00043, 0x12f00000, 0x12f000a5,
0x0fa00000, 0x0fa0005e, 0x0fe00000, 0x0fe00106,
0x10000000, 0x1000007b, 0x10100000, 0x10100063,
0x10100082, 0x10800000, 0x108000a4, 0x10d00000,
0x10d0002e, 0x10d00036, 0x10d0004e, 0x10d00060,
0x10d0009e, 0x10d000b2, 0x10d000b7, 0x11700000,
0x117000d4, 0x11f00000, 0x11f00060, 0x12400000,
0x12400052, 0x12800000, 0x12b00000, 0x12b00114,
0x12d00000, 0x12d00043, 0x12f00000, 0x12f000a4,
// Entry 80 - 9F
0x13000000, 0x13000081, 0x13000123, 0x13600000,
0x1360005e, 0x13600088, 0x13900000, 0x13900001,
0x13000000, 0x13000080, 0x13000122, 0x13600000,
0x1360005d, 0x13600087, 0x13900000, 0x13900001,
0x1390001a, 0x13900025, 0x13900026, 0x1390002d,
0x1390002e, 0x1390002f, 0x13900034, 0x13900036,
0x1390003a, 0x1390003d, 0x13900042, 0x13900046,
0x13900048, 0x13900049, 0x1390004a, 0x1390004e,
0x13900050, 0x13900052, 0x1390005d, 0x1390005e,
0x13900061, 0x13900062, 0x13900064, 0x13900065,
0x13900050, 0x13900052, 0x1390005c, 0x1390005d,
0x13900060, 0x13900061, 0x13900063, 0x13900064,
// Entry A0 - BF
0x1390006e, 0x13900073, 0x13900074, 0x13900075,
0x13900076, 0x1390007c, 0x1390007d, 0x13900080,
0x13900081, 0x13900082, 0x13900084, 0x1390008b,
0x1390008d, 0x1390008e, 0x13900097, 0x13900098,
0x13900099, 0x1390009a, 0x1390009b, 0x139000a0,
0x139000a1, 0x139000a5, 0x139000a8, 0x139000aa,
0x139000ae, 0x139000b2, 0x139000b5, 0x139000b6,
0x139000c0, 0x139000c1, 0x139000c7, 0x139000c8,
0x1390006d, 0x13900072, 0x13900073, 0x13900074,
0x13900075, 0x1390007b, 0x1390007c, 0x1390007f,
0x13900080, 0x13900081, 0x13900083, 0x1390008a,
0x1390008c, 0x1390008d, 0x13900096, 0x13900097,
0x13900098, 0x13900099, 0x1390009a, 0x1390009f,
0x139000a0, 0x139000a4, 0x139000a7, 0x139000a9,
0x139000ad, 0x139000b1, 0x139000b4, 0x139000b5,
0x139000bf, 0x139000c0, 0x139000c6, 0x139000c7,
// Entry C0 - DF
0x139000cb, 0x139000cc, 0x139000cd, 0x139000cf,
0x139000d1, 0x139000d3, 0x139000d6, 0x139000d7,
0x139000da, 0x139000de, 0x139000e0, 0x139000e1,
0x139000e7, 0x139000e8, 0x139000e9, 0x139000ec,
0x139000ed, 0x139000f1, 0x13900108, 0x1390010a,
0x1390010b, 0x1390010c, 0x1390010d, 0x1390010e,
0x1390010f, 0x13900110, 0x13900113, 0x13900118,
0x1390011c, 0x1390011e, 0x13900120, 0x13900126,
0x139000ca, 0x139000cb, 0x139000cc, 0x139000ce,
0x139000d0, 0x139000d2, 0x139000d5, 0x139000d6,
0x139000d9, 0x139000dd, 0x139000df, 0x139000e0,
0x139000e6, 0x139000e7, 0x139000e8, 0x139000eb,
0x139000ec, 0x139000f0, 0x13900107, 0x13900109,
0x1390010a, 0x1390010b, 0x1390010c, 0x1390010d,
0x1390010e, 0x1390010f, 0x13900112, 0x13900117,
0x1390011b, 0x1390011d, 0x1390011f, 0x13900125,
// Entry E0 - FF
0x1390012a, 0x1390012d, 0x1390012e, 0x13900130,
0x13900132, 0x13900134, 0x13900136, 0x1390013a,
0x1390013d, 0x1390013e, 0x13900140, 0x13900143,
0x13900162, 0x13900163, 0x13900165, 0x13c00000,
0x13900129, 0x1390012c, 0x1390012d, 0x1390012f,
0x13900131, 0x13900133, 0x13900135, 0x13900139,
0x1390013c, 0x1390013d, 0x1390013f, 0x13900142,
0x13900161, 0x13900162, 0x13900164, 0x13c00000,
0x13c00001, 0x13e00000, 0x13e0001f, 0x13e0002c,
0x13e0003f, 0x13e00041, 0x13e00048, 0x13e00051,
0x13e00054, 0x13e00057, 0x13e0005a, 0x13e00066,
0x13e00069, 0x13e0006a, 0x13e0006f, 0x13e00087,
0x13e00054, 0x13e00056, 0x13e00059, 0x13e00065,
0x13e00068, 0x13e00069, 0x13e0006e, 0x13e00086,
// Entry 100 - 11F
0x13e0008a, 0x13e00090, 0x13e00095, 0x13e000d0,
0x13e000d9, 0x13e000e3, 0x13e000e5, 0x13e000e8,
0x13e000ed, 0x13e000f2, 0x13e0011b, 0x13e00136,
0x13e00137, 0x13e0013c, 0x14000000, 0x1400006b,
0x14500000, 0x1450006f, 0x14600000, 0x14600052,
0x14800000, 0x14800024, 0x1480009d, 0x14e00000,
0x14e00052, 0x14e00085, 0x14e000ca, 0x14e00115,
0x15100000, 0x15100073, 0x15300000, 0x153000e8,
0x13e00089, 0x13e0008f, 0x13e00094, 0x13e000cf,
0x13e000d8, 0x13e000e2, 0x13e000e4, 0x13e000e7,
0x13e000ec, 0x13e000f1, 0x13e0011a, 0x13e00135,
0x13e00136, 0x13e0013b, 0x14000000, 0x1400006a,
0x14500000, 0x1450006e, 0x14600000, 0x14600052,
0x14800000, 0x14800024, 0x1480009c, 0x14e00000,
0x14e00052, 0x14e00084, 0x14e000c9, 0x14e00114,
0x15100000, 0x15100072, 0x15300000, 0x153000e7,
// Entry 120 - 13F
0x15800000, 0x15800064, 0x15800077, 0x15e00000,
0x15800000, 0x15800063, 0x15800076, 0x15e00000,
0x15e00036, 0x15e00037, 0x15e0003a, 0x15e0003b,
0x15e0003c, 0x15e00049, 0x15e0004b, 0x15e0004c,
0x15e0004d, 0x15e0004e, 0x15e0004f, 0x15e00052,
0x15e00063, 0x15e00068, 0x15e00079, 0x15e0007b,
0x15e0007f, 0x15e00085, 0x15e00086, 0x15e00087,
0x15e00092, 0x15e000a9, 0x15e000b8, 0x15e000bb,
0x15e000bc, 0x15e000bf, 0x15e000c0, 0x15e000c4,
0x15e00062, 0x15e00067, 0x15e00078, 0x15e0007a,
0x15e0007e, 0x15e00084, 0x15e00085, 0x15e00086,
0x15e00091, 0x15e000a8, 0x15e000b7, 0x15e000ba,
0x15e000bb, 0x15e000be, 0x15e000bf, 0x15e000c3,
// Entry 140 - 15F
0x15e000c9, 0x15e000ca, 0x15e000cd, 0x15e000d4,
0x15e000d5, 0x15e000e6, 0x15e000eb, 0x15e00103,
0x15e00108, 0x15e0010b, 0x15e00115, 0x15e0011d,
0x15e00121, 0x15e00123, 0x15e00129, 0x15e00140,
0x15e00141, 0x15e00160, 0x16900000, 0x1690009f,
0x16d00000, 0x16d000da, 0x16e00000, 0x16e00097,
0x17e00000, 0x17e0007c, 0x19000000, 0x1900006f,
0x1a300000, 0x1a30004e, 0x1a300079, 0x1a3000b3,
0x15e000c8, 0x15e000c9, 0x15e000cc, 0x15e000d3,
0x15e000d4, 0x15e000e5, 0x15e000ea, 0x15e00102,
0x15e00107, 0x15e0010a, 0x15e00114, 0x15e0011c,
0x15e00120, 0x15e00122, 0x15e00128, 0x15e0013f,
0x15e00140, 0x15e0015f, 0x16900000, 0x1690009e,
0x16d00000, 0x16d000d9, 0x16e00000, 0x16e00096,
0x17e00000, 0x17e0007b, 0x19000000, 0x1900006e,
0x1a300000, 0x1a30004e, 0x1a300078, 0x1a3000b2,
// Entry 160 - 17F
0x1a400000, 0x1a40009a, 0x1a900000, 0x1ab00000,
0x1ab000a5, 0x1ac00000, 0x1ac00099, 0x1b400000,
0x1b400081, 0x1b4000d5, 0x1b4000d7, 0x1b800000,
0x1b800136, 0x1bc00000, 0x1bc00098, 0x1be00000,
0x1be0009a, 0x1d100000, 0x1d100033, 0x1d100091,
0x1d200000, 0x1d200061, 0x1d500000, 0x1d500093,
0x1d700000, 0x1d700028, 0x1e100000, 0x1e100096,
0x1e700000, 0x1e7000d7, 0x1ea00000, 0x1ea00053,
0x1a400000, 0x1a400099, 0x1a900000, 0x1ab00000,
0x1ab000a4, 0x1ac00000, 0x1ac00098, 0x1b400000,
0x1b400080, 0x1b4000d4, 0x1b4000d6, 0x1b800000,
0x1b800135, 0x1bc00000, 0x1bc00097, 0x1be00000,
0x1be00099, 0x1d100000, 0x1d100033, 0x1d100090,
0x1d200000, 0x1d200060, 0x1d500000, 0x1d500092,
0x1d700000, 0x1d700028, 0x1e100000, 0x1e100095,
0x1e700000, 0x1e7000d6, 0x1ea00000, 0x1ea00053,
// Entry 180 - 19F
0x1f300000, 0x1f500000, 0x1f800000, 0x1f80009e,
0x1f900000, 0x1f90004e, 0x1f90009f, 0x1f900114,
0x1f900139, 0x1fa00000, 0x1fb00000, 0x20000000,
0x200000a3, 0x20300000, 0x20700000, 0x20700052,
0x20800000, 0x20a00000, 0x20a00130, 0x20e00000,
0x20f00000, 0x21000000, 0x2100007e, 0x21200000,
0x21200068, 0x21600000, 0x21700000, 0x217000a5,
0x21f00000, 0x22300000, 0x22300130, 0x22700000,
0x1f300000, 0x1f500000, 0x1f800000, 0x1f80009d,
0x1f900000, 0x1f90004e, 0x1f90009e, 0x1f900113,
0x1f900138, 0x1fa00000, 0x1fb00000, 0x20000000,
0x200000a2, 0x20300000, 0x20700000, 0x20700052,
0x20800000, 0x20a00000, 0x20a0012f, 0x20e00000,
0x20f00000, 0x21000000, 0x2100007d, 0x21200000,
0x21200067, 0x21600000, 0x21700000, 0x217000a4,
0x21f00000, 0x22300000, 0x2230012f, 0x22700000,
// Entry 1A0 - 1BF
0x2270005b, 0x23400000, 0x234000c4, 0x23900000,
0x239000a5, 0x24200000, 0x242000af, 0x24400000,
0x24400052, 0x24500000, 0x24500083, 0x24600000,
0x246000a5, 0x24a00000, 0x24a000a7, 0x25100000,
0x2510009a, 0x25400000, 0x254000ab, 0x254000ac,
0x25600000, 0x2560009a, 0x26a00000, 0x26a0009a,
0x26b00000, 0x26b00130, 0x26d00000, 0x26d00052,
0x26e00000, 0x26e00061, 0x27400000, 0x28100000,
0x2270005a, 0x23400000, 0x234000c3, 0x23900000,
0x239000a4, 0x24200000, 0x242000ae, 0x24400000,
0x24400052, 0x24500000, 0x24500082, 0x24600000,
0x246000a4, 0x24a00000, 0x24a000a6, 0x25100000,
0x25100099, 0x25400000, 0x254000aa, 0x254000ab,
0x25600000, 0x25600099, 0x26a00000, 0x26a00099,
0x26b00000, 0x26b0012f, 0x26d00000, 0x26d00052,
0x26e00000, 0x26e00060, 0x27400000, 0x28100000,
// Entry 1C0 - 1DF
0x2810007c, 0x28a00000, 0x28a000a6, 0x29100000,
0x29100130, 0x29500000, 0x295000b8, 0x2a300000,
0x2a300132, 0x2af00000, 0x2af00136, 0x2b500000,
0x2810007b, 0x28a00000, 0x28a000a5, 0x29100000,
0x2910012f, 0x29500000, 0x295000b7, 0x2a300000,
0x2a300131, 0x2af00000, 0x2af00135, 0x2b500000,
0x2b50002a, 0x2b50004b, 0x2b50004c, 0x2b50004d,
0x2b800000, 0x2b8000b0, 0x2bf00000, 0x2bf0009c,
0x2bf0009d, 0x2c000000, 0x2c0000b7, 0x2c200000,
0x2c20004b, 0x2c400000, 0x2c4000a5, 0x2c500000,
0x2c5000a5, 0x2c700000, 0x2c7000b9, 0x2d100000,
0x2b800000, 0x2b8000af, 0x2bf00000, 0x2bf0009b,
0x2bf0009c, 0x2c000000, 0x2c0000b6, 0x2c200000,
0x2c20004b, 0x2c400000, 0x2c4000a4, 0x2c500000,
0x2c5000a4, 0x2c700000, 0x2c7000b8, 0x2d100000,
// Entry 1E0 - 1FF
0x2d1000a5, 0x2d100130, 0x2e900000, 0x2e9000a5,
0x2ed00000, 0x2ed000cd, 0x2f100000, 0x2f1000c0,
0x2f200000, 0x2f2000d2, 0x2f400000, 0x2f400052,
0x2ff00000, 0x2ff000c3, 0x30400000, 0x3040009a,
0x30b00000, 0x30b000c6, 0x31000000, 0x31b00000,
0x31b0009a, 0x31f00000, 0x31f0003e, 0x31f000d1,
0x31f0010e, 0x32000000, 0x320000cc, 0x32500000,
0x32500052, 0x33100000, 0x331000c5, 0x33a00000,
0x2d1000a4, 0x2d10012f, 0x2e900000, 0x2e9000a4,
0x2ed00000, 0x2ed000cc, 0x2f100000, 0x2f1000bf,
0x2f200000, 0x2f2000d1, 0x2f400000, 0x2f400052,
0x2ff00000, 0x2ff000c2, 0x30400000, 0x30400099,
0x30b00000, 0x30b000c5, 0x31000000, 0x31b00000,
0x31b00099, 0x31f00000, 0x31f0003e, 0x31f000d0,
0x31f0010d, 0x32000000, 0x320000cb, 0x32500000,
0x32500052, 0x33100000, 0x331000c4, 0x33a00000,
// Entry 200 - 21F
0x33a0009d, 0x34100000, 0x34500000, 0x345000d3,
0x34700000, 0x347000db, 0x34700111, 0x34e00000,
0x34e00165, 0x35000000, 0x35000061, 0x350000da,
0x35100000, 0x3510009a, 0x351000dc, 0x36700000,
0x36700030, 0x36700036, 0x36700040, 0x3670005c,
0x367000da, 0x36700117, 0x3670011c, 0x36800000,
0x36800052, 0x36a00000, 0x36a000db, 0x36c00000,
0x33a0009c, 0x34100000, 0x34500000, 0x345000d2,
0x34700000, 0x347000da, 0x34700110, 0x34e00000,
0x34e00164, 0x35000000, 0x35000060, 0x350000d9,
0x35100000, 0x35100099, 0x351000db, 0x36700000,
0x36700030, 0x36700036, 0x36700040, 0x3670005b,
0x367000d9, 0x36700116, 0x3670011b, 0x36800000,
0x36800052, 0x36a00000, 0x36a000da, 0x36c00000,
0x36c00052, 0x36f00000, 0x37500000, 0x37600000,
// Entry 220 - 23F
0x37a00000, 0x38000000, 0x38000118, 0x38700000,
0x38900000, 0x38900132, 0x39000000, 0x39000070,
0x390000a5, 0x39500000, 0x3950009a, 0x39800000,
0x3980007e, 0x39800107, 0x39d00000, 0x39d05000,
0x39d050e9, 0x39d36000, 0x39d3609a, 0x3a100000,
0x3b300000, 0x3b3000ea, 0x3bd00000, 0x3bd00001,
0x37a00000, 0x38000000, 0x38000117, 0x38700000,
0x38900000, 0x38900131, 0x39000000, 0x3900006f,
0x390000a4, 0x39500000, 0x39500099, 0x39800000,
0x3980007d, 0x39800106, 0x39d00000, 0x39d05000,
0x39d050e8, 0x39d36000, 0x39d36099, 0x3a100000,
0x3b300000, 0x3b3000e9, 0x3bd00000, 0x3bd00001,
0x3be00000, 0x3be00024, 0x3c000000, 0x3c00002a,
0x3c000041, 0x3c00004e, 0x3c00005b, 0x3c000087,
0x3c000041, 0x3c00004e, 0x3c00005a, 0x3c000086,
// Entry 240 - 25F
0x3c00008c, 0x3c0000b8, 0x3c0000c7, 0x3c0000d2,
0x3c0000ef, 0x3c000119, 0x3c000127, 0x3c400000,
0x3c40003f, 0x3c40006a, 0x3c4000e5, 0x3d400000,
0x3c00008b, 0x3c0000b7, 0x3c0000c6, 0x3c0000d1,
0x3c0000ee, 0x3c000118, 0x3c000126, 0x3c400000,
0x3c40003f, 0x3c400069, 0x3c4000e4, 0x3d400000,
0x3d40004e, 0x3d900000, 0x3d90003a, 0x3dc00000,
0x3dc000bd, 0x3dc00105, 0x3de00000, 0x3de00130,
0x3e200000, 0x3e200047, 0x3e2000a6, 0x3e2000af,
0x3e2000bd, 0x3e200107, 0x3e200131, 0x3e500000,
0x3e500108, 0x3e600000, 0x3e600130, 0x3eb00000,
0x3dc000bc, 0x3dc00104, 0x3de00000, 0x3de0012f,
0x3e200000, 0x3e200047, 0x3e2000a5, 0x3e2000ae,
0x3e2000bc, 0x3e200106, 0x3e200130, 0x3e500000,
0x3e500107, 0x3e600000, 0x3e60012f, 0x3eb00000,
// Entry 260 - 27F
0x3eb00107, 0x3ec00000, 0x3ec000a5, 0x3f300000,
0x3f300130, 0x3fa00000, 0x3fa000e9, 0x3fc00000,
0x3fd00000, 0x3fd00073, 0x3fd000db, 0x3fd0010d,
0x3ff00000, 0x3ff000d2, 0x40100000, 0x401000c4,
0x3eb00106, 0x3ec00000, 0x3ec000a4, 0x3f300000,
0x3f30012f, 0x3fa00000, 0x3fa000e8, 0x3fc00000,
0x3fd00000, 0x3fd00072, 0x3fd000da, 0x3fd0010c,
0x3ff00000, 0x3ff000d1, 0x40100000, 0x401000c3,
0x40200000, 0x4020004c, 0x40700000, 0x40800000,
0x4085b000, 0x4085b0bb, 0x408eb000, 0x408eb0bb,
0x40c00000, 0x40c000b4, 0x41200000, 0x41200112,
0x41600000, 0x41600110, 0x41c00000, 0x41d00000,
0x4085a000, 0x4085a0ba, 0x408e8000, 0x408e80ba,
0x40c00000, 0x40c000b3, 0x41200000, 0x41200111,
0x41600000, 0x4160010f, 0x41c00000, 0x41d00000,
// Entry 280 - 29F
0x41e00000, 0x41f00000, 0x41f00073, 0x42200000,
0x42300000, 0x42300165, 0x42900000, 0x42900063,
0x42900070, 0x429000a5, 0x42900116, 0x43100000,
0x43100027, 0x431000c3, 0x4310014e, 0x43200000,
0x43220000, 0x43220033, 0x432200be, 0x43220106,
0x4322014e, 0x4325b000, 0x4325b033, 0x4325b0be,
0x4325b106, 0x4325b14e, 0x43700000, 0x43a00000,
0x43b00000, 0x44400000, 0x44400031, 0x44400073,
0x41e00000, 0x41f00000, 0x41f00072, 0x42200000,
0x42300000, 0x42300164, 0x42900000, 0x42900062,
0x4290006f, 0x429000a4, 0x42900115, 0x43100000,
0x43100027, 0x431000c2, 0x4310014d, 0x43200000,
0x43220000, 0x43220033, 0x432200bd, 0x43220105,
0x4322014d, 0x4325a000, 0x4325a033, 0x4325a0bd,
0x4325a105, 0x4325a14d, 0x43700000, 0x43a00000,
0x43b00000, 0x44400000, 0x44400031, 0x44400072,
// Entry 2A0 - 2BF
0x4440010d, 0x44500000, 0x4450004b, 0x445000a5,
0x44500130, 0x44500132, 0x44e00000, 0x45000000,
0x4500009a, 0x450000b4, 0x450000d1, 0x4500010e,
0x46100000, 0x4610009a, 0x46400000, 0x464000a5,
0x46400132, 0x46700000, 0x46700125, 0x46b00000,
0x46b00124, 0x46f00000, 0x46f0006e, 0x46f00070,
0x47100000, 0x47600000, 0x47600128, 0x47a00000,
0x48000000, 0x48200000, 0x4820012a, 0x48a00000,
0x4440010c, 0x44500000, 0x4450004b, 0x445000a4,
0x4450012f, 0x44500131, 0x44e00000, 0x45000000,
0x45000099, 0x450000b3, 0x450000d0, 0x4500010d,
0x46100000, 0x46100099, 0x46400000, 0x464000a4,
0x46400131, 0x46700000, 0x46700124, 0x46b00000,
0x46b00123, 0x46f00000, 0x46f0006d, 0x46f0006f,
0x47100000, 0x47600000, 0x47600127, 0x47a00000,
0x48000000, 0x48200000, 0x48200129, 0x48a00000,
// Entry 2C0 - 2DF
0x48a0005e, 0x48a0012c, 0x48e00000, 0x49400000,
0x49400107, 0x4a400000, 0x4a4000d5, 0x4a900000,
0x4a9000bb, 0x4ac00000, 0x4ac00053, 0x4ae00000,
0x4ae00131, 0x4b400000, 0x4b40009a, 0x4b4000e9,
0x48a0005d, 0x48a0012b, 0x48e00000, 0x49400000,
0x49400106, 0x4a400000, 0x4a4000d4, 0x4a900000,
0x4a9000ba, 0x4ac00000, 0x4ac00053, 0x4ae00000,
0x4ae00130, 0x4b400000, 0x4b400099, 0x4b4000e8,
0x4bc00000, 0x4bc05000, 0x4bc05024, 0x4bc20000,
0x4bc20138, 0x4bc5b000, 0x4bc5b138, 0x4be00000,
0x4be5b000, 0x4be5b0b5, 0x4bef4000, 0x4bef40b5,
0x4c000000, 0x4c300000, 0x4c30013f, 0x4c900000,
0x4bc20137, 0x4bc5a000, 0x4bc5a137, 0x4be00000,
0x4be5a000, 0x4be5a0b4, 0x4bef1000, 0x4bef10b4,
0x4c000000, 0x4c300000, 0x4c30013e, 0x4c900000,
// Entry 2E0 - 2FF
0x4c900001, 0x4cc00000, 0x4cc00130, 0x4ce00000,
0x4cf00000, 0x4cf0004e, 0x4e500000, 0x4e500115,
0x4f200000, 0x4fb00000, 0x4fb00132, 0x50900000,
0x4c900001, 0x4cc00000, 0x4cc0012f, 0x4ce00000,
0x4cf00000, 0x4cf0004e, 0x4e500000, 0x4e500114,
0x4f200000, 0x4fb00000, 0x4fb00131, 0x50900000,
0x50900052, 0x51200000, 0x51200001, 0x51800000,
0x5180003b, 0x518000d7, 0x51f00000, 0x51f3b000,
0x51f3b053, 0x51f3c000, 0x51f3c08e, 0x52800000,
0x528000bb, 0x52900000, 0x5293b000, 0x5293b053,
0x5293b08e, 0x5293b0c7, 0x5293b10e, 0x5293c000,
0x5180003b, 0x518000d6, 0x51f00000, 0x51f3b000,
0x51f3b053, 0x51f3c000, 0x51f3c08d, 0x52800000,
0x528000ba, 0x52900000, 0x5293b000, 0x5293b053,
0x5293b08d, 0x5293b0c6, 0x5293b10d, 0x5293c000,
// Entry 300 - 31F
0x5293c08e, 0x5293c0c7, 0x5293c12f, 0x52f00000,
0x52f00162,
0x5293c08d, 0x5293c0c6, 0x5293c12e, 0x52f00000,
0x52f00161,
} // Size: 3116 bytes
const specialTagsStr string = "ca-ES-valencia en-US-u-va-posix"
// Total table size 3147 bytes (3KiB); checksum: 5A8FFFA5
// Total table size 3147 bytes (3KiB); checksum: 6772C83C

File diff suppressed because it is too large Load Diff

View File

@@ -434,7 +434,7 @@ func newMatcher(supported []Tag, options []MatchOption) *matcher {
// (their canonicalization simply substitutes a different language code, but
// nothing else), the match confidence is Exact, otherwise it is High.
for i, lm := range language.AliasMap {
// If deprecated codes match and there is no fiddling with the script
// If deprecated codes match and there is no fiddling with the script or
// or region, we consider it an exact match.
conf := Exact
if language.AliasTypes[i] != language.Macro {

View File

@@ -23,31 +23,31 @@ const (
_419 = 31
_BR = 65
_CA = 73
_ES = 111
_GB = 124
_MD = 189
_PT = 239
_UK = 307
_US = 310
_ZZ = 358
_XA = 324
_XC = 326
_XK = 334
_ES = 110
_GB = 123
_MD = 188
_PT = 238
_UK = 306
_US = 309
_ZZ = 357
_XA = 323
_XC = 325
_XK = 333
)
const (
_Latn = 91
_Latn = 90
_Hani = 57
_Hans = 59
_Hant = 60
_Qaaa = 149
_Qaai = 157
_Qabx = 198
_Zinh = 255
_Zyyy = 260
_Zzzz = 261
_Qaaa = 147
_Qaai = 155
_Qabx = 196
_Zinh = 252
_Zyyy = 257
_Zzzz = 258
)
var regionToGroups = []uint8{ // 359 elements
var regionToGroups = []uint8{ // 358 elements
// Entry 0 - 3F
0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00,
@@ -60,51 +60,51 @@ var regionToGroups = []uint8{ // 359 elements
// Entry 40 - 7F
0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04,
0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00,
0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04,
0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x08,
0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
// Entry 80 - BF
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00,
0x00, 0x00, 0x04, 0x01, 0x00, 0x04, 0x02, 0x00,
0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00,
0x00, 0x04, 0x01, 0x00, 0x04, 0x02, 0x00, 0x04,
0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00,
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x04,
// Entry C0 - FF
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
0x01, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00,
// Entry C0 - FF
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01,
0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00,
0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00,
0x00, 0x00, 0x00, 0x04, 0x00, 0x05, 0x00, 0x00,
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// Entry 100 - 13F
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x04,
0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x05, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x04, 0x00,
0x00, 0x04, 0x00, 0x04, 0x04, 0x05, 0x00, 0x00,
// Entry 140 - 17F
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
} // Size: 383 bytes
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
} // Size: 382 bytes
var paradigmLocales = [][3]uint16{ // 3 elements
0: [3]uint16{0x139, 0x0, 0x7c},
0: [3]uint16{0x139, 0x0, 0x7b},
1: [3]uint16{0x13e, 0x0, 0x1f},
2: [3]uint16{0x3c0, 0x41, 0xef},
2: [3]uint16{0x3c0, 0x41, 0xee},
} // Size: 42 bytes
type mutualIntelligibility struct {
@@ -249,30 +249,30 @@ var matchLang = []mutualIntelligibility{ // 113 elements
// matchScript holds pairs of scriptIDs where readers of one script
// can typically also read the other. Each is associated with a confidence.
var matchScript = []scriptIntelligibility{ // 26 elements
0: {wantLang: 0x432, haveLang: 0x432, wantScript: 0x5b, haveScript: 0x20, distance: 0x5},
1: {wantLang: 0x432, haveLang: 0x432, wantScript: 0x20, haveScript: 0x5b, distance: 0x5},
2: {wantLang: 0x58, haveLang: 0x3e2, wantScript: 0x5b, haveScript: 0x20, distance: 0xa},
3: {wantLang: 0xa5, haveLang: 0x139, wantScript: 0xe, haveScript: 0x5b, distance: 0xa},
0: {wantLang: 0x432, haveLang: 0x432, wantScript: 0x5a, haveScript: 0x20, distance: 0x5},
1: {wantLang: 0x432, haveLang: 0x432, wantScript: 0x20, haveScript: 0x5a, distance: 0x5},
2: {wantLang: 0x58, haveLang: 0x3e2, wantScript: 0x5a, haveScript: 0x20, distance: 0xa},
3: {wantLang: 0xa5, haveLang: 0x139, wantScript: 0xe, haveScript: 0x5a, distance: 0xa},
4: {wantLang: 0x1d7, haveLang: 0x3e2, wantScript: 0x8, haveScript: 0x20, distance: 0xa},
5: {wantLang: 0x210, haveLang: 0x139, wantScript: 0x2e, haveScript: 0x5b, distance: 0xa},
6: {wantLang: 0x24a, haveLang: 0x139, wantScript: 0x4f, haveScript: 0x5b, distance: 0xa},
7: {wantLang: 0x251, haveLang: 0x139, wantScript: 0x53, haveScript: 0x5b, distance: 0xa},
8: {wantLang: 0x2b8, haveLang: 0x139, wantScript: 0x58, haveScript: 0x5b, distance: 0xa},
9: {wantLang: 0x304, haveLang: 0x139, wantScript: 0x6f, haveScript: 0x5b, distance: 0xa},
10: {wantLang: 0x331, haveLang: 0x139, wantScript: 0x76, haveScript: 0x5b, distance: 0xa},
11: {wantLang: 0x351, haveLang: 0x139, wantScript: 0x22, haveScript: 0x5b, distance: 0xa},
12: {wantLang: 0x395, haveLang: 0x139, wantScript: 0x83, haveScript: 0x5b, distance: 0xa},
13: {wantLang: 0x39d, haveLang: 0x139, wantScript: 0x36, haveScript: 0x5b, distance: 0xa},
14: {wantLang: 0x3be, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5b, distance: 0xa},
15: {wantLang: 0x3fa, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5b, distance: 0xa},
16: {wantLang: 0x40c, haveLang: 0x139, wantScript: 0xd6, haveScript: 0x5b, distance: 0xa},
17: {wantLang: 0x450, haveLang: 0x139, wantScript: 0xe6, haveScript: 0x5b, distance: 0xa},
18: {wantLang: 0x461, haveLang: 0x139, wantScript: 0xe9, haveScript: 0x5b, distance: 0xa},
19: {wantLang: 0x46f, haveLang: 0x139, wantScript: 0x2c, haveScript: 0x5b, distance: 0xa},
20: {wantLang: 0x476, haveLang: 0x3e2, wantScript: 0x5b, haveScript: 0x20, distance: 0xa},
21: {wantLang: 0x4b4, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5b, distance: 0xa},
22: {wantLang: 0x4bc, haveLang: 0x3e2, wantScript: 0x5b, haveScript: 0x20, distance: 0xa},
23: {wantLang: 0x512, haveLang: 0x139, wantScript: 0x3e, haveScript: 0x5b, distance: 0xa},
5: {wantLang: 0x210, haveLang: 0x139, wantScript: 0x2e, haveScript: 0x5a, distance: 0xa},
6: {wantLang: 0x24a, haveLang: 0x139, wantScript: 0x4e, haveScript: 0x5a, distance: 0xa},
7: {wantLang: 0x251, haveLang: 0x139, wantScript: 0x52, haveScript: 0x5a, distance: 0xa},
8: {wantLang: 0x2b8, haveLang: 0x139, wantScript: 0x57, haveScript: 0x5a, distance: 0xa},
9: {wantLang: 0x304, haveLang: 0x139, wantScript: 0x6e, haveScript: 0x5a, distance: 0xa},
10: {wantLang: 0x331, haveLang: 0x139, wantScript: 0x75, haveScript: 0x5a, distance: 0xa},
11: {wantLang: 0x351, haveLang: 0x139, wantScript: 0x22, haveScript: 0x5a, distance: 0xa},
12: {wantLang: 0x395, haveLang: 0x139, wantScript: 0x81, haveScript: 0x5a, distance: 0xa},
13: {wantLang: 0x39d, haveLang: 0x139, wantScript: 0x36, haveScript: 0x5a, distance: 0xa},
14: {wantLang: 0x3be, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5a, distance: 0xa},
15: {wantLang: 0x3fa, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5a, distance: 0xa},
16: {wantLang: 0x40c, haveLang: 0x139, wantScript: 0xd4, haveScript: 0x5a, distance: 0xa},
17: {wantLang: 0x450, haveLang: 0x139, wantScript: 0xe3, haveScript: 0x5a, distance: 0xa},
18: {wantLang: 0x461, haveLang: 0x139, wantScript: 0xe6, haveScript: 0x5a, distance: 0xa},
19: {wantLang: 0x46f, haveLang: 0x139, wantScript: 0x2c, haveScript: 0x5a, distance: 0xa},
20: {wantLang: 0x476, haveLang: 0x3e2, wantScript: 0x5a, haveScript: 0x20, distance: 0xa},
21: {wantLang: 0x4b4, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5a, distance: 0xa},
22: {wantLang: 0x4bc, haveLang: 0x3e2, wantScript: 0x5a, haveScript: 0x20, distance: 0xa},
23: {wantLang: 0x512, haveLang: 0x139, wantScript: 0x3e, haveScript: 0x5a, distance: 0xa},
24: {wantLang: 0x529, haveLang: 0x529, wantScript: 0x3b, haveScript: 0x3c, distance: 0xf},
25: {wantLang: 0x529, haveLang: 0x529, wantScript: 0x3c, haveScript: 0x3b, distance: 0x13},
} // Size: 232 bytes
@@ -295,4 +295,4 @@ var matchRegion = []regionIntelligibility{ // 15 elements
14: {lang: 0x529, script: 0x3c, group: 0x80, distance: 0x5},
} // Size: 114 bytes
// Total table size 1473 bytes (1KiB); checksum: 7BB90B5C
// Total table size 1472 bytes (1KiB); checksum: F86C669

13
vendor/modules.txt vendored
View File

@@ -1,16 +1,17 @@
# github.com/mattn/go-sqlite3 v1.14.7
## explicit; go 1.12
github.com/mattn/go-sqlite3
# golang.org/x/net v0.33.0
## explicit; go 1.18
# golang.org/x/net v0.8.0
## explicit; go 1.17
golang.org/x/net/html
golang.org/x/net/html/atom
golang.org/x/net/html/charset
# golang.org/x/sys v0.28.0
## explicit; go 1.18
# golang.org/x/sys v0.6.0
## explicit; go 1.17
golang.org/x/sys/internal/unsafeheader
golang.org/x/sys/windows
# golang.org/x/text v0.21.0
## explicit; go 1.18
# golang.org/x/text v0.8.0
## explicit; go 1.17
golang.org/x/text/encoding
golang.org/x/text/encoding/charmap
golang.org/x/text/encoding/htmlindex