Logo ROOT   6.08/07
Reference Guide
TEnv.cxx
Go to the documentation of this file.
1 // @(#)root/base:$Id: 0daf41ec24086ee7af29fdc2f9f2f848b150dcc8 $
2 // Author: Fons Rademakers 22/09/95
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TEnv
13 \ingroup Base
14 
15 The TEnv class reads config files, by default named `.rootrc`.
16 Three types of config files are read: global, user and local files. The
17 global file is `$ROOTSYS/etc/system<name>` (or `ROOTETCDIR/system<name>`)
18 the user file is `$HOME/<name>` and the local file is `./<name>`.
19 By setting the shell variable `ROOTENV_NO_HOME=1` the reading of
20 the `$HOME/<name>` resource file will be skipped. This might be useful
21 in case the home directory resides on an auto-mounted remote file
22 system and one wants to avoid this file system from being mounted.
23 
24 The format of the `.rootrc` file is similar to the `.Xdefaults` format:
25 ~~~ {.cpp}
26  [+]<SystemName>.<RootName|ProgName>.<name>[(type)]: <value>
27 ~~~
28 Where `<SystemName>` is either Unix, WinNT, MacOS or Vms,
29 `<RootName>` the name as given in the TApplication ctor (or "RootApp"
30 in case no explicit TApplication derived object was created),
31 `<ProgName>` the current program name and `<name>` the resource name,
32 with optionally a type specification. `<value>` can be either a
33 string, an integer, a float/double or a boolean with the values
34 TRUE, FALSE, ON, OFF, YES, NO, OK, NOT. Booleans will be returned as
35 an integer 0 or 1. The options [+] allows the concatenation of
36 values to the same resource name.
37 
38 E.g.:
39 ~~~ {.cpp}
40  Unix.Rint.Root.DynamicPath: .:$(ROOTSYS)/lib:~/lib
41  myapp.Root.Debug: FALSE
42  TH.Root.Debug: YES
43  *.Root.MemStat: 1
44 ~~~
45 `<SystemName>` and `<ProgName>` or `<RootName>` may be the wildcard "*".
46 A # in the first column starts comment line.
47 
48 Note that the environment variables (like $ROOTSYS) need to be
49 surrounded in parentheses in order to be expanded.
50 
51 For the currently defined resources (and their default values) see
52 `$ROOTSYS/etc/system.rootrc`.
53 
54 Note that the .rootrc config files contain the config for all ROOT
55 based applications.
56 
57 To add new entries to a TEnv:
58 ~~~ {.cpp}
59 TEnv env(".myfile");
60 env.SetValue("myname","value");
61 env.SaveLevel(kEnvLocal);
62 ~~~
63 All new entries will be saved in the file corresponding to the
64 first SaveLevel() command. If Save() is used, new entries go
65 into the local file by default.
66 */
67 
68 #include "RConfigure.h"
69 
70 #include <string.h>
71 #include <stdio.h>
72 #include <stdlib.h>
73 #include <ctype.h>
74 
75 #include "TEnv.h"
76 #include "TROOT.h"
77 #include "TSystem.h"
78 #include "THashList.h"
79 #include "TError.h"
80 
81 
82 TEnv *gEnv; // main environment created in TROOT
83 
84 
85 static struct BoolNameTable_t {
86  const char *fName;
87  Int_t fValue;
88 } gBoolNames[]= {
89  { "TRUE", 1 },
90  { "FALSE", 0 },
91  { "ON", 1 },
92  { "OFF", 0 },
93  { "YES", 1 },
94  { "NO", 0 },
95  { "OK", 1 },
96  { "NOT", 0 },
97  { 0, 0 }
98 };
99 
100 
101 /** \class TEnvParser
102 TEnv Parser.
103 */
104 
105 class TEnvParser {
106 
107 private:
108  FILE *fIfp;
109 
110 protected:
111  TEnv *fEnv;
112 
113 public:
114  TEnvParser(TEnv *e, FILE *f) : fIfp(f), fEnv(e) { }
115  virtual ~TEnvParser() { }
116  virtual void KeyValue(const TString&, const TString&, const TString&) { }
117  virtual void Char(Int_t) { }
118  void Parse();
119 };
120 
121 ////////////////////////////////////////////////////////////////////////////////
122 /// Parse a line of the env file and create an entry in the resource
123 /// dictionary (i.e. add a KeyValue pair).
124 
125 void TEnvParser::Parse()
126 {
127  TString name(1024);
128  TString type(1024);
129  TString value(1024);
130  int c, state = 0;
131 
132  while ((c = fgetc(fIfp)) != EOF) {
133  if (c == 13) // ignore CR
134  continue;
135  if (c == '\n') {
136  state = 0;
137  if (name.Length() > 0) {
138  KeyValue(name, value, type);
139  name.Clear();
140  value.Clear();
141  type.Clear();
142  }
143  Char(c);
144  continue;
145  }
146  switch (state) {
147  case 0: // start of line
148  switch (c) {
149  case ' ':
150  case '\t':
151  break;
152  case '#':
153  state = 1;
154  break;
155  default:
156  state = 2;
157  break;
158  }
159  break;
160 
161  case 1: // comment
162  break;
163 
164  case 2: // name
165  switch (c) {
166  case ' ':
167  case '\t':
168  case ':':
169  state = 3;
170  break;
171  case '(':
172  state = 7;
173  break;
174  default:
175  break;
176  }
177  break;
178 
179  case 3: // ws before value
180  if (c != ' ' && c != '\t')
181  state = 4;
182  break;
183 
184  case 4: // value
185  break;
186 
187  case 5: // type
188  if (c == ')')
189  state = 6;
190  break;
191 
192  case 6: // optional ':'
193  state = (c == ':') ? 3 : 4;
194  break;
195 
196  case 7:
197  state = (c == ')') ? 6 : 5;
198  break;
199 
200  }
201  switch (state) {
202  case 2:
203  name.Append(c);
204  break;
205  case 4:
206  value.Append(c);
207  break;
208  case 5:
209  type.Append(c);
210  break;
211  }
212  if (state != 4)
213  Char(c);
214  }
215  // In case EOF is reach before '\n'
216  if (name.Length() > 0) {
217  KeyValue(name, value, type);
218  name.Clear();
219  value.Clear();
220  type.Clear();
221  }
222 }
223 
224 /** \class TReadEnvParser
225 */
226 
227 class TReadEnvParser : public TEnvParser {
228 
229 private:
230  EEnvLevel fLevel;
231 
232 public:
233  TReadEnvParser(TEnv *e, FILE *f, EEnvLevel l) : TEnvParser(e, f), fLevel(l) { }
234  void KeyValue(const TString &name, const TString &value, const TString &type)
235  { fEnv->SetValue(name, value, fLevel, type); }
236 };
237 
238 /** \class TWriteEnvParser
239 */
240 
241 class TWriteEnvParser : public TEnvParser {
242 
243 private:
244  FILE *fOfp;
245 
246 public:
247  TWriteEnvParser(TEnv *e, FILE *f, FILE *of) : TEnvParser(e, f), fOfp(of) { }
248  void KeyValue(const TString &name, const TString &value, const TString &type);
249  void Char(Int_t c) { fputc(c, fOfp); }
250 };
251 
252 ////////////////////////////////////////////////////////////////////////////////
253 /// Write resources out to a new file.
254 
255 void TWriteEnvParser::KeyValue(const TString &name, const TString &value,
256  const TString &)
257 {
258  TEnvRec *er = fEnv->Lookup(name);
259  if (er && er->fModified) {
260  er->fModified = kFALSE;
261  fprintf(fOfp, "%s", er->fValue.Data());
262  } else
263  fprintf(fOfp, "%s", value.Data());
264 }
265 
266 
267 /** \class TEnvRec
268 */
269 
270 ////////////////////////////////////////////////////////////////////////////////
271 /// Ctor of a single resource.
272 
273 TEnvRec::TEnvRec(const char *n, const char *v, const char *t, EEnvLevel l)
274  : fName(n), fType(t), fLevel(l)
275 {
276  fValue = ExpandValue(v);
277  fModified = (l == kEnvChange);
278 }
279 
280 ////////////////////////////////////////////////////////////////////////////////
281 /// Change the value of a resource.
282 
283 void TEnvRec::ChangeValue(const char *v, const char *, EEnvLevel l,
284  Bool_t append, Bool_t ignoredup)
285 {
286  if (l != kEnvChange && fLevel == l && !append) {
287  // use global Warning() since interpreter might not yet be initialized
288  // at this stage (called from TROOT ctor)
289  if (fValue != v && !ignoredup)
290  ::Warning("TEnvRec::ChangeValue",
291  "duplicate entry <%s=%s> for level %d; ignored", fName.Data(), v, l);
292  return;
293  }
294  if (!append) {
295  if (fValue != v) {
296  if (l == kEnvChange)
297  fModified = kTRUE;
298  else
299  fModified = kFALSE;
300  fLevel = l;
301  fValue = ExpandValue(v);
302  }
303  } else {
304  if (l == kEnvChange)
305  fModified = kTRUE;
306  fLevel = l;
307  fValue += " ";
308  fValue += ExpandValue(v);
309  }
310 }
311 
312 ////////////////////////////////////////////////////////////////////////////////
313 /// Comparison function for resources.
314 
316 {
317  return fName.CompareTo(((TEnvRec*)op)->fName);
318 }
319 
320 ////////////////////////////////////////////////////////////////////////////////
321 /// Replace all $(XXX) strings by the value defined in the shell
322 /// (obtained via TSystem::Getenv()).
323 
324 TString TEnvRec::ExpandValue(const char *value)
325 {
326  const char *vv;
327  char *v, *vorg = StrDup(value);
328  v = vorg;
329 
330  char *s1, *s2;
331  int len = 0;
332  while ((s1 = (char*)strstr(v, "$("))) {
333  s1 += 2;
334  s2 = (char*)strchr(s1, ')');
335  if (!s2) {
336  len = 0;
337  break;
338  }
339  *s2 = 0;
340  vv = gSystem->Getenv(s1);
341  if (vv) len += strlen(vv);
342  *s2 = ')';
343  v = s2 + 1;
344  }
345 
346  if (!len) {
347  delete [] vorg;
348  return TString(value);
349  }
350 
351  v = vorg;
352  int nch = strlen(v) + len;
353  char *nv = new char[nch];
354  *nv = 0;
355 
356  while ((s1 = (char*)strstr(v, "$("))) {
357  *s1 = 0;
358  strlcat(nv, v,nch);
359  *s1 = '$';
360  s1 += 2;
361  s2 = (char*)strchr(s1, ')');
362  *s2 = 0;
363  vv = gSystem->Getenv(s1);
364  if (vv) strlcat(nv, vv,nch);
365  *s2 = ')';
366  v = s2 + 1;
367  }
368 
369  if (*v) strlcat(nv, v,nch);
370 
371  TString val = nv;
372  delete [] nv;
373  delete [] vorg;
374 
375  return val;
376 }
377 
378 ClassImp(TEnv)
379 
380 ////////////////////////////////////////////////////////////////////////////////
381 /// Create a resource table and read the (possibly) three resource files, i.e
382 /// `$ROOTSYS/etc/system``<name>` (or `ROOTETCDIR/system``<name>`),
383 /// `$HOME/``<name>` and
384 /// `./``<name>`.
385 /// ROOT always reads ".rootrc" (in TROOT::InitSystem()). You can
386 /// read additional user defined resource files by creating additional TEnv
387 /// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
388 /// the `$HOME/<name>` resource file will be skipped. This might be useful in
389 /// case the home directory resides on an auto-mounted remote file system
390 /// and one wants to avoid the file system from being mounted.
391 
392 TEnv::TEnv(const char *name)
393 {
394  fIgnoreDup = kFALSE;
395 
396  if (!name || !name[0] || !gSystem)
397  fTable = 0;
398  else {
399  fTable = new THashList(1000);
400  fRcName = name;
401 
402  TString sname = "system";
403  sname += name;
404 #ifdef ROOTETCDIR
405  char *s = gSystem->ConcatFileName(ROOTETCDIR, sname);
406 #else
407  TString etc = gRootDir;
408 #ifdef WIN32
409  etc += "\\etc";
410 #else
411  etc += "/etc";
412 #endif
413 #if defined(R__MACOSX) && (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)
414  // on iOS etc does not exist and system<name> resides in $ROOTSYS
415  etc = gRootDir;
416 #endif
417  char *s = gSystem->ConcatFileName(etc, sname);
418 #endif
419  ReadFile(s, kEnvGlobal);
420  delete [] s;
421  if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
423  ReadFile(s, kEnvUser);
424  delete [] s;
425  if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory()))
426  ReadFile(name, kEnvLocal);
427  } else
428  ReadFile(name, kEnvLocal);
429  }
430 }
431 
432 ////////////////////////////////////////////////////////////////////////////////
433 /// Delete the resource table.
434 
436 {
437  if (fTable) {
438  fTable->Delete();
439  SafeDelete(fTable);
440  }
441 }
442 
443 ////////////////////////////////////////////////////////////////////////////////
444 /// Returns the character value for a named resource.
445 
446 const char *TEnv::Getvalue(const char *name)
447 {
448  Bool_t haveProgName = kFALSE;
449  if (gProgName && strlen(gProgName) > 0)
450  haveProgName = kTRUE;
451 
452  TString aname;
453  TEnvRec *er = 0;
454  if (haveProgName && gSystem && gProgName) {
455  aname = gSystem->GetName(); aname += "."; aname += gProgName;
456  aname += "."; aname += name;
457  er = Lookup(aname);
458  }
459  if (er == 0 && gSystem && gROOT) {
460  aname = gSystem->GetName(); aname += "."; aname += gROOT->GetName();
461  aname += "."; aname += name;
462  er = Lookup(aname);
463  }
464  if (er == 0 && gSystem) {
465  aname = gSystem->GetName(); aname += ".*."; aname += name;
466  er = Lookup(aname);
467  }
468  if (er == 0 && haveProgName && gProgName) {
469  aname = gProgName; aname += "."; aname += name;
470  er = Lookup(aname);
471  }
472  if (er == 0 && gROOT) {
473  aname = gROOT->GetName(); aname += "."; aname += name;
474  er = Lookup(aname);
475  }
476  if (er == 0) {
477  aname = "*.*."; aname += name;
478  er = Lookup(aname);
479  }
480  if (er == 0) {
481  aname = "*."; aname += name;
482  er = Lookup(aname);
483  }
484  if (er == 0) {
485  er = Lookup(name);
486  }
487  if (er == 0)
488  return 0;
489  return er->fValue;
490 }
491 
492 ////////////////////////////////////////////////////////////////////////////////
493 /// Returns the integer value for a resource. If the resource is not found
494 /// return the default value.
495 
496 Int_t TEnv::GetValue(const char *name, Int_t dflt)
497 {
498  const char *cp = TEnv::Getvalue(name);
499  if (cp) {
500  char buf2[512], *cp2 = buf2;
501 
502  while (isspace((int)*cp))
503  cp++;
504  if (*cp) {
505  BoolNameTable_t *bt;
506  if (isdigit((int)*cp) || *cp == '-' || *cp == '+')
507  return atoi(cp);
508  while (isalpha((int)*cp))
509  *cp2++ = toupper((int)*cp++);
510  *cp2 = 0;
511  for (bt = gBoolNames; bt->fName; bt++)
512  if (strcmp(buf2, bt->fName) == 0)
513  return bt->fValue;
514  }
515  }
516  return dflt;
517 }
518 
519 ////////////////////////////////////////////////////////////////////////////////
520 /// Returns the double value for a resource. If the resource is not found
521 /// return the default value.
522 
523 Double_t TEnv::GetValue(const char *name, Double_t dflt)
524 {
525  const char *cp = TEnv::Getvalue(name);
526  if (cp) {
527  char *endptr;
528  Double_t val = strtod(cp, &endptr);
529  if (val == 0.0 && cp == endptr)
530  return dflt;
531  return val;
532  }
533  return dflt;
534 }
535 
536 ////////////////////////////////////////////////////////////////////////////////
537 /// Returns the character value for a named resource. If the resource is
538 /// not found the default value is returned.
539 
540 const char *TEnv::GetValue(const char *name, const char *dflt)
541 {
542  const char *cp = TEnv::Getvalue(name);
543  if (cp)
544  return cp;
545  return dflt;
546 }
547 
548 ////////////////////////////////////////////////////////////////////////////////
549 /// Loop over all resource records and return the one with name.
550 /// Return 0 in case name is not in the resource table.
551 
552 TEnvRec *TEnv::Lookup(const char *name)
553 {
554  if (!fTable) return 0;
555  return (TEnvRec*) fTable->FindObject(name);
556 }
557 
558 ////////////////////////////////////////////////////////////////////////////////
559 /// Print all resources or the global, user or local resources separately.
560 
561 void TEnv::Print(Option_t *opt) const
562 {
563  if (!opt || !opt[0]) {
564  PrintEnv();
565  return;
566  }
567 
568  if (!strcmp(opt, "global"))
569  PrintEnv(kEnvGlobal);
570  if (!strcmp(opt, "user"))
571  PrintEnv(kEnvUser);
572  if (!strcmp(opt, "local"))
573  PrintEnv(kEnvLocal);
574 }
575 
576 ////////////////////////////////////////////////////////////////////////////////
577 /// Print all resources for a certain level (global, user, local, changed).
578 
579 void TEnv::PrintEnv(EEnvLevel level) const
580 {
581  if (!fTable) return;
582 
583  TIter next(fTable);
584  TEnvRec *er;
585  static const char *lc[] = { "Global", "User", "Local", "Changed", "All" };
586 
587  while ((er = (TEnvRec*) next()))
588  if (er->fLevel == level || level == kEnvAll)
589  Printf("%-25s %-30s [%s]", Form("%s:", er->fName.Data()),
590  er->fValue.Data(), lc[er->fLevel]);
591 }
592 
593 ////////////////////////////////////////////////////////////////////////////////
594 /// Read and parse the resource file for a certain level.
595 /// Returns -1 on case of error, 0 in case of success.
596 
597 Int_t TEnv::ReadFile(const char *fname, EEnvLevel level)
598 {
599  if (!fname || !fname[0]) {
600  Error("ReadFile", "no file name specified");
601  return -1;
602  }
603 
604  FILE *ifp;
605  if ((ifp = fopen(fname, "r"))) {
606  TReadEnvParser rp(this, ifp, level);
607  rp.Parse();
608  fclose(ifp);
609  return 0;
610  }
611 
612  // no Error() here since we are allowed to try to read from a non-existing
613  // file (like ./.rootrc, $HOME/.rootrc, etc.)
614  return -1;
615 }
616 
617 ////////////////////////////////////////////////////////////////////////////////
618 /// Write resource records to file fname for a certain level. Use
619 /// level kEnvAll to write all resources. Returns -1 on case of error,
620 /// 0 in case of success.
621 
622 Int_t TEnv::WriteFile(const char *fname, EEnvLevel level)
623 {
624  if (!fname || !fname[0]) {
625  Error("WriteFile", "no file name specified");
626  return -1;
627  }
628 
629  if (!fTable) {
630  Error("WriteFile", "TEnv table is empty");
631  return -1;
632  }
633 
634  FILE *ofp;
635  if ((ofp = fopen(fname, "w"))) {
636  TIter next(fTable);
637  TEnvRec *er;
638  while ((er = (TEnvRec*) next()))
639  if (er->fLevel == level || level == kEnvAll)
640  fprintf(ofp, "%-40s %s\n", Form("%s:", er->fName.Data()),
641  er->fValue.Data());
642  fclose(ofp);
643  return 0;
644  }
645 
646  Error("WriteFile", "cannot open %s for writing", fname);
647  return -1;
648 }
649 
650 ////////////////////////////////////////////////////////////////////////////////
651 /// Write the resource files for each level. The new files have the same
652 /// name as the original files. The old files are renamed to *.bak.
653 
655 {
656  if (fRcName == "") {
657  Error("Save", "no resource file name specified");
658  return;
659  }
660 
661  SaveLevel(kEnvLocal); // Be default, new items will be put into Local.
662  SaveLevel(kEnvUser);
663  SaveLevel(kEnvGlobal);
664 }
665 
666 ////////////////////////////////////////////////////////////////////////////////
667 /// Write the resource file for a certain level.
668 
670 {
671  if (fRcName == "") {
672  Error("SaveLevel", "no resource file name specified");
673  return;
674  }
675 
676  if (!fTable) {
677  Error("SaveLevel", "TEnv table is empty");
678  return;
679  }
680 
681  TString rootrcdir;
682  FILE *ifp, *ofp;
683 
684  if (level == kEnvGlobal) {
685 
686  TString sname = "system";
687  sname += fRcName;
688 #ifdef ROOTETCDIR
689  char *s = gSystem->ConcatFileName(ROOTETCDIR, sname);
690 #else
691  TString etc = gRootDir;
692 #ifdef WIN32
693  etc += "\\etc";
694 #else
695  etc += "/etc";
696 #endif
697  char *s = gSystem->ConcatFileName(etc, sname);
698 #endif
699  rootrcdir = s;
700  delete [] s;
701  } else if (level == kEnvUser) {
702  char *s = gSystem->ConcatFileName(gSystem->HomeDirectory(), fRcName);
703  rootrcdir = s;
704  delete [] s;
705  } else if (level == kEnvLocal)
706  rootrcdir = fRcName;
707  else
708  return;
709 
710  if ((ofp = fopen(Form("%s.new", rootrcdir.Data()), "w"))) {
711  ifp = fopen(rootrcdir.Data(), "r");
712  if (ifp == 0) { // try to create file
713  ifp = fopen(rootrcdir.Data(), "w");
714  if (ifp) {
715  fclose(ifp);
716  ifp = 0;
717  }
718  }
719  if (ifp || (ifp = fopen(rootrcdir.Data(), "r"))) {
720  TWriteEnvParser wp(this, ifp, ofp);
721  wp.Parse();
722 
723  TIter next(fTable);
724  TEnvRec *er;
725  while ((er = (TEnvRec*) next())) {
726  if (er->fModified) {
727 
728  // If it doesn't have a level yet, make it this one.
729  if (er->fLevel == kEnvChange) er->fLevel = level;
730  if (er->fLevel == level) {
731  er->fModified = kFALSE;
732  fprintf(ofp, "%-40s %s\n", Form("%s:", er->fName.Data()),
733  er->fValue.Data());
734  }
735  }
736  }
737  fclose(ifp);
738  fclose(ofp);
739  gSystem->Rename(rootrcdir.Data(), Form("%s.bak", rootrcdir.Data()));
740  gSystem->Rename(Form("%s.new", rootrcdir.Data()), rootrcdir.Data());
741  return;
742  }
743  fclose(ofp);
744  } else
745  Error("SaveLevel", "cannot write to file %s", rootrcdir.Data());
746 }
747 
748 ////////////////////////////////////////////////////////////////////////////////
749 /// Set the value of a resource or create a new resource.
750 
751 void TEnv::SetValue(const char *name, const char *value, EEnvLevel level,
752  const char *type)
753 {
754  if (!fTable)
755  fTable = new THashList(1000);
756 
757  const char *nam = name;
758  Bool_t append = kFALSE;
759  if (name[0] == '+') {
760  nam = &name[1];
761  append = kTRUE;
762  }
763 
764  TEnvRec *er = Lookup(nam);
765  if (er)
766  er->ChangeValue(value, type, level, append, fIgnoreDup);
767  else
768  fTable->Add(new TEnvRec(nam, value, type, level));
769 }
770 
771 ////////////////////////////////////////////////////////////////////////////////
772 /// Set the value of a resource or create a new resource.
773 /// Use this method to set a resource like, "name=val".
774 /// If just "name" is given it will be interpreted as "name=1".
775 
776 void TEnv::SetValue(const char *name, EEnvLevel level)
777 {
778  TString buf = name;
779  int l = buf.Index("=");
780  if (l > 0) {
781  TString nm = buf(0, l);
782  TString val = buf(l+1, buf.Length());
783  SetValue(nm, val, level);
784  } else
785  SetValue(name, "1", level);
786 }
787 
788 ////////////////////////////////////////////////////////////////////////////////
789 /// Set or create an integer resource value.
790 
791 void TEnv::SetValue(const char *name, Int_t value)
792 {
793  SetValue(name, Form("%d", value));
794 }
795 
796 ////////////////////////////////////////////////////////////////////////////////
797 /// Set or create a double resource value.
798 
799 void TEnv::SetValue(const char *name, double value)
800 {
801  SetValue(name, Form("%g", value));
802 }
803 
804 ////////////////////////////////////////////////////////////////////////////////
805 /// If set to true, no warnings in case of duplicates are issued.
806 /// Returns previous value.
807 
809 {
810  Bool_t ret = fIgnoreDup;
811  fIgnoreDup = ignore;
812  return ret;
813 }
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
virtual const char * WorkingDirectory()
Return working directory.
Definition: TSystem.cxx:866
TEnvRec()
Definition: TEnv.h:112
const char * Getvalue(const char *name)
Returns the character value for a named resource.
Definition: TEnv.cxx:446
Definition: TEnv.h:76
return c
const char Option_t
Definition: RtypesCore.h:62
static struct BoolNameTable_t gBoolNames[]
virtual const char * HomeDirectory(const char *userName=0)
Return the user&#39;s home directory.
Definition: TSystem.cxx:882
#define gROOT
Definition: TROOT.h:364
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:582
The TEnv class reads config files, by default named .rootrc.
Definition: TEnv.h:128
Basic string class.
Definition: TString.h:137
void ChangeValue(const char *v, const char *t, EEnvLevel l, Bool_t append=kFALSE, Bool_t ignoredup=kFALSE)
Change the value of a resource.
Definition: TEnv.cxx:283
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
const char * Char
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=0)
Set the value of a resource or create a new resource.
Definition: TEnv.cxx:751
virtual int Rename(const char *from, const char *to)
Rename a file.
Definition: TSystem.cxx:1320
#define SafeDelete(p)
Definition: RConfig.h:507
virtual ~TEnv()
Delete the resource table.
Definition: TEnv.cxx:435
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:36
virtual void PrintEnv(EEnvLevel level=kEnvAll) const
Print all resources for a certain level (global, user, local, changed).
Definition: TEnv.cxx:579
virtual Int_t WriteFile(const char *fname, EEnvLevel level=kEnvAll)
Write resource records to file fname for a certain level.
Definition: TEnv.cxx:622
TString fName
Definition: TEnv.h:99
void Clear()
Clear string without changing its capacity.
Definition: TString.cxx:1140
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1628
TString & Append(const char *cs)
Definition: TString.h:492
Bool_t IgnoreDuplicates(Bool_t ignore)
If set to true, no warnings in case of duplicates are issued.
Definition: TEnv.cxx:808
virtual void Print(Option_t *option="") const
Print all resources or the global, user or local resources separately.
Definition: TEnv.cxx:561
Bool_t fModified
Definition: TEnv.h:103
EEnvLevel
Definition: TEnv.h:74
virtual Int_t ReadFile(const char *fname, EEnvLevel level)
Read and parse the resource file for a certain level.
Definition: TEnv.cxx:597
virtual void Save()
Write the resource files for each level.
Definition: TEnv.cxx:654
R__EXTERN const char * gProgName
Definition: TSystem.h:234
Definition: TEnv.h:91
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition: TObject.cxx:380
R__EXTERN TSystem * gSystem
Definition: TSystem.h:549
SVector< double, 2 > v
Definition: Dict.h:5
friend class TWriteEnvParser
Definition: TEnv.h:96
PyObject * fValue
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:496
virtual TEnvRec * Lookup(const char *n)
Loop over all resource records and return the one with name.
Definition: TEnv.cxx:552
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:925
char * Form(const char *fmt,...)
Ssiz_t Length() const
Definition: TString.h:390
TLine * l
Definition: textangle.C:4
const std::string sname
Definition: testIO.cxx:45
Definition: TEnv.h:77
#define Printf
Definition: TGeoToOCC.h:18
char * StrDup(const char *str)
Duplicate the string str.
Definition: TString.cxx:2514
PyObject * fType
Definition: TEnv.h:79
TEnv * gEnv
Definition: TEnv.cxx:82
Int_t Compare(const TObject *obj) const
Comparison function for resources.
Definition: TEnv.cxx:315
#define ClassImp(name)
Definition: Rtypes.h:279
double f(double x)
TString ExpandValue(const char *v)
Replace all strings by the value defined in the shell (obtained via TSystem::Getenv()).
Definition: TEnv.cxx:324
double Double_t
Definition: RtypesCore.h:55
int type
Definition: TGX11.cxx:120
friend class TReadEnvParser
Definition: TEnv.h:95
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:386
virtual void SaveLevel(EEnvLevel level)
Write the resource file for a certain level.
Definition: TEnv.cxx:669
Mother of all ROOT objects.
Definition: TObject.h:37
R__EXTERN const char * gRootDir
Definition: TSystem.h:233
TString fValue
Definition: TEnv.h:101
EEnvLevel fLevel
Definition: TEnv.h:102
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition: TSystem.cxx:1045
const Int_t n
Definition: legend1.C:16
char name[80]
Definition: TGX11.cxx:109
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:911
const char * Data() const
Definition: TString.h:349