in Unix/gen/gen.cpp [2925:3250]
static void GenClassHeader(
Parser& parser,
const MI_ClassDecl* cd,
set<string>& classIdentifiers)
{
const string alias = AliasOf(cd->name);
// Refuse to generate same class more than once.
if (generated_headers.find(cd->name) != generated_headers.end())
return;
generated_headers.insert(cd->name);
// Find direct dependencies of this class.
vector<string> deps;
FindDirectDependencies(cd, deps);
// Recurse on dependencies.
for (size_t i = 0; i < deps.size(); i++)
{
const MI_ClassDecl* tcd = parser.findClassDecl(deps[i].c_str());
if (!tcd)
err(ID_UNKNOWN_CLASS, "unknown class: %s", deps[i].c_str());
GenClassHeader(parser, tcd, classIdentifiers);
}
// Open class header file.
string path = ExpandPath(alias + ".h");
Fprintf(s_stdout, ID_CREATING, "Creating %s\n", path.c_str());
FILE* os = File_Open(path.c_str(), "w");
if (!os)
err(ID_FAILED_TO_OPEN_FILE, "failed to open file: %s", path.c_str());
GenStatikGenLine(os);
// Put comment header.
PutCommentBox(os, WARNING);
// Prevent multiple inclusion.
putl(os, "#ifndef _%s_h", alias.c_str());
putl(os, "#define _%s_h", alias.c_str());
nl(os);
// Include <MI.h>
putl(os, "#include <MI.h>");
// Generate includes for direct dependencies.
for (size_t i = 0; i < deps.size(); i++)
{
string al = AliasOf(deps[i]);
putl(os, "#include \"%s.h\"", al.c_str());
}
nl(os);
// Put comment box for the class structure. List the key names for this
// class.
{
putl(os, "/*");
PutRule(os);
putl(os, "**");
putl(os, "** %s [%s]", alias.c_str(), cd->name);
putl(os, "**");
putl(os, "** Keys:");
for (size_t i = 0; i < cd->numProperties; i++)
{
const MI_PropertyDecl* pd = cd->properties[i];
if (pd->flags & MI_FLAG_KEY)
putl(os, "** %s", pd->name);
}
putl(os, "**");
PutRule(os);
putl(os, "*/");
nl(os);
}
// Put class structure definition with all its properties.
if (cd->superClass)
{
putl(os, "typedef struct _%s /* extends %s */",
alias.c_str(), cd->superClass);
}
else
{
putl(os, "typedef struct _%s", alias.c_str());
}
putl(os, "{");
putl(os, " MI_Instance __instance;");
NameClassMap map;
GenProperties(os, parser, cd, cd, map);
putl(os, "}");
putl(os, "%s;", alias.c_str());
nl(os);
// Generate a reference of this type (if not an association or indication).
#if 0
if (!(cd->flags & MI_FLAG_ASSOCIATION || cd->flags & MI_FLAG_INDICATION))
#endif
// Associations can be used as endpoints in other associations.
{
{
const char T[] =
"typedef struct _<ALIAS>_Ref\n"
"{\n"
" <ALIAS>* value;\n"
" MI_Boolean exists;\n"
" MI_Uint8 flags;\n"
"}\n"
"<ALIAS>_Ref;\n"
"\n"
"typedef struct _<ALIAS>_ConstRef\n"
"{\n"
" MI_CONST <ALIAS>* value;\n"
" MI_Boolean exists;\n"
" MI_Uint8 flags;\n"
"}\n"
"<ALIAS>_ConstRef;\n"
"\n";
string r = sub(T, "<ALIAS>", alias);
puts(os, r);
}
{
const char T[] =
"typedef struct _<ALIAS>_Array\n"
"{\n"
" struct _<ALIAS>** data;\n"
" MI_Uint32 size;\n"
"}\n"
"<ALIAS>_Array;\n"
"\n"
"typedef struct _<ALIAS>_ConstArray\n"
"{\n"
" struct _<ALIAS> MI_CONST* MI_CONST* data;\n"
" MI_Uint32 size;\n"
"}\n"
"<ALIAS>_ConstArray;\n"
"\n"
"typedef struct _<ALIAS>_ArrayRef\n"
"{\n"
" <ALIAS>_Array value;\n"
" MI_Boolean exists;\n"
" MI_Uint8 flags;\n"
"}\n"
"<ALIAS>_ArrayRef;\n"
"\n"
"typedef struct _<ALIAS>_ConstArrayRef\n"
"{\n"
" <ALIAS>_ConstArray value;\n"
" MI_Boolean exists;\n"
" MI_Uint8 flags;\n"
"}\n"
"<ALIAS>_ConstArrayRef;\n"
"\n";
string r = sub(T, "<ALIAS>", alias);
puts(os, r);
}
}
// Generate an external reference to the class RTTI instance.
if (s_options.cpp || !s_options.noProviders)
{
putl(os, "MI_EXTERN_C MI_CONST MI_ClassDecl %s_rtti;", alias.c_str());
nl(os);
}
// Generate Instance function
if (!s_options.noProviders)
GenInstanceFunctions(os,cd);
// Gen setters.
{
for (size_t i = 0; i < cd->numProperties; i++)
GenSetter(os, cd, NULL, (MI_ParameterDecl*)cd->properties[i]);
}
// Put method definitions and setters for each method parameter.
for (size_t i = 0; i < cd->numMethods; i++)
{
const MI_MethodDecl* md = cd->methods[i];
GenParametersStruct(os, cd, md);
// Generate convenience functions.
if (!s_options.noProviders)
{
if (Strcasecmp(cd->name, md->propagator) == 0 ||
providerClasses.find(cd->name) != providerClasses.end())
{
GenMethodFunctions(os, cd, md);
}
}
// Generate parameter setter for "MIReturn".
if (!s_options.noProviders)
{
MI_ParameterDecl pd;
memset(&pd, 0, sizeof(pd));
pd.flags = MI_FLAG_PARAMETER|MI_FLAG_OUT;
pd.name = (char*)"MIReturn";
pd.type = md->returnType;
pd.offset = sizeof(MI_Instance);
pd.numQualifiers = md->numQualifiers;
pd.qualifiers = md->qualifiers;
GenSetter(os, cd, md, &pd);
}
if (!s_options.noProviders)
{
for (size_t j = 0; j < md->numParameters; j++)
{
const MI_ParameterDecl* pd = md->parameters[j];
// Skip stream parameters:
if (pd->flags & MI_FLAG_STREAM)
continue;
GenSetter(os, cd, md, pd);
}
}
}
if (providerClasses.find(cd->name) != providerClasses.end())
{
// Write the intrinsic provider function prototypes.
if (!s_options.noProviders)
{
PutCommentBox(os, alias + " provider function prototypes");
nl(os);
// Generate forward typedef for Self structure.
putl(os,"/* The developer may optionally define this structure */");
putl(os, "typedef struct _%s_Self %s_Self;\n",
alias.c_str(), alias.c_str());
if (cd->flags & MI_FLAG_ASSOCIATION)
{
string r;
if (CanGenerateAssocRoles(cd))
{
if (s_options.association)
r = ASSOCIATION_PROVIDER_PROTOTYPES;
else
{
r = ROLE_PROVIDER_PROTOTYPES;
SubRoles(cd, r);
}
}
else
errRefPropCount(cd->name);
r = sub(r, "<ALIAS>", alias);
puts(os, r);
}
else if (cd->flags & MI_FLAG_INDICATION)
{
string r;
r = INDICATION_PROVIDER_PROTOTYPES;
r = sub(r, "<ALIAS>", alias);
puts(os, r);
}
else
{
if (HasKeys(cd))
{
string r = INSTANCE_PROVIDER_PROTOTYPES;
r = sub(r, "<ALIAS>", alias);
puts(os, r);
}
else
{
string r = COMMON_PROVIDER_PROTOTYPES;
r = sub(r, "<ALIAS>", alias);
puts(os, r);
}
}
}
// Write the extrinsic provider function prototypes.
if (!s_options.noProviders)
{
for (size_t i = 0; i < cd->numMethods; i++)
{
const MI_MethodDecl* md = cd->methods[i];
string r = sub(EXTRINSIC_METHOD_PROTOTYPE, "<ALIAS>", alias);
r = sub(r, "<METHOD>", md->name);
puts(os, r);
}
}
}
// Generate the class identifier:
#if 0
{
char id[33];
_MakeID(id);
string classIdentifier = alias + "_" + id;
classIdentifiers.insert(classIdentifier);
putl(os, "#define %s\n", classIdentifier.c_str());
}
#endif
nl(os);
// c++ part
if (s_options.cpp)
GenCppClassHeader(parser, cd, os);
// End ifdef that Prevents multiple inclusion.
putl(os, "#endif /* _%s_h */", alias.c_str());
// Close file.
fclose(os);
}