//%2006//////////////////////////////////////////////////////////////////////// // // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.; // IBM Corp.; EMC Corporation, The Open Group. // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.; // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; // EMC Corporation; VERITAS Software Corporation; The Open Group. // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.; // EMC Corporation; Symantec Corporation; The Open Group. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // //%///////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include "cimmofMRR.h" #include "Closure.h" #define PEGASUS_LLD "%" PEGASUS_64BIT_CONVERSION_WIDTH "d" #define PEGASUS_LLU "%" PEGASUS_64BIT_CONVERSION_WIDTH "u" PEGASUS_USING_STD; PEGASUS_NAMESPACE_BEGIN #define PEGASUS_ARRAY_T CIMConstQualifier # include #undef PEGASUS_ARRAY_T //============================================================================== // // Local routines: // //============================================================================== static size_t _indent = 0; class Str { public: Str(const String& s) : _cstr(s.getCString()) { } Str(const CIMName& n) : _cstr(n.getString().getCString()) { } Str(const CIMNamespaceName& n) : _cstr(n.getString().getCString()) { } Str(const Exception& e) : _cstr(e.getMessage().getCString()) { } Str(const CIMDateTime& x) : _cstr(x.toString().getCString()) { } Str(const CIMObjectPath& x) : _cstr(x.toString().getCString()) { } const char* operator*() const { return (const char*)_cstr; } operator const char*() const { return (const char*)_cstr; } private: CString _cstr; }; static void _vout(FILE* os, const char* format, va_list ap) { for (size_t i = 0; i < _indent; i++) fprintf(os, " "); vfprintf(os, format, ap); } PEGASUS_FORMAT(2, 3) static void _throw(CIMStatusCode code, const char* format, ...) { char buffer[4096]; va_list ap; va_start(ap, format); vsprintf(buffer, format, ap); va_end(ap); throw CIMException(code, format); } static void _line(FILE* os) { fprintf(os, "//"); for (size_t i = 0; i < 78; i++) fputc('=', os); fputc('\n', os); } PEGASUS_FORMAT(2, 3) static void _box(FILE* os, const char* format, ...) { _line(os); fprintf(os, "//\n"); fprintf(os, "// "); va_list ap; va_start(ap, format); vfprintf(os, format, ap); va_end(ap); fputc('\n', os); fprintf(os, "//\n"); _line(os); } static void _writeHeaderFile(const String& ns) { const char format[] = "\n" "#ifndef _%s_namespace_h\n" "#define _%s_namespace_h\n" "\n" "#include \n" "\n" "PEGASUS_NAMESPACE_BEGIN\n" "\n" "extern const MRRNameSpace %s_namespace;\n" "\n" "PEGASUS_NAMESPACE_END\n" "\n" "#endif /* _%s_namespace_h */\n" ; String path = ns + "_namespace.h"; FILE* os = fopen(*Str(path), "wb"); if (!os) { fprintf(stderr, "cimmofl: failed to open \"%s\" for write\n", *Str(path)); exit(1); } _box(os, "CAUTION: THIS FILE WAS GENERATED BY CIMMOFL; " "PLEASE DO NOT EDIT IT."); fprintf(stderr, "\n"); fprintf(os, format, *Str(ns), *Str(ns), *Str(ns), *Str(ns)); fclose(os); } static String _makeIdent(const String& str) { // Build a legal C identifier from str. Translate all illegal characters // to underscores. String r; for (Uint32 i = 0; i < str.size(); i++) { Uint16 c = str[i]; if (c < 127 && (isalnum(c) || c == '_')) r.append(c); else r.append('_'); } return r; } static const char* _typeNames[] = { "CIMTYPE_BOOLEAN", "CIMTYPE_UINT8", "CIMTYPE_SINT8", "CIMTYPE_UINT16", "CIMTYPE_SINT16", "CIMTYPE_UINT32", "CIMTYPE_SINT32", "CIMTYPE_UINT64", "CIMTYPE_SINT64", "CIMTYPE_REAL32", "CIMTYPE_REAL64", "CIMTYPE_CHAR16", "CIMTYPE_STRING", "CIMTYPE_DATETIME", "CIMTYPE_REFERENCE", "CIMTYPE_OBJECT", "CIMTYPE_INSTANCE", }; static bool _is_printable(const char* s) { for (; *s; s++) { if (!isprint(*s)) return false; } return true; } template static void _writeFlags( FILE* os, const C& c, bool isProperty, bool isParameter) { // Build up flags mask: Uint32 flags = 0; if (isProperty) flags |= MRR_FLAG_READ; if (isParameter) flags |= MRR_FLAG_IN; for (Uint32 i = 0; i < c.getQualifierCount(); i++) { CIMConstQualifier cq = c.getQualifier(i); const CIMName& qn = cq.getName(); if (cq.getType() != CIMTYPE_BOOLEAN || cq.isArray()) continue; Boolean x; cq.getValue().get(x); if (System::strcasecmp(*Str(qn), "KEY") == 0) { if (x) flags |= MRR_FLAG_KEY; else flags &= ~MRR_FLAG_KEY; } else if (System::strcasecmp(*Str(qn), "IN") == 0) { if (x) flags |= MRR_FLAG_IN; else flags &= ~MRR_FLAG_IN; } else if (System::strcasecmp(*Str(qn), "OUT") == 0) { if (x) flags |= MRR_FLAG_OUT; else flags &= ~MRR_FLAG_OUT; } else if (System::strcasecmp(*Str(qn), "ABSTRACT") == 0) { if (x) flags |= MRR_FLAG_ABSTRACT; else flags &= ~MRR_FLAG_ABSTRACT; } else if (System::strcasecmp(*Str(qn), "AGGREGATE") == 0) { if (x) flags |= MRR_FLAG_AGGREGATE; else flags &= ~MRR_FLAG_AGGREGATE; } else if (System::strcasecmp(*Str(qn), "AGGREGATION") == 0) { if (x) flags |= MRR_FLAG_AGGREGATION; else flags &= ~MRR_FLAG_AGGREGATION; } else if (System::strcasecmp(*Str(qn), "COUNTER") == 0) { if (x) flags |= MRR_FLAG_COUNTER; else flags &= ~MRR_FLAG_COUNTER; } else if (System::strcasecmp(*Str(qn), "DELETE") == 0) { if (x) flags |= MRR_FLAG_DELETE; else flags &= ~MRR_FLAG_DELETE; } else if (System::strcasecmp(*Str(qn), "DN") == 0) { if (x) flags |= MRR_FLAG_DN; else flags &= ~MRR_FLAG_DN; } else if (System::strcasecmp(*Str(qn), "EMBEDDEDOBJECT") == 0) { if (x) flags |= MRR_FLAG_EMBEDDEDOBJECT; else flags &= ~MRR_FLAG_EMBEDDEDOBJECT; } else if (System::strcasecmp(*Str(qn), "EXPENSIVE") == 0) { if (x) flags |= MRR_FLAG_EXPENSIVE; else flags &= ~MRR_FLAG_EXPENSIVE; } else if (System::strcasecmp(*Str(qn), "EXPERIMENTAL") == 0) { if (x) flags |= MRR_FLAG_EXPERIMENTAL; else flags &= ~MRR_FLAG_EXPERIMENTAL; } else if (System::strcasecmp(*Str(qn), "GAUGE") == 0) { if (x) flags |= MRR_FLAG_GAUGE; else flags &= ~MRR_FLAG_GAUGE; } else if (System::strcasecmp(*Str(qn), "IFDELETED") == 0) { if (x) flags |= MRR_FLAG_IFDELETED; else flags &= ~MRR_FLAG_IFDELETED; } else if (System::strcasecmp(*Str(qn), "INVISIBLE") == 0) { if (x) flags |= MRR_FLAG_INVISIBLE; else flags &= ~MRR_FLAG_INVISIBLE; } else if (System::strcasecmp(*Str(qn), "LARGE") == 0) { if (x) flags |= MRR_FLAG_LARGE; else flags &= ~MRR_FLAG_LARGE; } else if (System::strcasecmp(*Str(qn), "OCTETSTRING") == 0) { if (x) flags |= MRR_FLAG_OCTETSTRING; else flags &= ~MRR_FLAG_OCTETSTRING; } else if (System::strcasecmp(*Str(qn), "READ") == 0) { if (x) flags |= MRR_FLAG_READ; else flags &= ~MRR_FLAG_READ; } else if (System::strcasecmp(*Str(qn), "REQUIRED") == 0) { if (x) flags |= MRR_FLAG_REQUIRED; else flags &= ~MRR_FLAG_REQUIRED; } else if (System::strcasecmp(*Str(qn), "STATIC") == 0) { if (x) flags |= MRR_FLAG_STATIC; else flags &= ~MRR_FLAG_STATIC; } else if (System::strcasecmp(*Str(qn), "TERMINAL") == 0) { if (x) flags |= MRR_FLAG_TERMINAL; else flags &= ~MRR_FLAG_TERMINAL; } else if (System::strcasecmp(*Str(qn), "WEAK") == 0) { if (x) flags |= MRR_FLAG_WEAK; else flags &= ~MRR_FLAG_WEAK; } else if (System::strcasecmp(*Str(qn), "WRITE") == 0) { if (x) flags |= MRR_FLAG_WRITE; else flags &= ~MRR_FLAG_WRITE; } else { // ATTN: Composition qualifier not handled (no more room in mask). } } // Write flags mask: if (flags & MRR_FLAG_KEY) fprintf(os, "|MRR_FLAG_KEY"); if (flags && (flags & MRR_FLAG_IN)) fprintf(os, "|MRR_FLAG_IN"); if (flags && (flags & MRR_FLAG_OUT)) fprintf(os, "|MRR_FLAG_OUT"); if (flags & MRR_FLAG_ABSTRACT) fprintf(os, "|MRR_FLAG_ABSTRACT"); if (flags & MRR_FLAG_AGGREGATE) fprintf(os, "|MRR_FLAG_AGGREGATE"); if (flags & MRR_FLAG_AGGREGATION) fprintf(os, "|MRR_FLAG_AGGREGATION"); if (flags & MRR_FLAG_COUNTER) fprintf(os, "|MRR_FLAG_COUNTER"); if (flags & MRR_FLAG_DELETE) fprintf(os, "|MRR_FLAG_DELETE"); if (flags & MRR_FLAG_DN) fprintf(os, "|MRR_FLAG_DN"); if (flags & MRR_FLAG_EMBEDDEDOBJECT) fprintf(os, "|MRR_FLAG_EMBEDDEDOBJECT"); if (flags & MRR_FLAG_EXPENSIVE) fprintf(os, "|MRR_FLAG_EXPENSIVE"); if (flags & MRR_FLAG_EXPERIMENTAL) fprintf(os, "|MRR_FLAG_EXPERIMENTAL"); if (flags & MRR_FLAG_GAUGE) fprintf(os, "|MRR_FLAG_GAUGE"); if (flags & MRR_FLAG_IFDELETED) fprintf(os, "|MRR_FLAG_IFDELETED"); if (flags & MRR_FLAG_INVISIBLE) fprintf(os, "|MRR_FLAG_INVISIBLE"); if (flags & MRR_FLAG_LARGE) fprintf(os, "|MRR_FLAG_LARGE"); if (flags & MRR_FLAG_OCTETSTRING) fprintf(os, "|MRR_FLAG_OCTETSTRING"); if (flags & MRR_FLAG_READ) fprintf(os, "|MRR_FLAG_READ"); if (flags & MRR_FLAG_REQUIRED) fprintf(os, "|MRR_FLAG_REQUIRED"); if (flags & MRR_FLAG_STATIC) fprintf(os, "|MRR_FLAG_STATIC"); if (flags & MRR_FLAG_TERMINAL) fprintf(os, "|MRR_FLAG_TERMINAL"); if (flags & MRR_FLAG_WEAK) fprintf(os, "|MRR_FLAG_WEAK"); if (flags & MRR_FLAG_WRITE) fprintf(os, "|MRR_FLAG_WRITE"); } static bool _testBooleanQualifier(const CIMClass& cc, const CIMName& name) { Uint32 pos = cc.findQualifier(name); if (pos == PEG_NOT_FOUND) return false; CIMConstQualifier cq = cc.getQualifier(pos); if (cq.getType() != CIMTYPE_BOOLEAN || cq.isArray()) return false; Boolean x; cq.getValue().get(x); return x; } static void _writeBoolean(FILE* os, Boolean x) { fprintf(os, "\\%03o", (int)x); } static void _writeUint8(FILE* os, Uint8 x) { fprintf(os, "\\%03o", (int)x); } static void _writeSint8(FILE* os, Sint8 x) { _writeUint8(os, Uint8(x)); } static void _writeUint16(FILE* os, Uint16 x) { Uint16 x0 = (x >> 8) & 0x00FF; Uint16 x1 = (x >> 0) & 0x00FF; fprintf(os, "\\%03o", (int)x0); fprintf(os, "\\%03o", (int)x1); } static void _writeSint16(FILE* os, Sint16 x) { _writeUint16(os, Uint16(x)); } static void _writeUint32(FILE* os, Uint32 x) { Uint32 x0 = (x >> 24) & 0x000000FF; Uint32 x1 = (x >> 16) & 0x000000FF; Uint32 x2 = (x >> 8) & 0x000000FF; Uint32 x3 = (x >> 0) & 0x000000FF; fprintf(os, "\\%03o", (int)x0); fprintf(os, "\\%03o", (int)x1); fprintf(os, "\\%03o", (int)x2); fprintf(os, "\\%03o", (int)x3); } static void _writeSint32(FILE* os, Sint32 x) { _writeUint32(os, Uint32(x)); } static void _writeUint64(FILE* os, Uint64 x) { Uint64 x0 = (x >> 56) & 0x00000000000000FF; Uint64 x1 = (x >> 48) & 0x00000000000000FF; Uint64 x2 = (x >> 40) & 0x00000000000000FF; Uint64 x3 = (x >> 32) & 0x00000000000000FF; Uint64 x4 = (x >> 24) & 0x00000000000000FF; Uint64 x5 = (x >> 16) & 0x00000000000000FF; Uint64 x6 = (x >> 8) & 0x00000000000000FF; Uint64 x7 = (x >> 0) & 0x00000000000000FF; fprintf(os, "\\%03o", (int)x0); fprintf(os, "\\%03o", (int)x1); fprintf(os, "\\%03o", (int)x2); fprintf(os, "\\%03o", (int)x3); fprintf(os, "\\%03o", (int)x4); fprintf(os, "\\%03o", (int)x5); fprintf(os, "\\%03o", (int)x6); fprintf(os, "\\%03o", (int)x7); } static void _writeSint64(FILE* os, Sint64 x) { _writeUint64(os, Uint64(x)); } static void _writeReal32(FILE* os, Real32 x) { _writeUint32(os, *((Uint32*)(void*)&x)); } static void _writeReal64(FILE* os, Real64 x) { _writeUint64(os, *((Uint64*)(void*)&x)); } static void _writeChar16(FILE* os, const Char16& x) { _writeUint16(os, x); } static void _writeString(FILE* os, const char* s) { size_t n = strlen(s); for (size_t i = 0; i < n; i++) { char c = s[i]; if (isprint(c) && c != '"') fprintf(os, "%c", c); else fprintf(os, "\\%03o", c); } } static void _writeString(FILE* os, const String& x) { _writeString(os, *Str(x)); } static void _writeDateTime(FILE* os, const CIMDateTime& x) { _writeString(os, x.toString()); } static int _writeValue(FILE* os, const CIMValue& cv, bool quote) { if (cv.isNull()) { fprintf(os, "0"); return 0; } if (quote) fputc('"', os); if (cv.isArray()) { switch (cv.getType()) { case CIMTYPE_BOOLEAN: { Array x; cv.get(x); _writeUint16(os, x.size()); for (Uint32 i = 0; i < x.size(); i++) _writeBoolean(os, x[i]); break; } case CIMTYPE_UINT8: { Array x; cv.get(x); _writeUint16(os, x.size()); for (Uint32 i = 0; i < x.size(); i++) _writeUint8(os, x[i]); break; } case CIMTYPE_SINT8: { Array x; cv.get(x); _writeUint16(os, x.size()); for (Uint32 i = 0; i < x.size(); i++) _writeSint8(os, x[i]); break; } case CIMTYPE_UINT16: { Array x; cv.get(x); _writeUint16(os, x.size()); for (Uint32 i = 0; i < x.size(); i++) _writeUint16(os, x[i]); break; } case CIMTYPE_SINT16: { Array x; cv.get(x); _writeUint16(os, x.size()); for (Uint32 i = 0; i < x.size(); i++) _writeSint16(os, x[i]); break; } case CIMTYPE_UINT32: { Array x; cv.get(x); _writeUint16(os, x.size()); for (Uint32 i = 0; i < x.size(); i++) _writeUint32(os, x[i]); break; } case CIMTYPE_SINT32: { Array x; cv.get(x); _writeUint16(os, x.size()); for (Uint32 i = 0; i < x.size(); i++) _writeSint32(os, x[i]); break; } case CIMTYPE_UINT64: { Array x; cv.get(x); _writeUint16(os, x.size()); for (Uint32 i = 0; i < x.size(); i++) _writeUint64(os, x[i]); break; } case CIMTYPE_SINT64: { Array x; cv.get(x); _writeUint16(os, x.size()); for (Uint32 i = 0; i < x.size(); i++) _writeSint64(os, x[i]); break; } case CIMTYPE_REAL32: { Array x; cv.get(x); _writeUint16(os, x.size()); for (Uint32 i = 0; i < x.size(); i++) _writeReal32(os, x[i]); break; } case CIMTYPE_REAL64: { Array x; cv.get(x); _writeUint16(os, x.size()); for (Uint32 i = 0; i < x.size(); i++) _writeReal64(os, x[i]); break; } case CIMTYPE_CHAR16: { Array x; cv.get(x); _writeUint16(os, x.size()); for (Uint32 i = 0; i < x.size(); i++) _writeChar16(os, x[i]); break; } case CIMTYPE_STRING: { Array x; cv.get(x); _writeUint16(os, x.size()); for (Uint32 i = 0; i < x.size(); i++) { _writeString(os, x[i]); _writeUint8(os, 0); } break; } case CIMTYPE_DATETIME: { Array x; cv.get(x); _writeUint16(os, x.size()); for (Uint32 i = 0; i < x.size(); i++) _writeDateTime(os, x[i]); break; } default: return -1; } } else { switch (cv.getType()) { case CIMTYPE_BOOLEAN: { Boolean x; cv.get(x); _writeBoolean(os, x); break; } case CIMTYPE_UINT8: { Uint8 x; cv.get(x); _writeUint8(os, x); break; } case CIMTYPE_SINT8: { Sint8 x; cv.get(x); _writeSint8(os, x); break; } case CIMTYPE_UINT16: { Uint16 x; cv.get(x); _writeUint16(os, x); break; } case CIMTYPE_SINT16: { Sint16 x; cv.get(x); _writeSint16(os, x); break; } case CIMTYPE_UINT32: { Uint32 x; cv.get(x); _writeUint32(os, x); break; } case CIMTYPE_SINT32: { Sint32 x; cv.get(x); _writeSint32(os, x); break; } case CIMTYPE_UINT64: { Uint64 x; cv.get(x); _writeUint64(os, x); break; } case CIMTYPE_SINT64: { Sint64 x; cv.get(x); _writeSint64(os, x); break; } case CIMTYPE_REAL32: { Real32 x; cv.get(x); _writeReal32(os, x); break; } case CIMTYPE_REAL64: { Real64 x; cv.get(x); _writeReal64(os, x); break; } case CIMTYPE_CHAR16: { Char16 x; cv.get(x); _writeChar16(os, x); break; } case CIMTYPE_STRING: { String x; cv.get(x); _writeString(os, x); break; } case CIMTYPE_DATETIME: { CIMDateTime x; cv.get(x); _writeDateTime(os, x); break; } default: return -1; } } if (quote) fputc('"', os); return 0; } //============================================================================== // // cimmofMRR // //============================================================================== cimmofMRR::cimmofMRR(bool discard) : _discard(discard), _os(0) { } cimmofMRR::~cimmofMRR() { } void cimmofMRR::addClass( const CIMNamespaceName& nameSpace, CIMClass& cimClass) { if (_findClass(cimClass.getClassName()) != PEG_NOT_FOUND) { _throw(CIM_ERR_ALREADY_EXISTS, "class already defined: %s:%s", *Str(nameSpace), *Str(cimClass.getClassName())); } _classes.append(cimClass); } void cimmofMRR::addQualifier( const CIMNamespaceName& nameSpace, CIMQualifierDecl& cimQualifierDecl) { if (_findQualifier(cimQualifierDecl.getName()) != PEG_NOT_FOUND) { _throw(CIM_ERR_ALREADY_EXISTS, "qualifier already defined: %s:%s", *Str(nameSpace), *Str(cimQualifierDecl.getName())); } _qualifiers.append(cimQualifierDecl); } void cimmofMRR::addInstance( const CIMNamespaceName& nameSpace, CIMInstance& instance) { const CIMObjectPath& cop = instance.getPath(); for (Uint32 i = 0; i < _instances.size(); i++) { if (_instances[i].getPath() == cop) { _throw(CIM_ERR_ALREADY_EXISTS, "instances already exists: %s", *Str(cop)); } } _instances.append(instance); } CIMQualifierDecl cimmofMRR::getQualifierDecl( const CIMNamespaceName& nameSpace, const CIMName& qualifierName) { Uint32 pos = _findQualifier(qualifierName); if (pos == PEG_NOT_FOUND) { _throw(CIM_ERR_NOT_FOUND, "undefined qualifier: %s:%s", *Str(nameSpace), *Str(qualifierName)); } return _qualifiers[pos]; } CIMClass cimmofMRR::getClass( const CIMNamespaceName& nameSpace, const CIMName& className) { Uint32 pos = _findClass(className); if (pos == PEG_NOT_FOUND) { _throw(CIM_ERR_NOT_FOUND, "undefined class: %s:%s", *Str(nameSpace), *Str(className)); } return _classes[pos]; } void cimmofMRR::modifyClass( const CIMNamespaceName& nameSpace, CIMClass& cimClass) { Uint32 pos = _findClass(cimClass.getClassName()); if (pos == PEG_NOT_FOUND) { _throw(CIM_ERR_NOT_FOUND, "undefined class: %s:%s", *Str(nameSpace), *Str(cimClass.getClassName())); } _classes[pos] = cimClass; } void cimmofMRR::createNameSpace( const CIMNamespaceName& nameSpace) { if (_nameSpace == nameSpace) { _throw(CIM_ERR_ALREADY_EXISTS, "namespace already exists: %s", *Str(nameSpace)); } if (!_nameSpace.isNull()) { _throw(CIM_ERR_FAILED, "cannot create more than one namespace"); } _nameSpace = nameSpace; } void cimmofMRR::start() { } void cimmofMRR::_loadClassFile( Array& classes, const String& path) { classes.clear(); // Open class file: FILE* is = fopen(*Str(path), "r"); if (!is) return; char buffer[1024]; for (int line = 1; fgets(buffer, sizeof(buffer), is) != NULL; line++) { if (buffer[0] == '#') continue; char* start = buffer; // Remove leading whitespace. while (isspace(*start)) start++; // Remove trailing whitespace. char* p = start; while (*p) p++; while (p != start && isspace(p[-1])) *--p = '\0'; // Skip empty lines. if (*start == '\0') continue; // Skip comment lines: if (*start == '#') continue; /* Check whether legal class name. */ if (_findClass(start) == PEG_NOT_FOUND) { fprintf(stderr, "cimmofl: unknown class on line %d of %s: \"%s\"\n", line, *Str(path), start); exit(1); } /* Append class to list. */ bool found = false; for (Uint32 i = 0; i < classes.size(); i++) { if (classes[i] == start) { found = true; break; } } if (!found) classes.append(start); } fclose(is); } void cimmofMRR::finish() { String ns = _makeIdent(_nameSpace.getString()); // Open classes file, if any. Array classNames; String classFile = ns + "_namespace.classes"; _loadClassFile(classNames, classFile); // Find closure of select classes: _closure.clear(); if (classNames.size()) { printf("Using %s to reduce class list\n", *Str(classFile)); // Find closure of classes from class file: for (Uint32 i = 0; i < classNames.size(); i++) { const CIMName& cn = classNames[i]; if (Closure(cn, _classes, _closure) != 0) { printf("cimmofl: failed to calculate closure for class %s\n", *Str(cn)); } } // Find closure of classes referred to by instances: for (Uint32 i = 0; i < _instances.size(); i++) { const CIMInstance& ci = _instances[i]; const CIMName& cn = ci.getClassName(); if (Closure(cn, _classes, _closure) != 0) { printf("cimmofl: failed to calculate closure for class %s\n", *Str(cn)); } } } // Write header file: _writeHeaderFile(ns); // Open source file: String path = ns + "_namespace.cpp"; _os = fopen(*Str(path), "wb"); if (!_os) { fprintf(stderr, "cimmofl: failed to open \"%s\" for write\n", *Str(path)); exit(1); } // Write prologue: _writeMetaPrologue(); // Write namespace: _writeNameSpace(_nameSpace); // Write epilogue: _writeMetaEpilogue(); // Close file: fclose(_os); // Write instances file (if any instances encountered). if (_instances.size()) { // Serialize all instances into a buffer: Buffer out; for (Uint32 i = 0; i < _instances.size(); i++) { MRRSerializeNameSpace(out, _nameSpace); MRRSerializeInstance(out, _instances[i]); } // Open instances output file: String path = ns + "_namespace.mrr"; FILE* os = fopen(*Str(path), "wb"); if (!os) { fprintf(stderr, "cimmofl: failed to open \"%s\" for write\n", *Str(path)); exit(1); } // Write instances to a file. if (fwrite(out.getData(), 1, out.size(), os) != out.size()) { fprintf(stderr, "cimmofl: failed to write to \"%s\"\n", *Str(path)); exit(1); } // Close output file: fclose(os); } // Write messages: printf("Created %s_namespace.h\n", *Str(ns)); printf("Created %s_namespace.cpp\n", *Str(ns)); if (_instances.size()) printf("Created %s_namespace.mrr\n", *Str(ns)); printf("\n"); } Uint32 cimmofMRR::_findClass(const CIMName& className) const { for (Uint32 i = 0; i < _classes.size(); i++) { if (_classes[i].getClassName() == className) return i; } // Not found! return PEG_NOT_FOUND; } Uint32 cimmofMRR::_findQualifier(const CIMName& qualifierName) const { for (Uint32 i = 0; i < _qualifiers.size(); i++) { if (_qualifiers[i].getName() == qualifierName) return i; } // Not found! return PEG_NOT_FOUND; } void cimmofMRR::_writeMetaPrologue() { String ns = _makeIdent(_nameSpace.getString()); String path = ns + "_namespace.h"; _box(_os, "CAUTION: THIS FILE WAS GENERATED BY CIMMOFL; " "PLEASE DO NOT EDIT IT."); _nl(); _outn("#include \"%s\"", *Str(path)); _nl(); _outn("/*NOCHKSRC*/"); _nl(); _outn("PEGASUS_NAMESPACE_BEGIN"); _nl(); } void cimmofMRR::_writeMetaEpilogue() { _outn("PEGASUS_NAMESPACE_END"); } void cimmofMRR::_writeQualifier( const Array& qualifierDecls, const CIMConstQualifier& cq) { CIMName qn = cq.getName(); CIMType qt = cq.getType(); CIMValue qv = cq.getValue(); Uint32 pos = _findQualifier(qn); if (pos == PEG_NOT_FOUND) _throw(CIM_ERR_FAILED, "undefined qualifier: %s", *Str(qn)); // Write the qualifier string literal: _outn(" /* %s */", *Str(qn)); _out(" (char*)\""); _writeUint8(_os, pos); _writeValue(_os, qv, false); _outn("\","); } void cimmofMRR::_writeQualifierDecl(const CIMConstQualifierDecl& cq) { CIMName qn = cq.getName(); CIMType qt = cq.getType(); const CIMValue& cv = cq.getValue(); // Write value definition (if any). String path = "_" + qn.getString() + "_qualifier_decl"; // Write MRRQualifierDecl header: _outn("static MRRQualifierDecl"); _outn("%s =", *Str(path)); _outn("{"); // MRRQualifierDecl.name: _outn(" /* name */"); _outn(" (char*)\"%s\",", *Str(qn)); // MRRQualifierDecl.type: _outn(" /* type */"); _outn(" %s,", _typeNames[qt]); // MRRQualifierDecl.subscript: _outn(" /* subscript */"); if (cq.isArray()) { Uint32 n = cq.getArraySize(); _outn(" %u,", n); } else { _outn(" -1,"); } // MRRQualifierDecl.scope: { _outn(" /* scope */"); CIMScope scope = cq.getScope(); Array scopes; if (scope.hasScope(CIMScope::ANY)) scopes.append("MRR_SCOPE_ANY"); else { if (scope.hasScope(CIMScope::CLASS)) scopes.append("MRR_SCOPE_CLASS"); if (scope.hasScope(CIMScope::ASSOCIATION)) scopes.append("MRR_SCOPE_ASSOCIATION"); if (scope.hasScope(CIMScope::INDICATION)) scopes.append("MRR_SCOPE_INDICATION"); if (scope.hasScope(CIMScope::PROPERTY)) scopes.append("MRR_SCOPE_PROPERTY"); if (scope.hasScope(CIMScope::REFERENCE)) scopes.append("MRR_SCOPE_REFERENCE"); if (scope.hasScope(CIMScope::METHOD)) scopes.append("MRR_SCOPE_METHOD"); if (scope.hasScope(CIMScope::PARAMETER)) scopes.append("MRR_SCOPE_PARAMETER"); } _out(" "); for (Uint32 i = 0; i < scopes.size(); i++) { _out("%s", *Str(scopes[i])); if (i + 1 != scopes.size()) _out("|"); } _outn(","); } // MRRQualifierDecl.flavor: { _outn(" /* flavor */"); CIMFlavor flavor = cq.getFlavor(); Array flavors; if (flavor.hasFlavor(CIMFlavor::OVERRIDABLE)) flavors.append("MRR_FLAVOR_OVERRIDABLE"); if (flavor.hasFlavor(CIMFlavor::TOSUBCLASS)) flavors.append("MRR_FLAVOR_TOSUBCLASS"); if (flavor.hasFlavor(CIMFlavor::TOINSTANCE)) flavors.append("MRR_FLAVOR_TOINSTANCE"); if (flavor.hasFlavor(CIMFlavor::TRANSLATABLE)) flavors.append("MRR_FLAVOR_TRANSLATABLE"); if (flavor.hasFlavor(CIMFlavor::DISABLEOVERRIDE)) flavors.append("MRR_FLAVOR_DISABLEOVERRIDE"); if (flavor.hasFlavor(CIMFlavor::RESTRICTED)) flavors.append("MRR_FLAVOR_RESTRICTED"); _out(" "); for (Uint32 i = 0; i < flavors.size(); i++) { _out("%s", *Str(flavors[i])); if (i + 1 != flavors.size()) _out("|"); } _outn(","); } // MRRQualifierDecl.value: _outn(" /* value */"); _out(" "); _writeValue(_os, cv, true); _outn(","); _outn("};"); _nl(); } template Array _Qualifiers(const C& c) { Array tmp; for (Uint32 i = 0; i < c.getQualifierCount(); i++) tmp.append(c.getQualifier(i)); return tmp; } void cimmofMRR::_writeQualifierArray( const String& root, const Array& qualifiers) { _outn("static const char*"); _outn("%s_qualifiers[] =", *Str(root)); _outn("{"); for (Uint32 i = 0; i < qualifiers.size(); i++) { CIMConstQualifier cq = qualifiers[i]; CIMName qn = cq.getName(); CIMType qt = cq.getType(); if (_discard && qn == "Description") continue; #if 0 if (qt == CIMTYPE_BOOLEAN && !cq.isArray()) continue; #endif _writeQualifier(_qualifiers, cq); } // Write terminator: _outn(" 0,"); _outn("};"); _nl(); } void cimmofMRR::_writeProperty( const CIMNamespaceName& nameSpace, const CIMName& cn, const CIMConstProperty& cp) { String ns = _makeIdent(nameSpace.getString()); CIMName pn = cp.getName(); CIMType ct = cp.getType(); CIMValue cv = cp.getValue(); String path = "_" + cn.getString() + "_" + pn.getString(); // Write qualifiers: _writeQualifierArray(path, _Qualifiers(cp)); // Header: if (ct == CIMTYPE_REFERENCE) _outn("static MRRReference"); else _outn("static MRRProperty"); _outn("%s =", *Str(path)); _outn("{"); // MRRProperty.flags: _outn(" /* flags */"); if (ct == CIMTYPE_REFERENCE) _out(" MRR_FLAG_REFERENCE"); else _out(" MRR_FLAG_PROPERTY"); _writeFlags(_os, cp, true, false); fprintf(_os, ",\n"); // MRRProperty.name: _outn(" /* name */"); _outn(" (char*)\"%s\",", *Str(pn)); // MRRProperty.qualifiers: _outn(" /* qualifiers */"); _outn(" %s_qualifiers,", *Str(path)); // MRRProperty.type: if (ct != CIMTYPE_REFERENCE) { _outn(" /* type */"); _outn(" %s,", _typeNames[ct]); } // MRRProperty.subscript: _outn(" /* subscript */"); if (cp.isArray()) { Uint32 n = cp.getArraySize(); _outn(" %u,", n); } else { _outn(" -1,"); } // MRRReference.ref: if (ct == CIMTYPE_REFERENCE) { const CIMName& rcn = cp.getReferenceClassName(); _outn(" /* refId */"); _outn(" &__%s_%s,", *Str(ns), *Str(rcn)); } // MRRQualifierDecl.value: if (ct != CIMTYPE_REFERENCE) { _outn(" /* value */"); _out(" "); _writeValue(_os, cv, true); _outn(","); } _outn("};"); _nl(); } void cimmofMRR::_writeParameter( const CIMNamespaceName& nameSpace, const CIMName& cn, const CIMName& mn, const CIMConstParameter& cp) { String ns = _makeIdent(nameSpace.getString()); CIMName pn = cp.getName(); CIMType ct = cp.getType(); String path = "_" + cn.getString() + "_" + mn.getString() + "_" + pn.getString(); _writeQualifierArray(path, _Qualifiers(cp)); if (ct == CIMTYPE_REFERENCE) _outn("static MRRReference"); else _outn("static MRRProperty"); _outn("%s =", *Str(path)); _outn("{"); // MRRProperty.flags: _outn(" /* flags */"); if (ct == CIMTYPE_REFERENCE) _out(" MRR_FLAG_REFERENCE"); else _out(" MRR_FLAG_PROPERTY"); _writeFlags(_os, cp, false, true); fprintf(_os, ",\n"); // MRRProperty.name: _outn(" /* name */"); _outn(" (char*)\"%s\",", *Str(pn)); // MRRProperty.qualifiers: _outn(" /* qualifiers */"); _outn(" %s_qualifiers,", *Str(path)); // MRRProperty.type: if (ct != CIMTYPE_REFERENCE) { _outn(" /* type */"); _outn(" %s,", _typeNames[ct]); } // MRRProperty.subscript: _outn(" /* subscript */"); if (cp.isArray()) { Uint32 n = cp.getArraySize(); _outn(" %u,", n); } else { _outn(" -1,"); } // MRRProperty.ref: if (ct == CIMTYPE_REFERENCE) { const CIMName& rcn = cp.getReferenceClassName(); _outn(" /* ref */"); _outn(" &__%s_%s,", *Str(ns), *Str(rcn)); } // MRRQualifierDecl.value: if (ct != CIMTYPE_REFERENCE) { _outn(" /* value */"); _outn(" 0,"); } _outn("};"); _nl(); } void cimmofMRR::_writeMethod( const CIMNamespaceName& nameSpace, const CIMName& cn, const CIMConstMethod& cm) { CIMName mn = cm.getName(); // Write parameter definitions: Array parameterNames; for (Uint32 i = 0; i < cm.getParameterCount(); i++) { CIMConstParameter cp = cm.getParameter(i); _writeParameter(nameSpace, cn, mn, cp); parameterNames.append(cp.getName()); } // Write parameters array: _outn("static MRRFeature*"); _outn("_%s_%s_parameters[] =", *Str(cn), *Str(mn)); _outn("{"); for (Uint32 i = 0; i < parameterNames.size(); i++) { const CIMName& pn = parameterNames[i]; _outn(" (MRRFeature*)&_%s_%s_%s,", *Str(cn), *Str(mn), *Str(pn)); } _outn(" 0,"); _outn("};"); _nl(); // Method header: String path = "_" + cn.getString() + "_" + mn.getString(); _writeQualifierArray(path, _Qualifiers(cm)); _outn("static MRRMethod"); _outn("%s =", *Str(path)); _outn("{"); // MRRMethod.flags: _outn(" /* flags */"); _out(" MRR_FLAG_METHOD"); _writeFlags(_os, cm, false, false); fprintf(_os, ",\n"); // MRRMethod.name: _outn(" /* name */"); _outn(" (char*)\"%s\",", *Str(mn)); // MRRMethod.qualifiers: _outn(" /* qualifiers */"); _outn(" %s_qualifiers,", *Str(path)); // MRRProperty.type: _outn(" /* type */"); _outn(" %s,", _typeNames[cm.getType()]); // MRRMethod.parameters: _outn(" /* parameters */"); _outn(" _%s_%s_parameters,", *Str(cn), *Str(mn)); // Method footer: _outn("};"); _nl(); } void cimmofMRR::_writeClass( const CIMNamespaceName& nameSpace, const CIMClass& cc) { String ns = _makeIdent(nameSpace.getString()); CIMName cn = cc.getClassName(); // Write comment: _box(_os, "Class: %s", *Str(cn)); _nl(); // Write property definitions: Array featureNames; for (Uint32 i = 0; i < cc.getPropertyCount(); i++) { CIMConstProperty cp = cc.getProperty(i); _writeProperty(nameSpace, cc.getClassName(), cp); featureNames.append(cp.getName()); } // Write method definitions: for (Uint32 i = 0; i < cc.getMethodCount(); i++) { CIMConstMethod cm = cc.getMethod(i); _writeMethod(nameSpace, cc.getClassName(), cm); featureNames.append(cm.getName()); } // Write feature array: _outn("static MRRFeature*"); _outn("_%s_features[] =", *Str(cn)); _outn("{"); for (Uint32 i = 0; i < featureNames.size(); i++) { const CIMName& fn = featureNames[i]; _outn(" (MRRFeature*)&_%s_%s,", *Str(cn), *Str(fn)); } _outn(" 0,"); _outn("};"); _nl(); // Class header: String path = "__" + ns + "_" + cn.getString(); _writeQualifierArray(path, _Qualifiers(cc)); _outn("MRRClass"); _outn("%s =", *Str(path)); _outn("{"); // MRRClass.flags: _outn(" /* flags */"); if (_testBooleanQualifier(cc, "Association")) _out(" MRR_FLAG_ASSOCIATION"); else if (_testBooleanQualifier(cc, "Indication")) _out(" MRR_FLAG_INDICATION"); else _out(" MRR_FLAG_CLASS"); _writeFlags(_os, cc, false, false); fprintf(_os, ",\n"); // MRRClass.name: _outn(" /* name */"); _outn(" (char*)\"%s\",", *Str(cn)); // MRRClass.qualifiers: _outn(" /* qualifiers */"); _outn(" %s_qualifiers,", *Str(path)); // MRRClass.super: const CIMName& scn = cc.getSuperClassName(); _outn(" /* super */"); if (scn.isNull()) _outn(" 0,"); else _outn(" &__%s_%s,", *Str(ns), *Str(scn)); // MRRClass.features: _outn(" /* features */"); _outn(" _%s_features,", *Str(cn)); // Class footer: _outn("};"); _nl(); } void cimmofMRR::_writeNameSpace(const CIMNamespaceName& nameSpace) { String ns = _makeIdent(nameSpace.getString()); // Write qualifiers: _box(_os, "Qualifiers"); _nl(); for (Uint32 i = 0; i < _qualifiers.size(); i++) { _writeQualifierDecl(_qualifiers[i]); } // Forward declare all classes: _box(_os, "Forward class declarations"); _nl(); for (Uint32 i = 0; i < _classes.size(); i++) { CIMName cn = _classes[i].getClassName(); if (_includeClass(cn)) _outn("extern MRRClass __%s_%s;", *Str(ns), *Str(cn)); } _nl(); // Write classes: for (Uint32 i = 0; i < _classes.size(); i++) { CIMName cn = _classes[i].getClassName(); if (_includeClass(cn)) _writeClass(nameSpace, _classes[i]); } // Write qualifiers list: _box(_os, "Qualifier array"); _nl(); _outn("static MRRQualifierDecl*"); _outn("_qualifiers[] ="); _outn("{"); _indent++; for (Uint32 i = 0; i < _qualifiers.size(); i++) { _outn("&_%s_qualifier_decl,", *Str(_qualifiers[i].getName())); } _outn("0,"); _indent--; _outn("};"); _nl(); // Write classes list: _box(_os, "Class array"); _nl(); _outn("static MRRClass*"); _outn("_classes[] ="); _outn("{"); _indent++; for (Uint32 i = 0; i < _classes.size(); i++) { CIMName cn = _classes[i].getClassName(); if (_includeClass(cn)) _outn("&__%s_%s,", *Str(ns), *Str(cn)); } _outn("0,"); _indent--; _outn("};"); _nl(); // Write MRRNameSpace structure: _outn("const MRRNameSpace %s_namespace =", *Str(ns)); _outn("{"); _outn(" (char*)\"%s\",", *Str(nameSpace)); _outn(" _qualifiers,"); _outn(" _classes,"); _outn("};"); _nl(); } PEGASUS_FORMAT(2, 3) void cimmofMRR::_out(const char* format, ...) { va_list ap; va_start(ap, format); _vout(_os, format, ap); va_end(ap); } PEGASUS_FORMAT(2, 3) void cimmofMRR::_outn(const char* format, ...) { va_list ap; va_start(ap, format); _vout(_os, format, ap); va_end(ap); fputc('\n', _os); } void cimmofMRR::_nl() { _out("\n"); } bool cimmofMRR::_includeClass(const CIMName& cn) { if (_closure.size() == 0) return true; for (Uint32 i = 0; i < _closure.size(); i++) { if (_closure[i] == cn) return true; } return false; } PEGASUS_NAMESPACE_END