aidl_language.cpp revision f7a421c02d43c3289ca45f0d5ccdf8d27e605f5a
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, bool is_array)
48    : name_(name),
49      line_(line),
50      is_array_(is_array),
51      comments_(comments) {}
52
53string AidlType::ToString() const {
54  return name_ + (is_array_ ? "[]" : "");
55}
56
57AidlArgument::AidlArgument(AidlArgument::Direction direction, AidlType* type,
58                           buffer_type name)
59    : type_(type),
60      direction_(direction),
61      direction_specified_(true),
62      name_(name.data),
63      line_(name.lineno) {}
64
65AidlArgument::AidlArgument(AidlType* type, buffer_type name)
66    : type_(type),
67      direction_(AidlArgument::IN_DIR),
68      direction_specified_(false),
69      name_(name.data),
70      line_(name.lineno) {}
71
72string AidlArgument::ToString() const {
73  string ret;
74
75  if (direction_specified_) {
76    switch(direction_) {
77    case AidlArgument::IN_DIR:
78      ret += "in ";
79      break;
80    case AidlArgument::OUT_DIR:
81      ret += "out ";
82      break;
83    case AidlArgument::INOUT_DIR:
84      ret += "inout ";
85      break;
86    }
87  }
88
89  ret += type_->ToString();
90  ret += " ";
91  ret += name_;
92
93  return ret;
94}
95
96AidlMethod::AidlMethod(bool oneway, AidlType* type, std::string name,
97                       std::vector<std::unique_ptr<AidlArgument>>* args,
98                       unsigned line, std::string comments, int id)
99    : oneway_(oneway),
100      comments_(comments),
101      type_(type),
102      name_(name),
103      line_(line),
104      arguments_(std::move(*args)),
105      id_(id) {
106  has_id_ = true;
107  delete args;
108}
109
110AidlMethod::AidlMethod(bool oneway, AidlType* type, std::string name,
111                       std::vector<std::unique_ptr<AidlArgument>>* args,
112                       unsigned line, std::string comments)
113    : AidlMethod(oneway, type, name, args, line, comments, 0) {
114  has_id_ = false;
115}
116
117string Parser::FileName() {
118  return filename_;
119}
120
121string Parser::Package() {
122  return g_currentPackage ? g_currentPackage : "";
123}
124
125void Parser::ReportError(const string& err) {
126  /* FIXME: We're printing out the line number as -1. We used to use yylineno
127   * (which was NEVER correct even before reentrant parsing). Now we'll need
128   * another way.
129   */
130  cerr << filename_ << ":" << -1 << ": " << err << endl;
131  error_ = 1;
132}
133
134bool Parser::FoundNoErrors() {
135  return error_ == 0;
136}
137
138void *Parser::Scanner() {
139  return scanner_;
140}
141
142bool Parser::OpenFileFromDisk() {
143  FILE *in = fopen(FileName().c_str(), "r");
144
145  if (! in)
146    return false;
147
148  yyset_in(in, Scanner());
149  return true;
150}
151
152void Parser::SetFileContents(const std::string& contents) {
153  if (buffer_is_valid_)
154    yy_delete_buffer(buffer_, scanner_);
155
156  buffer_ = yy_scan_string(contents.c_str(), scanner_);
157  buffer_is_valid_ = true;
158}
159
160bool Parser::RunParser() {
161  int ret = yy::parser(this).parse();
162
163  delete[] g_currentPackage;
164  g_currentPackage = NULL;
165
166  return ret == 0 && error_ == 0;
167}
168
169void Parser::SetDocument(document_item_type *d)
170{
171  document_ = d;
172}
173
174void Parser::AddImport(const buffer_type& statement)
175{
176  import_info* import = new import_info();
177  memset(import, 0, sizeof(import_info));
178  import->from = cpp_strdup(this->FileName().c_str());
179  import->statement.lineno = statement.lineno;
180  import->statement.data = cpp_strdup(statement.data);
181  import->statement.extra = NULL;
182  import->next = imports_;
183  import->neededClass = android::aidl::parse_import_statement(statement.data);
184  imports_ = import;
185}
186
187document_item_type *Parser::GetDocument() const
188{
189  return document_;
190}
191
192import_info *Parser::GetImports() const
193{
194  return imports_;
195}
196