1 // Copyright 2016 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expresso or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "android/base/StringParse.h"
16 
17 #include "android/base/threads/FunctorThread.h"
18 #include "aemu/base/testing/Utils.h"
19 #include <gtest/gtest.h>
20 
21 namespace android {
22 namespace base {
23 
testScanf()24 static void testScanf() {
25     static const char comma[] = "1,3";
26     static const char dot[] = "1.3";
27     static const char format[] = "%f%n";
28     float val = 0;
29     int n = 0;
30 
31     // Now make sure we parse floating point strings as expected.
32     EXPECT_EQ(1, sscanf(dot, format, &val, &n));
33     EXPECT_FLOAT_EQ(1, val);
34     EXPECT_EQ(1, n);
35     EXPECT_EQ(1, sscanf(comma, format, &val, &n));
36     EXPECT_FLOAT_EQ(1.3, val);
37     EXPECT_EQ(3, n);
38 
39     // C-Locale parsing should be able to parse strings with C locale
40     EXPECT_EQ(1, SscanfWithCLocale(dot, format, &val, &n));
41     EXPECT_FLOAT_EQ(1.3, val);
42     EXPECT_EQ(3, n);
43 
44     // And the regular parsing still works as it used to.
45     EXPECT_EQ(1, sscanf(dot, format, &val, &n));
46     EXPECT_FLOAT_EQ(1, val);
47     EXPECT_EQ(1, n);
48     EXPECT_EQ(1, sscanf(comma, format, &val, &n));
49     EXPECT_FLOAT_EQ(1.3, val);
50     EXPECT_EQ(3, n);
51 }
52 
53 // These are flaky as they depend on the build env.
TEST(StringParse,DISABLED_SscanfWithCLocale)54 TEST(StringParse, DISABLED_SscanfWithCLocale) {
55     auto scopedCommaLocale = setScopedCommaLocale();
56     testScanf();
57 }
58 
TEST(StringParse,DISABLED_SscanfWithCLocaleThreads)59 TEST(StringParse, DISABLED_SscanfWithCLocaleThreads) {
60     auto scopedCommaLocale = setScopedCommaLocale();
61 
62     std::vector<std::unique_ptr<FunctorThread>> threads;
63     for (int i = 0; i < 20; ++i) {
64         threads.emplace_back(new FunctorThread(&testScanf));
65     }
66     for (auto& t : threads) {
67         ASSERT_TRUE(t->start());
68     }
69     for (auto& t : threads) {
70         ASSERT_TRUE(t->wait());
71     }
72 }
73 
74 }  // namespace base
75 }  // namespace android
76