Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:27:23

0001 // Copyright 2020 The Abseil Authors.
0002 //
0003 // Licensed under the Apache License, Version 2.0 (the "License");
0004 // you may not use this file except in compliance with the License.
0005 // You may obtain a copy of the License at
0006 //
0007 //      https://www.apache.org/licenses/LICENSE-2.0
0008 //
0009 // Unless required by applicable law or agreed to in writing, software
0010 // distributed under the License is distributed on an "AS IS" BASIS,
0011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0012 // See the License for the specific language governing permissions and
0013 // limitations under the License.
0014 
0015 #ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_
0016 #define ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_
0017 
0018 #include <algorithm>
0019 
0020 #include "absl/base/attributes.h"
0021 #include "absl/strings/internal/str_format/arg.h"
0022 #include "absl/strings/internal/str_format/constexpr_parser.h"
0023 #include "absl/strings/internal/str_format/extension.h"
0024 
0025 // Compile time check support for entry points.
0026 
0027 #ifndef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
0028 // We disable format checker under vscode intellisense compilation.
0029 // See https://github.com/microsoft/vscode-cpptools/issues/3683 for
0030 // more details.
0031 #if ABSL_HAVE_ATTRIBUTE(enable_if) && !defined(__native_client__) && \
0032     !defined(__INTELLISENSE__)
0033 #define ABSL_INTERNAL_ENABLE_FORMAT_CHECKER 1
0034 #endif  // ABSL_HAVE_ATTRIBUTE(enable_if) && !defined(__native_client__) &&
0035         // !defined(__INTELLISENSE__)
0036 #endif  // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
0037 
0038 namespace absl {
0039 ABSL_NAMESPACE_BEGIN
0040 namespace str_format_internal {
0041 
0042 #ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
0043 
0044 template <FormatConversionCharSet... C>
0045 constexpr bool ValidFormatImpl(string_view format) {
0046   int next_arg = 0;
0047   const char* p = format.data();
0048   const char* const end = p + format.size();
0049   constexpr FormatConversionCharSet
0050       kAllowedConvs[(std::max)(sizeof...(C), size_t{1})] = {C...};
0051   bool used[(std::max)(sizeof...(C), size_t{1})]{};
0052   constexpr int kNumArgs = sizeof...(C);
0053   while (p != end) {
0054     while (p != end && *p != '%') ++p;
0055     if (p == end) {
0056       break;
0057     }
0058     if (p + 1 >= end) return false;
0059     if (p[1] == '%') {
0060       // %%
0061       p += 2;
0062       continue;
0063     }
0064 
0065     UnboundConversion conv(absl::kConstInit);
0066     p = ConsumeUnboundConversion(p + 1, end, &conv, &next_arg);
0067     if (p == nullptr) return false;
0068     if (conv.arg_position <= 0 || conv.arg_position > kNumArgs) {
0069       return false;
0070     }
0071     if (!Contains(kAllowedConvs[conv.arg_position - 1], conv.conv)) {
0072       return false;
0073     }
0074     used[conv.arg_position - 1] = true;
0075     for (auto extra : {conv.width, conv.precision}) {
0076       if (extra.is_from_arg()) {
0077         int pos = extra.get_from_arg();
0078         if (pos <= 0 || pos > kNumArgs) return false;
0079         used[pos - 1] = true;
0080         if (!Contains(kAllowedConvs[pos - 1], '*')) {
0081           return false;
0082         }
0083       }
0084     }
0085   }
0086   if (sizeof...(C) != 0) {
0087     for (bool b : used) {
0088       if (!b) return false;
0089     }
0090   }
0091   return true;
0092 }
0093 
0094 #endif  // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
0095 
0096 }  // namespace str_format_internal
0097 ABSL_NAMESPACE_END
0098 }  // namespace absl
0099 
0100 #endif  // ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_