mummy  1.0.3
MummyUtilities.cxx
Go to the documentation of this file.
1 //----------------------------------------------------------------------------
2 //
3 // $Id: MummyUtilities.cxx 470 2009-06-12 17:43:02Z hoffman $
4 //
5 // $Author: hoffman $
6 // $Date: 2009-06-12 13:43:02 -0400 (Fri, 12 Jun 2009) $
7 // $Revision: 470 $
8 //
9 // Copyright (C) 2006-2007 Kitware, Inc.
10 //
11 //----------------------------------------------------------------------------
12 
13 #include "MummyUtilities.h"
14 #include "MummyLog.h"
15 
16 #include "cableClass.h"
17 #include "cableClassType.h"
18 #include "cableConstructor.h"
19 #include "cableFunctionType.h"
20 #include "cableNamed.h"
21 #include "cablePointerType.h"
22 #include "cableReferenceType.h"
23 #include "cableType.h"
24 #include "cableTypedef.h"
25 
26 #include "cxxFundamentalType.h"
27 
28 #include "gxsys/RegularExpression.hxx"
29 #include "gxsys/SystemTools.hxx"
30 #include "gxsys/ios/fstream"
31 #include "gxsys/ios/sstream"
32 #include "gxsys/stl/map"
33 
34 #ifdef _WIN32
35 #include <windows.h> // only for "OutputDebugString"
36 #endif // _WIN32
37 
38 #include "string.h" // strlen
39 
40 
41 //----------------------------------------------------------------------------
42 void Trace(const char *s)
43 {
44 #ifdef _WIN32
45  OutputDebugString(s);
46 #endif // _WIN32
47 
48  //LogInfo(mi_Info, << s);
49 }
50 
51 
52 //----------------------------------------------------------------------------
53 void Emit(gxsys_ios::ostream &os, const char *s)
54 {
55  //Trace(s);
56  os << s;
57 }
58 
59 
60 //----------------------------------------------------------------------------
61 void EmitInt(gxsys_ios::ostream &os, const int i)
62 {
63  os << i;
64 }
65 
66 
67 //----------------------------------------------------------------------------
68 void EmitUint(gxsys_ios::ostream &os, const unsigned int i)
69 {
70  os << i;
71 }
72 
73 
74 //----------------------------------------------------------------------------
75 void EmitIndent(gxsys_ios::ostream &os, const unsigned int n)
76 {
77  // See also: indentString in EmitDocumentationBlock. If we change it here,
78  // we probably will want to change it there also...
79  //
80  unsigned int i = 0;
81  for (i= 0; i<n; ++i)
82  {
83  Emit(os, " ");
84  }
85 }
86 
87 
88 //----------------------------------------------------------------------------
89 void EmitFile(gxsys_ios::ostream &os, const char *filename)
90 {
91  gxsys_ios::ifstream file(filename);
92  if (file)
93  {
94  char line[4100];
95  while (!file.eof())
96  {
97  line[0] = 0;
98  file.getline(line, 4099);
99  os << line << gxsys_ios::endl;
100  }
101  }
102 }
103 
104 
105 //----------------------------------------------------------------------------
106 void WriteToFile(const char *filename, const char *s)
107 {
108  gxsys_ios::ofstream file;
109  file.open(filename, gxsys_ios::ios_base::out | gxsys_ios::ios_base::trunc);
110  if (file)
111  {
112  file << s;
113  file.flush();
114  file.close();
115  }
116 }
117 
118 
119 //----------------------------------------------------------------------------
120 bool IsChar(const cable::Type *t)
121 {
122  return IsFundamental(t, cxx::FundamentalType::Char);
123 }
124 
125 
126 //----------------------------------------------------------------------------
127 bool IsFundamental(const cable::Type *t, cxx::FundamentalType::Id tid)
128 {
129  if (cable::Type::FundamentalTypeId == t->GetTypeId())
130  {
131  const cxx::FundamentalType *cxxft = cxx::FundamentalType::SafeDownCast(
132  t->GetCxxType().GetType());
133 
134  if (cxxft)
135  {
136  return tid == cxxft->GetId();
137  }
138  }
139 
140  return false;
141 }
142 
143 
144 //----------------------------------------------------------------------------
145 bool IsObject(const cable::Type *t)
146 {
147  return cable::Type::ClassTypeId == t->GetTypeId();
148 }
149 
150 
151 //----------------------------------------------------------------------------
152 bool IsVoid(const cable::Type *t)
153 {
154  return IsFundamental(t, cxx::FundamentalType::Void);
155 }
156 
157 
158 //----------------------------------------------------------------------------
159 bool HasMapToType(const cable::Type *t)
160 {
161  if (IsObject(t))
162  {
163  return HasAttribute(cable::ClassType::SafeDownCast(t)->GetClass(),
164  "gccxml(iwhMapToType");
165  }
166 
167  if ((cable::Type::ReferenceTypeId == t->GetTypeId()) &&
168  IsObject(cable::ReferenceType::SafeDownCast(t)->GetTarget()))
169  {
170  return HasAttribute(cable::ClassType::SafeDownCast(
171  cable::ReferenceType::SafeDownCast(t)->GetTarget())->GetClass(),
172  "gccxml(iwhMapToType");
173  }
174 
175  return false;
176 }
177 
178 
179 //----------------------------------------------------------------------------
180 gxsys_stl::string GetMapToType(const cable::Type *t)
181 {
182  gxsys_stl::string s;
183 
184  if (IsObject(t))
185  {
186  s = ExtractMapToType(cable::ClassType::SafeDownCast(t)->GetClass());
187  }
188  else if ((cable::Type::ReferenceTypeId == t->GetTypeId()) &&
189  IsObject(cable::ReferenceType::SafeDownCast(t)->GetTarget()))
190  {
191  s = ExtractMapToType(cable::ClassType::SafeDownCast(
192  cable::ReferenceType::SafeDownCast(t)->GetTarget())->GetClass());
193  }
194 
195  return s;
196 }
197 
198 
199 //----------------------------------------------------------------------------
200 gxsys_stl::string GetStringMethod(const cable::Type *t)
201 {
202  gxsys_stl::string s;
203 
204  if (IsObject(t))
205  {
206  s = ExtractStringMethod(cable::ClassType::SafeDownCast(t)->GetClass());
207  }
208  else if ((cable::Type::ReferenceTypeId == t->GetTypeId()) &&
209  IsObject(cable::ReferenceType::SafeDownCast(t)->GetTarget()))
210  {
211  s = ExtractStringMethod(cable::ClassType::SafeDownCast(
212  cable::ReferenceType::SafeDownCast(t)->GetTarget())->GetClass());
213  }
214 
215  return s;
216 }
217 
218 
219 //----------------------------------------------------------------------------
220 bool IsCharPointer(const cable::Type *t)
221 {
222  return IsFundamentalPointer(t, cxx::FundamentalType::Char);
223 }
224 
225 
226 //----------------------------------------------------------------------------
227 bool IsCharPointerPointer(const cable::Type *t)
228 {
229  return IsFundamentalPointerPointer(t, cxx::FundamentalType::Char);
230 }
231 
232 
233 //----------------------------------------------------------------------------
234 bool IsFundamentalPointer(const cable::Type *t, cxx::FundamentalType::Id tid)
235 {
236  if (cable::Type::PointerTypeId == t->GetTypeId())
237  {
238  return IsFundamental(cable::PointerType::SafeDownCast(t)->GetTarget(), tid);
239  }
240 
241  return false;
242 }
243 
244 
245 //----------------------------------------------------------------------------
246 bool IsFundamentalPointerPointer(const cable::Type *t, cxx::FundamentalType::Id tid)
247 {
248  if (cable::Type::PointerTypeId == t->GetTypeId())
249  {
250  return IsFundamentalPointer(cable::PointerType::SafeDownCast(t)->GetTarget(), tid);
251  }
252 
253  return false;
254 }
255 
256 
257 //----------------------------------------------------------------------------
258 bool IsObjectPointer(const cable::Type *t)
259 {
260  if (cable::Type::PointerTypeId == t->GetTypeId())
261  {
262  return IsObject(cable::PointerType::SafeDownCast(t)->GetTarget());
263  }
264 
265  return false;
266 }
267 
268 
269 //----------------------------------------------------------------------------
270 bool IsObjectPointerReference(const cable::Type *t)
271 {
272  if (cable::Type::ReferenceTypeId == t->GetTypeId())
273  {
274  return IsObjectPointer(cable::ReferenceType::SafeDownCast(t)->GetTarget());
275  }
276 
277  return false;
278 }
279 
280 
281 //----------------------------------------------------------------------------
282 bool IsVoidPointer(const cable::Type *t)
283 {
284  return IsFundamentalPointer(t, cxx::FundamentalType::Void);
285 }
286 
287 
288 //----------------------------------------------------------------------------
289 const char *GetAccessString(cable::Context::Access access)
290 {
291  if (cable::Context::Public == access)
292  return "public";
293 
294  if (cable::Context::Protected == access)
295  return "protected";
296 
297  if (cable::Context::Private == access)
298  return "private";
299 
300  LogError(me_InvalidArg, << "ERROR_invalid_input_to_GetAccessString");
301  return "ERROR_invalid_input_to_GetAccessString";
302 }
303 
304 
305 //----------------------------------------------------------------------------
306 const cable::Class *GetParentClass(const cable::Class *c)
307 {
308  const cable::Class *parent = 0;
309 
310  if (c)
311  {
312  gxsys_stl::vector<cable::Class *> bases;
313  size_t basecount = 0;
314  gxsys_stl::vector<cable::Class *>::iterator it;
315 
316  c->GetBaseClasses(bases);
317  basecount = bases.size();
318 
319  if (0 == basecount)
320  {
321  }
322  else if (1 == basecount)
323  {
324  parent = *bases.begin();
325  }
326  else
327  {
328  LogError(
330  << "GetParentClass returning 0 because there is more than one base for class '"
331  << c->GetName() << "'"
332  );
333  }
334  }
335 
336  return parent;
337 }
338 
339 
340 //----------------------------------------------------------------------------
341 bool ClassIsA(const cable::Class *c, const gxsys_stl::string& parent)
342 {
343  bool isa = false;
344  const cable::Class *cIt = c;
345 
346  while (!isa && cIt != NULL)
347  {
348  if (GetFullyQualifiedNameForCPlusPlus(cIt) == parent)
349  {
350  isa = true;
351  }
352  else
353  {
354  cIt = GetParentClass(cIt);
355  }
356  }
357 
358  return isa;
359 }
360 
361 
362 //----------------------------------------------------------------------------
363 bool ValidateBaseClasses(const cable::Class *c)
364 {
365  bool validated = false;
366  gxsys_stl::vector<cable::Class *> bases;
367  size_t basecount = 0;
368  gxsys_stl::vector<cable::Class *>::iterator it;
369 
370  c->GetBaseClasses(bases);
371  basecount = bases.size();
372 
373  if (0 == basecount)
374  {
375  validated = true;
376  }
377  else if (1 == basecount)
378  {
379  it = bases.begin();
380  validated = ValidateBaseClasses(*it);
381  }
382  else
383  {
384  LogError(
386  << "ValidateBaseClasses returning false because there is more than one base for class '"
387  << c->GetName() << "'"
388  );
389  }
390 
391  return validated;
392 }
393 
394 
395 //----------------------------------------------------------------------------
396 gxsys_stl::string GetSimpleName(const cable::Named *n)
397 {
398  gxsys_stl::string s;
399 
400  if (n)
401  {
402  s = n->GetName();
403  }
404  else
405  {
406  s = "ERROR_invalid_input_to_GetSimpleName";
407  LogError(me_InvalidArg, << s.c_str());
408  }
409 
410  return s;
411 }
412 
413 
414 //----------------------------------------------------------------------------
415 gxsys_stl::string GetFullyQualifiedName(const cable::Named *n, const char *sep)
416 {
417  gxsys_stl::string s;
418 
419  if (n && sep && n->GetContext())
420  {
421  s = GetFullyQualifiedName(n->GetContext(), sep);
422 
423  // Do not emit a "leading separator" at global scope:
424  //
425  if (s == "::")
426  {
427  s = "";
428  }
429  else
430  {
431  s += sep;
432  }
433 
434  s += n->GetName();
435  }
436  else if (n && sep)
437  {
438  s = n->GetName();
439  }
440  else
441  {
442  s = "ERROR_invalid_input_to_GetFullyQualifiedName";
443  LogError(me_InvalidArg, << s.c_str());
444  }
445 
446  return s;
447 }
448 
449 
450 //----------------------------------------------------------------------------
451 gxsys_stl::string GetFullyQualifiedLengthPrefixedName(const cable::Named *n, const char *sep)
452 {
453  gxsys_stl::string s;
454 
455  if (n && sep && n->GetContext())
456  {
457  s = GetFullyQualifiedLengthPrefixedName(n->GetContext(), sep);
458 
459  // Do not emit a "leading separator" at global scope:
460  //
461  if (s == "::")
462  {
463  s = "";
464  }
465  else
466  {
467  s += sep;
468  }
469 
470  gxsys_ios::ostringstream oss;
471  oss << strlen(n->GetName());
472  s += oss.str();
473 
474  s += n->GetName();
475  }
476  else if (n && sep)
477  {
478  s = n->GetName();
479  }
480  else
481  {
482  s = "ERROR_invalid_input_to_GetFullyQualifiedLengthPrefixedName";
483  LogError(me_InvalidArg, << s.c_str());
484  }
485 
486  return s;
487 }
488 
489 
490 //----------------------------------------------------------------------------
491 gxsys_stl::string GetFullyQualifiedNameForCPlusPlus(const cable::Named *n)
492 {
493  return GetFullyQualifiedName(n, "::");
494 }
495 
496 
497 //----------------------------------------------------------------------------
498 gxsys_stl::string GetFullyQualifiedNameForCSharp(const cable::Named *n)
499 {
500  return GetFullyQualifiedName(n, ".");
501 }
502 
503 
504 //----------------------------------------------------------------------------
505 gxsys_stl::string GetFullyQualifiedCPlusPlusTypeIdName(const cable::Named *n)
506 {
507  gxsys_stl::string s("ERROR_unknown_compiler_in_GetFullyQualifiedCPlusPlusTypeIdName");
508 
509 #if defined(_MSC_VER)
510  s = "class ";
512 #elif defined(__GNUC__)
514 #endif
515 
516  return s;
517 }
518 
519 
520 //----------------------------------------------------------------------------
521 bool EquivalentTypedefNameExists(const cable::Class* c, const cable::FunctionType *target, gxsys_stl::string& s)
522 {
523  s = "";
524 
525  // Look through the typedefs of the target class and return the name of the
526  // first one found that matches the function pointer type inside of 't'...
527 
528  for (cable::Context::Iterator it = c->Begin(); it != c->End() && s == ""; ++it)
529  {
530  cable::Typedef *td = cable::Typedef::SafeDownCast(*it);
531 
532  if (td && (cable::Context::Public == it.GetAccess()))
533  {
534  gxsys_stl::string tname(td->GetName());
535 
536  cable::PointerType *pt = cable::PointerType::SafeDownCast(td->GetType());
537  cable::FunctionType *ft = 0;
538  if (pt)
539  {
540  ft = cable::FunctionType::SafeDownCast(pt->GetTarget());
541  }
542 
543  if (ft && ft == target)
544  {
545  s = tname;
546  }
547  }
548  }
549 
550  return (s != "");
551 }
552 
553 
554 //----------------------------------------------------------------------------
555 bool HasAttribute(const cable::SourceObject *o, const char *attr)
556 {
557  gxsys_stl::string atts(o->GetAttributes());
558  if (atts != "")
559  {
560  if (gxsys_stl::string::npos != atts.find(attr))
561  {
562  return true;
563  }
564  }
565 
566  return false;
567 }
568 
569 
570 //----------------------------------------------------------------------------
571 bool IsUtilityClass(const cable::Class *c)
572 {
573  return HasAttribute(c, "gccxml(iwhUtility)");
574 }
575 
576 
577 //----------------------------------------------------------------------------
578 gxsys_stl::string ExtractAttribute(const gxsys_stl::string& atts, const gxsys_stl::string& attBase)
579 {
580  gxsys_stl::string extracted;
581  bool hasAtt = false;
582 
583  if (gxsys_stl::string::npos != atts.find(gxsys_stl::string("gccxml(") + attBase))
584  {
585  hasAtt = true;
586  }
587 
588  if (hasAtt)
589  {
590  gxsys::RegularExpression re;
591  re.compile((gxsys_stl::string("(gccxml\\(")+attBase+")([^\\)]*)(\\))").c_str());
592  if (re.find(atts.c_str()))
593  {
594  extracted = re.match(2);
595  }
596  }
597 
598  return extracted;
599 }
600 
601 
602 //----------------------------------------------------------------------------
603 gxsys_stl::string ExtractAttribute(const cable::SourceObject *o, const gxsys_stl::string& attBase)
604 {
605  gxsys_stl::string atts(o->GetAttributes());
606  return ExtractAttribute(atts, attBase);
607 }
608 
609 
610 //----------------------------------------------------------------------------
611 gxsys_stl::string ExtractArraySize(const gxsys_stl::string& atts)
612 {
613  return ExtractAttribute(atts, "iwhArraySize");
614 }
615 
616 
617 //----------------------------------------------------------------------------
618 gxsys_stl::string ExtractImplementsInterface(const gxsys_stl::string& atts)
619 {
620  return ExtractAttribute(atts, "iwhImplementsInterface");
621 }
622 
623 
624 //----------------------------------------------------------------------------
625 gxsys_stl::string ExtractMapToType(const cable::SourceObject *o)
626 {
627  return ExtractAttribute(o, "iwhMapToType");
628 }
629 
630 
631 //----------------------------------------------------------------------------
632 gxsys_stl::string ExtractStringMethod(const cable::SourceObject *o)
633 {
634  return ExtractAttribute(o, "iwhStringMethod");
635 }
636 
637 
638 //----------------------------------------------------------------------------
639 gxsys_stl::string GetMappedTypeName(const cable::Class *c, bool fullyQualified)
640 {
641  gxsys_stl::string typeName(ExtractMapToType(c));
642 
643  if (typeName == "string")
644  {
645  typeName = "string";
646  }
647  else
648  {
649  if (fullyQualified)
650  {
651  typeName = GetFullyQualifiedNameForCSharp(c);
652  }
653  else
654  {
655  typeName = GetSimpleName(c);
656  }
657  }
658 
659  return typeName;
660 }
661 
662 
663 //----------------------------------------------------------------------------
664 gxsys_stl::string GetWrappedClassName(const cable::Class *c)
665 {
666  return GetMappedTypeName(c, false);
667 }
668 
669 
670 //----------------------------------------------------------------------------
671 gxsys_stl::string GetWrappedClassNameFullyQualified(const cable::Class *c)
672 {
673  return GetMappedTypeName(c, true);
674 }
675 
676 
677 //----------------------------------------------------------------------------
678 static gxsys_stl::map<int, int> suppressed_msg_values;
679 
680 
681 //----------------------------------------------------------------------------
682 void SuppressMsg(const int n)
683 {
684  suppressed_msg_values[n] = n;
685 }
686 
687 
688 //----------------------------------------------------------------------------
689 bool ShouldLogMsg(const int n)
690 {
691  gxsys_stl::map<int, int>::iterator it = suppressed_msg_values.find(n);
692  return it == suppressed_msg_values.end();
693 }
694 
695 
696 //----------------------------------------------------------------------------
697 static gxsys_stl::vector<int> error_values;
698 
699 
700 //----------------------------------------------------------------------------
701 void LogMsg(const gxsys_stl::string&, const unsigned long, const gxsys_stl::string& label, const int n)
702 {
703  if (label == "error")
704  {
705  if (n)
706  {
707  error_values.push_back(n);
708  }
709  else
710  {
711  gxsys_ios::cerr << "error: 'error' LogMsg n value should be non-zero...";
712  error_values.push_back(me_InternalError);
713  }
714  }
715 }
716 
717 
718 //----------------------------------------------------------------------------
720 {
721  return static_cast<int>(error_values.size());
722 }
723 
724 
725 //----------------------------------------------------------------------------
727 {
728  if (n >= 0 && n < GetErrorCount())
729  {
730  return error_values[n];
731  }
732 
733  return 0;
734 }
735 
736 
737 //----------------------------------------------------------------------------
739 {
740  return GetNthErrorValue(0);
741 }
742 
743 
744 //----------------------------------------------------------------------------
746 {
747  return GetNthErrorValue(GetErrorCount()-1);
748 }
749 
750 
751 //----------------------------------------------------------------------------
752 const cable::Constructor* FindNonAbstractPublicDefaultConstructor(const cable::Class *c)
753 {
754  const cable::Constructor* ctor = 0;
755 
756  if (!c->GetAbstract())
757  {
758  for (cable::Context::Iterator it = c->Begin(); 0 == ctor && it != c->End(); ++it)
759  {
760  cable::Constructor *ctorCandidate = cable::Constructor::SafeDownCast(*it);
761 
762  if (ctorCandidate &&
763  cable::Context::Public == it.GetAccess() &&
764  0 == ctorCandidate->GetFunctionType()->GetNumberOfRequiredArguments())
765  {
766  ctor = ctorCandidate;
767  break;
768  }
769  }
770  }
771 
772  return ctor;
773 }
774 
775 
776 //----------------------------------------------------------------------------
777 gxsys_stl::string GetCPlusPlusZeroInitializerExpression(const cable::Type *t)
778 {
779  gxsys_stl::string s;
780 
781  switch (t->GetTypeId())
782  {
783  case cable::Type::ClassTypeId:
784  s = "memset";
785  break;
786 
787  case cable::Type::EnumerationTypeId:
788  s = "cast";
789  break;
790 
791  case cable::Type::FundamentalTypeId:
792  case cable::Type::PointerTypeId:
793  s = "0";
794  break;
795 
796  default:
797  s = "error: unhandled cable::Type in GetCPlusPlusZeroInitializerExpression";
798  LogError(me_InternalError, << s.c_str());
799  break;
800  }
801 
802  return s;
803 }
804 
805 
806 //----------------------------------------------------------------------------
807 gxsys_stl::string GetCsharpZeroInitializerExpression(const cable::Type *t)
808 {
809  gxsys_stl::string s;
810 
811  switch (t->GetTypeId())
812  {
813  case cable::Type::ClassTypeId:
814  s = "null";
815  break;
816 
817  case cable::Type::EnumerationTypeId:
818  s = "cast";
819  break;
820 
821  case cable::Type::FundamentalTypeId:
822  case cable::Type::PointerTypeId:
823  s = "0";
824  break;
825 
826  default:
827  s = "error: unhandled cable::Type in GetCsharpZeroInitializerExpression";
828  LogError(me_InternalError, << s.c_str());
829  break;
830  }
831 
832  return s;
833 }
834 
835 
836 //----------------------------------------------------------------------------
837 bool BlockContains(const gxsys_stl::vector<gxsys_stl::string>& block, const char *value)
838 {
839  gxsys_stl::vector<gxsys_stl::string>::const_iterator blockIt;
840 
841  for (blockIt = block.begin(); blockIt!=block.end(); ++blockIt)
842  {
843  if (strstr(blockIt->c_str(), value))
844  {
845  return true;
846  }
847  }
848 
849  return false;
850 }
851 
852 
853 //----------------------------------------------------------------------------
854 bool ShouldEmitComment(const char *comment)
855 {
856  gxsys::RegularExpression re;
857  re.compile("//[\\t ]*Description:[\\t ]*");
858  if (re.find(comment))
859  {
860  return false;
861  }
862 
863  return true;
864 }
865 
866 
867 //----------------------------------------------------------------------------
868 gxsys_stl::string EncodeStringForXml(const char *s)
869 {
870  gxsys_stl::string encoded;
871 
872  if (s)
873  {
874  size_t i = 0;
875  size_t n = strlen(s);
876 
877  for (i= 0; i<n; ++i)
878  {
879  switch (s[i])
880  {
881  case '&' : encoded.append("&amp;"); break;
882  case '\'' : encoded.append("&apos;"); break;
883  case '>' : encoded.append("&gt;"); break;
884  case '<' : encoded.append("&lt;"); break;
885  case '"' : encoded.append("&quot;"); break;
886 
887  default : encoded += s[i]; break;
888  }
889  }
890  }
891 
892  return encoded;
893 }
894 
895 
896 // Valid XML doc tags are:
897 //
898 //"c"
899 //"code"
900 //"description"
901 //"example"
902 //"exception "
903 //"include"
904 //"item"
905 //"list"
906 //"listheader"
907 //"para"
908 //"param"
909 //"paramref"
910 //"permission"
911 //"remarks"
912 //"returns"
913 //"see"
914 //"seealso"
915 //"summary"
916 //"term"
917 //"typeparam"
918 //"typeparamref"
919 //"value"
920 
921 
922 //----------------------------------------------------------------------------
923 void EmitDocumentationBlock(gxsys_ios::ostream &os, const gxsys_stl::vector<gxsys_stl::string>& block, const unsigned int indent, bool isClassDoc)
924 {
925  // See also: EmitIndent. If we change indentString here,
926  // we probably will want to change it there also...
927  //
928  gxsys::String indentString = "";
929  for (unsigned int i= 0; i<indent; ++i)
930  {
931  indentString+=" ";
932  }
933 
934  gxsys::String xmlTag = "summary";
935 
936  gxsys_stl::map<gxsys_stl::string, gxsys_stl::string> tagBody;
937 
938  gxsys_stl::vector<gxsys_stl::string>::const_iterator blockIt;
939  gxsys_stl::string line;
940 
941  bool isXmlBlock =
942  (BlockContains(block, "<summary>") && BlockContains(block, "</summary>")) ||
943  (BlockContains(block, "<remarks>") && BlockContains(block, "</remarks>"));
944 
945  gxsys::RegularExpression descRE;
946  descRE.compile(gxsys_stl::string("Description:").c_str());
947  gxsys::RegularExpression nameRE;
948  nameRE.compile(gxsys_stl::string("\\.NAME").c_str());
949  gxsys::RegularExpression seeRE;
950  seeRE.compile(gxsys_stl::string("\\.SECTION[\\t ]+[Ss][Ee][Ee][\\t ]+[Aa][Ll][Ss][Oo]").c_str());
951  gxsys::RegularExpression secRE;
952  secRE.compile(gxsys_stl::string("\\.SECTION").c_str());
953  gxsys::RegularExpression noSpaceRE;
954  noSpaceRE.compile(gxsys_stl::string("[^ ]+").c_str());
955 
956  for (blockIt = block.begin(); blockIt!=block.end(); ++blockIt)
957  {
958  line = *blockIt;
959 
960  if (isClassDoc && !isXmlBlock)
961  {
962  //If it matches a .NAME section add to summary
963  if (nameRE.find(line))
964  {
965  gxsys::SystemTools::ReplaceString(line,nameRE.match(0).c_str(),"");
966  xmlTag = "summary";
967  }
968  //If it matches a .SECTION see also section add to see also
969  else if (seeRE.find(line))
970  {
971  gxsys::SystemTools::ReplaceString(line,seeRE.match(0).c_str(),"");
972  xmlTag = "seealso";
973  }
974  //If it matches a .SECTION * section add to remarks
975  else if (secRE.find(line))
976  {
977  gxsys::SystemTools::ReplaceString(line,secRE.match(0).c_str(),"");
978  xmlTag = "remarks";
979  }
980  //If it matches a Description: section add to summary
981  else if (descRE.find(line))
982  {
983  gxsys::SystemTools::ReplaceString(line,descRE.match(0).c_str(),"");
984  xmlTag = "summary";
985  }
986  }
987 
988  if (ShouldEmitComment(line.c_str()))
989  {
990  if (isXmlBlock)
991  {
992  EmitIndent(os, indent);
993 
994  if (gxsys::SystemTools::StringStartsWith(line.c_str(), "///"))
995  {
996  Emit(os, line.c_str());
997  }
998  else if (gxsys::SystemTools::StringStartsWith(line.c_str(), "//"))
999  {
1000  Emit(os, "/");
1001  Emit(os, line.c_str());
1002  }
1003  else
1004  {
1005  Emit(os, "///");
1006  Emit(os, line.c_str());
1007  }
1008  Emit(os,"\n");
1009  }
1010  else
1011  {
1012  line = EncodeStringForXml(line.c_str());
1013 
1014  //handle code in comments
1015  gxsys::SystemTools::ReplaceString(line,"\\code","<code>");
1016  gxsys::SystemTools::ReplaceString(line,"\\endcode","</code>");
1017 
1018  if (gxsys::SystemTools::StringStartsWith(line.c_str(), "///"))
1019  {
1020  tagBody[xmlTag]+=indentString+line+"\n";
1021  }
1022  else if (gxsys::SystemTools::StringStartsWith(line.c_str(), "//"))
1023  {
1024  tagBody[xmlTag]+=indentString+"/"+line+"\n";
1025  }
1026  else
1027  {
1028  tagBody[xmlTag]+=indentString+"///"+line+"\n";
1029  }
1030  }
1031  }
1032  }
1033 
1034  if(tagBody["summary"] != "")
1035  {
1036  gxsys::String beginTag = indentString+"/// <summary>\n";
1037  gxsys::String endTag = indentString+"/// </summary>\n";
1038  Emit(os,beginTag.c_str());
1039  Emit(os,(tagBody["summary"]).c_str());
1040  Emit(os,endTag.c_str());
1041  }
1042 
1043  if(tagBody["remarks"] != "")
1044  {
1045  gxsys::String beginTag = indentString+"/// <remarks>\n";
1046  gxsys::String endTag = indentString+"/// </remarks>\n";
1047  Emit(os,beginTag.c_str());
1048  Emit(os,(tagBody["remarks"]).c_str());
1049  Emit(os,endTag.c_str());
1050  }
1051 
1052  if(tagBody["seealso"] != "")
1053  {
1054  gxsys::String beginTag = indentString+"/// <seealso>\n";
1055  gxsys::String endTag = indentString+"/// </seealso>\n";
1056  Emit(os, beginTag.c_str());
1057  Emit(os, tagBody["seealso"].c_str());
1058  Emit(os, endTag.c_str());
1059  }
1060 }
1061 
1062 
1063 //----------------------------------------------------------------------------
1064 gxsys_stl::string ExtractDerivedName(const char *s, const cable::Named *n, bool verbose)
1065 {
1066  gxsys_stl::string name;
1067  gxsys_stl::string derivedName;
1068  gxsys_stl::string c1to2;
1069  gxsys_stl::string c1to3;
1070 
1071  if (s)
1072  {
1073  name = s;
1074  }
1075 
1076  if (s && strlen(s)>2)
1077  {
1078  c1to2 = name.substr(0, 2);
1079  }
1080 
1081  if (s && strlen(s)>3)
1082  {
1083  c1to3 = name.substr(0, 3);
1084  }
1085 
1086  if ((c1to3 == "Get") || (c1to3 == "get"))
1087  {
1088  derivedName = name.substr(3);
1089  }
1090  else if ((c1to3 == "Set") || (c1to3 == "set"))
1091  {
1092  derivedName = name.substr(3);
1093  }
1094  else if (c1to2 == "m_")
1095  {
1096  derivedName = name.substr(2);
1097  }
1098  else
1099  {
1100  derivedName = name;
1101 
1102  if (n && verbose)
1103  {
1104  LogFileLineInfoMsg(n->GetFile(), n->GetLine(), mi_VerboseInfo,
1105  "ExtractDerivedName could not extract derivedName from name: "
1106  << name << ". Using name as-is...");
1107  }
1108  }
1109 
1110  return derivedName;
1111 }
bool IsChar(const cable::Type *t)
bool ShouldEmitComment(const char *comment)
bool ShouldLogMsg(const int n)
bool IsCharPointerPointer(const cable::Type *t)
void Emit(gxsys_ios::ostream &os, const char *s)
int GetErrorCount()
bool IsCharPointer(const cable::Type *t)
gxsys_stl::string GetFullyQualifiedLengthPrefixedName(const cable::Named *n, const char *sep)
void EmitIndent(gxsys_ios::ostream &os, const unsigned int n)
gxsys_stl::string GetMapToType(const cable::Type *t)
const cable::Class * GetParentClass(const cable::Class *c)
void EmitUint(gxsys_ios::ostream &os, const unsigned int i)
gxsys_stl::string GetMappedTypeName(const cable::Class *c, bool fullyQualified)
void SuppressMsg(const int n)
bool ClassIsA(const cable::Class *c, const gxsys_stl::string &parent)
gxsys_stl::string GetCsharpZeroInitializerExpression(const cable::Type *t)
bool IsObject(const cable::Type *t)
bool EquivalentTypedefNameExists(const cable::Class *c, const cable::FunctionType *target, gxsys_stl::string &s)
bool IsFundamentalPointerPointer(const cable::Type *t, cxx::FundamentalType::Id tid)
bool HasAttribute(const cable::SourceObject *o, const char *attr)
bool HasMapToType(const cable::Type *t)
gxsys_stl::string GetStringMethod(const cable::Type *t)
bool IsObjectPointerReference(const cable::Type *t)
gxsys_stl::string GetFullyQualifiedNameForCPlusPlus(const cable::Named *n)
gxsys_stl::string GetCPlusPlusZeroInitializerExpression(const cable::Type *t)
gxsys_stl::string GetFullyQualifiedNameForCSharp(const cable::Named *n)
int GetMostRecentErrorValue()
bool BlockContains(const gxsys_stl::vector< gxsys_stl::string > &block, const char *value)
bool IsUtilityClass(const cable::Class *c)
bool IsVoid(const cable::Type *t)
gxsys_stl::string GetFullyQualifiedName(const cable::Named *n, const char *sep)
int GetFirstErrorValue()
bool IsObjectPointer(const cable::Type *t)
const char * GetAccessString(cable::Context::Access access)
void LogMsg(const gxsys_stl::string &, const unsigned long, const gxsys_stl::string &label, const int n)
gxsys_stl::string ExtractMapToType(const cable::SourceObject *o)
static gxsys_stl::map< int, int > suppressed_msg_values
gxsys_stl::string ExtractArraySize(const gxsys_stl::string &atts)
gxsys_stl::string ExtractAttribute(const gxsys_stl::string &atts, const gxsys_stl::string &attBase)
gxsys_stl::string ExtractStringMethod(const cable::SourceObject *o)
gxsys_stl::string GetSimpleName(const cable::Named *n)
int GetNthErrorValue(int n)
gxsys_stl::string GetFullyQualifiedCPlusPlusTypeIdName(const cable::Named *n)
gxsys_stl::string GetWrappedClassName(const cable::Class *c)
gxsys_stl::string ExtractDerivedName(const char *s, const cable::Named *n, bool verbose)
#define LogFileLineInfoMsg(file, line, n, m)
Definition: MummyLog.h:34
void EmitFile(gxsys_ios::ostream &os, const char *filename)
#define LogError(n, m)
Definition: MummyLog.h:41
const cable::Constructor * FindNonAbstractPublicDefaultConstructor(const cable::Class *c)
gxsys_stl::string ExtractImplementsInterface(const gxsys_stl::string &atts)
gxsys_stl::string EncodeStringForXml(const char *s)
void EmitDocumentationBlock(gxsys_ios::ostream &os, const gxsys_stl::vector< gxsys_stl::string > &block, const unsigned int indent, bool isClassDoc)
void WriteToFile(const char *filename, const char *s)
bool IsFundamental(const cable::Type *t, cxx::FundamentalType::Id tid)
bool ValidateBaseClasses(const cable::Class *c)
bool IsFundamentalPointer(const cable::Type *t, cxx::FundamentalType::Id tid)
bool IsVoidPointer(const cable::Type *t)
gxsys_stl::string GetWrappedClassNameFullyQualified(const cable::Class *c)
void Trace(const char *s)
static gxsys_stl::vector< int > error_values
void EmitInt(gxsys_ios::ostream &os, const int i)