269 lines
7.0 KiB
PHP
269 lines
7.0 KiB
PHP
<?php
|
|
namespace nulib\app\cli;
|
|
|
|
use nulib\cl;
|
|
use nulib\str;
|
|
use const true;
|
|
|
|
/**
|
|
* Class Aodefs: une liste d'objets Aodef
|
|
*/
|
|
abstract class Aolist {
|
|
function __construct(array $defs, bool $setup=true) {
|
|
$this->origDefs = $defs;
|
|
$this->initDefs($defs, $setup);
|
|
}
|
|
|
|
protected array $origDefs;
|
|
|
|
protected ?array $aomain;
|
|
protected ?array $aosections;
|
|
protected ?array $aospecials;
|
|
|
|
public ?Aodef $remainsArgdef = null;
|
|
|
|
function initDefs(array $defs, bool $setup=true): void {
|
|
$this->mergeParse($defs, $aobjects);
|
|
$this->aomain = $aobjects["main"] ?? null;
|
|
$this->aosections = $aobjects["sections"] ?? null;
|
|
$this->aospecials = $aobjects["specials"] ?? null;
|
|
if ($setup) $this->setup();
|
|
}
|
|
|
|
protected function mergeParse(array $defs, ?array &$aobjects, bool $parse=true): void {
|
|
$aobjects ??= [];
|
|
|
|
$merges = $defs["merges"] ?? null;
|
|
$merge = $defs["merge"] ?? null;
|
|
if ($merge !== null) $merges[] = $merge;
|
|
if ($merges !== null) {
|
|
foreach ($merges as $merge) {
|
|
$this->mergeParse($merge, $aobjects, false);
|
|
$this->parse($merge, $aobjects);
|
|
}
|
|
}
|
|
|
|
if ($parse) $this->parse($defs, $aobjects);
|
|
|
|
$merge = $defs["merge_after"] ?? null;
|
|
if ($merge !== null) {
|
|
$this->mergeParse($merge, $aobjects, false);
|
|
$this->parse($merge, $aobjects);
|
|
}
|
|
}
|
|
|
|
protected function parse(array $defs, array &$aobjects): void {
|
|
[$defs, $params] = cl::split_assoc($defs);
|
|
if ($defs !== null) {
|
|
$aomain =& $aobjects["main"];
|
|
foreach ($defs as $def) {
|
|
$first = $def[0] ?? null;
|
|
if ($first === "group") {
|
|
$aobject = new Aogroup($def);
|
|
} else {
|
|
$aobject = new Aodef($def);
|
|
}
|
|
$aomain[] = $aobject;
|
|
}
|
|
}
|
|
$sections = $params["sections"] ?? null;
|
|
if ($sections !== null) {
|
|
$aosections =& $aobjects["sections"];
|
|
$index = 0;
|
|
foreach ($sections as $key => $section) {
|
|
if ($key === $index) {
|
|
$index++;
|
|
$aosections[] = new Aosection($section);
|
|
} else {
|
|
/** @var Aosection $aosection */
|
|
$aosection = $aosections[$key] ?? null;
|
|
if ($aosection === null) {
|
|
$aosections[$key] = new Aosection($section);
|
|
} else {
|
|
#XXX il faut implémenter la fusion en cas de section existante
|
|
# pour le moment, la liste existante est écrasée
|
|
$aosection->initDefs($section);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
$this->parseParams($params);
|
|
}
|
|
|
|
protected function parseParams(?array $params): void {
|
|
}
|
|
|
|
function all(?array $what=null): iterable {
|
|
$returnsAodef = $what["aodef"] ?? true;
|
|
$returnsAolist = $what["aolist"] ?? false;
|
|
$returnExtends = $what["extends"] ?? false;
|
|
$withSpecials = $what["aospecials"] ?? true;
|
|
# lister les sections avant, pour que les options de la section principale
|
|
# soient prioritaires
|
|
$aosections = $this->aosections;
|
|
if ($aosections !== null) {
|
|
/** @var Aosection $aobject */
|
|
foreach ($aosections as $aosection) {
|
|
if ($returnsAolist) {
|
|
yield $aosection;
|
|
} elseif ($returnsAodef) {
|
|
yield from $aosection->all($what);
|
|
}
|
|
}
|
|
}
|
|
|
|
$aomain = $this->aomain;
|
|
if ($aomain !== null) {
|
|
/** @var Aodef $aobject */
|
|
foreach ($aomain as $aobject) {
|
|
if ($aobject instanceof Aodef) {
|
|
if ($returnsAodef) {
|
|
if ($returnExtends) {
|
|
if ($aobject->isExtends()) yield $aobject;
|
|
} else {
|
|
if (!$aobject->isExtends()) yield $aobject;
|
|
}
|
|
}
|
|
} elseif ($aobject instanceof Aolist) {
|
|
if ($returnsAolist) {
|
|
yield $aobject;
|
|
} elseif ($returnsAodef) {
|
|
yield from $aobject->all($what);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$aospecials = $this->aospecials;
|
|
if ($withSpecials && $aospecials !== null) {
|
|
/** @var Aodef $aobject */
|
|
foreach ($aospecials as $aobject) {
|
|
yield $aobject;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function filter(callable $callback): void {
|
|
$aomain = $this->aomain;
|
|
if ($aomain !== null) {
|
|
$filtered = [];
|
|
/** @var Aodef $aobject */
|
|
foreach ($aomain as $aobject) {
|
|
if ($aobject instanceof Aolist) {
|
|
$aobject->filter($callback);
|
|
}
|
|
if (call_user_func($callback, $aobject)) {
|
|
$filtered[] = $aobject;
|
|
}
|
|
}
|
|
$this->aomain = $filtered;
|
|
}
|
|
$aosections = $this->aosections;
|
|
if ($aosections !== null) {
|
|
$filtered = [];
|
|
/** @var Aosection $aosection */
|
|
foreach ($aosections as $aosection) {
|
|
$aosection->filter($callback);
|
|
if (call_user_func($callback, $aosection)) {
|
|
$filtered[] = $aosection;
|
|
}
|
|
}
|
|
$this->aosections = $filtered;
|
|
}
|
|
}
|
|
|
|
protected function setup(): void {
|
|
# calculer les options
|
|
foreach ($this->all() as $aodef) {
|
|
$aodef->setup1();
|
|
}
|
|
/** @var Aodef $aodef */
|
|
foreach ($this->all(["extends" => true]) as $aodef) {
|
|
$aodef->setup1(true, $this);
|
|
}
|
|
# ne garder que les objets non vides
|
|
$this->filter(function($aobject): bool {
|
|
if ($aobject instanceof Aodef) {
|
|
return !$aobject->isEmpty();
|
|
} elseif ($aobject instanceof Aolist) {
|
|
return !$aobject->isEmpty();
|
|
} else {
|
|
return false;
|
|
}
|
|
});
|
|
# puis calculer nombre d'arguments et actions
|
|
foreach ($this->all() as $aodef) {
|
|
$aodef->setup2();
|
|
}
|
|
}
|
|
|
|
function isEmpty(): bool {
|
|
foreach ($this->all() as $aobject) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function get(string $option): ?Aodef {
|
|
return null;
|
|
}
|
|
|
|
function actionPrintHelp(string $arg): void {
|
|
$this->printHelp([
|
|
"show_all" => $arg === "--help++",
|
|
]);
|
|
}
|
|
|
|
function printHelp(?array $what=null): void {
|
|
$show = $what["show_all"] ?? false;
|
|
if (!$show) $show = null;
|
|
|
|
$aosections = $this->aosections;
|
|
if ($aosections !== null) {
|
|
/** @var Aosection $aosection */
|
|
foreach ($aosections as $aosection) {
|
|
$aosection->printHelp(cl::merge($what, [
|
|
"show" => $show,
|
|
"prefix" => "\n",
|
|
]));
|
|
}
|
|
}
|
|
|
|
$aomain = $this->aomain;
|
|
if ($aomain !== null) {
|
|
echo "\nOPTIONS\n";
|
|
foreach ($aomain as $aobject) {
|
|
$aobject->printHelp(cl::merge($what, [
|
|
"show" => $show,
|
|
]));
|
|
}
|
|
}
|
|
}
|
|
|
|
function __toString(): string {
|
|
$items = [];
|
|
$what = [
|
|
"aodef" => true,
|
|
"aolist" => true,
|
|
];
|
|
foreach ($this->all($what) as $aobject) {
|
|
if ($aobject instanceof Aodef) {
|
|
$items[] = strval($aobject);
|
|
} elseif ($aobject instanceof Aogroup) {
|
|
$items[] = implode("\n", [
|
|
"group",
|
|
str::indent(strval($aobject)),
|
|
]);
|
|
} elseif ($aobject instanceof Aosection) {
|
|
$items[] = implode("\n", [
|
|
"section",
|
|
str::indent(strval($aobject)),
|
|
]);
|
|
} else {
|
|
$items[] = false;
|
|
}
|
|
}
|
|
return implode("\n", $items);
|
|
}
|
|
}
|