// 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 . // forBoris.cpp : Defines the entry point for the console application. // #include #include "conio.h" #include "nel/misc/sstring.h" #include "nel/misc/file.h" #include "sadge_lib/include/text_input.h" #include "sadge_lib/include/text_output.h" using namespace NLMISC; using namespace std; CTextOutput info(CTextOutput::ECHO_STDOUT); CTextOutput warn(CTextOutput::ECHO_STDERR); CTextOutput out(CTextOutput::RECORD+CTextOutput::ECHO_STDOUT); void splitStringCSV(const CSString& in,const CSString& separator,vector& result) { bool lastEmpty = false; CSString s=in.strip(); if (s.right((uint)separator.size()) == separator) { // there is en empty column at end of line, remember this lastEmpty = true; } while (!s.empty()) { // deal with empty columns first while (s.left((uint)separator.size())==separator) { s=s.leftCrop((uint)separator.size()); result.push_back(""); } if (!s.empty()) { string::size_type pos = s.find(separator.c_str(), 0); CSString col = s.left((uint)pos); s=s.leftCrop((uint)pos); if (!col.empty() && col[0] == '\"') { result.push_back(s.firstWordOrWords(true)); } else result.push_back(col); // we have a non-empty column... /* result.push_back(s.firstWordOrWords(true)); while (s.left(separator.size())!=separator && !s.empty()) result.back()+=s.firstWordOrWords(true); */ s=s.leftCrop((uint)separator.size()); } } if (lastEmpty) result.push_back(""); } class CCruncher { private: map paras; // the map of paragraph names to paragraph bodies map headers; // the map of column names to paragraph header bodies map footers; // the map of column names to paragraph footer bodies map headerIsOpen; // map of open headers... vector tblColumnNames; // the names of the table columns in a table vector lastTblCols; // the last set of table columns CSString tblSep; // the table column separator CSString outputName; // the name of the output file that we're building CSString paraName; // the name of the para, header or footer that we're building CSString fileHeader; // text to insert at start of output file CSString fileFooter; // text to insert at end of output file CSString fileBody; // the body text of the file bool firstTblLine; // boolean used to identify the first line of a table... bool readColumnName; // boolean used to identify need to read column name in first table line CSString tabTablePara; // name of the paragraph for tabbed table import enum { DEFAULT, PARA, HEADER, FOOTER, FILE_HEADER, FILE_FOOTER, TBL, TABTBL, TEXT } mode; public: CCruncher(): mode(DEFAULT), firstTblLine(true) { } void crunch(CTextInput& infile) { //--------------------------------------------------------------------------------------------- // process input file contents while (!infile.eof()) { CSString line=infile.getLine(); if (line.strip().left(1)=="#") { //------------------------------------------------------------------------------------- // deal with keywords dealWithKeyword(line,infile); } else { //------------------------------------------------------------------------------------- // deal with non-keyword lines switch (mode) { case TBL: case TABTBL: addTableLine(line); break; case PARA: // append text to the current para paras[paraName]+=line+"\n"; break; case HEADER: // append text to the current para headers[paraName]+=line+"\n"; headerIsOpen[paraName]=false; break; case FILE_HEADER: // append text to the current para fileHeader+=line+"\n"; break; case FILE_FOOTER: // append text to the current para fileFooter+=line+"\n"; break; case FOOTER: // append text to the current para footers[paraName]+=line+"\n"; break; case TEXT: // append the text directly to the output fileBody += line+"\n"; break; default: if (!line.strip().empty()) warn<<"ignoring line: "< cols; splitStringCSV(line,tblSep,cols); if (!tabTablePara.empty()) { // prepend the paragraph name to the columns names cols.insert(cols.begin(), tabTablePara); } // if not an empty line... if (!cols.empty()) { if (!firstTblLine && !readColumnName) { // deal with footer paragraphs uint32 firstChange; for (firstChange=0;firstChange=cols.size()) break; if (cols[firstChange]!=lastTblCols[firstChange]) break; } } } for (uint32 i=(uint32)tblColumnNames.size();(i--)>firstChange;) { CSString s=footers[tblColumnNames[i]]; for (uint32 j=1;j=cols.size() || i>=lastTblCols.size() || cols[i]!=lastTblCols[i] || (cols[i]!="" && !headerIsOpen[tblColumnNames[i]])) { CSString s=headers[tblColumnNames[i]]; for (uint32 j=1;j\n"; return 1; } CTextInput infile(argv[1]); if (infile.eof()) { warn<<"File not found or empty: "<