kdelibs/kjs/bytecode/generator/codeprinter.cpp
Ivailo Monev 39f1e04295 generic: add back khtml and kjs with some changes
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
2015-11-09 23:23:53 +02:00

178 lines
4.5 KiB
C++

/*
* A utilitity for building various tables and specializations for the
* KJS Frostbyte bytecode
*
* Copyright (C) 2007, 2008 Maks Orlovich (maksim@kde.org)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*/
#include "codeprinter.h"
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include "assert.h"
#include <cctype>
#include <cstdio>
#include <wtf/ASCIICType.h>
using namespace std;
void Enum::printDeclaration(ostream& hStream)
{
hStream << "enum " << name << " {\n";
for (unsigned p = 0; p < values.size(); ++p) {
hStream << " " << prefix << values[p] << ",\n";
}
hStream << " " << prefix << "NumValues\n";
hStream << "};\n";
hStream << "extern const char* const " << name << "Vals[];\n\n";
}
void Enum::printDefinition(ostream& cppStream)
{
Array vals(cppStream, "const char* const", name + "Vals");
for (unsigned p = 0; p < values.size(); ++p)
vals.item("\"" + prefix + values[p] + "\"");
vals.endArray();
}
Array::Array(ostream& out, const std::string& type, const std::string &name):
out(out), ended(false), first(true)
{
out << type << " " << name << "[] = {\n";
}
Array::~Array()
{
assert(ended);
}
void Array::item(const std::string& val, const std::string& newComment)
{
if (!first) {
out << ", ";
if (!comment.empty())
out << "// " << comment;
out << "\n";
} else {
first = false;
}
comment = newComment;
out << " " << val;
}
void Array::endArray()
{
assert(!ended);
ended = true;
if (!comment.empty())
out << " // " << comment;
out << "\n};\n\n";
}
void CodePrinter::issueError(const string& err)
{
std::cerr << err << "\n";
exit(-1);
}
std::string CodePrinter::stringFromInt(int val)
{
std::stringstream out;
out << val;
return out.str();
}
ostream& CodePrinter::mInd(int ind)
{
for (int i = 0; i < ind; ++i)
*mStream << ' ';
return *mStream;
}
static bool isWhitespaceString(const string& str)
{
for (unsigned c = 0; c < str.length(); ++c) {
if (!WTF::isASCIISpace(str[c]))
return false;
}
return true;
}
static StringList splitLines(const string& in)
{
StringList lines;
string curLine;
for (unsigned c = 0; c < in.length(); ++c) {
if (in[c] == '\n') {
lines.push_back(curLine);
curLine = "";
} else {
curLine += in[c];
}
}
return lines;
}
void CodePrinter::printCode(ostream& out, int baseIndent, const string& code, int baseLine)
{
StringList lines = splitLines(code);
if (!lines.empty() && isWhitespaceString(lines.front())) {
++baseLine;
lines.erase(lines.begin());
}
if (!lines.empty() && isWhitespaceString(lines.back()))
lines.pop_back();
out << "#line " << baseLine << " \"codes.def\"\n";
// Compute "leading" whitespace, from codes.def indentation
unsigned minWhiteSpace = 100000;
for (unsigned c = 0; c < lines.size(); ++c) {
const string& line = lines[c];
if (isWhitespaceString(line))
continue;
unsigned ws = 0;
while (ws < line.length() && WTF::isASCIISpace(line[ws]))
++ws;
if (ws < minWhiteSpace)
minWhiteSpace = ws;
}
// Print out w/it stripped, and replaced with the indent
// specified by the generator
for (unsigned c = 0; c < lines.size(); ++c) {
const string& line = lines[c];
if (line.length() < minWhiteSpace)
out << "\n";
else {
for (int c = 0; c < baseIndent; ++c)
out << ' ';
out << line.substr(minWhiteSpace) << "\n";
}
}
}
// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;