JSM now supports an array of base dirs
This commit is contained in:
parent
0b75d8404a
commit
e5507303cd
|
@ -0,0 +1 @@
|
||||||
|
tags
|
109
jsm.inc.php
109
jsm.inc.php
|
@ -6,7 +6,7 @@ class JSM
|
||||||
static private $modules = array();
|
static private $modules = array();
|
||||||
static private $consts = array();
|
static private $consts = array();
|
||||||
|
|
||||||
private $base_dir;
|
private $base_dirs = array();
|
||||||
private $file;
|
private $file;
|
||||||
private $scope_vars = array(array());
|
private $scope_vars = array(array());
|
||||||
private $includes = array();
|
private $includes = array();
|
||||||
|
@ -16,12 +16,17 @@ class JSM
|
||||||
private $cur_modules = array();
|
private $cur_modules = array();
|
||||||
private $args_parser;
|
private $args_parser;
|
||||||
|
|
||||||
function __construct($base_dir, $file)
|
function __construct($base_dirs/*can be a string for BC*/, $file)
|
||||||
{
|
{
|
||||||
//for rand constants
|
//for rand constants
|
||||||
mt_srand();
|
mt_srand();
|
||||||
|
|
||||||
$this->base_dir = rtrim(jsm_normalize_path($base_dir, true/*nix*/), '/');
|
if(is_string($base_dirs))
|
||||||
|
$base_dirs = array($base_dirs);
|
||||||
|
$this->base_dirs = array_map(
|
||||||
|
function($base_dir) { return rtrim(jsm_normalize_path($base_dir, true/*nix*/), '/'); },
|
||||||
|
$base_dirs
|
||||||
|
);
|
||||||
$this->file = $file;
|
$this->file = $file;
|
||||||
$this->args_parser = new JSM_ArgsParser();
|
$this->args_parser = new JSM_ArgsParser();
|
||||||
}
|
}
|
||||||
|
@ -261,9 +266,9 @@ class JSM
|
||||||
$full_path = realpath($curr_dir . '/' . $m[1]);
|
$full_path = realpath($curr_dir . '/' . $m[1]);
|
||||||
if(!$full_path)
|
if(!$full_path)
|
||||||
throw new Exception("Bad relative path '$m[1]'");
|
throw new Exception("Bad relative path '$m[1]'");
|
||||||
|
|
||||||
//2) now turning the path into *nix alike
|
//2) now turning the path into *nix alike
|
||||||
$full_path = jsm_normalize_path($full_path, true/*nix*/);
|
$rel_path = jsm_make_rel_path($this->base_dirs, $full_path);
|
||||||
$rel_path = ltrim(str_replace($this->base_dir, '', $full_path), '/');
|
|
||||||
|
|
||||||
return $rel_path;
|
return $rel_path;
|
||||||
}
|
}
|
||||||
|
@ -275,8 +280,7 @@ class JSM
|
||||||
if(!$full_path)
|
if(!$full_path)
|
||||||
throw new Exception("Bad relative path '$m[1]'" . ($curr_dir . '/' . $m[1]));
|
throw new Exception("Bad relative path '$m[1]'" . ($curr_dir . '/' . $m[1]));
|
||||||
|
|
||||||
$full_path = jsm_normalize_path($full_path, true/*nix*/);
|
$rel_path = jsm_make_rel_path($this->base_dirs, $full_path);
|
||||||
$rel_path = ltrim(str_replace($this->base_dir, '', $full_path), '/');
|
|
||||||
$rel_path = str_replace('.conf.js', '', $rel_path);
|
$rel_path = str_replace('.conf.js', '', $rel_path);
|
||||||
|
|
||||||
return "@$rel_path";
|
return "@$rel_path";
|
||||||
|
@ -301,11 +305,9 @@ class JSM
|
||||||
return $txt;
|
return $txt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*private */function _includesCallback(array $m, $curr_file)
|
/*private */function _includesCallback($inc_path, $curr_file)
|
||||||
{
|
{
|
||||||
$file_name = $m[1];
|
$file = jsm_resolve_inc_path($this->base_dirs, $curr_file, $inc_path);
|
||||||
$dir = ($file_name[0] == '/') ? $this->base_dir : dirname($curr_file);
|
|
||||||
$file = jsm_normalize_path($dir . '/' . $m[1]);
|
|
||||||
|
|
||||||
$cm = $this->_currentModule();
|
$cm = $this->_currentModule();
|
||||||
|
|
||||||
|
@ -355,7 +357,7 @@ class JSM
|
||||||
$self = $this;
|
$self = $this;
|
||||||
$txt = preg_replace_callback(
|
$txt = preg_replace_callback(
|
||||||
'~<%\s*INC\s*\(\s*"([^"]+)"\s*\)\s*%>~',
|
'~<%\s*INC\s*\(\s*"([^"]+)"\s*\)\s*%>~',
|
||||||
function($m) use($self, $file) { return $self->_includesCallback($m, $file); },
|
function($m) use($self, $file) { return $self->_includesCallback($m[1], $file); },
|
||||||
$txt);
|
$txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,43 +375,28 @@ class JSM
|
||||||
return strpos($file, $ext, strlen($file) - strlen($ext) - 1) !== false;
|
return strpos($file, $ext, strlen($file) - strlen($ext) - 1) !== false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function getDeps($base_dir, $file)
|
static function getDeps(array $base_dirs, $file)
|
||||||
{
|
{
|
||||||
$deps = array();
|
$deps = array();
|
||||||
self::_getDeps($base_dir, $file, $deps);
|
self::_getDeps($base_dirs, $file, $deps);
|
||||||
return $deps;
|
return $deps;
|
||||||
}
|
}
|
||||||
|
|
||||||
static private function _extractDeps($txt)
|
static private function _extractDeps($txt)
|
||||||
{
|
{
|
||||||
$dep_files = array();
|
$dep_files = array();
|
||||||
if(preg_match_all('~<%\s*((?:INC)|(?:BHL))\s*\(\s*"([^\n]+)~', $txt, $ms))
|
if(preg_match_all('~<%\s*(?:INC)\s*\(\s*"([^\n]+)~', $txt, $ms))
|
||||||
{
|
{
|
||||||
foreach($ms[1] as $idx => $type)
|
foreach($ms[1] as $raw_dep)
|
||||||
{
|
|
||||||
$raw_dep = $ms[2][$idx];
|
|
||||||
|
|
||||||
$is_bhl = $type === "BHL";
|
|
||||||
if($is_bhl)
|
|
||||||
{
|
|
||||||
$bhl_imps = explode(',', str_replace('"', '', $raw_dep));
|
|
||||||
foreach($bhl_imps as $bhl_imp)
|
|
||||||
{
|
|
||||||
if($bhl_imp)
|
|
||||||
$dep_files[$bhl_imp . '.bhl'] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
$dep_file = substr($raw_dep, 0, strpos($raw_dep, '"'));
|
$dep_file = substr($raw_dep, 0, strpos($raw_dep, '"'));
|
||||||
$dep_files[$dep_file] = false;
|
$dep_files[$dep_file] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return array_keys($dep_files);
|
||||||
return $dep_files;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static private function _getDeps($base_dir, $file, &$deps)
|
static private function _getDeps(array $base_dirs, $file, &$deps)
|
||||||
{
|
{
|
||||||
static $cache = array();
|
static $cache = array();
|
||||||
|
|
||||||
|
@ -424,31 +411,25 @@ class JSM
|
||||||
|
|
||||||
$extracted_deps = self::_extractDeps($txt);
|
$extracted_deps = self::_extractDeps($txt);
|
||||||
|
|
||||||
foreach($extracted_deps as $inc => $is_bhl)
|
foreach($extracted_deps as $inc)
|
||||||
{
|
{
|
||||||
$dir = ($inc[0] == '/') ? $base_dir : dirname($file);
|
$dep_file = jsm_resolve_inc_path($base_dirs, $file, $inc);
|
||||||
$dep_file = jsm_normalize_path($dir . "/" . $inc);
|
$local_deps[] = $dep_file;
|
||||||
$local_deps[] = array($is_bhl, $dep_file);
|
|
||||||
$cache[$file] = $local_deps;
|
$cache[$file] = $local_deps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
$local_deps = $cache[$file];
|
$local_deps = $cache[$file];
|
||||||
|
|
||||||
foreach($local_deps as $local_dep)
|
foreach($local_deps as $dep_file)
|
||||||
{
|
{
|
||||||
list($is_bhl, $dep_file) = $local_dep;
|
|
||||||
|
|
||||||
if(in_array($dep_file, $deps))
|
if(in_array($dep_file, $deps))
|
||||||
continue;
|
continue;
|
||||||
$deps[] = $dep_file;
|
$deps[] = $dep_file;
|
||||||
|
|
||||||
//NOTE: bhl deps are shallow
|
|
||||||
if(!$is_bhl)
|
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
self::_getDeps($base_dir, $dep_file, $deps);
|
self::_getDeps($base_dirs, $dep_file, $deps);
|
||||||
}
|
}
|
||||||
catch(Exception $e)
|
catch(Exception $e)
|
||||||
{
|
{
|
||||||
|
@ -456,7 +437,6 @@ class JSM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private function _extractDefNameAndArgs($full_name)
|
private function _extractDefNameAndArgs($full_name)
|
||||||
{
|
{
|
||||||
|
@ -587,6 +567,7 @@ class JSM
|
||||||
{
|
{
|
||||||
$txt = $this->_replaceVarsWithMacro($file, $txt);
|
$txt = $this->_replaceVarsWithMacro($file, $txt);
|
||||||
|
|
||||||
|
//let's exit early if there are no macro calls
|
||||||
if(strpos($txt, '<%') === false)
|
if(strpos($txt, '<%') === false)
|
||||||
{
|
{
|
||||||
$node->addChild(new JSM_TextNode($txt));
|
$node->addChild(new JSM_TextNode($txt));
|
||||||
|
@ -616,7 +597,7 @@ class JSM
|
||||||
|
|
||||||
$mcall = $this->_newCall($name);
|
$mcall = $this->_newCall($name);
|
||||||
if($mcall === null)
|
if($mcall === null)
|
||||||
throw new Exception("No node for '$name'");
|
throw new Exception("No macro for '$name'");
|
||||||
|
|
||||||
$this->_pushNode($mcall);
|
$this->_pushNode($mcall);
|
||||||
}
|
}
|
||||||
|
@ -627,7 +608,7 @@ class JSM
|
||||||
throw new Exception("Non paired macro ending");
|
throw new Exception("Non paired macro ending");
|
||||||
$tmp_node = $this->_node(false/*non strict*/);
|
$tmp_node = $this->_node(false/*non strict*/);
|
||||||
if($tmp_node == null)
|
if($tmp_node == null)
|
||||||
throw new Exception("No current node(prev. node " . $mcall->name . ")");
|
throw new Exception("No current macro (prev. " . $mcall->name . ")");
|
||||||
$tmp_node->addChild($mcall);
|
$tmp_node->addChild($mcall);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -805,7 +786,7 @@ class JSM_MacroPHPNode implements JSM_MacroNode
|
||||||
{
|
{
|
||||||
//NOTE: making sure file containing PHP macro was actually included by this file
|
//NOTE: making sure file containing PHP macro was actually included by this file
|
||||||
if(!$this->is_builtin && !$jsm->_isIncluded($this->refl->getFileName()))
|
if(!$this->is_builtin && !$jsm->_isIncluded($this->refl->getFileName()))
|
||||||
throw new Exception("Not found");
|
throw new Exception("Macro source file was not included by config file itself: ".$this->refl->getFileName());
|
||||||
|
|
||||||
$named = false;
|
$named = false;
|
||||||
$args = array();
|
$args = array();
|
||||||
|
@ -1438,6 +1419,36 @@ function jsm_normalize_path($path, $unix=null/*null means try to guess*/)
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function jsm_resolve_inc_path(array $base_dirs, $curr_file, $inc_path)
|
||||||
|
{
|
||||||
|
return jsm_normalize_path(
|
||||||
|
$inc_path[0] == '/' ?
|
||||||
|
jsm_make_full_path($base_dirs, $inc_path) :
|
||||||
|
dirname($curr_file) . '/' . $inc_path
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jsm_make_full_path(array $base_dirs, $rel_path)
|
||||||
|
{
|
||||||
|
foreach($base_dirs as $dir)
|
||||||
|
if(is_file($dir . '/' . $rel_path))
|
||||||
|
return $dir . '/' . $rel_path;
|
||||||
|
throw new Exception("No file for relative path '$rel_path'");
|
||||||
|
}
|
||||||
|
|
||||||
|
function jsm_make_rel_path(array $base_dirs, $full_path)
|
||||||
|
{
|
||||||
|
$full_path = jsm_normalize_path($full_path, true/*nix*/);
|
||||||
|
|
||||||
|
foreach($base_dirs as $base_dir)
|
||||||
|
{
|
||||||
|
$rel_path = str_replace($base_dir, '', $full_path);
|
||||||
|
if(strlen($rel_path) < strlen($full_path))
|
||||||
|
return ltrim($rel_path, '/');
|
||||||
|
}
|
||||||
|
throw new Exception("File '$full_path' not mapped to any base dir");
|
||||||
|
}
|
||||||
|
|
||||||
function jsm_eval_string(JSM $jsm, $expr_str)
|
function jsm_eval_string(JSM $jsm, $expr_str)
|
||||||
{
|
{
|
||||||
$expr = new JSM_Expr();
|
$expr = new JSM_Expr();
|
||||||
|
|
Loading…
Reference in New Issue