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