Logo ROOT  
Reference Guide
TTabCom.cxx
Go to the documentation of this file.
1 // @(#)root/rint:$Id$
2 // Author: Christian Lacunza <lacunza@cdfsg6.lbl.gov> 27/04/99
3 
4 // Modified by Artur Szostak <artur@alice.phy.uct.ac.za> : 1 June 2003
5 // Added support for namespaces.
6 
7 /*************************************************************************
8  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
9  * All rights reserved. *
10  * *
11  * For the licensing terms see $ROOTSYS/LICENSE. *
12  * For the list of contributors see $ROOTSYS/README/CREDITS. *
13  *************************************************************************/
14 
15 ////////////////////////////////////////////////////////////////////////////
16 // //
17 // TTabCom //
18 // //
19 // This class performs basic tab completion. //
20 // You should be able to hit [TAB] to complete a partially typed: //
21 // //
22 // username //
23 // environment variable //
24 // preprocessor directive //
25 // pragma //
26 // filename (with a context-sensitive path) //
27 // public member function or data member (including base classes) //
28 // global variable, function, or class name //
29 // //
30 // Also, something like //
31 // //
32 // someObject->Func([TAB] //
33 // someObject.Func([TAB] //
34 // someClass::Func([TAB] //
35 // someClass var([TAB] //
36 // new someClass([TAB] //
37 // //
38 // will print a list of prototypes for the indicated //
39 // method or constructor. //
40 // //
41 // Current limitations and bugs: //
42 // //
43 // 1. you can only use one member access operator at a time. //
44 // eg, this will work: gROOT->GetListOfG[TAB] //
45 // but this will not: gROOT->GetListOfGlobals()->Conta[TAB] //
46 // //
47 // 2. nothing is guaranteed to work on windows //
48 // (for one thing, /bin/env and /etc/passwd are hardcoded) //
49 // //
50 // 3. CINT shortcut #2 is deliberately not supported. //
51 // (using "operator.()" instead of "operator->()") //
52 // //
53 // 4. most identifiers (including C++ identifiers, usernames, //
54 // environment variables, etc) //
55 // are restriceted to this character set: [_a-zA-Z0-9] //
56 // therefore, you won't be able to complete things like //
57 // //
58 // operator new //
59 // operator+ //
60 // etc //
61 // //
62 // 5. ~whatever[TAB] always tries to complete a username. //
63 // use whitespace (~ whatever[TAB]) if you want to complete a global //
64 // identifier. //
65 // //
66 // 6. CINT shortcut #3 is not supported when trying to complete //
67 // the name of a global object. (it is supported when trying to //
68 // complete a member of a global object) //
69 // //
70 // 7. the list of #pragma's is hardcoded //
71 // (ie not obtained from the interpreter at runtime) //
72 // ==> user-defined #pragma's will not be recognized //
73 // //
74 // 8. the system include directories are also hardcoded //
75 // because i don't know how to get them from the interpreter. //
76 // fons, maybe they should be #ifdef'd for the different sytems? //
77 // //
78 // 9. the TabCom.FileIgnore resource is always applied, even if you //
79 // are not trying to complete a filename. //
80 // //
81 // 10. anything in quotes is assumed to be a filename //
82 // so (among other things) you can't complete a quoted class name: //
83 // eg, TClass class1( "TDict[TAB] //
84 // this won't work... looks for a file in pwd starting with TDict //
85 // //
86 // 11. the prototypes tend to omit the word "const" a lot. //
87 // this is a problem with ROOT or CINT. //
88 // //
89 // 12. when listing ambiguous matches, only one column is used, //
90 // even if there are many completions. //
91 // //
92 // 13. anonymous objects are not currently identified //
93 // so, for example, //
94 // //
95 // root> printf( TString([TAB //
96 // //
97 // gives an error message instead of listing TString's constructors. //
98 // (this could be fixed) //
99 // //
100 // 14. the routine that adds the "appendage" isn't smart enough to know //
101 // if it's already there: //
102 // //
103 // root> TCanvas::Update() //
104 // press [TAB] here ^ //
105 // root> TCanvas::Update()() //
106 // (this could be fixed) //
107 // //
108 // 15. the appendage is only applied if there is exactly 1 match. //
109 // eg, this //
110 // //
111 // root> G__at[TAB] //
112 // root> G__ateval //
113 // //
114 // happens instead of this //
115 // //
116 // root> G__at[TAB] //
117 // root> G__ateval( //
118 // //
119 // because there are several overloaded versions of G__ateval(). //
120 // (this could be fixed) //
121 // //
122 ////////////////////////////////////////////////////////////////////////////
123 
124 #include <cstdio>
125 #include <cassert>
126 #include <set>
127 
128 #include "RConfigure.h"
129 #include "TTabCom.h"
130 #include "TClass.h"
131 #include "TClassTable.h"
132 #include "TDataMember.h"
133 #include "TSystem.h"
134 #include "TROOT.h"
135 #include "TMethod.h"
136 #include "TEnv.h"
137 #include "TBenchmark.h"
138 #include "TError.h"
139 #include "TGlobal.h"
140 #include "TList.h"
141 #include "THashList.h"
142 #include "TObjString.h"
143 #include "Getline.h"
144 #include "TFunction.h"
145 #include "TMethodArg.h"
146 #include "TInterpreter.h"
147 #include "Riostream.h"
148 #include "Rstrstream.h"
149 #include "strlcpy.h"
150 
151 #define BUF_SIZE 1024 // must be smaller than/equal to fgLineBufSize in Getline.cxx and
152  // lineBufSize in cppcompleter.py
153 #define IfDebug(x) if(gDebug==TTabCom::kDebug) x
154 
155 #ifdef R__WIN32
156 const char kDelim = ';';
157 #else
158 const char kDelim = ':';
159 #endif
160 
161 
163 // ----------------------------------------------------------------------------
164 //
165 // global/file scope variables
166 //
168 
169 // ----------------------------------------------------------------------------
170 //
171 // constructors
172 //
173 
174 ////////////////////////////////////////////////////////////////////////////////
175 /// Default constructor.
176 
178  fpClasses(0),
179  fPrevInterpMarker(0),
180  fpDirectives(0),
181  fpEnvVars(0),
182  fpFiles(0),
183  fpGlobals(0),
184  fpPragmas(0),
185  fpSysIncFiles(0),
186  fpUsers(0),
187  fBuf(0),
188  fpLoc(0),
189  fVarIsPointer(kFALSE),
190  fLastIter(0)
191 {
192  InitPatterns();
193 }
194 
195 //
196 // constructors
197 //
198 // ----------------------------------------------------------------------------
199 
201 {
202  // Destructor.
203 
204  ClearAll();
205  ClearSysIncFiles(); // this one stays cached
206  ClearUsers(); // this one stays cached
207 }
208 
209 // ----------------------------------------------------------------------------
210 //
211 // public member functions
212 //
213 
214 
215 ////////////////////////////////////////////////////////////////////////////////
216 /// Clear classes and namespace collections.
217 
219 {
220  if (fpClasses) {
221  delete fpClasses;
222  fpClasses = 0;
223  }
224 
225 }
226 
227 ////////////////////////////////////////////////////////////////////////////////
228 /// Forget all Cpp directives seen so far.
229 
231 {
232  if (!fpDirectives)
233  return;
234  fpDirectives->Delete(0);
235  delete fpDirectives;
236  fpDirectives = 0;
237 }
238 
239 ////////////////////////////////////////////////////////////////////////////////
240 /// Forget all environment variables seen so far.
241 
243 {
244  if (!fpEnvVars)
245  return;
246  fpEnvVars->Delete(0);
247  delete fpEnvVars;
248  fpEnvVars = 0;
249 }
250 
251 ////////////////////////////////////////////////////////////////////////////////
252 /// Close all files.
253 
255 {
256  if (!fpFiles)
257  return;
258  fpFiles->Delete(0);
259  delete fpFiles;
260  fpFiles = 0;
261 }
262 
263 ////////////////////////////////////////////////////////////////////////////////
264 /// Forget all global functions seen so far.
265 /// Not needed anymore. Use gROOT->GetListOfGlobalFunctions()
266 
268 {
269 }
270 
271 ////////////////////////////////////////////////////////////////////////////////
272 /// Forget all global variables seen so far.
273 /// With teh new implamentation the list is gROOT->GetListOfGlobals(true).
274 
276 {
277 }
278 
279 ////////////////////////////////////////////////////////////////////////////////
280 /// Forget all pragmas seen so far.
281 
283 {
284  if (!fpPragmas)
285  return;
286  fpPragmas->Delete(0);
287  delete fpPragmas;
288  fpPragmas = 0;
289 }
290 
291 ////////////////////////////////////////////////////////////////////////////////
292 /// Close system files.
293 
295 {
296  if (!fpSysIncFiles)
297  return;
298  fpSysIncFiles->Delete(0);
299  delete fpSysIncFiles;
300  fpSysIncFiles = 0;
301 }
302 
303 ////////////////////////////////////////////////////////////////////////////////
304 /// Forget all user seen so far.
305 
307 {
308  if (!fpUsers)
309  return;
310  fpUsers->Delete(0);
311  delete fpUsers;
312  fpUsers = 0;
313 }
314 
315 ////////////////////////////////////////////////////////////////////////////////
316 /// clears all lists
317 /// except for user names and system include files.
318 
320 {
321  ClearClasses();
323  ClearEnvVars();
324  ClearFiles();
326  ClearGlobals();
327  ClearPragmas();
328 // ClearSysIncFiles(); <-- this one stays cached
329 // ClearUsers(); <-- this one stays cached
330 }
331 
332 ////////////////////////////////////////////////////////////////////////////////
333 /// Do the class rehash.
334 
336 {
337  ClearClasses();
339 }
340 
341 ////////////////////////////////////////////////////////////////////////////////
342 /// Cpp rehashing.
343 
345 {
348 }
349 
350 ////////////////////////////////////////////////////////////////////////////////
351 /// Environemnt variables rehashing.
352 
354 {
355  ClearEnvVars();
357 }
358 
359 ////////////////////////////////////////////////////////////////////////////////
360 /// Close files.
361 
363 {
364  ClearFiles(); /* path unknown */
365 } // think about this
366 
367 ////////////////////////////////////////////////////////////////////////////////
368 /// Reload global functions.
369 
371 {
373 }
374 
375 ////////////////////////////////////////////////////////////////////////////////
376 /// Reload globals.
377 
379 {
380  ClearGlobals();
382 }
383 
384 ////////////////////////////////////////////////////////////////////////////////
385 /// Reload pragmas.
386 
388 {
389  ClearPragmas();
391 }
392 
393 ////////////////////////////////////////////////////////////////////////////////
394 /// Reload system include files.
395 
397 {
400 }
401 
402 ////////////////////////////////////////////////////////////////////////////////
403 /// Reload users.
404 
406 {
407  ClearUsers();
408  GetListOfUsers();
409 }
410 
411 ////////////////////////////////////////////////////////////////////////////////
412 /// clears and then rebuilds all lists
413 /// except for user names and system include files.
414 
416 {
417  RehashClasses();
419  RehashEnvVars();
420  RehashFiles();
422  RehashGlobals();
423  RehashPragmas();
424 // RehashSysIncFiles(); <-- this one stays cached
425 // RehashUsers(); <-- this one stays cached
426 }
427 
428 ////////////////////////////////////////////////////////////////////////////////
429 /// Return the list of classes.
430 
432 {
433  if (!fpClasses) {
434  fpClasses = new THashList;
435  // Iterate over the table from the map file.
436  THashList* entries = gInterpreter->GetMapfile()->GetTable();
437  TIter next(entries);
438  while (const auto key = next()) {
439  // This is not needed with the new rootmap format
440  const char* className = key->GetName();
441  if (!strncmp(className, "Library.", 8))
442  className += 8;
443 
444  if (!strstr(className, ".h"))
445  fpClasses->Add(new TObjString(className));
446  }
447 
448  // We might have autoload entries that don't have a rootmap entry
449  // (libCore) and no interpreter info (not yet loaded).
450  TClassTable::Init(); // reset counter
451  while (const char* className = TClassTable::Next()) {
452  if (!fpClasses->FindObject(className)) {
453  fpClasses->Add(new TObjString(className));
454  }
455  }
456 
457  // Add possible identifiers coming from the global module index.
458  // FIXME: Consolidate all this -- we have ultimate source of information
459  // clang's identifier table and the ASTIndentifiers.
460  gInterpreter->AddAvailableIndentifiers(*fpClasses);
461  }
462 
463  if (fPrevInterpMarker != gInterpreter->GetInterpreterStateMarker()) {
464  ClassInfo_t* ci = gInterpreter->ClassInfo_Factory(kFALSE /*all*/);
465  while (gInterpreter->ClassInfo_Next(ci)) {
466  const char* className = gInterpreter->ClassInfo_FullName(ci);
467  if (strstr(className, "(anonymous)"))
468  continue;
469  if (!fpClasses->FindObject(className)) {
470  fpClasses->Add(new TObjString(className));
471  }
472  }
473  gInterpreter->ClassInfo_Delete(ci);
474  }
475 
476  return fpClasses;
477 }
478 
479 ////////////////////////////////////////////////////////////////////////////////
480 /// Return the list of CPP directives.
481 
483 {
484  if (!fpDirectives) {
485  fpDirectives = new TContainer;
486 
487  fpDirectives->Add(new TObjString("if"));
488  fpDirectives->Add(new TObjString("ifdef"));
489  fpDirectives->Add(new TObjString("ifndef"));
490  fpDirectives->Add(new TObjString("elif"));
491  fpDirectives->Add(new TObjString("else"));
492  fpDirectives->Add(new TObjString("endif"));
493  fpDirectives->Add(new TObjString("include"));
494  fpDirectives->Add(new TObjString("define"));
495  fpDirectives->Add(new TObjString("undef"));
496  fpDirectives->Add(new TObjString("line"));
497  fpDirectives->Add(new TObjString("error"));
498  fpDirectives->Add(new TObjString("pragma"));
499  }
500 
501  return fpDirectives;
502 }
503 
504 ////////////////////////////////////////////////////////////////////////////////
505 /// "path" should be initialized with a colon separated list of
506 /// system directories
507 
509 {
510  static TString previousPath;
511 
512  if (path && fpFiles && strcmp(path, previousPath) == 0) {
513  return fpFiles;
514  } else {
515  ClearFiles();
516 
518  previousPath = path;
519  }
520 
521  return fpFiles;
522 }
523 
524 ////////////////////////////////////////////////////////////////////////////////
525 /// Uses "env" (Unix) or "set" (Windows) to get list of environment variables.
526 
528 {
529  if (!fpEnvVars) {
530  TString outf = ".TTabCom-";
531  FILE *fout = gSystem->TempFileName(outf);
532  if (!fout) return 0;
533  fclose(fout);
534  TString cmd;
535 
536 #ifndef WIN32
537  char *env = gSystem->Which(gSystem->Getenv("PATH"), "env", kExecutePermission);
538  if (!env)
539  return 0;
540  cmd = env;
541  cmd += " > ";
542  delete [] env;
543 #else
544  cmd = "set > ";
545 #endif
546  cmd += outf;
547  cmd += "\n";
548  gSystem->Exec(cmd.Data());
549 
550  // open the file
551  std::ifstream file1(outf);
552  if (!file1) {
553  Error("TTabCom::GetListOfEnvVars", "could not open file \"%s\"",
554  outf.Data());
555  gSystem->Unlink(outf);
556  return 0;
557  }
558  // parse, add
559  fpEnvVars = new TContainer;
560  TString line;
561  while (file1) // i think this loop goes one time extra which
562  // results in an empty string in the list, but i don't think it causes any
563  // problems.
564  {
565  line.ReadToDelim(file1, '=');
566  file1.ignore(32000, '\n');
567  fpEnvVars->Add(new TObjString(line.Data()));
568  }
569 
570  file1.close();
571  gSystem->Unlink(outf);
572  }
573 
574  return fpEnvVars;
575 }
576 
577 ////////////////////////////////////////////////////////////////////////////////
578 /// Return the list of globals.
579 
581 {
582  return (TSeqCollection*)gROOT->GetListOfGlobals(true);
583 }
584 
585 ////////////////////////////////////////////////////////////////////////////////
586 /// Return the list of global functions.
587 
589 {
590  return gROOT->GetListOfGlobalFunctions(true);
591 }
592 
593 ////////////////////////////////////////////////////////////////////////////////
594 /// Return the list of pragmas
595 
597 {
598  if (!fpPragmas) {
599  fpPragmas = new TContainer;
600 
601  fpPragmas->Add(new TObjString("ANSI "));
602  fpPragmas->Add(new TObjString("autocompile "));
603  fpPragmas->Add(new TObjString("bytecode "));
604  fpPragmas->Add(new TObjString("compile "));
605  fpPragmas->Add(new TObjString("endbytecode "));
606  fpPragmas->Add(new TObjString("endcompile "));
607  fpPragmas->Add(new TObjString("include "));
608  fpPragmas->Add(new TObjString("includepath "));
609  fpPragmas->Add(new TObjString("K&R "));
610  fpPragmas->Add(new TObjString("link "));
611  fpPragmas->Add(new TObjString("preprocess "));
612  fpPragmas->Add(new TObjString("preprocessor "));
613  fpPragmas->Add(new TObjString("security level"));
614  // "setertti " omitted. Ordinary user should not use this statement
615  // "setstdio " omitted. Ordinary user should not use this statement
616  // "setstream " omitted. Ordinary user should not use this statement
617  // "stub" omitted. Ordinary user should not use this statement
618 
619  }
620 
621  return fpPragmas;
622 }
623 
624 ////////////////////////////////////////////////////////////////////////////////
625 /// Return the list of system include files.
626 
628 {
629  if (!fpSysIncFiles) {
631  }
632 
633  return fpSysIncFiles;
634 }
635 
636 ////////////////////////////////////////////////////////////////////////////////
637 /// reads from "/etc/passwd"
638 
640 {
641  if (!fpUsers) {
642  fpUsers = new TContainer;
643 
644  std::ifstream passwd;
645  TString user;
646 
647  passwd.open("/etc/passwd");
648  while (passwd) {
649  user.ReadToDelim(passwd, ':');
650  fpUsers->Add(new TObjString(user));
651  passwd.ignore(32000, '\n');
652  }
653  passwd.close();
654  }
655 
656  return fpUsers;
657 }
658 
659 //
660 // public member functions
661 //
662 // ----------------------------------------------------------------------------
663 
664 // ----------------------------------------------------------------------------
665 //
666 // static utility functions
667 //
668 
669 ////////////////////////////////////////////////////////////////////////////////
670 ///[static utility function]///////////////////////////////////////////
671 ///
672 /// if all the strings in "*pList" have the same ith character,
673 /// that character is returned.
674 /// otherwise 0 is returned.
675 ///
676 /// any string "s" for which "ExcludedByFignore(s)" is true
677 /// will be ignored unless All the strings in "*pList"
678 /// are "ExcludedByFignore()"
679 ///
680 /// in addition, the number of strings which were not
681 /// "ExcludedByFignore()" is returned in "nGoodStrings".
682 ///
683 //////////////////////////////////////////////////////////////////////////
684 
686  Int_t & nGoodStrings)
687 {
688  assert(pList != 0);
689 
690  TIter next(pList);
691  TObject *pObj;
692  const char *s = "";
693  char ch0;
694  Bool_t isGood;
695  Bool_t atLeast1GoodString;
696 
697  // init
698  nGoodStrings = 0;
699  atLeast1GoodString = kFALSE;
700 
701  // first look for a good string
702  do {
703  if ((pObj = next())) {
704  s = pObj->GetName();
705  isGood = !ExcludedByFignore(s);
706  if (isGood) {
707  atLeast1GoodString = kTRUE;
708  nGoodStrings += 1;
709  }
710  } else {
711  // reached end of list without finding a single good string.
712  // just use the first one.
713  next.Reset();
714  pObj = next();
715  if (pObj) s = pObj->GetName();
716  break;
717  }
718  }
719  while (!isGood);
720 
721  // found a good string...
722  ch0 = s[i];
723 
724  // all subsequent good strings must have the same ith char
725  do {
726  if ((pObj = next())) {
727  s = pObj->GetName();
728  isGood = !ExcludedByFignore(s);
729  if (isGood)
730  nGoodStrings += 1;
731  } else
732  return ch0;
733  }
734  while (((int) strlen(s) >= i && s[i] == ch0) ||
735  (atLeast1GoodString && !isGood));
736 
737  return 0;
738 }
739 
740 ////////////////////////////////////////////////////////////////////////////////
741 ///[static utility function]/////////////////////////////
742 ///
743 /// adds a TObjString to "*pList"
744 /// for each entry found in the system directory "dirName"
745 ///
746 /// directories that do not exist are silently ignored.
747 ///
748 ///////////////////////////////////////////////////////////
749 
750 void TTabCom::AppendListOfFilesInDirectory(const char dirName[],
751  TSeqCollection * pList)
752 {
753  assert(dirName != 0);
754  assert(pList != 0);
755 
756  // open the directory
757  void *dir = gSystem->OpenDirectory(dirName);
758 
759  // it is normal for this function to receive names of directories that do not exist.
760  // they should be ignored and should not generate any error messages.
761  if (!dir)
762  return;
763 
764  // put each filename in the list
765  const char *tmp_ptr; // gSystem->GetDirEntry() returns 0 when no more files.
766  TString fileName;
767 
768  while ((tmp_ptr = gSystem->GetDirEntry(dir))) {
769  fileName = tmp_ptr;
770 
771  // skip "." and ".."
772  if (fileName == "." || fileName == "..")
773  continue;
774 
775  // add to list
776  pList->Add(new TObjString(dirName + fileName.Prepend("/")));
777  }
778  // NOTE:
779  // with a path like "/usr/include:/usr/include/CC:$ROOTDIR/include:$ROOTDIR/cint/include:..."
780  // the above loop could get traversed 700 times or more.
781  // ==> keep it minimal or it could cost whole seconds on slower machines.
782  // also: TClonesArray doesn't help.
783 
784  // close the directory
785  gSystem->FreeDirectory(dir);
786 }
787 
788 // -----\/-------- homemade RTTI ---------------\/------------------------
789 ////////////////////////////////////////////////////////////////////////////////
790 ///[static utility function]/////////////////////////////
791 ///
792 /// returns empty string on failure.
793 /// otherwise returns something like this: "TROOT*".
794 /// fails for non-class types (ie, int, char, etc).
795 /// fails for pointers to functions.
796 ///
797 ////////////////////////////////////
798 
799 TString TTabCom::DetermineClass(const char varName[])
800 {
801 
802  ///////////////////////////////////
803  //
804  // note that because of the strange way this function works,
805  // CINT will print
806  //
807  // Error: No symbol asdf in current scope FILE:/var/tmp/gaaa001HR LINE:1
808  //
809  // if "varName" is not defined. (in this case, varName=="asdf")
810  // i don't know how to suppress this.
811  //
812  ///////////////////////////////////
813 
814  assert(varName != 0);
815  IfDebug(std::cerr << "DetermineClass(\"" << varName << "\");" << std::endl);
816 
817  TString outf = ".TTabCom-";
818  FILE *fout = gSystem->TempFileName(outf);
819  if (!fout) return "";
820  fclose(fout);
821 
822  TString cmd(".> ");
823  cmd += outf;
824  //redirect
825  gROOT->ProcessLineSync(cmd.Data());
826 
827  cmd = "gROOT->ProcessLine(\"";
828  cmd += varName;
829  cmd += "\");";
830  cmd += "\n";
831  gROOT->ProcessLineSync(cmd.Data());
832  // the type of the variable whose name is "varName"
833  // should now be stored on disk in the file "tmpfile"
834 
835  gROOT->ProcessLineSync(".>");
836 
837  TString type = "";
838  int c;
839 
840  // open the file
841  std::ifstream file1(outf);
842  if (!file1) {
843  Error("TTabCom::DetermineClass", "could not open file \"%s\"",
844  outf.Data());
845  goto cleanup;
846  }
847  // first char should be '(', which we can ignore.
848  c = file1.get();
849  if (!file1 || c <= 0 || c != '(') {
850  Error("TTabCom::DetermineClass", "variable \"%s\" not defined?",
851  varName);
852  goto cleanup;
853  }
854  IfDebug(std::cerr << (char) c << std::flush);
855 
856  // in case of success, "class TClassName*)0x12345" remains or TClassName 0x[0-9][a-f]+
857  // in case of objects
858  // since the opening '(' was removed.
859 
860  if (type == "const" || type == "class") {
861  file1 >> type;
862  // ignore ' '
863  c = file1.get();
864  IfDebug(std::cerr << (char) c << std::flush);
865  }
866 
867  // this is what we want
868  type.ReadToDelim(file1, ')');
869  IfDebug(std::cerr << type << std::endl);
870 
871  // new version of CINT returns: "class TClassName*const)0x12345"
872  // so we have to strip off "const"
873  if (type.EndsWith("const"))
874  type.Remove(type.Length() - 5);
875 
876 cleanup:
877  // done reading from file
878  file1.close();
879  gSystem->Unlink(outf);
880 
881  return type;
882 }
883 
884 ////////////////////////////////////////////////////////////////////////////////
885 ///[static utility function]/////////////////////////////
886 ///
887 /// returns true iff "s" ends with one of
888 /// the strings listed in the "TabCom.FileIgnore" resource.
889 ///
890 //////////////////////////////////////////////////////////////
891 
893 {
894  const char *fignore = gEnv->GetValue("TabCom.FileIgnore", (char *) 0);
895 
896  if (!fignore) {
897  return kFALSE;
898  } else {
899 #ifdef R__SSTREAM
900  std::istringstream endings((char *) fignore);
901 #else
902  std::istrstream endings((char *) fignore); // do i need to make a copy first?
903 #endif
904  TString ending;
905 
906  ending.ReadToDelim(endings, kDelim);
907 
908  while (!ending.IsNull()) {
909  if (s.EndsWith(ending))
910  return kTRUE;
911  else
912  ending.ReadToDelim(endings, kDelim); // next
913  }
914  return kFALSE;
915  }
916 }
917 
918 ////////////////////////////////////////////////////////////////////////////////
919 ///[static utility function]/////////////////////////////
920 ///
921 /// returns a colon-separated string of directories
922 /// that CINT will search when you call #include<...>
923 ///
924 /// returns empty string on failure.
925 ///
926 ////////////////////////////////////////////////////////////
927 
929 {
930  // >i noticed that .include doesn't list the standard directories like
931  // >/usr/include or /usr/include/CC.
932  // >
933  // >how can i get a list of all the directories the interpreter will
934  // >search through when the user does a #include<...> ?
935  //
936  // Right now, there is no easy command to tell you about it. Instead, I can
937  // describe it here.
938  //
939  // 1) CINT first searches current working directory for #include "xxx"
940  // (#include <xxx> does not)
941  //
942  // 2) CINT searches include path directories given by -I option
943  //
944  // 3) CINT searches following standard include directories.
945  // $CINTSYSDIR/include
946  // $CINTSYSDIR/stl
947  // $CINTSYSDIR/msdev/include if VC++4.0
948  // $CINTSYSDIR/sc/include if Symantec C++
949  // /usr/include
950  // /usr/include/g++ if gcc,g++
951  // /usr/include/CC if HP-UX
952  // /usr/include/codelibs if HP-UX
953  //
954  // .include command only displays 2).
955  //
956  // Thank you
957  // Masaharu Goto
958 
959  // 1) current dir
960  // ----------------------------------------------
961  // N/A
962 
963 
964  // 2) -I option (and #pragma includepath)
965  // ----------------------------------------------
966 
967  // get this part of the include path from the interpreter
968  // and stick it in a tmp file.
969  TString outf = ".TTabCom-";
970  FILE *fout = gSystem->TempFileName(outf);
971  if (!fout) return "";
972  gCling->DisplayIncludePath(fout);
973  fclose(fout);
974 
975  // open the tmp file
976  std::ifstream file1(outf);
977  if (!file1) { // error
978  Error("TTabCom::GetSysIncludePath", "could not open file \"%s\"",
979  outf.Data());
980  gSystem->Unlink(outf);
981  return "";
982  }
983  // parse it.
984  TString token; // input buffer
985  TString path; // all directories so far (colon-separated)
986  file1 >> token; // skip "include"
987  file1 >> token; // skip "path:"
988  while (file1) {
989  file1 >> token;
990  if (!token.IsNull()) {
991  if (path.Length() > 0)
992  path.Append(":");
993  path.Append(token.Data() + 2); // +2 skips "-I"
994  }
995  }
996 
997  // done with the tmp file
998  file1.close();
999  gSystem->Unlink(outf);
1000 
1001  // 3) standard directories
1002  // ----------------------------------------------
1003 
1004 #ifndef CINTINCDIR
1005  TString sCINTSYSDIR("$ROOTSYS/cint");
1006 #else
1007  TString sCINTSYSDIR(CINTINCDIR);
1008 #endif
1009  path.Append(":" + sCINTSYSDIR + "/include");
1010 // path.Append(":"+CINTSYSDIR+"/stl");
1011 // path.Append(":"+CINTSYSDIR+"/msdev/include");
1012 // path.Append(":"+CINTSYSDIR+"/sc/include");
1013  path.Append(":/usr/include");
1014 // path.Append(":/usr/include/g++");
1015 // path.Append(":/usr/include/CC");
1016 // path.Append(":/usr/include/codelibs");
1017 
1018  return path;
1019 }
1020 
1021 ////////////////////////////////////////////////////////////////////////////////
1022 ///[static utility function]/////////////////////////////
1023 ///
1024 /// calls TSystem::GetPathInfo() to see if "fileName"
1025 /// is a system directory.
1026 ///
1027 ////////////////////////////////////////////////////////
1028 
1029 Bool_t TTabCom::IsDirectory(const char fileName[])
1030 {
1031  FileStat_t stat;
1032  if (!gSystem->GetPathInfo(fileName, stat))
1033  return R_ISDIR(stat.fMode);
1034  else
1035  return false;
1036 }
1037 
1038 ////////////////////////////////////////////////////////////////////////////////
1039 ///[static utility function]/////////////////////////////
1040 ///
1041 /// creates a list containing the full path name for each file
1042 /// in the (colon separated) string "path1"
1043 ///
1044 /// memory is allocated with "new", so
1045 /// whoever calls this function takes responsibility for deleting it.
1046 ///
1047 ///////////////////////////////////////////////////////////////////////
1048 
1050 {
1051  assert(path1 != 0);
1052  if (!path1[0]) path1 = ".";
1053 
1054  TContainer *pList = new TContainer; // maybe use RTTI here? (since its a static function)
1055 #ifdef R__SSTREAM
1056  std::istringstream path((char *) path1);
1057 #else
1058  std::istrstream path((char *) path1);
1059 #endif
1060 
1061  while (path.good())
1062  {
1063  TString dirName;
1064  dirName.ReadToDelim(path, kDelim);
1065  if (dirName.IsNull())
1066  continue;
1067 
1068  IfDebug(std::cerr << "NewListOfFilesInPath(): dirName = " << dirName <<
1069  std::endl);
1070 
1071  AppendListOfFilesInDirectory(dirName, pList);
1072  }
1073 
1074  return pList;
1075 }
1076 
1077 ////////////////////////////////////////////////////////////////////////////////
1078 ///[static utility function]/////////////////////////////
1079 ///
1080 /// true if "fileName"
1081 /// 1. is an absolute path ("/tmp/a")
1082 /// 2. is a relative path ("../whatever", "./test")
1083 /// 3. starts with user name ("~/mail")
1084 /// 4. starts with an environment variable ("$ROOTSYS/bin")
1085 ///
1086 ///////////////////////////////////////////////////////////////////////////
1087 
1089 {
1090  char c1 = (fileName.Length() > 0) ? fileName[0] : 0;
1091  return c1 == '/' || c1 == '~' || c1 == '$' || fileName.BeginsWith("./")
1092  || fileName.BeginsWith("../");
1093 }
1094 
1095 ////////////////////////////////////////////////////////////////////////////////
1096 ///[static utility function]/////////////////////////////
1097 ///
1098 /// calling "NoMsg( errorLevel )",
1099 /// sets "gErrorIgnoreLevel" to "errorLevel+1" so that
1100 /// all errors with "level < errorLevel" will be ignored.
1101 ///
1102 /// calling the function with a negative argument
1103 /// (e.g., "NoMsg( -1 )")
1104 /// resets gErrorIgnoreLevel to its previous value.
1105 ///
1106 ///////////////////////////////////////////////////////////////////
1107 
1108 void TTabCom::NoMsg(Int_t errorLevel)
1109 {
1110  ////////////////////////////////////////////////////////////////
1111  //
1112  // if you call the function twice with a non-negative argument
1113  // (without an intervening call with a negative argument)
1114  // it will complain because it is almost certainly an error
1115  // that will cause the function to loose track of the previous
1116  // value of gErrorIgnoreLevel.
1117  //
1118  // most common causes: 1. suspiciously placed "return;" statement
1119  // 2. calling a function that calls "NoMsg()"
1120  //
1121  //////////////////////////////////////////////////////////////////
1122 
1123  const Int_t kNotDefined = -2;
1124  static Int_t old_level = kNotDefined;
1125 
1126  if (errorLevel < 0) // reset
1127  {
1128  if (old_level == kNotDefined) {
1129  std::cerr << "NoMsg(): ERROR 1. old_level==" << old_level << std::endl;
1130  return;
1131  }
1132 
1133  gErrorIgnoreLevel = old_level; // restore
1134  old_level = kNotDefined;
1135  } else // set
1136  {
1137  if (old_level != kNotDefined) {
1138  std::cerr << "NoMsg(): ERROR 2. old_level==" << old_level << std::endl;
1139  return;
1140  }
1141 
1142  old_level = gErrorIgnoreLevel;
1143  if (gErrorIgnoreLevel <= errorLevel)
1144  gErrorIgnoreLevel = errorLevel + 1;
1145  }
1146 }
1147 
1148 //
1149 // static utility functions
1150 //
1151 // ----------------------------------------------------------------------------
1152 
1153 
1154 // ----------------------------------------------------------------------------
1155 //
1156 // private member functions
1157 //
1158 //
1159 
1160 ////////////////////////////////////////////////////////////////////////////////
1161 /// [private]
1162 
1164  const TSeqCollection * pListOfCandidates,
1165  const char appendage[],
1166  std::ostream& out,
1168 {
1169  // returns position of first change in buffer
1170  // ------------------------------------------
1171  // -2 ==> new line altogether (whole thing needs to be redrawn, including prompt)
1172  // -1 ==> no changes
1173  // 0 ==> beginning of line
1174  // 1 ==> after 1st char
1175  // n ==> after nth char
1176 
1177  IfDebug(std::cerr << "TTabCom::Complete() ..." << std::endl);
1178  assert(fpLoc != 0);
1179  assert(pListOfCandidates != 0);
1180 
1181  Int_t pos = 0; // position of first change
1182  const int loc = *fpLoc; // location where TAB was pressed
1183 
1184  // -----------------------------------------
1185  //
1186  // 1. get the substring we need to complete
1187  //
1188  // NOTES:
1189  // s1 = original buffer
1190  // s2 = sub-buffer from 0 to wherever the user hit TAB
1191  // s3 = the actual text that needs completing
1192  //
1193  // -----------------------------------------
1194  TString s1(fBuf);
1195  TString s2 = s1(0, loc);
1196  TString s3 = s2(re);
1197 
1198  int start = s2.Index(re);
1199 
1200  IfDebug(std::cerr << " s1: " << s1 << std::endl);
1201  IfDebug(std::cerr << " s2: " << s2 << std::endl);
1202  IfDebug(std::cerr << " s3: " << s3 << std::endl);
1203  IfDebug(std::cerr << "start: " << start << std::endl);
1204  IfDebug(std::cerr << std::endl);
1205 
1206  // -----------------------------------------
1207  // 2. go through each possible completion,
1208  // keeping track of the number of matches
1209  // -----------------------------------------
1210  TList listOfMatches; // list of matches (local filenames only) (insertion order must agree across these 3 lists)
1211  TList listOfFullPaths; // list of matches (full filenames) (insertion order must agree across these 3 lists)
1212  listOfMatches.SetOwner();
1213  listOfFullPaths.SetOwner();
1214 
1215  int nMatches = 0; // number of matches
1216  TObject *pObj; // pointer returned by iterator
1217  TIter next_candidate(pListOfCandidates);
1218  TIter next_match(&listOfMatches);
1219  TIter next_fullpath(&listOfFullPaths);
1220 
1221  // stick all matches into "listOfMatches"
1222  while ((pObj = next_candidate())) {
1223  // get the full filename
1224  const char *s4 = pObj->GetName();
1225 
1226  assert(s4 != 0);
1227 
1228  // pick off tail
1229  const char *s5 = strrchr(s4, '/');
1230  if (!s5)
1231  s5 = s4; // no '/' found
1232  else
1233  s5 += 1; // advance past '/'
1234 
1235  // if case sensitive (normal behaviour), check for match
1236  // if case insensitive, convert to TString and compare case insensitively
1237  if ((cmp == TString::kExact) && (strstr(s5, s3) == s5)) {
1238  nMatches += 1;
1239  listOfMatches.Add(new TObjString(s5));
1240  listOfFullPaths.Add(new TObjString(s4));
1241  IfDebug(std::cerr << "adding " << s5 << '\t' << s4 << std::endl);
1242  } else if (cmp == TString::kIgnoreCase) {
1243  TString ts5(s5);
1244  if (ts5.BeginsWith(s3, cmp))
1245  {
1246  nMatches += 1;
1247  listOfMatches.Add(new TObjString(s5));
1248  listOfFullPaths.Add(new TObjString(s4));
1249  IfDebug(std::cerr << "adding " << s5 << '\t' << s4 << std::endl);
1250  }
1251  } else {
1252 //rdm IfDebug(std::cerr << "considered " << s5 << '\t' << s4 << std::endl);
1253  }
1254 
1255  }
1256 
1257  // -----------------------------------------
1258  // 3. beep, list, or complete
1259  // depending on how many matches were found
1260  // -----------------------------------------
1261 
1262  // 3a. no matches ==> bell
1263  TString partialMatch = "";
1264 
1265  if (nMatches == 0) {
1266  // Ring a bell!
1267  gSystem->Beep();
1268  pos = -1;
1269  goto done; //* RETURN *//
1270  }
1271  // 3b. one or more matches.
1272  char match[1024];
1273 
1274  if (nMatches == 1) {
1275  // get the (lone) match
1276  const char *short_name = next_match()->GetName();
1277  const char *full_name = next_fullpath()->GetName();
1278 
1279  pObj = pListOfCandidates->FindObject(short_name);
1280  if (pObj) {
1281  IfDebug(std::cerr << std::endl << "class: " << pObj->ClassName() << std::endl);
1282  TString className = pObj->ClassName();
1283  if (0);
1284  else if (className == "TMethod" || className == "TFunction") {
1285  TFunction *pFunc = (TFunction *) pObj;
1286  if (0 == pFunc->GetNargs())
1287  appendage = "()"; // no args
1288  else
1289  appendage = "("; // user needs to supply some args
1290  } else if (className == "TDataMember") {
1291  appendage = " ";
1292  }
1293  }
1294 
1295  CopyMatch(match, sizeof(match), short_name, appendage, full_name);
1296  } else {
1297  // multiple matches ==> complete as far as possible
1298  Char_t ch;
1299  Int_t nGoodStrings;
1300 
1301  for (int i = 0;
1302  (ch = AllAgreeOnChar(i, &listOfMatches, nGoodStrings));
1303  i += 1) {
1304  IfDebug(std::cerr << " i=" << i << " ch=" << ch << std::endl);
1305  partialMatch.Append(ch);
1306  }
1307 
1308  const char *s;
1309  const char *s0;
1310 
1311  // multiple matches, but maybe only 1 of them is any good.
1312  if (nGoodStrings == 1) {
1313 
1314  // find the 1 good match
1315  do {
1316  s = next_match()->GetName();
1317  s0 = next_fullpath()->GetName();
1318  }
1319  while (ExcludedByFignore(s));
1320 
1321  // and use it.
1322  CopyMatch(match, sizeof(match), s, appendage, s0);
1323  } else {
1324  IfDebug(std::cerr << "more than 1 GoodString" << std::endl);
1325 
1326  if (partialMatch.Length() > s3.Length())
1327  // this partial match is our (partial) completion.
1328  {
1329  CopyMatch(match, sizeof(match), partialMatch.Data());
1330  } else
1331  // couldn't do any completing at all,
1332  // print a list of all the ambiguous matches
1333  // (except for those excluded by "FileIgnore")
1334  {
1335  IfDebug(std::cerr << "printing ambiguous matches" << std::endl);
1336  std::set<std::string> alreadyPrinted;
1337  while ((pObj = next_match())) {
1338  s = pObj->GetName();
1339  if (alreadyPrinted.insert(s).second) {
1340  // Nothing of that name has been printed yet.
1341  s0 = next_fullpath()->GetName();
1342  if (!ExcludedByFignore(s) || nGoodStrings == 0) {
1343  if (IsDirectory(s0))
1344  out << s << "/" << std::endl;
1345  else
1346  out << s << std::endl;
1347  }
1348  }
1349  }
1350  pos = -2;
1351  if (cmp == TString::kExact || partialMatch.Length() < s3.Length()) {
1352  goto done; //* RETURN *//
1353  } // else:
1354  // update the matching part, will have changed
1355  // capitalization because only cmp == TString::kIgnoreCase
1356  // matches.
1357  CopyMatch(match, sizeof(match), partialMatch.Data());
1358  }
1359  }
1360  }
1361 
1362 
1363  // ---------------------------------------
1364  // 4. finally write text into the buffer.
1365  // ---------------------------------------
1366  {
1367  int i = strlen(fBuf); // old EOL position is i
1368  int l = strlen(match) - (loc - start); // new EOL position will be i+L
1369 
1370  // first check for overflow
1371  if (strlen(fBuf) + strlen(match) + 1 > BUF_SIZE) {
1372  Error("TTabCom::Complete", "buffer overflow");
1373  pos = -2;
1374  goto done; /* RETURN */
1375  }
1376  // debugging output
1377  IfDebug(std::cerr << " i=" << i << std::endl);
1378  IfDebug(std::cerr << " L=" << l << std::endl);
1379  IfDebug(std::cerr << "loc=" << loc << std::endl);
1380 
1381  // slide everything (including the null terminator) over to make space
1382  for (; i >= loc; i -= 1) {
1383  fBuf[i + l] = fBuf[i];
1384  }
1385 
1386  // insert match
1387  strlcpy(fBuf + start, match, BUF_SIZE - start);
1388 
1389  // the "get"->"Get" case of TString::kIgnore sets pos to -2
1390  // and falls through to update the buffer; we need to return
1391  // -2 in that case, so check here:
1392  if (pos != -2) {
1393  pos = loc; // position of first change in "fBuf"
1394  if (cmp == TString::kIgnoreCase && pos < 0) {
1395  // We might have changed somthing before loc, due to differences in
1396  // capitalization. So return start:
1397  pos = start;
1398  }
1399  }
1400  *fpLoc = loc + l; // new cursor position
1401  }
1402 
1403 done: // <----- goto label
1404  // un-init
1405  fpLoc = 0;
1406  fBuf = 0;
1407 
1408  return pos;
1409 }
1410 
1411 ////////////////////////////////////////////////////////////////////////////////
1412 /// [private]
1413 
1414 void TTabCom::CopyMatch(char *dest, int dest_len,
1415  const char *localName,
1416  const char *appendage,
1417  const char *fullName) const
1418 {
1419  // if "appendage" is 0, no appendage is applied.
1420  //
1421  // if "appendage" is of the form "filenameXXX" then,
1422  // "filename" is ignored and "XXX" is taken to be the appendage,
1423  // but it will only be applied if the file is not a directory...
1424  // if the file is a directory, a "/" will be used for the appendage instead.
1425  //
1426  // if "appendage" is of the form "XXX" then "XXX" will be appended to the match.
1427 
1428  assert(dest != 0);
1429  assert(localName != 0);
1430 
1431  // potential buffer overflow.
1432  strlcpy(dest, localName, dest_len);
1433 
1434  const char *key = "filename";
1435  const int key_len = strlen(key);
1436 
1437  IfDebug(std::cerr << "CopyMatch()." << std::endl);
1438  IfDebug(std::cerr << "localName: " << (localName ? localName : "0") <<
1439  std::endl);
1440  IfDebug(std::cerr << "appendage: " << (appendage ? appendage : "0") <<
1441  std::endl);
1442  IfDebug(std::cerr << " fullName: " << (fullName ? fullName : "0") <<
1443  std::endl);
1444 
1445 
1446  // check to see if "appendage" starts with "key"
1447  if (appendage && strncmp(appendage, key, key_len) == 0) {
1448  // filenames get special treatment
1449  appendage += key_len;
1450  IfDebug(std::cerr << "new appendage: " << appendage << std::endl);
1451  if (IsDirectory(fullName)) {
1452  if (fullName)
1453  strlcat(dest, "/", dest_len);
1454  } else {
1455  if (appendage)
1456  strlcat(dest, appendage, dest_len);
1457  }
1458  } else {
1459  if (appendage)
1460  strlcat(dest, appendage, dest_len);
1461  }
1462 }
1463 
1464 ////////////////////////////////////////////////////////////////////////////////
1465 /// [private]
1466 
1468 {
1469  assert(fBuf != 0);
1470 
1471  const char *pStart; // start of match
1472  const char *pEnd; // end of match
1473 
1474  for (int context = 0; context < kNUM_PAT; ++context) {
1475  pEnd = Matchs(fBuf, *fpLoc, fPat[context], &pStart);
1476  if (pEnd) {
1477  IfDebug(std::cerr << std::endl
1478  << "context=" << context << " "
1479  << "RegExp=" << fRegExp[context]
1480  << std::endl);
1481  return EContext_t(context); //* RETURN *//
1482  }
1483  }
1484 
1485  return kUNKNOWN_CONTEXT; //* RETURN *//
1486 }
1487 
1488 ////////////////////////////////////////////////////////////////////////////////
1489 /// [private]
1490 
1492  const char defaultPath[]) const
1493 {
1494  if (PathIsSpecifiedInFileName(fileName)) {
1495  TString path = fileName;
1496  gSystem->ExpandPathName(path);
1497  Int_t end = path.Length()-1;
1498  if (end>0 && path[end]!='/' && path[end]!='\\') {
1499  path = gSystem->GetDirName(path);
1500  }
1501  return path;
1502  } else {
1503  TString newBase, extendedPath;
1504  if (fileName.Contains("/")) {
1505  Int_t end = fileName.Length()-1;
1506  if (fileName[end] != '/' && fileName[end] != '\\') {
1507  newBase = gSystem->GetDirName(fileName);
1508  } else {
1509  newBase = fileName;
1510  }
1511  extendedPath = ExtendPath(defaultPath, newBase);
1512  } else {
1513  newBase = "";
1514  extendedPath = defaultPath;
1515  }
1516  IfDebug(std::cerr << std::endl);
1517  IfDebug(std::cerr << " fileName: " << fileName << std::endl);
1518  IfDebug(std::cerr << " pathBase: " << newBase << std::endl);
1519  if (defaultPath) {
1520  IfDebug(std::cerr << " defaultPath: " << defaultPath << std::endl);
1521  } else {
1522  IfDebug(std::cerr << " defaultPath: " << std::endl);
1523  }
1524  IfDebug(std::cerr << "extendedPath: " << extendedPath << std::endl);
1525  IfDebug(std::cerr << std::endl);
1526 
1527  return extendedPath;
1528  }
1529 }
1530 
1531 ////////////////////////////////////////////////////////////////////////////////
1532 /// [private]
1533 
1534 TString TTabCom::ExtendPath(const char originalPath[], TString newBase) const
1535 {
1536  if (newBase.BeginsWith("/"))
1537  newBase.Remove(TString::kLeading, '/');
1538 #ifdef R__SSTREAM
1539  std::stringstream str;
1540 #else
1541  std::strstream str;
1542 #endif
1543  TString dir;
1544  TString newPath;
1545  if (originalPath) str << originalPath;
1546 
1547  while (str.good())
1548  {
1549  dir = "";
1550  dir.ReadToDelim(str, kDelim);
1551  if (dir.IsNull())
1552  continue; // ignore blank entries
1553  newPath.Append(dir);
1554  if (!newPath.EndsWith("/"))
1555  newPath.Append("/");
1556  newPath.Append(newBase);
1557  newPath.Append(kDelim);
1558  }
1559 
1560  return newPath.Strip(TString::kTrailing, kDelim);
1561 }
1562 
1563 ////////////////////////////////////////////////////////////////////////////////
1564 /// [private]
1565 
1566 Int_t TTabCom::Hook(char *buf, int *pLoc, std::ostream& out)
1567 {
1568  // initialize
1569  fBuf = buf;
1570  fpLoc = pLoc;
1571 
1572  // frodo: iteration counter for recursive MakeClassFromVarName
1573  fLastIter = 0;
1574 
1575  // default
1576  Int_t pos = -2; // position of the first character that was changed in the buffer (needed for redrawing)
1577 
1578  // get the context this tab was triggered in.
1579  EContext_t context = DetermineContext();
1580 
1581  // get the substring that triggered this tab (as defined by "SetPattern()")
1582  const char dummy[] = ".";
1583  TRegexp re1(context == kUNKNOWN_CONTEXT ? dummy : fRegExp[context]);
1584  TString s1(fBuf);
1585  TString s2 = s1(0, *fpLoc);
1586  TString s3 = s2(re1);
1587 
1588  switch (context) {
1589  case kUNKNOWN_CONTEXT:
1590  std::cerr << std::endl << "tab completion not implemented for this context" <<
1591  std::endl;
1592  pos = -2;
1593  break;
1594 
1595  case kSYS_UserName:
1596  {
1597  const TSeqCollection *pListOfUsers = GetListOfUsers();
1598 
1599  pos = Complete("[^~]*$", pListOfUsers, "/", out);
1600  }
1601  break;
1602  case kSYS_EnvVar:
1603  {
1604  const TSeqCollection *pEnv = GetListOfEnvVars();
1605 
1606  pos = Complete("[^$]*$", pEnv, "", out);
1607  }
1608  break;
1609 
1610  case kCINT_stdout:
1611  case kCINT_stderr:
1612  case kCINT_stdin:
1613  {
1614  const TString fileName = s3("[^ ><]*$");
1615  const TString filePath = DeterminePath(fileName,0);
1616  const TSeqCollection *pListOfFiles =
1617  GetListOfFilesInPath(filePath.Data());
1618 
1619 // pos = Complete( "[^ /]*$", pListOfFiles, " ", out );
1620  pos = Complete("[^ /]*$", pListOfFiles, "filename ", out);
1621  }
1622  break;
1623 
1624  case kCINT_Edit:
1625  case kCINT_Load:
1626  case kCINT_Exec:
1627  case kCINT_EXec:
1628  {
1629  const TString fileName = s3("[^ ]*$");
1630  const TString macroPath =
1631  DeterminePath(fileName, TROOT::GetMacroPath());
1632  const TSeqCollection *pListOfFiles =
1633  GetListOfFilesInPath(macroPath.Data());
1634 
1635 // pos = Complete( "[^ /]*$", pListOfFiles, " ", out);
1636  pos = Complete("[^ /]*$", pListOfFiles, "filename ", out);
1637  }
1638  break;
1639 
1640  case kCINT_pragma:
1641  {
1642  pos = Complete("[^ ]*$", GetListOfPragmas(), "", out);
1643  }
1644  break;
1645  case kCINT_includeSYS:
1646  {
1647  TString fileName = s3("[^<]*$");
1648  if (PathIsSpecifiedInFileName(fileName) || fileName.Contains("/")) {
1649  TString includePath =
1650  DeterminePath(fileName, GetSysIncludePath());
1651 
1652 // pos = Complete( "[^</]*$", GetListOfFilesInPath( includePath ), "> ", out);
1653  pos =
1654  Complete("[^</]*$", GetListOfFilesInPath(includePath),
1655  "filename> ", out);
1656  } else {
1657 // pos = Complete( "[^</]*$", GetListOfSysIncFiles(), "> ", out);
1658  pos =
1659  Complete("[^</]*$", GetListOfSysIncFiles(), "filename> ", out);
1660  }
1661  }
1662  break;
1663  case kCINT_includePWD:
1664  {
1665  const TString fileName = s3("[^\"]*$");
1666  const TString includePath = DeterminePath(fileName, ".");
1667  const TSeqCollection *pListOfFiles =
1668  GetListOfFilesInPath(includePath.Data());
1669 
1670 // pos = Complete( "[^\"/]*$", pListOfFiles, "\" ", out);
1671  pos = Complete("[^\"/]*$", pListOfFiles, "filename\" ", out);
1672  }
1673  break;
1674 
1675  case kCINT_cpp:
1676  {
1677  pos = Complete("[^# ]*$", GetListOfCppDirectives(), " ", out);
1678  }
1679  break;
1680 
1681  case kROOT_Load:
1682  {
1683  const TString fileName = s3("[^\"]*$");
1684  const TString dynamicPath = DeterminePath(fileName, gSystem->GetDynamicPath());
1685  const TSeqCollection *pListOfFiles = GetListOfFilesInPath(dynamicPath);
1686 
1687 // pos = Complete( "[^\"/]*$", pListOfFiles, "\");", out);
1688  pos = Complete("[^\"/]*$", pListOfFiles, "filename\");", out);
1689  }
1690  break;
1691 
1692  case kSYS_FileName:
1693  {
1694  const TString fileName = s3("[^ \"]*$");
1695  const TString filePath = DeterminePath(fileName,".");
1696  const TSeqCollection *pListOfFiles = GetListOfFilesInPath(filePath.Data());
1697 
1698  pos = Complete("[^\" /]*$", pListOfFiles, "filename\"", out);
1699  }
1700  break;
1701 
1702  case kCXX_ScopeMember:
1703  {
1704  const EContext_t original_context = context; // save this for later
1705 
1706  TClass *pClass;
1707  // may be a namespace, class, object, or pointer
1708  TString name = s3("^[_a-zA-Z][_a-zA-Z0-9]*");
1709 
1710  IfDebug(std::cerr << std::endl);
1711  IfDebug(std::cerr << "name: " << '"' << name << '"' << std::endl);
1712 
1713  // We need to decompose s3 a little more:
1714  // The part name is the partial symbol at the end of ::
1715  // eg. given s3 = "foo::bar::part" , partname = "part"
1716  TString partname = s3("[_a-zA-Z][_a-zA-Z0-9]*$");
1717 
1718  // The prefix, considering the s3 = "foo::bar::part" example would be
1719  // prefix = "foo::bar::". prefix equals the empty string if there is only one
1720  // or no set of colons in s3.
1721  // Note: we reconstruct the fully qualified name with a while loop because
1722  // it does not seem that TRegexp can handle something like "([_a-zA-Z][_a-zA-Z0-9]*::)+$"
1723  TString prefix = "";
1724  TString str = s2;
1725  str.Remove(str.Length() - partname.Length(), partname.Length());
1726  while (1) {
1727  TString sym = str("[_a-zA-Z][_a-zA-Z0-9]*::$");
1728  if (sym.Length() == 0)
1729  break;
1730  str.Remove(str.Length() - sym.Length(), sym.Length());
1731  prefix = sym + prefix;
1732  }
1733 
1734  // Not the preprefix would be = "foo::" from our previous example or the empty
1735  // string, "" if there is only one or no set of colons in prefix, eg. prefix = "bar::"
1736  TString preprefix = prefix;
1737  TString sym = prefix("[_a-zA-Z][_a-zA-Z0-9]*::$");
1738  preprefix.Remove(preprefix.Length() - sym.Length(), sym.Length());
1739 
1740  IfDebug(std::cerr << "prefix: " << '"' << prefix << '"' << std::endl);
1741  IfDebug(std::cerr << "preprefix: " << '"' << preprefix << '"' << std::endl);
1742 
1743  TString namesp = prefix;
1744  if (namesp.Length() >= 2)
1745  namesp.Remove(namesp.Length() - 2, 2); // Remove the '::' at the end of the string.
1746  IfDebug(std::cerr << "namesp: " << '"' << namesp << '"' << std::endl);
1747 
1748  // Make sure autoloading happens (if it can).
1749  TryMakeClassFromClassName(namesp);
1750 
1751  TContainer *pList = new TContainer;
1752  // Add all classes to pList that contain the prefix, i.e. are in the
1753  // specified namespace.
1754  const TSeqCollection *tmp = GetListOfClasses();
1755  if (!tmp) break;
1756 
1757  Int_t i;
1758  for (i = 0; i < tmp->GetSize(); i++) {
1759  TString astr = ((TObjString *) tmp->At(i))->String();
1760  TString rxp = "^";
1761  rxp += prefix;
1762  if (astr.Contains(TRegexp(rxp))) {
1763  astr.Remove(0, prefix.Length());
1764  TString s = astr("^[^: ]*");
1765  TObjString *ostr = new TObjString(s);
1766  if (!pList->Contains(ostr))
1767  pList->Add(ostr);
1768  else
1769  delete ostr;
1770  }
1771  }
1772 
1773  // If a class with the same name as the Namespace name exists then
1774  // add it to the pList. (I don't think the C++ spec allows for this
1775  // but do this anyway, cant harm).
1776  pClass = TryMakeClassFromClassName(preprefix + name);
1777  if (pClass) {
1778  pList->AddAll(pClass->GetListOfAllPublicMethods(true));
1779  pList->AddAll(pClass->GetListOfAllPublicDataMembers(true));
1780  }
1781 
1782  pos = Complete("[^: ]*$", pList, "", out);
1783 
1784  delete pList;
1785 
1786  if (context != original_context)
1787  pos = -2;
1788  }
1789  break;
1790 
1791  case kCXX_DirectMember:
1792  case kCXX_IndirectMember:
1793  {
1794  const EContext_t original_context = context; // save this for later
1795 
1796  TClass *pClass;
1797 
1798  // frodo: Instead of just passing the last portion of the string to
1799  // MakeClassFromVarName(), we now pass the all string and let
1800  // it decide how to handle it... I know it's not the best way
1801  // because of the context handling, but I wanted to "minimize"
1802  // the changes to the current code and this seemed the best way
1803  // to do it
1804  TString name = s1("[_a-zA-Z][-_a-zA-Z0-9<>():.]*$");
1805 
1806  IfDebug(std::cerr << std::endl);
1807  IfDebug(std::cerr << "name: " << '"' << name << '"' << std::endl);
1808 
1809  switch (context) {
1810  case kCXX_DirectMember:
1811  pClass = MakeClassFromVarName(name, context);
1812  break;
1813  case kCXX_IndirectMember:
1814  pClass = MakeClassFromVarName(name, context);
1815  break;
1816  default:
1817  Fatal("TTabCom::Hook","Conext case %d not handled",context);
1818  return 0; // Avoid warning about uninitialized pClass.
1819  }
1820  if (!pClass) {
1821  pos = -2;
1822  break;
1823  }
1824 
1825  TContainer *pList = new TContainer;
1826 
1827  pList->AddAll(pClass->GetListOfAllPublicMethods());
1828  pList->AddAll(pClass->GetListOfAllPublicDataMembers());
1829 
1830  switch (context) {
1831  case kCXX_DirectMember:
1832  {
1833  int* store_fpLoc = fpLoc;
1834  char* store_fBuf = fBuf;
1835  pos = Complete("[^. ]*$", pList, "(", out);
1836  if (pos == -1) {
1837  fpLoc = store_fpLoc;
1838  fBuf = store_fBuf;
1839  pos = Complete("[^. ]*$", pList, "(", out, TString::kIgnoreCase);
1840  }
1841  break;
1842  }
1843  case kCXX_IndirectMember:
1844  pos = Complete("[^> ]*$", pList, "(", out);
1845  break;
1846  default:
1847  Fatal("TTabCom::Hook","Conext case %d not handled",context);
1848  return 0; // Avoid warning about uninitialized pClass.
1849  }
1850 
1851  delete pList;
1852 
1853  if (context != original_context)
1854  pos = -2;
1855  }
1856  break;
1857 
1858  case kCXX_ScopeProto:
1859  {
1860  const EContext_t original_context = context; // save this for later
1861 
1862  // get class
1863  TClass *pClass;
1864  TString name = s3("^[_a-zA-Z][_a-zA-Z0-9]*");
1865  // "name" may now be the name of a class, object, or pointer
1866 
1867  IfDebug(std::cerr << std::endl);
1868  IfDebug(std::cerr << "name: " << '"' << name << '"' << std::endl);
1869 
1870  // We need to decompose s3 a little more:
1871  // The partname is the method symbol and a bracket at the end of ::
1872  // eg. given s3 = "foo::bar::part(" , partname = "part("
1873  TString partname = s3("[_a-zA-Z][_a-zA-Z0-9]* *($");
1874 
1875  // The prefix, considering the s3 = "foo::bar::part" example would be
1876  // prefix = "foo::bar::". prefix equals the empty string if there is only one
1877  // or no set of colons in s3.
1878  // Note: we reconstruct the fully qualified name with a while loop because
1879  // it does not seem that TRegexp can handle something like "([_a-zA-Z][_a-zA-Z0-9]*::)+$"
1880  TString prefix = "";
1881  TString str = s2;
1882  str.Remove(str.Length() - partname.Length(), partname.Length());
1883  while (1) {
1884  TString sym = str("[_a-zA-Z][_a-zA-Z0-9]*::$");
1885  if (sym.Length() == 0)
1886  break;
1887  str.Remove(str.Length() - sym.Length(), sym.Length());
1888  prefix = sym + prefix;
1889  }
1890 
1891  // Not the preprefix would be = "foo::" from our previous example or the empty
1892  // string, "" if there is only one or no set of colons in prefix, eg. prefix = "bar::"
1893  TString preprefix = prefix;
1894  TString sym = prefix("[_a-zA-Z][_a-zA-Z0-9]*::$");
1895  preprefix.Remove(preprefix.Length() - sym.Length(), sym.Length());
1896 
1897  IfDebug(std::cerr << "prefix: " << '"' << prefix << '"' << std::endl);
1898  IfDebug(std::cerr << "preprefix: " << '"' << preprefix << '"' << std::endl);
1899 
1900  pClass = MakeClassFromClassName(preprefix + name);
1901  if (!pClass) {
1902  pos = -2;
1903  break;
1904  }
1905  // get method name
1906  TString methodName;
1907 
1908  // (normal member function)
1909  methodName = s3("[^:>\\.(]*($");
1910  methodName.Chop();
1911  methodName.Remove(TString::kTrailing, ' ');
1912 
1913  IfDebug(std::cerr << methodName << std::endl);
1914 
1915  // get methods
1916  TContainer *pList = new TContainer;
1917  pList->AddAll(pClass->GetListOfAllPublicMethods());
1918 
1919  // print prototypes
1920  Bool_t foundOne = kFALSE;
1921  TIter nextMethod(pList);
1922  TMethod *pMethod;
1923  while ((pMethod = (TMethod *) nextMethod())) {
1924  if (methodName == pMethod->GetName()) {
1925  foundOne = kTRUE;
1926  out << pMethod->GetReturnTypeName()
1927  << " " << pMethod->GetName()
1928  << pMethod->GetSignature();
1929  const char *comment = pMethod->GetCommentString();
1930  if (comment && comment[0] != '\0') {
1931  out << " \t// " << comment;
1932  }
1933  out << std::endl;
1934  }
1935  }
1936 
1937  // done
1938  if (foundOne) {
1939  pos = -2;
1940  } else {
1941  gSystem->Beep();
1942  pos = -1;
1943  }
1944 
1945  // cleanup
1946  delete pList;
1947 
1948  if (context != original_context)
1949  pos = -2;
1950  }
1951  break;
1952 
1953  case kCXX_DirectProto:
1954  case kCXX_IndirectProto:
1955  case kCXX_NewProto:
1956  case kCXX_ConstructorProto:
1957  {
1958  const EContext_t original_context = context; // save this for later
1959 
1960  // get class
1961  TClass *pClass;
1962  TString name;
1963  if (context == kCXX_NewProto) {
1964  name = s3("[_a-zA-Z][_a-zA-Z0-9:]* *($", 3);
1965  name.Chop();
1966  name.Remove(TString::kTrailing, ' ');
1967  // "name" should now be the name of a class
1968  } else {
1969  name = s3("^[_a-zA-Z][_a-zA-Z0-9:]*");
1970  // "name" may now be the name of a class, object, or pointer
1971  }
1972  IfDebug(std::cerr << std::endl);
1973  IfDebug(std::cerr << "name: " << '"' << name << '"' << std::endl);
1974 
1975  // frodo: Again, passing the all string
1976  TString namerec = s1;
1977 
1978  switch (context) {
1979  case kCXX_ScopeProto:
1980  pClass = MakeClassFromClassName(name);
1981  break;
1982  case kCXX_DirectProto:
1983  pClass = MakeClassFromVarName(namerec, context); // frodo
1984  break;
1985  case kCXX_IndirectProto:
1986  pClass = MakeClassFromVarName(namerec, context); // frodo
1987  break;
1988  case kCXX_NewProto:
1989  pClass = MakeClassFromClassName(name);
1990  break;
1991  case kCXX_ConstructorProto:
1992  pClass = MakeClassFromClassName(name);
1993  break;
1994  default:
1995  Fatal("TTabCom::Hook","Conext case %d not handled",context);
1996  return 0; // Avoid warning about uninitialized pClass.
1997  }
1998  if (!pClass) {
1999  pos = -2;
2000  break;
2001  }
2002  // get method name
2003  TString methodName;
2004  if (context == kCXX_ConstructorProto || context == kCXX_NewProto) {
2005  // (constructor)
2006  methodName = name("[_a-zA-Z][_a-zA-Z0-9]*$");
2007  } else {
2008  // (normal member function)
2009  methodName = s3("[^:>\\.(]*($");
2010  methodName.Chop();
2011  methodName.Remove(TString::kTrailing, ' ');
2012  }
2013  IfDebug(std::cerr << methodName << std::endl);
2014 
2015  // get methods
2016  TContainer *pList = new TContainer;
2017  pList->AddAll(pClass->GetListOfAllPublicMethods());
2018 
2019  // print prototypes
2020  Bool_t foundOne = kFALSE;
2021  TIter nextMethod(pList);
2022  TMethod *pMethod;
2023  while ((pMethod = (TMethod *) nextMethod())) {
2024  if (methodName == pMethod->GetName()) {
2025  foundOne = kTRUE;
2026  out << pMethod->GetReturnTypeName()
2027  << " " << pMethod->GetName()
2028  << pMethod->GetSignature();
2029  const char *comment = pMethod->GetCommentString();
2030  if (comment && comment[0] != '\0') {
2031  out << " \t// " << comment;
2032  }
2033  out << std::endl;
2034  }
2035  }
2036 
2037  // done
2038  if (foundOne) {
2039  pos = -2;
2040  } else {
2041  gSystem->Beep();
2042  pos = -1;
2043  }
2044 
2045  // cleanup
2046  delete pList;
2047 
2048  if (context != original_context)
2049  pos = -2;
2050  }
2051  break;
2052 
2053  case kCXX_Global:
2054  {
2055  // first need to veto a few possibilities.
2056  int l2 = s2.Length(), l3 = s3.Length();
2057 
2058  // "abc().whatever[TAB]"
2059  if (l2 > l3 && s2[l2 - l3 - 1] == '.') {
2060  std::cerr << std::endl <<
2061  "tab completion not implemented for this context" << std::endl;
2062  break; // veto
2063  }
2064  // "abc()->whatever[TAB]"
2065  if (l2 > l3 + 1 && s2(l2 - l3 - 2, 2) == "->") {
2066  std::cerr << std::endl <<
2067  "tab completion not implemented for this context" << std::endl;
2068  break; // veto
2069  }
2070 
2071  TContainer *pList = new TContainer;
2072 
2073  const TSeqCollection *pL2 = GetListOfClasses();
2074  if (pL2) pList->AddAll(pL2);
2075 
2076  //
2077  const TSeqCollection *pC1 = GetListOfGlobals();
2078  if (pC1) pList->AddAll(pC1);
2079  //
2081  if (pC3) pList->AddAll(pC3);
2082 
2083  pos = Complete("[_a-zA-Z][_a-zA-Z0-9]*$", pList, "", out);
2084 
2085  delete pList;
2086  }
2087  break;
2088 
2089  case kCXX_GlobalProto:
2090  {
2091  // get function name
2092  TString functionName = s3("[_a-zA-Z][_a-zA-Z0-9]*");
2093  IfDebug(std::cerr << functionName << std::endl);
2094 
2095  TContainer listOfMatchingGlobalFuncs;
2096  TIter nextGlobalFunc(GetListOfGlobalFunctions());
2097  TObject *pObj;
2098  while ((pObj = nextGlobalFunc())) {
2099  if (strcmp(pObj->GetName(), functionName) == 0) {
2100  listOfMatchingGlobalFuncs.Add(pObj);
2101  }
2102  }
2103 
2104  if (listOfMatchingGlobalFuncs.IsEmpty()) {
2105  std::cerr << std::endl << "no such function: " << dblquote(functionName)
2106  << std::endl;
2107  } else {
2108  TIter next(&listOfMatchingGlobalFuncs);
2109  TFunction *pFunction;
2110  while ((pFunction = (TFunction *) next())) {
2111  out << pFunction->GetReturnTypeName()
2112  << " " << pFunction->GetName()
2113  << pFunction->GetSignature()
2114  << std::endl;
2115  }
2116  }
2117 
2118  pos = -2;
2119  }
2120  break;
2121 
2122  /******************************************************************/
2123  /* */
2124  /* default: should never happen */
2125  /* */
2126  /******************************************************************/
2127  default:
2128  Fatal("TTabCom::Hook","Conext case %d not handled",context);
2129  return 0; // Avoid warning about uninitialized pClass.
2130  }
2131 
2132  return pos;
2133 }
2134 
2135 ////////////////////////////////////////////////////////////////////////////////
2136 /// [private]
2137 
2139 {
2140  // add more patterns somewhere below.
2141  // add corresponding enum to "EContext_t"
2142  //
2143  // note:
2144  // 1. in some cases order is important ...
2145  //
2146  // the order of the "case" statements in "switch( context )" in "TTabCom::Hook()" is Not important.
2147  //
2148  // the order of the "SetPattern()" function calls below is Not important.
2149  //
2150  // the order of the initializers in the "EContext_t" enumeration Is important
2151  // because DetermineContext() goes through the array in order, and returns at the first match.
2152  //
2153  // 2. below, "$" will match cursor position
2154 
2155  SetPattern(kSYS_UserName, "~[_a-zA-Z0-9]*$");
2156  SetPattern(kSYS_EnvVar, "$[_a-zA-Z0-9]*$");
2157 
2158  SetPattern(kCINT_stdout, "; *>>?.*$"); // stdout
2159  SetPattern(kCINT_stderr, "; *2>>?.*$"); // stderr
2160  SetPattern(kCINT_stdin, "; *<.*$"); // stdin
2161 
2162  SetPattern(kCINT_Edit, "^ *\\.E .*$");
2163  SetPattern(kCINT_Load, "^ *\\.L .*$");
2164  SetPattern(kCINT_Exec, "^ *\\.x +[-0-9_a-zA-Z~$./]*$");
2165  SetPattern(kCINT_EXec, "^ *\\.X +[-0-9_a-zA-Z~$./]*$");
2166 
2167  SetPattern(kCINT_pragma, "^# *pragma +[_a-zA-Z0-9]*$");
2168  SetPattern(kCINT_includeSYS, "^# *include *<[^>]*$"); // system files
2169  SetPattern(kCINT_includePWD, "^# *include *\"[^\"]*$"); // local files
2170 
2171  SetPattern(kCINT_cpp, "^# *[_a-zA-Z0-9]*$");
2172 
2173  SetPattern(kROOT_Load, "gSystem *-> *Load *( *\"[^\"]*$");
2174 
2175  SetPattern(kCXX_NewProto, "new +[_a-zA-Z][_a-zA-Z0-9:]* *($");
2177  "[_a-zA-Z][_a-zA-Z0-9:]* +[_a-zA-Z][_a-zA-Z0-9]* *($");
2179  "[_a-zA-Z][_a-zA-Z0-9]* *:: *[_a-zA-Z0-9]* *($");
2181  "[_a-zA-Z][_a-zA-Z0-9()]* *\\. *[_a-zA-Z0-9]* *($");
2183  "[_a-zA-Z][_a-zA-Z0-9()]* *-> *[_a-zA-Z0-9]* *($");
2184 
2186  "[_a-zA-Z][_a-zA-Z0-9]* *:: *[_a-zA-Z0-9]*$");
2188  "[_a-zA-Z][_a-zA-Z0-9()]* *\\. *[_a-zA-Z0-9()]*$"); //
2189 
2191  "[_a-zA-Z][_a-zA-Z0-9()]* *-> *[_a-zA-Z0-9()]*$"); // frodo
2192 
2193  SetPattern(kSYS_FileName, "\"[-0-9_a-zA-Z~$./]*$");
2194  SetPattern(kCXX_Global, "[_a-zA-Z][_a-zA-Z0-9]*$");
2195  SetPattern(kCXX_GlobalProto, "[_a-zA-Z][_a-zA-Z0-9]* *($");
2196 }
2197 
2198 ////////////////////////////////////////////////////////////////////////////////
2199 /// [private]
2200 /// (does some specific error handling that makes the function unsuitable for general use.)
2201 /// returns a new'd TClass given the name of a class.
2202 /// user must delete.
2203 /// returns 0 in case of error.
2204 
2205 TClass *TTabCom::MakeClassFromClassName(const char className[]) const
2206 {
2207  // the TClass constructor will print a Warning message for classes that don't exist
2208  // so, ignore warnings temporarily.
2209  NoMsg(kWarning);
2210  TClass *pClass = TClass::GetClass(className);
2211  NoMsg(-1);
2212 
2213  if (!pClass){
2214  Error("TTabCom::MakeClassFromClassName", "Unknown class \"%s\"", className);
2215  return nullptr;
2216  }
2217 
2218  // make sure "className" exists
2219  // if (pClass->Size() == 0) { //namespace has 0 size
2220  if (pClass->GetListOfAllPublicMethods()->GetSize() == 0 &&
2221  pClass->GetListOfAllPublicDataMembers()->GetSize() == 0) {
2222  // i'm assuming this happens iff there was some error.
2223  // (misspelled the class name, for example)
2224  Error("TTabCom::MakeClassFromClassName", "class \"%s\" is not defined.", className);
2225  return 0;
2226  }
2227 
2228  return pClass;
2229 }
2230 
2231 ////////////////////////////////////////////////////////////////////////////////
2232 /// Same as above but does not print the error message.
2233 
2234 TClass *TTabCom::TryMakeClassFromClassName(const char className[]) const
2235 {
2236  // the TClass constructor will print a Warning message for classes that don't exist
2237  // so, ignore warnings temporarily.
2238  NoMsg(kWarning);
2239  TClass *pClass = TClass::GetClass(className);
2240  NoMsg(-1);
2241 
2242  return pClass;
2243 }
2244 
2245 ////////////////////////////////////////////////////////////////////////////////
2246 /// [private]
2247 /// (does some specific error handling that makes the function unsuitable for general use.)
2248 /// returns a new'd TClass given the name of a variable.
2249 /// user must delete.
2250 /// returns 0 in case of error.
2251 /// if user has operator.() or operator->() backwards, will modify: context, *fpLoc and fBuf.
2252 /// context sensitive behavior.
2253 
2255  EContext_t & context, int iter)
2256 {
2257  // frodo:
2258  // Because of the Member and Proto recursion, this has become a bit
2259  // complicated, so here is how it works:
2260  //
2261  // root [1] var.a.b.c[TAB]
2262  //
2263  // will generate the sucessive calls:
2264  // MakeClassFromVarName("var.a.b.c", context, 0) returns the class of "c"
2265  // MakeClassFromVarName("var.a.b", context, 1) returns the class of "b"
2266  // MakeClassFromVarName("var.a", context, 2) returns the class of "a"
2267  // MakeClassFromVarName("var", context, 3)
2268 
2269  // need to make sure "varName" exists
2270  // because "DetermineClass()" prints clumsy error message otherwise.
2271  Bool_t varName_exists = GetListOfGlobals()->Contains(varName) || // check in list of globals first.
2272  (gROOT->FindObject(varName) != 0); // then check CINT "shortcut #3"
2273 
2274 
2275  //
2276  // frodo: Member and Proto recursion code
2277  //
2278  if (0) printf("varName is [%s] with iteration [%i]\n", varName, iter);
2279 
2280  // ParseReverse will return 0 if there are no "." or "->" in the varName
2281  Int_t cut = ParseReverse(varName, strlen(varName));
2282 
2283  // If it's not a "simple" variable and if there is at least one "." or "->"
2284  if (!varName_exists && cut != 0)
2285  {
2286  TString parentName = varName;
2287  TString memberName = varName;
2288 
2289  // Check to see if this is the last call (last member/method)
2290  if (iter > fLastIter) fLastIter = iter;
2291 
2292  parentName[cut] = 0;
2293  if (0) printf("Parent string is [%s]\n", parentName.Data());
2294 
2295  // We are treating here cases like h->SetXTitle(gROOT->Get<TAB>
2296  // i.e. when the parentName has an unbalanced number of paranthesis.
2297  if (cut>2) {
2298  UInt_t level = 0;
2299  for(Int_t i = cut-1; i>=0; --i) {
2300  switch (parentName[i]) {
2301  case '(':
2302  if (level) --level;
2303  else {
2304  parentName = parentName(i+1,cut-i-1);
2305  i = 0;
2306  }
2307  break;
2308  case ')':
2309  ++level; break;
2310  }
2311  }
2312  }
2313 
2314  TClass *pclass;
2315  // Can be "." or "->"
2316  if (varName[cut] == '.') {
2317  memberName = varName+cut+1;
2318  if (0) printf("Member/method is [%s]\n", memberName.Data());
2319  EContext_t subcontext = kCXX_DirectMember;
2320  pclass = MakeClassFromVarName(parentName.Data(), subcontext, iter+1);
2321  } else {
2322  memberName = varName+cut+2;
2323  if (0) printf("Member/method is [%s]\n", memberName.Data());
2324  EContext_t subcontext = kCXX_IndirectMember;
2325  pclass = MakeClassFromVarName(parentName.Data(), subcontext, iter+1);
2326  }
2327 
2328  if (0) printf("I got [%s] from MakeClassFromVarName()\n", pclass->GetName());
2329 
2330  if (pclass)
2331  {
2332  if (0) printf("Variable [%s] exists!\n", parentName.Data());
2333 
2334  // If it's back in the first call of the function, return immediatly
2335  if (iter == 0) return pclass;
2336 
2337  if (0) printf("Trying data member [%s] of class [%s] ...\n",
2338  memberName.Data(), pclass->GetName());
2339 
2340  // Check if it's a member
2341  TDataMember *dmptr = 0; //pclass->GetDataMember(memberName.Data());
2342  TIter next(pclass->GetListOfAllPublicDataMembers());
2343  while ((dmptr = (TDataMember *) next())) {
2344  if (memberName == dmptr->GetName()) break;
2345  }
2346  if (dmptr)
2347  {
2348  if (0) printf("It's a member!\n");
2349 
2350  TString returnName = dmptr->GetTypeName();
2351  // if (returnName[returnName.Length()-1] == '*')
2352  // printf("It's a pointer!\n");
2353 
2354  TClass *mclass = TClass::GetClass(returnName.Data());
2355  return mclass;
2356  }
2357 
2358 
2359  // Check if it's a proto: must have ()
2360  // This might not be too safe to use :(
2361  char *parentesis_ptr = (char*)strrchr(memberName.Data(), '(');
2362  if (parentesis_ptr) *parentesis_ptr = 0;
2363 
2364 
2365  if (0) printf("Trying method [%s] of class [%s] ...\n",
2366  memberName.Data(), pclass->GetName());
2367 
2368  // Check if it's a method
2369  TMethod *mptr = 0; // pclass->GetMethodAny(memberName.Data());
2370  const TList *mlist = pclass->GetListOfAllPublicMethods();
2371  next = mlist;
2372  while ((mptr = (TMethod *) next())) {
2373  if (strcmp(memberName.Data(),mptr->GetName())==0) break;
2374  }
2375  if (mptr)
2376  {
2377  TString returnName = mptr->GetReturnTypeName();
2378 
2379  if (0) printf("It's a method called [%s] with return type [%s]\n",
2380  memberName.Data(), returnName.Data());
2381 
2382  // This will handle the methods that returns a pointer to a class
2383  if (returnName[returnName.Length()-1] == '*')
2384  {
2385  returnName[returnName.Length()-1] = 0;
2386  fVarIsPointer = kTRUE;
2387  }
2388  else
2389  {
2391  }
2392 
2393  TClass *mclass = TClass::GetClass(returnName.Data());
2394  return mclass;
2395  }
2396  }
2397  }
2398 
2399  //
2400  // frodo: End of Member and Proto recursion code
2401  //
2402 
2403 
2404  // not found...
2405  if (!varName_exists) {
2406  std::cerr << std::endl << "variable " << dblquote(varName) << " not defined."
2407  << std::endl;
2408  return 0; //* RETURN *//
2409  }
2410 
2411  /*****************************************************************************************/
2412  /* */
2413  /* this section is really ugly. */
2414  /* and slow. */
2415  /* it could be made a lot better if there was some way to tell whether or not a given */
2416  /* variable is a pointer or a pointer to a pointer. */
2417  /* */
2418  /*****************************************************************************************/
2419 
2420  TString className = DetermineClass(varName);
2421 
2422  if (className.IsNull() || className == "*") {
2423  // this will happen if "varName" is a fundamental type (as opposed to class type).
2424  // or a pointer to a pointer.
2425  // or a function pointer.
2426  std::cerr << std::endl << "problem determining class of " << dblquote(varName)
2427  << std::endl;
2428  return 0; //* RETURN *//
2429  }
2430 
2431  fVarIsPointer = className[className.Length() - 1] == '*';
2432 
2433  // frodo: I shouldn't have to do this, but for some reason now I have to
2434  // otherwise the varptr->[TAB] won't work :(
2435  if (fVarIsPointer || className[className.Length() - 1] == '&')
2436  className[className.Length()-1] = 0;
2437 
2438  // frodo case '.' dealt with in the previous if statement?!
2439  // frodo: I wasn't able to put the automatic "." to "->" replacing working
2440  // so I just commented out.
2441  //
2442 
2443 
2444  // Bool_t varIsPointer = className[className.Length() - 1] == '*';
2445 
2446  //printf("Context is %i, fContext is %i, pointer is %i\n", context, fContext, fVarIsPointer);
2447 
2448  if (fVarIsPointer &&
2449  (context == kCXX_DirectMember || context == kCXX_DirectProto)) {
2450  // user is using operator.() instead of operator->()
2451  // ==>
2452  // 1. we are in wrong context.
2453  // 2. user is lazy
2454  // 3. or maybe confused
2455 
2456  // 1. fix the context
2457  switch (context) {
2458  case kCXX_DirectMember:
2459  context = kCXX_IndirectMember;
2460  break;
2461  case kCXX_DirectProto:
2462  context = kCXX_IndirectProto;
2463  break;
2464  default:
2465  Fatal("TTabCom::MakeClassFromVarName","Conext case %d not handled",context);
2466  return 0; // Avoid warning about uninitialized pClass.
2467  }
2468 
2469  // 2. fix the operator.
2470  int i;
2471  for (i = *fpLoc; fBuf[i] != '.'; i -= 1) {
2472  }
2473  int loc = i;
2474  for (i = strlen(fBuf); i >= loc; i -= 1) {
2475  fBuf[i + 1] = fBuf[i];
2476  }
2477  fBuf[loc] = '-';
2478  fBuf[loc + 1] = '>';
2479  *fpLoc += 1;
2480 
2481  // 3. inform the user.
2482  std::cerr << std::endl << dblquote(varName) <<
2483  " is of pointer type. Use this operator: ->" << std::endl;
2484  return 0;
2485  }
2486 
2487  if (context == kCXX_IndirectMember || context == kCXX_IndirectProto) {
2488  if (fVarIsPointer) {
2489  // frodo: This part no longer makes sense...
2490  className.Chop(); // remove the '*'
2491 
2492  if (className[className.Length() - 1] == '*') {
2493  std::cerr << std::endl << "can't handle pointers to pointers." << std::endl;
2494  return 0; // RETURN
2495  }
2496  } else {
2497  // user is using operator->() instead of operator.()
2498  // ==>
2499  // 1. we are in wrong context.
2500  // 2. user is lazy
2501  // 3. or maybe confused
2502 
2503  // 1. fix the context
2504  switch (context) {
2505  case kCXX_IndirectMember:
2506  context = kCXX_DirectMember;
2507  break;
2508  case kCXX_IndirectProto:
2509  context = kCXX_DirectProto;
2510  break;
2511  default:
2512  Fatal("TTabCom::MakeClassFromVarName","Conext case %d not handled",context);
2513  return 0; // Avoid warning about uninitialized pClass.
2514  }
2515 
2516  // 2. fix the operator.
2517  int i;
2518  for (i = *fpLoc; fBuf[i - 1] != '-' && fBuf[i] != '>'; i -= 1) {
2519  }
2520  fBuf[i - 1] = '.';
2521  int len = strlen(fBuf);
2522  for (; i < len; i += 1) {
2523  fBuf[i] = fBuf[i + 1];
2524  }
2525  *fpLoc -= 1;
2526 
2527  // 3. inform the user.
2528  std::cerr << std::endl << dblquote(varName) <<
2529  " is not of pointer type. Use this operator: ." << std::endl;
2530  return 0;
2531  }
2532  }
2533 
2534  className.Strip(TString::kBoth);
2535 
2536  return TClass::GetClass(className);
2537 }
2538 
2539 ////////////////////////////////////////////////////////////////////////////////
2540 /// [private]
2541 
2542 void TTabCom::SetPattern(EContext_t handle, const char regexp[])
2543 {
2544  // prevent overflow
2545  if (handle >= kNUM_PAT) {
2546  std::cerr << std::endl
2547  << "ERROR: handle="
2548  << (int) handle << " >= kNUM_PAT=" << (int) kNUM_PAT << std::endl;
2549  return;
2550  }
2551 
2552  fRegExp[handle] = regexp;
2553  Makepat(regexp, fPat[handle], MAX_LEN_PAT);
2554 }
2555 
2556 
2557 
2558 ////////////////////////////////////////////////////////////////////////////////
2559 ///
2560 /// Returns the place in the string where to put the \0, starting the search
2561 /// from "start"
2562 ///
2563 
2564 int TTabCom::ParseReverse(const char *var_str, int start)
2565 {
2566  int end = 0;
2567  if (start > (int)strlen(var_str)) start = strlen(var_str);
2568 
2569  for (int i = start; i > 0; i--)
2570  {
2571  if (var_str[i] == '.') return i;
2572  if (var_str[i] == '>' && i > 0 && var_str[i-1] == '-') return i-1;
2573  }
2574 
2575  return end;
2576 }
TTabCom::RehashEnvVars
void RehashEnvVars()
Environemnt variables rehashing.
Definition: TTabCom.cxx:353
TTabCom.h
c
#define c(i)
Definition: RSha256.hxx:101
TTabCom::InitPatterns
void InitPatterns()
[private]
Definition: TTabCom.cxx:2138
l
auto * l
Definition: textangle.C:4
TTabCom::ExtendPath
TString ExtendPath(const char originalPath[], TString newBase) const
[private]
Definition: TTabCom.cxx:1534
TDataMember::GetTypeName
const char * GetTypeName() const
Get type of data member, e,g.: "class TDirectory*" -> "TDirectory".
Definition: TDataMember.cxx:407
TTabCom::fVarIsPointer
Bool_t fVarIsPointer
Definition: TTabCom.h:223
TSystem::Unlink
virtual int Unlink(const char *name)
Unlink, i.e.
Definition: TSystem.cxx:1380
TSystem::GetPathInfo
int GetPathInfo(const char *path, Long_t *id, Long_t *size, Long_t *flags, Long_t *modtime)
Get info about a file: id, size, flags, modification time.
Definition: TSystem.cxx:1397
TString::ReadToDelim
std::istream & ReadToDelim(std::istream &str, char delim='\n')
Read up to an EOF, or a delimiting character, whichever comes first.
Definition: Stringio.cxx:89
TTabCom::NewListOfFilesInPath
static TSeqCollection * NewListOfFilesInPath(const char path[])
[static utility function]/////////////////////////////
Definition: TTabCom.cxx:1049
TTabCom::kCINT_Load
@ kCINT_Load
Definition: TTabCom.h:133
TTabCom::GetListOfFilesInPath
const TSeqCollection * GetListOfFilesInPath(const char path[])
"path" should be initialized with a colon separated list of system directories
Definition: TTabCom.cxx:508
Rstrstream.h
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:100
TTabCom::fpDirectives
TSeqCollection * fpDirectives
Definition: TTabCom.h:210
TClass::GetListOfAllPublicMethods
const TList * GetListOfAllPublicMethods(Bool_t load=kTRUE)
Returns a list of all public methods of this class and its base classes.
Definition: TClass.cxx:3838
TTabCom::ClearUsers
void ClearUsers()
Forget all user seen so far.
Definition: TTabCom.cxx:306
TTabCom::kROOT_Load
@ kROOT_Load
Definition: TTabCom.h:151
TTabCom::kCXX_DirectProto
@ kCXX_DirectProto
Definition: TTabCom.h:170
TTabCom::ParseReverse
int ParseReverse(const char *var_str, int start)
Returns the place in the string where to put the \0, starting the search from "start".
Definition: TTabCom.cxx:2564
sym
#define sym(otri1, otri2)
Definition: triangle.c:933
TClass::GetListOfAllPublicDataMembers
TList * GetListOfAllPublicDataMembers(Bool_t load=kTRUE)
Returns a list of all public data members of this class and its base classes.
Definition: TClass.cxx:3855
TTabCom::kCXX_IndirectMember
@ kCXX_IndirectMember
Definition: TTabCom.h:177
dest
#define dest(otri, vertexptr)
Definition: triangle.c:1041
Matchs
const char * Matchs(const char *, size_t len, const Pattern_t *, const char **)
Match a string with a pattern.
Definition: Match.cxx:220
TTabCom::RehashAll
void RehashAll()
clears and then rebuilds all lists except for user names and system include files.
Definition: TTabCom.cxx:415
Makepat
int Makepat(const char *, Pattern_t *, int)
Make a pattern template from the string pointed to by exp.
Definition: Match.cxx:129
TString::Strip
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1131
TTabCom::fRegExp
const char * fRegExp[kNUM_PAT]
Definition: TTabCom.h:222
TSeqCollection::Add
virtual void Add(TObject *obj)
Definition: TSeqCollection.h:38
TString::Prepend
TString & Prepend(const char *cs)
Definition: TString.h:661
gEnv
R__EXTERN TEnv * gEnv
Definition: TEnv.h:170
TString::Data
const char * Data() const
Definition: TString.h:369
TFunction.h
TSystem::FreeDirectory
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition: TSystem.cxx:845
TTabCom::ClearCppDirectives
void ClearCppDirectives()
Forget all Cpp directives seen so far.
Definition: TTabCom.cxx:230
TTabCom::GetListOfClasses
const TSeqCollection * GetListOfClasses()
Return the list of classes.
Definition: TTabCom.cxx:431
TROOT::GetMacroPath
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition: TROOT.cxx:2708
TSystem::Which
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1545
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
TTabCom::kCXX_ConstructorProto
@ kCXX_ConstructorProto
Definition: TTabCom.h:168
TObjString.h
TClassTable::Init
static void Init()
Definition: TClassTable.cxx:334
BUF_SIZE
#define BUF_SIZE
Definition: TTabCom.cxx:151
FileStat_t
Definition: TSystem.h:124
kWarning
const Int_t kWarning
Definition: TError.h:45
TCollection::Delete
virtual void Delete(Option_t *option="")=0
Delete this object.
TMethod.h
TString::kIgnoreCase
@ kIgnoreCase
Definition: TString.h:268
TTabCom::RehashGlobals
void RehashGlobals()
Reload globals.
Definition: TTabCom.cxx:378
TTabCom::GetSysIncludePath
static TString GetSysIncludePath()
[static utility function]/////////////////////////////
Definition: TTabCom.cxx:928
TCollection::SetOwner
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
Definition: TCollection.cxx:746
gInterpreter
#define gInterpreter
Definition: TInterpreter.h:560
TDataMember.h
TGeant4Unit::s
static constexpr double s
Definition: TGeant4SystemOfUnits.h:162
TTabCom::kSYS_UserName
@ kSYS_UserName
Definition: TTabCom.h:121
TDataMember
All ROOT classes may have RTTI (run time type identification) support added.
Definition: TDataMember.h:31
TTabCom::kCXX_Global
@ kCXX_Global
Definition: TTabCom.h:181
TString::Contains
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:624
TString::EndsWith
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2202
TTabCom::fPat
Pattern_t fPat[kNUM_PAT][MAX_LEN_PAT]
Definition: TTabCom.h:221
TTabCom::GetListOfEnvVars
const TSeqCollection * GetListOfEnvVars()
Uses "env" (Unix) or "set" (Windows) to get list of environment variables.
Definition: TTabCom.cxx:527
TString::Length
Ssiz_t Length() const
Definition: TString.h:410
TTabCom::ClearPragmas
void ClearPragmas()
Forget all pragmas seen so far.
Definition: TTabCom.cxx:282
TString::kExact
@ kExact
Definition: TString.h:268
TClass.h
TTabCom::kNUM_PAT
@ kNUM_PAT
Definition: TTabCom.h:186
TList.h
TTabCom::ClearGlobalFunctions
void ClearGlobalFunctions()
Forget all global functions seen so far.
Definition: TTabCom.cxx:267
TEnv::GetValue
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
TIter::Reset
void Reset()
Definition: TCollection.h:252
TSystem::TempFileName
virtual FILE * TempFileName(TString &base, const char *dir=nullptr)
Create a secure temporary file by appending a unique 6 letter string to base.
Definition: TSystem.cxx:1496
passwd
Definition: TWinNTSystem.h:47
TTabCom::kCINT_Edit
@ kCINT_Edit
Definition: TTabCom.h:132
TCollection::Contains
Bool_t Contains(const char *name) const
Definition: TCollection.h:169
TTabCom::fpFiles
TSeqCollection * fpFiles
Definition: TTabCom.h:212
gTabCom
TTabCom * gTabCom
Definition: TTabCom.cxx:167
TEnv.h
TTabCom::~TTabCom
virtual ~TTabCom()
Definition: TTabCom.cxx:200
TString
Basic string class.
Definition: TString.h:136
TTabCom::ClearAll
void ClearAll()
clears all lists except for user names and system include files.
Definition: TTabCom.cxx:319
TCollection::AddAll
virtual void AddAll(const TCollection *col)
Add all objects from collection col to this collection.
Definition: TCollection.cxx:195
TTabCom::RehashClasses
void RehashClasses()
Do the class rehash.
Definition: TTabCom.cxx:335
kDelim
const char kDelim
Definition: TTabCom.cxx:158
TTabCom::fpClasses
TSeqCollection * fpClasses
Definition: TTabCom.h:208
TSystem::GetDirName
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:1031
TTabCom::SetPattern
void SetPattern(EContext_t handle, const char regexp[])
[private]
Definition: TTabCom.cxx:2542
bool
TTabCom::DetermineContext
EContext_t DetermineContext() const
[private]
Definition: TTabCom.cxx:1467
dblquote
#define dblquote(x)
Definition: TTabCom.h:43
TTabCom::MakeClassFromClassName
TClass * MakeClassFromClassName(const char className[]) const
private returns a new'd TClass given the name of a class.
Definition: TTabCom.cxx:2205
TTabCom::GetListOfUsers
const TSeqCollection * GetListOfUsers()
reads from "/etc/passwd"
Definition: TTabCom.cxx:639
TString::kBoth
@ kBoth
Definition: TString.h:267
TTabCom::fpUsers
TSeqCollection * fpUsers
Definition: TTabCom.h:216
TTabCom::GetListOfSysIncFiles
const TSeqCollection * GetListOfSysIncFiles()
Return the list of system include files.
Definition: TTabCom.cxx:627
TROOT.h
TTabCom::MakeClassFromVarName
TClass * MakeClassFromVarName(const char varName[], EContext_t &context, int iter=0)
private returns a new'd TClass given the name of a variable.
Definition: TTabCom.cxx:2254
TTabCom::kCINT_EXec
@ kCINT_EXec
Definition: TTabCom.h:135
TObjString
Collectable string class.
Definition: TObjString.h:28
MAX_LEN_PAT
#define MAX_LEN_PAT
Definition: TTabCom.h:42
TTabCom::TryMakeClassFromClassName
TClass * TryMakeClassFromClassName(const char className[]) const
Same as above but does not print the error message.
Definition: TTabCom.cxx:2234
TObject::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:359
TTabCom::kCINT_stdin
@ kCINT_stdin
Definition: TTabCom.h:127
TTabCom::kCINT_includeSYS
@ kCINT_includeSYS
Definition: TTabCom.h:139
TTabCom::GetListOfGlobals
const TSeqCollection * GetListOfGlobals()
Return the list of globals.
Definition: TTabCom.cxx:580
s0
#define s0(x)
Definition: RSha256.hxx:90
TString::ECaseCompare
ECaseCompare
Definition: TString.h:268
TTabCom::PathIsSpecifiedInFileName
static Bool_t PathIsSpecifiedInFileName(const TString &fileName)
[static utility function]/////////////////////////////
Definition: TTabCom.cxx:1088
IfDebug
#define IfDebug(x)
Definition: TTabCom.cxx:153
TTabCom::kCXX_IndirectProto
@ kCXX_IndirectProto
Definition: TTabCom.h:171
TMethod::GetCommentString
virtual const char * GetCommentString()
Returns a comment string from the class declaration.
Definition: TMethod.cxx:107
TClassTable.h
TTabCom::GetListOfGlobalFunctions
TCollection * GetListOfGlobalFunctions()
Return the list of global functions.
Definition: TTabCom.cxx:588
TTabCom::AppendListOfFilesInDirectory
static void AppendListOfFilesInDirectory(const char dirName[], TSeqCollection *pList)
[static utility function]/////////////////////////////
Definition: TTabCom.cxx:750
TTabCom::TContainer
TList TContainer
Definition: TTabCom.h:59
TString::Chop
TString & Chop()
Definition: TString.h:679
kExecutePermission
@ kExecutePermission
Definition: TSystem.h:45
TSystem.h
TTabCom::Hook
Int_t Hook(char *buf, int *pLoc, std::ostream &out)
[private]
Definition: TTabCom.cxx:1566
TString::kTrailing
@ kTrailing
Definition: TString.h:267
THashList
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:34
TTabCom::ClearClasses
void ClearClasses()
Clear classes and namespace collections.
Definition: TTabCom.cxx:218
TTabCom::fpSysIncFiles
TSeqCollection * fpSysIncFiles
Definition: TTabCom.h:215
FileStat_t::fMode
Int_t fMode
Definition: TSystem.h:127
TTabCom::RehashPragmas
void RehashPragmas()
Reload pragmas.
Definition: TTabCom.cxx:387
TString::Remove
TString & Remove(Ssiz_t pos)
Definition: TString.h:673
TInterpreter::DisplayIncludePath
virtual int DisplayIncludePath(FILE *) const
Definition: TInterpreter.h:254
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:101
TString::Append
TString & Append(const char *cs)
Definition: TString.h:564
Fatal
void Fatal(const char *location, const char *msgfmt,...)
Use this function in case of a fatal error. It will abort the program.
Definition: TError.cxx:245
TSystem::Exec
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition: TSystem.cxx:655
s1
#define s1(x)
Definition: RSha256.hxx:91
TTabCom::fpLoc
int * fpLoc
Definition: TTabCom.h:219
TMethod
Each ROOT class (see TClass) has a linked list of methods.
Definition: TMethod.h:38
xmlio::String
const char * String
Definition: TXMLSetup.cxx:94
TTabCom::kUNKNOWN_CONTEXT
@ kUNKNOWN_CONTEXT
Definition: TTabCom.h:114
TTabCom::ClearSysIncFiles
void ClearSysIncFiles()
Close system files.
Definition: TTabCom.cxx:294
TTabCom::kCINT_pragma
@ kCINT_pragma
Definition: TTabCom.h:138
TGlobal.h
TBenchmark.h
TString::BeginsWith
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:615
TFunction::GetReturnTypeName
const char * GetReturnTypeName() const
Get full type description of function return type, e,g.: "class TDirectory*".
Definition: TFunction.cxx:141
TClass::GetClass
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2955
TTabCom::CopyMatch
void CopyMatch(char *dest, int dest_len, const char *localName, const char *appendage=nullptr, const char *fullName=nullptr) const
[private]
Definition: TTabCom.cxx:1414
TTabCom::kCINT_stdout
@ kCINT_stdout
Definition: TTabCom.h:125
TSystem::ExpandPathName
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1273
TFunction::GetNargs
Int_t GetNargs() const
Number of function arguments.
Definition: TFunction.cxx:165
TTabCom::kCXX_NewProto
@ kCXX_NewProto
Definition: TTabCom.h:167
line
TLine * line
Definition: entrylistblock_figure1.C:235
TCollection::IsEmpty
virtual Bool_t IsEmpty() const
Definition: TCollection.h:186
TTabCom::RehashCppDirectives
void RehashCppDirectives()
Cpp rehashing.
Definition: TTabCom.cxx:344
TClassTable::Next
static char * Next()
Returns next class from sorted class table.
Definition: TClassTable.cxx:681
TSystem::Beep
void Beep(Int_t freq=-1, Int_t duration=-1, Bool_t setDefault=kFALSE)
Beep for duration milliseconds with a tone of frequency freq.
Definition: TSystem.cxx:326
TTabCom::fLastIter
Int_t fLastIter
Definition: TTabCom.h:224
TTabCom::fPrevInterpMarker
ULong64_t fPrevInterpMarker
Definition: TTabCom.h:209
TTabCom::RehashFiles
void RehashFiles()
Close files.
Definition: TTabCom.cxx:362
unsigned int
TRegexp
Regular expression class.
Definition: TRegexp.h:31
THashList.h
TString::Index
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:639
gSystem
R__EXTERN TSystem * gSystem
Definition: TSystem.h:559
TTabCom::RehashUsers
void RehashUsers()
Reload users.
Definition: TTabCom.cxx:405
TSeqCollection
Sequenceable collection abstract base class.
Definition: TSeqCollection.h:28
TSystem::Getenv
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1662
gErrorIgnoreLevel
R__EXTERN Int_t gErrorIgnoreLevel
Definition: TError.h:127
TString::IsNull
Bool_t IsNull() const
Definition: TString.h:407
TTabCom::GetListOfCppDirectives
const TSeqCollection * GetListOfCppDirectives()
Return the list of CPP directives.
Definition: TTabCom.cxx:482
TTabCom::AllAgreeOnChar
static Char_t AllAgreeOnChar(int i, const TSeqCollection *pList, Int_t &nGoodStrings)
[static utility function]///////////////////////////////////////////
Definition: TTabCom.cxx:685
TSystem::OpenDirectory
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition: TSystem.cxx:836
TTabCom::DeterminePath
TString DeterminePath(const TString &fileName, const char defaultPath[]) const
[private]
Definition: TTabCom.cxx:1491
TTabCom
Definition: TTabCom.h:52
TTabCom::kCXX_ScopeMember
@ kCXX_ScopeMember
Definition: TTabCom.h:175
TCollection::GetSize
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
TInterpreter.h
TTabCom::kCINT_includePWD
@ kCINT_includePWD
Definition: TTabCom.h:140
TTabCom::EContext_t
EContext_t
Definition: TTabCom.h:113
TClass
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:80
R_ISDIR
Bool_t R_ISDIR(Int_t mode)
Definition: TSystem.h:115
TTabCom::IsDirectory
static Bool_t IsDirectory(const char fileName[])
[static utility function]/////////////////////////////
Definition: TTabCom.cxx:1029
TTabCom::RehashGlobalFunctions
void RehashGlobalFunctions()
Reload global functions.
Definition: TTabCom.cxx:370
TTabCom::NoMsg
static void NoMsg(Int_t errorLevel)
[static utility function]/////////////////////////////
Definition: TTabCom.cxx:1108
TList::Add
virtual void Add(TObject *obj)
Definition: TList.h:87
TSystem::GetDirEntry
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition: TSystem.cxx:853
TObject
Mother of all ROOT objects.
Definition: TObject.h:37
gCling
R__EXTERN TInterpreter * gCling
Definition: TInterpreter.h:561
TTabCom::DetermineClass
static TString DetermineClass(const char varName[])
[static utility function]/////////////////////////////
Definition: TTabCom.cxx:799
TTabCom::kCINT_stderr
@ kCINT_stderr
Definition: TTabCom.h:126
name
char name[80]
Definition: TGX11.cxx:110
TTabCom::kSYS_FileName
@ kSYS_FileName
Definition: TTabCom.h:164
TTabCom::kCXX_GlobalProto
@ kCXX_GlobalProto
Definition: TTabCom.h:182
TTabCom::kCXX_DirectMember
@ kCXX_DirectMember
Definition: TTabCom.h:176
TIter
Definition: TCollection.h:233
TTabCom::fBuf
char * fBuf
Definition: TTabCom.h:218
TString::kLeading
@ kLeading
Definition: TString.h:267
TTabCom::ClearEnvVars
void ClearEnvVars()
Forget all environment variables seen so far.
Definition: TTabCom.cxx:242
TFunction::GetSignature
const char * GetSignature()
Return signature of function.
Definition: TFunction.cxx:116
TTabCom::kCINT_cpp
@ kCINT_cpp
Definition: TTabCom.h:147
TTabCom::fpEnvVars
TSeqCollection * fpEnvVars
Definition: TTabCom.h:211
TCollection
Collection abstract base class.
Definition: TCollection.h:63
ROOT::TMetaUtils::propNames::comment
static const std::string comment("comment")
TMethodArg.h
TNamed::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
type
int type
Definition: TGX11.cxx:121
TSystem::GetDynamicPath
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition: TSystem.cxx:1792
TTabCom::kCXX_ScopeProto
@ kCXX_ScopeProto
Definition: TTabCom.h:169
TTabCom::RehashSysIncFiles
void RehashSysIncFiles()
Reload system include files.
Definition: TTabCom.cxx:396
TTabCom::ClearGlobals
void ClearGlobals()
Forget all global variables seen so far.
Definition: TTabCom.cxx:275
TTabCom::GetListOfPragmas
const TSeqCollection * GetListOfPragmas()
Return the list of pragmas.
Definition: TTabCom.cxx:596
TTabCom::ExcludedByFignore
static Bool_t ExcludedByFignore(TString s)
[static utility function]/////////////////////////////
Definition: TTabCom.cxx:892
Riostream.h
TTabCom::Complete
Int_t Complete(const TRegexp &re, const TSeqCollection *pListOfCandidates, const char appendage[], std::ostream &out, TString::ECaseCompare cmp=TString::kExact)
[private]
Definition: TTabCom.cxx:1163
Char_t
char Char_t
Definition: RtypesCore.h:33
TCollection::FindObject
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
Definition: TCollection.cxx:312
TObject::ClassName
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:130
TSeqCollection::At
virtual TObject * At(Int_t idx) const =0
TTabCom::kSYS_EnvVar
@ kSYS_EnvVar
Definition: TTabCom.h:122
TFunction
Global functions class (global functions are obtained from CINT).
Definition: TFunction.h:30
TTabCom::ClearFiles
void ClearFiles()
Close all files.
Definition: TTabCom.cxx:254
TList
A doubly linked list.
Definition: TList.h:44
TTabCom::TTabCom
TTabCom()
Default constructor.
Definition: TTabCom.cxx:177
TTabCom::kCINT_Exec
@ kCINT_Exec
Definition: TTabCom.h:134
gROOT
#define gROOT
Definition: TROOT.h:404
TTabCom::fpPragmas
TSeqCollection * fpPragmas
Definition: TTabCom.h:214
int
Error
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition: TError.cxx:187
TError.h
c1
return c1
Definition: legend1.C:41