- Added (disfunctional) A3t::append_stdin method.  Disfunctional in that
  it breaks a lot of tests because they use pipes, although it works.
- Added A3t::get_overrides to extract rc:<file>.
- Added A3t::get_data_location to extract rc.data.location:<location>.
This commit is contained in:
Paul Beckingham 2014-04-13 23:53:04 -04:00
parent 70ea3fec8c
commit cf01cc4d02
2 changed files with 118 additions and 3 deletions

View file

@ -24,14 +24,25 @@
//
////////////////////////////////////////////////////////////////////////////////
#include <cmake.h>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <Context.h>
#include <A3t.h>
#include <Nibbler.h>
#include <Directory.h>
#include <main.h>
#include <text.h>
#include <util.h>
#include <i18n.h>
#ifdef FEATURE_STDIN
#include <sys/select.h>
#endif
extern Context context;
static const int minimumMatchLength = 3;
////////////////////////////////////////////////////////////////////////////////
@ -49,8 +60,10 @@ A3t::~A3t ()
}
////////////////////////////////////////////////////////////////////////////////
// char** argv --> std::vector <std::string> _args
void A3t::initialize (int argc, const char** argv)
{
// Create top-level nodes.
for (int i = 0; i < argc; ++i)
{
Tree* branch = _tree->addBranch (new Tree (format ("arg{1}", i)));
@ -60,14 +73,58 @@ void A3t::initialize (int argc, const char** argv)
}
}
////////////////////////////////////////////////////////////////////////////////
// Add an arg for every word from std::cin.
//
// echo one two -- three | task zero --> task zero one two
// 'three' is left in the input buffer.
void A3t::append_stdin ()
{
#ifdef FEATURE_STDIN
// Use 'select' to determine whether there is any std::cin content buffered
// before trying to read it, to prevent blocking.
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 1000;
fd_set fds;
FD_ZERO (&fds);
FD_SET (STDIN_FILENO, &fds);
int result = select (STDIN_FILENO + 1, &fds, NULL, NULL, &tv);
if (result && result != -1)
{
if (FD_ISSET (0, &fds))
{
int i = 0;
std::string arg;
while (std::cin >> arg)
{
// It the terminator token is found, stop reading.
if (arg == "--")
break;
Tree* branch = _tree->addBranch (new Tree (format ("stdin{1}", i++)));
branch->attribute ("raw", arg);
branch->tag ("ORIGINAL");
branch->tag ("STDIN");
branch->tag ("?");
}
}
}
#endif
}
////////////////////////////////////////////////////////////////////////////////
Tree* A3t::parse ()
{
findBinary ();
findTerminator ();
findCommand ();
/*
findFileOverride ();
findConfigOverride ();
*/
findSubstitution ();
findPattern ();
findTag ();
@ -221,6 +278,7 @@ void A3t::findCommand ()
}
////////////////////////////////////////////////////////////////////////////////
// Process 'rc:<file>' command line override.
void A3t::findFileOverride ()
{
std::vector <Tree*>::iterator i;
@ -277,6 +335,57 @@ void A3t::findConfigOverride ()
}
}
////////////////////////////////////////////////////////////////////////////////
// Look for RC and return file as a File.
void A3t::get_overrides (
std::string& home,
File& rc)
{
std::vector <Tree*>::iterator i;
for (i = _tree->_branches.begin (); i != _tree->_branches.end (); ++i)
{
if ((*i)->hasTag ("RC"))
{
rc = File ((*i)->attribute ("file"));
home = rc;
std::string::size_type last_slash = rc._data.rfind ("/");
if (last_slash != std::string::npos)
home = rc._data.substr (0, last_slash);
else
home = ".";
context.header (format (STRING_A3_ALTERNATE_RC, rc._data));
// Keep looping, because if there are multiple rc:file arguments, we
// want the last one to dominate.
}
}
}
////////////////////////////////////////////////////////////////////////////////
// Look for CONFIG data.location and return value as a Path.
void A3t::get_data_location (Path& data)
{
std::string location = context.config.get ("data.location");
if (location != "")
data = location;
std::vector <Tree*>::iterator i;
for (i = _tree->_branches.begin (); i != _tree->_branches.end (); ++i)
{
if ((*i)->hasTag ("CONFIG") &&
(*i)->attribute ("name") == "data.location")
{
data = Directory ((*i)->attribute ("value"));
context.header (format (STRING_A3_ALTERNATE_DATA, (std::string) data));
}
// Keep looping, because if there are multiple overrides, we want the last
// one to dominate.
}
}
////////////////////////////////////////////////////////////////////////////////
// /pattern/
void A3t::findPattern ()

View file

@ -27,6 +27,8 @@
#define INCLUDED_A3T
#include <Tree.h>
#include <Path.h>
#include <File.h>
#include <string>
#include <map>
@ -36,16 +38,20 @@ public:
A3t ();
~A3t ();
void initialize (int, const char**);
void append_stdin ();
Tree* parse ();
void entity (const std::string&, const std::string&);
bool canonicalize (std::string&, const std::string&, const std::string&) const;
void findFileOverride ();
void findConfigOverride ();
void get_overrides (std::string&, File&);
void get_data_location (Path&);
private:
void findBinary ();
void findTerminator ();
void findCommand ();
void findFileOverride ();
void findConfigOverride ();
void findPattern ();
void findSubstitution ();
void findTag ();
@ -67,7 +73,7 @@ private:
// TODO Convert to postfix - not necessary given parse tree?
private:
Tree* _tree;
Tree* _tree;
std::multimap <std::string, std::string> _entities;
};