libs/EDoc/FunctionLoc.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/FunctionLoc.h"
00022 #include "EDoc/Function.h"
00023 #include "EDoc/Dictionary.h"
00024 #include "EDoc/PStack.h"
00025 #include "EDoc/StackRef.h"
00026 
00027 #include "EDoc/PersistenceIFace.h"
00028 #include "IndexedDictionary.h"
00029 #include "EDoc/persistence_data.h"
00030 
00031 namespace EDoc
00032 {
00033    //===========================================================================
00034    FunctionLoc::FunctionLoc(Dictionary& dict_in, Function* value_in, 
00035          const Location& loc_in) :
00036       
00037       DictionarySpecific(&dict_in),
00038       loc(loc_in, dict_in),
00039       value(value_in),
00040       possible(false),
00041       is_top_level(false)
00042    {
00043       EDOC_ASSERT(!value || dict.functions.Get(value->GetKeyName()), "");
00044    }
00045    //===========================================================================
00046    FunctionLoc::FunctionLoc(Dictionary* dict_in) :
00047       DictionarySpecific(dict_in),
00048       loc(dict_in),
00049       value(NULL),
00050       possible(false),
00051       is_top_level(false)
00052    {
00053    }
00054    //===========================================================================
00055    FunctionLoc::FunctionLoc(const FunctionLoc& right) :
00056       DictionarySpecific(&right.dict),
00057       loc(right.loc),
00058       value(right.value),
00059       possible(right.possible),
00060       is_top_level(false)
00061    {
00062    }
00063    //===========================================================================
00064    FunctionLoc::FunctionLoc(const FunctionLoc& right, Dictionary& dict_in) :
00065       DictionarySpecific(&dict_in),
00066       loc(right.loc, dict_in),
00067       value(NULL),
00068       possible(right.possible),
00069       is_top_level(false)
00070    {
00071       if (right.value)
00072       {
00073          value = dict.functions.AlwaysGet(*right.value);
00074       }
00075    }
00076    //===========================================================================
00077    FunctionLoc& FunctionLoc::operator=(const FunctionLoc& right)
00078    {
00079       if (this == &right)
00080       {
00081          return *this;
00082       }
00083       
00084       value = NULL;
00085       if (right.value)
00086       {
00087          value = dict.functions.AlwaysGet(*right.value);
00088       }
00089       possible = right.possible;
00090       
00091       return *this;
00092    }
00093    //===========================================================================
00094    void FunctionLoc::Read(PersistenceIFace& file, IndexedDictionary& idict)
00095    {
00096       // Item then location.
00097       value = idict.functions.AlwaysGet(file.ReadUInt32(KEY_FUNCTION));
00098       
00099       loc.Read(file, idict);
00100    }
00101    //===========================================================================
00102    void FunctionLoc::Write(PersistenceIFace& file) const
00103    {
00104       // Item then location.
00105       EDOC_ASSERT(value, "Value should only ever be NULL for "
00106          "PropagatingException instances and they are never written to file.");
00107       file.WriteUInt32Debug(KEY_FUNCTION, 
00108          value->GetIndex(), value->GetDeclaredName());
00109       
00110       loc.Write(file);
00111    }
00112    //===========================================================================
00113    bool FunctionLoc::operator==(const FunctionLoc& right) const
00114    {
00115       if (loc != right.loc)
00116       {
00117          return false;
00118       }
00119       
00120       // Value can be NULL in which case both must be null to be equal.
00121       if (!value || !right.value)
00122       {
00123          return value == right.value;
00124       }
00125       else
00126       {
00127          return (value->GetNormalisedName() == 
00128             right.value->GetNormalisedName());
00129       }
00130    }
00131    //===========================================================================
00132    bool FunctionLoc::operator<(const FunctionLoc& right) const
00133    {
00134       if (loc < right.loc)
00135       {
00136          return true;
00137       }
00138       else if (!(loc == right.loc))
00139       {
00140          return false;
00141       }
00142 
00143       
00144       // Value can be NULL in which case both must be null to be equal.
00145       if (!value || !right.value)
00146       {
00147          // Use a pointer comparison as the NULL pointer will always be less.
00148          return value < right.value;
00149       }
00150       else
00151       {
00152          return value->GetKeyName() < right.value->GetKeyName();
00153       }
00154 
00155    }
00156    //===========================================================================
00157    //@@@Brendon Possibly use special C++ type conversion functions.
00158    #define EDOC_REPLACE(DataType, Data, From, To, Count) \
00159       if ((void*)Data == From) {Data = (DataType*)To; Count++;}
00160    //===========================================================================
00161    size_t FunctionLoc::ReplaceReferences(PStack& stack, void* remove, 
00162       void* replace)
00163    {
00164       size_t count = 0;
00165       if (!stack.Push(this))
00166       {
00167          return count;
00168       }
00169 
00170       // Dont replace recursivly. Only replace inside us.
00171       EDOC_REPLACE(Function, value, remove, replace, count);
00172 
00173       count += loc.ReplaceReferences(stack, remove, replace);
00174       
00175       return count;
00176    }
00177    //===========================================================================
00178    void FunctionLoc::Validate(PStack& stack, const Dictionary& dict_in) const
00179    {
00180       StackRef ref(stack, this);
00181       if (!ref)
00182       {
00183          return;
00184       }
00185       
00186       EDOC_ASSERT(&dict == &dict_in, "");
00187       
00188       loc.Validate(stack, dict_in);
00189       if (value)
00190       {
00191          value->Validate(stack, dict_in);
00192       }
00193    }
00194    //===========================================================================
00195    std::ostream& FunctionLoc::Print(std::ostream& out, std::string prefix) const
00196    {
00197       // Print the location first
00198       loc.Print(out, prefix);
00199       
00200       // Then the functions key.
00201       out << prefix << "Function: ";
00202       if (value)
00203       {
00204          out << value->GetKeyName();
00205       }
00206       else
00207       {
00208          out << "(NULL)";
00209       }
00210       out << std::endl;
00211       return out;
00212    }
00213    //===========================================================================
00214 }
00215 

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