g4tools  5.4.0
columns
Go to the documentation of this file.
1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
2 // See the file tools.license for terms.
3 
4 #ifndef tools_columns
5 #define tools_columns
6 
7 #include "vmanip"
8 
9 #include "forit"
10 #include "sout"
11 #include "schar"
12 
13 #ifdef TOOLS_MEM
14 #include "mem"
15 #include "S_STRING"
16 #endif
17 
18 namespace tools {
19 namespace columns {
20 
21 class tree {
22 #ifdef TOOLS_MEM
24 #endif
25 public:
26  tree(tree* a_parent,const std::string& a_dcl):m_parent(a_parent),m_dcl(a_dcl){
27 #ifdef TOOLS_MEM
28  mem::increment(s_class().c_str());
29 #endif
30  if(a_parent) a_parent->m_sub.push_back(this);
31  }
32  virtual ~tree(){
33  clear();
34 #ifdef TOOLS_MEM
35  mem::decrement(s_class().c_str());
36 #endif
37  }
38 protected:
39  tree(const tree&) {}
40  tree& operator=(const tree&) {return *this;}
41 public:
42  void clear() {
43  m_dcl.clear();
45  }
46  void dump_tree(std::ostream& a_out,const std::string& a_margin) {
47  if(m_dcl.size()) a_out << a_margin << m_dcl << std::endl;
48  {tools_vforit(tree*,m_sub,it) {
49  (*it)->dump_tree(a_out,a_margin+" ");
50  }}
51  }
52 public:
54  std::string m_dcl;
55  std::vector<tree*> m_sub;
56 };
57 
58 }}
59 
60 #include "strip"
61 
62 namespace tools {
63 namespace columns {
64 
65 class parser {
66 public:
67  parser():m_top(0,""){}
68  virtual ~parser(){m_top.clear();}
69 protected:
70  parser(const parser&):m_top(0,"") {}
71  parser& operator=(const parser&){return *this;}
72 public:
73  bool parse(const std::string& a_s){
74  m_top.clear();
75  tree* prev = &m_top;
76  {std::string s;
77  for(std::string::const_iterator it=a_s.begin();;++it) {
78  if(it==a_s.end()) {
79  if(s.size()) {
80  new tree(prev,s);
81  s.clear();
82  }
83  break;
84  } else {
85  const char& c = *it;
86  if(c==',') {
87  if(s.size()) {
88  new tree(prev,s);
89  s.clear();
90  }
91  } else if(c=='{') {
92  tree* _tree = new tree(prev,s);
93  s.clear();
94 
95  prev = _tree;
96  } else if(c=='}') {
97  if(s.size()) {
98  new tree(prev,s);
99  s.clear();
100  }
101  prev = prev->m_parent;
102  if(!prev) return false; //should not happen.
103  } else {
104  s += c;
105  }
106  }
107  }}
108  return true;
109  }
110 
111  void dump(std::ostream& a_out) {m_top.dump_tree(a_out,"");}
112 protected:
114 };
115 
116 }}
117 
118 #include "words"
119 #include "value"
120 
121 namespace tools {
122 namespace columns {
123 
124 inline void delete_columns(std::vector<value>& a_vars) {
125  tools_vforit(value,a_vars,it) {
126  if((*it).type()==value::VOID_STAR) {
127  std::vector<value>* vars =
128  (std::vector<value>*)(*it).get_void_star();
129  delete_columns(*vars);
130  delete vars;
131  }
132  }
133  a_vars.clear();
134 }
135 
136 inline void copy_columns(const std::vector<value>& a_from,std::vector<value>& a_to) {
137  std::vector<value>::const_iterator it;
138  for(it=a_from.begin();it!=a_from.end();++it) {
139  if((*it).type()==value::VOID_STAR) {
140  std::vector<value>* vars = new std::vector<value>();
141  value v((void*)vars);
142  v.set_label((*it).label());
143  a_to.push_back(v);
144  std::vector<value>* p =
145  (std::vector<value>*)(*it).get_void_star();
146  copy_columns(*p,*vars);
147  } else {
148  a_to.push_back(*it);
149  }
150  }
151 }
152 
153 inline void dump_columns(std::ostream& a_out,const std::vector<value>& a_vars,const std::string& a_margin = "") {
154  std::vector<value>::const_iterator it;
155  for(it=a_vars.begin();it!=a_vars.end();++it) {
156  if((*it).type()==value::VOID_STAR) {
157  a_out << a_margin
158  << "ITuple : " << (*it).label() << " : begin "
159  << std::endl;
160  std::vector<value>* vars = (std::vector<value>*)(*it).get_void_star();
161  dump_columns(a_out,*vars,a_margin+" ");
162  //a_out << a_margin
163  // << "ITuple : " << (*it).label() << " : end "
164  // << std::endl;
165  } else {
166  std::string stype;
167  (*it).s_type(stype);
168  std::string sval;
169  (*it).tos(sval);
170 
171  a_out << a_margin
172  << stype << " : "
173  << (*it).label() << " : "
174  << sval
175  << std::endl;
176  }
177  }
178 }
179 
180 class finder : public columns::parser {
181  typedef columns::parser parent;
182 public:
183  finder(std::ostream& a_out,const std::string& a_script)
184  :m_out(a_out)
185  ,m_script(a_script)
186  //,fSuccess(false)
187  ,m_cur_type(value::NONE)
188  {}
189  virtual ~finder() {clear();}
190 protected:
191  finder(const finder& a_from):parent(a_from),m_out(a_from.m_out){}
192  finder& operator=(const finder&){return *this;}
193 public:
194  //void setScript(const std::string& a_string) { m_script = a_string;}
195  bool find_variables() {
196  clear();
197  if(m_script.empty()) return false; //keep old version logic.
198  if(!parse(m_script)) return false;
199  //dump(m_out);
200  //analyse m_top :
201  if(!analyse(m_top,m_stack)) {clear();return false;}
202  return true;
203  }
204 
205  void result(std::vector<value>& a_vars) const {
206  a_vars.clear();
207  copy_columns(m_stack,a_vars);
208  }
209 
210  void clear() {
211  m_top.clear();
214  }
215 /*
216  const std::string& script() const { return m_script;}
217  //bool isSuccess() const { return fSuccess;}
218  std::ostream& out() const {return m_out;}
219 */
220 protected:
221  bool analyse(columns::tree& a_tree,std::vector<value>& a_stack) {
222  if(a_tree.m_dcl.empty()) { //top
223  //std::cout << "debug : dcl empty" << std::endl;
224  tools_vforit(columns::tree*,a_tree.m_sub,it) {
225  if(!analyse(*(*it),a_stack)) return false;
226  }
227  } else {
228  //std::cout << "debug : dcl not empty" << std::endl;
229  if(is_spaces(a_tree.m_dcl)) return true;
230  value* v = analyse_dcl(a_tree.m_dcl);
231  if(!v) return false;
232  //std::cout << "debug : dcl label " << v->label() << std::endl;
233  if(a_tree.m_sub.size()) {
234  if(v->type()!=value::VOID_STAR) {
235  m_out << "tools::columns::finder::analyse :"
236  << " Expect a VOID_STAR."
237  << std::endl;
238  delete v;
239  return false;
240  }
242  std::vector<value>* stk = new std::vector<value>();
243  tools_vforit(columns::tree*,a_tree.m_sub,it) {
244  if(!analyse(*(*it),*stk)) {
245  delete v;
246  return false;
247  }
248  }
249  v->set((void*)stk);
250  } else {
251  m_cur_type = v->type();
252  }
253  a_stack.push_back(*v);
254  delete v;
255  }
256  return true;
257  }
258  value* analyse_dcl(const std::string& a_s) {
259  std::vector<std::string> ws;
260  words(a_s,"=",false,ws);
261  if(ws.size()==2) { //<type> <name>=<value>
262  std::vector<std::string> swords;
263  words(ws[0]," ",false,swords);
264  if(swords.size()==2) {
265 
266  strip(swords[0]);
267  strip(swords[1]);
268 
269  if(swords[0]=="ITuple") {
270 
271  //create a value::VOID_STAR :
272  value* v = new value((void*)0);
273  v->set_label(swords[1]);
274  return v;
275 
276  } else {
277 
278  value::e_type type;
279  if(!s2type(swords[0],type)){
280  m_out << "tools::columns::finder::analyse_dcl :"
281  << " s2type failed for " << sout(swords[0]) << "."
282  << std::endl;
283  return 0;
284  }
285 
286  strip(ws[1]);
287  value* v = new_value(type,ws[1]);
288  if(!v) {
289  m_out << "tools::columns::finder::analyse_dcl :"
290  << " syntax error in " << sout(a_s) << "."
291  << " new_value() failed."
292  << std::endl;
293  return 0;
294  }
295  v->set_label(swords[1]);
296  return v;
297 
298  }
299 
300  } else if(swords.size()==1) {
301  if(m_cur_type==value::NONE) {
302  m_out << "tools::columns::finder::analyse_dcl :"
303  << " (1) current type is NONE."
304  << std::endl;
305  return 0;
306  }
307 
308  strip(ws[1]);
309  value* v = new_value(m_cur_type,ws[1]);
310  if(!v) {
311  m_out << "tools::columns::finder::analyse_dcl :"
312  << " syntax error in " << sout(a_s) << "."
313  << " Bad value " << sout(ws[1]) << "."
314  << std::endl;
315  return 0;
316  }
317  v->set_label(swords[0]);
318  return v;
319 
320  } else {
321  m_out << "tools::columns::finder::analyse_dcl :"
322  << " syntax error in " << sout(a_s)
323  << ". Case 1."
324  << std::endl;
325  return 0;
326  }
327 
328  } else if(ws.size()==1) {
329  //<type> <name>
330  //<type> <name>={
331  std::vector<std::string> swords;
332  words(ws[0]," ",false,swords);
333  if(swords.size()==2) {
334  strip(swords[0]);
335  strip(swords[1]);
336 
337  if(swords[0]=="ITuple") {
338 
339  //create a value::VOID_STAR :
340  value* v = new value((void*)0);
341  v->set_label(swords[1]);
342  return v;
343 
344  } else {
345  value::e_type type;
346  if(!s2type(swords[0],type)){
347  m_out << "tools::columns::finder::analyse_dcl :"
348  << " s2type failed for " << sout(swords[0]) << "."
349  << std::endl;
350  return 0;
351  }
352 
353  value* v = new_value(type,"");
354  if(!v) {
355  m_out << "tools::columns::finder::analyse_dcl :"
356  << " (2) syntax error in " << sout(ws[0]) << "."
357  << " Unknown type " << sout(swords[0]) << "."
358  << std::endl;
359  return 0;
360  }
361  v->set_label(swords[1]);
362  return v;
363  }
364 
365  } else if(swords.size()==1) {
366 
367  if(m_cur_type==value::NONE) {
368  m_out << "tools::columns::finder::analyse_dcl :"
369  << " (1) current type is NONE."
370  << std::endl;
371  return 0;
372  }
373 
374  value* v = new value();
375  v->set_type(m_cur_type);
376  v->set_label(swords[0]);
377  return v;
378 
379  } else {
380  m_out << "tools::columns::finder::analyse_dcl :"
381  << " syntax error in " << sout(a_s)
382  << ". Case 2."
383  << std::endl;
384  return 0;
385  }
386 
387  } else {
388  m_out << "tools::columns::finder::analyse_dcl :"
389  << " syntax error in " << sout(a_s)
390  << ". Case 3."
391  << std::endl;
392  return 0;
393  }
394  }
395 protected:
396  static bool s2type(const std::string& a_s,value::e_type& a_type){
397  if(a_s=="float") {
398  a_type = value::FLOAT;
399  } else if(a_s=="double") {
400  a_type = value::DOUBLE;
401  //} else if(a_s=="char") {
402  // a_type = value::CHAR;
403  } else if(a_s=="short") {
404  a_type = value::SHORT;
405  } else if(a_s=="int") {
406  a_type = value::INT;
407  } else if(a_s=="long") {
408  a_type = value::INT64;
409  } else if((a_s=="bool")||(a_s=="boolean")) {
410  a_type = value::BOOL;
411  } else if((a_s=="string")||(a_s=="java.lang.String")){
412  a_type = value::STRING;
413  //} else if(a_s=="byte") {
414  // a_type = value::UNSIGNED_CHAR;
415 
416  } else if(a_s=="float[]") {
417  a_type = value::ARRAY_FLOAT;
418  } else if(a_s=="double[]") {
419  a_type = value::ARRAY_DOUBLE;
420  //} else if(a_s=="char[]") {
421  // a_type = value::ARRAY_CHAR;
422  //} else if(a_s=="byte[]") {
423  // a_type = value::ARRAY_UNSIGNED_CHAR;
424  } else if(a_s=="short[]") {
425  a_type = value::ARRAY_SHORT;
426  } else if(a_s=="int[]") {
427  a_type = value::ARRAY_INT;
428  } else if(a_s=="long[]") {
429  a_type = value::ARRAY_INT64;
430  } else if((a_s=="bool[]")||(a_s=="boolean[]")) {
431  a_type = value::ARRAY_BOOL;
432  } else if((a_s=="string[]")||(a_s=="java.lang.String[]")){
433  a_type = value::ARRAY_STRING;
434 
435  // not AIDA :
436  //} else if(a_s=="uchar") {
437  // a_type = value::UNSIGNED_CHAR;
438  } else if(a_s=="ushort") {
439  a_type = value::UNSIGNED_SHORT;
440  } else if(a_s=="uint") {
441  a_type = value::UNSIGNED_INT;
442  } else if(a_s=="ulong") {
443  a_type = value::UNSIGNED_INT64;
444  } else {
445  return false;
446  }
447  return true;
448  }
449  static value* new_value(value::e_type a_type,const std::string& a_v) {
450  if(a_type==value::FLOAT) {
451  float v = 0;
452  if(a_v.size()) {if(!to<float>(a_v,v)) return 0;}
453  return new value(v);
454  } else if(a_type==value::DOUBLE) {
455  double v = 0;
456  if(a_v.size()) {if(!to<double>(a_v,v)) return 0;}
457  return new value(v);
458  //} else if(a_type==value::CHAR) {
459  // char v = 0;
460  // if(a_v.size()) {if(!to<char>(a_v,v)) return 0;}
461  // return new value(v);
462  } else if(a_type==value::SHORT) {
463  short v = 0;
464  if(a_v.size()) {if(!to<short>(a_v,v)) return 0;}
465  return new value(v);
466  } else if(a_type==value::INT) {
467  int v = 0;
468  if(a_v.size()) {if(!to<int>(a_v,v)) return 0;}
469  return new value(v);
470 
471  } else if(a_type==value::INT64) {
472  int64 v = 0;
473  if(a_v.size()) {if(!to<int64>(a_v,v)) return 0;}
474  return new value(v);
475  } else if(a_type==value::BOOL) {
476  bool v = false;
477  if(a_v.size()) {if(!to(a_v,v)) return 0;}
478  return new value(v);
479 
480  } else if(a_type==value::STRING) {
481  if( (a_v.size()>=2) && (a_v[0]=='"') && (a_v[a_v.size()-1]=='"') ){
482  return new value(a_v.substr(1,a_v.size()-2));
483  } else {
484  return new value(a_v);
485  }
486 
487  //} else if(a_type==value::UNSIGNED_CHAR) {
488  // unsigned short v = 0;
489  // if(a_v.size()) {if(!to<unsigned short>(a_v,v)) return 0;}
490  // return new value((unsigned char)v);
491 
492  } else if(a_type==value::UNSIGNED_SHORT) {
493  unsigned short v = 0;
494  if(a_v.size()) {if(!to<unsigned short>(a_v,v)) return 0;}
495  return new value(v);
496  } else if(a_type==value::UNSIGNED_INT) {
497  unsigned int v = 0;
498  if(a_v.size()) {if(!to<unsigned int>(a_v,v)) return 0;}
499  return new value(v);
500 
501  } else if(a_type==value::UNSIGNED_INT64) {
502  uint64 v = 0;
503  if(a_v.size()) {if(!to<uint64>(a_v,v)) return 0;}
504  return new value(v);
505 
506  } else if(a_type==value::ARRAY_FLOAT) {
507  if(a_v.size()) return 0;
508  value* v = new value();
510  return v;
511  } else if(a_type==value::ARRAY_DOUBLE) {
512  if(a_v.size()) return 0;
513  value* v = new value();
515  return v;
516  //} else if(a_type==value::ARRAY_UNSIGNED_CHAR) {
517  // if(a_v.size()) return 0;
518  // value* v = new value();
519  // v->set_type(value::ARRAY_UNSIGNED_CHAR);
520  // return v;
521  //} else if(a_type==value::ARRAY_CHAR) {
522  // if(a_v.size()) return 0;
523  // value* v = new value();
524  // v->set_type(value::ARRAY_CHAR);
525  // return v;
526  } else if(a_type==value::ARRAY_SHORT) {
527  if(a_v.size()) return 0;
528  value* v = new value();
530  return v;
531  } else if(a_type==value::ARRAY_INT) {
532  if(a_v.size()) return 0;
533  value* v = new value();
535  return v;
536  } else if(a_type==value::ARRAY_INT64) {
537  if(a_v.size()) return 0;
538  value* v = new value();
540  return v;
541  } else if(a_type==value::ARRAY_BOOL) {
542  if(a_v.size()) return 0;
543  value* v = new value();
545  return v;
546  } else if(a_type==value::ARRAY_STRING) {
547  if(a_v.size()) return 0;
548  value* v = new value();
550  return v;
551  } else {
552  return 0;
553  }
554  }
555 public:
556  std::ostream& m_out;
557  std::string m_script;
558  std::vector<value> m_stack;
560  //bool fSuccess;
561 };
562 
563 }}
564 
565 #endif
tools::columns::parser::parser
parser(const parser &)
Definition: columns:70
tools::value::ARRAY_SHORT
@ ARRAY_SHORT
Definition: value:51
tools::uint64
unsigned long long uint64
Definition: typedefs:72
tools::int64
long long int64
Definition: typedefs:67
tools::value
Definition: value:18
tools::columns::finder::finder
finder(std::ostream &a_out, const std::string &a_script)
Definition: columns:183
tools::columns::tree::tree
tree(const tree &)
Definition: columns:39
tools::value::type
e_type type() const
Definition: value:440
tools::columns::tree::operator=
tree & operator=(const tree &)
Definition: columns:40
tools::columns::parser::parser
parser()
Definition: columns:67
tools::value::ARRAY_FLOAT
@ ARRAY_FLOAT
Definition: value:56
tools::columns::finder::clear
void clear()
Definition: columns:210
tools::value::FLOAT
@ FLOAT
Definition: value:36
tools::columns::finder::~finder
virtual ~finder()
Definition: columns:189
tools::value::UNSIGNED_SHORT
@ UNSIGNED_SHORT
Definition: value:29
tools::columns::copy_columns
void copy_columns(const std::vector< value > &a_from, std::vector< value > &a_to)
Definition: columns:136
tools::columns::parser
Definition: columns:65
tools::columns::finder::m_stack
std::vector< value > m_stack
Definition: columns:558
tools::columns::tree::m_parent
tree * m_parent
Definition: columns:53
tools::columns::finder::analyse
bool analyse(columns::tree &a_tree, std::vector< value > &a_stack)
Definition: columns:221
tools::columns::tree
Definition: columns:21
tools::columns::finder::find_variables
bool find_variables()
Definition: columns:195
tools::columns::finder::result
void result(std::vector< value > &a_vars) const
Definition: columns:205
tools::value::e_type
e_type
Definition: value:24
tools::value::set_type
void set_type(e_type a_type)
Definition: value:441
tools::value::ARRAY_DOUBLE
@ ARRAY_DOUBLE
Definition: value:57
tools::value::DOUBLE
@ DOUBLE
Definition: value:37
tools::value::ARRAY_STRING
@ ARRAY_STRING
Definition: value:59
strip
tools::value::set
void set(short a_value)
Definition: value:499
tools::columns::finder
Definition: columns:180
tools::columns::tree::clear
void clear()
Definition: columns:42
TOOLS_SCLASS
#define TOOLS_SCLASS(a_name)
Definition: S_STRING:41
tools::columns::finder::operator=
finder & operator=(const finder &)
Definition: columns:192
mem
tools::value::ARRAY_INT64
@ ARRAY_INT64
Definition: value:55
tools::safe_reverse_clear
void safe_reverse_clear(std::vector< T * > &a_vec)
Definition: vmanip:29
tools::value::ARRAY_INT
@ ARRAY_INT
Definition: value:53
tools::value::VOID_STAR
@ VOID_STAR
Definition: value:42
tools::sout
Definition: sout:17
tools::value::set_label
void set_label(const std::string &a_s)
Definition: value:434
tools::columns::tree::m_sub
std::vector< tree * > m_sub
Definition: columns:55
tools::columns::tree::dump_tree
void dump_tree(std::ostream &a_out, const std::string &a_margin)
Definition: columns:46
tools::columns::tree::m_dcl
std::string m_dcl
Definition: columns:54
tools::columns::parser::m_top
tree m_top
Definition: columns:113
tools::value::STRING
@ STRING
Definition: value:40
tools::columns::parser::parse
bool parse(const std::string &a_s)
Definition: columns:73
tools::to
std::vector< std::string > to(int a_argc, char **a_argv)
Definition: args:507
tools_vforit
#define tools_vforit(a__T, a__v, a__it)
Definition: forit:13
tools::columns::dump_columns
void dump_columns(std::ostream &a_out, const std::vector< value > &a_vars, const std::string &a_margin="")
Definition: columns:153
tools
inlined C code : ///////////////////////////////////
Definition: aida_ntuple:26
vmanip
value
schar
tools::words
void words(const std::string &a_string, const std::string &a_sep, bool a_take_empty, std::vector< std::string > &a_words, bool a_clear=true)
Definition: words:12
tools::columns::finder::finder
finder(const finder &a_from)
Definition: columns:191
tools::columns::finder::m_cur_type
value::e_type m_cur_type
Definition: columns:559
tools::is_spaces
bool is_spaces(const std::string &a_string)
Definition: schar:28
words
tools::value::UNSIGNED_INT
@ UNSIGNED_INT
Definition: value:31
S_STRING
tools::value::ARRAY_BOOL
@ ARRAY_BOOL
Definition: value:58
tools::value::UNSIGNED_INT64
@ UNSIGNED_INT64
Definition: value:33
tools::columns::tree::tree
tree(tree *a_parent, const std::string &a_dcl)
Definition: columns:26
tools::columns::tree::~tree
virtual ~tree()
Definition: columns:32
tools::columns::finder::m_script
std::string m_script
Definition: columns:557
forit
tools::columns::finder::analyse_dcl
value * analyse_dcl(const std::string &a_s)
Definition: columns:258
tools::columns::finder::m_out
std::ostream & m_out
Definition: columns:556
tools::strip
bool strip(std::string &a_string, what a_type=both, char a_char=' ')
Definition: strip:14
tools::value::SHORT
@ SHORT
Definition: value:30
tools::columns::parser::dump
void dump(std::ostream &a_out)
Definition: columns:111
tools::columns::parser::~parser
virtual ~parser()
Definition: columns:68
tools::columns::delete_columns
void delete_columns(std::vector< value > &a_vars)
Definition: columns:124
tools::value::INT
@ INT
Definition: value:32
tools::stype
const std::string & stype(const mat4f &)
Definition: mat4f:73
tools::columns::finder::s2type
static bool s2type(const std::string &a_s, value::e_type &a_type)
Definition: columns:396
tools::columns::parser::operator=
parser & operator=(const parser &)
Definition: columns:71
sout
tools::columns::finder::new_value
static value * new_value(value::e_type a_type, const std::string &a_v)
Definition: columns:449
tools::value::INT64
@ INT64
Definition: value:34
tools::value::BOOL
@ BOOL
Definition: value:39
tools::value::NONE
@ NONE
Definition: value:25