📄 main.cxx
字号:
/* * main.cxx * * PWLib application source file for asnparser * * ASN.1 compiler to produce C++ classes. * * Copyright (c) 1997-1999 Equivalence Pty. Ltd. * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is ASN Parser. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Portions of this code were written with the assisance of funding from * Vovida Networks, Inc. http://www.vovida.com. * * Portions are Copyright (C) 1993 Free Software Foundation, Inc. * All Rights Reserved. * * Contributor(s): ______________________________________. * * $Log: main.cxx,v $ * Revision 1.28 2000/06/26 13:14:46 robertj * Nucleus++ port. * * Revision 1.27 2000/03/21 21:23:23 robertj * Added option to rename imported module names, allows include filename matching. * * Revision 1.26 2000/01/19 12:33:07 robertj * Fixed parsing of OID's in IMPORTS section. * * Revision 1.25 2000/01/19 03:38:12 robertj * Fixed support for parsing multiple IMPORTS * * Revision 1.24 1999/09/18 04:17:40 robertj * Added generation of C++ inlines for some functions. * Optimised CreateObject() switch statements, collapsing common cases. * * Revision 1.23 1999/09/18 02:42:27 craigs * Added optimisation to collapse switch arms in CreateObject functions * * Revision 1.22 1999/09/07 09:56:04 robertj * Fixed failure to put "using anmespace" in every generated .cxx file. * * Revision 1.21 1999/08/28 01:48:55 robertj * Fixed anomaly to always include non-optional extensions in encodings. * * Revision 1.20 1999/08/09 13:02:36 robertj * Added ASN compiler #defines for backward support of pre GCC 2.9 compilers. * Added ASN compiler #defines to reduce its memory footprint. * Added ASN compiler code generation of assignment operators for string classes. * * Revision 1.19 1999/07/22 06:48:55 robertj * Added comparison operation to base ASN classes and compiled ASN code. * Added support for ANY type in ASN parser. * * Revision 1.18 1999/07/06 05:00:26 robertj * Incremented release number * * Revision 1.17 1999/07/01 12:21:46 robertj * Changed PASN_Choice cast operators so no longer "break" const-ness of object. * * Revision 1.16 1999/06/30 08:57:19 robertj * Fixed bug in encodeing sequence of constrained primitive type. Constraint not set. * Fixed bug in not emitting namespace use clause. * Added "normalisation" of separate sequence of <base type> to be single class. * * Revision 1.15 1999/06/14 13:00:15 robertj * Fixed bug in code generation for string constraints. * * Revision 1.14 1999/06/09 06:58:09 robertj * Adjusted heading comments. * * Revision 1.13 1999/06/09 02:07:49 robertj * Fixed backward compatibility of generated template code with G++ 2.7.x * * Revision 1.12 1999/06/07 01:56:25 robertj * Added header comment on license. * */#include <ptlib.h>#include "main.h"#include "asn_grammar.h"unsigned lineNumber;PString fileName;unsigned fatals, warnings;extern FILE * yyin;extern int yydebug;extern int LexEcho;ModuleDefinition * Module;static const char * UniversalTagClassNames[] = { "UniversalTagClass", "ApplicationTagClass", "ContextSpecificTagClass", "PrivateTagClass"};static const char * UniversalTagNames[] = { NULL, "UniversalBoolean", "UniversalInteger", "UniversalBitString", "UniversalOctetString", "UniversalNull", "UniversalObjectId", "UniversalObjectDescriptor", "UniversalExternalType", "UniversalReal", "UniversalEnumeration", "UniversalEmbeddedPDV", NULL, NULL, NULL, NULL, "UniversalSequence", "UniversalSet", "UniversalNumericString", "UniversalPrintableString", "UniversalTeletexString", "UniversalVideotexString", "UniversalIA5String", "UniversalUTCTime", "UniversalGeneralisedTime", "UniversalGraphicString", "UniversalVisibleString", "UniversalGeneralString", "UniversalUniversalString", NULL, "UniversalBMPString"};static const char * const StandardClasses[] = { "PASN_Null", "PASN_Boolean", "PASN_Integer", "PASN_Enumeration", "PASN_Real", "PASN_ObjectId", "PASN_BitString", "PASN_OctetString", "PASN_NumericString", "PASN_PrintableString", "PASN_VisibleString", "PASN_IA5String", "PASN_GeneralString", "PASN_BMPString", "PASN_Sequence"};///////////////////////////////////////////// yyerror// required function for flex//void yyerror(char * str){ extern char * yytext; PError << StdError(Fatal) << str << " near token \"" << yytext <<"\"\n";}ostream & operator<<(ostream & out, const StdError & e){ out << fileName << '(' << lineNumber << ") : "; if (e.e == Fatal) { fatals++; out << "error"; } else { warnings++; out << "warning"; } return out << ": ";}///////////////////////////////////////////////////////////// Utility//static PString MakeIdentifierC(const PString & identifier){ PString s = identifier; s.Replace("-", "_", TRUE); return s;}class OutputFile : public PTextFile{ PCLASSINFO(OutputFile, PTextFile); public: ~OutputFile() { Close(); } BOOL Open(const PFilePath & path, const PString & suffix, const char * extension); BOOL Close();};BOOL OutputFile::Open(const PFilePath & path, const PString & suffix, const char * extension){ PFilePath fn = path.GetDirectory() + path.GetTitle() + suffix; fn.SetType(extension); if (PTextFile::Open(fn, WriteOnly)) *this << "//\n" "// " << GetFilePath().GetFileName() << "\n" "//\n" "// Code automatically generated by asnparse.\n" "//\n" "\n"; else PError << PProcess::Current().GetName() << ": cannot create \"" << GetFilePath() << "\" :" << GetErrorText() << endl; return IsOpen();}BOOL OutputFile::Close(){ if (IsOpen()) *this << "\n" "// End of " << GetFilePath().GetFileName() << '\n'; return PTextFile::Close();}///////////////////////////////////////////////////////////// Application//class App : public PProcess{ PCLASSINFO(App, PProcess); public: App(); void Main();};PCREATE_PROCESS(App);App::App() : PProcess("Equivalence", "ASNParse", 1, 3, BetaCode, 3){}void App::Main(){ PArgList & args = GetArguments(); args.Parse("v-verbose." "e-echo." "d-debug." "c-c++." "n-namespace." "i-inlines." "s-split;" "o-output:" "m-module:" "r-rename:"); unsigned numFiles = 1; if (args.HasOption('s')) { PString numFilesStr = args.GetOptionString('s'); if (numFilesStr.IsEmpty()) numFiles = 2; else numFiles = numFilesStr.AsUnsigned(); } if (args.GetCount() < 1 || args.GetCount() > 1 || numFiles == 0) { PError << "usage: asnparse [options] asnfile\n" " -v --verbose Verbose output (multiple times for more verbose)\n" " -e --echo Echo input file\n" " -d --debug Debug output (copious!)\n" " -c --c++ Generate C++ files\n" " -n --namespace Use C++ namespace\n" " -i --inlines Use C++ inlines\n" " -s[n] --split[n] Split output into n (default 2) files\n" " -o --output file Output filename/directory\n" " -m --module name Module name prefix/namespace\n" " -r --rename from=to Rename import module\n" << endl; return; } PTextFile prcFile; if (!prcFile.Open(args[0], PFile::ReadOnly)) { PError << GetName() << ": cannot open \"" << prcFile.GetFilePath() << "\" :" << prcFile.GetErrorText() << endl; return; } cout << GetName() << " version " << GetVersion(TRUE) << " for " << GetOSClass() << ' ' << GetOSName() << " by " << GetManufacturer() << endl; if (args.HasOption('d')) yydebug = 1; if (args.HasOption('e')) LexEcho = TRUE; fileName = prcFile.GetFilePath(); lineNumber = 1; fatals = 0; warnings = 0; if (args.HasOption('v')) cout << "Parsing..." << endl; yyin = _fdopen(prcFile.GetHandle(), "r"); PAssertNULL(yyin); yyparse(); if (Module != NULL) { if (args.GetOptionCount('v') > 1) PError << "Module " << *Module << endl; if (args.HasOption('c')) Module->GenerateCplusplus(args.GetOptionString('o', args[0]), args.GetOptionString('m'), numFiles, args.HasOption('n'), args.HasOption('i'), args.HasOption('v')); }}///////////////////////////////////////////// miscellaneous//class indent{ public: indent() { } friend ostream & operator<<(ostream & s, const indent &) { return s << setw(Module->GetIndentLevel()*3) << ' '; }};///////////////////////////////////////////// intermediate structures from parser//NamedNumber::NamedNumber(PString * nam) : name(*nam){ delete nam; number = 0; autonumber = TRUE;}NamedNumber::NamedNumber(PString * nam, int num) : name(*nam){ delete nam; number = num; autonumber = FALSE;}NamedNumber::NamedNumber(PString * nam, const PString & ref) : name(*nam), reference(ref){ delete nam; number = 0; autonumber = FALSE;}void NamedNumber::PrintOn(ostream & strm) const{ strm << name << " ("; if (reference.IsEmpty()) strm << number; else strm << reference; strm << ')';}void NamedNumber::SetAutoNumber(const NamedNumber & prev){ if (autonumber) { number = prev.number + 1; autonumber = FALSE; }}/////////////////////////////////////////////////////////Tag::Tag(unsigned tagNum){ type = Universal; number = tagNum; mode = Module->GetDefaultTagMode();}const char * Tag::classNames[] = { "UNIVERSAL", "APPLICATION", "CONTEXTSPECIFIC", "PRIVATE"};const char * Tag::modeNames[] = { "IMPLICIT", "EXPLICIT", "AUTOMATIC"};void Tag::PrintOn(ostream & strm) const{ if (type != Universal || number != IllegalUniversalTag) { strm << '['; if (type != ContextSpecific) strm << classNames[type] << ' '; strm << number << "] " << modeNames[mode] << ' '; }}/////////////////////////////////////////////////////////Constraint::Constraint(ConstraintElementBase * elmt){ standard.Append(elmt); extendable = FALSE;}Constraint::Constraint(ConstraintElementList * stnd, BOOL extend, ConstraintElementList * ext){ if (stnd != NULL) { standard = *stnd; delete stnd; } extendable = extend; if (ext != NULL) { extensions = *ext; delete ext; }}void Constraint::PrintOn(ostream & strm) const{ strm << '('; for (PINDEX i = 0; i < standard.GetSize(); i++) strm << standard[i]; if (extendable) { strm << indent(); if (standard.GetSize() > 0) strm << ", "; strm << "..., "; for (PINDEX i = 0; i < extensions.GetSize(); i++) strm << extensions[i]; } strm << ')';}void Constraint::GenerateCplusplus(const PString & fn, ostream & hdr, ostream & cxx){ switch (standard.GetSize()) { case 0 : return; case 1 : break; default : PError << StdError(Warning) << "unsupported UNION constraints, ignored." << endl; } if (extensions.GetSize() > 0) PError << StdError(Warning) << "unsupported extension constraints, ignored." << endl; PString fn2 = fn; if (fn.Find("PASN_Object::") == P_MAX_INDEX) { if (extendable) fn2 += "PASN_Object::ExtendableConstraint"; else fn2 += "PASN_Object::FixedConstraint"; } standard[0].GenerateCplusplus(fn2, hdr, cxx);}BOOL Constraint::ReferencesType(const TypeBase & type){ PINDEX i; for (i = 0; i < standard.GetSize(); i++) { if (standard[i].ReferencesType(type)) return TRUE; } for (i = 0; i < extensions.GetSize(); i++) { if (extensions[i].ReferencesType(type)) return TRUE; } return FALSE;}/////////////////////////////////////////////////////////ConstraintElementBase::ConstraintElementBase(){ exclusions = NULL;}void ConstraintElementBase::GenerateCplusplus(const PString &, ostream &, ostream &){ PError << StdError(Warning) << "unsupported constraint, ignored." << endl;}BOOL ConstraintElementBase::ReferencesType(const TypeBase &){ return FALSE;}/////////////////////////////////////////////////////////ConstrainAllConstraintElement::ConstrainAllConstraintElement(ConstraintElementBase * excl){ SetExclusions(excl);}/////////////////////////////////////////////////////////ElementListConstraintElement::ElementListConstraintElement(ConstraintElementList * list) : elements(*list){ delete list;}void ElementListConstraintElement::PrintOn(ostream & strm) const{ elements.PrintOn(strm);}void ElementListConstraintElement::GenerateCplusplus(const PString & fn, ostream & hdr, ostream & cxx){ for (PINDEX i = 0; i < elements.GetSize(); i++) elements[i].GenerateCplusplus(fn, hdr, cxx);}BOOL ElementListConstraintElement::ReferencesType(const TypeBase & type){ for (PINDEX i = 0; i < elements.GetSize(); i++) { if (elements[i].ReferencesType(type)) return TRUE; } return FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -