libs/EDoc/TryBlock.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003    Copyright (C) 2007 by Brendon Costa
00004 
00005    This library is free software; you can redistribute it and/or modify 
00006    it under the terms of the "LGPL Like" License defined in the file COPYING 
00007    that should have been distributed along with this source.
00008 
00009    This library is distributed in the hope that it will be useful, 
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of 
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013    You should have received a copy of the "LGPL Like" License 
00014    along with this library; see the file COPYING. if not, it can be 
00015    obtained from the EDoc++ website: 
00016    http://edoc.sourceforge.net/license.html
00017 
00018 *******************************************************************************/
00019 #include "config.h"
00020 
00021 #include "EDoc/TryBlock.h"
00022 
00023 #include "EDoc/CodeBlock.h"
00024 #include "EDoc/utils.h"
00025 #include "EDoc/PStack.h"
00026 #include "EDoc/StackRef.h"
00027 
00028 #include "EDoc/PersistenceIFace.h"
00029 #include "IndexedDictionary.h"
00030 #include "EDoc/persistence_data.h"
00031 
00032 namespace EDoc
00033 {
00034    //===========================================================================
00035    TryBlock::TryBlock(Dictionary* dict_in) :
00036       DictionarySpecific(dict_in),
00037       try_block(NULL)
00038    {
00039       try_block = new CodeBlock(dict_in);
00040    }
00041    //===========================================================================
00042    TryBlock::TryBlock(const TryBlock& right) :
00043       DictionarySpecific(&right.dict),
00044       try_block(NULL)
00045    {
00046       try_block = new CodeBlock(*right.try_block);
00047       catch_blocks = right.catch_blocks;
00048    }
00049    //===========================================================================
00050    TryBlock::TryBlock(const TryBlock& right, Dictionary& dict_in) :
00051       DictionarySpecific(&dict_in),
00052       try_block(NULL)
00053    {
00054       try_block = new CodeBlock(*right.try_block, dict);
00055 
00056       for (size_t i = 0; i < right.catch_blocks.size(); i++)
00057       {
00058          catch_blocks.push_back(CatchBlock(right.catch_blocks[i], dict));
00059       }
00060    }
00061    //===========================================================================
00062    TryBlock::~TryBlock()
00063    {
00064       delete try_block;
00065       try_block = NULL;
00066    }
00067    //===========================================================================
00068    TryBlock& TryBlock::operator=(const TryBlock& right)
00069    {
00070       if (this == &right)
00071       {
00072          return *this;
00073       }
00074       
00075       *try_block = *right.try_block;
00076 
00077       Erase(catch_blocks);
00078       for (size_t i = 0; i < right.catch_blocks.size(); i++)
00079       {
00080          catch_blocks.push_back(CatchBlock(right.catch_blocks[i], dict));
00081       }
00082       
00083       return *this;
00084    }
00085    //===========================================================================
00086    void TryBlock::Read(PersistenceIFace& file, IndexedDictionary& idict)
00087    {
00088       uint32_t size = 0;
00089       
00090       try_block->Read(file, idict);
00091       
00092       Erase(catch_blocks);
00093       size = file.ReadUInt32(KEY_CATCH_BLOCKS_LS);
00094       for (size_t i = 0; i < size; i++)
00095       {
00096          catch_blocks.push_back(CatchBlock(&dict));
00097          catch_blocks.back().Read(file, idict);
00098       }
00099    }
00100    //===========================================================================
00101    void TryBlock::Write(PersistenceIFace& file) const
00102    {
00103       try_block->Write(file);
00104       
00105       file.WriteUInt32(KEY_CATCH_BLOCKS_LS, catch_blocks.size());
00106       for (size_t i = 0; i < catch_blocks.size(); i++)
00107       {
00108          catch_blocks[i].Write(file);
00109       }
00110    }
00111    //===========================================================================
00112    bool TryBlock::operator==(const TryBlock& right) const
00113    {
00114       if (catch_blocks.size() != right.catch_blocks.size())
00115       {
00116          return false;
00117       }
00118 
00119       if (!(*try_block == *right.try_block))
00120       {
00121          return false;
00122       }
00123       
00124       // @@@Brendon !! Actually order is important for catch blocks. Should look
00125       // at changing this.
00126       // Contents is important but order is not.
00127       for (size_t i = 0; i < catch_blocks.size(); i++)
00128       {
00129          bool found = false;
00130          for (size_t j = 0; j < right.catch_blocks.size(); j++)
00131          {
00132             if (catch_blocks[i] == right.catch_blocks[j])
00133             {
00134                found = true;
00135                break;
00136             }
00137          }
00138          
00139          if (!found)
00140          {
00141             return false;
00142          }
00143       }
00144       
00145       return true;
00146    }
00147    //===========================================================================
00148    std::ostream& TryBlock::Print(std::ostream& out, std::string prefix) const
00149    {
00150       out << prefix << "try" << std::endl;
00151       try_block->Print(out, prefix);
00152       for (size_t i = 0; i < catch_blocks.size(); i++)
00153       {
00154          catch_blocks[i].Print(out, prefix);
00155       }
00156       
00157       return out;
00158    }
00159    //===========================================================================
00160    size_t TryBlock::ReplaceReferences(PStack& stack, void* remove, 
00161       void* replace)
00162    {
00163       size_t count = 0;
00164       if (!stack.Push(this))
00165       {
00166          return count;
00167       }
00168 
00169       count += try_block->ReplaceReferences(stack, remove, replace);
00170       for (size_t i = 0; i < catch_blocks.size(); i++)
00171       {
00172          count += catch_blocks[i].ReplaceReferences(stack, remove, replace);
00173       }
00174       
00175       return count;
00176    }
00177    //===========================================================================
00178    void TryBlock::ExpandCallGraph(Function& function)
00179    {
00180       try_block->ExpandCallGraph(function);
00181       
00182       for (size_t i = 0; i < catch_blocks.size(); i++)
00183       {
00184          catch_blocks[i].ExpandCallGraph(function);
00185       }
00186    }
00187    //===========================================================================
00188    void TryBlock::Validate(PStack& stack, const Dictionary& dict_in) const
00189    {
00190       StackRef ref(stack, this);
00191       if (!ref)
00192       {
00193          return;
00194       }
00195       
00196       EDOC_ASSERT(&dict == &dict_in, "");
00197       
00198       try_block->Validate(stack, dict_in);
00199       for (size_t i = 0; i < catch_blocks.size(); i++)
00200       {
00201          catch_blocks[i].Validate(stack, dict_in);
00202       }
00203    }
00204    //===========================================================================
00205 }

Generated on Tue Jan 20 18:26:07 2009 for EDoc-0.2.1 by  doxygen 1.5.1