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