1 /*  $Id: namespace.cpp 371238 2012-08-07 13:34:40Z gouriano $
2 * ===========================================================================
3 *
4 *                            PUBLIC DOMAIN NOTICE
5 *               National Center for Biotechnology Information
6 *
7 *  This software/database is a "United States Government Work" under the
8 *  terms of the United States Copyright Act.  It was written as part of
9 *  the author's official duties as a United States Government employee and
10 *  thus cannot be copyrighted.  This software/database is freely available
11 *  to the public for use. The National Library of Medicine and the U.S.
12 *  Government have not placed any restriction on its use or reproduction.
13 *
14 *  Although all reasonable efforts have been taken to ensure the accuracy
15 *  and reliability of the software and data, the NLM and the U.S.
16 *  Government do not and cannot warrant the performance or results that
17 *  may be obtained by using this software or data. The NLM and the U.S.
18 *  Government disclaim all warranties, express or implied, including
19 *  warranties of performance, merchantability or fitness for any particular
20 *  purpose.
21 *
22 *  Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Eugene Vasilchenko
27 *
28 * File Description:
29 *   !!! PUT YOUR DESCRIPTION HERE !!!
30 *
31 */
32 
33 #include <ncbi_pch.hpp>
34 #include <corelib/ncbistd.hpp>
35 #include <corelib/ncbiutil.hpp>
36 #include "namespace.hpp"
37 
38 BEGIN_NCBI_SCOPE
39 
40 const string CNamespace::KNCBINamespaceName("ncbi");
41 const string CNamespace::KNCBINamespaceDefine("NCBI_NS_NCBI");
42 const string CNamespace::KSTDNamespaceName("std");
43 const string CNamespace::KSTDNamespaceDefine("NCBI_NS_STD");
44 
45 const CNamespace CNamespace::KEmptyNamespace;
46 const CNamespace CNamespace::KNCBINamespace(KNCBINamespaceName);
47 const CNamespace CNamespace::KSTDNamespace(KSTDNamespaceName);
48 
CNamespace(void)49 CNamespace::CNamespace(void)
50     : m_UseFullname(false)
51 {
52 }
53 
CNamespace(const string & ns)54 CNamespace::CNamespace(const string& ns)
55     : m_UseFullname(false)
56 {
57     SIZE_TYPE pos = 0;
58     if ( NStr::StartsWith(ns, "::") )
59         pos = 2; // skip leading ::
60 
61     SIZE_TYPE end = ns.find("::", pos);
62     while ( end != NPOS ) {
63         m_Namespaces.push_back(ns.substr(pos, end-pos));
64         pos = end + 2;
65         end = ns.find("::", pos);
66     }
67     string last(ns.substr(pos));
68     if (!last.empty()) {
69         m_Namespaces.push_back(last);
70     }
71     if (!m_Namespaces.empty()) {
72         if ( m_Namespaces[0] == KNCBINamespaceDefine )
73             m_Namespaces[0] = KNCBINamespaceName;
74         else if ( m_Namespaces[0] == KSTDNamespaceDefine )
75             m_Namespaces[0] = KSTDNamespaceName;
76     }
77 }
78 
EqualLevels(const CNamespace & ns) const79 size_t CNamespace::EqualLevels(const CNamespace& ns) const
80 {
81     size_t end = min(GetNamespaceLevel(), ns.GetNamespaceLevel());
82     for ( size_t i = 0; i < end; ++i ) {
83         if ( GetNamespaces()[i] != ns.GetNamespaces()[i] )
84             return i;
85     }
86     return end;
87 }
88 
Set(const CNamespace & ns,CNcbiOstream & out,bool mainHeader)89 void CNamespace::Set(const CNamespace& ns, CNcbiOstream& out, bool mainHeader)
90 {
91     size_t equal = EqualLevels(ns);
92     CloseAllAbove(equal, out);
93     for ( size_t i = equal, end = ns.GetNamespaceLevel(); i < end; ++i )
94         Open(ns.GetNamespaces()[i], out, mainHeader);
95 }
96 
GetNamespaceRef(const CNamespace & ns) const97 string CNamespace::GetNamespaceRef(const CNamespace& ns) const
98 {
99     size_t equal = EqualLevels(ns);
100     string s;
101     if ( equal == GetNamespaceLevel() ) {
102         // internal namespace
103     }
104     else {
105         // reference from root
106         equal = 0;
107         if ( ns.InNCBI() ) {
108             s = KNCBINamespaceDefine;
109             equal = 1;
110         }
111         else if ( ns.InSTD() ) {
112             s = KSTDNamespaceDefine;
113             equal = 1;
114         }
115         if (!ns.UseFullname()) {
116             if ( equal == 1 ) {
117                 // std or ncbi
118                 if ( InNCBI() )
119                     s.erase();
120                 else
121                     s += "::";
122             }
123             else {
124                 // from root
125                 s = "::";
126             }
127         }
128         else if (!s.empty()) {
129             s += "::";
130         }
131     }
132     for ( size_t i = equal, end = ns.GetNamespaceLevel(); i < end; ++i ) {
133         s += ns.GetNamespaces()[i];
134         s += "::";
135     }
136     return s;
137 }
138 
Open(const string & s,CNcbiOstream & out,bool mainHeader)139 void CNamespace::Open(const string& s, CNcbiOstream& out, bool mainHeader)
140 {
141     m_Namespaces.push_back(s);
142     if ( IsNCBI() ) {
143         out <<
144             "BEGIN_NCBI_SCOPE\n"
145             "\n";
146     }
147     else {
148         if ( mainHeader ) {
149             out <<
150                 "#ifndef BEGIN_"<<s<<"_SCOPE\n"
151                 "#  define BEGIN_"<<s<<"_SCOPE BEGIN_SCOPE("<<s<<")\n"
152                 "#  define END_"<<s<<"_SCOPE END_SCOPE("<<s<<")\n"
153                 "#endif\n";
154         }
155         out <<
156             "BEGIN_"<<s<<"_SCOPE // namespace "<<*this<<"\n"
157             "\n";
158     }
159 }
160 
Close(CNcbiOstream & out)161 void CNamespace::Close(CNcbiOstream& out)
162 {
163     _ASSERT(!m_Namespaces.empty());
164     if ( IsNCBI() ) {
165         out <<
166             "END_NCBI_SCOPE\n"
167             "\n";
168     }
169     else {
170         out <<
171             "END_"<<m_Namespaces.back()<<"_SCOPE // namespace "<<*this<<"\n"
172             "\n";
173     }
174     m_Namespaces.pop_back();
175 }
176 
CloseAllAbove(size_t level,CNcbiOstream & out)177 void CNamespace::CloseAllAbove(size_t level, CNcbiOstream& out)
178 {
179     for ( size_t size = GetNamespaceLevel(); size > level; --size )
180         Close(out);
181 }
182 
PrintFullName(CNcbiOstream & out) const183 CNcbiOstream& CNamespace::PrintFullName(CNcbiOstream& out) const
184 {
185     ITERATE ( TNamespaces, i, GetNamespaces() )
186         out << *i << "::";
187     return out;
188 }
189 
ToStringTo(string & s) const190 void CNamespace::ToStringTo(string& s) const
191 {
192     ITERATE ( TNamespaces, i, GetNamespaces() ) {
193         s += *i;
194         s += "::";
195     }
196 }
197 
198 END_NCBI_SCOPE
199