blob: 55bc361c008579393c6c8a635d8aee0d492f9432 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ZIRCON_SYSTEM_HOST_FIDL_INCLUDE_FIDL_UTILS_H_
#define ZIRCON_SYSTEM_HOST_FIDL_INCLUDE_FIDL_UTILS_H_
#include <errno.h>
#include <clocale>
#include <string>
#include <fidl/error_reporter.h>
#include <fidl/findings.h>
namespace fidl {
namespace utils {
enum class ParseNumericResult {
kSuccess,
kOutOfBounds,
kMalformed,
};
template <typename NumericType>
ParseNumericResult ParseNumeric(const std::string& input,
NumericType* out_value,
int base = 0) {
assert(out_value != nullptr);
// Set locale to "C" for numeric types, since all strtox() functions are locale-dependent
setlocale(LC_NUMERIC, "C");
const char* startptr = input.data();
if (base == 0 && 2 < input.size() && input[0] == '0' && (input[1] == 'b' || input[1] == 'B')) {
startptr += 2;
base = 2;
}
char* endptr;
if constexpr (std::is_unsigned<NumericType>::value) {
if (input[0] == '-')
return ParseNumericResult::kOutOfBounds;
errno = 0;
unsigned long long value = strtoull(startptr, &endptr, base);
if (errno != 0)
return ParseNumericResult::kMalformed;
if (value > std::numeric_limits<NumericType>::max())
return ParseNumericResult::kOutOfBounds;
*out_value = static_cast<NumericType>(value);
} else if constexpr (std::is_floating_point<NumericType>::value) {
errno = 0;
long double value = strtold(startptr, &endptr);
if (errno != 0)
return ParseNumericResult::kMalformed;
if (value > std::numeric_limits<NumericType>::max())
return ParseNumericResult::kOutOfBounds;
if (value < std::numeric_limits<NumericType>::lowest())
return ParseNumericResult::kOutOfBounds;
*out_value = static_cast<NumericType>(value);
} else {
errno = 0;
long long value = strtoll(startptr, &endptr, base);
if (errno != 0)
return ParseNumericResult::kMalformed;
if (value > std::numeric_limits<NumericType>::max())
return ParseNumericResult::kOutOfBounds;
if (value < std::numeric_limits<NumericType>::lowest())
return ParseNumericResult::kOutOfBounds;
*out_value = static_cast<NumericType>(value);
}
if (endptr != (input.c_str() + input.size()))
return ParseNumericResult::kMalformed;
return ParseNumericResult::kSuccess;
}
bool ends_with_underscore(const std::string& str);
bool has_adjacent_underscores(const std::string& str);
std::vector<std::string> id_to_words(const std::string& str);
bool is_konstant_case(const std::string& str);
bool is_lower_no_separator_case(const std::string& str);
bool is_lower_snake_case(const std::string& str);
bool is_upper_snake_case(const std::string& str);
bool is_lower_camel_case(const std::string& str);
bool is_upper_camel_case(const std::string& str);
std::string strip_konstant_k(const std::string& str);
std::string to_lower_no_separator_case(const std::string& str);
std::string to_lower_snake_case(const std::string& str);
std::string to_upper_snake_case(const std::string& str);
std::string to_lower_camel_case(const std::string& str);
std::string to_upper_camel_case(const std::string& str);
// Used by fidl-lint main() and for testing, this generates the linter error
// messages in the format required for the fidl::ErrorReporter.
void WriteFindingsToErrorReporter(
const Findings& findings, ErrorReporter* error_reporter);
} // namespace utils
} // namespace fidl
#endif // ZIRCON_SYSTEM_HOST_FIDL_INCLUDE_FIDL_UTILS_H_