/* --------------------------------------------------------------------------
libmusicbrainz5 - Client library to access MusicBrainz
Copyright (C) 2012 Andrew Hawkins
This file is part of libmusicbrainz5.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
libmusicbrainz5 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
Lesser General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library. If not, see <http://www.gnu.org/licenses/>.
$Id$
----------------------------------------------------------------------------*/
#include "config.h"
#include "musicbrainz5/defines.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstring>
#include <unistd.h>
#include <vector>
#include <string>
#include <cstdlib>
#include "musicbrainz5/xmlParser.h"
void ProcessBoilerplate(const XMLNode& Node, std::ofstream& Source, std::ofstream& Include, const std::string& Path);
void ProcessHeader(const XMLNode& Node, std::ofstream& Source, std::ofstream& Include);
void ProcessEntity(const XMLNode& Node, std::ofstream& Source, std::ofstream& Include);
void ProcessClass(const XMLNode& Node, std::ofstream& Source, std::ofstream& Include);
void ProcessList(const XMLNode& Node, std::ofstream& Source, std::ofstream& Include);
void ProcessDeclare(const XMLNode& Node, std::ofstream& Source, std::ofstream& Include);
int main(int argc, const char *argv[])
{
for (int count=0;count<argc;count++)
std::cout << argv[count] << " ";
std::cout << std::endl;
if (argc==6)
{
std::string XMLFile=std::string(argv[1])+"/"+argv[2];
XMLResults Results;
XMLNode *TopNode=XMLRootNode::parseFile(XMLFile.c_str(),&Results);
if (!TopNode->isEmpty())
{
std::cout << "Generating '" << argv[3] << "/" << argv[4] << "' and '" << argv[3] << "/" << argv[5] << "'" << std::endl;
std::string IncludeName=std::string(argv[3])+"/"+argv[5];
std::ofstream Include(IncludeName.c_str());
std::string SourceName=std::string(argv[3])+"/" + argv[4];
std::ofstream Source(SourceName.c_str());
if (!Include.is_open())
{
std::cerr << "Error opening '" << IncludeName << "'" << std::endl;
return 1;
}
if (!Source.is_open())
{
std::cerr << "Error opening '" << SourceName << "'" << std::endl;
return 1;
}
for (XMLNode Node = TopNode->getChildNode();
!Node.isEmpty();
Node = Node.next())
{
std::string Name=Node.getName();
if ("boilerplate"==Name)
ProcessBoilerplate(Node,Source,Include,argv[1]);
else if ("header"==Name)
ProcessHeader(Node,Source,Include);
else if ("declare"==Name)
ProcessDeclare(*TopNode,Source,Include);
else if ("entity"==Name)
ProcessEntity(Node,Source,Include);
else if ("class"==Name)
ProcessClass(Node,Source,Include);
else if ("list"==Name)
ProcessList(Node,Source,Include);
else
{
std::cerr << "Unrecognised item " << Name << std::endl;
return 1;
}
}
}
else
{
std::cerr << "Error reading XML: " << Results.message << " at line " << Results.line << std::endl;
return 1;
}
if (TopNode != NULL)
delete TopNode;
}
return 0;
}
std::ofstream *GetFile(const XMLNode& Node, std::ofstream& Source, std::ofstream& Include)
{
std::ofstream *File=&Source;
if (Node.isAttributeSet("target"))
{
std::string Target=Node.getAttribute("target").value();
if ("source"==Target)
File=&Source;
else if ("include"==Target)
File=&Include;
}
return File;
}
void ProcessHeader(const XMLNode& /*Node*/, std::ofstream& Source, std::ofstream& Include)
{
std::stringstream os;
os << "/* --------------------------------------------------------------------------" << std::endl;
os << std::endl;
os << " libmusicbrainz5 - Client library to access MusicBrainz" << std::endl;
os << std::endl;
os << " Copyright (C) 2012 Andrew Hawkins" << std::endl;
os << std::endl;
os << " This file is part of libmusicbrainz5." << std::endl;
os << std::endl;
os << " This library is free software; you can redistribute it and/or" << std::endl;
os << " modify it under the terms of the GNU Lesser General Public" << std::endl;
os << " License as published by the Free Software Foundation; either" << std::endl;
os << " version 2.1 of the License, or (at your option) any later version." << std::endl;
os << std::endl;
os << " libmusicbrainz5 is distributed in the hope that it will be useful," << std::endl;
os << " but WITHOUT ANY WARRANTY; without even the implied warranty of" << std::endl;
os << " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU" << std::endl;
os << " Lesser General Public License for more details." << std::endl;
os << std::endl;
os << " You should have received a copy of the GNU General Public License" << std::endl;
os << " along with this library. If not, see <http://www.gnu.org/licenses/>." << std::endl;
os << std::endl;
os << " THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT IT!" << std::endl;
os << std::endl;
os << "----------------------------------------------------------------------------*/" << std::endl;
os << std::endl;
Source << os.str() << std::endl;
Include << os.str() << std::endl;
}
void ProcessBoilerplate(const XMLNode& Node, std::ofstream& Source, std::ofstream& Include, const std::string& Path)
{
std::ofstream *File=GetFile(Node,Source,Include);
if (Node.isAttributeSet("file"))
{
std::string FileName=Path+"/"+Node.getAttribute("file").value();
std::ifstream InFile(FileName.c_str());
if (InFile.is_open())
*File << InFile.rdbuf() << std::endl;
else
{
std::cerr << "Error opening include file '" << FileName << "'" << std::endl;
exit(1);
}
}
else if (Node.getText())
{
*File << Node.getText() << std::endl;
}
*File << std::endl;
}
void ProcessEntity(const XMLNode& /*Node*/, std::ofstream& Source, std::ofstream& Include)
{
Include << "/**" << std::endl;
Include << " * Returns the number of extension attributes for the entity" << std::endl;
Include << " *" << std::endl;
Include << " * @param Entity #Mb5Entity object" << std::endl;
Include << " *" << std::endl;
Include << " * @return The number of characters in the string to copy (not including terminating NULL)" << std::endl;
Include << " */" << std::endl;
Include << " int mb5_entity_ext_attributes_size(Mb5Entity Entity);" << std::endl;
Include << std::endl;
Include << "/**" << std::endl;
Include << " * Returns the name of the requested extension attribute" << std::endl;
Include << " *" << std::endl;
Include << " * @param Entity #Mb5Entity object" << std::endl;
Include << " * @param Item Item to return" << std::endl;
Include << " * @param str Returned string" << std::endl;
Include << " * @param len Number of characters available in return string" << std::endl;
Include << " *" << std::endl;
Include << " * @return The number of characters in the string to copy (not including terminating NULL)" << std::endl;
Include << " */" << std::endl;
Include << " int mb5_entity_ext_attribute_name(Mb5Entity Entity, int Item, char *str, int len);" << std::endl;
Include << std::endl;
Include << "/**" << std::endl;
Include << " * Returns the value of the requested extension attribute" << std::endl;
Include << " *" << std::endl;
Include << " * @param Entity #Mb5Entity object" << std::endl;
Include << " * @param Item Item to return" << std::endl;
Include << " * @param str Returned string" << std::endl;
Include << " * @param len Number of characters available in return string" << std::endl;
Include << " *" << std::endl;
Include << " * @return The number of characters in the string to copy (not including terminating NULL)" << std::endl;
Include << " */" << std::endl;
Include << " int mb5_entity_ext_attribute_value(Mb5Entity Entity, int Item, char *str, int len);" << std::endl;
Include << std::endl;
Include << "/**" << std::endl;
Include << " * Returns the number of extension elements for the entity" << std::endl;
Include << " *" << std::endl;
Include << " * @param Entity #Mb5Entity object" << std::endl;
Include << " *" << std::endl;
Include << " * @return The number of characters in the string to copy (not including terminating NULL)" << std::endl;
Include << " */" << std::endl;
Include << " int mb5_entity_ext_elements_size(Mb5Entity Entity);" << std::endl;
Include << std::endl;
Include << "/**" << std::endl;
Include << " * Returns the name of the requested extension element" << std::endl;
Include << " *" << std::endl;
Include << " * @param Entity #Mb5Entity object" << std::endl;
Include << " * @param Item Item to return" << std::endl;
Include << " * @param str Returned string" << std::endl;
Include << " * @param len Number of characters available in return string" << std::endl;
Include << " *" << std::endl;
Include << " * @return The number of characters in the string to copy (not including terminating NULL)" << std::endl;
Include << " */" << std::endl;
Include << " int mb5_entity_ext_element_name(Mb5Entity Entity, int Item, char *str, int len);" << std::endl;
Include << std::endl;
Include << "/**" << std::endl;
Include << " * Returns the value of the requested extension element" << std::endl;
Include << " *" << std::endl;
Include << " * @param Entity #Mb5Entity object" << std::endl;
Include << " * @param Item Item to return" << std::endl;
Include << " * @param str Returned string" << std::endl;
Include << " * @param len Number of characters available in return string" << std::endl;
Include << " *" << std::endl;
Include << " * @return The number of characters in the string to copy (not including terminating NULL)" << std::endl;
Include << " */" << std::endl;
Include << " int mb5_entity_ext_element_value(Mb5Entity Entity, int Item, char *str, int len);" << std::endl;
Include << std::endl;
Source << " MB5_C_EXT_GETTER(Attribute,attribute)" << std::endl;
Source << " MB5_C_EXT_GETTER(Element,element)" << std::endl;
Source << std::endl;
}
void ProcessClass(const XMLNode& Node, std::ofstream& Source, std::ofstream& Include)
{
if (Node.isAttributeSet("name"))
{
std::string LowerName=Node.getAttribute("name").value();
std::string UpperName=LowerName;
if (Node.isAttributeSet("uppername"))
UpperName=Node.getAttribute("uppername").value();
else
UpperName[0]=toupper(UpperName[0]);
Include << "/**" << std::endl;
Include << "* Delete an #Mb5" << UpperName << " object" << std::endl;
Include << "*" << std::endl;
Include << "* @param " << UpperName << " Object to delete" << std::endl;
Include << "*/" << std::endl;
Include << " void mb5_" << LowerName << "_delete(Mb5" << UpperName << " " << UpperName << ");" << std::endl;
Include << std::endl;
Source << " MB5_C_DELETE(" << UpperName << "," << LowerName << ")" << std::endl;
Include << "/**" << std::endl;
Include << "* Clone an #Mb5" << UpperName << " object" << std::endl;
Include << "*" << std::endl;
Include << "* @param " << UpperName << " Object to clone" << std::endl;
Include << "*" << std::endl;
Include << "* @return Cloned object. This object <b>must</b> be deleted once" << std::endl;
Include << "* finished with." << std::endl;
Include << "*/" << std::endl;
Include << " Mb5" << UpperName << " mb5_" << LowerName << "_clone(Mb5" << UpperName << " " << UpperName << ");" << std::endl;
Include << std::endl;
Source << " MB5_C_CLONE(" << UpperName << "," << LowerName << ")" << std::endl;
for (XMLNode ChildNode = Node.getChildNode();
!ChildNode.isEmpty();
ChildNode = ChildNode.next())
{
std::string Name=ChildNode.getName();
if ("property"==Name)
{
if (ChildNode.isAttributeSet("name") && ChildNode.isAttributeSet("type"))
{
std::string PropertyLowerName=ChildNode.getAttribute("name").value();
std::string PropertyUpperName=PropertyLowerName;
if (ChildNode.isAttributeSet("uppername"))
PropertyUpperName=ChildNode.getAttribute("uppername").value();
else
PropertyUpperName[0]=toupper(PropertyUpperName[0]);
std::string PropertyType=ChildNode.getAttribute("type").value();
if ("string"==PropertyType)
{
bool Deprecated=false;
std::string Replacement;
if (ChildNode.isAttributeSet("deprecated"))
{
std::string StrDeprecated=ChildNode.getAttribute("deprecated").value();
if (StrDeprecated=="true")
Deprecated=true;
if (ChildNode.isAttributeSet("replacement"))
Replacement=ChildNode.getAttribute("replacement").value();
}
Include << "/**" << std::endl;
Include << " * ";
if (Deprecated)
Include << "@deprecated ";
Include << "@see MusicBrainz5::C" << UpperName << "::" << PropertyUpperName << std::endl;
Include << " *" << std::endl;
if (Deprecated)
{
Include << " * <b>This method is deprecated, please use #" << Replacement << "</b>" << std::endl;
Include << " *" << std::endl;
}
Include << " * @param " << UpperName << " #Mb5" << UpperName << " object" << std::endl;
Include << " * @param str Returned string" << std::endl;
Include << " * @param len Number of characters available in return string" << std::endl;
Include << " *" << std::endl;
Include << " * @return The number of characters in the string to copy (not including terminating NULL)" << std::endl;
Include << " */" << std::endl;
Include << " ";
if (Deprecated)
Include << "LIBMB5_DEPRECATED(" << Replacement << ") ";
Include << "int mb5_" << LowerName << "_get_" << PropertyLowerName << "(Mb5" << UpperName << " " << UpperName << ", char *str, int len);" << std::endl;
Include << std::endl;
Source << " MB5_C_STR_GETTER(" << UpperName << "," << LowerName << "," << PropertyUpperName << "," << PropertyLowerName << ")" << std::endl;
}
else if ("integer"==PropertyType)
{
Include << "/**" << std::endl;
Include << " * @see MusicBrainz5::C" << UpperName << "::" << PropertyUpperName << std::endl;
Include << " *" << std::endl;
Include << " * @param " << UpperName << " #Mb5" << UpperName << " object" << std::endl;
Include << " *" << std::endl;
Include << " * @return Returned value" << std::endl;
Include << " */" << std::endl;
Include << " int mb5_" << LowerName << "_get_" << PropertyLowerName << "(Mb5" << UpperName << " " << UpperName << ");" << std::endl;
Include << std::endl;
Source << " MB5_C_INT_GETTER(" << UpperName << "," << LowerName << "," << PropertyUpperName << "," << PropertyLowerName << ")" << std::endl;
}
else if ("double"==PropertyType)
{
Include << "/**" << std::endl;
Include << " * @see MusicBrainz5::C" << UpperName << "::" << PropertyUpperName << std::endl;
Include << " *" << std::endl;
Include << " * @param " << UpperName << " #Mb5" << UpperName << " object" << std::endl;
Include << " *" << std::endl;
Include << " * @return Returned value" << std::endl;
Include << " */" << std::endl;
Include << " double mb5_" << LowerName << "_get_" << PropertyLowerName << "(Mb5" << UpperName << " " << UpperName << ");" << std::endl;
Include << std::endl;
Source << " MB5_C_DOUBLE_GETTER(" << UpperName << "," << LowerName << "," << PropertyUpperName << "," << PropertyLowerName << ")" << std::endl;
}
else if ("object"==PropertyType)
{
Include << "/**" << std::endl;
Include << " * @see MusicBrainz5::C" << UpperName << "::" << PropertyUpperName << std::endl;
Include << " *" << std::endl;
Include << " * @param " << UpperName << " #Mb5" << UpperName << " object" << std::endl;
Include << " *" << std::endl;
Include << " * @return #Mb5" << PropertyUpperName << " object" << std::endl;
Include << " */" << std::endl;
Include << " Mb5" << PropertyUpperName << " mb5_" << LowerName << "_get_" << PropertyLowerName << "(Mb5" << UpperName << " " << UpperName << ");" << std::endl;
Include << std::endl;
Source << " MB5_C_OBJ_GETTER(" << UpperName << "," << LowerName << "," << PropertyUpperName << "," << PropertyLowerName << ")" << std::endl;
}
else if ("relationlist"==PropertyType)
{
Include << "/**" << std::endl;
Include << " * @see MusicBrainz5::C" << UpperName << "::" << PropertyUpperName << "List" << std::endl;
Include << " *" << std::endl;
Include << " * @param " << UpperName << " #Mb5" << UpperName << "List object" << std::endl;
Include << " *" << std::endl;
Include << " * @return #Mb5" << PropertyUpperName << "List object" << std::endl;
Include << " */" << std::endl;
Include << " Mb5" << PropertyUpperName << "List mb5_" << LowerName << "_get_" << PropertyLowerName << "list(Mb5" << UpperName << " " << UpperName << ");" << std::endl;
Include << std::endl;
Source << " MB5_C_OBJ_GETTER(" << UpperName << "," << LowerName << "," << PropertyUpperName << "List," << PropertyLowerName << "list)" << std::endl;
}
else if ("iswc"==PropertyType)
{
Include << "/**" << std::endl;
Include << " * @see MusicBrainz5::C" << UpperName << "::" << PropertyUpperName << "List" << std::endl;
Include << " *" << std::endl;
Include << " * @param " << UpperName << " #Mb5" << UpperName << "List object" << std::endl;
Include << " *" << std::endl;
Include << " * @return #Mb5" << PropertyUpperName << "List object" << std::endl;
Include << " */" << std::endl;
Include << " Mb5" << PropertyUpperName << "List mb5_" << LowerName << "_get_" << PropertyLowerName << "list(Mb5" << UpperName << " " << UpperName << ");" << std::endl;
Include << std::endl;
Source << " MB5_C_OBJ_GETTER(" << UpperName << "," << LowerName << "," << PropertyUpperName << "List," << PropertyLowerName << "list)" << std::endl;
}
else if ("ipi"==PropertyType)
{
Include << "/**" << std::endl;
Include << " * @see MusicBrainz5::C" << UpperName << "::" << PropertyUpperName << "List" << std::endl;
Include << " *" << std::endl;
Include << " * @param " << UpperName << " #Mb5" << UpperName << "List object" << std::endl;
Include << " *" << std::endl;
Include << " * @return #Mb5" << PropertyUpperName << "List object" << std::endl;
Include << " */" << std::endl;
Include << " Mb5" << PropertyUpperName << "List mb5_" << LowerName << "_get_" << PropertyLowerName << "list(Mb5" << UpperName << " " << UpperName << ");" << std::endl;
Include << std::endl;
Source << " MB5_C_OBJ_GETTER(" << UpperName << "," << LowerName << "," << PropertyUpperName << "List," << PropertyLowerName << "list)" << std::endl;
}
else
{
std::cerr << "Unexpected property type: '" << PropertyType << "'" << std::endl;
exit(1);
}
}
else
{
std::cerr << "Class " << LowerName << " property specified with no name or type" << std::endl;
exit(1);
}
}
}
Source << std::endl;
}
else
{
std::cerr << "Class specified with no name" << std::endl;
exit(1);
}
}
void ProcessList(const XMLNode& Node, std::ofstream& Source, std::ofstream& Include)
{
if (Node.isAttributeSet("name"))
{
std::string LowerName=Node.getAttribute("name").value();
std::string UpperName=LowerName;
if (Node.isAttributeSet("uppername"))
UpperName=Node.getAttribute("uppername").value();
else
UpperName[0]=toupper(UpperName[0]);
Include << "/**" << std::endl;
Include << " * Delete a #Mb5" << UpperName << "List" << std::endl;
Include << " *" << std::endl;
Include << " * @param List List to delete" << std::endl;
Include << " */" << std::endl;
Include << " void mb5_" << LowerName << "_list_delete(Mb5" << UpperName << "List List);" << std::endl;
Include << std::endl;
Include << "/**" << std::endl;
Include << " * Return the number of entries in a #Mb5" << UpperName << "List" << std::endl;
Include << " *" << std::endl;
Include << " * @param List List to use" << std::endl;
Include << " */" << std::endl;
Include << " int mb5_" << LowerName << "_list_size(Mb5" << UpperName << "List List);" << std::endl;
Include << std::endl;
Include << "/**" << std::endl;
Include << " * Returns an entry from a #Mb5" << UpperName << "List" << std::endl;
Include << " *" << std::endl;
Include << " * @param List List to use" << std::endl;
Include << " * @param Item Item number to return" << std::endl;
Include << " *" << std::endl;
Include << " * @return A #Mb5" << UpperName << " object." << std::endl;
Include << " */" << std::endl;
Include << " Mb5" << UpperName << " mb5_" << LowerName << "_list_item(Mb5" << UpperName << "List List, int Item);" << std::endl;
Include << std::endl;
Include << "/**" << std::endl;
Include << " * Return the count of entries in an #Mb5" << UpperName << "List" << std::endl;
Include << " *" << std::endl;
Include << " * @param List List to use" << std::endl;
Include << " */" << std::endl;
Include << " int mb5_" << LowerName << "_list_get_count(Mb5" << UpperName << "List List);" << std::endl;
Include << std::endl;
Include << "/**" << std::endl;
Include << " * Return the offset of entries in an #Mb5" << UpperName << "List" << std::endl;
Include << " *" << std::endl;
Include << " * @param List List to use" << std::endl;
Include << " */" << std::endl;
Include << " int mb5_" << LowerName << "_list_get_offset(Mb5" << UpperName << "List List);" << std::endl;
Include << std::endl;
Source << " MB5_C_LIST_GETTER(" << UpperName << "," << LowerName << ")" << std::endl;
Include << "/**" << std::endl;
Include << "* Clone an #Mb5" << UpperName << "List object" << std::endl;
Include << "*" << std::endl;
Include << "* @param " << UpperName << "List Object to clone" << std::endl;
Include << "*" << std::endl;
Include << "* @return Cloned list. This list <b>must</b> be deleted once" << std::endl;
Include << "* finished with." << std::endl;
Include << "*/" << std::endl;
Include << " Mb5" << UpperName << "List mb5_" << LowerName << "_list_clone(Mb5" << UpperName << "List " << UpperName << "List" << ");" << std::endl;
Include << std::endl;
Source << " MB5_C_CLONE(" << UpperName << "List," << LowerName << "_list)" << std::endl;
for (XMLNode ChildNode = Node.getChildNode();
!ChildNode.isEmpty();
ChildNode = ChildNode.next())
{
std::string Name=ChildNode.getName();
if ("property"==Name)
{
if (ChildNode.isAttributeSet("name") && ChildNode.isAttributeSet("type"))
{
std::string PropertyLowerName=ChildNode.getAttribute("name").value();
std::string PropertyUpperName=PropertyLowerName;
if (ChildNode.isAttributeSet("uppername"))
PropertyUpperName=ChildNode.getAttribute("uppername").value();
else
PropertyUpperName[0]=toupper(PropertyUpperName[0]);
std::string PropertyType=ChildNode.getAttribute("type").value();
if ("string"==PropertyType)
{
Include << "/**" << std::endl;
Include << " * @see MusicBrainz5::C" << UpperName << "::" << PropertyUpperName << std::endl;
Include << " *" << std::endl;
Include << " * @param List List to use" << std::endl;
Include << " * @param str Returned string" << std::endl;
Include << " * @param len Number of characters available in return string" << std::endl;
Include << " *" << std::endl;
Include << " * @return The number of characters in the string to copy (not including terminating NULL)" << std::endl;
Include << " */" << std::endl;
Include << " int mb5_" << LowerName << "_list_get_" << PropertyLowerName << "(Mb5" << UpperName << "List List, char *str, int len);" << std::endl;
Include << std::endl;
Source << " MB5_C_STR_GETTER(" << UpperName << "List," << LowerName << "_list," << PropertyUpperName << "," << PropertyLowerName << ")" << std::endl;
}
else if ("integer"==PropertyType)
{
Include << "/**" << std::endl;
Include << " * @see MusicBrainz5::C" << UpperName << "::" << PropertyUpperName << std::endl;
Include << " *" << std::endl;
Include << " * @param List List to use" << std::endl;
Include << " *" << std::endl;
Include << " * @return Returned value" << std::endl;
Include << " */" << std::endl;
Include << " int mb5_" << LowerName << "_list_get_" << PropertyLowerName << "(Mb5" << UpperName << "List List);" << std::endl;
Include << std::endl;
Source << " MB5_C_INT_GETTER(" << UpperName << "List," << LowerName << "_list," << PropertyUpperName << "," << PropertyLowerName << ")" << std::endl;
}
else if ("double"==PropertyType)
{
Include << "/**" << std::endl;
Include << " * @see MusicBrainz5::C" << UpperName << "::" << PropertyUpperName << std::endl;
Include << " *" << std::endl;
Include << " * @param List List to use" << std::endl;
Include << " *" << std::endl;
Include << " * @return Returned value" << std::endl;
Include << " */" << std::endl;
Include << " double mb5_" << LowerName << "_list_get_" << PropertyLowerName << "(Mb5" << UpperName << "List List);" << std::endl;
Include << std::endl;
Source << " MB5_C_DOUBLE_GETTER(" << UpperName << "List," << LowerName << "_list," << PropertyUpperName << "," << PropertyLowerName << ")" << std::endl;
}
else if ("object"==PropertyType)
{
Include << "/**" << std::endl;
Include << " * @see MusicBrainz5::C" << UpperName << "::" << PropertyUpperName << std::endl;
Include << " *" << std::endl;
Include << " * @param List List to use" << std::endl;
Include << " *" << std::endl;
Include << " * @return #Mb5" << PropertyUpperName << " object" << std::endl;
Include << " */" << std::endl;
Include << " int mb5_" << LowerName << "_list_get_" << PropertyLowerName << "(Mb5" << UpperName << "List List);" << std::endl;
Include << std::endl;
Source << " MB5_C_OBJ_GETTER(" << UpperName << "List," << LowerName << "_list," << PropertyUpperName << "," << PropertyLowerName << ")" << std::endl;
}
else
{
std::cerr << "Unexpected property type: '" << PropertyType << "'" << std::endl;
exit(1);
}
}
else
{
std::cerr << "List " << LowerName << " property specified with no name or type" << std::endl;
exit(1);
}
}
}
Source << std::endl;
}
else
{
std::cerr << "List specified with no name" << std::endl;
exit(1);
}
}
void ProcessDeclare(const XMLNode& Node, std::ofstream& /*Source*/, std::ofstream& Include)
{
std::vector<std::string> Classes;
Classes.push_back("Entity");
for (XMLNode ChildNode = Node.getChildNode();
!ChildNode.isEmpty();
ChildNode = ChildNode.next())
{
std::string Name=ChildNode.getName();
if ("class"==Name || "list"==Name)
{
if (ChildNode.isAttributeSet("name"))
{
std::string UpperName=ChildNode.getAttribute("name").value();
if (ChildNode.isAttributeSet("uppername"))
UpperName=ChildNode.getAttribute("uppername").value();
else
UpperName[0]=toupper(UpperName[0]);
if ("list"==Name)
UpperName+="List";
Classes.push_back(UpperName);
}
else
{
std::cerr << "Entity, Class or List specified with no name or type" << std::endl;
exit(1);
}
}
}
for (std::vector<std::string>::const_iterator Class=Classes.begin();Class!=Classes.end();Class++)
{
Include << " typedef void *Mb5" << *Class << ";" << std::endl;
}
Include << std::endl;
}