php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
sync-constants.php
Go to the documentation of this file.
1#!/usr/bin/env php
2<?php
3
10
11const CURL_DOC_FILE = 'https://curl.se/libcurl/c/symbols-in-versions.html';
12
13const SOURCE_FILE = __DIR__ . '/curl_arginfo.h';
14
16
18 'CURLOPT_PROGRESSDATA',
19 'CURLOPT_XFERINFODATA',
20 'CURLOPT_PREREQDATA',
21 'CURLOPT_DEBUGDATA',
22];
23
25 'CURLOPT_BINARYTRANSFER',
26 'CURLOPT_RETURNTRANSFER',
27 'CURLOPT_SAFE_UPLOAD',
28];
29
30const CONSTANTS_REGEX_PATTERN = '~^CURL(?:E|INFO|OPT|_VERSION|_HTTP)_[A-Z0-9_]+$~';
31
37{
41 private $values = [];
42
46 private $length = [];
47
51 private $padding = 4;
52
58 public function add(string ...$values) : void
59 {
60 $this->values[] = $values;
61
62 foreach ($values as $key => $value) {
63 $length = strlen($value);
64
65 if (isset($this->length[$key])) {
66 $this->length[$key] = max($this->length[$key], $length);
67 } else {
68 $this->length[$key] = $length;
69 }
70 }
71 }
72
76 public function __toString() : string
77 {
78 $result = '';
79
80 foreach ($this->values as $values) {
81 foreach ($values as $key => $value) {
82 if ($key !== 0) {
83 $result .= str_repeat(' ', $this->padding);
84 }
85
86 $result .= str_pad($value, $this->length[$key]);
87 }
88
89 $result .= "\n";
90 }
91
92 return $result;
93 }
94}
95
98
99$notInPHP = []; // In cURL doc, but missing from PHP
100$notInCurl = []; // In the PHP source, but not in the cURL doc
101$outdated = []; // In the PHP source, but removed before the minimum supported cURL version
102
103foreach ($curlConstants as $name => [$introduced, $deprecated, $removed]) {
105
106 if ($removed !== null) {
107 if (version_compare($removed, MIN_SUPPORTED_CURL_VERSION) <= 0) {
108 // constant removed before the minimum supported version
109 continue;
110 }
111 }
112
113 if (! $inPHP) {
114 $notInPHP[$name] = [$introduced, $removed];
115 }
116}
117
118foreach ($sourceConstants as $name) {
119 if (! isset($curlConstants[$name])) {
120 $notInCurl[] = $name;
121 continue;
122 }
123
124 $removed = $curlConstants[$name][2];
125
126 if ($removed === null) {
127 continue;
128 }
129
130 if (version_compare($removed, MIN_SUPPORTED_CURL_VERSION) <= 0) {
131 // constant removed before the minimum supported version
132 $outdated[$name] = $removed;
133 }
134}
135
136$allGood = true;
137
138if ($notInPHP) {
139 uasort($notInPHP, function($a, $b) {
140 return version_compare($a[0], $b[0]);
141 });
142
143 $table = new AsciiTable();
144 $table->add('Constant', 'Introduced', '', 'Removed', '');
145
146 foreach ($notInPHP as $name => [$introduced, $removed]) {
147 if ($removed === null) {
148 $removed = '';
149 $removedHex = '';
150 } else {
151 $removedHex = getHexVersion($removed);
152 }
153
154 $table->add($name, $introduced, getHexVersion($introduced), $removed, $removedHex);
155 }
156
157 echo "Constants missing from the PHP source:\n\n";
158 echo $table, "\n";
159
160 $allGood = false;
161}
162
163if ($notInCurl) {
164 $table = new AsciiTable();
165
166 foreach ($notInCurl as $name) {
167 $table->add($name);
168 }
169
170 echo "Constants defined in the PHP source, but absent from the cURL documentation:\n\n";
171 echo $table, "\n";
172
173 $allGood = false;
174}
175
176if ($outdated) {
177 uasort($outdated, function($a, $b) {
178 return version_compare($a, $b);
179 });
180
181 $table = new AsciiTable();
182 $table->add('Constant', 'Removed');
183
184 foreach ($outdated as $name => $version) {
185 $table->add($name, $version);
186 }
187
188 echo "Constants defined in the PHP source, but removed before the minimum supported cURL version:\n\n";
189 echo $table, "\n";
190
191 $allGood = false;
192}
193
194if ($allGood) {
195 echo "All good! Source code and cURL documentation are in sync.\n";
196}
197
208function getCurlConstants() : array
209{
211
212 // Extract the constant list from the HTML file (located in the only <pre> tag in the page)
213 preg_match('~<table>(.*?)</table>~s', $html, $matches);
214 $constantList = $matches[1];
215
225 $regexp = '@<tr><td>(?:<a href=".*?">)?(?<const>[A-Za-z0-9_]+)(?:</a>)?</td><td>(?:<a href=".*?">)?(?<added>[\d\.]+)(?:</a>)?</td><td>(?:<a href=".*?">)?(?<deprecated>[\d\.]+)?(?:</a>)?</td><td>(<a href=".*?">)?(?<removed>[\d\.]+)?(</a>)?</td></tr>@m';
226 preg_match_all($regexp, $constantList, $matches, PREG_SET_ORDER);
227
228 $constants = [];
229
230 foreach ($matches as $match) {
231 $name = $match['const'];
232 $introduced = $match['added'];
233 $deprecated = $match['deprecated'] ?? null;
234 $removed = $match['removed'] ?? null;
235
237 // not a wanted constant
238 continue;
239 }
240
241 if ($deprecated === '-') { // deprecated version can be a hyphen
242 $deprecated = null;
243 }
244
245 $constants[$name] = [$introduced, $deprecated, $removed];
246 }
247
248 return $constants;
249}
250
258function getSourceConstants() : array
259{
261
262 preg_match_all('/REGISTER_LONG_CONSTANT\‍(\"\w+\", (\w+), .+\‍)/', $source, $matches);
263
264 $constants = [];
265
266 foreach ($matches[1] as $name) {
267 if ($name === '__c') { // macro
268 continue;
269 }
270
272 // not a wanted constant
273 continue;
274 }
275
276 $constants[] = $name;
277 }
278
279 return $constants;
280}
281
293function getHexVersion(string $version) : string
294{
295 $parts = explode('.', $version);
296
297 if (count($parts) === 2) {
298 $parts[] = '0';
299 }
300
301 if (count($parts) !== 3) {
302 throw new \RuntimeException('Invalid version number: ' . $version);
303 }
304
305 $hex = '0x';
306
307 foreach ($parts as $value) {
308 if (! ctype_digit($value) || strlen($value) > 3) {
309 throw new \RuntimeException('Invalid version number: ' . $version);
310 }
311
312 $value = (int) $value;
313
314 if ($value > 255) {
315 throw new \RuntimeException('Invalid version number: ' . $version);
316 }
317
318 $value = dechex($value);
319
320 if (strlen($value) === 1) {
321 $value = '0' . $value;
322 }
323
324 $hex .= $value;
325 }
326
327 return $hex;
328}
str_repeat(string $string, int $times)
in_array(mixed $needle, array $haystack, bool $strict=false)
file_get_contents(string $filename, bool $use_include_path=false, $context=null, int $offset=0, ?int $length=null)
explode(string $separator, string $string, int $limit=PHP_INT_MAX)
version_compare(string $version1, string $version2, ?string $operator=null)
dechex(int $num)
str_pad(string $string, int $length, string $pad_string=" ", int $pad_type=STR_PAD_RIGHT)
count(Countable|array $value, int $mode=COUNT_NORMAL)
uasort(array &$array, callable $callback)
add(string ... $values)
#define max(a, b)
Definition exif.c:60
foreach(explode("\n", $input) as $line) $result
#define ctype_digit
#define PREG_SET_ORDER
Definition php_pcre.c:26
preg_match_all(string $pattern, string $subject, &$matches=null, int $flags=0, int $offset=0)
preg_match(string $pattern, string $subject, &$matches=null, int $flags=0, int $offset=0)
getSourceConstants()
const SOURCE_FILE
const IGNORED_CURL_CONSTANTS
getHexVersion(string $version)
$sourceConstants
foreach( $curlConstants as $name=>[ $introduced, $deprecated, $removed]) foreach($sourceConstants as $name) $allGood
$notInPHP
const CURL_DOC_FILE
const IGNORED_PHP_CONSTANTS
const MIN_SUPPORTED_CURL_VERSION
if($notInPHP) if( $notInCurl) if($outdated) if( $allGood) getCurlConstants()
$curlConstants
const CONSTANTS_REGEX_PATTERN
strlen(string $string)
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)