idlrepoid.cc
来自「编译工具」· CC 代码 · 共 433 行
CC
433 行
// -*- c++ -*-// Package : omniidl// idlrepoId.cc Created on: 1999/10/11// Author : Duncan Grisby (dpg1)//// Copyright (C) 1999 AT&T Laboratories Cambridge//// This file is part of omniidl.//// omniidl is free software; you can redistribute it and/or modify it// under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA// 02111-1307, USA.//// Description:// // Implementation of repoId management// $Id: idlrepoId.cc,v 1.5.2.9 2005/07/21 15:25:08 dgrisby Exp $// $Log: idlrepoId.cc,v $// Revision 1.5.2.9 2005/07/21 15:25:08 dgrisby// Silence some gcc 4 warnings / errors.//// Revision 1.5.2.8 2005/05/03 10:12:40 dgrisby// Trying to redefine built in CORBA module types led to a segfault.//// Revision 1.5.2.7 2003/04/25 15:54:28 dgrisby// Remove unnecessary iostream.h include.//// Revision 1.5.2.6 2001/11/13 14:11:46 dpg1// Tweaks for CORBA 2.5 compliance.//// Revision 1.5.2.5 2001/10/17 16:48:33 dpg1// Minor error message tweaks//// Revision 1.5.2.4 2000/11/03 12:20:58 dpg1// #pragma ID can now be declared more than once for a type, as long as// the id is the same.//// Revision 1.5.2.3 2000/10/27 16:31:09 dpg1// Clean up of omniidl dependencies and types, from omni3_develop.//// Revision 1.5.2.2 2000/10/10 10:18:51 dpg1// Update omniidl front-end from omni3_develop.//// Revision 1.3.2.1 2000/08/29 10:20:27 dpg1// Operations and attributes now have repository ids.//// Revision 1.3 1999/11/08 10:50:47 dpg1// Change to behaviour when files end inside a scope.//// Revision 1.2 1999/11/02 17:07:25 dpg1// Changes to compile on Solaris.//// Revision 1.1 1999/10/27 14:05:56 dpg1// *** empty log message ***//#include <idlrepoId.h>#include <idlast.h>#include <idlutil.h>#include <idlerr.h>#include <idlvisitor.h>#include <string.h>#include <stdio.h>#include <ctype.h>// Globals from lexer/parserextern int yylineno;extern char* currentFile;Prefix* Prefix::current_ = 0;Prefix::Prefix(char* str, IDL_Boolean isfile) : str_(str), parent_(current_), isfile_(isfile){ current_ = this;}Prefix::~Prefix(){ current_ = parent_; delete [] str_;}const char*Prefix::current(){ return current_->get();}voidPrefix::newScope(const char* name){ if (name[0] == '_') ++name; int len = strlen(current()) + strlen(name) + 2; char* str = new char[len]; strcpy(str, current()); if (str[0] != '\0') strcat(str, "/"); strcat(str, name); new Prefix(str, 0);}voidPrefix::newFile(){ char* str = new char[1]; str[0] = '\0'; new Prefix(str, 1);}voidPrefix::setPrefix(const char* prefix){ current_->set(prefix);}voidPrefix::endScope(){ if (current_->parent_) delete current_; else IdlWarning(currentFile, yylineno, "Confused by pre-processor line directives");}voidPrefix::endFile(){ if (!current_->isfile()) { IdlWarning(currentFile, yylineno, "File ended inside a declaration. " "Repository identifiers may be incorrect"); } if (current_->parent_) delete current_; else IdlWarning(currentFile, yylineno, "Confused by pre-processor line directives");}voidPrefix::endOuterFile(){ if (current_->parent_) IdlWarning(currentFile, yylineno, "Confused by pre-processor line directives"); else delete current_;}const char*Prefix::get(){ return str_;}voidPrefix::set(const char* setTo){ char* str; delete [] str_; if (setTo[0] == '\0') { str = new char[1]; str[0] = '\0'; } else str = idl_strdup(setTo); str_ = str;}IDL_BooleanPrefix::isfile(){ return isfile_;}// Implementation of DeclRepoIdDeclRepoId::DeclRepoId(const char* identifier) : eidentifier_(idl_strdup(identifier)), prefix_(idl_strdup(Prefix::current())), set_(0), maj_(1), min_(0){ if (identifier[0] == '_') identifier_ = idl_strdup(++identifier); else identifier_ = eidentifier_; const ScopedName* psn = Scope::current()->scopedName(); if (psn) { scopedName_ = new ScopedName(psn); scopedName_->append(identifier); } else scopedName_ = new ScopedName(identifier, 1); genRepoId();}DeclRepoId::~DeclRepoId(){ if (identifier_ != eidentifier_) delete [] identifier_; delete [] eidentifier_; delete [] repoId_; delete [] prefix_; if (set_) delete [] rifile_;}voidDeclRepoId::setRepoId(const char* repoId, const char* file, int line){ if (set_) { if (strcmp(repoId, repoId_)) { IdlError(file, line, "Cannot set repository id of '%s' to '%s'", identifier_, repoId); IdlErrorCont(rifile_, riline_, "Repository id previously set to '%s' here", repoId_); } } else { delete [] repoId_; repoId_ = idl_strdup(repoId); set_ = 1; rifile_ = idl_strdup(file); riline_ = line; for (; *repoId && *repoId != ':'; ++repoId); if (*repoId == '\0') goto invalid; // If the repoId set is in OMG IDL format, we must figure out the // version number, so a future #pragma version can succeed if the // same version is given. Evil spec. if (!strncmp(repoId_, "IDL:", 4)) { const char* c; for (c=repoId_ + 4; *c && *c != ':'; ++c); if (*c++ == '\0') goto invalid; // c should now point to a string of the form maj.min if (sscanf(c, "%hd.%hd", &maj_, &min_) != 2) goto invalid; // Check there's no trailing garbage for (; *c && isdigit(*c); ++c); if (*c++ != '.') goto invalid; for (; *c && isdigit(*c); ++c); if (*c != '\0') goto invalid; } else { maj_ = -1; // Make sure a future #pragma version complains } } return; invalid: IdlWarning(file, line, "Repository id of '%s' set to invalid string '%s'", identifier_, repoId_); maj_ = -1;}voidDeclRepoId::setVersion(IDL_Short maj, IDL_Short min, const char* file, int line){ if (set_) { if (maj_ != maj || min_ != min) { IdlError(file, line, "Cannot set version of '%s' to '%d.%d'", identifier_, maj, min); IdlErrorCont(rifile_, riline_, "Repository id previously set to '%s' here", repoId_); } } else { delete [] repoId_; maj_ = maj; min_ = min; set_ = 1; rifile_ = idl_strdup(file); riline_ = line; genRepoId(); }}voidDeclRepoId::genRepoId(){ char* id; int len; // RepoId length = IDL: + prefix + "/" + identifier + : + maj + . + min + \0 len = 4 + strlen(prefix_) + 1 + strlen(identifier_) + 1 + 5 + 1 + 5 + 1; char* repoId = new char[len]; sprintf(repoId, "IDL:%s%s%s:%hd.%hd", prefix_, prefix_[0] == '\0' ? "" : "/", identifier_, maj_, min_); repoId_ = repoId;}// Static set functionsclass SetRepoIdVisitor : public AstVisitor {public: SetRepoIdVisitor(const char* repoId, const char* file, int line) : r_(repoId), f_(file), l_(line) {} virtual ~SetRepoIdVisitor() {} void visitModule (Module* d) { d->setRepoId(r_, f_, l_); } void visitInterface (Interface* d) { d->setRepoId(r_, f_, l_); } void visitForward (Forward* d) { d->setRepoId(r_, f_, l_); } void visitConst (Const* d) { d->setRepoId(r_, f_, l_); } void visitDeclarator (Declarator* d) { d->setRepoId(r_, f_, l_); } void visitStruct (Struct* d) { d->setRepoId(r_, f_, l_); } void visitException (Exception* d) { d->setRepoId(r_, f_, l_); } void visitUnion (Union* d) { d->setRepoId(r_, f_, l_); } void visitEnum (Enum* d) { d->setRepoId(r_, f_, l_); } void visitNative (Native* d) { d->setRepoId(r_, f_, l_); } void visitValueForward (ValueForward* d) { d->setRepoId(r_, f_, l_); } void visitValueBox (ValueBox* d) { d->setRepoId(r_, f_, l_); } void visitValueAbs (ValueAbs* d) { d->setRepoId(r_, f_, l_); } void visitValue (Value* d) { d->setRepoId(r_, f_, l_); } void visitMember (Member* d) { error(d); } void visitUnionCase (UnionCase* d) { error(d); } void visitEnumerator (Enumerator* d) { error(d); } void visitAttribute (Attribute* d) { error(d); } void visitOperation (Operation* d) { d->setRepoId(r_, f_, l_); } void visitStateMember (StateMember* d) { error(d); } void visitFactory (Factory* d) { error(d); }private: const char* r_; const char* f_; int l_; void error(Decl* d) { IdlError(f_, l_, "Cannot set repository id of %s", d->kindAsString()); }};voidDeclRepoId::setRepoId(Decl* d, const char* repoId, const char* file, int line){ SetRepoIdVisitor v(repoId, file, line); d->accept(v);}class SetVersionVisitor : public AstVisitor {public: SetVersionVisitor(IDL_Short maj, IDL_Short min, const char* file, int line) : a_(maj), i_(min), f_(file), l_(line) {} virtual ~SetVersionVisitor() {} void visitModule (Module* d) { d->setVersion(a_, i_, f_, l_); } void visitInterface (Interface* d) { d->setVersion(a_, i_, f_, l_); } void visitForward (Forward* d) { d->setVersion(a_, i_, f_, l_); } void visitConst (Const* d) { d->setVersion(a_, i_, f_, l_); } void visitDeclarator (Declarator* d) { d->setVersion(a_, i_, f_, l_); } void visitStruct (Struct* d) { d->setVersion(a_, i_, f_, l_); } void visitException (Exception* d) { d->setVersion(a_, i_, f_, l_); } void visitUnion (Union* d) { d->setVersion(a_, i_, f_, l_); } void visitEnum (Enum* d) { d->setVersion(a_, i_, f_, l_); } void visitNative (Native* d) { d->setVersion(a_, i_, f_, l_); } void visitValueForward (ValueForward* d) { d->setVersion(a_, i_, f_, l_); } void visitValueBox (ValueBox* d) { d->setVersion(a_, i_, f_, l_); } void visitValueAbs (ValueAbs* d) { d->setVersion(a_, i_, f_, l_); } void visitValue (Value* d) { d->setVersion(a_, i_, f_, l_); } void visitMember (Member* d) { error(d); } void visitUnionCase (UnionCase* d) { error(d); } void visitEnumerator (Enumerator* d) { error(d); } void visitAttribute (Attribute* d) { error(d); } void visitOperation (Operation* d) { d->setVersion(a_, i_, f_, l_); } void visitStateMember (StateMember* d) { error(d); } void visitFactory (Factory* d) { error(d); }private: IDL_Short a_; IDL_Short i_; const char* f_; int l_; void error(Decl* d) { IdlError(f_, l_, "Cannot set version of %s", d->kindAsString()); }};voidDeclRepoId::setVersion(Decl* d, IDL_Short maj, IDL_Short min, const char* file, int line){ SetVersionVisitor v(maj, min, file, line); d->accept(v);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?