aidl_language.cpp revision 3c6df36e1b5b1b14a7f8863d05e67dfd6caa51f7
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
23void yylex_init(void **);
24void yylex_destroy(void *);
25void yyset_in(FILE *f, void *);
26int yyparse(Parser*);
27YY_BUFFER_STATE yy_scan_string(const char *, void *);
28void yy_delete_buffer(YY_BUFFER_STATE, void *);
29
30Parser::Parser(const string& filename)
31    : filename_(filename) {
32  yylex_init(&scanner_);
33}
34
35Parser::~Parser() {
36  if (buffer_is_valid_)
37    yy_delete_buffer(buffer_, scanner_);
38  yylex_destroy(scanner_);
39}
40
41AidlType::AidlType(const std::string& name, unsigned line,
42                   const std::string& comments, bool is_array)
43    : name_(name),
44      line_(line),
45      is_array_(is_array),
46      comments_(comments) {}
47
48string AidlType::ToString() const {
49  return name_ + (is_array_ ? "[]" : "");
50}
51
52AidlArgument::AidlArgument(AidlArgument::Direction direction, AidlType* type,
53                           std::string name, unsigned line)
54    : type_(type),
55      direction_(direction),
56      direction_specified_(true),
57      name_(name),
58      line_(line) {}
59
60AidlArgument::AidlArgument(AidlType* type, std::string name, unsigned line)
61    : type_(type),
62      direction_(AidlArgument::IN_DIR),
63      direction_specified_(false),
64      name_(name),
65      line_(line) {}
66
67string AidlArgument::ToString() const {
68  string ret;
69
70  if (direction_specified_) {
71    switch(direction_) {
72    case AidlArgument::IN_DIR:
73      ret += "in ";
74      break;
75    case AidlArgument::OUT_DIR:
76      ret += "out ";
77      break;
78    case AidlArgument::INOUT_DIR:
79      ret += "inout ";
80      break;
81    }
82  }
83
84  ret += type_->ToString();
85  ret += " ";
86  ret += name_;
87
88  return ret;
89}
90
91AidlMethod::AidlMethod(bool oneway, AidlType* type, std::string name,
92                       std::vector<std::unique_ptr<AidlArgument>>* args,
93                       unsigned line, std::string comments, int id)
94    : oneway_(oneway),
95      comments_(comments),
96      type_(type),
97      name_(name),
98      line_(line),
99      arguments_(std::move(*args)),
100      id_(id) {
101  has_id_ = true;
102  delete args;
103}
104
105AidlMethod::AidlMethod(bool oneway, AidlType* type, std::string name,
106                       std::vector<std::unique_ptr<AidlArgument>>* args,
107                       unsigned line, std::string comments)
108    : AidlMethod(oneway, type, name, args, line, comments, 0) {
109  has_id_ = false;
110}
111
112void Parser::ReportError(const string& err) {
113  /* FIXME: We're printing out the line number as -1. We used to use yylineno
114   * (which was NEVER correct even before reentrant parsing). Now we'll need
115   * another way.
116   */
117  cerr << filename_ << ":" << -1 << ": " << err << endl;
118  error_ = 1;
119}
120
121bool Parser::OpenFileFromDisk() {
122  FILE *in = fopen(FileName().c_str(), "r");
123
124  if (! in)
125    return false;
126
127  yyset_in(in, Scanner());
128  return true;
129}
130
131void Parser::SetFileContents(const std::string& contents) {
132  if (buffer_is_valid_)
133    yy_delete_buffer(buffer_, scanner_);
134
135  buffer_ = yy_scan_string(contents.c_str(), scanner_);
136  buffer_is_valid_ = true;
137}
138
139bool Parser::RunParser() {
140  int ret = yy::parser(this).parse();
141
142  return ret == 0 && error_ == 0;
143}
144
145void Parser::AddImport(std::vector<std::string>* terms, unsigned line) {
146  std::string data;
147  bool first = true;
148
149  /* NOTE: This string building code is duplicated from below. We haven't
150   * factored it out into a function because it's hoped that when import_info
151   * becomes a class we won't need this anymore.
152   **/
153  for (const auto& term : *terms) {
154      if (first)
155          data = term;
156      else
157          data += '.' + term;
158  }
159
160  import_info* import = new import_info();
161  memset(import, 0, sizeof(import_info));
162  import->from = cpp_strdup(this->FileName().c_str());
163  import->next = imports_;
164  import->line = line;
165  import->neededClass = cpp_strdup(data.c_str());
166  imports_ = import;
167
168  delete terms;
169}
170
171void Parser::SetPackage(std::vector<std::string> *terms) {
172    bool first = true;
173
174    for (const auto& term : *terms) {
175        if (first)
176            package_ = term;
177        else
178            package_ += '.' + term;
179    }
180
181    delete terms;
182}
183