📄 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.49 2004/04/13 11:33:55 csoutheren * Fixed XER output, thanks to Federico Pinna * * Revision 1.48 2004/04/03 08:22:23 csoutheren * Remove pseudo-RTTI and replaced with real RTTI * * Revision 1.47 2004/02/17 10:24:04 rjongbloed * Updated version number so will rebuild ASN files. * * Revision 1.46 2004/02/17 09:38:24 csoutheren * Added change to remove duplicate forward declarations * See SourceForge bug 832245 * Thanks to Vyacheslav E. Andrejev * * Revision 1.45 2003/10/03 00:13:04 rjongbloed * Added ability to specify CHOICE field selection by function rather than operator as the operator technique does not work with some dumb compilers. * Added ability to specify that the header file name be different from the module name and module prefix string. * * Revision 1.44 2003/02/27 04:05:30 robertj * Added ability to have alternate directories for header file * includes in generated C++ code. * Added constructors to PASN_OctetString descendant classes to help * with doing simple assignments. * * Revision 1.43 2003/02/26 01:57:44 robertj * Added XML encoding rules to ASN system, thanks Federico Pinna * * Revision 1.42 2003/02/19 14:18:55 craigs * Fixed ifdef problem with multipart cxx files * * Revision 1.41 2003/02/18 10:50:41 craigs * Added minor optimisation of outputted ASN code * Added automatic insertion of defines to allow disabling of generated code * * Revision 1.40 2002/11/27 11:42:52 robertj * Rearranged code to avoid GNU compiler problem. * Changed new classheader parameters to be full C literal like string for * improved backslash conversion. * Incremented version number. * * Revision 1.39 2002/11/26 11:39:10 craigs * Added option to allow adding functions to generated header files * * Revision 1.38 2002/09/16 01:08:59 robertj * Added #define so can select if #pragma interface/implementation is used on * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan. * * Revision 1.37 2001/10/02 00:56:14 robertj * Fixed problem with autonumering enumerated types. * * Revision 1.36 2001/08/06 01:39:02 robertj * Added assignement operator with RHS of PASN_BMPString to classes * descended from PASN_BMPString. * * Revision 1.35 2001/08/03 09:01:02 robertj * Added assignement operator with RHS of PWORDArray to classes * descended from PASN_BMPString. * * Revision 1.34 2001/06/14 02:09:20 robertj * Corrected support for ASN object class type reference constructs * ie TYPE-IDENTIFIER.&Type encoded as octet string. * * Revision 1.33 2001/04/26 08:15:58 robertj * Fixed problem with ASN compile of single constraints on enumerations. * * Revision 1.32 2001/04/23 04:40:14 robertj * Added ASN standard types GeneralizedTime and UTCTime * * Revision 1.31 2001/02/22 23:31:42 robertj * Fixed display of version number just added. * * Revision 1.30 2001/02/22 22:31:01 robertj * Added command line flag to display version number only. * * Revision 1.29 2000/10/12 23:11:48 robertj * Fixed problem with BER encoding of ASN with optional fields. * * 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"#define MAJOR_VERSION 1#define MINOR_VERSION 9#define BUILD_TYPE ReleaseCode#define BUILD_NUMBER 1unsigned 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(); BOOL SetClassHeaderFile(PArgList & args); BOOL SetClassHeader(PArgList & args); void OutputAdditionalHeaders(ostream & hdr, const PString & className); protected: PStringToString classToHeader;};PCREATE_PROCESS(App);App::App() : PProcess("Equivalence", "ASNParse", MAJOR_VERSION, MINOR_VERSION, BUILD_TYPE, BUILD_NUMBER){}void App::Main(){ cout << GetName() << " version " << GetVersion(TRUE) << " for " << GetOSClass() << ' ' << GetOSName() << " by " << GetManufacturer() << endl; PArgList & args = GetArguments(); args.Parse("c-c++." "d-debug." "e-echo." "h-hdr-prefix:" "i-inlines." "m-module:" "n-namespace." "o-output:" "r-rename:" "s-split;" "V-version." "v-verbose." "x-xml." "-no-operators." "-classheader:" "-classheaderfile:"); if (args.HasOption('V')) return; 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 --version Display version and exit\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" " -h --hdr-prefix str Prefix for C++ include of header (eg directory)\n" " -i --inlines Use C++ inlines\n" " -s[n] --split[n] Split output into n (default 2) files\n" " -m --module name Module name prefix/namespace\n" " -r --rename args Rename import module where arg is:\n" " from=name[,prefix[,fname]]\n" " from is module name in ASN file\n" " name is target header file name\n" " prefix is optional prefix for include\n" " (eg header directory)\n" " fname is optional base name for header files\n" " --no-operators Generate functions instead of operators for choice\n" " sub-object extraction.\n" " -x --xml X.693 support (XER)\n" " -o --output file Output filename/directory\n" << endl; return; } PTextFile prcFile; if (!prcFile.Open(args[0], PFile::ReadOnly)) { PError << GetName() << ": cannot open \"" << prcFile.GetFilePath() << "\" :" << prcFile.GetErrorText() << endl; return; } if (args.HasOption('d')) yydebug = 1; if (args.HasOption('e')) LexEcho = TRUE; fileName = prcFile.GetFilePath(); lineNumber = 1; fatals = 0; warnings = 0; if (args.HasOption("classheaderfile")) { if (!SetClassHeaderFile(args)) return; } if (args.HasOption("classheader")) { if (!SetClassHeader(args)) return; } 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'), args.GetOptionString('h'), numFiles, args.HasOption('n'), args.HasOption('i'), !args.HasOption("no-operators"), args.HasOption('v')); }}BOOL App::SetClassHeaderFile(PArgList & args){ PStringArray lines = args.GetOptionString("classheaderfile").Lines(); if (lines.IsEmpty()) { PError << GetName() << ": malformed --classheaderfile option\n"; return FALSE; } for (PINDEX i = 0; i < lines.GetSize(); i++) { PString str = lines[i]; PINDEX pos = str.Find("="); if (pos == P_MAX_INDEX) { PError << GetName() << ": malformed --classheaderfile option\n"; return FALSE; } PFilePath fn = str.Right(pos+1); PTextFile file(fn, PFile::ReadOnly); if (!file.IsOpen()) { PError << GetName() << ": cannot open file required for --classheaderfile option \"" << fn << "\" :" << file.GetErrorText() << '\n'; return FALSE; } PString text; PString line; while (file.ReadLine(line)) text += PString(PString::Literal, (const char *)line) + '\n'; classToHeader.SetAt(str.Left(pos), text); } return TRUE;}BOOL App::SetClassHeader(PArgList & args){ PStringArray lines = args.GetOptionString("classheader").Lines(); if (lines.IsEmpty()) { PError << GetName() << ": malformed --classheader option\n"; return FALSE; } for (PINDEX i = 0; i < lines.GetSize(); i++) { PString str = lines[i]; PINDEX pos = str.Find("="); if (pos == P_MAX_INDEX) { PError << GetName() << ": malformed --classheader option\n"; return FALSE; } PString text(PString::Literal, (const char *)str.Mid(pos+1)); classToHeader.SetAt(str.Left(pos), text); } return TRUE;}void App::OutputAdditionalHeaders(ostream & hdr, const PString & className){ if (classToHeader.Contains(className)) { hdr << "// following code added by command line option\n"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -