1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 #include <precomp.h>
23 #include "opageenv.hxx"
24 
25 
26 // NOT FULLY DEFINED SERVICES
27 #include <cosv/ploc_dir.hxx>
28 #include <ary/cpp/c_ce.hxx>
29 #include <ary/cpp/c_class.hxx>
30 #include <ary/cpp/c_enum.hxx>
31 #include <ary/cpp/c_gate.hxx>
32 #include <ary/cpp/c_namesp.hxx>
33 #include <ary/cpp/c_tydef.hxx>
34 #include <ary/cpp/cp_ce.hxx>
35 #include <ary/loc/loc_file.hxx>
36 #include <udm/html/htmlitem.hxx>
37 #include <estack.hxx>
38 #include "hdimpl.hxx"
39 #include "strconst.hxx"
40 
41 
42 const String  C_sCppDir( "names" );
43 const String  C_sIndexDir( "ix" );
44 
45 
46 //************************         Implementation          ********************//
47 
48 namespace
49 {
50 
51 void    CreateDirectory( const csv::ploc::Path &    i_rPath );
52 
53 void
CreateDirectory(const csv::ploc::Path & i_rPath)54 CreateDirectory( const csv::ploc::Path & i_rPath )
55 {
56     csv::ploc::Directory aDirectory(i_rPath);
57 	if (NOT aDirectory.Exists())
58         aDirectory.PhysicalCreate();
59 }
60 
61 //************************         CheshireCat          ********************//
62 
63 struct InNamespaceTree
64 {
65     enum E_Type
66     {
67         t_unknown,
68         t_namespace,
69         t_type,
70         t_operations,
71         t_data
72     };
73 
74     EStack< const ary::cpp::Namespace * >
75                         aNamespaces; /// never empty.
76     EStack< const ary::cpp::Class * >
77                         aClasses;      /// maybe empty.
78     const ary::cpp::CodeEntity *
79                         pCe;        /// CurFileCe, maybe 0
80     E_Type              eType;
81 
82                         InNamespaceTree(
83                             const ary::cpp::Namespace &
84                                                 i_rNsp );
85                         ~InNamespaceTree();
86     void                GoDown(
87                             const ary::cpp::Namespace &
88                                                 i_rNsp );
89     void                GoDown(
90                             const ary::cpp::Class &
91                                                 i_rClass );
92     void                GoUp();
93 };
94 
InNamespaceTree(const ary::cpp::Namespace & i_rNsp)95 InNamespaceTree::InNamespaceTree( const ary::cpp::Namespace & i_rNsp )
96     :   // aNamespaces,
97         // aClasses,
98         pCe(0),
99         eType(t_unknown)
100 {
101     aNamespaces.push( &i_rNsp );
102 }
103 
~InNamespaceTree()104 InNamespaceTree::~InNamespaceTree()
105 {
106 }
107 
108 void
GoDown(const ary::cpp::Namespace & i_rNsp)109 InNamespaceTree::GoDown( const ary::cpp::Namespace & i_rNsp )
110 {
111     aNamespaces.push(&i_rNsp);
112     aClasses.erase_all();
113     pCe = 0;
114     eType = t_unknown;
115 }
116 
117 void
GoDown(const ary::cpp::Class & i_rClass)118 InNamespaceTree::GoDown( const ary::cpp::Class & i_rClass )
119 {
120     aClasses.push(&i_rClass);
121     pCe = 0;
122     eType = t_unknown;
123 }
124 
125 void
GoUp()126 InNamespaceTree::GoUp()
127 {
128     if ( NOT aClasses.empty() )
129         aClasses.pop();
130     else
131         aNamespaces.pop();
132     pCe = 0;
133     eType = t_unknown;
134 }
135 
136 struct InIndex
137 {
138     char                cLetter;
139 
InIndex__anonc405e81c0111::InIndex140                         InIndex() : cLetter('A') {}
141 };
142 
143 
144 }   // anonymous namespace
145 
146 
147 
148 
149 
150 struct OuputPage_Environment::CheshireCat
151 {
152     csv::ploc::Path     aOutputRoot;
153     csv::ploc::Path     aMyPath;
154     csv::StreamStr      aFileName;
155 
156     const ary::cpp::Gate *
157                         pGate;
158     const display::CorporateFrame *
159                         pLayout;
160     intt                nDepth;
161 
162     Dyn<InNamespaceTree>
163                         pInNamespace;
164     Dyn<InIndex>        pInIndex;
165 
166                         CheshireCat(
167                             const csv::ploc::Path &
168                                                 io_rOutputDir,
169                             const ary::cpp::Gate &
170                                                 i_rGate,
171                             const display::CorporateFrame &
172                                                 i_rLayout );
173                         ~CheshireCat();
174     void                AddQualifiedName2Path(
175                             const ary::cpp::CodeEntity &
176                                                 i_rCe,
177                             bool                i_bIncludeLocalName );
178 
179     const Dyn<InNamespaceTree> &
NspEnvOuputPage_Environment::CheshireCat180                         NspEnv() const          { return pInNamespace; }
181     Dyn<InNamespaceTree> &
NspEnvOuputPage_Environment::CheshireCat182                         NspEnv()                { return pInNamespace; }
183     const ary::cpp::Namespace *
NamespaceOuputPage_Environment::CheshireCat184                         Namespace() const       { return pInNamespace ? pInNamespace->aNamespaces.top() : 0; }
185     const ary::cpp::Class *
ClassOuputPage_Environment::CheshireCat186                         Class() const           { return pInNamespace ? (pInNamespace->aClasses.empty() ? 0 : pInNamespace->aClasses.top()) : 0; }
187 };
188 
189 OuputPage_Environment::
CheshireCat(const csv::ploc::Path & io_rOutputDir,const ary::cpp::Gate & i_rGate,const display::CorporateFrame & i_rLayout)190 CheshireCat::CheshireCat( const csv::ploc::Path &         io_rOutputDir,
191                           const ary::cpp::Gate &   i_rGate,
192                           const display::CorporateFrame & i_rLayout )
193     :   aOutputRoot(io_rOutputDir),
194         aMyPath(io_rOutputDir),
195         aFileName(500),
196         pGate(&i_rGate),
197         pLayout(&i_rLayout),
198         nDepth(0),
199         pInNamespace(),
200         pInIndex()
201 {
202 }
203 
204 OuputPage_Environment::
~CheshireCat()205 CheshireCat::~CheshireCat()
206 {
207 }
208 
209 void
210 OuputPage_Environment::
AddQualifiedName2Path(const ary::cpp::CodeEntity & i_rCe,bool i_bIncludeLocalName)211 CheshireCat::AddQualifiedName2Path( const ary::cpp::CodeEntity & i_rCe,
212                                     bool                    i_bIncludeLocalName )
213 {
214     if (NOT i_rCe.Owner().IsValid())
215     {
216         aMyPath.DirChain().PushBack( C_sCppDir );
217         return;
218     }
219 
220     const ary::cpp::CodeEntity &
221         rParent = pGate->Ces().Find_Ce( i_rCe.Owner() );
222     AddQualifiedName2Path( rParent, true );
223 
224     if ( i_bIncludeLocalName )
225         aMyPath.DirChain().PushBack( i_rCe.LocalName() );
226 }
227 
228 
229 
230 //************************         OuputPage_Environment          ********************//
231 
OuputPage_Environment(const csv::ploc::Path & io_rOutputDir,const ary::cpp::Gate & i_rGate,const display::CorporateFrame & i_rLayout)232 OuputPage_Environment::OuputPage_Environment( const csv::ploc::Path &           io_rOutputDir,
233                                               const ary::cpp::Gate &            i_rGate,
234                                               const display::CorporateFrame &   i_rLayout )
235     :   pi( new CheshireCat(io_rOutputDir, i_rGate, i_rLayout) )
236 {
237 }
238 
~OuputPage_Environment()239 OuputPage_Environment::~OuputPage_Environment()
240 {
241 }
242 
243 void
MoveDir_2Root()244 OuputPage_Environment::MoveDir_2Root()
245 {
246     pi->NspEnv() = 0;
247     pi->pInIndex = 0;
248     pi->nDepth = 0;
249     while ( pi->aMyPath.DirChain().Size() > pi->aOutputRoot.DirChain().Size() )
250         pi->aMyPath.DirChain().PopBack();
251     pi->aMyPath.SetFile(String ::Null_());
252 }
253 
254 void
MoveDir_2Names()255 OuputPage_Environment::MoveDir_2Names()
256 {
257     pi->NspEnv() = new InNamespaceTree( Gate().Ces().GlobalNamespace() );
258     pi->aMyPath.DirChain().PushBack( C_sCppDir );
259     pi->aMyPath.SetFile(String ::Null_());
260     ++pi->nDepth;
261 
262    	CreateDirectory( pi->aMyPath );
263 }
264 
265 void
MoveDir_Down2(const ary::cpp::Namespace & i_rNsp)266 OuputPage_Environment::MoveDir_Down2( const ary::cpp::Namespace & i_rNsp )
267 {
268     csv_assert(i_rNsp.Depth() > 0);
269     csv_assert( pi->NspEnv() );
270     csv_assert( pi->Namespace()->CeId() == i_rNsp.Owner() );
271 
272     pi->NspEnv()->GoDown( i_rNsp );
273     pi->aMyPath.DirChain().PushBack(i_rNsp.LocalName());
274     ++pi->nDepth;
275     pi->aMyPath.SetFile(String ::Null_());
276 
277    	CreateDirectory( pi->aMyPath );
278 }
279 
280 void
MoveDir_Down2(const ary::cpp::Class & i_rClass)281 OuputPage_Environment::MoveDir_Down2( const ary::cpp::Class & i_rClass )
282 {
283     csv_assert( pi->NspEnv() );
284     if ( i_rClass.Protection() == ary::cpp::PROTECT_global )
285     {
286         csv_assert( pi->Namespace()->CeId() == i_rClass.Owner() );
287     }
288     else
289     {
290         csv_assert( pi->Class() != 0 );
291         csv_assert( pi->Class()->CeId() == i_rClass.Owner() );
292     }
293 
294     pi->NspEnv()->GoDown(i_rClass);
295     pi->aMyPath.DirChain().PushBack(i_rClass.LocalName());
296     pi->aMyPath.SetFile(String ::Null_());
297     ++pi->nDepth;
298 
299    	CreateDirectory( pi->aMyPath );
300 }
301 
302 void
MoveDir_2Index()303 OuputPage_Environment::MoveDir_2Index()
304 {
305     MoveDir_2Root();
306     pi->pInIndex = new InIndex;
307     pi->aMyPath.DirChain().PushBack( String (C_sDIR_Index) );
308     pi->aMyPath.SetFile(String ::Null_());
309     pi->nDepth = 1;
310 
311    	CreateDirectory( pi->aMyPath );
312 }
313 
314 void
MoveDir_Up()315 OuputPage_Environment::MoveDir_Up()
316 {
317  	if ( pi->nDepth == 1 )
318     {
319      	MoveDir_2Root();
320         return;
321     }
322     else if ( pi->NspEnv() )
323     {
324         pi->NspEnv()->GoUp();
325         pi->aMyPath.DirChain().PopBack();
326         pi->aMyPath.SetFile(String ::Null_());
327         --pi->nDepth;
328     }
329 }
330 
331 void
SetFile_Css()332 OuputPage_Environment::SetFile_Css()
333 {
334     pi->aMyPath.SetFile( C_sHFN_Css );
335 }
336 
337 void
SetFile_Overview()338 OuputPage_Environment::SetFile_Overview()
339 {
340     pi->aMyPath.SetFile( C_sHFN_Overview );
341 }
342 
343 void
SetFile_AllDefs()344 OuputPage_Environment::SetFile_AllDefs()
345 {
346     // Provisorium
347     pi->aMyPath.SetFile("def-all.html");
348 }
349 
350 void
SetFile_Index(char i_cLetter)351 OuputPage_Environment::SetFile_Index( char i_cLetter )
352 {
353     csv_assert( 'A' <= i_cLetter AND i_cLetter <= 'Z' OR i_cLetter == '_' );
354 
355     static StreamStr sIndexFileName(40);
356     sIndexFileName.seekp(0);
357     sIndexFileName << "index-";
358     if ( i_cLetter == '_' )
359     {
360         sIndexFileName << "27";
361     }
362     else
363     {
364         sIndexFileName << int(i_cLetter -'A' + 1);
365     }
366     sIndexFileName << ".html";
367 
368     pi->aMyPath.SetFile( sIndexFileName.c_str() );
369 }
370 
371 void
SetFile_Help()372 OuputPage_Environment::SetFile_Help()
373 {
374     pi->aMyPath.SetFile( C_sHFN_Help );
375 }
376 
377 void
SetFile_CurNamespace()378 OuputPage_Environment::SetFile_CurNamespace()
379 {
380     csv_assert( pi->NspEnv() );
381     pi->aMyPath.SetFile("index.html");
382     pi->NspEnv()->pCe = pi->Namespace();
383     pi->NspEnv()->eType = InNamespaceTree::t_namespace;
384 }
385 
386 void
SetFile_Class(const ary::cpp::Class & i_rClass)387 OuputPage_Environment::SetFile_Class( const ary::cpp::Class & i_rClass )
388 {
389     csv_assert( pi->NspEnv() );
390     pi->aMyPath.SetFile( ClassFileName(i_rClass.LocalName()) );
391     pi->NspEnv()->pCe = &i_rClass;
392     pi->NspEnv()->eType = InNamespaceTree::t_type;
393 }
394 
395 void
SetFile_Enum(const ary::cpp::Enum & i_rEnum)396 OuputPage_Environment::SetFile_Enum( const ary::cpp::Enum & i_rEnum )
397 {
398     csv_assert( pi->NspEnv() );
399     pi->aMyPath.SetFile( EnumFileName(i_rEnum.LocalName()) );
400     pi->NspEnv()->pCe = &i_rEnum;
401     pi->NspEnv()->eType = InNamespaceTree::t_type;
402 }
403 
404 void
SetFile_Typedef(const ary::cpp::Typedef & i_rTypedef)405 OuputPage_Environment::SetFile_Typedef( const ary::cpp::Typedef & i_rTypedef )
406 {
407     csv_assert( pi->NspEnv() );
408     pi->aMyPath.SetFile( TypedefFileName(i_rTypedef.LocalName()) );
409     pi->NspEnv()->pCe = &i_rTypedef;
410     pi->NspEnv()->eType = InNamespaceTree::t_type;
411 }
412 
413 void
SetFile_Operations(const ary::loc::File * i_pFile)414 OuputPage_Environment::SetFile_Operations( const ary::loc::File * i_pFile )
415 {
416     csv_assert( pi->NspEnv() );
417     if ( CurClass() != 0 )
418         pi->aMyPath.SetFile( "o.html" );
419 	else
420     {
421         csv_assert( i_pFile != 0 );
422         pi->aMyPath.SetFile( HtmlFileName("o-", i_pFile->LocalName()) );
423     }
424     pi->NspEnv()->pCe = 0;
425     pi->NspEnv()->eType = InNamespaceTree::t_operations;
426 }
427 
428 void
SetFile_Data(const ary::loc::File * i_pFile)429 OuputPage_Environment::SetFile_Data( const ary::loc::File * i_pFile )
430 {
431     csv_assert( pi->NspEnv() );
432     if ( CurClass() != 0 )
433         pi->aMyPath.SetFile( "d.html" );
434     else
435     {
436         csv_assert( i_pFile != 0 );
437         pi->aMyPath.SetFile( HtmlFileName("d-", i_pFile->LocalName()) );
438     }
439     pi->NspEnv()->pCe = 0;
440     pi->NspEnv()->eType = InNamespaceTree::t_data;
441 }
442 
443 const ary::cpp::Namespace *
CurNamespace() const444 OuputPage_Environment::CurNamespace() const
445 {
446     return pi->Namespace();
447 }
448 
449 const ary::cpp::Class *
CurClass() const450 OuputPage_Environment::CurClass() const
451 {
452     return pi->Class();
453 }
454 
455 const csv::ploc::Path &
CurPath() const456 OuputPage_Environment::CurPath() const
457 {
458     return pi->aMyPath;
459 }
460 
461 const ary::cpp::Gate &
Gate() const462 OuputPage_Environment::Gate() const
463 {
464     return *pi->pGate;
465 }
466 
467 const display::CorporateFrame &
Layout() const468 OuputPage_Environment::Layout() const
469 {
470     return *pi->pLayout;
471 }
472 
473 uintt
Depth() const474 OuputPage_Environment::Depth() const
475 {
476     return static_cast<uintt>(pi->nDepth);
477 }
478 
479 const String &
RepositoryTitle() const480 OuputPage_Environment::RepositoryTitle() const
481 {
482     return Gate().RepositoryTitle();
483 }
484