]> git.tdb.fi Git - r2c2.git/blobdiff - source/shoppinglist/main.cpp
Initial revision
[r2c2.git] / source / shoppinglist / main.cpp
diff --git a/source/shoppinglist/main.cpp b/source/shoppinglist/main.cpp
new file mode 100644 (file)
index 0000000..a87e2f8
--- /dev/null
@@ -0,0 +1,138 @@
+#include <fstream>
+#include <iostream>
+#include <map>
+#include <msp/core/getopt.h>
+#include <msp/parser/loader.h>
+#include <msp/parser/parser.h>
+
+using namespace std;
+using namespace Msp;
+
+class ShoppingList
+{
+public:
+       ShoppingList(int, char **);
+       void print(ostream &);
+private:
+       class InventoryLoader: public Parser::Loader
+       {
+       public:
+               InventoryLoader(ShoppingList &);
+       private:
+               ShoppingList &sl;
+
+               void track(unsigned, unsigned);
+       };
+
+       class LayoutLoader: public Parser::Loader
+       {
+       public:
+               LayoutLoader(ShoppingList &);
+       private:
+               ShoppingList &sl;
+
+               void track(unsigned);
+       };
+
+       typedef map<unsigned, unsigned> TrackMap;
+
+       TrackMap inventory;
+       TrackMap layout;
+
+       void load_inventory(const string &);
+       void load_layout(const string &);
+};
+
+int main(int argc, char **argv)
+{
+       ShoppingList sl(argc, argv);
+       sl.print(cout);
+       return 0;
+}
+
+ShoppingList::ShoppingList(int argc, char **argv)
+{
+       string inv_fn="inventory";
+       GetOpt getopt;
+       getopt.add_option('i', "inventory", inv_fn, GetOpt::REQUIRED_ARG);
+       getopt(argc,argv);
+
+       load_inventory(inv_fn);
+       load_layout(getopt.get_args().front());
+}
+
+void ShoppingList::load_inventory(const string &fn)
+{
+       ifstream in(fn.c_str());
+       Parser::Parser parser(in, fn);
+       InventoryLoader il(*this);
+       il.load(parser);
+}
+
+void ShoppingList::load_layout(const string &fn)
+{
+       ifstream in(fn.c_str());
+       Parser::Parser parser(in, fn);
+       LayoutLoader ll(*this);
+       ll.load(parser);
+}
+
+void ShoppingList::print(ostream &out)
+{
+       out<<"// Need to get:\n";
+       for(TrackMap::iterator i=layout.begin(); i!=layout.end(); ++i)
+       {
+               TrackMap::iterator j=inventory.find(i->first);
+               if(j!=inventory.end())
+               {
+                       if(j->second<i->second)
+                               out<<"track "<<i->first<<' '<<i->second-j->second<<";\n";
+               }
+               else
+                       out<<"track "<<i->first<<' '<<i->second<<";\n";
+       }
+
+       out<<"// Pre-existing:\n";
+       for(TrackMap::iterator i=layout.begin(); i!=layout.end(); ++i)
+       {
+               TrackMap::iterator j=inventory.find(i->first);
+               if(j!=inventory.end())
+                       out<<"track "<<i->first<<' '<<min(i->second,j->second)<<";\n";
+       }
+
+       out<<"// Unused:\n";
+       for(TrackMap::iterator i=inventory.begin(); i!=inventory.end(); ++i)
+       {
+               TrackMap::iterator j=layout.find(i->first);
+               if(j!=layout.end())
+               {
+                       if(j->second<i->second)
+                               out<<"track "<<i->first<<' '<<i->second-j->second<<";\n";
+               }
+               else
+                       out<<"track "<<i->first<<' '<<i->second<<";\n";
+       }
+}
+
+ShoppingList::InventoryLoader::InventoryLoader(ShoppingList &s):
+       sl(s)
+{
+       add("track", &InventoryLoader::track);
+}
+
+void ShoppingList::InventoryLoader::track(unsigned part, unsigned count)
+{
+       sl.inventory[part]+=count;
+}
+
+ShoppingList::LayoutLoader::LayoutLoader(ShoppingList &s):
+       sl(s)
+{
+       add("track", &LayoutLoader::track);
+       add("base");
+}
+
+void ShoppingList::LayoutLoader::track(unsigned part)
+{
+       ++sl.layout[part];
+}