fix: Windows toolchain compatibility (curl 8.21 re-vendor, endless reconfigure loop) (#4355)

## Problem

Windows builds break with a current local toolchain (Scoop LLVM 22.1.8,
CMake 4.4.0, VS 2026), in two independent ways:

1. The build stops at curl's deliberate guard: `#error "no non-blocking
method was found/used/set"` in `third-party/curl/lib/nonblock.c`.
2. From the second configure onward, `cmake --build` re-runs CMake in an
endless loop (observed 42 consecutive reconfigure cycles in a single
build). Likely the same mechanism behind the "endlessly building" VS
2026 note in `docs/setup/dev/vs.md`.

## Root cause

1. `third-party/curl/CMake/CurlTests.c` passes `int *` to
`ioctlsocket()`, whose third parameter is `u_long *`. Clang 22 promotes
`-Wincompatible-pointer-types` to a hard error in C, so the
`HAVE_IOCTLSOCKET_FIONBIO` try_compile silently fails and
`curl_config.h` never defines it. Upstream CI does not see this because
the windows-2022 runner image ships an older LLVM. GCC 14 promotes the
same warning to a hard error, which is very likely the `CurlTests.c.obj`
failure reported from MSYS2 in open-goal/jak-project#3551. Upstream curl
hit the identical problem with GCC 14 and fixed the probe in curl 8.8.0
(curl/curl#13578).
2. The root CMakeLists copies the build tree's `compile_commands.json`
into `<src>/build/` for clangd using `configure_file()`, which registers
its input as a configure dependency. CMake rewrites
`compile_commands.json` late in every generation, after
`CTestTestfile.cmake` and `cmake_install.cmake` (outputs of the same
Ninja regen rule), so once the dependency is registered the rule is
deterministically dirty and every `ninja` invocation re-runs CMake. A
pristine first configure is safe (the file does not exist yet, so the
`if(EXISTS ...)` guard skips the copy), which is why the loop looks
machine- or IDE-specific.

## Fix

1. Per review, re-vendor `third-party/curl` at the `curl-8_21_0` tag
(previously `curl-8_3_0`), which carries the upstream probe fix plus two
years of upstream development; `vendor.yaml` updated to match.
Adjustments the version jump forced:
- curl 8.15 removed the native macOS Secure Transport backend
(`CURL_USE_SECTRANSP`), so macOS now builds curl against OpenSSL like
Linux. The two macOS workflows install Homebrew `openssl@3` and export
`OPENSSL_ROOT_DIR` (keg-only), and the macOS setup docs gained the same
two lines.
- `CURL_BROTLI` / `CURL_ZSTD` switched to AUTO-detection in curl 8.10;
pinned OFF to keep the previous no-compression behavior and avoid
silently linking whatever the CI images happen to have.
- curl's new top-level `BUILD_EXAMPLES` cache option (default ON) leaked
into discord-rpc's identically named option and broke configure at a
nonexistent `examples/send-presence` directory; pinned OFF ahead of the
third-party subdirectories.

The diff is dominated by the mechanical tag-tree swap under
`third-party/curl` (linguist-vendored, collapsed in review). The
hand-written changes are `CMakeLists.txt`, the two macOS workflows,
`docs/setup/system/macos.md`, and `vendor.yaml`.
2. Swap `configure_file()` for `file(COPY ...)`: the same clangd copy
with no configure dependency registered. (`file(COPY_FILE ...
ONLY_IF_DIFFERENT)` would be cleaner still but requires CMake 3.21,
above the declared `cmake_minimum_required(VERSION 3.10)`.)

## Test plan

- [x] Fresh `cmake --preset Release-windows-clang` (LLVM 22, no cache
seeding) completes and logs `Enabled SSL backends: Schannel`; the
FIONBIO probe passes without the previous `#error`
- [x] Full Windows Release build from scratch in the branch worktree
(all 1422 targets)
- [x] goalc-test suite: 1509 passed, 0 failed
- [x] Second consecutive configure with `compile_commands.json` present:
the regen rule in `build.ninja` has no `compile_commands.json` input;
`<src>/build/compile_commands.json` is still refreshed for clangd
- [x] Repeated `ninja` invocations after a full build no longer re-run
CMake
- [x] macOS Intel and ARM CI green (first exercise of the OpenSSL
backend switch)

---

I work off a self-hosted forge, so this GitHub account is quiet; the
configure logs and ninja dirty-node traces from the investigation are
available if anyone wants the raw data.

(AI-assisted)
This commit is contained in:
Alexander J. Semenuk
2026-07-27 19:19:18 -04:00
committed by GitHub
parent 888b300487
commit 5d5e35fb9b
5480 changed files with 345923 additions and 288294 deletions
+130
View File
@@ -0,0 +1,130 @@
#!/usr/bin/env perl
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# SPDX-License-Identifier: curl
#
# Input: cmdline docs markdown files, they get modified *in place*
#
# Strip off the leading meta-data/header part, remove all known curl symbols
# and long command line options. Also clean up whatever else the spell checker
# might have a problem with that we still deem is fine.
#
use strict;
use warnings;
my @asyms;
open(S, "<./docs/libcurl/symbols-in-versions")
or die "cannot find symbols-in-versions";
while(<S>) {
if(/^([^ ]*) /) {
push @asyms, $1;
}
}
close(S);
# init the opts table with "special" options not easy to figure out
my @aopts = (
'--ftp-ssl-reqd', # old alias
);
open(O, "<./docs/options-in-versions")
or die "cannot find options-in-versions";
while(<O>) {
chomp;
if(/^([^ ]+)/) {
my $o = $1;
push @aopts, $o;
if($o =~ /^--no-(.*)/) {
# for the --no options, also make one without it
push @aopts, "--$1";
}
elsif($o =~ /^--disable-(.*)/) {
# for the --disable options, also make the special ones
push @aopts, "--$1";
push @aopts, "--no-$1";
}
}
}
close(O);
open(C, "<./.github/scripts/spellcheck.curl")
or die "cannot find spellcheck.curl";
while(<C>) {
if(/^\#/) {
next;
}
chomp;
if(/^([^ ]+)/) {
push @asyms, $1;
}
}
close(C);
# longest symbols first
my @syms = sort { length($b) <=> length($a) } @asyms;
# longest cmdline options first
my @opts = sort { length($b) <=> length($a) } @aopts;
sub process {
my ($f) = @_;
my $ignore = 0;
my $sepcount = 0;
my $out;
my $line = 0;
open(F, "<$f") or die;
while(<F>) {
$line++;
if(/^---/ && ($line == 1)) {
$ignore = 1;
next;
}
elsif(/^---/ && $ignore) {
$ignore = 0;
next;
}
next if($ignore);
my $l = $_;
# strip out backticked words
$l =~ s/`[^`]+`//g;
# **bold**
$l =~ s/\*\*(\S.*?)\*\*//g;
# *italics*
$l =~ s/\*(\S.*?)\*//g;
# strip out https URLs, we do not want them spellchecked
$l =~ s!https://[a-z0-9\#_/.-]+!!gi;
# strip links, both name and target
$l =~ s/(\[.*?\])\(.*?\)//g;
$out .= $l;
}
close(F);
# cut out all known curl cmdline options
map { $out =~ s/$_//g; } (@opts);
# cut out all known curl symbols
map { $out =~ s/\b$_\b//g; } (@syms);
if(!$ignore) {
open(O, ">$f") or die;
print O $out;
close(O);
}
}
my @filemasks = @ARGV;
open(my $git_ls_files, '-|', 'git', 'ls-files', '--', @filemasks) or die "Failed running git ls-files: $!";
while(my $f = <$git_ls_files>) {
chomp $f;
process($f);
}
close $git_ls_files;
-79
View File
@@ -1,79 +0,0 @@
#!/usr/bin/perl
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# SPDX-License-Identifier: curl
#
# Input: a libcurl nroff man page
# Output: the same file, minus the SYNOPSIS and the EXAMPLE sections
#
my $f = $ARGV[0];
my $o = $ARGV[1];
open(F, "<$f") or die;
open(O, ">$o") or die;
my $ignore = 0;
while(<F>) {
if($_ =~ /^.SH (SYNOPSIS|EXAMPLE|\"SEE ALSO\"|SEE ALSO)/) {
$ignore = 1;
}
elsif($ignore && ($_ =~ /^.SH/)) {
$ignore = 0;
}
elsif(!$ignore) {
# filter out mentioned CURLE_ names
$_ =~ s/CURL(M|SH|U|H)code//g;
$_ =~ s/CURL_(READ|WRITE)FUNC_[A-Z0-9_]*//g;
$_ =~ s/CURL_CSELECT_[A-Z0-9_]*//g;
$_ =~ s/CURL_DISABLE_[A-Z0-9_]*//g;
$_ =~ s/CURL_FORMADD_[A-Z0-9_]*//g;
$_ =~ s/CURL_HET_DEFAULT//g;
$_ =~ s/CURL_IPRESOLVE_[A-Z0-9_]*//g;
$_ =~ s/CURL_PROGRESSFUNC_CONTINUE//g;
$_ =~ s/CURL_REDIR_[A-Z0-9_]*//g;
$_ =~ s/CURL_RTSPREQ_[A-Z0-9_]*//g;
$_ =~ s/CURL_TIMECOND_[A-Z0-9_]*//g;
$_ =~ s/CURL_VERSION_[A-Z0-9_]*//g;
$_ =~ s/CURLALTSVC_[A-Z0-9_]*//g;
$_ =~ s/CURLAUTH_[A-Z0-9_]*//g;
$_ =~ s/CURLE_[A-Z0-9_]*//g;
$_ =~ s/CURLFORM_[A-Z0-9_]*//g;
$_ =~ s/CURLFTP_[A-Z0-9_]*//g;
$_ =~ s/CURLFTPAUTH_[A-Z0-9_]*//g;
$_ =~ s/CURLFTPMETHOD_[A-Z0-9_]*//g;
$_ =~ s/CURLFTPSSL_[A-Z0-9_]*//g;
$_ =~ s/CURLGSSAPI_[A-Z0-9_]*//g;
$_ =~ s/CURLHEADER_[A-Z0-9_]*//g;
$_ =~ s/CURLINFO_[A-Z0-9_]*//g;
$_ =~ s/CURLM_[A-Z0-9_]*//g;
$_ =~ s/CURLMIMEOPT_[A-Z0-9_]*//g;
$_ =~ s/CURLMOPT_[A-Z0-9_]*//g;
$_ =~ s/CURLOPT_[A-Z0-9_]*//g;
$_ =~ s/CURLPIPE_[A-Z0-9_]*//g;
$_ =~ s/CURLPROTO_[A-Z0-9_]*//g;
$_ =~ s/CURLPROXY_[A-Z0-9_]*//g;
$_ =~ s/CURLPX_[A-Z0-9_]*//g;
$_ =~ s/CURLSHE_[A-Z0-9_]*//g;
$_ =~ s/CURLSHOPT_[A-Z0-9_]*//g;
$_ =~ s/CURLSSH_[A-Z0-9_]*//g;
$_ =~ s/CURLSSLBACKEND_[A-Z0-9_]*//g;
$_ =~ s/CURLU_[A-Z0-9_]*//g;
$_ =~ s/CURLUE_[A-Z0-9_]*//g;
$_ =~ s/CURLUPART_[A-Z0-9_]*//g;
$_ =~ s/CURLUSESSL_[A-Z0-9_]*//g;
$_ =~ s/curl_global_(init_mem|sslset|cleanup)//g;
$_ =~ s/curl_(strequal|strnequal|formadd|waitfd|formget|getdate|formfree)//g;
$_ =~ s/curl_easy_(nextheader|duphandle)//g;
$_ =~ s/curl_multi_fdset//g;
$_ =~ s/curl_mime_(subparts|addpart|filedata|data_cb)//g;
$_ =~ s/curl_ws_(send|recv|meta)//g;
$_ =~ s/curl_url_(dup)//g;
$_ =~ s/curl_pushheader_by(name|num)//g;
$_ =~ s/libcurl-(env|ws)//g;
$_ =~ s/(^|\W)((tftp|https|http|ftp):\/\/[a-z0-9\-._~%:\/?\#\[\]\@!\$&'()*+,;=]+)//gi;
print O $_;
}
}
close(F);
close(O);
+136
View File
@@ -0,0 +1,136 @@
#!/usr/bin/env perl
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
# SPDX-License-Identifier: curl
#
###########################################################################
use strict;
use warnings;
my $autotools = $ARGV[0];
my $cmake = $ARGV[1];
if(!$cmake) {
print "Usage: cmp-config <config1> <config2.h>\n";
exit;
}
# this lists complete lines that are removed from the output if matching
my %remove = (
'#define CURL_EXTERN_SYMBOL' => 1,
'#define CURL_OS "Linux"' => 1,
'#define CURL_OS "x86_64-pc-linux-gnu"' => 1,
'#define GETHOSTNAME_TYPE_ARG2 int' => 1,
'#define GETHOSTNAME_TYPE_ARG2 size_t' => 1,
'#define HAVE_BROTLI 1' => 1,
'#define HAVE_BROTLI_DECODE_H 1' => 1,
'#define HAVE_DLFCN_H 1' => 1,
'#define HAVE_GSSAPI_GSSAPI_GENERIC_H 1' => 1,
'#define HAVE_GSSAPI_GSSAPI_H 1' => 1,
'#define HAVE_GSSAPI_GSSAPI_KRB5_H 1' => 1,
'#define HAVE_INTTYPES_H 1' => 1,
'#define HAVE_LDAP_H 1' => 1,
'#define HAVE_LDAP_SSL 1' => 1,
'#define HAVE_LIBBROTLIDEC 1' => 1,
'#define HAVE_LIBPSL_H 1' => 1,
'#define HAVE_LIBSOCKET 1' => 1,
'#define HAVE_LIBSSH' => 1,
'#define HAVE_LIBSSH2 1' => 1,
'#define HAVE_LIBSSL 1' => 1,
'#define HAVE_LIBZSTD 1' => 1,
'#define HAVE_NGHTTP2_NGHTTP2_H 1' => 1,
'#define HAVE_NGHTTP3_NGHTTP3_H 1' => 1,
'#define HAVE_NGTCP2_NGTCP2_CRYPTO_H 1' => 1,
'#define HAVE_NGTCP2_NGTCP2_H 1' => 1,
'#define HAVE_OPENSSL_CRYPTO_H 1' => 1,
'#define HAVE_OPENSSL_ERR_H 1' => 1,
'#define HAVE_OPENSSL_PEM_H 1' => 1,
'#define HAVE_OPENSSL_RSA_H 1' => 1,
'#define HAVE_OPENSSL_SSL_H 1' => 1,
'#define HAVE_QUICHE_H 1' => 1,
'#define HAVE_SSL_SET_QUIC_TLS_CBS 1' => 1,
'#define HAVE_SSL_SET_QUIC_USE_LEGACY_CODEPOINT 1' => 1,
'#define HAVE_STDINT_H 1' => 1,
'#define HAVE_STDIO_H 1' => 1,
'#define HAVE_STDLIB_H 1' => 1,
'#define HAVE_STRING_H 1' => 1,
'#define HAVE_SYS_STAT_H 1' => 1,
'#define HAVE_SYS_XATTR_H 1' => 1,
'#define HAVE_UNICODE_UIDNA_H 1' => 1,
'#define HAVE_WOLFSSL_SET_QUIC_USE_LEGACY_CODEPOINT 1' => 1,
'#define HAVE_ZSTD 1' => 1,
'#define HAVE_ZSTD_H 1' => 1,
'#define LT_OBJDIR ".libs/"' => 1,
'#define NEED_LBER_H 1' => 1,
'#define PACKAGE "curl"' => 1,
'#define PACKAGE_BUGREPORT "a suitable curl mailing list: https://curl.se/mail/"' => 1,
'#define PACKAGE_NAME "curl"' => 1,
'#define PACKAGE_STRING "curl -"' => 1,
'#define PACKAGE_TARNAME "curl"' => 1,
'#define PACKAGE_URL ""' => 1,
'#define PACKAGE_VERSION "-"' => 1,
'#define VERSION "-"' => 1,
'#define _FILE_OFFSET_BITS 64' => 1,
);
sub filter {
my ($line) = @_;
if(!$remove{$line}) {
return "$line\n";
}
$remove{$line}++;
return "";
}
sub grepit {
my ($input, $output) = @_;
my @defines;
# first get all the #define lines
open(F, "<$input");
while(<F>) {
if($_ =~ /^#def/) {
chomp;
push @defines, $_;
}
}
close(F);
open(O, ">$output");
# output the sorted list through the filter
foreach my $d(sort @defines) {
print O filter($d);
}
close(O);
}
grepit($autotools, "/tmp/autotools");
grepit($cmake, "/tmp/cmake");
foreach my $v (keys %remove) {
if($remove{$v} == 1) {
print "Ignored, never matched line: $v\n";
}
}
# return the exit code from diff
exit system('diff', ('-u', '/tmp/autotools', '/tmp/cmake')) >> 8;
+49
View File
@@ -0,0 +1,49 @@
#!/usr/bin/env bash
# Copyright (C) Viktor Szakats
#
# SPDX-License-Identifier: curl
# Sort list of libs, libpaths, cflags found in libcurl.pc and curl-config files,
# then diff the autotools and cmake generated ones.
sort_lists() {
prevline=''
section=''
while IFS= read -r l; do
if [[ "${prevline}" =~ (--cc|--configure) ]]; then # curl-config
echo "<IGNORED>"
else
# libcurl.pc
if [[ "${l}" =~ ^(Requires|Libs|Cflags)(\.private)?:\ (.+)$ ]]; then
if [ "${BASH_REMATCH[1]}" = 'Requires' ]; then
# Spec does not allow duplicates here:
# https://manpages.debian.org/unstable/pkg-config/pkg-config.1.en.html#Requires:
# "You may only mention the same package one time on the Requires: line"
val="$(printf '%s' "${BASH_REMATCH[3]}" | tr ',' '\n' | sort | tr '\n' ' ')"
else
val="$(printf '%s' "${BASH_REMATCH[3]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')"
fi
l="${BASH_REMATCH[1]}${BASH_REMATCH[2]}: ${val}"
# curl-config
elif [[ "${section}" =~ (--libs|--static-libs) && "${l}" =~ ^( *echo\ \")(.+)(\")$ ]]; then
val="$(printf '%s' "${BASH_REMATCH[2]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')"
l="${BASH_REMATCH[1]}${val}${BASH_REMATCH[3]}"
section=''
fi
echo "${l}"
fi
# curl-config
prevline="${l}"
if [[ "${l}" =~ --[a-z-]+\) ]]; then
section="${BASH_REMATCH[0]}"
fi
done < "$1"
}
am=$(mktemp -t autotools.XXX); sort_lists "$1" > "${am}"
cm=$(mktemp -t cmake.XXX) ; sort_lists "$2" > "${cm}"
diff -u "${am}" "${cm}"
res="$?"
rm -r -f "${am}" "${cm}"
exit "${res}"
+21
View File
@@ -0,0 +1,21 @@
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# SPDX-License-Identifier: curl
anonymou
aNULL
bu
clen
CNA
hel
htpts
inout
PASE
passwor
perfec
proxys
seh
ser
strat
te
UE
WONT
+22
View File
@@ -0,0 +1,22 @@
#!/bin/sh
# Copyright (C) Viktor Szakats
#
# SPDX-License-Identifier: curl
set -eu
cd "$(dirname "${0}")"/../..
git ls-files -z | xargs -0 -r \
codespell \
--skip '.github/scripts/pyspelling.words' \
--skip '.github/scripts/typos.toml' \
--skip 'docs/THANKS' \
--skip 'projects/OS400/*' \
--skip 'projects/vms/*' \
--skip 'RELEASE-NOTES' \
--skip 'scripts/wcurl' \
--skip 'tests/unit/unit1625.c' \
--ignore-regex '.*spellchecker:disable-line' \
--ignore-words '.github/scripts/codespell-ignore.words' \
--
+54
View File
@@ -0,0 +1,54 @@
#!/usr/bin/env bash
# Copyright (C) Viktor Szakats
#
# SPDX-License-Identifier: curl
# Compare git repo files with tarball files and report a mismatch
# after excluding exceptions.
set -eu
gitonly=".git*
^.*
^appveyor.*
^GIT-INFO.md
^README.md
^renovate.json
^REUSE.toml
^SECURITY.md
^LICENSES/*
^docs/examples/adddocsref.pl
^docs/tests/CI.md
^docs/THANKS-filter
^projects/Windows/*
^scripts/contributors.sh
^scripts/contrithanks.sh
^scripts/delta
^scripts/installcheck.sh
^scripts/release-notes.pl
^scripts/singleuse.pl"
tarfiles="$(mktemp)"
gitfiles="$(mktemp)"
tar -tf "$1" \
| sed -E 's|^[^/]+/||g' \
| grep -v -E '(/|^)$' \
| sort > "${tarfiles}"
git -C "${2:-.}" ls-files \
| grep -v -E "($(printf '%s' "${gitonly}" | tr $'\n' '|' | sed -e 's|\.|\\.|g' -e 's|\*|.+|g'))$" \
| sort > "${gitfiles}"
dif="$(diff -u "${tarfiles}" "${gitfiles}" | tail -n +3 || true)"
rm -rf "${tarfiles:?}" "${gitfiles:?}"
echo 'Only in tarball:'
echo "${dif}" | grep '^-' || true
echo
echo 'Missing from tarball:'
if echo "${dif}" | grep '^+'; then
exit 1
fi
@@ -2,6 +2,7 @@
#
# SPDX-License-Identifier: curl
#
AAAA
ABI
accessor
ACK
@@ -10,10 +11,12 @@ AIA
AIX
al
Alessandro
aliasMode
allocator
alnum
ALPN
Altera
AltSvc
ALTSVC
amiga
AmigaOS
@@ -30,7 +33,6 @@ archivers
Archos
Arntsen
Aros
ascii
asynch
AsynchDNS
atime
@@ -38,7 +40,10 @@ auth
autobuild
autobuilds
Autoconf
autoconf
Automake
automake
autoreconf
Autotools
autotools
AVR
@@ -48,7 +53,9 @@ axTLS
backend
backends
backoff
backtick
backticks
balancers
Baratov
basename
bashrc
@@ -57,13 +64,13 @@ BearSSL
Benoit
BeOS
bitmask
bitset
bitwise
Björn
Bjørn
bool
boolean
BoringSSL
boringssl
Boukris
Broadcom
brotli
@@ -73,7 +80,6 @@ bugfix
bugfixes
buildable
buildbot
buildconf
Caddy
calloc
CAPA
@@ -82,6 +88,7 @@ CCC
CDN
CentOS
CFLAGS
cflags
CGI's
CHACHA
chacha
@@ -91,6 +98,7 @@ changeset
CharConv
charset
charsets
checkdocs
checksrc
checksums
chgrp
@@ -104,18 +112,24 @@ CLA
CLAs
cleartext
CLI
ClientHello
clientp
cliget
closesocket
CMake
cmake
CMake's
cmake's
CMakeLists
CNA
CNAME
CNAMEs
CodeQL
codeql
CODESET
codeset
CodeSonar
Comcast
commit's
Config
config
conncache
@@ -126,6 +140,7 @@ CPUs
CR
CRL
CRLF
crontab
crt
crypto
cryptographic
@@ -135,11 +150,13 @@ CSeq
csh
cshrc
CTRL
cURL
CURLcode
curldown
CURLE
CURLECH
CURLH
curlimages
CURLINFO
curlrc
curltest
customizable
@@ -150,13 +167,25 @@ CWE
cyassl
Cygwin
daniel
datagrams
datatracker
dbg
decapsulation
Debian
DEBUGBUILD
decrypt
decrypted
decrypting
deepcode
defacto
DELE
DER
dereference
dereferences
DES
deselectable
deserialization
Deserialized
destructor
detections
dev
@@ -164,7 +193,9 @@ devcpp
DevOps
devtools
DHCP
DHE
dir
discoverable
distro
distro's
distros
@@ -176,30 +207,42 @@ DLLs
DNS
dns
dnsop
DNSSEC
DoH
DoT
doxygen
drftpd
dsa
DSN
dtrace
Dudka
Dymond
dynbuf
EAGAIN
EBCDIC
ECC
ECCN
ECDHE
ECH
ECHConfig
ECHConfigList
ecl
ECONNREFUSED
eCOS
ECT
EF
EFnet
EGD
EHLO
EINTR
else's
encapsulation
encodings
enctype
endianness
Engler
enum
enums
epoll
EPRT
EPSV
@@ -210,6 +253,7 @@ et
etag
ETag
ETags
exa
exe
executables
EXPN
@@ -224,8 +268,10 @@ Feltzing
ffi
filesize
filesystem
FindCURL
FLOSS
fnmatch
footguns
formpost
formposts
Fortnite
@@ -258,27 +304,33 @@ getinfo
GETing
getpwuid
ggcov
GHA
Ghedini
giga
Gisle
Glesys
glibc
globbed
globbing
gmail
GnuTLS
gnutls
Golemon
GOST
GPG
GPL
GPLed
GREASE
GREASEing
Greear
groff
gsasl
GSKit
gskit
GSS
GSSAPI
GTFO
Guenter
GUIs
Gunderson
Gustafsson
gzip
@@ -292,6 +344,7 @@ Hards
Haxx
haxx
Heimdal
HelloRetryRequest
HELO
HH
HMAC
@@ -301,6 +354,7 @@ homebrew
hostname
hostnames
Housley
HRR
Hruska
HSTS
hsts
@@ -314,8 +368,8 @@ httpget
HttpGet
HTTPS
https
HTTPSRR
hyper's
Högskolan
IANA
Icecast
ICONV
@@ -328,14 +382,16 @@ ifdef
ifdefed
Ifdefs
ifdefs
ifhost
IIS
ILE
Illumos
illumos
IMAP
imap
IMAPS
imaps
impacket
implementers
init
initializer
inlined
@@ -345,6 +401,9 @@ interoperates
IoT
ipadOS
IPCXN
IPFS
ipld
IPNS
IPv
IPv4
IPv4/6
@@ -371,6 +430,7 @@ kerberos
Keychain
keychain
KiB
kibibyte
kickstart
Kirei
Knauf
@@ -379,14 +439,15 @@ Krb
krb
Kubernetes
Kuhrt
Kungliga
Largefile
LDAP
ldap
LDAPS
ldaps
LF
LGPL
LGTM
libbacktrace
libbrotlidec
libc
libcurl
@@ -403,25 +464,30 @@ libpsl
Libre
libre
LibreSSL
libressl
librtmp
libs
libssh
libSSH
libssh2
libtest
libtests
Libtool
libtool
libuv
libWebSocket
libz
libzstd
LineageOS
linter
linux
lldb
ln
localhost
LOGDIR
logfile
lookups
loopback
LOWCOST
LOWDELAY
LPRT
LSB
lseek
@@ -434,11 +500,15 @@ Makefile
makefiles
malloc
mallocs
manpage
manpages
maprintf
Marek
Mavrogiannopoulos
Mbed
mbedTLS
md
mebibyte
Meglio
memdebug
MesaLink
@@ -449,6 +519,8 @@ Michal
Micrium
MicroBlaze
MicroOS
middlebox
MINCOST
mingw
MinGW
MINIX
@@ -465,6 +537,7 @@ MorphOS
MPE
MPL
mprintf
MPTCP
MQTT
mqtt
mqtts
@@ -484,6 +557,7 @@ mTLS
MUA
multicwd
multiparts
multipath
MultiSSL
mumbo
musedev
@@ -507,6 +581,7 @@ Necko
NetBSD
netrc
netstat
NetWare
Netware
NFS
nghttp
@@ -552,6 +627,7 @@ Orbis
ORing
Osipov
OSS
PaaS
pac
pacman
parser's
@@ -562,6 +638,7 @@ PEM
pem
perl
permafailing
peta
PINGs
pipelining
PKCS
@@ -569,6 +646,7 @@ pkcs
PKGBUILD
PKI
pluggable
pn
PolarSSL
Polhem
pollset
@@ -604,6 +682,7 @@ py
pycurl
pytest
Pytest
qname
QNX
QoS
Qubes
@@ -618,6 +697,7 @@ ReactOS
README
realloc
Realtime
rebalances
rebase
RECV
recv
@@ -639,17 +719,21 @@ RETR
retransmit
retrigger
RHEL
RICS
Rikard
rmdir
ROADMAP
Roadmap
Rockbox
roffit
RPC
RPG
RR
RRs
RRtype
RSA
RTMP
rtmp
rtmpdump
RTMPE
RTMPS
RTMPT
@@ -664,7 +748,9 @@ runtests
runtime
Ruslan
rustc
Rustls
rustls
rustup
Sagula
SanDisk
SAS
@@ -678,6 +764,7 @@ scp
SDK
se
SEB
SecTrust
SEK
selectable
Serv
@@ -698,6 +785,7 @@ sizeof
SLE
slist
sln
Slowloris
SMB
smb
SMBS
@@ -708,6 +796,7 @@ smtp
smtps
SMTPS
SNI
sockd
socketopen
socketpair
sockopt
@@ -716,6 +805,7 @@ SOCKSv
Solaris
SONAME
Soref
SOVERSION
SPARC
SPDX
SPNEGO
@@ -724,10 +814,12 @@ sprintf
src
SRP
SRWLOCK
SSI
SSL
ssl
SSLeay
SSLKEYLOGFILE
SSLS
sslv
SSLv
SSLVERSION
@@ -739,9 +831,11 @@ stateful
statvfs
stderr
stdin
stdint
stdout
Steinar
Stenberg
STLS
STOR
strcat
strcpy
@@ -758,11 +852,14 @@ subdirectory
submitters
substring
substrings
sudo
SunOS
SunSSH
superset
svc
svcb
SVCB
SVG
Svyatoslav
Swisscom
sws
@@ -776,10 +873,12 @@ Tatsuhiro
TBD
TCP
tcpdump
Tekniska
tera
testability
testcurl
TFTP
tftp
threadsafe
Tizen
TLS
tlsv
@@ -790,24 +889,31 @@ toolchain
toolchains
toolset
toplevel
TOS
TPF
TrackMemory
transcode
Tru
trurl
trustless
Tse
Tsujikawa
TTL
tty
tvOS
txt
typedef
typedefed
Ubuntu
ucLinux
UCRT
UDP
UI
UID
UIDL
uint
Ultrix
umask
Unary
unassign
UNC
@@ -816,8 +922,8 @@ unencoded
unencrypted
unescape
Unglobbed
Unicode
UNICOS
unix
UnixSockets
UnixWare
unlink
@@ -829,6 +935,7 @@ unsanitized
Unshare
unsharing
untrusted
unwrite
UPN
upstreaming
URI
@@ -851,12 +958,17 @@ VC
vcpkg
vexxhost
Viktor
virtualized
Virtuozzo
VLAN
VM
VMS
VMware
vnd
VRF
VRFY
VSE
vsftpd
vsprintf
vt
vtls
@@ -866,34 +978,35 @@ Warta
watchOS
WAV
WB
web page
wcurl
WebDAV
WebOS
webpage
webpages
WebSocket
WEBSOCKET
Wget
WHATWG
whitespace
Whitespaces
winbind
WinBind
winbuild
winidn
WinIDN
WinLDAP
WinSock
winsock
WinSSL
winssl
Wireshark
wolfSSH
wolfSSL
ws
WS
WSS
www
Xbox
XDG
xdigit
XHTML
Xilinx
xmllint
XP
Xtensa
XYZ
@@ -901,6 +1014,7 @@ Youtube
YYYY
YYYYMMDD
Zakrzewski
Zeropath
Zitzmann
zlib
zsh
+33
View File
@@ -0,0 +1,33 @@
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# SPDX-License-Identifier: curl
#
# Docs: https://facelessuser.github.io/pyspelling/configuration/
# Docs: https://github.com/UnicornGlobal/spellcheck-github-actions
matrix:
- name: Markdown
expect_match: false
apsell:
mode: en
dictionary:
wordlists:
- wordlist.txt
output: wordlist.dic
encoding: utf-8
pipeline:
- pyspelling.filters.markdown:
markdown_extensions:
- markdown.extensions.extra:
- pyspelling.filters.html:
comments: true
attributes:
- title
- alt
ignores:
- ':matches(code, pre)'
- 'code'
- 'pre'
- 'strong'
- 'em'
sources:
- '**/*.md|!docs/BINDINGS.md|!docs/DISTROS.md|!docs/CIPHERS-TLS12.md|!docs/wcurl.md|!tests/data/data*.md'
+251
View File
@@ -0,0 +1,251 @@
#!/usr/bin/env perl
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# SPDX-License-Identifier: curl
#
# Input: number of seconds to run.
#
# 1. Figure out all existing command line options
# 2. Generate random command line using supported options
# 3. Run the command line
# 4. Verify that it does not return an unexpected return code
# 5. Iterate until the time runs out
#
# Do the same with regular command lines as well as reading the options from a
# -K config file
#
# BEWARE: this may create a large amount of files using random names in the
# directory where it runs.
#
use strict;
use warnings;
my $curl = "../src/curl";
my $url = "localhost:7777"; # not listening to this
my $seconds = $ARGV[0];
if($ARGV[1]) {
$curl = $ARGV[1];
}
if(!$seconds) {
$seconds = 10;
}
print "Run $curl for $seconds seconds\n";
my @opt;
my %arg;
my %uniq;
my %allrc;
my $totalargs = 0;
my $totalcmds = 0;
my $counter = 0xabcdef + time();
sub getnum {
my ($max) = @_;
return int(rand($max));
}
sub storedata {
my ($short, $long, $arg) = @_;
push @opt, "-$short" if($short);
push @opt, "--$long";
if($arg =~ /^</) {
# these take an argument
$arg{"-$short"} = $arg if($short);
$arg{"--$long"} = $arg;
}
}
sub getoptions {
my @all = qx($curl --help all);
for my $o (@all) {
chomp $o;
if($o =~ /^ -(.), --([^ ]*) (.*)/) {
storedata($1, $2, $3);
}
elsif($o =~ /^ --([^ ]*) (.*)/) {
storedata("", $1, $2);
}
}
}
# this adds a fake randomly generated command line option
sub addarg {
my $nice = "abcdefhijklmnopqrstuvwqxyz".
"ABCDEFHIJKLMNOPQRSTUVWQXYZ".
"0123456789-";
my $len = getnum(20) + 2;
my $o;
for (1 .. $len) {
$o .= substr($nice, getnum(length($nice)), 1);
}
return "--$o";
}
sub randarg {
my $nice = "abcdefhijklmnopqrstuvwqxyz".
"ABCDEFHIJKLMNOPQRSTUVWQXYZ".
"0123456789".
",-?#$%!@ ";
my $len = getnum(20);
my $o = '';
for (1 .. $len) {
$o .= substr($nice, getnum(length($nice)), 1);
}
return "\'$o\'";
}
getoptions();
my $nopts = scalar(@opt);
my %useropt = (
'-U' => 1,
'-u' => 1,
'--user' => 1,
'--proxy-user' => 1);
my %commonrc = (
'0' => 1,
'1' => 1,
'2' => 1,
'26' => 1,
);
sub runone {
my $a;
my $nargs = getnum(60) + 1;
$totalargs += $nargs;
$totalcmds++;
for (1 .. $nargs) {
my $o = getnum($nopts);
my $option = $opt[$o];
my $ar = "";
$uniq{$option}++;
if($arg{$option}) {
$ar = " ".randarg();
if($useropt{$option}) {
# append password to avoid prompting
$ar .= ":".randarg();
}
}
$a .= sprintf(" %s%s", $option, $ar);
}
if(getnum(100) < 15) {
# add a fake arg
$a .= " ".addarg();
}
my $cmd = "$curl$a $url";
my $rc = system("$cmd >curl-output 2>&1 </dev/null -M 0.1") >> 8;
#my $rc = system("valgrind -q $cmd >/dev/null 2>&1 </dev/null -M 0.1") >> 8;
$allrc{$rc}++;
#print "CMD: $cmd\n";
if(!$commonrc{$rc}) {
print "CMD: $cmd\n";
print "RC: $rc\n";
print "== curl-output == \n";
open(D, "<curl-output");
my @out = <D>;
print @out;
close(D);
exit;
}
}
sub runconfig {
my $a;
my $nargs = getnum(80) + 1;
open(C, ">config");
$totalargs += $nargs;
$totalcmds++;
for (1 .. $nargs) {
my $o = getnum($nopts);
my $option = $opt[$o];
my $ar = "";
$uniq{$option} = 0 if(!exists $uniq{$option});
$uniq{$option}++;
if($arg{$option}) {
$ar = " ".randarg();
if($useropt{$option}) {
# append password
$ar .= ":".randarg();
}
}
$a .= sprintf("\n%s%s", $option, $ar);
}
if(getnum(100) < 15) {
# add a fake arg
$a .= "\n".addarg();
}
print C "$a\n";
close(C);
my $cmd = "$curl -K config $url";
my $rc = system("$cmd >curl-output 2>&1 </dev/null -M 0.1") >> 8;
$allrc{$rc}++;
if(!$commonrc{$rc}) {
print "CMD: $cmd\n";
print "RC: $rc\n";
print "== config == \n";
open(D, "<config");
my @all = <D>;
print @all;
close(D);
print "\n== curl-output == \n";
open(D, "<curl-output");
my @out = <D>;
print @out;
close(D);
exit 2;
}
}
# run curl command lines using -K
my $end = time() + $seconds / 2;
my $c = 0;
print "Running command lines\n";
do {
runconfig();
$c++;
} while(time() <= $end);
print "$c command lines\n";
# run curl command lines
$end = time() + $seconds / 2;
$c = 0;
print "Running config lines\n";
do {
runone();
$c++;
} while(time() <= $end);
print "$c config line uses\n";
print "Recorded exit codes:\n";
for my $rc (keys %allrc) {
printf " %2d: %d times\n", $rc, $allrc{$rc};
}
printf "Number or command lines tested:\n".
" $totalcmds (%.1f/second)\n", $totalcmds/$seconds;
printf "Number or command line options tested:\n".
" $totalargs (average %.1f per command line)\n",
$totalargs/$totalcmds;
printf "Number or different options tested:\n".
" %u out of %u\n", scalar(keys %uniq), $nopts;
+5
View File
@@ -0,0 +1,5 @@
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# SPDX-License-Identifier: curl
pyspelling==2.12.1
+5
View File
@@ -0,0 +1,5 @@
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# SPDX-License-Identifier: curl
proselint==0.16.0
+8
View File
@@ -0,0 +1,8 @@
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# SPDX-License-Identifier: curl
cmakelang==0.6.13
codespell==2.4.2
reuse==6.2.0
ruff==0.15.16
+30
View File
@@ -0,0 +1,30 @@
#!/bin/sh
# Copyright (C) Viktor Szakats
#
# SPDX-License-Identifier: curl
# Required: yq
set -eu
export SHELLCHECK_OPTS='--exclude=1090,1091,2086,2153 --enable=avoid-nullary-conditions,deprecate-which'
# GHA
git ls-files '.github/workflows/*.yml' | while read -r f; do
echo "Verifying ${f}..."
{
echo '#!/usr/bin/env bash'
echo 'set -eu'
yq eval '.. | select(has("run") and (.run | type == "!!str")) | .run + "\ntrue\n"' "${f}"
} | sed -E 's|\$\{\{ .+ \}\}|GHA_EXPRESSION|g' | shellcheck -
done
# Circle CI
git ls-files '.circleci/*.yml' | while read -r f; do
echo "Verifying ${f}..."
{
echo '#!/usr/bin/env bash'
echo 'set -eu'
yq eval '.. | select(has("command") and (.command | type == "!!str")) | .command + "\ntrue\n"' "${f}"
} | shellcheck -
done
+13
View File
@@ -0,0 +1,13 @@
#!/bin/sh
# Copyright (C) Viktor Szakats
#
# SPDX-License-Identifier: curl
set -eu
cd "$(dirname "${0}")"/../..
git grep -z -l -E '^#!(/usr/bin/env bash|/bin/sh|/bin/bash)' | xargs -0 -r \
shellcheck --exclude=1091,2248 \
--enable=avoid-nullary-conditions,deprecate-which \
--
+153
View File
@@ -0,0 +1,153 @@
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# SPDX-License-Identifier: curl
#
# common variable types + structs
# callback typedefs
# public functions names
# some man page names
curl_fileinfo
curl_forms
curl_hstsentry
curl_httppost
curl_index
curl_khkey
curl_pushheaders
curl_waitfd
CURLcode
CURLformoption
CURLHcode
CURLMcode
CURLMsg
CURLSHcode
CURLUcode
curl_calloc_callback
curl_chunk_bgn_callback
curl_chunk_end_callback
curl_conv_callback
curl_debug_callback
curl_fnmatch_callback
curl_formget_callback
curl_free_callback
curl_hstsread_callback
curl_hstswrite_callback
curl_ioctl_callback
curl_malloc_callback
curl_multi_timer_callback
curl_opensocket_callback
curl_prereq_callback
curl_progress_callback
curl_push_callback
curl_read_callback
curl_realloc_callback
curl_resolver_start_callback
curl_seek_callback
curl_socket_callback
curl_sockopt_callback
curl_ssl_ctx_callback
curl_strdup_callback
curl_trailer_callback
curl_write_callback
curl_xferinfo_callback
curl_strequal
curl_strnequal
curl_mime_init
curl_mime_free
curl_mime_addpart
curl_mime_name
curl_mime_filename
curl_mime_type
curl_mime_encoder
curl_mime_data
curl_mime_filedata
curl_mime_data_cb
curl_mime_subparts
curl_mime_headers
curl_formadd
curl_formget
curl_formfree
curl_getdate
curl_getenv
curl_version
curl_easy_escape
curl_escape
curl_easy_unescape
curl_unescape
curl_free
curl_global_init
curl_global_init_mem
curl_global_cleanup
curl_global_trace
curl_global_sslset
curl_slist_append
curl_slist_free_all
curl_getdate
curl_share_init
curl_share_setopt
curl_share_cleanup
curl_version_info
curl_easy_strerror
curl_share_strerror
curl_easy_pause
curl_easy_ssls_import
curl_easy_ssls_export
curl_easy_init
curl_easy_setopt
curl_easy_perform
curl_easy_cleanup
curl_easy_getinfo
curl_easy_duphandle
curl_easy_reset
curl_easy_recv
curl_easy_send
curl_easy_upkeep
curl_easy_header
curl_easy_nextheader
curl_mprintf
curl_mfprintf
curl_msprintf
curl_msnprintf
curl_mvprintf
curl_mvfprintf
curl_mvsprintf
curl_mvsnprintf
curl_maprintf
curl_mvaprintf
curl_multi_init
curl_multi_add_handle
curl_multi_remove_handle
curl_multi_fdset
curl_multi_waitfds
curl_multi_wait
curl_multi_poll
curl_multi_wakeup
curl_multi_perform
curl_multi_cleanup
curl_multi_info_read
curl_multi_strerror
curl_multi_socket
curl_multi_socket_action
curl_multi_socket_all
curl_multi_timeout
curl_multi_setopt
curl_multi_assign
curl_multi_get_handles
curl_multi_get_offt
curl_multi_notify_disable
curl_multi_notify_enable
curl_pushheader_bynum
curl_pushheader_byname
curl_easy_option_by_name
curl_easy_option_by_id
curl_easy_option_next
curl_url
curl_url_cleanup
curl_url_dup
curl_url_get
curl_url_set
curl_url_strerror
curl_ws_recv
curl_ws_send
curl_ws_meta
libcurl-env
libcurl-ws
-32
View File
@@ -1,32 +0,0 @@
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# SPDX-License-Identifier: curl
#
# Docs: https://github.com/UnicornGlobal/spellcheck-github-actions
matrix:
- name: Markdown
expect_match: false
apsell:
mode: en
dictionary:
wordlists:
- wordlist.txt
output: wordlist.dic
encoding: utf-8
pipeline:
- pyspelling.filters.markdown:
markdown_extensions:
- markdown.extensions.extra:
- pyspelling.filters.html:
comments: true
attributes:
- title
- alt
ignores:
- ':matches(code, pre)'
- 'code'
- 'pre'
- 'strong'
- 'em'
sources:
- '**/*.md|!docs/BINDINGS.md'
+44
View File
@@ -0,0 +1,44 @@
#!/usr/bin/env perl
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# SPDX-License-Identifier: curl
#
# Given: a libcurl curldown man page
# Outputs: the same file, minus the header
#
use strict;
use warnings;
my $f = $ARGV[0] || '';
open(F, "<$f") or die;
my @out;
my $line = 0;
my $hideheader = 0;
while(<F>) {
if($hideheader) {
if(/^---/) {
# end if hiding
$hideheader = 0;
}
push @out, "\n"; # replace with blank
next;
}
elsif(!$line++ && /^---/) {
# starts with a header, strip off the header
$hideheader = 1;
push @out, "\n"; # replace with blank
next;
}
push @out, $_;
}
close(F);
open(O, ">$f") or die;
for my $l (@out) {
print O $l;
}
close(O);
+14
View File
@@ -0,0 +1,14 @@
#!/bin/sh
# Copyright (C) Viktor Szakats
#
# SPDX-License-Identifier: curl
set -eu
cd "$(dirname "${0}")"/../..
git ls-files | typos \
--isolated \
--force-exclude \
--config '.github/scripts/typos.toml' \
--file-list -
+36
View File
@@ -0,0 +1,36 @@
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# SPDX-License-Identifier: curl
[default]
extend-ignore-identifiers-re = [
"^(ba|fo|pn|PN|UE)$",
"^(CNA|cpy|ser)$",
"^(ECT0|ECT1|HELO|htpts|mport|PASE)$",
"^[A-Za-z0-9_-]*(EDE|GOST)[A-Z0-9_-]*$", # ciphers
"^0x[0-9a-fA-F]+FUL$", # unsigned long hex literals ending with 'F'
"^[0-9a-zA-Z+]{64,}$", # possibly base64
"^(eyeballers|HELO_smtp|Januar|optin|passin|perfec|SMTP_HELO)$",
"^(clen|req_clen|smtp_perform_helo|smtp_state_helo_resp|Tru64|_stati64)$",
"(_ccontains|_controllen|O_WRONLY|secur32)",
"proxys", # this should be limited to tests/http/*. Short for secure proxy.
]
extend-ignore-re = [
".*spellchecker:disable-line",
]
[files]
extend-exclude = [
".github/scripts/codespell-ignore.words",
".github/scripts/pyspelling.words",
"docs/THANKS",
"projects/OS400/*",
"projects/vms/*",
"projects/Windows/tmpl/curl.vcxproj",
"projects/Windows/tmpl/libcurl.vcxproj",
"RELEASE-NOTES",
"scripts/wcurl",
"tests/data/test*",
"tests/unit/unit1625.c",
]
+106
View File
@@ -0,0 +1,106 @@
#!/usr/bin/env perl
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
# SPDX-License-Identifier: curl
#
###########################################################################
use strict;
use warnings;
my @files = @ARGV;
my $cfile = "test.c";
my $check = "./scripts/checksrc.pl";
my $error = 0;
if(!@files || $files[0] eq "-h") {
print "Usage: verify-examples [markdown pages]\n";
exit;
}
sub testcompile {
my $rc = system('gcc -c test.c -I include -W -Wall -pedantic -Werror ' .
'-Wno-unused-parameter -Wno-unused-but-set-variable ' .
'-DCURL_ALLOW_OLD_MULTI_SOCKET -DCURL_DISABLE_DEPRECATION') >> 8;
return $rc;
}
sub checksrc {
my $rc = system($check, ('test.c')) >> 8;
return $rc;
}
sub extract {
my($f) = @_;
my $syn = 0;
my $l = 0;
my $iline = 0;
my $fail = 0;
open(F, "<$f") or die "failed opening input file $f : $!";
open(O, ">$cfile") or die "failed opening output file $cfile : $!";
print O "#include <curl/curl.h>\n";
while(<F>) {
$iline++;
if(/^# EXAMPLE/) {
$syn = 1
}
elsif($syn == 1) {
if(/^~~~/) {
$syn++;
print O "/* !checksrc! disable BANNEDFUNC all */\n"; # for fopen()
print O "/* !checksrc! disable COPYRIGHT all */\n";
print O "/* !checksrc! disable UNUSEDIGNORE all */\n";
printf O "#line %d \"$f\"\n", $iline + 1;
}
}
elsif($syn == 2) {
if(/^~~~/) {
last;
}
# two backslashes become one
$_ =~ s/\\\\/\\/g;
print O $_;
$l++;
}
}
close(F);
close(O);
return ($fail ? 0 : $l);
}
my $count = 0;
for my $m (@files) {
#print "Verify $m\n";
my $out = extract($m);
if($out) {
$error |= testcompile($m);
$error |= checksrc($m);
}
$count++;
}
if(!$error) {
print "Verified $count man pages ok\n";
}
else {
print "Detected problems\n";
}
exit $error;
+87
View File
@@ -0,0 +1,87 @@
#!/usr/bin/env perl
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
# SPDX-License-Identifier: curl
#
###########################################################################
use strict;
use warnings;
my @files = @ARGV;
my $cfile = "test.c";
if(!@files || $files[0] eq "-h") {
print "Usage: verify-synopsis [man pages]\n";
exit;
}
sub testcompile {
my $rc = system('gcc -c test.c -I include -W -Wall -pedantic -Werror ' .
'-DCURL_ALLOW_OLD_MULTI_SOCKET -DCURL_DISABLE_TYPECHECK') >> 8;
return $rc;
}
sub extract {
my($f) = @_;
my $syn = 0;
my $l = 0;
my $iline = 0;
open(F, "<$f");
open(O, ">$cfile");
while(<F>) {
$iline++;
if(/^# SYNOPSIS/) {
$syn = 1
}
elsif($syn == 1) {
if(/^\~\~\~/) {
$syn++;
print O "#line $iline \"$f\"\n";
}
}
elsif($syn == 2) {
if(/^\~\~\~/) {
last;
}
# turn the vararg argument into vararg
$_ =~ s/, parameter\)\;/, ...);/;
print O $_;
$l++;
}
}
close(F);
close(O);
if($syn < 2) {
print STDERR "Found no synopsis in $f\n";
return 1;
}
return 0;
}
my $error;
for my $m (@files) {
$error |= extract($m);
$error |= testcompile($m);
}
exit $error;
+15
View File
@@ -0,0 +1,15 @@
#!/bin/sh
# Copyright (C) Viktor Szakats
#
# SPDX-License-Identifier: curl
set -eu
cd "$(dirname "${0}")"/../..
git ls-files '*.yaml' '*.yml' -z | xargs -0 -r \
yamllint \
--format standard \
--strict \
--config-data .github/scripts/yamlcheck.yaml \
--
+17
View File
@@ -0,0 +1,17 @@
# Copyright (C) Viktor Szakats
#
# SPDX-License-Identifier: curl
#
# Docs: https://yamllint.readthedocs.io/en/stable/configuration.html
extends: default
rules:
line-length:
max: 500
level: warning
braces: disable
commas: disable
comments: disable
document-start: disable