📄 main.cxx
字号:
/* * main.cxx * * PWLib application source file for asnparser * * ASN.1 compiler to produce C++ classes. * * Copyright (c) 1997-1999 Equivalence Pty. Ltd. * * Copyright (c) 2001 Institute for Information Industry * (http://www.iii.org.tw/iiia/ewelcome.htm) * * 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.4 2002/08/20 22:35:54 mangelo * Add MSVC DLL support * * Revision 1.3 2002/07/02 02:03:25 mangelo * Remove Pwlib dependency * * Revision 1.2 2001/09/07 22:39:28 mangelo * add Log keyword substitution * * * 2001/07/25 Huang-Ming Huang * Added code to generate "#undef ERROR" * * 2001/07/18 Huang-Ming Huang * Fixed the bug of generating non-static info for SEQUENCE_OF type. * * 2001/07/18 Huang-Ming Huang * The includeOptionalField has been changed to take two parameter in * accordance with the ASN1 library. * * 2001/06/26 Huang-Ming Huang * Version 2.1 Reimplemented to minimize the generated code size. * * 2001/05/03 Huang-Ming Huang * Fixed the problem with my wrong interpretation to varaible constraint. * * March, 2001 Huang-Ming Huang * Add support for Information Object Class and generate code that follows * X/Open ASN.1/C++ interface. */#include <unistd.h>#include "main.h"#include <boost/mem_fn.hpp>#include <boost/ref.hpp>#include <boost/bind.hpp>#include <boost/iterator_adaptors.hpp>#include <boost/functional.hpp>#include <typeinfo>#include <algorithm>#include <numeric>#include <set>#include <strstream>#include <fstream>#include <iostream>#include <iomanip>#include <assert.h>#include "asn_grammar.h"#ifdef _WIN32#define DIR_SEPARATOR '\\'#else#define DIR_SEPARATOR '/'#endif//using namespace boost;unsigned lineNumber;std::string fileName;unsigned fatals, warnings;extern void yyrestart(FILE*);extern FILE * yyin;extern FILE * idin;extern int yydebug;extern int iddebug;int LexEcho;static const char * const StandardClasses[] = { "ASN1::Null", "ASN1::BOOLEAN", "ASN1::INTEGER", "ASN1::ENUMERATED", "ASN1::BinaryReal", "ASN1::OBJECT_IDENGIFIER", "ASN1::BIT_STRING", "ASN1::OCTET_STRING", "ASN1::NumericString", "ASN1::PrintableString", "ASN1::VisibleString", "ASN1::IA5String", "ASN1::GeneralString", "ASN1::BMPString", "ASN1::SEQUENCE_OF"};static const char * CppReserveWords[] = { "and","and_eq", "asm", "auto", "bitand", "bitor", "bool", "break", "case", "catch", "char", "class", "compl", "const", "const_cast", "continue", "default", "delete", "do", "double", "dynamic_cast", "else", "enum", "explicit", "export", "extern", "false", "float", "for", "friend", "goto", "if", "inline", "int", "long", "mutable", "namespace", "new", "not", "not_eq", "operator", "or", "or_eq", "private", "protected", "public", "register", "reinterpret_cast", "return", "short", "signed", "sizeof", "static", "static_cast", "struct", "switch", "template", "this", "throw", "true", "try", "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual", "void", "volitile", "wchar_t", "while", "xor", "xor_eq"};#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))ModuleDefinition * Module;ModuleList Modules;ClassStack *classStack;ParameterList * DummyParameters;extern int IdentifierTokenContext ;extern int BraceTokenContext ;extern int InOIDContext ;extern int NullTokenContext ;extern int InObjectSetContext;TypePtr ValueTypeContext;std::vector<std::string> RemoveList;//// yyerror// required function for flex//void yyerror(char * str){ extern char * yytext; std::cerr << StdError(Fatal) << str << " near token \"" << yytext <<"\"\n";}void iderror(char * str){ extern char * idtext; std::cerr << StdError(Fatal) << str << " near token \"" << idtext <<"\"\n";}std::ostream & operator<<(std::ostream & out, const StdError & e){ out << fileName << '(' << lineNumber << ") : "; if (e.e == Fatal) { fatals++; out << "error"; } else { warnings++; out << "warning"; } return out << ": ";}///////////////////////////////////////////////////////////// Utility//void str_replace(std::string& str, const char* src, const char* target, int pos = 0){ while ( (pos = str.find(src,pos)) != -1) str.replace(pos, strlen(src), target);}struct strcompare : std::binary_function<const char*, const char*, bool>{ bool operator () (const char* lhs, const char* rhs) { return strcmp(lhs, rhs)<0; }};static std::string MakeIdentifierC(const std::string & identifier){ std::string s = identifier; if (s != "") { str_replace(s, "-", "_"); static const char** end = CppReserveWords+ARRAY_SIZE(CppReserveWords); if (std::binary_search(CppReserveWords, end, s.c_str(), strcompare())) s += '_'; } return s;}// creates a short name for module names from combining the first character// of each '-' parted words, eg. H323-MESSAGES => HM, // Multimedia-System-Control => MSCstatic std::string ShortenName(const std::string& name){ std::string s ; s += name[0]; size_t i = 0; while ( (i = name.find('-', i+1)) != -1) s += name[i+1]; return s;}inline std::string ToLower(const std::string& str){ std::string result; result.resize(str.size()); std::transform(str.begin(), str.end(), result.begin(), tolower); return result;}inline std::string ToUpper(const std::string& str){ std::string result; result.resize(str.size()); std::transform(str.begin(), str.end(), result.begin(), toupper); return result;}std::string GetFileName(const std::string& fullname){ int i = fullname.find_last_of(DIR_SEPARATOR); return fullname.substr(i+1);}std::string GetFileDirectory(const std::string& fullname){ int i = fullname.find_last_of(DIR_SEPARATOR); if (i>=1) return fullname.substr(0, i-1); else return std::string();}std::string GetFileTitle(const std::string& fullname){ std::string result = GetFileName(fullname); int dotpos = result.find_last_of('.'); if (dotpos == -1) return result.substr(0, dotpos-1); return result;}class OutputFile : public std::ofstream{ public: OutputFile() {} ~OutputFile() { Close(); } bool Open(const std::string & path, const char* suffix, const char * extension); void Close(); const std::string& GetFilePath() const { return filename; }private: OutputFile(const OutputFile&); OutputFile& operator = (const OutputFile&); std::string filename;};bool OutputFile::Open(const std::string & path, const char * suffix, const char * extension){ filename = path + suffix + extension; open(filename.c_str()); if (is_open()) { *this << "//\n" "// " << GetFileName(filename) << "\n" "//\n" "// Code automatically generated by asnparser.\n" "//\n" "\n"; return true; } std::cerr << "asnparser : cannot create " << filename << std::endl; return false;}void OutputFile::Close(){ if (is_open()) *this << "\n" "// End of " << GetFileName(filename) << '\n'; using namespace std; ofstream::close();}class Indent {public: Indent(int i) : space(i){} Indent operator + (int i) const { return Indent(space +i); } Indent operator - (int i) const { return Indent(space -i); } Indent& operator += (int i) { space+= i; return *this;} Indent& operator -= (int i) { space-= i; return *this;} friend std::ostream& operator << (std::ostream& os, const Indent& indent) { if (indent.space) os << std::setw(indent.space) << " "; return os; }private: int space;};void AddRemoveItem(const char* item){ RemoveList.push_back(std::string(item));}template <class Cont, class Fun>void for_all(Cont& cont, Fun fun){ std::for_each(cont.begin(), cont.end(), fun);}ModuleDefinition* FindModule(const char* name){ return FindWithName(Modules, name).get();}template <class T>std::ostream& operator << (std::ostream& os, const std::vector<boost::shared_ptr<T> >& cont){ typename std::vector<boost::shared_ptr<T> >::const_iterator it, last = cont.end(); for (it = cont.begin(); it != last; ++it) os << **it; return os;}///////////////////////////////////////////////////////////// Application//int verbose=0;std::string dllMacroExport;std::string dllMacroStatic;int main(int argc, char** argv){ extern int yydebug ; // nonzero means print parse trace const char* opt = "cdo:s:vm:"; int c; unsigned classesPerFile = 0; bool generateCpp = false; std::string path; while ((c=getopt(argc, argv, opt)) != -1) { switch (c) { case 'c': generateCpp = true; break; case 'd': yydebug = 1; iddebug = 1; break; case 'o': path = optarg; break; case 's': classesPerFile = atoi(optarg); break; case 'v': ++verbose; break; case 'm': dllMacroExport = optarg; dllMacroExport += "_EXPORT "; dllMacroStatic = optarg; dllMacroStatic += "_STATIC"; break; } } size_t fileCount = argc-optind; if (fileCount < 1 ) { std::cerr << "usage: asnparser [options] asnfile...\n" " -v Verbose output (multiple times for more verbose)\n" " -d Debug output (copious!)\n" " -c Generate C++ files\n" " -s n Split output if it has more than n (default 50) classes\n" " -o dir Output directory\n" " -m name Macro name for generating DLLs under windows with MergeSym\n" << std::endl; return 1; } std::cout << "asnparser version 2.2 by Institute for Information Industry" << std::endl; classStack = new ClassStack; std::vector<FILE*> fds(fileCount); size_t i; for ( i = 0 ; i < fileCount; ++i) { idin = fds[i] = fopen(argv[i+optind],"r"); if (!idin) { std::cerr << "asnparser: cannot open \"" << argv[i+optind] << '"'<<std::endl; return 1; } fileName = argv[i+optind]; lineNumber = 1; fatals = 0; warnings = 0; if (verbose) std::cout << "First Stage Parsing... " << fileName << std::endl; idparse(); // parse the identifier types } for (i = 0; i < fileCount; ++i) { fileName = argv[i+optind]; lineNumber = 1; fatals = 0; warnings = 0; yyin = fds[i]; if (verbose) std::cout << "Second Stage Parsing... " << fileName << std::endl; rewind(yyin); // rewind the file yyrestart( yyin ); yyparse(); // actually parse the content of the ASN.1 } for (i = 0 ; i < Modules.size(); ++i) { Modules[i]->AdjustModuleName(path); } for (i = 0; i < RemoveList.size(); ++i) { int dotpos = RemoveList[i].find('.'); std::string modulename = RemoveList[i].substr(0, dotpos); ModuleDefinition* module = FindModule(modulename.c_str()); if (module) module->AddToRemoveList(RemoveList[i].substr(dotpos+1, RemoveList[i].size()-1)); } for (i = 0 ; i < Modules.size(); ++i) { Modules[i]->RemoveReferences(verbose !=0 ); Modules[i]->AdjustImportedModules(); } for (i = 0; i < Modules.size(); ++i) { Module = Modules[i].get(); if (verbose > 1) std::cerr << "Module " << *Module << std::endl; if (generateCpp) Module->GenerateCplusplus(path, classesPerFile, verbose!=0); } delete classStack; return 0;}///////////////////////////////////////////// miscellaneous//class indent{ public: indent() { } friend std::ostream & operator<<(std::ostream & s, const indent &) { return s << std::setw(Module->GetIndentLevel()*3) << ' '; }};///////////////////////////////////////////// intermediate structures from parser//NamedNumber::NamedNumber(std::string * nam) : name(*nam){ delete nam; number = 0; autonumber = true;}NamedNumber::NamedNumber(std::string * nam, int num) : name(*nam){ delete nam; number = num; autonumber = false;}NamedNumber::NamedNumber(std::string * nam, const std::string & ref) : name(*nam), reference(ref){ delete nam;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -