Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

/ray/src/lib/sourcepos/sparchive.cc

Go to the documentation of this file.
00001 /*
00002  * lib/sourcepos/sparchive.cc
00003  * 
00004  * Classes for sophisticated source position (file/line/lpos, 
00005  * include hierarchy) handling. 
00006  * 
00007  * Copyright (c) 2003--2004 by Wolfgang Wieser ] wwieser (a) gmx <*> de [ 
00008  * 
00009  * This file may be distributed and/or modified under the terms of the 
00010  * GNU General Public License version 2 as published by the Free Software 
00011  * Foundation. (See COPYING.GPL for details.)
00012  * 
00013  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00014  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00015  * 
00016  */
00017 
00018 #include "sparchive.h"
00019 #include "spcache.h"
00020 
00022 #include <stdio.h>
00023 
00024 
00025 _InternalSourceFileNode *SourcePositionArchive::AllocISF(
00026     const TLString &path,SourceFileNode &parent)
00027 {
00028     _InternalSourceFileNode *isf=new _InternalSourceFileNode(path,
00029         &*parent,this);
00030     
00031     ++tot_file_nodes;
00032     ++curr_file_nodes;
00033     if(max_file_nodes<curr_file_nodes)
00034     {  max_file_nodes=curr_file_nodes;  }
00035     
00036     return(isf);
00037 }
00038 
00039 void SourcePositionArchive::DestroyingISF(_InternalSourceFileNode *isf)
00040 {
00041     // Normally called by _InternalSourceFileNode's destructor. 
00042     if(!isf)  return;
00043     
00044     --curr_file_nodes;
00045     
00046     // This may actually not happen as long as we still exist and 
00047     // need that; this is guaranteed by reference conting. 
00048     
00049 }
00050 
00051 
00052 // This will NOT see if we have the required position in the cache. 
00053 // JUST allocate a new one. 
00054 _InternalSourcePosition *SourcePositionArchive::AllocISPNoCache(
00055     const SourceFileNode &fnode,int line,int lpos)
00056 {
00057     _InternalSourcePosition *isp=new _InternalSourcePosition(fnode,line,lpos);
00058     
00059     ++tot_src_pos;
00060     ++curr_src_pos;
00061     if(max_src_pos<curr_src_pos)
00062     {  max_src_pos=curr_src_pos;  }
00063     
00064     return(isp);
00065 }
00066 
00067 void SourcePositionArchive::DestroyingISP(_InternalSourcePosition *isp)
00068 {
00069     // Normally called by _InternalSourcePosition's destructor. 
00070     if(!isp)  return;
00071     
00072     --curr_src_pos;
00073 }
00074 
00075 
00076 SourceFileNode SourcePositionArchive::IncludeFile(const TLString &file,
00077     int line,int lpos,
00078     filepos_t include_stmt_pos,size_t include_stmt_len)
00079 {
00080     Assert(current);
00081     
00082     _InternalSourceFileNode *isf=AllocISF(file,/*parent=*/current);
00083     
00084     isf->parent_include_line=line;
00085     isf->parent_include_lpos=lpos;
00086     isf->include_stmt_pos=include_stmt_pos;
00087     isf->include_stmt_len=include_stmt_len;
00088     
00089     current=SourceFileNode(isf);
00090     return(current);
00091 }
00092 
00093 
00094 SourceFileNode SourcePositionArchive::EndFile()
00095 {
00096     Assert(current);
00097     
00098     // Can delete the position cache here because it will no 
00099     // longer be used. 
00100     // OTOH, can also keep it because it is small...
00101     current->_DestroyPosCache();
00102     
00103     current=SourceFileNode(current->up);   // ..which may be NULL (primary input EOF)
00104     return(current);
00105 }
00106 
00107 
00108 SourcePosition SourcePositionArchive::GetPos(int line,int lpos)
00109 {
00110     Assert(current);
00111     
00112     // Query the cache: 
00113     if(current->pos_cache)
00114     {
00115         SourcePosition sp=current->pos_cache->find(line,lpos);
00116         if(sp)  return(sp);
00117     }
00118     
00119     // Allocate a new position object: 
00120     SourcePosition sp((line>=0) ? AllocISPNoCache(current,line,lpos) : NULL);
00121     
00122     // Add it to cache: 
00123     if(current->pos_cache)
00124     {  current->pos_cache->store(sp);  }
00125     
00126     return(sp);
00127 }
00128 
00129 
00130 // Recursively call _DetachArchive() for all InternalSourceFileNodes. 
00131 void SourcePositionArchive::_RecursiveDetachArchive(
00132     _InternalSourceFileNode *head)
00133 {
00134     if(!head)  return;
00135     
00136     // Make sure we keep a reference: 
00137     SourceFileNode tmp(head);
00138     
00139     for(_InternalSourceFileNode *_i=head->down.first(); _i; )
00140     {
00141         _InternalSourceFileNode *i=_i;
00142         _i=_i->next;
00143         
00144         _RecursiveDetachArchive(i);
00145     }
00146     
00147     head->_DetachArchive();
00148 }
00149 
00150 SourcePositionArchive::SourcePositionArchive(const TLString &path) : 
00151     head(),
00152     current(head)
00153 {
00154     tot_file_nodes=0;
00155     max_file_nodes=0;
00156     curr_file_nodes=0;
00157     
00158     tot_src_pos=0;
00159     max_src_pos=0;
00160     curr_src_pos=0;
00161     
00162     _InternalSourceFileNode *isf=AllocISF(path,
00163         /*parent=*/current/*, which is NULL ref*/);
00164     head=SourceFileNode(isf);
00165     current=head;
00166 }
00167 
00168 SourcePositionArchive::~SourcePositionArchive()
00169 {
00170     current=SourceFileNode();
00171     
00172     // Tell all the SourceFileNodes that the archive no longer exists: 
00173     _RecursiveDetachArchive(&*head);
00174     
00175     // This is debug; should be commented out. 
00176     fprintf(stderr,"SourcePositionArchive: files: tot=%d, max=%d (%u bytes)\n",
00177         tot_file_nodes,max_file_nodes,
00178         max_file_nodes*sizeof(_InternalSourceFileNode));
00179     fprintf(stderr,"    src pos: tot=%u, max=%u (%u bytes)\n",
00180         tot_src_pos,max_src_pos,max_src_pos*sizeof(_InternalSourcePosition));
00181 }

Generated on Sat Feb 19 22:33:46 2005 for Ray by doxygen 1.3.5