#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include "simple_cpp_lexer.hpp"
using namespace std;
using namespace boost::spirit;
using namespace boost::spirit::repository;
namespace
{
struct process
{
process(ostream& out,std::vector<string>& list)
: out(out) , name(name),list(list){};
template <typename IteratorT>
void operator()(IteratorT first, IteratorT last) const
{
std::stringstream _str;
bool b = true;
if(list.size() > 0)
{
if((*(list.end() - 1)) == "#include"
|| (*(list.end() - 1)) == "#import"
|| (*(list.end() - 1)) == "L")
{
b = false;
}
}
if(list.size() > 1)
{
string a = (*(list.end() - 2)) + (*(list.end() - 1));
if( a == "_T(" )
{
b = false;
}
}
if(b){
out << "_T(";
}
while (first != last){
_str << *first;
out << *first++;
}
list.push_back(_str.str());
if(b){
out << ")";
}
}
ostream& out;
string name;
vector<string>& list;
};
struct none
{
none(ostream& out,std::vector<string>& list,bool add = true)
: out(out) ,name(name),list(list) { badd_list = add;};
template <typename IteratorT>
void operator()(IteratorT first, IteratorT last) const
{
std::stringstream _str;
while (first != last){
_str << *first;
out << *first++;
}
if(badd_list){
list.push_back(_str.str());
}
}
ostream& out;
std::string name;
vector<string>& list;
bool badd_list;
};
struct unexpected_char
{
unexpected_char(ostream& out)
: out(out) {};
template <typename CharT>
void operator()(CharT ch) const
{
out << ch; }
ostream& out;
};
struct cpp_to_html_actions
{
cpp_to_html_actions(ostream& out)
: preprocessor(out,list)
, comment(out,list,false)
, keyword(out,list)
, identifier(out,list)
, special(out,list)
, string(out,list)
, literal(out,list)
, number(out,list)
, unexpected(out)
{};
none
preprocessor, comment, keyword, identifier,
special, number;
process literal,string;
unexpected_char unexpected;
vector<std::string> list;
};
}
static int
parse(istream& in,
ostream& out)
{
in.unsetf(ios::skipws); vector<char> vec;
std::copy(
istream_iterator<char>(in),
istream_iterator<char>(),
std::back_inserter(vec));
vector<char>::const_iterator first = vec.begin();
vector<char>::const_iterator last = vec.end();
cpp_to_html_actions actions(out);
simple_cpp_lexer<cpp_to_html_actions> p(actions);
parse_info<vector<char>::const_iterator> info =
parse(first, last, p);
if (!info.full)
{
cerr << "parsing error\r\n";
cerr << string(info.stop, last);
return -1;
}
return 0;
}
int
main(int argc, char* argv[])
{
string in_file;
string out_file;
string title;
string option;
string usage =
string ("usage: ")
+ argv[0]
+ " [-o <out-file>]"
+ " [<in-file>]";
for (int i = 1; i < argc; i++)
{
if (!option.empty())
{
if (option == "-o") out_file = argv[i];
else
{
cerr << "Unknown option \'" << option << "\'" << endl
<< usage << endl;
return -1;
}
option.clear ();
continue;
}
if (argv[i] == string ("-o"))
{
option = argv[i];
}
else
{
if (in_file.empty())
{
in_file = argv[i];
}
else
{
cerr << "Unexpected argument \'" << argv[i] << "\'" << endl
<< usage << endl;
return -1;
}
}
}
string in_file_name;
string::size_type pos = in_file.find_last_of("\\/");
if (pos != string::npos)
{
in_file_name.assign(in_file, ++pos, in_file.size () - pos);
}
else
{
in_file_name = in_file;
}
if (out_file.empty() && !in_file.empty())
{
string::size_type pos = in_file.find_last_of('.');
out_file.assign(in_file, 0, pos);
out_file += ".tmp";
}
if (title.empty())
title = in_file_name;
ifstream ifs;
if (!in_file.empty())
{
ifs.open(in_file.c_str());
if (!ifs)
{
cerr << "Unable to open input file: " << in_file << endl;
return -1;
}
}
istream& in = ifs.is_open() ? (istream&) ifs : (istream&) cin;
ofstream ofs;
if (!out_file.empty())
{
ofs.open(out_file.c_str());
if (!ofs)
{
cerr << "Unable to open output file: " << out_file << endl;
return -1;
}
}
ostream& out = ofs.is_open() ? (ostream&)ofs : (ostream&)cout;
parse(in, out);
if(ifs.is_open())
{
ifs.close();
}
if(ofs.is_open())
{
ofs.close();
}
}