core/vsl/vsl_indent.cxx
Go to the documentation of this file.
00001 // This is core/vsl/vsl_indent.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 
00008 #include "vsl_indent.h"
00009 #include <vcl_iostream.h>
00010 #include <vcl_map.txx>
00011 #include <vcl_utility.h>
00012 
00013 const int default_tab = 2;
00014 
00015 typedef vcl_pair<int,int> indent_data_type;
00016 
00017 // Get pointer to tab and indent data for os
00018 indent_data_type* indent_data(vcl_ostream& os)
00019 {
00020   typedef vcl_map<void*, indent_data_type, vcl_less<void*> > maps2i_type;
00021   // Global record of tab information for streams.
00022   // Allows data to persist beyond the lifetime of the indent object itself,
00023   // which may be mercifully brief
00024   static maps2i_type indent_data_map;
00025 
00026   maps2i_type::iterator entry = indent_data_map.find(&os);
00027   if (entry==indent_data_map.end())
00028   {
00029     // Create a new entry
00030     indent_data_map[&os]=indent_data_type(0,default_tab);
00031   entry = indent_data_map.find(&os);
00032   }
00033 
00034   return &((*entry).second);
00035 }
00036 
00037 //: Increments current indent for given stream
00038 void vsl_indent_inc(vcl_ostream& os)
00039 {
00040   indent_data(os)->first++;
00041 }
00042 
00043 //: Decrements current indent for given stream
00044 void vsl_indent_dec(vcl_ostream& os)
00045 {
00046   indent_data(os)->first--;
00047 }
00048 
00049 //: Set number of spaces per increment step
00050 void vsl_indent_set_tab(vcl_ostream& os, int t)
00051 {
00052   indent_data(os)->second = t;
00053 }
00054 
00055 //: Number of spaces per increment step
00056 int vsl_indent_tab(vcl_ostream& os)
00057 {
00058   return indent_data(os)->second;
00059 }
00060 
00061 //: Set indentation to zero
00062 void vsl_indent_clear(vcl_ostream& os)
00063 {
00064   indent_data(os)->first =0;
00065 }
00066 
00067 vcl_ostream& operator<<(vcl_ostream& os, const vsl_indent& /*indent*/)
00068 {
00069   indent_data_type* data = indent_data(os);
00070 
00071   int n = data->first * data->second;
00072   for (int i=0;i<n;i++) os<<' ';
00073   return os;
00074 }
00075 
00076 //: Tidy up the internal indent map to remove potential memory leaks
00077 //  The details of indents for each stream are stored in a static
00078 //  map.  When testing for memory leaks, this is flagged, creating
00079 //  lots of noise in the output of memory leak checkers.
00080 //  This call empties the map, removing the potential leak.
00081 //  Pragmatically it is called in the vsl_delete_all_loaders()
00082 //
00083 //  This should no longer be needed, since that static map was made a static
00084 //  inside the function indent_data() instead of a global one. - PVr.
00085 //  (B.t.w., purify on SGI's native compiler never showed a memory leak here.)
00086 void vsl_indent_clear_all_data()
00087 {
00088 #if 0 // no longer needed?
00089   indent_data_map.clear();
00090 #endif
00091 }
00092 
00093 
00094 // removed explicit instantiation of map<void*, pair<int, int> > -- fsm.