in vm/jitrino/src/main/PMF.cpp [1382:1720]
void PMF::init (bool first_)
{
assert(!initialized);
first = first_;
help_requested = false;
processVMProperties();
initialized = true;
#ifdef _DEBUG_PMF
cout << endl << "Commands received:" << endl;
for (Cmds::iterator it = cmds.begin(); it != cmds.end(); ++it)
{
Cmd& cmd = **it;
cout << *cmd.left << " = <" << cmd.right << "> " << endl;
}
cout << endl << "ActionFactory:" << endl;
for (IActionFactory* afp = IActionFactory::getFirst(); afp != 0; afp = afp->getNext())
cout << " " << afp->getName() << endl;
#endif
if (first && !help_requested.empty() && !(help_requested == "jit"))
showHelp(cout);
// Create common pipeline with empty filter
pipelines.push_back(new (mm) Pipeline(*this));
// Process all filter statements
FilterSpecs filterspecs(mm);
Cmd* cmdp;
for (Cmds::iterator it = cmds.begin(); it != cmds.end(); ++it)
if ((cmdp = *it) != 0 && parse(*cmdp, "filter", filterspecs))
{
*it = 0;
if (cmdp->right.empty())
cmdp->fatal("Empty filter");
if (cmdp->filtername.empty())
cmdp->fatal("Invalid filter name");
if (cmdp->filtername == jitname)
cmdp->fatal("Invalid filter name - the same as jit name");
if (filterspecs.find(cmdp->filtername) != filterspecs.end())
cmdp->fatal("Duplicate filters defined");
filterspecs[cmdp->filtername] = &cmdp->right;
}
// Process all path statements
for (Cmds::iterator it = cmds.begin(); it != cmds.end(); ++it)
if ((cmdp = *it) != 0 && parse(*cmdp, "path", filterspecs))
{
*it = 0;
if (!cmdp->filtername.empty() && filterspecs.find(cmdp->filtername) == filterspecs.end())
continue;
// Process left of '=" part
Str* namep = 0;
size_t x = cmdp->left->size() - cmdp->xkeyword - 1;
if (x == 0)
{
}
else if (x == 1)
{
Str& name = cmdp->left->at(cmdp->xkeyword + 1);
if (!name.empty())
namep = &name;
}
else
cmdp->fatal("Extra items after path name");
Pipeline* pipeline = lookup(&cmdp->filtername, true);
Pipeline::Alias* aliasp = pipeline->lookup(namep);
if (aliasp == 0)
{
aliasp = new (mm) Pipeline::Alias(mm);
if (namep == 0)
pipeline->root = aliasp;
else
aliasp->name = *namep;
pipeline->aliases->push_back(aliasp);
}
else
{
cmdp->fatal("Multiple path defined");
}
// Process right of '=" part
for (StrTokenizer tokens(',', cmdp->right); tokens.next();)
{
Pipeline::Alias::Child child;
child.aliasp = 0;
child.type = Pipeline::Alias::Child::DEFON;
if (!tokens.token.empty())
{
char x = tokens.token.ptr[tokens.token.count-1];
if (x == '!')
{
child.type = Pipeline::Alias::Child::REQUIRED;
--tokens.token.count;
}
else if (x == '+')
{
child.type = Pipeline::Alias::Child::DEFON;
--tokens.token.count;
}
else if (x == '-')
{
child.type = Pipeline::Alias::Child::DEFOFF;
--tokens.token.count;
}
tokens.token.trim();
}
if (tokens.token.empty())
cmdp->fatal("Empty path child name");
child.name = tokens.token;
aliasp->childs.push_back(child);
}
}
else if (cmdp != 0 && !cmdp->jitname.empty() && !(cmdp->jitname == jitname))
*it = 0; // not for this jit command
// Process all arg statements
for (Cmds::iterator it = cmds.begin(); it != cmds.end(); ++it)
if ((cmdp = *it) != 0 && parse(*cmdp, "arg", filterspecs))
{
cmdp->arg = true;
lookup(&cmdp->filtername, true);
}
else if (cmdp != 0 && !cmdp->jitname.empty() && !(cmdp->jitname == jitname))
*it = 0; // not for this jit command
// Path resolution
Pipeline& compipeline = **pipelines.begin(); // this is the common (empty) pipeline
if (compipeline.root == 0)
compipeline.stop("PMF: Invalid common pipeline for '%s' - does not have a root path\n");
for (Pipelines::iterator k = pipelines.begin(); k != pipelines.end(); ++k)
{
Pipeline& pipeline = **k;
Pipeline::Aliases& aliases = *pipeline.aliases;
if (&pipeline != &compipeline)
{
FilterSpecs::iterator it = filterspecs.find(pipeline.name);
if (it == filterspecs.end())
pipeline.stop("PMF: Invalid pipeline for '%s.%s' - unspecified filter\n");
pipeline.method.init(*it->second);
if (pipeline.method.empty())
pipeline.stop("PMF: Invalid pipeline for '%s.%s' - empty filter\n");
}
if (pipeline.root == 0)
{
pipeline.root = new (mm) Pipeline::Alias(mm, *compipeline.root);
aliases.push_back(pipeline.root);
}
for (;;)
{
Pipeline::Aliases newaliases(mm);
for (Pipeline::Aliases::iterator l = aliases.begin(); l != aliases.end(); ++l)
{
Pipeline::Alias::Childs::iterator end = (*l)->childs.end(),
ptr = (*l)->childs.begin();
for (; ptr != end; ++ptr)
{
ptr->aliasp = pipeline.lookup(&ptr->name);
if (ptr->aliasp == 0 && &pipeline != &compipeline)
{
Pipeline::Alias* comaliasp;
if ((comaliasp = compipeline.lookup(&ptr->name)) != 0)
newaliases.push_back(new (mm) Pipeline::Alias(mm, *comaliasp));
}
}
}
if (newaliases.empty())
break;
else
aliases.insert(aliases.end(), newaliases.begin(), newaliases.end());
}
Strs fqname(mm);
walk(pipeline, pipeline.root, fqname);
}
// Build parameters map
for (Cmds::iterator it = cmds.begin(); it != cmds.end(); ++it)
if ((cmdp = *it) != 0 && cmdp->arg)
{
size_t n = cmdp->left->size() - cmdp->xkeyword - 1;
if (n == 0)
cmdp->fatal("No argument name");
}
initStreams();
for (Pipelines::iterator k = pipelines.begin(); k != pipelines.end(); ++k)
{
Pipeline& pipeline = **k;
for (Pipeline::Steps::iterator s = pipeline.steps->begin(); s != pipeline.steps->end(); ++s)
{
Pipeline::Step& step = *s;
step.setup(mm);
}
}
// Create actions for common filter
for (Pipeline::Steps::iterator s = compipeline.steps->begin(); s != compipeline.steps->end(); ++s)
{
Pipeline::Step& step = *s;
step.action = step.factory->createAction(mm);
step.reused = false;
}
// Create actions for other filters
for (Pipelines::iterator k = pipelines.begin() + 1; k != pipelines.end(); ++k)
{
Pipeline& pipeline = **k;
for (Pipeline::Steps::iterator s = pipeline.steps->begin(); s != pipeline.steps->end(); ++s)
{
Pipeline::Step& step = *s;
step.action = 0;
step.reused = false;
// Check if this step has any filter-specific agruments
bool filterspec = false;
if (step.args != 0)
for (Args::Store::iterator m = step.args->store.begin(); m != step.args->store.end(); ++m)
if (!m->cmdp->filtername.empty())
{
filterspec = true;
break;
}
// If step doesn't have such arguments, action from common filter can be reused
if (!filterspec)
for (Pipeline::Steps::iterator m = compipeline.steps->begin(); m != compipeline.steps->end(); ++m)
if (step.factory == m->factory)
{
step.action = m->action;
step.reused = true;
break;
}
// Otherwise action is created and initiated
if (step.action == 0)
step.action = step.factory->createAction(mm);
}
}
if (help_requested == "jit" || help_requested == "all")
showHelpJits(cout);
// Debug output
#ifdef _DEBUG_PMF
cout << endl << "PMF jit<" << jitname << ">" << endl;
for (Pipelines::iterator k = pipelines.begin(); k != pipelines.end(); ++k)
{
Pipeline& pipeline = **k;
cout << " Pipeline<" << pipeline.name <<
"> method<" << pipeline.method.classname
<< "><" << pipeline.method.methodname
<< "><" << pipeline.method.signature
<< ">" << endl;
for (Pipeline::Aliases::iterator l = pipeline.aliases->begin(); l != pipeline.aliases->end(); ++l)
{
Pipeline::Alias& alias = **l;
cout << " Alias<" << alias.name << ">";
if (pipeline.root == &alias)
cout << " *root*";
cout << endl;
for (Pipeline::Alias::Childs::iterator m = alias.childs.begin(); m != alias.childs.end(); ++m)
{
Pipeline::Alias::Child& child = *m;
cout << " Child<" << child.name << "> kind:" << child.type;
if (child.aliasp!= 0)
cout << " to <" << child.aliasp->name << ">";
cout << endl;
}
}
for (Pipeline::Steps::iterator l = pipeline.steps->begin(); l != pipeline.steps->end(); ++l)
{
Pipeline::Step& step = *l;
cout << " Step <" << *step.fqname
<< "> action <" << step.factory->getName()
<< "> reused:" << step.reused
<< endl;
if (step.args != 0)
for (Args::Store::iterator m = step.args->store.begin(); m != step.args->store.end(); ++m)
{
Args::Arg& arg = *m;
cout << " arg <" << arg.key << "> = <" << arg.value
<< "> strength:" << arg.strength
<< endl;
}
if (step.logs != 0)
for (size_t sid = 0; sid < step.logs->streamidxs.size(); ++sid)
{
size_t idx = step.logs->streamidxs.at(sid);
cout << " sid#" << sid
<< " idx#" << idx
<< endl;
}
}
}
#endif
// Initialize commom pipeline only (others get intialized as need by PipelineIterator)
compipeline.init();
}