mummy  1.0.3
MummyApplication.cxx
Go to the documentation of this file.
1 //----------------------------------------------------------------------------
2 //
3 // $Id: MummyApplication.cxx 506 2010-07-27 15:30:53Z david.cole $
4 //
5 // $Author: david.cole $
6 // $Date: 2010-07-27 11:30:53 -0400 (Tue, 27 Jul 2010) $
7 // $Revision: 506 $
8 //
9 // Copyright (C) 2006-2009 Kitware, Inc.
10 //
11 //----------------------------------------------------------------------------
12 
13 #include "MummyApplication.h"
14 #include "MummyCsharpGenerator.h"
18 #include "MummyLog.h"
19 #include "MummySettings.h"
20 
21 #include "cableClass.h"
22 #include "cableClassType.h"
23 #include "cableContext.h"
24 #include "cableMethod.h"
25 #include "cableNamespace.h"
26 #include "cableSourceRepresentation.h"
27 #include "cableTypedef.h"
28 #include "cableVariable.h"
29 #include "cableXMLSourceParser.h"
30 #include "cxxFundamentalType.h"
31 
32 #include "gxsys/ios/fstream"
33 #include "gxsys/ios/iostream"
34 #include "gxsys/ios/sstream"
35 #include "gxsys/stl/map"
36 #include "gxsys/stl/set"
37 #include "gxsys/stl/string"
38 
39 #include "string.h" // strlen
40 
41 
42 //----------------------------------------------------------------------------
44 {
45  this->Settings = 0;
46 }
47 
48 
49 //----------------------------------------------------------------------------
51 {
52 }
53 
54 
55 //----------------------------------------------------------------------------
56 int MummyApplication::Main(int argc, char *argv[])
57 {
58  int err = 0;
59 
60  MummySettings settings;
61  this->SetSettings(&settings);
62 
63  err = settings.Initialize(argc, argv);
64 
65  if (!err && settings.ShouldRun())
66  {
67  cable::SourceRepresentation::Pointer sr = BuildSourceRepresentation();
68 
69  err = ProcessSource(sr);
70  }
71 
72  this->SetSettings(0);
73 
74  return GetFirstErrorValue();
75 }
76 
77 
78 //----------------------------------------------------------------------------
80 {
81  return this->Settings;
82 }
83 
84 
85 //----------------------------------------------------------------------------
87 {
88  this->Settings = settings;
89 }
90 
91 
92 //----------------------------------------------------------------------------
93 cable::SourceRepresentation* MummyApplication::BuildSourceRepresentation()
94 {
95  const char* inFileName = this->GetSettings()->GetGccxmlFileName();
96 
97  if (!inFileName || (0 == strlen(inFileName)))
98  {
99  LogError(me_InvalidArg, << "Must specify valid --gccxml-file (use --help for options).");
100  return 0;
101  }
102 
103  LogVerboseInfo(<< "Using --gccxml-file '" << inFileName << "'");
104 
105  // Open the XML input file produced by GCC-XML.
106  gxsys_ios::ifstream inFile(inFileName, std::ios_base::in|std::ios_base::binary);
107  if (!inFile)
108  {
109  LogError(me_CouldNotOpen, << "Could not open GCC-XML output: " << inFileName);
110  return 0;
111  }
112 
113  // Parse the XML input file.
114  cable::XMLSourceParser::Pointer parser = cable::XMLSourceParser::New();
115  parser->SetStream(&inFile);
116  if(!parser->Parse())
117  {
118  LogError(me_CouldNotParse, << "Could not parse GCC-XML output: " << inFileName);
119  return 0;
120  }
121  parser->SetStream(0);
122  inFile.close();
123 
124  // Get the parsed source representation.
125  return parser->GetSourceRepresentation();
126 }
127 
128 
129 //----------------------------------------------------------------------------
130 int MummyApplication::ProcessSource(cable::SourceRepresentation* sr)
131 {
132  int err = 0;
133 
134  if (!sr)
135  {
136  LogError(me_InvalidArg, << "MummyApplication::ProcessSource");
137  return me_InvalidArg;
138  }
139 
140  gxsys_stl::string s;
141  const cable::Namespace* gns = sr->GetGlobalNamespace();
142 
143  // Look inside the _cable_ namespace for a wrappers namespace
144  // and classes within:
145  //
146  cable::Context::Iterator lower = gns->LowerBound("_cable_");
147  cable::Context::Iterator upper = gns->UpperBound("_cable_");
148  cable::Namespace* cns = 0;
149  if (lower != upper)
150  {
151  cns = cable::Namespace::SafeDownCast(*lower);
152  }
153  if (!cns)
154  {
155  LogError(me_UnexpectedGccxmlInput, << "MummyApplication::ProcessSource");
157  }
158 
159  // Give the settings object a chance to read package, packageVersion
160  // and group info out of the source rep:
161  //
162  err = this->GetSettings()->ProcessSource(sr);
163 
164  // Collect up all the classes to be wrapped:
165  //
166  gxsys_stl::map<const cable::Class*, cable::Typedef*> TypedefLookup;
167  gxsys_stl::set<const cable::Class*> ClassesToBeIncluded;
168 
169  const cable::Namespace* wns = 0;
170  cable::Context::Iterator wlower = cns->LowerBound("wrappers");
171  cable::Context::Iterator wupper = cns->UpperBound("wrappers");
172  if (wlower != wupper)
173  {
174  wns = cable::Namespace::SafeDownCast(*wlower);
175  }
176  if (!wns)
177  {
178  LogError(me_UnexpectedGccxmlInput, << "MummyApplication::ProcessSource");
180  }
181 
182  for (cable::Context::Iterator w = wns->Begin(); w != wns->End(); ++w)
183  {
184  cable::Typedef* td = cable::Typedef::SafeDownCast(*w);
185  if(td)
186  {
187  const cable::ClassType* ct = cable::ClassType::SafeDownCast(td->GetType());
188  if(ct)
189  {
190  const cable::Class* c = ct->GetClass();
191  TypedefLookup.insert(gxsys_stl::make_pair(c, td));
192  ClassesToBeIncluded.insert(c);
193  }
194  }
195  }
196 
197  // Wrap 'em:
198  //
199  for (gxsys_stl::set<const cable::Class*>::iterator i =
200  ClassesToBeIncluded.begin(); !err && i != ClassesToBeIncluded.end(); ++i)
201  {
202  const cable::Class* c = *i;
203 
204  //cable::Typedef* td = 0;
205  //gxsys_stl::map<const cable::Class*, cable::Typedef*>::iterator tdi =
206  // TypedefLookup.find(c);
207  //if(tdi != TypedefLookup.end())
208  // {
209  // td = tdi->second;
210  // }
211 
212  err = this->ProcessClass(sr, c);
213  }
214 
215  return err;
216 }
217 
218 
219 //----------------------------------------------------------------------------
220 int MummyApplication::ProcessClass(cable::SourceRepresentation* sr, const cable::Class* c)
221 {
222  int err = 0;
223 
224  if (!ValidateBaseClasses(c))
225  {
226  LogError(me_CouldNotValidate, << "ValidateBaseClasses failed for class '" << c->GetName() << "'");
227  return me_CouldNotValidate;
228  }
229 
230  if (!this->GetSettings()->ClassIsWrappable(c))
231  {
232  LogError(me_CouldNotWrap, << "ClassIsWrappable returned false for class '" << c->GetName() << "'");
233  return me_CouldNotWrap;
234  }
235 
237  gxsys_ios::ostringstream ossCS;
238  csg.SetSettings(this->GetSettings());
239  csg.SetSourceRepresentation(sr);
240  csg.SetStream(&ossCS);
241  csg.SetTargetClass(c);
242  csg.Generate();
243 
245  gxsys_ios::ostringstream ossEL;
246  cselg.SetCsharpGenerator(&csg);
247  cselg.SetSettings(this->GetSettings());
248  cselg.SetSourceRepresentation(sr);
249  cselg.SetStream(&ossEL);
250  cselg.SetTargetClass(c);
251  cselg.Generate();
252 
253  if (this->GetSettings()->GetUseShadow(c))
254  {
256  csslg.SetCsharpGenerator(&csg);
257  csslg.SetSettings(this->GetSettings());
258  csslg.SetSourceRepresentation(sr);
259  csslg.SetStream(&ossEL);
260  csslg.SetTargetClass(c);
261  csslg.Generate();
262  }
263 
265  gxsys_ios::ostringstream ossUT;
266  csutg.SetCsharpGenerator(&csg);
267  csutg.SetSettings(this->GetSettings());
268  csutg.SetSourceRepresentation(sr);
269  csutg.SetStream(&ossUT);
270  csutg.SetTargetClass(c);
271  csutg.Generate();
272 
273  WriteToFile(this->GetSettings()->GetCsharpFileName(c).c_str(), ossCS.str().c_str());
274  LogVerboseInfo("Wrote file: " << this->GetSettings()->GetCsharpFileName(c));
275 
276  WriteToFile(this->GetSettings()->GetExportLayerFileName(c).c_str(), ossEL.str().c_str());
277  LogVerboseInfo("Wrote file: " << this->GetSettings()->GetExportLayerFileName(c));
278 
279 // Not yet ready for prime time:
280 // WriteToFile(this->GetSettings()->GetCsharpUnitTestFileName(c).c_str(), ossUT.str().c_str());
281 // LogVerboseInfo("Wrote file: " << this->GetSettings()->GetCsharpUnitTestFileName(c));
282 
283  return err;
284 }
285 
286 
378 
379 
380 // // // DONE // // //
381 
382 // get rid of "ref" args for things like "double*" and "int*" where
383 // we do not know how much memory the thing points to... Translate to an
384 // array if size is known, otherwise, translate to IntPtr -- only use
385 // "ref" for "double&" (actual reference-type args...)
386 
387 // configure or generate an AssemblyInfo.cs with version number info in it
388 // for each managed dll...
389 
390 // pull in VTK hints file (similar to inline hint iwhArraySize)
391 
392 // hand-craft(?) VTK events
393 
394 // "install"
395 
396 // identify all methods that require the iwhCounted hint because they
397 // return objects that have already been registered (anything "like"
398 // a factory method)
399 
400 // flesh out C# keywords table to include *all* C# keywords
401 
402 // Make getters const -- add warnings to mummy for void/non-const getters...
403 // (added mw_PropGetReturnsVoid and mw_PropGetNotConst)
404 
405 // hint to remove "property get/set or just set" code from *some* generated C#
406 // structs?? -- iwhNoFieldAccess -- (add the hint, then write gets/sets
407 // manually...)
408 
409 // other Session Manager ModelCreated/Deleting events (namespace qualification
410 // required...)
411 
412 // handle NULL object pointer return values from methods properly
413 
414 // test infrastructure work : mummy wrapping of "main" style funcs
415 // recognize argc/argv param pairs and transform to a single string[] param in
416 // the C# method (automatic "main" wrapping...) -- if name is "main" transform
417 // to "Main"??
418 
419 // handle Register/UnRegister properly
420 
421 // turn warnings back on
422 
423 // add "iwhPropGet/iwhPropSet needed?" for "^[gGsS]et" methods warning
424 
425 // warning suppression code, so we can ignore the many, many warnings
426 // from wrapping VTK while still keeping them for other code bases...
427 
428 // make header file header blocks uniform -- update copyright everywhere:
429 // header and source file leading comment blocks
430 
431 // re-structuring (table of all objects, one-to-one map,
432 // methodology for removing objects from table, a working "KeepAlive" strategy)
433 
434 // table stuff and other incidentals while I'm in there...
435 
436 // consistently log errors when functions that return type strings encounter
437 // an unknown type
438 
439 // make sure wrapped reference args work at runtime - done in SignatureSeries
440 // example class
441 
442 // search for any generated "ERROR_" chunks
443 
444 
445 //----------------------------------------------------------------------------