Files
android_development/tools/emulator/opengl/host/tools/emugen/EntryPoint.cpp
Stas Gurtovoy d32c2d9633 emulator opengl: system GLESv1 first commit.
This is the first commit for the GLESv1 implementation.
It also includes needed fixes in emugen to support const types.
Also, changed glFinish definition in gl.in to match the
definition as in gl.h.

Change-Id: I90262a1db6035a90af8db17984acecef6499847a
2011-06-17 17:18:45 +03:00

325 lines
10 KiB
C++

/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include "EntryPoint.h"
#include <string>
#include "TypeFactory.h"
#include "strUtils.h"
#include <sstream>
EntryPoint::EntryPoint()
{
reset();
}
EntryPoint::~EntryPoint()
{
}
void EntryPoint::reset()
{
m_unsupported = false;
m_customDecoder = false;
m_vars.empty();
}
bool parseTypeField(const std::string & f, std::string *vartype, std::string *varname)
{
size_t pos = 0, last;
bool done = false;
*vartype = "";
if (varname != NULL) *varname = "";
enum { ST_TYPE, ST_NAME, ST_END } state = ST_TYPE;
while(!done) {
std::string str = getNextToken(f, pos, &last, WHITESPACE);
if (str.size() == 0) break;
switch(state) {
case ST_TYPE:
if (str == "const") {
pos = last;
*vartype = "const ";
} else {
// must be a type name;
*vartype += str;
state = ST_NAME;
pos = last;
}
break;
case ST_NAME:
if (str.size() == 0) {
done = true;
} else if (str == "*") {
(*vartype) += "*";
pos = last;
} else if (varname == NULL) {
done = true;
} else {
while (str[0] == '*') {
(*vartype) += "*";
str[0] = ' ';
str = trim(str);
}
*varname = str;
done = true;
}
break;
case ST_END:
break;
}
}
return true;
}
// return true for valid line (need to get into the entry points list)
bool EntryPoint::parse(unsigned int lc, const std::string & str)
{
size_t pos, last;
std::string field;
reset();
std::string linestr = trim(str);
if (linestr.size() == 0) return false;
if (linestr.at(0) == '#') return false;
// skip PREFIX
field = getNextToken(linestr, 0, &last, "(");
pos = last + 1;
// return type
field = getNextToken(linestr, pos, &last, ",)");
std::string retTypeName;
if (!parseTypeField(field, &retTypeName, NULL)) {
fprintf(stderr, "line: %d: Parsing error in field <%s>\n", lc, field.c_str());
return false;
}
pos = last + 1;
const VarType *theType = TypeFactory::instance()->getVarTypeByName(retTypeName);
if (theType->name() == "UNKNOWN") {
fprintf(stderr, "UNKNOWN retval: %s\n", linestr.c_str());
}
m_retval.init(std::string(""), theType, std::string(""), Var::POINTER_OUT, std::string(""));
// function name
m_name = getNextToken(linestr, pos, &last, ",)");
pos = last + 1;
// parameters;
int nvars = 0;
while (pos < linestr.size() - 1) {
field = getNextToken(linestr, pos, &last, ",)");
std::string vartype, varname;
if (!parseTypeField(field, &vartype, &varname)) {
fprintf(stderr, "line: %d: Parsing error in field <%s>\n", lc, field.c_str());
return false;
}
nvars++;
const VarType *v = TypeFactory::instance()->getVarTypeByName(vartype);
if (v->id() == 0) {
fprintf(stderr, "%d: Unknown type: %s\n", lc, vartype.c_str());
} else {
if (varname == "" &&
!(v->name() == "void" && !v->isPointer())) {
std::ostringstream oss;
oss << "var" << nvars;
varname = oss.str();
}
m_vars.push_back(Var(varname, v, std::string(""), Var::POINTER_IN, ""));
}
pos = last + 1;
}
return true;
}
void EntryPoint::print(FILE *fp, bool newline,
const std::string & name_suffix,
const std::string & name_prefix,
const std::string & ctx_param ) const
{
fprintf(fp, "%s %s%s%s(",
m_retval.type()->name().c_str(),
name_prefix.c_str(),
m_name.c_str(),
name_suffix.c_str());
if (ctx_param != "") fprintf(fp, "%s ", ctx_param.c_str());
for (size_t i = 0; i < m_vars.size(); i++) {
if (m_vars[i].isVoid()) continue;
if (i != 0 || ctx_param != "") fprintf(fp, ", ");
fprintf(fp, "%s %s", m_vars[i].type()->name().c_str(),
m_vars[i].name().c_str());
}
fprintf(fp, ")%s", newline? "\n" : "");
}
Var * EntryPoint::var(const std::string & name)
{
Var *v = NULL;
for (size_t i = 0; i < m_vars.size(); i++) {
if (m_vars[i].name() == name) {
v = &m_vars[i];
break;
}
}
return v;
}
bool EntryPoint::hasPointers()
{
bool pointers = false;
if (m_retval.isPointer()) pointers = true;
if (!pointers) {
for (size_t i = 0; i < m_vars.size(); i++) {
if (m_vars[i].isPointer()) {
pointers = true;
break;
}
}
}
return pointers;
}
int EntryPoint::setAttribute(const std::string &line, size_t lc)
{
size_t pos = 0;
size_t last;
std::string token = getNextToken(line, 0, &last, WHITESPACE);
if (token == "len") {
pos = last;
std::string varname = getNextToken(line, pos, &last, WHITESPACE);
if (varname.size() == 0) {
fprintf(stderr, "ERROR: %u: Missing variable name in 'len' attribute\n", (unsigned int)lc);
return -1;
}
Var * v = var(varname);
if (v == NULL) {
fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n",
(unsigned int)lc, varname.c_str(), name().c_str());
return -2;
}
// set the size expression into var
pos = last;
v->setLenExpression(line.substr(pos));
} else if (token == "dir") {
pos = last;
std::string varname = getNextToken(line, pos, &last, WHITESPACE);
if (varname.size() == 0) {
fprintf(stderr, "ERROR: %u: Missing variable name in 'dir' attribute\n", (unsigned int)lc);
return -1;
}
Var * v = var(varname);
if (v == NULL) {
fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n",
(unsigned int)lc, varname.c_str(), name().c_str());
return -2;
}
pos = last;
std::string pointerDirStr = getNextToken(line, pos, &last, WHITESPACE);
if (pointerDirStr.size() == 0) {
fprintf(stderr, "ERROR: %u: missing pointer directions\n", (unsigned int)lc);
return -3;
}
if (pointerDirStr == "out") {
v->setPointerDir(Var::POINTER_OUT);
} else if (pointerDirStr == "inout") {
v->setPointerDir(Var::POINTER_INOUT);
} else if (pointerDirStr == "in") {
v->setPointerDir(Var::POINTER_IN);
} else {
fprintf(stderr, "ERROR: %u: unknow pointer direction %s\n", (unsigned int)lc, pointerDirStr.c_str());
}
} else if (token == "var_flag") {
pos = last;
std::string varname = getNextToken(line, pos, &last, WHITESPACE);
if (varname.size() == 0) {
fprintf(stderr, "ERROR: %u: Missing variable name in 'var_flag' attribute\n", (unsigned int)lc);
return -1;
}
Var * v = var(varname);
if (v == NULL) {
fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n",
(unsigned int)lc, varname.c_str(), name().c_str());
return -2;
}
pos = last;
std::string flag = getNextToken(line, pos, &last, WHITESPACE);
if (flag.size() == 0) {
fprintf(stderr, "ERROR: %u: missing flag\n", (unsigned int) lc);
return -3;
}
if (flag == "nullAllowed") {
if (v->isPointer()) {
v->setNullAllowed(true);
} else {
fprintf(stderr, "WARNING: %u: setting nullAllowed for non-pointer variable %s\n",
(unsigned int) lc, v->name().c_str());
}
} else {
fprintf(stderr, "WARNING: %u: unknow flag %s\n", (unsigned int)lc, flag.c_str());
}
} else if (token == "custom_pack") {
pos = last;
std::string varname = getNextToken(line, pos, &last, WHITESPACE);
if (varname.size() == 0) {
fprintf(stderr, "ERROR: %u: Missing variable name in 'custom_pack' attribute\n", (unsigned int)lc);
return -1;
}
Var * v = var(varname);
if (v == NULL) {
fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n",
(unsigned int)lc, varname.c_str(), name().c_str());
return -2;
}
// set the size expression into var
pos = last;
v->setPackExpression(line.substr(pos));
} else if (token == "flag") {
pos = last;
std::string flag = getNextToken(line, pos, &last, WHITESPACE);
if (flag.size() == 0) {
fprintf(stderr, "ERROR: %u: missing flag\n", (unsigned int) lc);
return -4;
}
if (flag == "unsupported") {
setUnsupported(true);
} else if (flag == "custom_decoder") {
setCustomDecoder(true);
} else {
fprintf(stderr, "WARNING: %u: unknown flag %s\n", (unsigned int)lc, flag.c_str());
}
} else {
fprintf(stderr, "WARNING: %u: unknown attribute %s\n", (unsigned int)lc, token.c_str());
}
return 0;
}