blob: 1a84b4956d6201bcd0f33dfb1ef337973116ede7 [file] [log] [blame]
#include "aidl_language.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include "aidl_language_y.hpp"
#include "parse_helpers.h"
#ifdef _WIN32
int isatty(int fd)
{
return (fd == 0);
}
#endif
using std::string;
using std::cerr;
using std::endl;
using android::aidl::cpp_strdup;
Parser *psGlobal = NULL;
ParserCallbacks* g_callbacks = NULL; // &k_parserCallbacks;
char const* g_currentPackage = NULL;
void yylex_init(void **);
void yylex_destroy(void *);
void yyset_in(FILE *f, void *);
int yyparse(Parser*);
YY_BUFFER_STATE yy_scan_string(const char *, void *);
void yy_delete_buffer(YY_BUFFER_STATE, void *);
Parser::Parser(const string& filename)
: filename_(filename) {
yylex_init(&scanner_);
}
Parser::~Parser() {
if (buffer_is_valid_)
yy_delete_buffer(buffer_, scanner_);
yylex_destroy(scanner_);
}
AidlType::AidlType(const std::string& name, unsigned line,
const std::string& comments, bool is_array)
: name_(name),
line_(line),
is_array_(is_array),
comments_(comments) {}
string AidlType::ToString() const {
return name_ + (is_array_ ? "[]" : "");
}
AidlArgument::AidlArgument(AidlArgument::Direction direction, AidlType* type,
buffer_type name)
: type_(type),
direction_(direction),
direction_specified_(true),
name_(name.data),
line_(name.lineno) {}
AidlArgument::AidlArgument(AidlType* type, buffer_type name)
: type_(type),
direction_(AidlArgument::IN_DIR),
direction_specified_(false),
name_(name.data),
line_(name.lineno) {}
string AidlArgument::ToString() const {
string ret;
if (direction_specified_) {
switch(direction_) {
case AidlArgument::IN_DIR:
ret += "in ";
break;
case AidlArgument::OUT_DIR:
ret += "out ";
break;
case AidlArgument::INOUT_DIR:
ret += "inout ";
break;
}
}
ret += type_->ToString();
ret += " ";
ret += name_;
return ret;
}
AidlMethod::AidlMethod(bool oneway, AidlType* type, std::string name,
std::vector<std::unique_ptr<AidlArgument>>* args,
unsigned line, std::string comments, int id)
: oneway_(oneway),
comments_(comments),
type_(type),
name_(name),
line_(line),
arguments_(std::move(*args)),
id_(id) {
has_id_ = true;
delete args;
}
AidlMethod::AidlMethod(bool oneway, AidlType* type, std::string name,
std::vector<std::unique_ptr<AidlArgument>>* args,
unsigned line, std::string comments)
: AidlMethod(oneway, type, name, args, line, comments, 0) {
has_id_ = false;
}
string Parser::FileName() {
return filename_;
}
string Parser::Package() {
return g_currentPackage ? g_currentPackage : "";
}
void Parser::ReportError(const string& err) {
/* FIXME: We're printing out the line number as -1. We used to use yylineno
* (which was NEVER correct even before reentrant parsing). Now we'll need
* another way.
*/
cerr << filename_ << ":" << -1 << ": " << err << endl;
error_ = 1;
}
bool Parser::FoundNoErrors() {
return error_ == 0;
}
void *Parser::Scanner() {
return scanner_;
}
bool Parser::OpenFileFromDisk() {
FILE *in = fopen(FileName().c_str(), "r");
if (! in)
return false;
yyset_in(in, Scanner());
return true;
}
void Parser::SetFileContents(const std::string& contents) {
if (buffer_is_valid_)
yy_delete_buffer(buffer_, scanner_);
buffer_ = yy_scan_string(contents.c_str(), scanner_);
buffer_is_valid_ = true;
}
bool Parser::RunParser() {
int ret = yy::parser(this).parse();
delete[] g_currentPackage;
g_currentPackage = NULL;
return ret == 0 && error_ == 0;
}
void Parser::SetDocument(document_item_type *d)
{
document_ = d;
}
void Parser::AddImport(const buffer_type& statement)
{
import_info* import = new import_info();
memset(import, 0, sizeof(import_info));
import->from = cpp_strdup(this->FileName().c_str());
import->statement.lineno = statement.lineno;
import->statement.data = cpp_strdup(statement.data);
import->statement.extra = NULL;
import->next = imports_;
import->neededClass = android::aidl::parse_import_statement(statement.data);
imports_ = import;
}
document_item_type *Parser::GetDocument() const
{
return document_;
}
import_info *Parser::GetImports() const
{
return imports_;
}