Index: trunk/FACT++/src/csv2root.cc
===================================================================
--- trunk/FACT++/src/csv2root.cc	(revision 19873)
+++ trunk/FACT++/src/csv2root.cc	(revision 19878)
@@ -26,5 +26,5 @@
     po::options_description control("Root to SQL");
     control.add_options()
-        ("file",           var<string>()->required(), "The csv input file")
+        ("file",           var<string>("-"),          "The csv input file. The default ('-') is reading from stdin.")
         ("out,o",          var<string>(""),           "Output root file name")
         ("force,f",        po_switch(),               "Force overwrite if output file already exists.")
@@ -34,4 +34,5 @@
         ("no-header,n",    po_switch(),               "Use if the first line contains no header")
         ("rename.*",       var<string>(),             "Can be used to rename a column")
+        ("delimiter",      var<string>(";:, \t"),     "List of possible delimiters")
         ("dry-run",        po_switch(),               "Do not create or manipulate any output file")
         ("verbose,v",      var<uint16_t>(1),          "Verbosity (0: quiet, 1: default, 2: more, 3, ...)")
@@ -148,4 +149,5 @@
 //    const bool dryrun            = conf.Get<bool>("dry-run");
     const bool noheader          = conf.Get<bool>("no-header");
+    const string delimiter       = conf.Get<string>("delimiter");
 
     const uint16_t verbose       = conf.Get<uint16_t>("verbose");
@@ -158,8 +160,9 @@
     if (out.empty())
     {
-        out = file;
+        out = file.empty() || file=="-" ? "csv2root" : file;
         const auto p = out.find_last_of('.');
         if (p!=string::npos)
-            out = string(out.substr(0, p))+".root";
+            out.erase(p);
+        out += ".root";
     }
 
@@ -179,5 +182,7 @@
     cout << "Reading from '" << file << "'.\n";
 
-    ifstream fin(file.c_str());
+    ifstream ifs(file.c_str());
+
+    istream &fin = file=="-" ? cin : ifs;
     if (!fin.good())
     {
@@ -195,5 +200,5 @@
 
     buf = buf.Strip(TString::kBoth);
-    TObjArray *title = buf.Tokenize(" ");
+    TObjArray *title = buf.Tokenize(delimiter);
     if (title->GetEntries()==0)
     {
@@ -203,5 +208,8 @@
 
     if (title->At(0)->GetName()[0]=='#')
+    {
         title->RemoveAt(0);
+        title->Compress();
+    }
 
     const auto numcol = title->GetEntries();
@@ -280,5 +288,4 @@
         }
     }
-
     const auto rename = conf.GetWildcardOptions("rename.*");
 
@@ -293,4 +300,7 @@
         boost::regex rexpr(":");
         col = boost::regex_replace(col, rexpr, "");
+
+        if (col[0]=='.')
+            col.erase(0, 1);
 
         if (verbose>1)
@@ -333,5 +343,5 @@
             continue;
 
-        TObjArray *arr = buf.Tokenize(" ");
+        TObjArray *arr = buf.Tokenize(delimiter);
         if (arr->GetEntries()!=numcol)
         {
@@ -369,15 +379,12 @@
     for (auto it=ttree.begin(); it!=ttree.end(); it++)
     {
-        if (update)
-        {
-            TIter NextBranch((*it)->GetListOfBranches());
-            TBranch *b=0;
-            while ((b=static_cast<TBranch*>(NextBranch())))
-                if (b->GetAddress() && b->GetEntries()>0)
-                {
-                    (*it)->SetEntries(b->GetEntries());
-                    break;
-                }
-        }
+        TIter NextBranch((*it)->GetListOfBranches());
+        TBranch *b=0;
+        while ((b=static_cast<TBranch*>(NextBranch())))
+            if (b->GetAddress() && b->GetEntries()>0)
+            {
+                (*it)->SetEntries(b->GetEntries());
+                break;
+            }
 
         (*it)->Write("", TObject::kOverwrite);
