2025-02-24 19:22:01 +03:00
|
|
|
<?php
|
|
|
|
namespace taskman;
|
|
|
|
use Exception;
|
|
|
|
|
|
|
|
class ConfigParseResult
|
|
|
|
{
|
|
|
|
public int $error = 0;
|
|
|
|
public string $error_descr;
|
|
|
|
public string $normalized_jzon = '';
|
|
|
|
public array $parsed_arr;
|
|
|
|
public int $parser_type;
|
|
|
|
public $jsm_module;
|
|
|
|
}
|
|
|
|
|
|
|
|
function config_parse(array $base_dirs, string $file) : ConfigParseResult
|
|
|
|
{
|
|
|
|
$res = new ConfigParseResult();
|
|
|
|
|
|
|
|
$normalized_jzon = '';
|
|
|
|
try
|
|
|
|
{
|
|
|
|
$jsm = new \JSM($base_dirs, $file);
|
|
|
|
list($normalized_jzon, $jsm_module) = $jsm->process();
|
|
|
|
$res->normalized_jzon = $normalized_jzon;
|
|
|
|
$res->jsm_module = $jsm_module;
|
|
|
|
}
|
|
|
|
catch(Exception $e)
|
|
|
|
{
|
|
|
|
$res->error = 1;
|
2025-02-25 18:05:12 +03:00
|
|
|
$res->error_descr = $e->getMessage() . "\n" . $e->getTraceAsString();
|
2025-02-24 19:22:01 +03:00
|
|
|
return $res;
|
|
|
|
}
|
|
|
|
|
|
|
|
$decode_res = config_check_and_decode_jzon($normalized_jzon);
|
|
|
|
|
|
|
|
if($decode_res[0] === 0)
|
|
|
|
{
|
|
|
|
$res->parsed_arr = $decode_res[2];
|
|
|
|
$res->parser_type = $decode_res[3];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$res->error = $decode_res[0];
|
2025-02-25 20:04:47 +03:00
|
|
|
$res->error_descr = $decode_res[1];
|
2025-02-24 19:22:01 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return $res;
|
|
|
|
}
|
|
|
|
|
|
|
|
function config_check_and_decode_jzon(string $json) : array
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2025-02-25 13:48:24 +03:00
|
|
|
$parser = 0;
|
2025-02-24 19:22:01 +03:00
|
|
|
$arr = \jzon_parse($json, $parser);
|
|
|
|
return array(0, "", $arr, $parser);
|
|
|
|
}
|
|
|
|
catch(Exception $e)
|
|
|
|
{
|
|
|
|
return array(1, $e->getMessage(), array(), 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function config_get_header(string $file, ?int &$conf_id, ?string &$strid, bool $use_cache = true) : bool
|
|
|
|
{
|
|
|
|
static $cache = array();
|
|
|
|
if($use_cache && isset($cache[$file]))
|
|
|
|
{
|
|
|
|
list($conf_id, $strid) = $cache[$file];
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
$h = fopen($file, "r");
|
|
|
|
$line = fgets($h, 256);
|
|
|
|
fclose($h);
|
|
|
|
|
|
|
|
//TODO: rewrite it without regex usage
|
|
|
|
if(preg_match('~\{\s*/\*\s*proto_id\s*=\s*(\d+)\s*;\s*alias\s*=\s*([^\s]+)~', $line, $matches))
|
|
|
|
{
|
|
|
|
$conf_id = (int)$matches[1];
|
|
|
|
$strid = $matches[2];
|
|
|
|
if($use_cache)
|
|
|
|
$cache[$file] = array($conf_id, $strid);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function config_set_header(string $contents, int $conf_id, string $strid, bool &$is_success) : string
|
|
|
|
{
|
|
|
|
$contents = preg_replace('~\s*\{~', "{ /* proto_id = {$conf_id} ; alias = {$strid} */", $contents, 1/*limit*/, $count);
|
|
|
|
$is_success = $count == 1;
|
|
|
|
return $contents;
|
|
|
|
}
|
|
|
|
|
|
|
|
function config_replace_header(string $contents) : string
|
|
|
|
{
|
|
|
|
return preg_replace('~(\s*\{)\s*/\*\s*proto_id\s*=\s*\d+\s*;\s*alias\s*=\s*[^\s]+\s*\*/~', '$1', $contents);
|
|
|
|
}
|
|
|
|
|
|
|
|
//returns [proto_id, alias]
|
|
|
|
function config_ensure_header(string $conf_dir, string $file, bool $force = false) : array
|
|
|
|
{
|
|
|
|
if(config_get_header($file, $curr_proto_id, $curr_alias, !$force))
|
|
|
|
{
|
|
|
|
//TODO: add 'normalized' argument when we are sure both path arguments are normalized
|
|
|
|
$alias = config_file2strid($conf_dir, $file);
|
|
|
|
if($force)
|
|
|
|
$curr_proto_id = config_file2id($conf_dir, $file);
|
|
|
|
|
|
|
|
//NOTE: keeping current proto id intact if not forced
|
|
|
|
if($force || $curr_alias !== $alias)
|
|
|
|
{
|
|
|
|
$lines = file($file);
|
|
|
|
//TODO: why not using config_set_header(..) ?
|
|
|
|
$lines[0] = preg_replace(
|
|
|
|
'~\s*\{\s*/\*\s*proto_id\s*=\s*\d+\s*;\s*alias\s*=\s*[^\s]+\s*\*/~', "{ /* proto_id = {$curr_proto_id} ; alias = {$alias} */",
|
|
|
|
$lines[0],
|
|
|
|
1/*limit*/,
|
|
|
|
$count);
|
|
|
|
if($count != 1)
|
|
|
|
throw new Exception("Could not set header for '$file' in line: {$lines[0]}");
|
|
|
|
ensure_write_if_differs($file, join("", $lines));
|
|
|
|
}
|
|
|
|
|
|
|
|
return array($curr_proto_id, $alias);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$conf_id = config_file2id($conf_dir, $file);
|
|
|
|
$alias = config_file2strid($conf_dir, $file);
|
|
|
|
|
|
|
|
$lines = file($file);
|
|
|
|
|
|
|
|
$is_success = false;
|
|
|
|
$lines[0] = config_set_header($lines[0], $conf_id, $alias, $is_success);
|
|
|
|
if(!$is_success)
|
|
|
|
throw new Exception("Could not set header for '$file' in line: {$lines[0]}");
|
|
|
|
ensure_write($file, join("", $lines));
|
|
|
|
|
|
|
|
return array($conf_id, $alias);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-02-25 15:41:22 +03:00
|
|
|
function config_apply_class_normalization(array $kv_data, bool $check_junk = false) : array
|
2025-02-24 19:22:01 +03:00
|
|
|
{
|
|
|
|
$class = $kv_data['class'];
|
|
|
|
$norm_data = array();
|
2025-02-25 15:41:22 +03:00
|
|
|
unset($kv_data['class']);
|
|
|
|
call_user_func_array([$class, 'normalize'],
|
|
|
|
array(&$kv_data, &$norm_data, true, $check_junk));
|
2025-02-24 19:22:01 +03:00
|
|
|
return array($class, $class::CLASS_ID, $norm_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
//returns array<ref, number>
|
|
|
|
function config_content_match_refs(string $src) : array
|
|
|
|
{
|
|
|
|
$refs = array();
|
|
|
|
|
|
|
|
if(strpos($src, '@') === false)
|
|
|
|
return $refs;
|
|
|
|
|
|
|
|
if(preg_match_all('~"(@[^"]+)"~', $src, $matches))
|
|
|
|
{
|
|
|
|
foreach($matches[1] as $ref)
|
|
|
|
{
|
|
|
|
if(!isset($refs[$ref]))
|
|
|
|
$refs[$ref] = 1;
|
|
|
|
++$refs[$ref];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $refs;
|
|
|
|
}
|
|
|
|
|