// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // CodeFast.cpp : Defines the entry point for the console application. // /* TODO - re-do 'case' parser to look for anything with a '::' sub-string - build handy command line behaviour - test ... test ... outfile timestamp on no change test... */ #include "nel/misc/types_nl.h" #include #include #include #include #include #include class COutputFile { public: enum TParamType { STRING, INT, FLOAT }; // ctor COutputFile(const char *filename); // input string parsers void processString(const std::string &s); void processCase(const std::string &s); void addStruct(const std::string &name,const std::string &qualifiers); void addStructEntry(const std::string ¶mName,const std::string &className,TParamType type,const std::string &defaultValue,const std::string &comment); void addEnum(const std::string &name); void addEnumEntry(const std::string &entry); void display() const; void generateOutput() const; void generateEnumOutput(std::string &outbuff) const; private: std::string _FileName; struct CStructParam { std::string _Name; std::string _Class; TParamType _Type; std::string _DefaultValue; std::string _Comment; }; struct CStruct { std::string _Name; std::string _Qualifiers; std::vector _Params; void display() const; void generateOutput(std::string &outbuff) const; }; std::vector _Structures; std::vector _Enums; std::vector _EnumEntries; unsigned _OpenStruct; // the index of the last open structure }; inline COutputFile::COutputFile(const char *filename) { _OpenStruct=~0u; _FileName=filename; // display the string printf("OUTPUT FILE: %s\n",filename); } inline void COutputFile::processString(const std::string &s) { /* special strings: 'ENUM' 'STRUCT' '-'('s'|'i'|'f') ['='] ['//'] */ // see whether we have a struct parameter if (s.size()>5 && s[0]=='-') { // start by parsing the 'type' character if ( (s[1]!='s' && s[1]!='i' && s[1]!='f') || (s[2]!=' ' && s[2]!='\t') ) { printf("Ignoring structure parameter due to bad type (should be 's','i' or 'f'): %s",s.c_str()); return; } COutputFile::TParamType type= s[1]=='i'? COutputFile::INT: s[1]=='s'? COutputFile::STRING: FLOAT; // skip space after the 'type' character unsigned i=2; while ( i7 && (s[6]==' ' || s[6]=='\t')) if ((s[0]|('a'^'A')=='s') && (s[1]|('a'^'A')=='t') && (s[2]|('a'^'A')=='r') && (s[3]|('a'^'A')=='u') && (s[4]|('a'^'A')=='c') && (s[5]|('a'^'A')=='t')) { // we have a struct so skip the first 6 letters + opening spaces unsigned i=7; while (i5 && (s[4]==' ' || s[4]=='\t')) if ((s[0]|('a'^'A')=='e') && (s[1]|('a'^'A')=='n') && (s[2]|('a'^'A')=='u') && (s[3]|('a'^'A')=='m')) { // we have an enum so skip the first 4 letters + opening spaces unsigned i=5; while (i=_Structures.size()) { printf("Failed to add structure entry (%s) due to lack of open structure!\n",paramName.c_str()); return; } unsigned paramCount=_Structures[_OpenStruct]._Params.size(); _Structures[_OpenStruct]._Params.resize(paramCount+1); COutputFile::CStructParam ¶m= _Structures[_OpenStruct]._Params[paramCount]; param._Class=className; param._Comment=comment; param._DefaultValue=defaultValue; param._Name=paramName; param._Type=type; } inline void COutputFile::addEnum(const std::string &name) { unsigned i; for (i=0; i<_Enums.size();++i) if (name==_Enums[i]) { printf("Warning: Double declaration of enum: %s\n",name.c_str()); return; } _Enums.resize(i+1); _Enums[i]=name; } inline void COutputFile::addEnumEntry(const std::string &entry) { // see whether this entry already exists and don't add a second time of this is the case for (unsigned i=_EnumEntries.size();i--;) if (_EnumEntries[i]==entry) return; // entry not found in existing values in vector so append it _EnumEntries.push_back(entry); } void COutputFile::display() const { unsigned i; // display the filename printf("\nFILE: %s\n",_FileName.c_str()); // display the set of structures for (i=0;i<_Structures.size();++i) { if (i==_OpenStruct) printf("\n* "); else printf("\n "); _Structures[i].display(); } // display the set of Enums for (i=0;i<_Enums.size();++i) { printf("\nENUM: %s\n",_Enums[i].c_str()); unsigned j; for (j=0;j<_EnumEntries.size();++j) { if (_EnumEntries[j].substr(0,_Enums[i].size()+2)==_Enums[i]+"::") printf("=> %s\n",_EnumEntries[j].substr(_Enums[i].size()+2).c_str()); } } } void COutputFile::generateEnumOutput(std::string &outbuff) const { unsigned i; // output the set of Enums for (i=0;i<_Enums.size();++i) { // open the enum outbuff+="class "; outbuff+=_Enums[i]+"\n"; outbuff+="{\n"; outbuff+="public:\n"; outbuff+="\tenum TValueType\n"; outbuff+="\t{\n"; // add values to the enum unsigned j; for (j=0;j<_EnumEntries.size();++j) { if (_EnumEntries[j].substr(0,_Enums[i].size()+2)==_Enums[i]+"::") { outbuff+="\t\t"; outbuff+=_EnumEntries[j].substr(_Enums[i].size()+2); outbuff+=",\n"; } } // close the enum outbuff+="\t\tNUM_VALUES,\n"; outbuff+="\t\tBAD_VALUE= NUM_VALUES\n"; outbuff+="\t};\n"; outbuff+="\n"; // IId: a template id interface class outbuff+="\tclass IId : public NLMISC::CRefCount\n"; outbuff+="\t{\n"; outbuff+="\tpublic:\n"; outbuff+="\t\tIId() : ParsedOk(false) { }\n"; outbuff+="\t\tTValueType id() const\t{ return _Id; }\n"; outbuff+="\t\tvoid convertInput(std::vector &args, const std::string &input)\n"; outbuff+="\t\t{\n"; outbuff+="\t\t\tunsigned i=0,j=0;\n"; outbuff+="\t\t\twhile (i < input.size())\n"; outbuff+="\t\t\t{\n"; outbuff+="\t\t\t\tj=i;\n"; outbuff+="\t\t\t\twhile( i type='%s' class='%s' name='%s' default='%s' comment='%s'\n", _Params[i]._Type==COutputFile::INT? "INT": _Params[i]._Type==COutputFile::STRING? "STR": "FLO", _Params[i]._Class.c_str(), _Params[i]._Name.c_str(), _Params[i]._DefaultValue.c_str(), _Params[i]._Comment.c_str()); } } void COutputFile::CStruct::generateOutput(std::string &outbuff) const { // open the structure outbuff+="struct "; outbuff+=_Name+" : public TBrickParam::IId\n"; outbuff+="{\n"; // declare structure data parameters unsigned i; for (i=0;i<_Params.size();++i) { outbuff+="\t"; outbuff+=_Params[i]._Comment+"\n"; outbuff+="\t"; outbuff+=_Params[i]._Class+" "+_Params[i]._Name+";\n"; } outbuff+="\n"; // default constructor outbuff+="\t"; outbuff+=_Name; if (_Params.size() > 0) { outbuff+="():\n"; for (i=0;i<_Params.size();++i) { outbuff+="\t\t"; outbuff+=_Params[i]._Name+"("+_Params[i]._DefaultValue; if (i != (_Params.size()-1)) outbuff+="),\n"; else outbuff+=")\n"; } } else { outbuff+="()\n"; } outbuff+="\t{\n"; outbuff+="\t\t_Id = "+_Qualifiers+";\n"; outbuff+="\t}\n"; outbuff+="\n"; // constructor from string outbuff+="\t"; outbuff+=_Name; outbuff+="(const std::string&str)\n"; outbuff+="\t{\n"; outbuff+="\t\t*this="; outbuff+=_Name+"();\n"; outbuff+="\t\t*this=str;\n"; outbuff+="\t}\n"; outbuff+="\n"; // '=' operator from string outbuff+="\tconst "; outbuff+=_Name+"& operator=(const std::string& input)\n"; outbuff+="\t{\n"; outbuff+="\t\tstd::vector args;\n"; outbuff+="\t\tconvertInput(args, input);\n"; outbuff+="\n"; outbuff+="\t\tif (args.size()!="; if (_Params.size()>100) outbuff+=('0'+((_Params.size()/100)%10)); if (_Params.size()>10) outbuff+=('0'+((_Params.size()/10)%10)); outbuff+=('0'+(_Params.size()%10)); outbuff+=")\n"; outbuff+="\t\t\treturn *this;\n"; outbuff+="\n"; outbuff+="\t\tParsedOk=true;\n"; for (i=0;i<_Params.size();++i) { outbuff+="\t\t"; outbuff+="NLMISC::fromString(args["; if (i>100) outbuff+=('0'+((i/100)%10)); if (i>10) outbuff+=('0'+((i/10)%10)); outbuff+=('0'+(i%10)); outbuff+="], "+_Params[i]._Name+");\n"; } outbuff+="\n"; outbuff+="\t\treturn *this;\n"; outbuff+="\t}\n"; // close the struct outbuff+="};\n\n\n"; } void processInputFile(const char *infile,COutputFile &outputFile) { // open the input file FILE *inf=fopen(infile,"rb"); assert(inf!=NULL); // allocate a RAM buffer for input file unsigned filesize=filelength(fileno(inf)); char *inbuff=(char *)malloc(filesize+1); assert(inbuff!=NULL); // read the file into the RAM buffer and '0' terminate fread(inbuff,filesize,1,inf); inbuff[filesize]=0; // housekeeping fclose(inf); // scan the data read into the input buffer for special strings for (unsigned i=0;i %s\n",srcFile.c_str(),dstFile.c_str()); printf("===================================\n\n"); // instantiate the output buffer COutputFile outputFile(dstFile.c_str()); // parse the source file processInputFile(srcFile.c_str(),outputFile); // display the list of information extracted from the source file outputFile.display(); // generate the target file outputFile.generateOutput(); } return 0; }