// 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 "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: "<