mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-25 03:12:49 +00:00
178 lines
4.5 KiB
C++
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;
|