commit b20a040c701e5336d3e1c49fe116625692ee4d90 Author: Jephte Clain Date: Tue Oct 3 04:17:01 2023 +0400 importation initiale diff --git a/.composer.yaml b/.composer.yaml new file mode 100644 index 0000000..81afa48 --- /dev/null +++ b/.composer.yaml @@ -0,0 +1,10 @@ +# -*- coding: utf-8 mode: yaml -*- vim:sw=2:sts=2:et:ai:si:sta:fenc=utf-8 +composer_php_min: '7.3' +composer_php_max: '8.0' +composer_registry: pubdocker.univ-reunion.fr +composer_image: image/phpbuilder:d10 +require: +branch: + master: + develop: + wip: diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..ef72495 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +/sbin/composer.phar -delta diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..12ade08 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +/.idea/**/workspace.xml +/.idea/**/tasks.xml +/.idea/**/usage.statistics.xml +/.idea/**/dictionaries +/.idea/**/shelf +/.idea/**/contentModel.xml +/.idea/**/dataSources/ +/.idea/**/dataSources.ids +/.idea/**/dataSources.local.xml +/.idea/**/sqlDataSources.xml +/.idea/**/dynamic.xml +/.idea/**/uiDesigner.xml +/.idea/**/dbnavigator.xml +/.phpunit.result.cache + +.~lock*# +.*.swp +/vendor/ diff --git a/bin/composer b/bin/composer new file mode 120000 index 0000000..42fbf67 --- /dev/null +++ b/bin/composer @@ -0,0 +1 @@ +runphp \ No newline at end of file diff --git a/bin/runphp b/bin/runphp new file mode 100755 index 0000000..a3aa6dc --- /dev/null +++ b/bin/runphp @@ -0,0 +1,52 @@ +#!/bin/bash +# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 +MYDIR="$(dirname -- "$0")"; MYNAME="$(basename -- "$0")" +function die() { echo 1>&2 "ERROR: $*"; exit 1; } + +case "$MYNAME" in +runphp) ;; +composer) + if [ -f "$MYDIR/composer.phar" ]; then + set -- "$MYDIR/composer.phar" "$@" + elif [ -f "$MYDIR/../sbin/composer.phar" ]; then + set -- "$MYDIR/../sbin/composer.phar" "$@" + elif [ -f "/usr/bin/composer" ]; then + set -- "/usr/bin/composer" "$@" + else + set -- "" "$@" + fi + ;; +*) die "$MYNAME: nom de script invalide";; +esac + +function runphp_help() { + echo "$MYNAME: lance un programme PHP en sélectionnant une version en particulier + +USAGE + $MYNAME [options] [args...] + +OPTIONS + -s, --min PHP_MIN + -m, --max PHP_MAX + -i, --image IMAGE" +} + +SOPTS=+smi +LOPTS=help,php-min,min,php-max,max,image +args="$(getopt -n runphp -o "$SOPTS" -l "$LOPTS" -- "$@")" || exit 1; eval "set -- $args" + +while [ $# -gt 0 ]; do + case "$1" in + --) shift; break;; + --help) runphp_help; exit 0;; + *) die "$1: option non configurée";; + esac + shift +done + +script="$1"; shift +[ -n "$script" ] || die "vous devez spécifier le script à lancer" +[ -f "$script" ] || die "$script: script introuvable" + +scriptdir="$(dirname -- "$script")" +scritname="$(basename -- "$script")" diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..861793c --- /dev/null +++ b/composer.json @@ -0,0 +1,35 @@ +{ + "name": "nucore/php", + "type": "library", + "description": "fonctions et classes essentielles", + "repositories": [ + { + "type": "composer", + "url": "https://repos.univ-reunion.fr/composer" + } + ], + "require": { + "php": ">=7.3" + }, + "require-dev": { + "mur/tests": "7.3" + }, + "autoload": { + "psr-4": { + "nucore\\": "php/src_base" + } + }, + "autoload-dev": { + "psr-4": { + "nucore\\": "php/tests" + } + }, + "scripts": { + }, + "authors": [ + { + "name": "Jephte Clain", + "email": "Jephte.Clain@univ-reunion.fr" + } + ] +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..0a4d1e0 --- /dev/null +++ b/composer.lock @@ -0,0 +1,1785 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "96c185f6994b1dc8e8d6c551789bf871", + "packages": [], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.5.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^11", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.30 || ^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.5.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-12-30T00:15:36+00:00" + }, + { + "name": "mur/tests", + "version": "7.3", + "source": { + "type": "git", + "url": "https://git.univ-reunion.fr/sda-php/mur-tests.git", + "reference": "8902035bef6ddfe9864675a00844dd14872f6d13" + }, + "require": { + "php": ">=7.3", + "phpunit/phpunit": "^9" + }, + "type": "library", + "autoload": { + "psr-4": { + "mur\\tests\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "mur\\tests\\": "tests" + } + }, + "authors": [ + { + "name": "Jephte Clain", + "email": "Jephte.Clain@univ-reunion.fr" + } + ], + "description": "fonctions et classes pour les tests", + "time": "2023-10-01T11:57:55+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2023-03-08T13:26:56+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.17.1", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" + }, + "time": "2023-08-13T19:53:39+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.29", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.15", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-09-19T04:57:46+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.6.13", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f3d767f7f9e191eab4189abe41ab37797e30b1be", + "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1 || ^2", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpunit/php-code-coverage": "^9.2.28", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.8", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.5", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^3.2", + "sebastian/version": "^3.0.2" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.6-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.13" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2023-09-19T05:39:22+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T12:41:17+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:52:27+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131", + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-05-07T05:35:17+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:03:51+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T06:03:37+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bde739e7565280bda77be70044ac1047bc007e34" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bde739e7565280bda77be70044ac1047bc007e34", + "reference": "bde739e7565280bda77be70044ac1047bc007e34", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-02T09:26:13+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:07:39+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" + }, + { + "name": "sebastian/type", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:13:03+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=7.3" + }, + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/php/run-tests b/php/run-tests new file mode 100755 index 0000000..1b0c5a1 --- /dev/null +++ b/php/run-tests @@ -0,0 +1,5 @@ +#!/bin/bash +# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 +MYDIR="$(dirname -- "$0")" +VENDOR="$MYDIR/../vendor" +"$VENDOR/bin/phpunit" --bootstrap "$VENDOR/autoload.php" "$@" "$MYDIR/tests" diff --git a/php/src_base/AccessException.php b/php/src_base/AccessException.php new file mode 100644 index 0000000..540df72 --- /dev/null +++ b/php/src_base/AccessException.php @@ -0,0 +1,31 @@ +"; + } elseif (is_array($value)) { + $values = $value; + $parts = []; + foreach ($values as $value) { + $parts[] = self::value($value); + } + return "[".implode(", ", $parts)."]"; + } else { + return var_export($value, true); + } + } + + private static function message($value, ?string $message, ?string $kind, ?string $prefix, ?string $suffix): string { + if ($kind === null) $kind = "value"; + if ($message === null) $message = "$kind$suffix"; + if ($value !== null) { + $value = self::value($value); + if ($prefix) $prefix = "$prefix: $value"; + else $prefix = $value; + } + if ($prefix) $prefix = "$prefix: "; + return $prefix.$message; + } + + static final function null(?string $kind=null, ?string $prefix=null, ?string $message=null): self { + return new static(self::message(null, $message, $kind, $prefix, " is null")); + } + + static final function invalid($value=null, ?string $kind=null, ?string $prefix=null, ?string $message=null): self { + return new static(self::message($value, $message, $kind, $prefix, " is invalid")); + } + + static final function forbidden($value=null, ?string $kind=null, ?string $prefix=null, ?string $message=null): self { + return new static(self::message($value, $message, $kind, $prefix, " is forbidden")); + } +} diff --git a/php/src_base/cl.php b/php/src_base/cl.php new file mode 100644 index 0000000..e424afa --- /dev/null +++ b/php/src_base/cl.php @@ -0,0 +1,467 @@ +offsetExists($key); + } + return false; + } + + /** + * retourner $array[$key] ou $default si la clé n'existe pas + * + * @param array|ArrayAccess $array + */ + static final function get($array, $key, $default=null) { + if (is_array($array)) { + if (array_key_exists($key, $array)) return $array[$key]; + } elseif ($array instanceof ArrayAccess) { + if ($array->offsetExists($key)) return $array->offsetGet($key); + } + return $default; + } + + /** + * si $array est un array ou une instance de ArrayAccess, créer ou modifier + * l'élément dont la clé est $key + * + * @param array|ArrayAccess $array + */ + static final function set(&$array, $key, $value): void { + if (is_array($array) || $array === null) { + if ($key === null) $array[] = $value; + else $array[$key] = $value; + } elseif ($array instanceof ArrayAccess) { + $array->offsetSet($key, $value); + } + } + + /** + * si $array est un array ou une instance de ArrayAccess, supprimer l'élément + * dont la clé est $key + * + * @param array|ArrayAccess $array + */ + static final function del(&$array, $key): void { + if (is_array($array)) { + unset($array[$key]); + } elseif ($array instanceof ArrayAccess) { + $array->offsetUnset($key); + } + } + + /** retourner le nombre d'éléments de $array */ + static final function count(?array $array): int { + return $array !== null? count($array): 0; + } + + /** retourner la liste des clés de $array */ + static final function keys(?array $array): array { + return $array !== null? array_keys($array): []; + } + + ############################################################################# + + /** + * Fusionner tous les tableaux spécifiés. Les valeurs null sont ignorées. + * Retourner null si aucun tableau n'est fourni ou s'ils étaient tous null. + */ + static final function merge(...$arrays): ?array { + $merges = []; + foreach ($arrays as $array) { + self::ensure_narray($array); + if ($array !== null) $merges[] = $array; + } + return $merges? array_merge(...$merges): null; + } + + ############################################################################# + + /** + * vérifier que le chemin $keys existe dans le tableau $array + * + * si $keys est vide ou null, retourner true + */ + static final function phas($array, $pkey): bool { + if ($pkey !== null && !is_array($pkey)) { + $pkey = explode(".", strval($pkey)); + } + if ($pkey === null || $pkey === []) return true; + $first = true; + foreach($pkey as $key) { + if ($key === "" && $first) { + # une chaine vide en première position est ignorée + continue; + } elseif (is_array($array)) { + if (!array_key_exists($key, $array)) return false; + $array = $array[$key]; + } elseif ($array instanceof ArrayAccess) { + if (!$array->offsetExists($key)) return false; + $array = $array->offsetGet($key); + } else { + return false; + } + $first = false; + } + return true; + } + + static final function each_phas($array, ?array $pkeys): array { + $result = []; + if ($pkeys !== null) { + foreach ($pkeys as $pkey) { + $result[] = self::phas($array, $pkey); + } + } + return $result; + } + + /** + * obtenir la valeur correspondant au chemin $keys dans $array + * + * si $keys est vide ou null, retourner $default + */ + static final function pget($array, $pkey, $default=null) { + if ($pkey !== null && !is_array($pkey)) { + $pkey = explode(".", strval($pkey)); + } + if ($pkey === null || $pkey === []) return true; + $value = $array; + $first = true; + foreach($pkey as $key) { + if ($key === "" && $first) { + # une chaine vide en première position est ignorée + continue; + } elseif (is_array($value)) { + if (!array_key_exists($key, $value)) return $default; + $value = $value[$key]; + } elseif ($value instanceof ArrayAccess) { + if (!$value->offsetExists($key)) return $default; + $value = $value->offsetGet($key); + } else { + return $default; + } + $first = false; + } + return $value; + } + + static final function each_pget($array, ?array $pkeys): array { + $result = []; + if ($pkeys !== null) { + foreach ($pkeys as $key => $pkey) { + $result[$key] = self::pget($array, $pkey); + } + } + return $result; + } + + /** + * modifier la valeur au chemin de clé $keys dans le tableau $array + * + * utiliser la clé "" (chaine vide) en dernière position pour rajouter à la fin, e.g + * - _pset($array, [""], $value) est équivalent à $array[] = $value + * - _pset($array, ["a", "b", ""], $value) est équivalent à $array["a"]["b"][] = $value + * la clé "" n'a pas de propriété particulière quand elle n'est pas en dernière position + * + * si $keys est vide ou null, $array est remplacé par $value + */ + static final function pset(&$array, $pkey, $value): void { + if ($pkey !== null && !is_array($pkey)) { + $pkey = explode(".", strval($pkey)); + } + if ($pkey === null || $pkey === []) { + $array = $value; + return; + } + self::ensure_array($array); + $current =& $array; + $key = null; + $last = count($pkey) - 1; + $i = 0; + foreach ($pkey as $key) { + if ($i == $last) break; + if ($current instanceof ArrayAccess) { + if (!$current->offsetExists($key)) $current->offsetSet($key, []); + $current =& $current->offsetGet($key); + if ($current === null) { + $current = []; + } elseif (!is_array($current) && !($current instanceof ArrayAccess)) { + $current = [$current]; + } + } else { + self::ensure_array($current[$key]); + $current =& $current[$key]; + } + $i++; + } + if ($key === "") $current[] = $value; + else $current[$key] = $value; + } + + static final function each_pset(&$array, ?array $values): void { + if ($values !== null) { + foreach ($values as $pkey => $value) { + self::pset($array, $pkey, $value); + } + } + } + + /** + * supprimer la valeur au chemin $keys fourni sous forme de tableau + */ + static final function pdel_a(&$array, ?array $pkey): void { + } + + /** + * supprimer la valeur au chemin de clé $keys dans $array + * + * si $array vaut null ou false, sa valeur est inchangée. + * si $keys est vide ou null, $array devient null + */ + static final function pdel(&$array, $pkey): void { + if ($array === false || $array === null) return; + if ($pkey !== null && !is_array($pkey)) { + $pkey = explode(".", strval($pkey)); + } + if ($pkey === null || $pkey === []) { + $array = null; + return; + } + self::ensure_array($array); + $current =& $array; + $key = null; + $last = count($pkey) - 1; + $i = 0; + foreach ($pkey as $key) { + if ($i == $last) break; + if ($current instanceof ArrayAccess) { + if (!$current->offsetExists($key)) break; + } elseif (is_array($current)) { + if (!array_key_exists($key, $current)) break; + } else { + break; + } + $current =& $current[$key]; + $i++; + } + if ($i == $last) { + if ($current instanceof ArrayAccess) { + $current->offsetUnset($key); + } elseif (is_array($current)) { + unset($current[$key]); + } + } + } + + static final function each_pdel(&$array, ?array $pkeys): void { + if ($pkeys !== null) { + foreach ($pkeys as $pkey) { + self::pdel($array, $pkey); + } + } + } + + ############################################################################# + + /** + * retourner le tableau $array en "renommant" les clés selon le tableau + * $mappings qui contient des associations de la forme [$from => $to] + */ + static function rekey(?array $array, ?array $mappings): ?array { + if ($array === null || $mappings === null) return $array; + $mapped = []; + foreach ($array as $key => $value) { + if (array_key_exists($key, $mappings)) $key = $mappings[$key]; + $mapped[$key] = $value; + } + return $mapped; + } + + ############################################################################# + + /** tester si tous les éléments du tableau satisfont la condition */ + static final function all_if(?array $array, callable $cond): bool { + if ($array !== null) { + foreach ($array as $value) { + if (!$cond($value)) return false; + } + } + return true; + } + + static final function all_z(?array $array): bool { return self::all_if($array, [cv::class, "z"]);} + static final function all_nz(?array $array): bool { return self::all_if($array, [cv::class, "nz"]);} + static final function all_n(?array $array): bool { return self::all_if($array, [cv::class, "n"]);} + static final function all_nn(?array $array): bool { return self::all_if($array, [cv::class, "nn"]);} + static final function all_t(?array $array): bool { return self::all_if($array, [cv::class, "t"]);} + static final function all_f(?array $array): bool { return self::all_if($array, [cv::class, "f"]);} + static final function all_pt(?array $array): bool { return self::all_if($array, [cv::class, "pt"]);} + static final function all_pf(?array $array): bool { return self::all_if($array, [cv::class, "pf"]);} + static final function all_equals(?array $array, $value): bool { return self::all_if($array, cv::equals($value)); } + static final function all_not_equals(?array $array, $value): bool { return self::all_if($array, cv::not_equals($value)); } + static final function all_same(?array $array, $value): bool { return self::all_if($array, cv::same($value)); } + static final function all_not_same(?array $array, $value): bool { return self::all_if($array, cv::not_same($value)); } + + #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** tester si au moins un élément du tableau satisfait la condition */ + static final function any_if(?array $array, callable $cond): bool { + if ($array !== null) { + foreach ($array as $value) { + if ($cond($value)) return true; + } + } + return false; + } + + static final function any_z(?array $array): bool { return self::any_if($array, [cv::class, "z"]);} + static final function any_nz(?array $array): bool { return self::any_if($array, [cv::class, "nz"]);} + static final function any_n(?array $array): bool { return self::any_if($array, [cv::class, "n"]);} + static final function any_nn(?array $array): bool { return self::any_if($array, [cv::class, "nn"]);} + static final function any_t(?array $array): bool { return self::any_if($array, [cv::class, "t"]);} + static final function any_f(?array $array): bool { return self::any_if($array, [cv::class, "f"]);} + static final function any_pt(?array $array): bool { return self::any_if($array, [cv::class, "pt"]);} + static final function any_pf(?array $array): bool { return self::any_if($array, [cv::class, "pf"]);} + static final function any_equals(?array $array, $value): bool { return self::any_if($array, cv::equals($value)); } + static final function any_not_equals(?array $array, $value): bool { return self::any_if($array, cv::not_equals($value)); } + static final function any_same(?array $array, $value): bool { return self::any_if($array, cv::same($value)); } + static final function any_not_same(?array $array, $value): bool { return self::any_if($array, cv::not_same($value)); } + + #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + static final function filter_if(?array $array, callable $cond): ?array { + if ($array === null) return null; + $filtered = []; + $index = 0; + foreach ($array as $key => $value) { + if (!$cond($value)) { + if ($key === $index) { + $index++; + $filtered[] = $value; + } else { + $filtered[$key] = $value; + } + } elseif ($key === $index) { + $index++; + } + } + return $filtered; + } + + static final function filter_z(?array $array): ?array { return self::filter_if($array, [cv::class, "z"]);} + static final function filter_nz(?array $array): ?array { return self::filter_if($array, [cv::class, "nz"]);} + static final function filter_n(?array $array): ?array { return self::filter_if($array, [cv::class, "n"]);} + static final function filter_nn(?array $array): ?array { return self::filter_if($array, [cv::class, "nn"]);} + static final function filter_t(?array $array): ?array { return self::filter_if($array, [cv::class, "t"]);} + static final function filter_f(?array $array): ?array { return self::filter_if($array, [cv::class, "f"]);} + static final function filter_pt(?array $array): ?array { return self::filter_if($array, [cv::class, "pt"]);} + static final function filter_pf(?array $array): ?array { return self::filter_if($array, [cv::class, "pf"]);} + static final function filter_equals(?array $array, $value): ?array { return self::filter_if($array, cv::equals($value)); } + static final function filter_not_equals(?array $array, $value): ?array { return self::filter_if($array, cv::not_equals($value)); } + static final function filter_same(?array $array, $value): ?array { return self::filter_if($array, cv::same($value)); } + static final function filter_not_same(?array $array, $value): ?array { return self::filter_if($array, cv::not_same($value)); } + + ############################################################################# + + static final function sorted(?array $array, int $flags=SORT_REGULAR, bool $assoc=false): ?array { + if ($array === null) return null; + if ($assoc) asort($array, $flags); + else sort($array, $flags); + return $array; + } + + static final function ksorted(?array $array, int $flags=SORT_REGULAR): ?array { + if ($array === null) return null; + ksort($array, $flags); + return $array; + } + + /** + * retourner une fonction permettant de trier un tableau sur les clés + * spécifiées. + * + * - les clés ayant le préfixe '+' ou le suffixe '|asc' indiquent un tri + * ascendant + * - les clés ayant le préfixe '-' ou le suffixe '|desc' indiquent un tri + * descendant + * - sinon, par défaut, le tri est ascendant + */ + static final function compare(array $keys): callable { + return function ($a, $b) use ($keys) { + foreach ($keys as $key) { + if (cstr::del_prefix($key, "+")) $w = 1; + elseif (cstr::del_prefix($key, "-")) $w = -1; + elseif (cstr::del_suffix($key, "|asc")) $w = 1; + elseif (cstr::del_suffix($key, "|desc")) $w = -1; + else $w = 1; + if ($c = $w * cv::compare(cl::get($a, $key), cl::get($b, $key))) { + return $c; + } + } + return 0; + }; + } + + static final function usorted(?array $array, array $keys, bool $assoc=false): ?array { + if ($array === null) return null; + if ($assoc) uasort($array, self::compare($keys)); + else usort($array, self::compare($keys)); + return $array; + } +} diff --git a/php/src_base/cstr.php b/php/src_base/cstr.php new file mode 100644 index 0000000..eb35183 --- /dev/null +++ b/php/src_base/cstr.php @@ -0,0 +1,367 @@ + $length) { + if ($ellips && $length > 3) $s = substr($s, 0, $length - 3)."..."; + else $s = substr($s, 0, $length); + } + if ($suffix !== null) $s .= $suffix; + return $s; + } + + /** trimmer $s */ + static final function trim(?string $s): ?string { + if ($s === null) return null; + else return trim($s); + } + + /** trimmer $s à gauche */ + static final function ltrim(?string $s): ?string { + if ($s === null) return null; + else return ltrim($s); + } + + /** trimmer $s à droite */ + static final function rtrim(?string $s): ?string { + if ($s === null) return null; + else return rtrim($s); + } + + static final function lower(?string $s): ?string { + if ($s === null) return null; + else return strtolower($s); + } + + static final function lower1(?string $s): ?string { + if ($s === null) return null; + else return lcfirst($s); + } + + static final function upper(?string $s): ?string { + if ($s === null) return null; + else return strtoupper($s); + } + + static final function upper1(?string $s): ?string { + if ($s === null) return null; + else return ucfirst($s); + } + + static final function upperw(?string $s, ?string $delimiters=null): ?string { + if ($s === null) return null; + if ($delimiters !== null) return ucwords($s, $delimiters); + else return ucwords($s, " _-\t\r\n\f\v"); + } + + protected static final function _starts_with(string $prefix, string $s, ?int $min_len=null): bool { + if ($prefix === $s) return true; + $len = strlen($prefix); + if ($min_len !== null && ($len < $min_len || $len > strlen($s))) return false; + return $len == 0 || $prefix === substr($s, 0, $len); + } + + /** + * tester si $s commence par $prefix + * par exemple: + * - starts_with("", "whatever") est true + * - starts_with("fi", "first") est true + * - starts_with("no", "yes") est false + * + * si $min_len n'est pas null, c'est la longueur minimum requise de $prefix + * pour qu'on teste la correspondance. dans le cas contraire, la valeur de + * retour est toujours false, sauf s'il y a égalité. e.g + * - starts_with("a", "abc", 2) est false + * - starts_with("a", "a", 2) est true + */ + static final function starts_with(?string $prefix, ?string $s, ?int $min_len=null): bool { + if ($s === null || $prefix === null) return false; + else return self::_starts_with($prefix, $s, $min_len); + } + + /** Retourner $s sans le préfixe $prefix s'il existe */ + static final function without_prefix(?string $prefix, ?string $s): ?string { + if ($s === null || $prefix === null) return $s; + if (self::_starts_with($prefix, $s)) $s = substr($s, strlen($prefix)); + return $s; + } + + /** + * modifier $s en place pour supprimer le préfixe $prefix s'il existe + * + * retourner true si le préfixe a été enlevé. + */ + static final function del_prefix(?string &$s, ?string $prefix): bool { + if ($s === null || !self::_starts_with($prefix, $s)) return false; + $s = self::without_prefix($prefix, $s); + return true; + } + + /** + * Retourner $s avec le préfixe $prefix + * + * Si $unless_exists, ne pas ajouter le préfixe s'il existe déjà + */ + static final function with_prefix(?string $prefix, ?string $s, ?string $sep=null, bool $unless_exists=false): ?string { + if ($s === null || $prefix === null) return $s; + if (!self::_starts_with($prefix, $s) || !$unless_exists) $s = $prefix.$sep.$s; + return $s; + } + + /** + * modifier $s en place pour ajouter le préfixe $prefix + * + * retourner true si le préfixe a été ajouté. + */ + static final function add_prefix(?string &$s, ?string $prefix, bool $unless_exists=true): bool { + if (($s === null || self::_starts_with($prefix, $s)) && $unless_exists) return false; + $s = self::with_prefix($prefix, $s, null, $unless_exists); + return true; + } + + protected static final function _ends_with(string $suffix, string $s, ?int $min_len=null): bool { + if ($suffix === $s) return true; + $len = strlen($suffix); + if ($min_len !== null && ($len < $min_len || $len > strlen($s))) return false; + return $len == 0 || $suffix === substr($s, -$len); + } + + /** + * tester si $string se termine par $suffix + * par exemple: + * - ends_with("", "whatever") est true + * - ends_with("st", "first") est true + * - ends_with("no", "yes") est false + * + * si $min_len n'est pas null, c'est la longueur minimum requise de $prefix + * pour qu'on teste la correspondance. dans le cas contraire, la valeur de + * retour est toujours false, sauf s'il y a égalité. e.g + * - ends_with("c", "abc", 2) est false + * - ends_with("c", "c", 2) est true + */ + static final function ends_with(?string $suffix, ?string $s, ?int $min_len=null): bool { + if ($s === null || $suffix === null) return false; + else return self::_ends_with($suffix, $s, $min_len); + } + + /** Retourner $s sans le suffixe $suffix s'il existe */ + static final function without_suffix(?string $suffix, ?string $s): ?string { + if ($s === null || $suffix === null) return $s; + if (self::_ends_with($suffix, $s)) $s = substr($s, 0, -strlen($suffix)); + return $s; + } + + /** + * modifier $s en place pour supprimer le suffixe $suffix s'il existe + * + * retourner true si le suffixe a été enlevé. + */ + static final function del_suffix(?string &$s, ?string $suffix): bool { + if ($s === null || !self::_ends_with($suffix, $s)) return false; + $s = self::without_suffix($suffix, $s); + return true; + } + + /** + * Retourner $s avec le suffixe $suffix + * + * Si $unless_exists, ne pas ajouter le suffixe s'il existe déjà + */ + static final function with_suffix(?string $suffix, ?string $s, ?string $sep=null, bool $unless_exists=false): ?string { + if ($s === null || $suffix === null) return $s; + if (!self::_ends_with($suffix, $s) || !$unless_exists) $s = $s.$sep.$suffix; + return $s; + } + + /** + * modifier $s en place pour ajouter le suffixe $suffix + * + * retourner true si le suffixe a été ajouté. + */ + static final function add_suffix(?string &$s, ?string $suffix, bool $unless_exists=true): bool { + if (($s === null || self::_ends_with($suffix, $s)) && $unless_exists) return false; + $s = self::with_suffix($suffix, $s, null, $unless_exists); + return true; + } + + /** splitter $s en deux chaines séparées par $sep */ + static final function split_pair(?string $s, string $sep=":"): array { + if ($s === null) return [null, null]; + $parts = explode($sep, $s, 2); + if ($parts === false) return [null, null]; + if (count($parts) < 2) $parts[] = null; + return $parts; + } + + /** retourner $line sans son caractère de fin de ligne */ + static final function strip_nl(?string $line): ?string { + if ($line === null) return null; + if (substr($line, -2) == "\r\n") { + $line = substr($line, 0, -2); + } elseif (substr($line, -1) == "\n") { + $line = substr($line, 0, -1); + } elseif (substr($line, -1) == "\r") { + $line = substr($line, 0, -1); + } + return $line; + } + + /** + * normaliser le caractère de fin de ligne: tous les occurrences de [CR]LF et CR sont remplacées par LF + */ + static final function norm_nl(?string $s): ?string { + if ($s === null) return null; + $s = str_replace("\r\n", "\n", $s); + $s = str_replace("\r", "\n", $s); + return $s; + } + + /** + * joindre les éléments de $parts comme avec implode(), mais en ignorant les + * valeurs fausses (cela n'inclue pas la chaine "0") + * + * pour chaque valeur du tableau avec une clé associative, c'est la clé qui + * est utilisée mais uniquement si la valeur est vraie + */ + static final function join(string $glue, ?array $values): ?string { + if ($values === null) return null; + $pieces = []; + $index = 0; + foreach ($values as $key => $value) { + if (is_array($value)) $value = self::join($glue, $value); + if ($key === $index) { + $index++; + if (cv::t($value)) $pieces[] = $value; + } elseif (cv::t($value)) { + $pieces[] = $key; + } + } + return implode($glue, $pieces); + } + + /** + * comme {@link join()} mais en ignorant les valeurs fausses selon les règles + * de PHP + */ + static final function pjoin(string $glue, ?array $values): ?string { + if ($values === null) return null; + $pieces = []; + $index = 0; + foreach ($values as $key => $value) { + if (is_array($value)) $value = self::join($glue, $value); + if ($key === $index) { + $index++; + if ($value) $pieces[] = $value; + } elseif ($value) { + $pieces[] = $key; + } + } + return implode($glue, $pieces); + } + + const CAMEL_PATTERN0 = '/([A-Z0-9]+)$/A'; + const CAMEL_PATTERN1 = '/([A-Z0-9]+)[A-Z]/A'; + const CAMEL_PATTERN2 = '/([^A-Z]+)/A'; + const CAMEL_PATTERN3 = '/([A-Z][^A-Z]*)/A'; + + /** + * convertir une chaine de la forme "camelCase" en "under_score". le premier + * ensemble de caractères en majuscule est considéré comme étant en minuscule + * + * par exemple: + * - 'myCamelCase' devient 'my_camel_case' + * - 'AValue' devient 'a_value' + * - 'UPPERValue' devient 'upper_value' + * - 'UPPER' devient 'upper' + * - 'aXYZ' devient 'a_x_y_z' + * + * $delimiter est le séparateur en sortie ('_' par défaut) + * $upper indique s'il faut transformer le résultat en majuscule + */ + static final function camel2us(?string $camel, bool $upper=false, string $delimiter="_"): ?string { + if ($camel === null || $camel === "") return $camel; + $parts = []; + if (preg_match(self::CAMEL_PATTERN0, $camel, $vs, PREG_OFFSET_CAPTURE)) { + # que des majuscules + } elseif (preg_match(self::CAMEL_PATTERN1, $camel, $vs, PREG_OFFSET_CAPTURE)) { + # préfixe en majuscule + } elseif (preg_match(self::CAMEL_PATTERN2, $camel, $vs, PREG_OFFSET_CAPTURE)) { + # préfixe en minuscule + } else { + throw ValueException::invalid($camel, "camel string"); + } + $parts[] = strtolower($vs[1][0]); + $index = intval($vs[1][1]) + strlen($vs[1][0]); + while (preg_match(self::CAMEL_PATTERN3, $camel, $vs, PREG_OFFSET_CAPTURE, $index)) { + $parts[] = strtolower($vs[1][0]); + $index = intval($vs[1][1]) + strlen($vs[1][0]); + } + $us = implode($delimiter, $parts); + if ($upper) $us = strtoupper($us); + return $us; + } + + const US_PATTERN = '/([ _\-\t\r\n\f\v])/'; + + /** + * convertir une chaine de la forme "under_score" en "camelCase" + * + * par exemple, 'my_camel_case' devient 'myCamelCalse' + * et 'UPPER_VALUE' devient 'upperValue' + * + * si la chaine de départ ne contient pas de delimiter, e.g 'myValue', elle + * est retournée inchangée + */ + static final function us2camel(?string $us, ?string $delimiters=null): ?string { + if ($us === null || $us === "") return $us; + if ($delimiters === null) $pattern = self::US_PATTERN; + else $pattern = '/(['.preg_quote($delimiters).'])/'; + $parts = preg_split($pattern, $us); + $count = count($parts); + if ($count == 1) return $us; + for ($i = 0; $i < $count; $i++) { + $part = strtolower($parts[$i]); + if ($i > 0) $part = ucfirst($part); + $parts[$i] = $part; + } + return implode("", $parts); + } +} diff --git a/php/src_base/cv.php b/php/src_base/cv.php new file mode 100644 index 0000000..d96a440 --- /dev/null +++ b/php/src_base/cv.php @@ -0,0 +1,216 @@ + $b) return 1; + return 0; + } +} diff --git a/php/tests/cstrTest.php b/php/tests/cstrTest.php new file mode 100644 index 0000000..3af2838 --- /dev/null +++ b/php/tests/cstrTest.php @@ -0,0 +1,56 @@ +