aidl_language.cpp revision f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4
1#include "aidl_language.h"
2
3#include <iostream>
4#include <stdio.h>
5#include <stdlib.h>
6#include <string>
7
8#include "aidl_language_y.hpp"
9#include "parse_helpers.h"
10
11#ifdef _WIN32
12int isatty(int  fd)
13{
14    return (fd == 0);
15}
16#endif
17
18using std::string;
19using std::cerr;
20using std::endl;
21using android::aidl::cpp_strdup;
22
23Parser *psGlobal = NULL;
24ParserCallbacks* g_callbacks = NULL; // &k_parserCallbacks;
25char const* g_currentPackage = NULL;
26
27
28void yylex_init(void **);
29void yylex_destroy(void *);
30void yyset_in(FILE *f, void *);
31int yyparse(Parser*);
32YY_BUFFER_STATE yy_scan_string(const char *, void *);
33void yy_delete_buffer(YY_BUFFER_STATE, void *);
34
35Parser::Parser(const string& filename)
36    : filename_(filename) {
37  yylex_init(&scanner_);
38}
39
40Parser::~Parser() {
41  if (buffer_is_valid_)
42    yy_delete_buffer(buffer_, scanner_);
43  yylex_destroy(scanner_);
44}
45
46AidlType::AidlType(const std::string& name, unsigned line,
47                   const std::string& comments, unsigned dimension)
48    : name_(name),
49      line_(line),
50      dimension_(dimension),
51      comments_(comments) {}
52
53AidlType::AidlType(const std::string& name, unsigned line,
54                   const std::string& comments)
55    : AidlType(name, line, comments, 0) {}
56
57string AidlType::ToString() const {
58  return name_ + Brackets();
59}
60
61std::string AidlType::Brackets() const {
62  std::string result;
63
64  for (unsigned i = 0; i < dimension_; i++)
65    result += "[]";
66
67  return result;
68}
69
70AidlArgument::AidlArgument(AidlArgument::Direction direction, AidlType* type,
71                           buffer_type name)
72    : type_(type),
73      direction_(direction),
74      direction_specified_(true),
75      name_(name.data),
76      line_(name.lineno) {}
77
78AidlArgument::AidlArgument(AidlType* type, buffer_type name)
79    : type_(type),
80      direction_(AidlArgument::IN_DIR),
81      direction_specified_(false),
82      name_(name.data),
83      line_(name.lineno) {}
84
85string AidlArgument::ToString() const {
86  string ret;
87
88  if (direction_specified_) {
89    switch(direction_) {
90    case AidlArgument::IN_DIR:
91      ret += "in ";
92      break;
93    case AidlArgument::OUT_DIR:
94      ret += "out ";
95      break;
96    case AidlArgument::INOUT_DIR:
97      ret += "inout ";
98      break;
99    }
100  }
101
102  ret += type_->ToString();
103  ret += " ";
104  ret += name_;
105
106  return ret;
107}
108
109AidlMethod::AidlMethod(bool oneway, AidlType* type, std::string name,
110                       std::vector<std::unique_ptr<AidlArgument>>* args,
111                       unsigned line, std::string comments, int id)
112    : oneway_(oneway),
113      comments_(comments),
114      type_(type),
115      name_(name),
116      line_(line),
117      arguments_(std::move(*args)),
118      id_(id) {
119  has_id_ = true;
120  delete args;
121}
122
123AidlMethod::AidlMethod(bool oneway, AidlType* type, std::string name,
124                       std::vector<std::unique_ptr<AidlArgument>>* args,
125                       unsigned line, std::string comments)
126    : AidlMethod(oneway, type, name, args, line, comments, 0) {
127  has_id_ = false;
128}
129
130string Parser::FileName() {
131  return filename_;
132}
133
134string Parser::Package() {
135  return g_currentPackage ? g_currentPackage : "";
136}
137
138void Parser::ReportError(const string& err) {
139  /* FIXME: We're printing out the line number as -1. We used to use yylineno
140   * (which was NEVER correct even before reentrant parsing). Now we'll need
141   * another way.
142   */
143  cerr << filename_ << ":" << -1 << ": " << err << endl;
144  error_ = 1;
145}
146
147bool Parser::FoundNoErrors() {
148  return error_ == 0;
149}
150
151void *Parser::Scanner() {
152  return scanner_;
153}
154
155bool Parser::OpenFileFromDisk() {
156  FILE *in = fopen(FileName().c_str(), "r");
157
158  if (! in)
159    return false;
160
161  yyset_in(in, Scanner());
162  return true;
163}
164
165void Parser::SetFileContents(const std::string& contents) {
166  if (buffer_is_valid_)
167    yy_delete_buffer(buffer_, scanner_);
168
169  buffer_ = yy_scan_string(contents.c_str(), scanner_);
170  buffer_is_valid_ = true;
171}
172
173bool Parser::RunParser() {
174  int ret = yy::parser(this).parse();
175
176  delete[] g_currentPackage;
177  g_currentPackage = NULL;
178
179  return ret == 0 && error_ == 0;
180}
181
182void Parser::SetDocument(document_item_type *d)
183{
184  document_ = d;
185}
186
187void Parser::AddImport(const buffer_type& statement)
188{
189  import_info* import = new import_info();
190  memset(import, 0, sizeof(import_info));
191  import->from = cpp_strdup(this->FileName().c_str());
192  import->statement.lineno = statement.lineno;
193  import->statement.data = cpp_strdup(statement.data);
194  import->statement.extra = NULL;
195  import->next = imports_;
196  import->neededClass = android::aidl::parse_import_statement(statement.data);
197  imports_ = import;
198}
199
200document_item_type *Parser::GetDocument() const
201{
202  return document_;
203}
204
205import_info *Parser::GetImports() const
206{
207  return imports_;
208}
209