main.cxx
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:81k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. /*
  2.  * main.cxx
  3.  *
  4.  * PWLib application source file for asnparser
  5.  *
  6.  * ASN.1 compiler to produce C++ classes.
  7.  *
  8.  * Copyright (c) 1997-1999 Equivalence Pty. Ltd.
  9.  *
  10.  * The contents of this file are subject to the Mozilla Public License
  11.  * Version 1.0 (the "License"); you may not use this file except in
  12.  * compliance with the License. You may obtain a copy of the License at
  13.  * http://www.mozilla.org/MPL/
  14.  *
  15.  * Software distributed under the License is distributed on an "AS IS"
  16.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  17.  * the License for the specific language governing rights and limitations
  18.  * under the License.
  19.  *
  20.  * The Original Code is ASN Parser.
  21.  *
  22.  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
  23.  *
  24.  * Portions of this code were written with the assisance of funding from
  25.  * Vovida Networks, Inc. http://www.vovida.com.
  26.  *
  27.  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
  28.  * All Rights Reserved.
  29.  *
  30.  * Contributor(s): ______________________________________.
  31.  *
  32.  * $Log: main.cxx,v $
  33.  * Revision 1.28  2000/06/26 13:14:46  robertj
  34.  * Nucleus++ port.
  35.  *
  36.  * Revision 1.27  2000/03/21 21:23:23  robertj
  37.  * Added option to rename imported module names, allows include filename matching.
  38.  *
  39.  * Revision 1.26  2000/01/19 12:33:07  robertj
  40.  * Fixed parsing of OID's in IMPORTS section.
  41.  *
  42.  * Revision 1.25  2000/01/19 03:38:12  robertj
  43.  * Fixed support for parsing multiple IMPORTS
  44.  *
  45.  * Revision 1.24  1999/09/18 04:17:40  robertj
  46.  * Added generation of C++ inlines for some  functions.
  47.  * Optimised CreateObject() switch statements, collapsing common cases.
  48.  *
  49.  * Revision 1.23  1999/09/18 02:42:27  craigs
  50.  * Added optimisation to collapse switch arms in CreateObject functions
  51.  *
  52.  * Revision 1.22  1999/09/07 09:56:04  robertj
  53.  * Fixed failure to put "using anmespace" in every generated .cxx file.
  54.  *
  55.  * Revision 1.21  1999/08/28 01:48:55  robertj
  56.  * Fixed anomaly to always include non-optional extensions in encodings.
  57.  *
  58.  * Revision 1.20  1999/08/09 13:02:36  robertj
  59.  * Added ASN compiler #defines for backward support of pre GCC 2.9 compilers.
  60.  * Added ASN compiler #defines to reduce its memory footprint.
  61.  * Added ASN compiler code generation of assignment operators for string classes.
  62.  *
  63.  * Revision 1.19  1999/07/22 06:48:55  robertj
  64.  * Added comparison operation to base ASN classes and compiled ASN code.
  65.  * Added support for ANY type in ASN parser.
  66.  *
  67.  * Revision 1.18  1999/07/06 05:00:26  robertj
  68.  * Incremented release number
  69.  *
  70.  * Revision 1.17  1999/07/01 12:21:46  robertj
  71.  * Changed PASN_Choice cast operators so no longer "break" const-ness of object.
  72.  *
  73.  * Revision 1.16  1999/06/30 08:57:19  robertj
  74.  * Fixed bug in encodeing sequence of constrained primitive type. Constraint not set.
  75.  * Fixed bug in not emitting namespace use clause.
  76.  * Added "normalisation" of separate sequence of <base type> to be single class.
  77.  *
  78.  * Revision 1.15  1999/06/14 13:00:15  robertj
  79.  * Fixed bug in code generation for string constraints.
  80.  *
  81.  * Revision 1.14  1999/06/09 06:58:09  robertj
  82.  * Adjusted heading comments.
  83.  *
  84.  * Revision 1.13  1999/06/09 02:07:49  robertj
  85.  * Fixed backward compatibility of generated template code with G++ 2.7.x
  86.  *
  87.  * Revision 1.12  1999/06/07 01:56:25  robertj
  88.  * Added header comment on license.
  89.  *
  90.  */
  91. #include <ptlib.h>
  92. #include "main.h"
  93. #include "asn_grammar.h"
  94. unsigned lineNumber;
  95. PString  fileName;
  96. unsigned fatals, warnings;
  97. extern FILE * yyin;
  98. extern int yydebug;
  99. extern int LexEcho;
  100. ModuleDefinition * Module;
  101. static const char * UniversalTagClassNames[] = {
  102.   "UniversalTagClass",
  103.   "ApplicationTagClass",
  104.   "ContextSpecificTagClass",
  105.   "PrivateTagClass"
  106. };
  107. static const char * UniversalTagNames[] = {
  108.   NULL,
  109.   "UniversalBoolean",
  110.   "UniversalInteger",
  111.   "UniversalBitString",
  112.   "UniversalOctetString",
  113.   "UniversalNull",
  114.   "UniversalObjectId",
  115.   "UniversalObjectDescriptor",
  116.   "UniversalExternalType",
  117.   "UniversalReal",
  118.   "UniversalEnumeration",
  119.   "UniversalEmbeddedPDV",
  120.   NULL,
  121.   NULL,
  122.   NULL,
  123.   NULL,
  124.   "UniversalSequence",
  125.   "UniversalSet",
  126.   "UniversalNumericString",
  127.   "UniversalPrintableString",
  128.   "UniversalTeletexString",
  129.   "UniversalVideotexString",
  130.   "UniversalIA5String",
  131.   "UniversalUTCTime",
  132.   "UniversalGeneralisedTime",
  133.   "UniversalGraphicString",
  134.   "UniversalVisibleString",
  135.   "UniversalGeneralString",
  136.   "UniversalUniversalString",
  137.   NULL,
  138.   "UniversalBMPString"
  139. };
  140. static const char * const StandardClasses[] = {
  141.   "PASN_Null",
  142.   "PASN_Boolean",
  143.   "PASN_Integer",
  144.   "PASN_Enumeration",
  145.   "PASN_Real",
  146.   "PASN_ObjectId",
  147.   "PASN_BitString",
  148.   "PASN_OctetString",
  149.   "PASN_NumericString",
  150.   "PASN_PrintableString",
  151.   "PASN_VisibleString",
  152.   "PASN_IA5String",
  153.   "PASN_GeneralString",
  154.   "PASN_BMPString",
  155.   "PASN_Sequence"
  156. };
  157. /////////////////////////////////////////
  158. //
  159. //  yyerror
  160. //  required function for flex
  161. //
  162. void yyerror(char * str)
  163. {
  164.   extern char * yytext;
  165.   PError << StdError(Fatal) << str << " near token "" << yytext <<""n";
  166. }
  167. ostream & operator<<(ostream & out, const StdError & e)
  168. {
  169.   out << fileName << '(' << lineNumber << ") : ";
  170.   if (e.e == Fatal) {
  171.     fatals++;
  172.     out << "error";
  173.   }
  174.   else {
  175.     warnings++;
  176.     out << "warning";
  177.   }
  178.   return out << ": ";
  179. }
  180. /////////////////////////////////////////////////////////
  181. //
  182. //  Utility
  183. //
  184. static PString MakeIdentifierC(const PString & identifier)
  185. {
  186.   PString s = identifier;
  187.   s.Replace("-", "_", TRUE);
  188.   return s;
  189. }
  190. class OutputFile : public PTextFile
  191. {
  192.     PCLASSINFO(OutputFile, PTextFile);
  193.   public:
  194.     ~OutputFile() { Close(); }
  195.     BOOL Open(const PFilePath & path, const PString & suffix, const char * extension);
  196.     BOOL Close();
  197. };
  198. BOOL OutputFile::Open(const PFilePath & path,
  199.                       const PString & suffix,
  200.                       const char * extension)
  201. {
  202.   PFilePath fn = path.GetDirectory() + path.GetTitle() + suffix;
  203.   fn.SetType(extension);
  204.   if (PTextFile::Open(fn, WriteOnly))
  205.     *this << "//n"
  206.              "// " << GetFilePath().GetFileName() << "n"
  207.              "//n"
  208.              "// Code automatically generated by asnparse.n"
  209.              "//n"
  210.              "n";
  211.   else
  212.     PError << PProcess::Current().GetName() << ": cannot create "" 
  213.          << GetFilePath() << "" :" << GetErrorText() << endl;
  214.   return IsOpen();
  215. }
  216. BOOL OutputFile::Close()
  217. {
  218.   if (IsOpen())
  219.     *this << "n"
  220.              "// End of " << GetFilePath().GetFileName() << 'n';
  221.   return PTextFile::Close();
  222. }
  223. /////////////////////////////////////////////////////////
  224. //
  225. //  Application
  226. //
  227. class App : public PProcess
  228. {
  229.     PCLASSINFO(App, PProcess);
  230.   public:
  231.     App();
  232.     void Main();
  233. };
  234. PCREATE_PROCESS(App);
  235. App::App()
  236.   : PProcess("Equivalence", "ASNParse", 1, 3, BetaCode, 3)
  237. {
  238. }
  239. void App::Main()
  240. {
  241.   PArgList & args = GetArguments();
  242.   args.Parse("v-verbose."
  243.              "e-echo."
  244.              "d-debug."
  245.              "c-c++."
  246.              "n-namespace."
  247.              "i-inlines."
  248.              "s-split;"
  249.              "o-output:"
  250.              "m-module:"
  251.              "r-rename:");
  252.   unsigned numFiles = 1;
  253.   if (args.HasOption('s')) {
  254.     PString numFilesStr = args.GetOptionString('s');
  255.     if (numFilesStr.IsEmpty())
  256.       numFiles = 2;
  257.     else
  258.       numFiles = numFilesStr.AsUnsigned();
  259.   }
  260.   if (args.GetCount() < 1 || args.GetCount() > 1 || numFiles == 0) {
  261.     PError << "usage: asnparse [options] asnfilen"
  262.               "  -v --verbose        Verbose output (multiple times for more verbose)n"
  263.               "  -e --echo           Echo input filen"
  264.               "  -d --debug          Debug output (copious!)n"
  265.               "  -c --c++            Generate C++ filesn"
  266.               "  -n --namespace      Use C++ namespacen"
  267.               "  -i --inlines        Use C++ inlinesn"
  268.               "  -s[n] --split[n]    Split output into n (default 2) filesn"
  269.               "  -o --output file    Output filename/directoryn"
  270.               "  -m --module name    Module name prefix/namespacen"
  271.               "  -r --rename from=to Rename import modulen"
  272.            << endl;
  273.     return;
  274.   }
  275.   PTextFile prcFile;
  276.   if (!prcFile.Open(args[0], PFile::ReadOnly)) {
  277.     PError << GetName() << ": cannot open "" 
  278.          << prcFile.GetFilePath() << "" :" << prcFile.GetErrorText() << endl;
  279.     return;
  280.   }
  281.   cout << GetName() << " version " << GetVersion(TRUE)
  282.        << " for " << GetOSClass() << ' ' << GetOSName()
  283.        << " by " << GetManufacturer() << endl;
  284.   if (args.HasOption('d'))
  285.     yydebug = 1;
  286.   if (args.HasOption('e'))
  287.     LexEcho = TRUE;
  288.   fileName   = prcFile.GetFilePath();
  289.   lineNumber = 1;
  290.   fatals     = 0;
  291.   warnings   = 0;
  292.   if (args.HasOption('v'))
  293.     cout << "Parsing..." << endl;
  294.   yyin = _fdopen(prcFile.GetHandle(), "r");
  295.   PAssertNULL(yyin);
  296.   yyparse();
  297.   if (Module != NULL) {
  298.     if (args.GetOptionCount('v') > 1)
  299.       PError << "Module " << *Module << endl;
  300.     if (args.HasOption('c'))
  301.       Module->GenerateCplusplus(args.GetOptionString('o', args[0]),
  302.                                 args.GetOptionString('m'),
  303.                                 numFiles,
  304.                                 args.HasOption('n'),
  305.                                 args.HasOption('i'),
  306.                                 args.HasOption('v'));
  307.   }
  308. }
  309. /////////////////////////////////////////
  310. //
  311. //  miscellaneous
  312. //
  313. class indent
  314. {
  315.   public:
  316.     indent() { }
  317.     friend ostream & operator<<(ostream & s, const indent &)
  318.     { return s << setw(Module->GetIndentLevel()*3) << ' '; }
  319. };
  320. /////////////////////////////////////////
  321. //
  322. //  intermediate structures from parser
  323. //
  324. NamedNumber::NamedNumber(PString * nam)
  325.   : name(*nam)
  326. {
  327.   delete nam;
  328.   number = 0;
  329.   autonumber = TRUE;
  330. }
  331. NamedNumber::NamedNumber(PString * nam, int num)
  332.   : name(*nam)
  333. {
  334.   delete nam;
  335.   number = num;
  336.   autonumber = FALSE;
  337. }
  338. NamedNumber::NamedNumber(PString * nam, const PString & ref)
  339.   : name(*nam), reference(ref)
  340. {
  341.   delete nam;
  342.   number = 0;
  343.   autonumber = FALSE;
  344. }
  345. void NamedNumber::PrintOn(ostream & strm) const
  346. {
  347.   strm << name << " (";
  348.   if (reference.IsEmpty())
  349.     strm << number;
  350.   else
  351.     strm << reference;
  352.   strm << ')';
  353. }
  354. void NamedNumber::SetAutoNumber(const NamedNumber & prev)
  355. {
  356.   if (autonumber) {
  357.     number = prev.number + 1;
  358.     autonumber = FALSE;
  359.   }
  360. }
  361. /////////////////////////////////////////////////////////
  362. Tag::Tag(unsigned tagNum)
  363. {
  364.   type = Universal;
  365.   number = tagNum;
  366.   mode = Module->GetDefaultTagMode();
  367. }
  368. const char * Tag::classNames[] = {
  369.   "UNIVERSAL", "APPLICATION", "CONTEXTSPECIFIC", "PRIVATE"
  370. };
  371. const char * Tag::modeNames[] = {
  372.   "IMPLICIT", "EXPLICIT", "AUTOMATIC"
  373. };
  374. void Tag::PrintOn(ostream & strm) const
  375. {
  376.   if (type != Universal || number != IllegalUniversalTag) {
  377.     strm << '[';
  378.     if (type != ContextSpecific)
  379.       strm << classNames[type] << ' ';
  380.     strm << number << "] " << modeNames[mode] << ' ';
  381.   }
  382. }
  383. /////////////////////////////////////////////////////////
  384. Constraint::Constraint(ConstraintElementBase * elmt)
  385. {
  386.   standard.Append(elmt);
  387.   extendable = FALSE;
  388. }
  389. Constraint::Constraint(ConstraintElementList * stnd, BOOL extend, ConstraintElementList * ext)
  390. {
  391.   if (stnd != NULL) {
  392.     standard = *stnd;
  393.     delete stnd;
  394.   }
  395.   extendable = extend;
  396.   if (ext != NULL) {
  397.     extensions = *ext;
  398.     delete ext;
  399.   }
  400. }
  401. void Constraint::PrintOn(ostream & strm) const
  402. {
  403.   strm << '(';
  404.   for (PINDEX i = 0; i < standard.GetSize(); i++)
  405.     strm << standard[i];
  406.   if (extendable) {
  407.     strm << indent();
  408.     if (standard.GetSize() > 0)
  409.       strm << ", ";
  410.     strm << "..., ";
  411.     for (PINDEX i = 0; i < extensions.GetSize(); i++)
  412.       strm << extensions[i];
  413.   }
  414.   strm << ')';
  415. }
  416. void Constraint::GenerateCplusplus(const PString & fn, ostream & hdr, ostream & cxx)
  417. {
  418.   switch (standard.GetSize()) {
  419.     case 0 :
  420.       return;
  421.     case 1 :
  422.       break;
  423.     default :
  424.       PError << StdError(Warning) << "unsupported UNION constraints, ignored." << endl;
  425.   }
  426.   if (extensions.GetSize() > 0)
  427.     PError << StdError(Warning) << "unsupported extension constraints, ignored." << endl;
  428.   PString fn2 = fn;
  429.   if (fn.Find("PASN_Object::") == P_MAX_INDEX) {
  430.     if (extendable)
  431.       fn2 += "PASN_Object::ExtendableConstraint";
  432.     else
  433.       fn2 += "PASN_Object::FixedConstraint";
  434.   }
  435.   standard[0].GenerateCplusplus(fn2, hdr, cxx);
  436. }
  437. BOOL Constraint::ReferencesType(const TypeBase & type)
  438. {
  439.   PINDEX i;
  440.   for (i = 0; i < standard.GetSize(); i++) {
  441.     if (standard[i].ReferencesType(type))
  442.       return TRUE;
  443.   }
  444.   for (i = 0; i < extensions.GetSize(); i++) {
  445.     if (extensions[i].ReferencesType(type))
  446.       return TRUE;
  447.   }
  448.   return FALSE;
  449. }
  450. /////////////////////////////////////////////////////////
  451. ConstraintElementBase::ConstraintElementBase()
  452. {
  453.   exclusions = NULL;
  454. }
  455. void ConstraintElementBase::GenerateCplusplus(const PString &, ostream &, ostream &)
  456. {
  457.   PError << StdError(Warning) << "unsupported constraint, ignored." << endl;
  458. }
  459. BOOL ConstraintElementBase::ReferencesType(const TypeBase &)
  460. {
  461.   return FALSE;
  462. }
  463. /////////////////////////////////////////////////////////
  464. ConstrainAllConstraintElement::ConstrainAllConstraintElement(ConstraintElementBase * excl)
  465. {
  466.   SetExclusions(excl);
  467. }
  468. /////////////////////////////////////////////////////////
  469. ElementListConstraintElement::ElementListConstraintElement(ConstraintElementList * list)
  470.   : elements(*list)
  471. {
  472.   delete list;
  473. }
  474. void ElementListConstraintElement::PrintOn(ostream & strm) const
  475. {
  476.   elements.PrintOn(strm);
  477. }
  478. void ElementListConstraintElement::GenerateCplusplus(const PString & fn, ostream & hdr, ostream & cxx)
  479. {
  480.   for (PINDEX i = 0; i < elements.GetSize(); i++)
  481.     elements[i].GenerateCplusplus(fn, hdr, cxx);
  482. }
  483. BOOL ElementListConstraintElement::ReferencesType(const TypeBase & type)
  484. {
  485.   for (PINDEX i = 0; i < elements.GetSize(); i++) {
  486.     if (elements[i].ReferencesType(type))
  487.       return TRUE;
  488.   }
  489.   return FALSE;
  490. }
  491. /////////////////////////////////////////////////////////
  492. SingleValueConstraintElement::SingleValueConstraintElement(ValueBase * val)
  493. {
  494.   value = val;
  495. }
  496. SingleValueConstraintElement::~SingleValueConstraintElement()
  497. {
  498.   delete value;
  499. }
  500. void SingleValueConstraintElement::PrintOn(ostream & strm) const
  501. {
  502.   strm << *value;
  503. }
  504. void SingleValueConstraintElement::GenerateCplusplus(const PString & fn, ostream & hdr, ostream & cxx)
  505. {
  506.   if (value->IsDescendant(IntegerValue::Class())) {
  507.     cxx << fn << ", ";
  508.     value->GenerateCplusplus(hdr, cxx);
  509.     cxx << ", ";
  510.     value->GenerateCplusplus(hdr, cxx);
  511.     cxx << ");n";
  512.     return;
  513.   }
  514.   if (value->IsDescendant(CharacterStringValue::Class())) {
  515.     cxx << fn << ", ";
  516.     value->GenerateCplusplus(hdr, cxx);
  517.     cxx << ");n";
  518.     return;
  519.   }
  520.   PError << StdError(Warning) << "Unsupported constraint type, ignoring." << endl;
  521. }
  522. /////////////////////////////////////////////////////////
  523. ValueRangeConstraintElement::ValueRangeConstraintElement(ValueBase * lowerBound, ValueBase * upperBound)
  524. {
  525.   lower = lowerBound;
  526.   upper = upperBound;
  527. }
  528. ValueRangeConstraintElement::~ValueRangeConstraintElement()
  529. {
  530.   delete lower;
  531.   delete upper;
  532. }
  533. void ValueRangeConstraintElement::PrintOn(ostream & strm) const
  534. {
  535.   strm << *lower << ".." << *upper;
  536. }
  537. void ValueRangeConstraintElement::GenerateCplusplus(const PString & fn, ostream & hdr, ostream & cxx)
  538. {
  539.   cxx << fn << ", ";
  540.   lower->GenerateCplusplus(hdr, cxx);
  541.   cxx << ", ";
  542.   upper->GenerateCplusplus(hdr, cxx);
  543.   cxx << ");n";
  544. }
  545. /////////////////////////////////////////////////////////
  546. SubTypeConstraintElement::SubTypeConstraintElement(TypeBase * typ)
  547. {
  548.   subtype = typ;
  549. }
  550. SubTypeConstraintElement::~SubTypeConstraintElement()
  551. {
  552.   delete subtype;
  553. }
  554. void SubTypeConstraintElement::PrintOn(ostream & strm) const
  555. {
  556.   strm << subtype->GetTypeName();
  557. }
  558. void SubTypeConstraintElement::GenerateCplusplus(const PString &, ostream & hdr, ostream &)
  559. {
  560.   hdr << subtype->GetTypeName();
  561. }
  562. BOOL SubTypeConstraintElement::ReferencesType(const TypeBase & type)
  563. {
  564.   return subtype->ReferencesType(type);
  565. }
  566. /////////////////////////////////////////////////////////
  567. NestedConstraintConstraintElement::NestedConstraintConstraintElement(Constraint * con)
  568. {
  569.   constraint = con;
  570. }
  571. NestedConstraintConstraintElement::~NestedConstraintConstraintElement()
  572. {
  573.   delete constraint;
  574. }
  575. BOOL NestedConstraintConstraintElement::ReferencesType(const TypeBase & type)
  576. {
  577.   if (constraint == NULL)
  578.     return FALSE;
  579.   return constraint->ReferencesType(type);
  580. }
  581. /////////////////////////////////////////////////////////
  582. SizeConstraintElement::SizeConstraintElement(Constraint * constraint)
  583.   : NestedConstraintConstraintElement(constraint)
  584. {
  585. }
  586. void SizeConstraintElement::PrintOn(ostream & strm) const
  587. {
  588.   strm << "SIZE" << *constraint;
  589. }
  590. void SizeConstraintElement::GenerateCplusplus(const PString & fn, ostream & hdr, ostream & cxx)
  591. {
  592.   constraint->GenerateCplusplus(fn, hdr, cxx);
  593. }
  594. /////////////////////////////////////////////////////////
  595. FromConstraintElement::FromConstraintElement(Constraint * constraint)
  596.   : NestedConstraintConstraintElement(constraint)
  597. {
  598. }
  599. void FromConstraintElement::PrintOn(ostream & strm) const
  600. {
  601.   strm << "FROM" << *constraint;
  602. }
  603. void FromConstraintElement::GenerateCplusplus(const PString & fn, ostream & hdr, ostream & cxx)
  604. {
  605.   PString newfn = fn;
  606.   newfn.Replace("SetConstraints(", "SetCharacterSet(");
  607.   constraint->GenerateCplusplus(newfn, hdr, cxx);
  608. }
  609. /////////////////////////////////////////////////////////
  610. WithComponentConstraintElement::WithComponentConstraintElement(PString * newName,
  611.                                                                Constraint * constraint,
  612.                                                                int pres)
  613.   : NestedConstraintConstraintElement(constraint)
  614. {
  615.   if (newName != NULL) {
  616.     name = *newName;
  617.     delete newName;
  618.   }
  619.   presence = pres;
  620. }
  621. void WithComponentConstraintElement::PrintOn(ostream & strm) const
  622. {
  623.   if (name.IsEmpty())
  624.     strm << "WITH COMPONENT";
  625.   else
  626.     strm << name;
  627.   if (constraint != NULL)
  628.     strm << *constraint;
  629.   switch (presence) {
  630.     case Present :
  631.       strm << " PRESENT";
  632.       break;
  633.     case Absent :
  634.       strm << " ABSENT";
  635.       break;
  636.     case Optional :
  637.       strm << " OPTIONAL";
  638.       break;
  639.   }
  640. }
  641. void WithComponentConstraintElement::GenerateCplusplus(const PString &, ostream &, ostream & cxx)
  642. {
  643.   if (presence == Present)
  644.     cxx << "  IncludeOptionalField(e_" << name << ");n";
  645. }
  646. /////////////////////////////////////////////////////////
  647. InnerTypeConstraintElement::InnerTypeConstraintElement(ConstraintElementList * list,
  648.                                                        BOOL part)
  649.   : ElementListConstraintElement(list)
  650. {
  651.   partial = part;
  652. }
  653. void InnerTypeConstraintElement::PrintOn(ostream & strm) const
  654. {
  655.   strm << "WITH COMPONENTS { ";
  656.   if (partial)
  657.     strm << "..., ";
  658.   for (PINDEX i = 0; i < elements.GetSize(); i++) {
  659.     if (i > 0)
  660.       strm << ", ";
  661.     elements[i].PrintOn(strm);
  662.   }
  663.   strm << " }";
  664. }
  665. void InnerTypeConstraintElement::GenerateCplusplus(const PString & fn, ostream & hdr, ostream & cxx)
  666. {
  667.   for (PINDEX i = 0; i < elements.GetSize(); i++)
  668.     elements[i].GenerateCplusplus(fn, hdr, cxx);
  669. }
  670. /////////////////////////////////////////////////////////
  671. UserDefinedConstraintElement::UserDefinedConstraintElement(TypesList * t)
  672. {
  673.   if (t != NULL) {
  674.     types = *t;
  675.     delete t;
  676.   }
  677. }
  678. void UserDefinedConstraintElement::PrintOn(ostream & strm) const
  679. {
  680.   strm << "CONSTRAINED BY { ";
  681.   for (PINDEX i = 0; i < types.GetSize(); i++) {
  682.     if (i > 0)
  683.       strm << ", ";
  684.     strm << types[i].GetTypeName();
  685.   }
  686.   strm << " }";
  687. }
  688. void UserDefinedConstraintElement::GenerateCplusplus(const PString &, ostream &, ostream &)
  689. {
  690. }
  691. /////////////////////////////////////////////////////////
  692. TypeBase::TypeBase(unsigned tagNum)
  693.   : tag(tagNum), defaultTag(tagNum)
  694. {
  695.   isOptional = FALSE;
  696.   defaultValue = NULL;
  697.   isGenerated = FALSE;
  698. }
  699. TypeBase::TypeBase(TypeBase * copy)
  700.   : name(copy->name),
  701.     identifier(MakeIdentifierC(name)),
  702.     tag(copy->tag),
  703.     defaultTag(copy->tag)
  704. {
  705.   isOptional = copy->isOptional;
  706.   defaultValue = NULL;
  707.   isGenerated = FALSE;
  708. }
  709. PObject::Comparison TypeBase::Compare(const PObject & obj) const
  710. {
  711.   return name.Compare(((const TypeBase &)obj).name);
  712. }
  713. void TypeBase::PrintOn(ostream & strm) const
  714. {
  715.   PrintStart(strm);
  716.   PrintFinish(strm);
  717. }
  718. void TypeBase::PrintStart(ostream & strm) const
  719. {
  720.   strm << indent();
  721.   if (!name) {
  722.     strm << name;
  723.     if (!parameters.IsEmpty()) {
  724.       strm << " { ";
  725.       for (PINDEX i = 0; i < parameters.GetSize(); i++) {
  726.         if (i > 0)
  727.           strm << ", ";
  728.         strm << parameters[i];
  729.       }
  730.       strm << " } ";
  731.     }
  732.     strm << ": ";
  733.   }
  734.   strm << tag << GetClass() << ' ';
  735.   Module->SetIndentLevel(1);
  736. }
  737. void TypeBase::PrintFinish(ostream & strm) const
  738. {
  739.   Module->SetIndentLevel(-1);
  740.   strm << ' ' << constraints;
  741.   if (isOptional)
  742.     strm << " OPTIONAL";
  743.   if (defaultValue != NULL)
  744.     strm << " DEFAULT " << *defaultValue;
  745.   strm << 'n';
  746. }
  747. int TypeBase::GetIdentifierTokenContext() const
  748. {
  749.   return IDENTIFIER;
  750. }
  751. int TypeBase::GetBraceTokenContext() const
  752. {
  753.   return '{';
  754. }
  755. void TypeBase::SetName(PString * newName)
  756. {
  757.   name = *newName;
  758.   delete newName;
  759.   identifier = MakeIdentifierC(name);
  760. }
  761. void TypeBase::AdjustIdentifier()
  762. {
  763.   identifier = Module->GetPrefix() + MakeIdentifierC(name);
  764. }
  765. void TypeBase::SetTag(Tag::Type type, unsigned num, Tag::Mode mode)
  766. {
  767.   tag.type = type;
  768.   tag.number = num;
  769.   tag.mode = mode;
  770. }
  771. void TypeBase::SetParameters(PStringList * list)
  772. {
  773.   parameters = *list;
  774.   delete list;
  775. }
  776. void TypeBase::MoveConstraints(TypeBase * from)
  777. {
  778.   from->constraints.DisallowDeleteObjects();
  779.   while (!from->constraints.IsEmpty())
  780.     constraints.Append(from->constraints.RemoveAt(0));
  781.   from->constraints.AllowDeleteObjects();
  782. }
  783. void TypeBase::FlattenUsedTypes()
  784. {
  785. }
  786. TypeBase * TypeBase::FlattenThisType(const TypeBase &)
  787. {
  788.   return this;
  789. }
  790. BOOL TypeBase::IsChoice() const
  791. {
  792.   return FALSE;
  793. }
  794. BOOL TypeBase::IsParameterizedType() const
  795. {
  796.   return FALSE;
  797. }
  798. BOOL TypeBase::IsPrimitiveType() const
  799. {
  800.   return TRUE;
  801. }
  802. void TypeBase::GenerateCplusplus(ostream & hdr, ostream & cxx)
  803. {
  804.   BeginGenerateCplusplus(hdr, cxx);
  805.   // Close off the constructor implementation
  806.   cxx << ")n"
  807.          "{n";
  808.   GenerateCplusplusConstraints(PString(), hdr, cxx);
  809.   EndGenerateCplusplus(hdr, cxx);
  810. }
  811. void TypeBase::GenerateForwardDecls(ostream &)
  812. {
  813. }
  814. void TypeBase::GenerateOperators(ostream &, ostream &, const TypeBase &)
  815. {
  816. }
  817. PString TypeBase::GetTypeName() const
  818. {
  819.   return GetAncestorClass();
  820. }
  821. BOOL TypeBase::CanReferenceType() const
  822. {
  823.   return FALSE;
  824. }
  825. BOOL TypeBase::ReferencesType(const TypeBase &)
  826. {
  827.   return FALSE;
  828. }
  829. void TypeBase::SetImportPrefix(const PString &)
  830. {
  831. }
  832. BOOL TypeBase::IsParameterisedImport() const
  833. {
  834.   return FALSE;
  835. }
  836. void TypeBase::BeginGenerateCplusplus(ostream & hdr, ostream & cxx)
  837. {
  838.   classNameString = GetIdentifier();
  839.   if (!parameters.IsEmpty()) {
  840.     templatePrefix = "template <";
  841.     classNameString += '<';
  842.     for (PINDEX i = 0; i < parameters.GetSize(); i++) {
  843.       if (i > 0) {
  844.         templatePrefix += ", ";
  845.         classNameString += ", ";
  846.       }
  847.       PString ident = MakeIdentifierC(parameters[i]);
  848.       templatePrefix += "class " + ident;
  849.       classNameString += ident;
  850.     }
  851.     templatePrefix += ">n";
  852.     classNameString += '>';
  853.   }
  854.   // Output header file declaration of class
  855.   hdr << "//n"
  856.          "// " << GetName() << "n"
  857.          "//n"
  858.          "n";
  859.   GenerateForwardDecls(hdr);
  860.   hdr << templatePrefix
  861.       << "class " << GetIdentifier() << " : public " << GetTypeName() << "n"
  862.          "{n"
  863.          "#ifndef PASN_LEANANDMEANn"
  864.          "    PCLASSINFO(" << GetIdentifier() << ", " << GetTypeName() << ");n"
  865.          "#endifn"
  866.          "  public:n"
  867.          "    " << GetIdentifier() << "(unsigned tag = ";
  868.   if (tag.type == Tag::Universal &&
  869.       tag.number < PARRAYSIZE(UniversalTagNames) &&
  870.       UniversalTagNames[tag.number] != NULL)
  871.     hdr << UniversalTagNames[tag.number];
  872.   else
  873.     hdr << tag.number;
  874.   hdr << ", TagClass tagClass = " << UniversalTagClassNames[tag.type] << ");nn";
  875.   // Output cxx file implementation of class
  876.   cxx << "//n"
  877.          "// " << GetName() << "n"
  878.          "//n"
  879.          "n"
  880.       << GetTemplatePrefix()
  881.       << GetClassNameString() << "::" << GetIdentifier() << "(unsigned tag, PASN_Object::TagClass tagClass)n"
  882.          "  : " << GetTypeName() << "(tag, tagClass";
  883. }
  884. void TypeBase::EndGenerateCplusplus(ostream & hdr, ostream & cxx)
  885. {
  886.   cxx << "}n"
  887.          "n"
  888.          "n";
  889.   GenerateOperators(hdr, cxx, *this);
  890.   // Output header file declaration of class
  891.   hdr << "    PObject * Clone() const;n"
  892.          "};n"
  893.          "n"
  894.          "n";
  895.   // Output cxx file implementation of class
  896.   cxx << GetTemplatePrefix()
  897.       << "PObject * " << GetClassNameString() << "::Clone() constn"
  898.          "{n"
  899.          "#ifndef PASN_LEANANDMEANn"
  900.          "  PAssert(IsClass(" << GetClassNameString() << "::Class()), PInvalidCast);n"
  901.          "#endifn"
  902.          "  return new " << GetClassNameString() << "(*this);n"
  903.          "}n"
  904.          "n"
  905.          "n";
  906.   isGenerated = TRUE;
  907. }
  908. void TypeBase::GenerateCplusplusConstructor(ostream &, ostream & cxx)
  909. {
  910.   cxx << '(';
  911.   if (HasNonStandardTag()) {
  912.     if (tag.type == Tag::Universal &&
  913.         tag.number < PARRAYSIZE(UniversalTagNames) &&
  914.         UniversalTagNames[tag.number] != NULL)
  915.       cxx << UniversalTagNames[tag.number];
  916.     else
  917.       cxx << tag.number;
  918.     cxx << ", " << UniversalTagClassNames[tag.type];
  919.   }
  920.   cxx << ')';
  921. }
  922. void TypeBase::GenerateCplusplusConstraints(const PString & prefix, ostream & hdr, ostream & cxx)
  923. {
  924.   for (PINDEX i = 0; i < constraints.GetSize(); i++)
  925.     constraints[i].GenerateCplusplus("  " + prefix + "SetConstraints(", hdr, cxx);
  926. }
  927. /////////////////////////////////////////////////////////
  928. DefinedType::DefinedType(PString * name, BOOL parameter)
  929.   : TypeBase(Tag::IllegalUniversalTag),
  930.     referenceName(*name)
  931. {
  932.   delete name;
  933.   baseType = NULL;
  934.   unresolved = !parameter;
  935. }
  936. DefinedType::DefinedType(TypeBase * refType, TypeBase * bType)
  937.   : TypeBase(refType),
  938.     referenceName(bType->GetName())
  939. {
  940.   MoveConstraints(refType);
  941.   baseType = bType;
  942.   unresolved = FALSE;
  943. }
  944. DefinedType::DefinedType(TypeBase * refType, const PString & refName)
  945.   : TypeBase(refType)
  946. {
  947.   MoveConstraints(refType);
  948.   ConstructFromType(refType, refName);
  949. }
  950. DefinedType::DefinedType(TypeBase * refType, const TypeBase & parent)
  951.   : TypeBase(refType)
  952. {
  953.   if (!name)
  954.     ConstructFromType(refType, parent.GetName() + '_' + name);
  955.   else
  956.     ConstructFromType(refType, parent.GetName() + "_subtype");
  957. }
  958. void DefinedType::ConstructFromType(TypeBase * refType, const PString & name)
  959. {
  960.   referenceName = name;
  961.   refType->SetName(new PString(name));
  962.   Module->AppendType(refType);
  963.   baseType = refType;
  964.   unresolved = FALSE;
  965. }
  966. void DefinedType::PrintOn(ostream & strm) const
  967. {
  968.   PrintStart(strm);
  969.   strm << referenceName << ' ';
  970.   PrintFinish(strm);
  971. }
  972. BOOL DefinedType::CanReferenceType() const
  973. {
  974.   return TRUE;
  975. }
  976. BOOL DefinedType::IsChoice() const
  977. {
  978.   if (baseType != NULL)
  979.     return baseType->IsChoice();
  980.   return FALSE;
  981. }
  982. BOOL DefinedType::IsParameterizedType() const
  983. {
  984.   if (baseType != NULL)
  985.     return baseType->IsParameterizedType();
  986.   return FALSE;
  987. }
  988. BOOL DefinedType::ReferencesType(const TypeBase & type)
  989. {
  990.   if (unresolved) {
  991.     unresolved = FALSE;
  992.     if ((baseType = Module->FindType(referenceName)) == NULL)
  993.       PError << StdError(Warning) << "unresolved symbol: " << referenceName << endl;
  994.     else {
  995.       if (!HasNonStandardTag())
  996.         defaultTag = tag = baseType->GetTag();
  997.     }
  998.   }
  999.   return type.GetName() == referenceName;
  1000. }
  1001. void DefinedType::GenerateOperators(ostream & hdr, ostream & cxx, const TypeBase & actualType)
  1002. {
  1003.   if (baseType != NULL)
  1004.     baseType->GenerateOperators(hdr, cxx, actualType);
  1005. }
  1006. const char * DefinedType::GetAncestorClass() const
  1007. {
  1008.   if (baseType != NULL)
  1009.     return baseType->GetAncestorClass();
  1010.   return NULL;
  1011. }
  1012. PString DefinedType::GetTypeName() const
  1013. {
  1014.   if (baseType == NULL)
  1015.     return referenceName;
  1016.   if (HasConstraints() && baseType->IsPrimitiveType())
  1017.     return baseType->GetTypeName();
  1018.   return baseType->GetIdentifier();
  1019. }
  1020. /////////////////////////////////////////////////////////
  1021. ParameterizedType::ParameterizedType(PString * name, TypesList * args)
  1022.   : DefinedType(name, FALSE),
  1023.     arguments(*args)
  1024. {
  1025.   delete args;
  1026. }
  1027. void ParameterizedType::PrintOn(ostream & strm) const
  1028. {
  1029.   PrintStart(strm);
  1030.   strm << referenceName << " { ";
  1031.   for (PINDEX i = 0; i < arguments.GetSize(); i++) {
  1032.     if (i > 0)
  1033.       strm << ", ";
  1034.     strm << arguments[i].GetTypeName();
  1035.   }
  1036.   strm << " }";
  1037.   PrintFinish(strm);
  1038. }
  1039. BOOL ParameterizedType::IsParameterizedType() const
  1040. {
  1041.   return TRUE;
  1042. }
  1043. BOOL ParameterizedType::ReferencesType(const TypeBase & type)
  1044. {
  1045.   for (PINDEX i = 0; i < arguments.GetSize(); i++) {
  1046.     if (arguments[i].ReferencesType(type))
  1047.       return TRUE;
  1048.   }
  1049.   return DefinedType::ReferencesType(type);
  1050. }
  1051. PString ParameterizedType::GetTypeName() const
  1052. {
  1053.   PString typeName = DefinedType::GetTypeName();
  1054.   if (!arguments.IsEmpty()) {
  1055.     typeName += '<';
  1056.     for (PINDEX i = 0; i < arguments.GetSize(); i++) {
  1057.       if (i > 0)
  1058.         typeName += ", ";
  1059.       typeName += arguments[i].GetTypeName();
  1060.     }
  1061.     typeName += '>';
  1062.   }
  1063.   return typeName;
  1064. }
  1065. /////////////////////////////////////////////////////////
  1066. SelectionType::SelectionType(PString * name, TypeBase * base)
  1067.   : TypeBase(Tag::IllegalUniversalTag),
  1068.     selection(*name)
  1069. {
  1070.   delete name;
  1071.   baseType = PAssertNULL(base);
  1072. }
  1073. SelectionType::~SelectionType()
  1074. {
  1075.   delete baseType;
  1076. }
  1077. void SelectionType::PrintOn(ostream & strm) const
  1078. {
  1079.   PrintStart(strm);
  1080.   strm << selection << '<' << *baseType;
  1081.   PrintFinish(strm);
  1082. }
  1083. void SelectionType::FlattenUsedTypes()
  1084. {
  1085.   baseType = baseType->FlattenThisType(*this);
  1086. }
  1087. TypeBase * SelectionType::FlattenThisType(const TypeBase & parent)
  1088. {
  1089.   return new DefinedType(this, parent);
  1090. }
  1091. void SelectionType::GenerateCplusplus(ostream &, ostream &)
  1092. {
  1093.   PError << StdError(Fatal) << "Cannot generate code for Selection type" << endl;
  1094.   isGenerated = TRUE;
  1095. }
  1096. const char * SelectionType::GetAncestorClass() const
  1097. {
  1098.   return "";
  1099. }
  1100. BOOL SelectionType::CanReferenceType() const
  1101. {
  1102.   return TRUE;
  1103. }
  1104. BOOL SelectionType::ReferencesType(const TypeBase & type)
  1105. {
  1106.   return baseType->ReferencesType(type);
  1107. }
  1108. /////////////////////////////////////////////////////////
  1109. BooleanType::BooleanType()
  1110.   : TypeBase(Tag::UniversalBoolean)
  1111. {
  1112. }
  1113. void BooleanType::GenerateOperators(ostream & hdr, ostream & cxx, const TypeBase & actualType)
  1114. {
  1115.   hdr << "    " << actualType.GetIdentifier() << " & operator=(BOOL v)";
  1116.   if (Module->UsingInlines())
  1117.     hdr << " { SetValue(v);  return *this; }n";
  1118.   else {
  1119.     hdr << ";n";
  1120.     cxx << actualType.GetTemplatePrefix()
  1121.         << actualType.GetIdentifier() << " & "
  1122.         << actualType.GetClassNameString() << "::operator=(BOOL v)n"
  1123.            "{n"
  1124.            "  SetValue(v);n"
  1125.            "  return *this;n"
  1126.            "}n"
  1127.            "n"
  1128.            "n";
  1129.   }
  1130. }
  1131. const char * BooleanType::GetAncestorClass() const
  1132. {
  1133.   return "PASN_Boolean";
  1134. }
  1135. /////////////////////////////////////////////////////////
  1136. IntegerType::IntegerType()
  1137.   : TypeBase(Tag::UniversalInteger)
  1138. {
  1139. }
  1140. IntegerType::IntegerType(NamedNumberList * lst)
  1141.   : TypeBase(Tag::UniversalInteger),
  1142.     allowedValues(*lst)
  1143. {
  1144.   delete lst;
  1145. }
  1146. void IntegerType::GenerateOperators(ostream & hdr, ostream & cxx, const TypeBase & actualType)
  1147. {
  1148.   hdr << "    " << actualType.GetIdentifier() << " & operator=(int v)";
  1149.   if (Module->UsingInlines())
  1150.     hdr << " { SetValue(v);  return *this; }n";
  1151.   else {
  1152.     hdr << ";n";
  1153.     cxx << actualType.GetTemplatePrefix()
  1154.         << actualType.GetIdentifier() << " & "
  1155.         << actualType.GetClassNameString() << "::operator=(int v)n"
  1156.            "{n"
  1157.            "  SetValue(v);n"
  1158.            "  return *this;n"
  1159.            "}n"
  1160.            "n"
  1161.            "n";
  1162.   }
  1163.   hdr << "    " << actualType.GetIdentifier() << " & operator=(unsigned v)";
  1164.   if (Module->UsingInlines())
  1165.     hdr << " { SetValue(v);  return *this; }n";
  1166.   else {
  1167.     hdr << ";n";
  1168.     cxx  << actualType.GetTemplatePrefix()
  1169.         << actualType.GetIdentifier() << " & "
  1170.         << actualType.GetClassNameString() << "::operator=(unsigned v)n"
  1171.            "{n"
  1172.            "  SetValue(v);n"
  1173.            "  return *this;n"
  1174.            "}n"
  1175.            "n"
  1176.            "n";
  1177.   }
  1178. }
  1179. const char * IntegerType::GetAncestorClass() const
  1180. {
  1181.   return "PASN_Integer";
  1182. }
  1183. /////////////////////////////////////////////////////////
  1184. EnumeratedType::EnumeratedType(NamedNumberList * enums, BOOL extend, NamedNumberList * ext)
  1185.   : TypeBase(Tag::UniversalEnumeration),
  1186.     enumerations(*enums)
  1187. {
  1188.   numEnums = enums->GetSize();
  1189.   delete enums;
  1190.   extendable = extend;
  1191.   if (ext != NULL) {
  1192.     ext->DisallowDeleteObjects();
  1193.     for (PINDEX i = 0; i < ext->GetSize(); i++)
  1194.       enumerations.Append(ext->GetAt(i));
  1195.     delete ext;
  1196.   }
  1197. }
  1198. void EnumeratedType::PrintOn(ostream & strm) const
  1199. {
  1200.   PrintStart(strm);
  1201.   strm << 'n';
  1202.   PINDEX i;
  1203.   for (i = 0; i < numEnums; i++)
  1204.     strm << indent() << enumerations[i] << 'n';
  1205.   if (extendable) {
  1206.     strm << "...n";
  1207.     for (; i < enumerations.GetSize(); i++)
  1208.       strm << indent() << enumerations[i] << 'n';
  1209.   }
  1210.   PrintFinish(strm);
  1211. }
  1212. TypeBase * EnumeratedType::FlattenThisType(const TypeBase & parent)
  1213. {
  1214.   return new DefinedType(this, parent);
  1215. }
  1216. void EnumeratedType::GenerateCplusplus(ostream & hdr, ostream & cxx)
  1217. {
  1218.   PINDEX i;
  1219.   BeginGenerateCplusplus(hdr, cxx);
  1220.   int maxEnumValue = 0;
  1221.   for (i = 0; i < enumerations.GetSize(); i++) {
  1222.     int num = enumerations[i].GetNumber();
  1223.     if (maxEnumValue < num)
  1224.       maxEnumValue = num;
  1225.   }
  1226.   // Generate enumerations and complete the constructor implementation
  1227.   hdr << "    enum Enumerations {n";
  1228.   cxx << ", " << maxEnumValue << ", " << (extendable ? "TRUE" : "FALSE") << "n"
  1229.          "#ifndef PASN_NOPRINTONn"
  1230.          "      , "";
  1231.   int prevNum = -1;
  1232.   for (i = 0; i < enumerations.GetSize(); i++) {
  1233.     if (i > 0) {
  1234.       hdr << ",n";
  1235.       cxx << "        "";
  1236.     }
  1237.     hdr << "      e_" << MakeIdentifierC(enumerations[i].GetName());
  1238.     cxx << enumerations[i].GetName();
  1239.     int num = enumerations[i].GetNumber();
  1240.     if (num != prevNum+1) {
  1241.       hdr << " = " << num;
  1242.       cxx << '=' << num;
  1243.     }
  1244.     prevNum = num;
  1245.     cxx << " "n";
  1246.   }
  1247.   hdr << "n"
  1248.          "    };n"
  1249.          "n";
  1250.   cxx << "#endifn"
  1251.          "    )n"
  1252.          "{n";
  1253.   GenerateCplusplusConstraints(PString(), hdr, cxx);
  1254.   EndGenerateCplusplus(hdr, cxx);
  1255. }
  1256. void EnumeratedType::GenerateOperators(ostream & hdr, ostream & cxx, const TypeBase & actualType)
  1257. {
  1258.   hdr << "    " << actualType.GetIdentifier() << " & operator=(unsigned v)";
  1259.   if (Module->UsingInlines())
  1260.     hdr << " { SetValue(v);  return *this; }n";
  1261.   else {
  1262.     hdr << ";n";
  1263.     cxx << actualType.GetTemplatePrefix()
  1264.         << actualType.GetIdentifier() << " & "
  1265.         << actualType.GetClassNameString() << "::operator=(unsigned v)n"
  1266.            "{n"
  1267.            "  SetValue(v);n"
  1268.            "  return *this;n"
  1269.            "}n"
  1270.            "n"
  1271.            "n";
  1272.   }
  1273. }
  1274. const char * EnumeratedType::GetAncestorClass() const
  1275. {
  1276.   return "PASN_Enumeration";
  1277. }
  1278. /////////////////////////////////////////////////////////
  1279. RealType::RealType()
  1280.   : TypeBase(Tag::UniversalReal)
  1281. {
  1282. }
  1283. const char * RealType::GetAncestorClass() const
  1284. {
  1285.   return "PASN_Real";
  1286. }
  1287. /////////////////////////////////////////////////////////
  1288. BitStringType::BitStringType()
  1289.   : TypeBase(Tag::UniversalBitString)
  1290. {
  1291. }
  1292. BitStringType::BitStringType(NamedNumberList * lst)
  1293.   : TypeBase(Tag::UniversalBitString),
  1294.     allowedBits(*lst)
  1295. {
  1296.   delete lst;
  1297. }
  1298. int BitStringType::GetIdentifierTokenContext() const
  1299. {
  1300.   return OID_IDENTIFIER;
  1301. }
  1302. int BitStringType::GetBraceTokenContext() const
  1303. {
  1304.   return BITSTRING_BRACE;
  1305. }
  1306. const char * BitStringType::GetAncestorClass() const
  1307. {
  1308.   return "PASN_BitString";
  1309. }
  1310. /////////////////////////////////////////////////////////
  1311. OctetStringType::OctetStringType()
  1312.   : TypeBase(Tag::UniversalOctetString)
  1313. {
  1314. }
  1315. void OctetStringType::GenerateOperators(ostream & hdr, ostream & cxx, const TypeBase & actualType)
  1316. {
  1317.   hdr << "    " << actualType.GetIdentifier() << " & operator=(const char * v)";
  1318.   if (Module->UsingInlines())
  1319.     hdr << " { SetValue(v);  return *this; }n";
  1320.   else {
  1321.     hdr << ";n";
  1322.     cxx << actualType.GetTemplatePrefix()
  1323.         << actualType.GetIdentifier() << " & "
  1324.         << actualType.GetClassNameString() << "::operator=(const char * v)n"
  1325.            "{n"
  1326.            "  SetValue(v);n"
  1327.            "  return *this;n"
  1328.            "}n"
  1329.            "n"
  1330.            "n";
  1331.   }
  1332.   hdr << "    " << actualType.GetIdentifier() << " & operator=(const PString & v)";
  1333.   if (Module->UsingInlines())
  1334.     hdr << " { SetValue(v);  return *this; }n";
  1335.   else {
  1336.     hdr << ";n";
  1337.     cxx << actualType.GetTemplatePrefix()
  1338.         << actualType.GetIdentifier() << " & "
  1339.         << actualType.GetClassNameString() << "::operator=(const PString & v)n"
  1340.            "{n"
  1341.            "  SetValue(v);n"
  1342.            "  return *this;n"
  1343.            "}n"
  1344.            "n"
  1345.            "n";
  1346.   }
  1347.   hdr << "    " << actualType.GetIdentifier() << " & operator=(const PBYTEArray & v)";
  1348.   if (Module->UsingInlines())
  1349.     hdr << " { SetValue(v);  return *this; }n";
  1350.   else {
  1351.     hdr << ";n";
  1352.     cxx << actualType.GetTemplatePrefix()
  1353.         << actualType.GetIdentifier() << " & "
  1354.         << actualType.GetClassNameString() << "::operator=(const PBYTEArray & v)n"
  1355.            "{n"
  1356.            "  SetValue(v);n"
  1357.            "  return *this;n"
  1358.            "}n"
  1359.            "n"
  1360.            "n";
  1361.   }
  1362. }
  1363. const char * OctetStringType::GetAncestorClass() const
  1364. {
  1365.   return "PASN_OctetString";
  1366. }
  1367. /////////////////////////////////////////////////////////
  1368. NullType::NullType()
  1369.   : TypeBase(Tag::UniversalNull)
  1370. {
  1371. }
  1372. const char * NullType::GetAncestorClass() const
  1373. {
  1374.   return "PASN_Null";
  1375. }
  1376. /////////////////////////////////////////////////////////
  1377. SequenceType::SequenceType(TypesList * stnd,
  1378.                            BOOL extend,
  1379.                            TypesList * ext,
  1380.                            unsigned tagNum)
  1381.   : TypeBase(tagNum)
  1382. {
  1383.   if (stnd != NULL) {
  1384.     numFields = stnd->GetSize();
  1385.     fields = *stnd;
  1386.     delete stnd;
  1387.   }
  1388.   else
  1389.     numFields = 0;
  1390.   extendable = extend;
  1391.   if (ext != NULL) {
  1392.     ext->DisallowDeleteObjects();
  1393.     for (PINDEX i = 0; i < ext->GetSize(); i++)
  1394.       fields.Append(ext->GetAt(i));
  1395.     delete ext;
  1396.   }
  1397. }
  1398. void SequenceType::PrintOn(ostream & strm) const
  1399. {
  1400.   PrintStart(strm);
  1401.   strm << 'n';
  1402.   PINDEX i;
  1403.   for (i = 0; i < numFields; i++)
  1404.     strm << fields[i];
  1405.   if (extendable) {
  1406.     strm << indent() << "...n";
  1407.     for (; i < fields.GetSize(); i++)
  1408.       strm << fields[i];
  1409.   }
  1410.   PrintFinish(strm);
  1411. }
  1412. void SequenceType::FlattenUsedTypes()
  1413. {
  1414.   for (PINDEX i = 0; i < fields.GetSize(); i++)
  1415.     fields.SetAt(i, fields[i].FlattenThisType(*this));
  1416. }
  1417. TypeBase * SequenceType::FlattenThisType(const TypeBase & parent)
  1418. {
  1419.   return new DefinedType(this, parent);
  1420. }
  1421. BOOL SequenceType::IsPrimitiveType() const
  1422. {
  1423.   return FALSE;
  1424. }
  1425. void SequenceType::GenerateCplusplus(ostream & hdr, ostream & cxx)
  1426. {
  1427.   PINDEX i;
  1428.   BeginGenerateCplusplus(hdr, cxx);
  1429.   PINDEX baseOptions = 0;
  1430.   for (i = 0; i < fields.GetSize(); i++) {
  1431.     if (i < numFields && fields[i].IsOptional())
  1432.       baseOptions++;
  1433.   }
  1434.   // Complete ancestor constructor parameters
  1435.   cxx << ", " << baseOptions << ", "
  1436.       << (extendable ? "TRUE" : "FALSE") << ", "
  1437.       << fields.GetSize() - numFields
  1438.       << ')';
  1439.   // Output enum for optional parameters
  1440.   BOOL outputEnum = FALSE;
  1441.   for (i = 0; i < fields.GetSize(); i++) {
  1442.     if (i >= numFields || fields[i].IsOptional()) {
  1443.       if (outputEnum)
  1444.         hdr << ",n";
  1445.       else {
  1446.         hdr << "    enum OptionalFields {n";
  1447.         outputEnum = TRUE;
  1448.       }
  1449.       hdr << "      e_" << fields[i].GetIdentifier();
  1450.     }
  1451.   }
  1452.   if (outputEnum)
  1453.     hdr << "n"
  1454.            "    };n"
  1455.            "n";
  1456.   // Output the declarations and constructors for member variables
  1457.   for (i = 0; i < fields.GetSize(); i++) {
  1458.     PString varname = "m_" + fields[i].GetIdentifier();
  1459.     hdr << "    " << fields[i].GetTypeName() << ' ' << varname << ";n";
  1460.     if (fields[i].HasNonStandardTag()) {
  1461.       cxx << ",n"
  1462.              "    " << varname;
  1463.       fields[i].GenerateCplusplusConstructor(hdr, cxx);
  1464.     }
  1465.   }
  1466.   // Output declarations for generated functions
  1467.   hdr << "n"
  1468.          "    PINDEX GetDataLength() const;n"
  1469.          "    BOOL Decode(PASN_Stream & strm);n"
  1470.          "    void Encode(PASN_Stream & strm) const;n"
  1471.          "#ifndef PASN_NOPRINTONn"
  1472.          "    void PrintOn(ostream & strm) const;n"
  1473.          "#endifn";
  1474.   if (numFields > 0)
  1475.     hdr << "    Comparison Compare(const PObject & obj) const;n";
  1476.   cxx << "n"
  1477.          "{n";
  1478.   GenerateCplusplusConstraints(PString(), hdr, cxx);
  1479.   for (i = 0; i < fields.GetSize(); i++) {
  1480.     PString ident = fields[i].GetIdentifier();
  1481.     fields[i].GenerateCplusplusConstraints("m_" + ident + ".", hdr, cxx);
  1482.     if (i >= numFields && !fields[i].IsOptional())
  1483.       cxx << "  IncludeOptionalField(e_" << ident << ");n";
  1484.   }
  1485.   cxx << "}n"
  1486.          "n"
  1487.          "n"
  1488.          "#ifndef PASN_NOPRINTONn"
  1489.       << GetTemplatePrefix()
  1490.       << "void " << GetClassNameString() << "::PrintOn(ostream & strm) constn"
  1491.          "{n"
  1492.          "  int indent = strm.precision() + 2;n"
  1493.          "  strm << "{\n";n";
  1494.   for (i = 0; i < fields.GetSize(); i++) {
  1495.     PString id = fields[i].GetIdentifier();
  1496.     if (i >= numFields || fields[i].IsOptional())
  1497.       cxx << "  if (HasOptionalField(e_" << id << "))n"
  1498.              "  ";
  1499.     cxx << "  strm << setw(indent+" << id.GetLength()+3 << ") << ""
  1500.         << id << " = " << setprecision(indent) << m_" << id << " << '\n';n";
  1501.   }
  1502.   cxx << "  strm << setw(indent-1) << "}";n"
  1503.          "}n"
  1504.          "#endifn"
  1505.          "n"
  1506.          "n";
  1507.   if (numFields > 0) {
  1508.     cxx << GetTemplatePrefix()
  1509.         << "PObject::Comparison " << GetClassNameString() << "::Compare(const PObject & obj) constn"
  1510.            "{n"
  1511.            "#ifndef PASN_LEANANDMEANn"
  1512.            "  PAssert(IsDescendant(" << GetClassNameString() << "::Class()), PInvalidCast);n"
  1513.            "#endifn"
  1514.            "  const " << GetClassNameString() << " & other = (const " << GetClassNameString() << " &)obj;n"
  1515.            "n"
  1516.            "  Comparison result;n"
  1517.            "n";
  1518.     for (i = 0; i < numFields; i++) {
  1519.       PString identifier = fields[i].GetIdentifier();
  1520.       cxx << "  if ((result = m_" << identifier << ".Compare(other.m_" << identifier << ")) != EqualTo)n"
  1521.              "    return result;n";
  1522.     }
  1523.     cxx << "n"
  1524.            "  return PASN_Sequence::Compare(other);n"
  1525.            "}n"
  1526.            "n"
  1527.            "n";
  1528.   }
  1529.   cxx << GetTemplatePrefix()
  1530.       << "PINDEX " << GetClassNameString() << "::GetDataLength() constn"
  1531.          "{n"
  1532.          "  return ";
  1533.   outputEnum = FALSE;
  1534.   for (i = 0; i < numFields; i++) {
  1535.     if (outputEnum)
  1536.       cxx << " +n"
  1537.              "         ";
  1538.     else
  1539.       outputEnum = TRUE;
  1540.     cxx << "m_" << fields[i].GetIdentifier() << ".GetObjectLength()";
  1541.   }
  1542.   if (!outputEnum)
  1543.     cxx << '0';
  1544.   cxx << ";n"
  1545.          "}n"
  1546.          "n"
  1547.          "n"
  1548.       << GetTemplatePrefix()
  1549.       << "BOOL " << GetClassNameString() << "::Decode(PASN_Stream & strm)n"
  1550.          "{n"
  1551.          "  if (!PreambleDecode(strm))n"
  1552.          "    return FALSE;nn";
  1553.   for (i = 0; i < numFields; i++) {
  1554.     cxx << "  if (";
  1555.     if (fields[i].IsOptional())
  1556.       cxx << "HasOptionalField(e_" << fields[i].GetIdentifier() << ") && ";
  1557.     cxx << "!m_" << fields[i].GetIdentifier() << ".Decode(strm))n"
  1558.            "    return FALSE;n";
  1559.   }
  1560.   for (; i < fields.GetSize(); i++)
  1561.     cxx << "  if (!KnownExtensionDecode(strm, e_"
  1562.         << fields[i].GetIdentifier()
  1563.         << ", m_" << fields[i].GetIdentifier() << "))n"
  1564.            "    return FALSE;n";
  1565.   cxx << "n"
  1566.          "  return UnknownExtensionsDecode(strm);n"
  1567.          "}n"
  1568.          "n"
  1569.          "n"
  1570.       << GetTemplatePrefix()
  1571.       << "void " << GetClassNameString() << "::Encode(PASN_Stream & strm) constn"
  1572.          "{n"
  1573.          "  PreambleEncode(strm);nn";
  1574.   for (i = 0; i < numFields; i++) {
  1575.     if (fields[i].IsOptional())
  1576.       cxx << "  if (HasOptionalField(e_" << fields[i].GetIdentifier() << "))n"
  1577.              "  ";
  1578.     cxx << "  m_" << fields[i].GetIdentifier() << ".Encode(strm);n";
  1579.   }
  1580.   for (; i < fields.GetSize(); i++)
  1581.     cxx << "  KnownExtensionEncode(strm, e_"
  1582.         << fields[i].GetIdentifier()
  1583.         << ", m_" << fields[i].GetIdentifier() << ");n";
  1584.   cxx << "n"
  1585.          "  UnknownExtensionsEncode(strm);n";
  1586.   EndGenerateCplusplus(hdr, cxx);
  1587. }
  1588. const char * SequenceType::GetAncestorClass() const
  1589. {
  1590.   return "PASN_Sequence";
  1591. }
  1592. BOOL SequenceType::CanReferenceType() const
  1593. {
  1594.   return TRUE;
  1595. }
  1596. BOOL SequenceType::ReferencesType(const TypeBase & type)
  1597. {
  1598.   for (PINDEX i = 0; i < fields.GetSize(); i++)
  1599.     if (fields[i].ReferencesType(type))
  1600.       return TRUE;
  1601.   return FALSE;
  1602. }
  1603. /////////////////////////////////////////////////////////
  1604. SequenceOfType::SequenceOfType(TypeBase * base, Constraint * constraint, unsigned tag)
  1605.   : TypeBase(tag)
  1606. {
  1607.   baseType = base;
  1608.   if (constraint != NULL)
  1609.     AddConstraint(constraint);
  1610. }
  1611. SequenceOfType::~SequenceOfType()
  1612. {
  1613.   delete baseType;
  1614. }
  1615. void SequenceOfType::PrintOn(ostream & strm) const
  1616. {
  1617.   PrintStart(strm);
  1618.   if (baseType == NULL)
  1619.     strm << "!!Null Type!!n";
  1620.   else
  1621.     strm << *baseType << 'n';
  1622.   PrintFinish(strm);
  1623. }
  1624. void SequenceOfType::FlattenUsedTypes()
  1625. {
  1626.   baseType = baseType->FlattenThisType(*this);
  1627. }
  1628. TypeBase * SequenceOfType::FlattenThisType(const TypeBase & parent)
  1629. {
  1630.   if (!baseType->IsPrimitiveType() || baseType->HasConstraints())
  1631.     return new DefinedType(this, parent);
  1632.   // Search for an existing sequence of type
  1633.   PString seqName = "ArrayOf_" + baseType->GetTypeName();
  1634.   TypeBase * existingType = Module->FindType(seqName);
  1635.   if (existingType != NULL)
  1636.     return new DefinedType(this, existingType);
  1637.   return new DefinedType(this, seqName);
  1638. }
  1639. BOOL SequenceOfType::IsPrimitiveType() const
  1640. {
  1641.   return FALSE;
  1642. }
  1643. void SequenceOfType::GenerateCplusplus(ostream & hdr, ostream & cxx)
  1644. {
  1645.   BeginGenerateCplusplus(hdr, cxx);
  1646.   cxx << ")n"
  1647.          "{n";
  1648.   GenerateCplusplusConstraints(PString(), hdr, cxx);
  1649.   cxx << "}n"
  1650.          "n"
  1651.          "n";
  1652.   PString baseTypeName = baseType->GetTypeName();
  1653.   // Generate declarations for generated functions
  1654.   hdr << "    PASN_Object * CreateObject() const;n"
  1655.          "    " << baseTypeName << " & operator[](PINDEX i) const";
  1656.   if (Module->UsingInlines())
  1657.     hdr << " { return (" << baseTypeName << " &)array[i]; }n";
  1658.   else
  1659.     hdr << ";n";
  1660.   // Generate implementation for functions
  1661.   cxx << GetTemplatePrefix()
  1662.       << "PASN_Object * " << GetClassNameString() << "::CreateObject() constn"
  1663.          "{n";
  1664.   if (baseType->HasConstraints()) {
  1665.     cxx << "  " << baseTypeName << " * obj = new " << baseTypeName << ";n";
  1666.     baseType->GenerateCplusplusConstraints("obj->", hdr, cxx);
  1667.     cxx << "  return obj;n";
  1668.   }
  1669.   else
  1670.     cxx << "  return new " << baseTypeName << ";n";
  1671.   if (!Module->UsingInlines())
  1672.     cxx << "}n"
  1673.            "n"
  1674.            "n"
  1675.         << GetTemplatePrefix()
  1676.         << baseTypeName << " & " << GetClassNameString() << "::operator[](PINDEX i) constn"
  1677.            "{n"
  1678.            "  return (" << baseTypeName << " &)array[i];n";
  1679.   EndGenerateCplusplus(hdr, cxx);
  1680. }
  1681. void SequenceOfType::GenerateForwardDecls(ostream & hdr)
  1682. {
  1683.   if (baseType->IsParameterizedType())
  1684.     return;
  1685.   PString baseTypeName = baseType->GetTypeName();
  1686.   PStringSet typesOutput(PARRAYSIZE(StandardClasses), StandardClasses);
  1687.   typesOutput += GetIdentifier();
  1688.   if (!typesOutput.Contains(baseTypeName))
  1689.     hdr << "class " << baseTypeName << ";nn";
  1690. }
  1691. const char * SequenceOfType::GetAncestorClass() const
  1692. {
  1693.   return "PASN_Array";
  1694. }
  1695. BOOL SequenceOfType::CanReferenceType() const
  1696. {
  1697.   return TRUE;
  1698. }
  1699. BOOL SequenceOfType::ReferencesType(const TypeBase & type)
  1700. {
  1701.   return baseType->ReferencesType(type) && baseType->IsParameterizedType();
  1702. }
  1703. /////////////////////////////////////////////////////////
  1704. SetType::SetType()
  1705.   : SequenceType(NULL, FALSE, NULL, Tag::UniversalSet)
  1706. {
  1707. }
  1708. SetType::SetType(SequenceType * seq)
  1709.   : SequenceType(*seq)
  1710. {
  1711.   tag.number = Tag::UniversalSet;
  1712. }
  1713. const char * SetType::GetAncestorClass() const
  1714. {
  1715.   return "PASN_Set";
  1716. }
  1717. /////////////////////////////////////////////////////////
  1718. SetOfType::SetOfType(TypeBase * base, Constraint * constraint)
  1719.   : SequenceOfType(base, constraint, Tag::UniversalSet)
  1720. {
  1721. }
  1722. /////////////////////////////////////////////////////////
  1723. ChoiceType::ChoiceType(TypesList * stnd,
  1724.                        BOOL extendable,
  1725.                        TypesList * extensions)
  1726.   : SequenceType(stnd, extendable, extensions, Tag::IllegalUniversalTag)
  1727. {
  1728. }
  1729. void ChoiceType::GenerateCplusplus(ostream & hdr, ostream & cxx)
  1730. {
  1731.   PINDEX i;
  1732.   BeginGenerateCplusplus(hdr, cxx);
  1733.   // Complete the ancestor constructor parameters
  1734.   cxx << ", " << numFields << ", " << (extendable ? "TRUE" : "FALSE");
  1735.   // Generate the enum's for each choice discriminator, and include strings for
  1736.   // PrintOn() debug output into acncestor constructor
  1737.   BOOL outputEnum = FALSE;
  1738.   int prevNum = -1;
  1739.   for (i = 0; i < fields.GetSize(); i++) {
  1740.     const Tag & fieldTag = fields[i].GetTag();
  1741.     if (fieldTag.mode == Tag::Automatic || !fields[i].IsChoice()) {
  1742.       if (outputEnum) {
  1743.         hdr << ",n";
  1744.         cxx << "        "";
  1745.       }
  1746.       else {
  1747.         hdr << "    enum Choices {n";
  1748.         cxx << "n"
  1749.                "#ifndef PASN_NOPRINTONn"
  1750.                "      , "";
  1751.         outputEnum = TRUE;
  1752.       }
  1753.       hdr << "      e_" << fields[i].GetIdentifier();
  1754.       cxx << fields[i].GetIdentifier();
  1755.       if (fieldTag.mode != Tag::Automatic && fieldTag.number != (unsigned)(prevNum+1)) {
  1756.         hdr << " = " << fieldTag.number;
  1757.         cxx << '=' << fieldTag.number;
  1758.       }
  1759.       prevNum = fieldTag.number;
  1760.       cxx << " "n";
  1761.     }
  1762.   }
  1763.   if (outputEnum) {
  1764.     hdr << "n"
  1765.            "    };n"
  1766.            "n";
  1767.     cxx << "#endifn"
  1768.            "    ";
  1769.   }
  1770.   cxx << ")n"
  1771.          "{n";
  1772.   GenerateCplusplusConstraints(PString(), hdr, cxx);
  1773.   cxx << "}n"
  1774.          "n"
  1775.          "n";
  1776.   // Generate code for type safe cast operators of selected choice object
  1777.   BOOL needExtraLine = FALSE;
  1778.   PStringSet typesOutput(PARRAYSIZE(StandardClasses), StandardClasses);
  1779.   typesOutput += GetIdentifier();
  1780.   for (i = 0; i < fields.GetSize(); i++) {
  1781.     PString type = fields[i].GetTypeName();
  1782.     if (!typesOutput.Contains(type)) {
  1783.       if (Module->UsingInlines()) {
  1784.         hdr << "#if defined(__GNUC__) && __GNUC__ <= 2 && __GNUC_MINOR__ < 9n"
  1785.                "    operator " << type << " &() const { return *(" << type << " *)choice; }n"
  1786.                "#elsen"
  1787.                "    operator " << type << " &() { return *(" << type << " *)choice; }n"
  1788.                "    operator const " << type << " &() const { return *(const " << type << " *)choice; }n"
  1789.                "#endifn";
  1790.       }
  1791.       else {
  1792.         hdr << "#if defined(__GNUC__) && __GNUC__ <= 2 && __GNUC_MINOR__ < 9n"
  1793.                "    operator " << type << " &() const;n"
  1794.                "#elsen"
  1795.                "    operator " << type << " &();n"
  1796.                "    operator const " << type << " &() const;n"
  1797.                "#endifn";
  1798.         cxx << "#if defined(__GNUC__) && __GNUC__ <= 2 && __GNUC_MINOR__ < 9n"
  1799.             << GetTemplatePrefix()
  1800.             << GetClassNameString() << "::operator " << type << " &() constn"
  1801.                "#elsen"
  1802.             << GetTemplatePrefix()
  1803.             << GetClassNameString() << "::operator " << type << " &()n"
  1804.                "{n"
  1805.                "#ifndef PASN_LEANANDMEANn"
  1806.                "  PAssert(PAssertNULL(choice)->IsDescendant(" << type << "::Class()), PInvalidCast);n"
  1807.                "#endifn"
  1808.                "  return *(" << type << " *)choice;n"
  1809.                "}n"
  1810.                "n"
  1811.                "n"
  1812.             << GetTemplatePrefix()
  1813.             << GetClassNameString() << "::operator const " << type << " &() constn"
  1814.                "#endifn"
  1815.                "{n"
  1816.                "#ifndef PASN_LEANANDMEANn"
  1817.                "  PAssert(PAssertNULL(choice)->IsDescendant(" << type << "::Class()), PInvalidCast);n"
  1818.                "#endifn"
  1819.                "  return *(" << type << " *)choice;n"
  1820.                "}n"
  1821.                "n"
  1822.                "n";
  1823.       }
  1824.       typesOutput += type;
  1825.       needExtraLine = TRUE;
  1826.     }
  1827.   }
  1828.   if (needExtraLine)
  1829.     hdr << 'n';
  1830.   // Generate virtual function to create chosen object based on discriminator
  1831.   hdr << "    BOOL CreateObject();n";
  1832.   cxx << GetTemplatePrefix()
  1833.       << "BOOL " << GetClassNameString() << "::CreateObject()n"
  1834.          "{n";
  1835.   // declare an array of flags indicating whether the tag has been output or not
  1836.   PBYTEArray flags(fields.GetSize());
  1837.   for (i = 0; i < fields.GetSize(); i++)
  1838.     flags[i] = 0;
  1839.   // keep
  1840.   outputEnum = FALSE;
  1841.   for (i = 0; i < fields.GetSize(); i++) {
  1842.     if (fields[i].GetTag().mode == Tag::Automatic || !fields[i].IsChoice()) {
  1843.       // ignore this tag if output previously
  1844.       if (flags[i] != 0)
  1845.         continue;
  1846.     
  1847.       if (!outputEnum) {
  1848.         cxx << "  switch (tag) {n";
  1849.         outputEnum = TRUE;
  1850.       }
  1851.       // if the field has constraints, then output it alone
  1852.       // otherwise, look for all fields with the same type
  1853.       PString name = fields[i].GetTypeName();
  1854.       if (fields[i].HasConstraints()) {
  1855.         cxx << "    case e_" << fields[i].GetIdentifier() << " :n";
  1856.         flags[i] = 1;
  1857.       } else {
  1858.         PINDEX j;
  1859.         for (j = i; j < fields.GetSize(); j++) {
  1860.           if (fields[j].GetTypeName() == name) {
  1861.             cxx << "    case e_" << fields[j].GetIdentifier() << " :n";
  1862.             flags[j] = 1;
  1863.           }
  1864.         }
  1865.       }
  1866.       cxx << "      choice = new " << name;
  1867.       fields[i].GenerateCplusplusConstructor(hdr, cxx);
  1868.       cxx << ";n";
  1869.       fields[i].GenerateCplusplusConstraints("    choice->", hdr, cxx);
  1870.       cxx << "      return TRUE;n";
  1871.     }
  1872.   }
  1873.   if (outputEnum)
  1874.     cxx << "  }n"
  1875.            "n";
  1876.   for (i = 0; i < fields.GetSize(); i++) {
  1877.     if (fields[i].GetTag().mode != Tag::Automatic && fields[i].IsChoice())
  1878.       cxx << "  choice = new " << fields[i].GetTypeName() << "(tag, tagClass);n"
  1879.              "  if (((PASN_Choice*)choice)->CreateObject())n"
  1880.              "    return TRUE;n"
  1881.              "  delete choice;n"
  1882.              "n";
  1883.   }
  1884.   cxx << "  choice = NULL;n"
  1885.          "  return FALSE;n";
  1886.   EndGenerateCplusplus(hdr, cxx);
  1887. }
  1888. void ChoiceType::GenerateForwardDecls(ostream & hdr)
  1889. {
  1890.   // Output forward declarations for choice pointers, but not standard classes
  1891.   BOOL needExtraLine = FALSE;
  1892.   PStringSet typesOutput(PARRAYSIZE(StandardClasses), StandardClasses);
  1893.   typesOutput += GetIdentifier();
  1894.   for (PINDEX i = 0; i < fields.GetSize(); i++) {
  1895.     PString type = fields[i].GetTypeName();
  1896.     if (!fields[i].IsParameterizedType() && !typesOutput.Contains(type)) {
  1897.       hdr << "class " << type << ";n";
  1898.       needExtraLine = TRUE;
  1899.     }
  1900.   }
  1901.   if (needExtraLine)
  1902.     hdr << 'n';
  1903. }
  1904. BOOL ChoiceType::IsPrimitiveType() const
  1905. {
  1906.   return FALSE;
  1907. }
  1908. BOOL ChoiceType::IsChoice() const
  1909. {
  1910.   return TRUE;
  1911. }
  1912. const char * ChoiceType::GetAncestorClass() const
  1913. {
  1914.   return "PASN_Choice";
  1915. }
  1916. BOOL ChoiceType::ReferencesType(const TypeBase & type)
  1917. {
  1918.   for (PINDEX i = 0; i < fields.GetSize(); i++) {
  1919.     if (fields[i].ReferencesType(type) && fields[i].IsParameterizedType())
  1920.       return TRUE;
  1921.   }
  1922.   return FALSE;
  1923. }
  1924. /////////////////////////////////////////////////////////
  1925. EmbeddedPDVType::EmbeddedPDVType()
  1926.   : TypeBase(Tag::UniversalEmbeddedPDV)
  1927. {
  1928. }
  1929. const char * EmbeddedPDVType::GetAncestorClass() const
  1930. {
  1931.   return "PASN_OctetString";
  1932. }
  1933. /////////////////////////////////////////////////////////
  1934. ExternalType::ExternalType()
  1935.   : TypeBase(Tag::UniversalExternalType)
  1936. {
  1937. }
  1938. const char * ExternalType::GetAncestorClass() const
  1939. {
  1940.   return "PASN_OctetString";
  1941. }
  1942. /////////////////////////////////////////////////////////
  1943. AnyType::AnyType(PString * ident)
  1944.   : TypeBase(Tag::UniversalExternalType)
  1945. {
  1946.   if (ident != NULL) {
  1947.     identifier = *ident;
  1948.     delete ident;
  1949.   }
  1950. }
  1951. void AnyType::PrintOn(ostream & strm) const
  1952. {
  1953.   PrintStart(strm);
  1954.   if (!identifier)
  1955.     strm << "Defined by " << identifier;
  1956.   PrintFinish(strm);
  1957. }
  1958. const char * AnyType::GetAncestorClass() const
  1959. {
  1960.   return "PASN_OctetString";
  1961. }
  1962. /////////////////////////////////////////////////////////
  1963. StringTypeBase::StringTypeBase(int tag)
  1964.   : TypeBase(tag)
  1965. {
  1966. }
  1967. int StringTypeBase::GetBraceTokenContext() const
  1968. {
  1969.   return STRING_BRACE;
  1970. }
  1971. void StringTypeBase::GenerateOperators(ostream & hdr, ostream & cxx, const TypeBase & actualType)
  1972. {
  1973.   hdr << "    " << actualType.GetIdentifier() << " & operator=(const char * v)";
  1974.   if (Module->UsingInlines())
  1975.     hdr << " { SetValue(v);  return *this; }n";
  1976.   else {
  1977.     hdr << ";n";
  1978.     cxx << actualType.GetTemplatePrefix()
  1979.         << actualType.GetIdentifier() << " & "
  1980.         << actualType.GetClassNameString() << "::operator=(const char * v)n"
  1981.            "{n"
  1982.            "  SetValue(v);n"
  1983.            "  return *this;n"
  1984.            "}n"
  1985.            "n"
  1986.            "n";
  1987.   }
  1988.   hdr << "    " << actualType.GetIdentifier() << " & operator=(const PString & v)";
  1989.   if (Module->UsingInlines())
  1990.     hdr << " { SetValue(v);  return *this; }n";
  1991.   else {
  1992.     hdr << ";n";
  1993.     cxx << actualType.GetTemplatePrefix()
  1994.         << actualType.GetIdentifier() << " & "
  1995.         << actualType.GetClassNameString() << "::operator=(const PString & v)n"
  1996.            "{n"
  1997.            "  SetValue(v);n"
  1998.            "  return *this;n"
  1999.            "}n"
  2000.            "n"
  2001.            "n";
  2002.   }
  2003. }
  2004. /////////////////////////////////////////////////////////
  2005. BMPStringType::BMPStringType()
  2006.   : StringTypeBase(Tag::UniversalBMPString)
  2007. {
  2008. }
  2009. const char * BMPStringType::GetAncestorClass() const
  2010. {
  2011.   return "PASN_BMPString";
  2012. }
  2013. /////////////////////////////////////////////////////////
  2014. GeneralStringType::GeneralStringType()
  2015.   : StringTypeBase(Tag::UniversalGeneralString)
  2016. {
  2017. }
  2018. const char * GeneralStringType::GetAncestorClass() const
  2019. {
  2020.   return "PASN_GeneralString";
  2021. }
  2022. /////////////////////////////////////////////////////////
  2023. GraphicStringType::GraphicStringType()
  2024.   : StringTypeBase(Tag::UniversalGraphicString)
  2025. {
  2026. }
  2027. const char * GraphicStringType::GetAncestorClass() const
  2028. {
  2029.   return "PASN_GraphicString";
  2030. }
  2031. /////////////////////////////////////////////////////////
  2032. IA5StringType::IA5StringType()
  2033.   : StringTypeBase(Tag::UniversalIA5String)
  2034. {
  2035. }
  2036. const char * IA5StringType::GetAncestorClass() const
  2037. {
  2038.   return "PASN_IA5String";
  2039. }
  2040. /////////////////////////////////////////////////////////
  2041. ISO646StringType::ISO646StringType()
  2042.   : StringTypeBase(Tag::UniversalVisibleString)
  2043. {
  2044. }
  2045. const char * ISO646StringType::GetAncestorClass() const
  2046. {
  2047.   return "PASN_ISO646String";
  2048. }
  2049. /////////////////////////////////////////////////////////
  2050. NumericStringType::NumericStringType()
  2051.   : StringTypeBase(Tag::UniversalNumericString)
  2052. {
  2053. }
  2054. const char * NumericStringType::GetAncestorClass() const
  2055. {
  2056.   return "PASN_NumericString";
  2057. }
  2058. /////////////////////////////////////////////////////////
  2059. PrintableStringType::PrintableStringType()
  2060.   : StringTypeBase(Tag::UniversalPrintableString)
  2061. {
  2062. }
  2063. const char * PrintableStringType::GetAncestorClass() const
  2064. {
  2065.   return "PASN_PrintableString";
  2066. }
  2067. /////////////////////////////////////////////////////////
  2068. TeletexStringType::TeletexStringType()
  2069.   : StringTypeBase(Tag::UniversalTeletexString)
  2070. {
  2071. }
  2072. const char * TeletexStringType::GetAncestorClass() const
  2073. {
  2074.   return "PASN_TeletexString";
  2075. }
  2076. /////////////////////////////////////////////////////////
  2077. T61StringType::T61StringType()
  2078.   : StringTypeBase(Tag::UniversalTeletexString)
  2079. {
  2080. }
  2081. const char * T61StringType::GetAncestorClass() const
  2082. {
  2083.   return "PASN_T61String";
  2084. }
  2085. /////////////////////////////////////////////////////////
  2086. UniversalStringType::UniversalStringType()
  2087.   : StringTypeBase(Tag::UniversalUniversalString)
  2088. {
  2089. }
  2090. const char * UniversalStringType::GetAncestorClass() const
  2091. {
  2092.   return "PASN_UniversalString";
  2093. }
  2094. /////////////////////////////////////////////////////////
  2095. VideotexStringType::VideotexStringType()
  2096.   : StringTypeBase(Tag::UniversalVideotexString)
  2097. {
  2098. }
  2099. const char * VideotexStringType::GetAncestorClass() const
  2100. {
  2101.   return "PASN_VideotexString";
  2102. }
  2103. /////////////////////////////////////////////////////////
  2104. VisibleStringType::VisibleStringType()
  2105.   : StringTypeBase(Tag::UniversalVisibleString)
  2106. {
  2107. }
  2108. const char * VisibleStringType::GetAncestorClass() const
  2109. {
  2110.   return "PASN_VisibleString";
  2111. }
  2112. /////////////////////////////////////////////////////////
  2113. UnrestrictedCharacterStringType::UnrestrictedCharacterStringType()
  2114.   : StringTypeBase(Tag::UniversalUniversalString)
  2115. {
  2116. }
  2117. const char * UnrestrictedCharacterStringType::GetAncestorClass() const
  2118. {
  2119.   return "PASN_UnrestrictedString";
  2120. }
  2121. /////////////////////////////////////////////////////////
  2122. GeneralizedTimeType::GeneralizedTimeType()
  2123.   : TypeBase(Tag::UniversalGeneralisedTime)
  2124. {
  2125. }
  2126. const char * GeneralizedTimeType::GetAncestorClass() const
  2127. {
  2128.   return "PASN_GeneralizedTime";
  2129. }
  2130. /////////////////////////////////////////////////////////
  2131. UTCTimeType::UTCTimeType()
  2132.   : TypeBase(Tag::UniversalUTCTime)
  2133. {
  2134. }
  2135. const char * UTCTimeType::GetAncestorClass() const
  2136. {
  2137.   return "PASN_UTCTime";
  2138. }
  2139. /////////////////////////////////////////////////////////
  2140. ObjectDescriptorType::ObjectDescriptorType()
  2141.   : TypeBase(Tag::UniversalObjectDescriptor)
  2142. {
  2143. }
  2144. const char * ObjectDescriptorType::GetAncestorClass() const
  2145. {
  2146.   return "PASN_ObectDescriptor";
  2147. }
  2148. /////////////////////////////////////////////////////////
  2149. ObjectIdentifierType::ObjectIdentifierType()
  2150.   : TypeBase(Tag::UniversalObjectId)
  2151. {
  2152. }
  2153. int ObjectIdentifierType::GetIdentifierTokenContext() const
  2154. {
  2155.   return OID_IDENTIFIER;
  2156. }
  2157. int ObjectIdentifierType::GetBraceTokenContext() const
  2158. {
  2159.   return OID_BRACE;
  2160. }
  2161. const char * ObjectIdentifierType::GetAncestorClass() const
  2162. {
  2163.   return "PASN_ObjectId";
  2164. }
  2165. /////////////////////////////////////////////////////////
  2166. ObjectClassFieldType::ObjectClassFieldType(PString * objclass, PString * field)
  2167.   : TypeBase(Tag::IllegalUniversalTag),
  2168.     asnObjectClassName(*objclass),
  2169.     asnObjectClassField(*field)
  2170. {
  2171.   delete objclass;
  2172.   delete field;
  2173. }
  2174. const char * ObjectClassFieldType::GetAncestorClass() const
  2175. {
  2176.   return "";
  2177. }
  2178. void ObjectClassFieldType::PrintOn(ostream & strm) const
  2179. {
  2180.   PrintStart(strm);
  2181.   strm << asnObjectClassName << '.' << asnObjectClassField;
  2182.   PrintFinish(strm);
  2183. }
  2184. void ObjectClassFieldType::GenerateCplusplus(ostream & hdr, ostream & cxx)
  2185. {
  2186.   hdr << "//n"
  2187.          "// " << GetName() << "n"
  2188.          "//n"
  2189.          "n"
  2190.          "typedef ";
  2191.   GenerateCplusplusConstraints(PString(), hdr, cxx);
  2192.   hdr << ' ' << GetIdentifier() << ";n"
  2193.          "n"
  2194.          "n";
  2195. }
  2196. BOOL ObjectClassFieldType::CanReferenceType() const
  2197. {
  2198.   return TRUE;
  2199. }
  2200. BOOL ObjectClassFieldType::ReferencesType(const TypeBase & type)
  2201. {
  2202.   for (PINDEX i = 0; i < constraints.GetSize(); i++) {
  2203.     if (constraints[i].ReferencesType(type))
  2204.       return TRUE;
  2205.   }
  2206.   return FALSE;
  2207. }
  2208. /////////////////////////////////////////////////////////
  2209. ImportedType::ImportedType(PString * theName, BOOL param)
  2210.   : TypeBase(Tag::IllegalUniversalTag)
  2211. {
  2212.   identifier = name = *theName;
  2213.   delete theName;
  2214.   parameterised = param;
  2215. }
  2216. const char * ImportedType::GetAncestorClass() const
  2217. {
  2218.   return identifier;
  2219. }
  2220. void ImportedType::AdjustIdentifier()
  2221. {
  2222.   identifier = modulePrefix + '_' + MakeIdentifierC(name);
  2223. }
  2224. void ImportedType::GenerateCplusplus(ostream &, ostream &)
  2225. {
  2226. }
  2227. void ImportedType::SetImportPrefix(const PString & prefix)
  2228. {
  2229.   modulePrefix = prefix;
  2230. }
  2231. BOOL ImportedType::IsParameterisedImport() const
  2232. {
  2233.   return parameterised;
  2234. }
  2235. /////////////////////////////////////////////////////////
  2236. SearchType::SearchType(const PString & theName)
  2237.   : TypeBase(Tag::IllegalUniversalTag)
  2238. {
  2239.   identifier = name = theName;
  2240. }
  2241. const char * SearchType::GetAncestorClass() const
  2242. {
  2243.   return identifier;
  2244. }
  2245. /////////////////////////////////////////////////////////
  2246. void ValueBase::SetValueName(PString * name)
  2247. {
  2248.   valueName = *name;
  2249.   delete name;
  2250. }
  2251. void ValueBase::PrintBase(ostream & strm) const
  2252. {
  2253.   if (!valueName)
  2254.     strm << 'n' << indent() << valueName << '=';
  2255. }
  2256. void ValueBase::GenerateCplusplus(ostream &, ostream &)
  2257. {
  2258.   PError << StdError(Warning) << "unsupported value type." << endl;
  2259. }
  2260. /////////////////////////////////////////////////////////
  2261. DefinedValue::DefinedValue(PString * name)
  2262.   : referenceName(*name)
  2263. {
  2264.   delete name;
  2265.   actualValue = NULL;
  2266.   unresolved = TRUE;
  2267. }
  2268. void DefinedValue::PrintOn(ostream & strm) const
  2269. {
  2270.   PrintBase(strm);
  2271.   strm << referenceName;
  2272. }
  2273. void DefinedValue::GenerateCplusplus(ostream & hdr, ostream & cxx)
  2274. {
  2275.   if (unresolved) {
  2276.     unresolved = FALSE;
  2277.     const ValuesList & values = Module->GetValues();
  2278.     for (PINDEX i = 0; i < values.GetSize(); i++) {
  2279.       if (values[i].GetName() == referenceName) {
  2280.         actualValue = &values[i];
  2281.         break;
  2282.       }
  2283.     }
  2284.   }
  2285.   if (actualValue != NULL)
  2286.     actualValue->GenerateCplusplus(hdr, cxx);
  2287.   else
  2288.     cxx << referenceName;
  2289. }
  2290. /////////////////////////////////////////////////////////
  2291. BooleanValue::BooleanValue(BOOL newVal)
  2292. {
  2293.   value = newVal;
  2294. }
  2295. void BooleanValue::PrintOn(ostream & strm) const
  2296. {
  2297.   PrintBase(strm);
  2298.   strm << (value ? "TRUE" : "FALSE");
  2299. }
  2300. void BooleanValue::GenerateCplusplus(ostream &, ostream & cxx)
  2301. {
  2302.   cxx << (value ? "TRUE" : "FALSE");
  2303. }
  2304. /////////////////////////////////////////////////////////
  2305. IntegerValue::IntegerValue(PInt64 newVal)
  2306. {
  2307.   value = newVal;
  2308. }
  2309. void IntegerValue::PrintOn(ostream & strm) const
  2310. {
  2311.   PrintBase(strm);
  2312.   
  2313.   strm << value;
  2314. }
  2315. void IntegerValue::GenerateCplusplus(ostream &, ostream & cxx)
  2316. {
  2317.   cxx << value;
  2318.   if (value > INT_MAX)
  2319.     cxx << 'U';
  2320. }
  2321. /////////////////////////////////////////////////////////
  2322. RealValue::RealValue(double newVal)
  2323. {
  2324.   value = newVal;
  2325. }
  2326. /////////////////////////////////////////////////////////
  2327. OctetStringValue::OctetStringValue(PString * newVal)
  2328. {
  2329.   // value = *newVal;
  2330.   delete newVal;
  2331. }
  2332. /////////////////////////////////////////////////////////
  2333. BitStringValue::BitStringValue(PString * newVal)
  2334. {
  2335.   // value = *newVal;
  2336.   delete newVal;
  2337. }
  2338. BitStringValue::BitStringValue(PStringList * newVal)
  2339. {
  2340.   // value = *newVal;
  2341.   delete newVal;
  2342. }
  2343. /////////////////////////////////////////////////////////
  2344. CharacterValue::CharacterValue(BYTE c)
  2345. {
  2346.   value = c;
  2347. }
  2348. CharacterValue::CharacterValue(BYTE t1, BYTE t2)
  2349. {
  2350.   value = (t1<<8) + t2;
  2351. }
  2352. CharacterValue::CharacterValue(BYTE q1, BYTE q2, BYTE q3, BYTE q4)
  2353. {
  2354.   value = (q1<<24) + (q2<<16) + (q3<<8) + q4;
  2355. }
  2356. void CharacterValue::PrintOn(ostream & strm) const
  2357. {
  2358.   strm << "'\x" << hex << value << ''';
  2359. }
  2360. void CharacterValue::GenerateCplusplus(ostream &, ostream & cxx)
  2361. {
  2362.   cxx << value;
  2363. }
  2364. /////////////////////////////////////////////////////////
  2365. CharacterStringValue::CharacterStringValue(PString * newVal)
  2366. {
  2367.   value = *newVal;
  2368.   delete newVal;
  2369. }
  2370. CharacterStringValue::CharacterStringValue(PStringList * newVal)
  2371. {
  2372.   for (PINDEX i = 0; i < newVal->GetSize(); i++)
  2373.     value += (*newVal)[i];
  2374.   delete newVal;
  2375. }
  2376. void CharacterStringValue::PrintOn(ostream & strm) const
  2377. {
  2378.   strm << value;
  2379. }
  2380. void CharacterStringValue::GenerateCplusplus(ostream &, ostream & cxx)
  2381. {
  2382.   cxx << value;
  2383. }
  2384. /////////////////////////////////////////////////////////
  2385. ObjectIdentifierValue::ObjectIdentifierValue(PString * newVal)
  2386. {
  2387.   value.Append(newVal);
  2388. }
  2389. ObjectIdentifierValue::ObjectIdentifierValue(PStringList * newVal)
  2390. {
  2391.   value = *newVal;
  2392.   delete newVal;
  2393. }
  2394. void ObjectIdentifierValue::PrintOn(ostream & strm) const
  2395. {
  2396.   PrintBase(strm);
  2397.   if (value.IsEmpty())
  2398.     strm << "empty object identifier";
  2399.   else {
  2400.     strm << value[0];
  2401.     for (PINDEX i = 1; i < value.GetSize(); i++)
  2402.       strm << '.' << value[i];
  2403.   }
  2404.   strm << 'n';
  2405. }
  2406. /////////////////////////////////////////////////////////
  2407. void MinValue::PrintOn(ostream & strm) const
  2408. {
  2409.   strm << "MIN";
  2410. }
  2411. void MinValue::GenerateCplusplus(ostream &, ostream & cxx)
  2412. {
  2413.   cxx << "MinimumValue";
  2414. }
  2415. /////////////////////////////////////////////////////////
  2416. void MaxValue::PrintOn(ostream & strm) const
  2417. {
  2418.   strm << "MAX";
  2419. }
  2420. void MaxValue::GenerateCplusplus(ostream &, ostream & cxx)
  2421. {
  2422.   cxx << "MaximumValue";
  2423. }
  2424. /////////////////////////////////////////////////////////
  2425. SequenceValue::SequenceValue(ValuesList * list)
  2426. {
  2427.   if (list != NULL) {
  2428.     values = *list;
  2429.     delete list;
  2430.   }
  2431. }
  2432. void SequenceValue::PrintOn(ostream & strm) const
  2433. {
  2434.   strm << "{ ";
  2435.   for (PINDEX i = 0; i < values.GetSize(); i++) {
  2436.     if (i > 0)
  2437.       strm << ", ";
  2438.     strm << values[i];
  2439.   }
  2440.   strm << " }";
  2441. }
  2442. /////////////////////////////////////////////////////////
  2443. MibBase::MibBase(PString * nam,
  2444.                  PString * descr,
  2445.                  PString * refer,
  2446.                  ValueBase * val)
  2447.   : name(*nam)
  2448. {
  2449.   delete nam;
  2450.   if (descr != NULL) {
  2451.     description = *descr;
  2452.     delete descr;
  2453.   }
  2454.   if (refer != NULL) {
  2455.     reference = *refer;
  2456.     delete refer;
  2457.   }
  2458.   value = val;
  2459. }
  2460. MibBase::~MibBase()
  2461. {
  2462.   delete value;
  2463. }
  2464. /////////////////////////////////////////////////////////
  2465. MibObject::MibObject(PString * nam,
  2466.                      TypeBase * typ,
  2467.                      Access acc,
  2468.                      Status stat,
  2469.                      PString * descr,
  2470.                      PString * refer,
  2471.                      PStringList * idx,
  2472.                      ValueBase * defVal,
  2473.                      ValueBase * setVal)
  2474.   : MibBase(nam, descr, refer, setVal)
  2475. {
  2476.   type = typ;
  2477.   access = acc;
  2478.   status = stat;
  2479.   if (idx != NULL) {
  2480.     index = *idx;
  2481.     delete idx;
  2482.   }
  2483.   defaultValue = defVal;
  2484. }
  2485. MibObject::~MibObject()
  2486. {
  2487.   delete type;
  2488.   delete defaultValue;
  2489. }
  2490. void MibObject::PrintOn(ostream & strm) const
  2491. {
  2492.   strm << "  Object: " << name << "n  " << *type
  2493.        << "    " << description << "n"
  2494.           "    " << *value << 'n';
  2495. }
  2496. /////////////////////////////////////////////////////////
  2497. MibTrap::MibTrap(PString * nam, ValueBase * ent, ValuesList * var,
  2498.                  PString * descr, PString * refer, ValueBase * val)
  2499.   : MibBase(nam, descr, refer, val)
  2500. {
  2501.   enterprise = ent;
  2502.   if (var != NULL) {
  2503.     variables = *var;
  2504.     delete var;
  2505.   }
  2506. }
  2507. MibTrap::~MibTrap()
  2508. {
  2509.   delete enterprise;
  2510. }
  2511. void MibTrap::PrintOn(ostream & strm) const
  2512. {
  2513.   strm << "  Trap: " << name << "n  " << *enterprise
  2514.        << "    " << description << "n"
  2515.           "    " << *value << 'n';
  2516. }
  2517. /////////////////////////////////////////////////////////
  2518. ImportModule::ImportModule(PString * name, TypesList * syms)
  2519.   : fullModuleName(*name),
  2520.     shortModuleName(Module->GetImportModuleName(*name))
  2521. {
  2522.   delete name;
  2523.   symbols = *syms;
  2524.   delete syms;
  2525.   for (PINDEX i = 0; i < symbols.GetSize(); i++) {
  2526.     symbols[i].SetImportPrefix(shortModuleName);
  2527.     Module->AppendType(&symbols[i]);
  2528.   }
  2529. }
  2530. void ImportModule::PrintOn(ostream & strm) const
  2531. {
  2532.   strm << "  " << fullModuleName << " (" << shortModuleName << "):n";
  2533.   for (PINDEX i = 0; i < symbols.GetSize(); i++)
  2534.     strm << "    " << symbols[i];
  2535.   strm << 'n';
  2536. }
  2537. void ImportModule::GenerateCplusplus(ostream & hdr, ostream & cxx)
  2538. {
  2539.   PString filename = shortModuleName.ToLower();
  2540.   hdr << "#include "" << filename << ".h"n";
  2541.   for (PINDEX i = 0; i < symbols.GetSize(); i++) {
  2542.     if (symbols[i].IsParameterisedImport()) {
  2543.       cxx << "#include "" << filename << "_t.cxx"n";
  2544.       break;
  2545.     }
  2546.   }
  2547. }
  2548. /////////////////////////////////////////////////////////
  2549. ModuleDefinition::ModuleDefinition(PString * name, PStringList * id, Tag::Mode defTagMode)
  2550.   : moduleName(*name),
  2551.     definitiveId(*id)
  2552. {
  2553.   delete name;
  2554.   delete id;
  2555.   defaultTagMode = defTagMode;
  2556.   exportAll = FALSE;
  2557.   indentLevel = 1;
  2558.   PArgList & args = PProcess::Current().GetArguments();
  2559.   if (args.HasOption('r')) {
  2560.     PStringArray renames = args.GetOptionString('r').Lines();
  2561.     for (PINDEX i = 0; i < renames.GetSize(); i++) {
  2562.       PINDEX equal = renames[i].Find('=');
  2563.       if (equal > 0 && equal != P_MAX_INDEX)
  2564.         importNames.SetAt(renames[i].Left(equal).Trim(), renames[i].Mid(equal+1).Trim());
  2565.     }
  2566.   }
  2567. }
  2568. void ModuleDefinition::SetExportAll()
  2569. {
  2570.   exportAll = TRUE;
  2571. }
  2572. void ModuleDefinition::SetExports(TypesList * syms)
  2573. {
  2574.   exports = *syms;
  2575.   delete syms;
  2576. }
  2577. void ModuleDefinition::PrintOn(ostream & strm) const
  2578. {
  2579.   strm << moduleName << "n"
  2580.           "Default Tags: " << Tag::modeNames[defaultTagMode] << "n"
  2581.           "Exports:";
  2582.   if (exportAll)
  2583.     strm << " ALL";
  2584.   else {
  2585.     strm << "n  ";
  2586.     for (PINDEX i = 0; i < exports.GetSize(); i++)
  2587.       strm << exports[i] << ' ';
  2588.     strm << 'n';
  2589.   }
  2590.   strm << "Imports:n" << imports << "n"
  2591.           "Types:n" << types << "n"
  2592.           "Values:n" << values << "n"
  2593.           "MIBs:n" << mibs << endl;
  2594. }
  2595. void ModuleDefinition::AppendType(TypeBase * type)
  2596. {
  2597.   types.Append(type);
  2598.   sortedTypes.Append(type);
  2599. }
  2600. TypeBase * ModuleDefinition::FindType(const PString & name)
  2601. {
  2602.   PINDEX pos = sortedTypes.GetValuesIndex(SearchType(name));
  2603.   if (pos != P_MAX_INDEX)
  2604.     return &sortedTypes[pos];
  2605.   return NULL;
  2606. }
  2607. PString ModuleDefinition::GetImportModuleName(const PString & moduleName)
  2608. {
  2609.   if (importNames.Contains(moduleName))
  2610.     return importNames[moduleName];
  2611.   PINDEX pos = moduleName.Find('-');
  2612.   if (pos > 32)
  2613.     pos = 32;
  2614.   return moduleName.Left(pos);
  2615. }
  2616. void ModuleDefinition::GenerateCplusplus(const PFilePath & path,
  2617.                                          const PString & modName,
  2618.                                          unsigned numFiles,
  2619.                                          BOOL useNamespaces,
  2620.                                          BOOL useInlines,
  2621.                                          BOOL verbose)
  2622. {
  2623.   PINDEX i;
  2624.   usingInlines = useInlines;
  2625.   // Adjust the module name to what is specified to a default
  2626.   if (!modName)
  2627.     moduleName = modName;
  2628.   else
  2629.     moduleName = MakeIdentifierC(moduleName);
  2630.   // Set the prefix on all external class names
  2631.   if (!useNamespaces)
  2632.     classNamePrefix = moduleName + '_';
  2633.   if (verbose)
  2634.     cout << "Sorting " << types.GetSize() << " types..." << endl;
  2635.   // Create sorted list for faster searching.
  2636.   sortedTypes.DisallowDeleteObjects();
  2637.   for (i = 0; i < types.GetSize(); i++)
  2638.     sortedTypes.Append(&types[i]);
  2639.   // Flatten types by generating types for "inline" definitions
  2640.   for (i = 0; i < types.GetSize(); i++)
  2641.     types[i].FlattenUsedTypes();
  2642.   // Reorder types
  2643.   // Determine if we need a separate file for template closure
  2644.   BOOL hasTemplates = FALSE;
  2645.   types.DisallowDeleteObjects();
  2646.   PINDEX loopDetect = 0;
  2647.   PINDEX bubble = 0;
  2648.   while (bubble < types.GetSize()) {
  2649.     BOOL makesReference = FALSE;
  2650.     TypeBase & bubbleType = types[bubble];
  2651.     if (bubbleType.CanReferenceType()) {
  2652.       for (i = bubble; i < types.GetSize(); i++) {
  2653.         if (bubbleType.ReferencesType(types[i])) {
  2654.           makesReference = TRUE;
  2655.           break;
  2656.         }
  2657.       }
  2658.     }
  2659.     if (makesReference) {
  2660.       types.Append(types.RemoveAt(bubble));
  2661.       if (loopDetect > types.GetSize()) {
  2662.         PError << StdError(Fatal)
  2663.                << "Recursive type definition: " << bubbleType.GetName() << endl;
  2664.         break;
  2665.       }
  2666.       loopDetect++;
  2667.     }
  2668.     else {
  2669.       loopDetect = bubble;
  2670.       bubble++;
  2671.     }
  2672.     if (bubbleType.HasParameters())
  2673.       hasTemplates = TRUE;
  2674.   }
  2675.   types.AllowDeleteObjects();
  2676.   // Adjust all of the C++ identifiers prepending module name
  2677.   for (i = 0; i < types.GetSize(); i++)
  2678.     types[i].AdjustIdentifier();
  2679.   // Generate the code
  2680.   if (verbose)
  2681.     cout << "Generating code (" << types.GetSize() << " classes) ..." << endl;
  2682.   // Output the special template closure file, if necessary
  2683.   PString templateFilename;
  2684.   if (hasTemplates) {
  2685.     OutputFile templateFile;
  2686.     if (!templateFile.Open(path, "_t", ".cxx"))
  2687.       return;
  2688.     for (i = 0; i < types.GetSize(); i++) {
  2689.       if (types[i].HasParameters()) {
  2690.         PStringStream dummy;
  2691.         types[i].GenerateCplusplus(dummy, templateFile);
  2692.       }
  2693.     }
  2694.     if (verbose)
  2695.       cout << "Completed " << templateFile.GetFilePath() << endl;
  2696.     templateFilename = templateFile.GetFilePath().GetFileName();
  2697.   }
  2698.   // Start the header file
  2699.   OutputFile hdrFile;
  2700.   if (!hdrFile.Open(path, "", ".h"))
  2701.     return;
  2702.   hdrFile << "#ifndef __" << moduleName.ToUpper() << "_Hn"
  2703.              "#define __" << moduleName.ToUpper() << "_Hn"
  2704.              "n"
  2705.              "#ifdef __GNUC__n"
  2706.              "#pragma interfacen"
  2707.              "#endifn"
  2708.              "n"
  2709.              "#include <ptclib/asner.h>n"
  2710.              "n";
  2711.   // Start the first (and maybe only) cxx file
  2712.   OutputFile cxxFile;
  2713.   if (!cxxFile.Open(path, numFiles > 1 ? "_1" : "", ".cxx"))
  2714.     return;
  2715.   PString headerName = hdrFile.GetFilePath().GetFileName();
  2716.   cxxFile << "#ifdef __GNUC__n"
  2717.              "#pragma implementation "" << headerName << ""n"
  2718.              "#endifn"
  2719.              "n"
  2720.              "#include <ptlib.h>n"
  2721.              "#include "" << headerName << ""n"
  2722.              "n"
  2723.              "#define new PNEWn"
  2724.              "n"
  2725.              "n";
  2726.   // Include the template closure file.
  2727.   if (hasTemplates)
  2728.     cxxFile << "#include "" << templateFilename << ""nn";
  2729.   for (i = 0; i < imports.GetSize(); i++)
  2730.     imports[i].GenerateCplusplus(hdrFile, cxxFile);
  2731.   if (!imports.IsEmpty()) {
  2732.     hdrFile << "nn";
  2733.     cxxFile << "nn";
  2734.   }
  2735.   if (useNamespaces) {
  2736.     hdrFile << "namespace " << moduleName << " {n"
  2737.                "n";
  2738.     cxxFile << "using namespace " << moduleName << ";n"
  2739.                "n";
  2740.   }
  2741.   PINDEX classesPerFile = (types.GetSize()+numFiles-1)/numFiles;
  2742.   for (i = 0; i < types.GetSize(); i++) {
  2743.     if (i > 0 && i%classesPerFile == 0) {
  2744.       cxxFile.Close();
  2745.       if (verbose)
  2746.         cout << "Completed " << cxxFile.GetFilePath() << endl;
  2747.       if (!cxxFile.Open(path, psprintf("_%u", i/classesPerFile+1), ".cxx"))
  2748.         return;
  2749.       cxxFile << "#include <ptlib.h>n"
  2750.                  "#include "" << headerName << ""n"
  2751.                  "n";
  2752.       if (useNamespaces)
  2753.         cxxFile << "using namespace " << moduleName << ";n"
  2754.                    "n";
  2755.       cxxFile << "#define new PNEWn"
  2756.                  "n"
  2757.                  "n";
  2758.     }
  2759.     if (types[i].HasParameters()) {
  2760.       PStringStream dummy;
  2761.       types[i].GenerateCplusplus(hdrFile, dummy);
  2762.     }
  2763.     else
  2764.       types[i].GenerateCplusplus(hdrFile, cxxFile);
  2765.   }
  2766.   // Close off the files
  2767.   if (useNamespaces)
  2768.     hdrFile << "};n"
  2769.                "n";
  2770.   hdrFile << "#endif // __" << moduleName.ToUpper() << "_Hn"
  2771.              "n";
  2772.   if (verbose)
  2773.     cout << "Completed " << cxxFile.GetFilePath() << endl;
  2774. }
  2775. //////////////////////////////////////////////////////////////////////////////