summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoshan Pius <rpius@google.com>2016-07-25 20:17:23 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-07-25 20:17:23 +0000
commitbb780700ae3258e229edd902e7dc18fbc527880d (patch)
treed3c40d338c96940cf5ed1ccb1cbeb4d946d2a814
parent4da2e74cb51eeea6f858e2ed85163f2fa640b57a (diff)
parent6de5776d32595a38ecf3d0592586cb2604c2156e (diff)
downloadandroid_system_tools_aidl-bb780700ae3258e229edd902e7dc18fbc527880d.tar.gz
android_system_tools_aidl-bb780700ae3258e229edd902e7dc18fbc527880d.tar.bz2
android_system_tools_aidl-bb780700ae3258e229edd902e7dc18fbc527880d.zip
aidl-cpp: Add support for hex values in const int am: 3b2203ddad
am: 6de5776d32 Change-Id: Ia767f29f60d8e332b3d881ed364f66e46ab1a7df
-rw-r--r--aidl.cpp2
-rw-r--r--aidl_language.cpp24
-rw-r--r--aidl_language.h3
-rw-r--r--aidl_language_l.ll3
-rw-r--r--aidl_language_y.yy6
-rw-r--r--aidl_unittest.cpp50
-rw-r--r--tests/aidl_test_client_primitives.cpp10
-rw-r--r--tests/android/aidl/tests/ITestService.aidl4
8 files changed, 99 insertions, 3 deletions
diff --git a/aidl.cpp b/aidl.cpp
index dea559a..513aaee 100644
--- a/aidl.cpp
+++ b/aidl.cpp
@@ -422,6 +422,8 @@ bool validate_constants(const AidlInterface& interface) {
success = false;
}
names.insert(int_constant->GetName());
+ // We've logged an error message for this on object construction.
+ success = success && int_constant->IsValid();
}
for (const std::unique_ptr<AidlStringConstant>& string_constant :
interface.GetStringConstants()) {
diff --git a/aidl_language.cpp b/aidl_language.cpp
index becca81..608c9f6 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -89,7 +89,29 @@ string AidlArgument::ToString() const {
AidlIntConstant::AidlIntConstant(std::string name, int32_t value)
: name_(name),
- value_(value) {}
+ value_(value),
+ is_valid_(true) {}
+
+AidlIntConstant::AidlIntConstant(std::string name,
+ std::string value,
+ unsigned line_number)
+ : name_(name) {
+ char *end;
+ // Use long long to ensure 0xFFFFFFFF -> -1 works on 32 bit devices.
+ unsigned long long int long_value = std::strtoull(value.c_str(), &end, 16);
+ // Ensure that we parsed the string fully and the value fits in int32.
+ if ((*end != '\0') ||
+ ((long_value == ULLONG_MAX) && (errno == ERANGE)) ||
+ (long_value > std::numeric_limits<uint32_t>::max())) {
+ is_valid_ = false;
+ LOG(ERROR) << "Found invalid int value '" << value
+ << "' on line " << line_number;
+ } else {
+ // Converting from unsigned long to signed integer.
+ value_ = long_value;
+ is_valid_ = true;
+ }
+}
AidlStringConstant::AidlStringConstant(std::string name,
std::string value,
diff --git a/aidl_language.h b/aidl_language.h
index 5db8d85..43b8a9d 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -158,16 +158,19 @@ class AidlMember : public AidlNode {
class AidlIntConstant : public AidlMember {
public:
AidlIntConstant(std::string name, int32_t value);
+ AidlIntConstant(std::string name, std::string value, unsigned line_number);
virtual ~AidlIntConstant() = default;
const std::string& GetName() const { return name_; }
int GetValue() const { return value_; }
+ bool IsValid() const { return is_valid_; }
AidlIntConstant* AsIntConstant() override { return this; }
private:
std::string name_;
int32_t value_;
+ bool is_valid_;
DISALLOW_COPY_AND_ASSIGN(AidlIntConstant);
};
diff --git a/aidl_language_l.ll b/aidl_language_l.ll
index b354481..a56758b 100644
--- a/aidl_language_l.ll
+++ b/aidl_language_l.ll
@@ -19,6 +19,7 @@
identifier [_a-zA-Z][_a-zA-Z0-9]*
whitespace ([ \t\r]+)
intvalue [-+]?(0|[1-9][0-9]*)
+hexvalue 0[x|X][0-9a-fA-F]+
%%
%{
@@ -90,6 +91,8 @@ oneway { yylval->token = new AidlToken("oneway", extra_text);
}
{intvalue} { yylval->integer = std::stoi(yytext);
return yy::parser::token::INTVALUE; }
+{hexvalue} { yylval->token = new AidlToken(yytext, extra_text);
+ return yy::parser::token::HEXVALUE; }
/* syntax error! */
. { printf("UNKNOWN(%s)", yytext);
diff --git a/aidl_language_y.yy b/aidl_language_y.yy
index 888e6b9..4ad6754 100644
--- a/aidl_language_y.yy
+++ b/aidl_language_y.yy
@@ -37,7 +37,7 @@ int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *);
AidlDocument* parcelable_list;
}
-%token<token> IDENTIFIER INTERFACE ONEWAY C_STR
+%token<token> IDENTIFIER INTERFACE ONEWAY C_STR HEXVALUE
%token<integer> INTVALUE
%token '(' ')' ',' '=' '[' ']' '<' '>' '.' '{' '}' ';'
@@ -192,6 +192,10 @@ constant_decl
$$ = new AidlIntConstant($3->GetText(), $5);
delete $3;
}
+ | CONST INT identifier '=' HEXVALUE ';' {
+ $$ = new AidlIntConstant($3->GetText(), $5->GetText(), @5.begin.line);
+ delete $3;
+ }
| CONST STRING identifier '=' C_STR ';' {
$$ = new AidlStringConstant($3->GetText(), $5->GetText(), @5.begin.line);
delete $3;
diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp
index 4677092..0d2ba53 100644
--- a/aidl_unittest.cpp
+++ b/aidl_unittest.cpp
@@ -282,6 +282,56 @@ TEST_F(AidlTest, FailOnDuplicateConstantNames) {
EXPECT_EQ(AidlError::BAD_CONSTANTS, reported_error);
}
+TEST_F(AidlTest, FailOnMalformedConstHexValue) {
+ AidlError reported_error;
+ EXPECT_EQ(nullptr,
+ Parse("p/IFoo.aidl",
+ R"(package p;
+ interface IFoo {
+ const int BAD_HEX_VALUE = 0xffffffffffffffffff;
+ }
+ )",
+ &cpp_types_,
+ &reported_error));
+ EXPECT_EQ(AidlError::BAD_CONSTANTS, reported_error);
+}
+
+TEST_F(AidlTest, ParsePositiveConstHexValue) {
+ AidlError reported_error;
+ auto cpp_parse_result =
+ Parse("p/IFoo.aidl",
+ R"(package p;
+ interface IFoo {
+ const int POSITIVE_HEX_VALUE = 0xf5;
+ }
+ )",
+ &cpp_types_,
+ &reported_error);
+ EXPECT_NE(nullptr, cpp_parse_result);
+ const auto& cpp_int_constants = cpp_parse_result->GetIntConstants();
+ EXPECT_EQ((size_t)1, cpp_int_constants.size());
+ EXPECT_EQ("POSITIVE_HEX_VALUE", cpp_int_constants[0]->GetName());
+ EXPECT_EQ(245, cpp_int_constants[0]->GetValue());
+}
+
+TEST_F(AidlTest, ParseNegativeConstHexValue) {
+ AidlError reported_error;
+ auto cpp_parse_result =
+ Parse("p/IFoo.aidl",
+ R"(package p;
+ interface IFoo {
+ const int NEGATIVE_HEX_VALUE = 0xffffffff;
+ }
+ )",
+ &cpp_types_,
+ &reported_error);
+ EXPECT_NE(nullptr, cpp_parse_result);
+ const auto& cpp_int_constants = cpp_parse_result->GetIntConstants();
+ EXPECT_EQ((size_t)1, cpp_int_constants.size());
+ EXPECT_EQ("NEGATIVE_HEX_VALUE", cpp_int_constants[0]->GetName());
+ EXPECT_EQ(-1, cpp_int_constants[0]->GetValue());
+}
+
TEST_F(AidlTest, UnderstandsNativeParcelables) {
io_delegate_.SetFileContents(
"p/Bar.aidl",
diff --git a/tests/aidl_test_client_primitives.cpp b/tests/aidl_test_client_primitives.cpp
index 9142abd..6f70f43 100644
--- a/tests/aidl_test_client_primitives.cpp
+++ b/tests/aidl_test_client_primitives.cpp
@@ -73,7 +73,15 @@ bool ConfirmPrimitiveRepeat(const sp<ITestService>& s) {
!RepeatPrimitive(
s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT7) ||
!RepeatPrimitive(
- s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT8)
+ s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT8) ||
+ !RepeatPrimitive(
+ s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT9) ||
+ !RepeatPrimitive(
+ s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT10) ||
+ !RepeatPrimitive(
+ s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT11) ||
+ !RepeatPrimitive(
+ s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT12)
) {
return false;
}
diff --git a/tests/android/aidl/tests/ITestService.aidl b/tests/android/aidl/tests/ITestService.aidl
index c9efecb..4de6925 100644
--- a/tests/android/aidl/tests/ITestService.aidl
+++ b/tests/android/aidl/tests/ITestService.aidl
@@ -30,6 +30,10 @@ interface ITestService {
const int TEST_CONSTANT6 = -0;
const int TEST_CONSTANT7 = +0;
const int TEST_CONSTANT8 = 0;
+ const int TEST_CONSTANT9 = 0x56;
+ const int TEST_CONSTANT10 = 0xa5;
+ const int TEST_CONSTANT11 = 0xFA;
+ const int TEST_CONSTANT12 = 0xffffffff;
const String STRING_TEST_CONSTANT = "foo";
const String STRING_TEST_CONSTANT2 = "bar";