| // Copyright 2019 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. |
| |
| #include "tools/kazoo/output_util.h" |
| |
| #include "src/lib/fxl/logging.h" |
| #include "src/lib/fxl/strings/join_strings.h" |
| |
| bool CopyrightHeaderWithCppComments(Writer* writer) { |
| return writer->Puts(R"(// Copyright 2019 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. |
| |
| // WARNING: THIS FILE IS MACHINE GENERATED BY //tools/kazoo. DO NOT EDIT. |
| |
| )"); |
| } |
| |
| bool CopyrightHeaderWithHashComments(Writer* writer) { |
| return writer->Puts(R"(# Copyright 2019 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. |
| |
| # WARNING: THIS FILE IS MACHINE GENERATED BY //tools/kazoo. DO NOT EDIT. |
| |
| )"); |
| } |
| |
| void MapRequestResponseToCAbi(const Struct& request, const Struct& response, Type* return_type, |
| std::vector<StructMember>* arguments) { |
| FXL_DCHECK(arguments->empty()); |
| for (const auto& m : request.members()) { |
| StructMember copy = m; |
| if (std::holds_alternative<TypeHandle>(copy.type())) { |
| copy.set_handle_use("handle_use"); |
| } |
| arguments->emplace_back(copy); |
| } |
| if (response.members().size() == 0) { |
| *return_type = Type(TypeVoid{}); |
| } else { |
| *return_type = response.members()[0].type(); |
| for (size_t i = 1; i < response.members().size(); ++i) { |
| const StructMember& m = response.members()[i]; |
| StructMember copy = m.CopyAsPointerTo(); |
| copy.set_optional(false); |
| if (std::holds_alternative<TypeHandle>( |
| m.type())) { // Note, checking m, not copy as it's always TypePointer. |
| copy.set_handle_use("handle_acquire"); |
| } |
| arguments->push_back(copy); |
| } |
| } |
| } |
| |
| std::string ToLowerAscii(const std::string& input) { |
| std::string ret = input; |
| std::transform(ret.begin(), ret.end(), ret.begin(), fxl::ToLowerASCII); |
| return ret; |
| } |
| |
| std::string CamelToSnake(const std::string& camel_fidl) { |
| auto is_transition = [](char prev, char cur, char peek) { |
| enum { Upper, Lower, Other }; |
| auto categorize = [](char c) { |
| if (c == 0) |
| return Other; |
| if (c >= 'a' && c <= 'z') |
| return Lower; |
| if (c >= 'A' && c <= 'Z') |
| return Upper; |
| if ((c >= '0' && c <= '9') || c == '_') |
| return Other; |
| FXL_DCHECK(false); |
| return Other; |
| }; |
| auto prev_type = categorize(prev); |
| auto cur_type = categorize(cur); |
| auto peek_type = categorize(peek); |
| |
| bool lower_to_upper = prev_type != Upper && cur_type == Upper; |
| bool multiple_caps_to_lower = |
| peek && (prev_type == Upper && cur_type == Upper && peek_type == Lower); |
| |
| return lower_to_upper || multiple_caps_to_lower; |
| }; |
| std::vector<std::string> parts; |
| char prev = 0; |
| std::string current_word; |
| for (size_t i = 0; i < camel_fidl.size(); ++i) { |
| char cur = camel_fidl[i]; |
| char peek = i + 1 < camel_fidl.size() ? camel_fidl[i + 1] : 0; |
| if (current_word.size() > 1 && is_transition(prev, cur, peek)) { |
| parts.push_back(ToLowerAscii(current_word)); |
| current_word = cur; |
| } else { |
| current_word += cur; |
| } |
| prev = cur; |
| } |
| |
| if (!current_word.empty()) { |
| parts.push_back(ToLowerAscii(current_word)); |
| } |
| |
| return fxl::JoinStrings(parts, "_"); |
| } |