xref: /aosp_15_r20/development/vndk/tools/header-checker/src/utils/string_utils.cpp (revision 90c8c64db3049935a07c6143d7fd006e26f8ecca)
1 // Copyright (C) 2019 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 express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "utils/string_utils.h"
16 
17 #include <fnmatch.h>
18 
19 #include <algorithm>
20 #include <cctype>
21 #include <cstdlib>
22 #include <optional>
23 #include <string>
24 #include <utility>
25 
26 
27 namespace header_checker {
28 namespace utils {
29 
30 
Trim(std::string_view s)31 std::string_view Trim(std::string_view s) {
32   std::string::size_type start = s.find_first_not_of(" \t\r\n");
33   if (start == std::string::npos) {
34     return "";
35   }
36   std::string::size_type end = s.find_last_not_of(" \t\r\n");
37   if (end == std::string::npos) {
38     return s.substr(start);
39   }
40   return s.substr(start, end - start + 1);
41 }
42 
43 
StartsWith(std::string_view s,std::string_view prefix)44 bool StartsWith(std::string_view s, std::string_view prefix) {
45   return s.size() >= prefix.size() && s.compare(0, prefix.size(), prefix) == 0;
46 }
47 
48 
EndsWith(std::string_view s,std::string_view suffix)49 bool EndsWith(std::string_view s, std::string_view suffix) {
50   return (s.size() >= suffix.size() &&
51           s.compare(s.size() - suffix.size(), suffix.size(), suffix) == 0);
52 }
53 
54 
Split(std::string_view s,std::string_view delim_chars)55 std::vector<std::string_view> Split(std::string_view s,
56                                     std::string_view delim_chars) {
57   std::vector<std::string_view> res;
58   std::string::size_type pos = 0;
59   while (true) {
60     pos = s.find_first_not_of(delim_chars, pos);
61     if (pos == std::string::npos) {
62       break;
63     }
64 
65     std::string::size_type end = s.find_first_of(delim_chars, pos + 1);
66     if (end == std::string::npos) {
67       res.push_back(s.substr(pos));
68       break;
69     }
70 
71     res.push_back(s.substr(pos, end - pos));
72     pos = end + 1;
73   }
74   return res;
75 }
76 
77 
ParseInt(const std::string & s)78 std::optional<int> ParseInt(const std::string &s) {
79   const char *start = s.c_str();
80   if (*start == '\0') {
81     return {};
82   }
83 
84   char *endptr = nullptr;
85   long int res = ::strtol(start, &endptr, 10);
86   if (*endptr != '\0') {
87     return {};
88   }
89 
90   return static_cast<int>(res);
91 }
92 
93 
ParseBool(const std::string & s)94 bool ParseBool(const std::string &s) {
95   std::string value(s);
96   std::transform(value.begin(), value.end(), value.begin(),
97                  [](unsigned char c){ return std::tolower(c); }
98                 );
99   return (value == "true" || value == "on" || value == "1");
100 }
101 
102 
IsGlobPattern(std::string_view s)103 bool IsGlobPattern(std::string_view s) {
104   return s.find_first_of("*?[") != std::string::npos;
105 }
106 
107 
HasMatchingGlobPattern(const StringSet & patterns,const char * text)108 bool HasMatchingGlobPattern(const StringSet &patterns, const char *text) {
109   for (auto &&pattern : patterns) {
110     if (fnmatch(pattern.c_str(), text, 0) == 0) {
111       return true;
112     }
113   }
114   return false;
115 }
116 
117 
118 }  // namespace utils
119 }  // namespace header_checker
120