1    	
2    	#include <stdio.h>
3    	#include <stdlib.h>
4    	#include "TROOT.h"
5    	#include "TClass.h"
6    	#include "TBaseClass.h"
7    	#include "TDataMember.h"
8    	#include "TMethod.h"
9    	#include "TMethodArg.h"
10   	#include "TDataType.h"
11   	#include "Api.h"
12   	#include "TBrowser.h"
13   	#include "TMemberInspector.h"
14   	#include "TError.h"
15   	#include "StAutoBrowse.h"
16   	
17   	class StAutoInspector : public TMemberInspector {
18   	public:
19   	StAutoInspector(TBrowser *b){fBrowser=b;fCount=0;};
20   	virtual ~StAutoInspector(){};
21   	virtual void Inspect(TClass* cl, const char* parent, const char* name, const void* addr);
22   	
23   	Int_t fCount;
24   	TBrowser *fBrowser;
25   	};      
26   	//______________________________________________________________________________
27   	void StAutoInspector::Inspect(TClass* kl, const char* tit , const char* name, const void* addr)
28   	{
(1) Event cond_false: Condition "tit", taking false branch
(2) Event if_end: End of if statement
(3) Event var_compare_op: Comparing "tit" to null implies that "tit" might be null.
Also see events: [var_deref_model]
29   	  if(tit && strchr(tit,'.'))	return ;
(4) Event cond_true: Condition "this->fCount", taking true branch
(5) Event cond_false: Condition "!this->fBrowser", taking false branch
(6) Event if_end: End of if statement
30   	  if (fCount && !fBrowser) return;
31   	
32   	  TString ts;
33   	
(7) Event cond_false: Condition "!kl", taking false branch
(8) Event if_end: End of if statement
34   	  if (!kl) return;
(9) Event cond_false: Condition "*kl->GetName() == 'T'", taking false branch
(10) Event if_end: End of if statement
35   	  if (*(kl->GetName()) == 'T') return;
(11) Event cond_true: Condition "*name == '*'", taking true branch
36   	  if (*name == '*') name++;
37   	  int ln = strcspn(name,"[ ");
38   	  TString iname(name,ln);
39   	  
40   	  G__ClassInfo *classInfo = (G__ClassInfo*) kl->GetClassInfo();  	
(12) Event cond_false: Condition "!classInfo", taking false branch
(13) Event if_end: End of if statement
41   	  if (!classInfo)		return;
42   	  G__ClassInfo &cl = *classInfo;
43   	
44   	
45   	// 		Browse data members
46   	  G__DataMemberInfo m(cl);
47   	  TString mname;
48   	
49   	  int found=0;
(14) Event cond_true: Condition "m.Next()", taking true branch
50   	  while (m.Next()) {	// MemberLoop
51   	     mname = m.Name();
52   	     mname.ReplaceAll("*","");
(15) Event cond_true: Condition "found = iname == mname", taking true branch
(16) Event break: Breaking from loop
53   	     if ((found = (iname==mname))) break;
(17) Event loop_end: Reached end of loop
54   	  }     
(18) Event cond_true: Condition "found", taking true branch
55   	  assert(found);
56   	
57   	  // we skip: non TObjects
58   	  //  - the member G__virtualinfo inserted by the CINT RTTI system
59   	
60   	  long prop = m.Property() | m.Type()->Property();
(19) Event cond_false: Condition "prop & 16384", taking false branch
(20) Event if_end: End of if statement
61   	  if (prop & G__BIT_ISSTATIC) 	return;
(21) Event cond_false: Condition "prop & 32", taking false branch
(22) Event if_end: End of if statement
62   	  if (prop & G__BIT_ISFUNDAMENTAL) 	return;
(23) Event cond_false: Condition "prop & 8", taking false branch
(24) Event if_end: End of if statement
63   	  if (prop & G__BIT_ISENUM) 		return;
(25) Event cond_true: Condition "strcmp(m.Type()->Fullname(), "TObject")", taking true branch
(26) Event cond_false: Condition "!m.Type()->IsBase("TObject")", taking false branch
64   	  if (strcmp(m.Type()->Fullname(),"TObject") && !m.Type()->IsBase("TObject"))
(27) Event if_end: End of if statement
65   	  					return;
(28) Event cond_false: Condition "mname == "G__virtualinfo"", taking false branch
(29) Event if_end: End of if statement
66   	  if (mname == "G__virtualinfo")	return;
67   	
68   	  int  size = sizeof(void*);
(30) Event cond_true: Condition "!(prop & 4096)", taking true branch
69   	  if (!(prop&G__BIT_ISPOINTER)) size = m.Type()->Size(); 
70   	
71   	  int nmax = 1;
(31) Event cond_true: Condition "prop & 8192", taking true branch
72   	  if (prop & G__BIT_ISARRAY) {
(32) Event cond_false: Condition "dim < m.ArrayDim()", taking false branch
(33) Event loop_end: Reached end of loop
73   	    for (int dim = 0; dim < m.ArrayDim(); dim++) nmax *= m.MaxIndex(dim);
74   	  }
75   	
(34) Event cond_true: Condition "i < nmax", taking true branch
76   	  for(int i=0; i<nmax; i++) {
77   	    char *ptr = (char*)addr + i*size;
78   	    TObject *obj = (prop&G__BIT_ISPOINTER) ? *((TObject**)ptr) : (TObject*)ptr;
(35) Event cond_false: Condition "!obj", taking false branch
(36) Event if_end: End of if statement
79   	    if (!obj) 		continue;
80   	    fCount++;
(37) Event cond_false: Condition "!this->fBrowser", taking false branch
(38) Event if_end: End of if statement
81   	    if (!fBrowser) 	return;
82   	    const char *bwname = obj->GetName();
(39) Event cond_true: Condition "!bwname[0]", taking true branch
83   	    if (!bwname[0] || strcmp(bwname,obj->ClassName())==0) {
84   	      bwname = name;
(40) Event cond_true: Condition "strcmp(bwname, "fOrBrowser") == 0", taking true branch
85   	      if (strcmp(bwname,"fOrBrowser")==0) {
(41) Event var_deref_model: Passing null pointer "tit" to "strlen", which dereferences it.
Also see events: [var_compare_op]
86   	        ts.Replace(0,999,tit,strlen(tit)-1);
87   	        bwname = (const char*)ts;
88   	      } else {
89   		int l = strcspn(bwname,"[ ");
90   		if (bwname[l]=='[') {
91   	          char cbuf[12]; sprintf(cbuf,"[%02d]",i);
92   	          ts.Replace(0,999,bwname,l);
93   	          ts += cbuf;
94   	          bwname = (const char*)ts;
95   		}
96   	      }  
97   	    }  
98   	   
99   	    fBrowser->Add(obj,bwname);
100  	  }
101  	
102  	}    
103  	
104  	//______________________________________________________________________________
105  	Int_t StAutoBrowse::Browse(TObject *obj,TBrowser *browser)
106  	{
107  	  if(!obj)	return 0;
108  	  StAutoInspector insp(browser);
109  	#if ROOT_VERSION_CODE < 334597
110  	  char cbuf[1000]; *cbuf=0;
111  	
112  	  ((TObject*)obj)->ShowMembers(insp,cbuf);
113  	#else
114  	  ((TObject*)obj)->ShowMembers(insp);
115  	#endif
116  	  return insp.fCount;
117  	}
118