diff --git a/.clang-format b/.clang-format index eeed4bea..c2333882 100644 --- a/.clang-format +++ b/.clang-format @@ -63,7 +63,7 @@ BraceWrapping: AfterUnion: true BeforeCatch: true BeforeElse: true -#IncludeBlocks: "Preserve" # for future version of clang +IncludeBlocks: "Preserve" # for future version of clang IncludeCategories: - Regex: "^<" # system includes Priority: 10 diff --git a/erpc_c/Makefile b/erpc_c/Makefile index 0637a6dc..71957b44 100644 --- a/erpc_c/Makefile +++ b/erpc_c/Makefile @@ -60,6 +60,7 @@ SOURCES += $(ERPC_C_ROOT)/infra/erpc_arbitrated_client_manager.cpp \ $(ERPC_C_ROOT)/infra/erpc_server.cpp \ $(ERPC_C_ROOT)/infra/erpc_simple_server.cpp \ $(ERPC_C_ROOT)/infra/erpc_transport_arbitrator.cpp \ + $(ERPC_C_ROOT)/infra/erpc_utils.cpp \ $(ERPC_C_ROOT)/infra/erpc_pre_post_action.cpp \ $(ERPC_C_ROOT)/port/erpc_port_stdlib.cpp \ $(ERPC_C_ROOT)/port/erpc_threading_pthreads.cpp \ @@ -93,6 +94,7 @@ HEADERS += $(ERPC_C_ROOT)/config/erpc_config.h \ $(ERPC_C_ROOT)/infra/erpc_static_queue.hpp \ $(ERPC_C_ROOT)/infra/erpc_transport_arbitrator.hpp \ $(ERPC_C_ROOT)/infra/erpc_transport.hpp \ + $(ERPC_C_ROOT)/infra/erpc_utils.hpp \ $(ERPC_C_ROOT)/infra/erpc_client_server_common.hpp \ $(ERPC_C_ROOT)/infra/erpc_pre_post_action.h \ $(ERPC_C_ROOT)/port/erpc_setup_extensions.h \ diff --git a/erpc_c/infra/erpc_arbitrated_client_manager.hpp b/erpc_c/infra/erpc_arbitrated_client_manager.hpp index fa2e45a1..33b65ab7 100644 --- a/erpc_c/infra/erpc_arbitrated_client_manager.hpp +++ b/erpc_c/infra/erpc_arbitrated_client_manager.hpp @@ -63,7 +63,7 @@ class ArbitratedClientManager : public ClientManager * * @return TransportArbitrator * Transport arbitrator instance. */ - TransportArbitrator *getArbitrator(void) { return m_arbitrator; }; + TransportArbitrator * getArbitrator(void) { return m_arbitrator; }; protected: TransportArbitrator *m_arbitrator; //!< Optional transport arbitrator. May be NULL. diff --git a/erpc_c/infra/erpc_basic_codec.cpp b/erpc_c/infra/erpc_basic_codec.cpp index 4c3adaa1..7fc54407 100644 --- a/erpc_c/infra/erpc_basic_codec.cpp +++ b/erpc_c/infra/erpc_basic_codec.cpp @@ -161,37 +161,6 @@ void BasicCodec::writeNullFlag(bool isNull) write(static_cast(isNull ? null_flag_t::kIsNull : null_flag_t::kNotNull)); } -void BasicCodec::writeCallback(arrayOfFunPtr callbacks, uint8_t callbacksCount, funPtr callback) -{ - uint8_t i; - - erpc_assert(callbacksCount > 1U); - - // callbacks = callbacks table - for (i = 0; i < callbacksCount; i++) - { - if (callbacks[i] == callback) - { - write(i); - break; - } - if ((i + 1U) == callbacksCount) - { - updateStatus(kErpcStatus_UnknownCallback); - } - } -} - -void BasicCodec::writeCallback(funPtr callback1, funPtr callback2) -{ - // callbacks = callback directly - // When declared only one callback function no serialization is needed. - if (callback1 != callback2) - { - updateStatus(kErpcStatus_UnknownCallback); - } -} - void BasicCodec::startReadMessage(message_type_t &type, uint32_t &service, uint32_t &request, uint32_t &sequence) { uint32_t header; @@ -396,34 +365,6 @@ void BasicCodec::readNullFlag(bool &isNull) } } -void BasicCodec::readCallback(arrayOfFunPtr callbacks, uint8_t callbacksCount, funPtr *callback) -{ - uint8_t _tmp_local; - - erpc_assert(callbacksCount > 1U); - - // callbacks = callbacks table - read(_tmp_local); - if (isStatusOk()) - { - if (_tmp_local < callbacksCount) - { - *callback = callbacks[_tmp_local]; - } - else - { - *callback = NULL; - m_status = kErpcStatus_UnknownCallback; - } - } -} - -void BasicCodec::readCallback(funPtr callbacks1, funPtr *callback2) -{ - // callbacks = callback directly - *callback2 = callbacks1; -} - ERPC_MANUALLY_CONSTRUCTED_ARRAY_STATIC(BasicCodec, s_basicCodecManual, ERPC_CODEC_COUNT); Codec *BasicCodecFactory::create(void) diff --git a/erpc_c/infra/erpc_basic_codec.hpp b/erpc_c/infra/erpc_basic_codec.hpp index 204b9a9e..c39a0c64 100644 --- a/erpc_c/infra/erpc_basic_codec.hpp +++ b/erpc_c/infra/erpc_basic_codec.hpp @@ -189,23 +189,6 @@ class BasicCodec : public Codec * @param[in] isNull Null flag to send. */ virtual void writeNullFlag(bool isNull) override; - - /*! - * @brief Writes an order ID of callback function. - * - * @param[in] callbacks Pointer to array of callbacks. - * @param[in] callbacksCount Size of array of callbacks. - * @param[in] callback Callback which ID should be serialized. - */ - virtual void writeCallback(arrayOfFunPtr callbacks, uint8_t callbacksCount, funPtr callback) override; - - /*! - * @brief Writes an order ID of callback function. - * - * @param[in] callback1 Pointer to existing callback. - * @param[out] callback2 Callback which ID should be serialized. - */ - virtual void writeCallback(funPtr callback1, funPtr callback2) override; //@} //! @name Decoding @@ -350,23 +333,6 @@ class BasicCodec : public Codec * @param[in] isNull Null flag to read. */ virtual void readNullFlag(bool &isNull) override; - - /*! - * @brief Read an callback function id and return address of callback function. - * - * @param[in] callbacks Pointer to array of callbacks. - * @param[in] callbacksCount Size of array of callbacks. - * @param[out] callback Callback which is deserialized. Null in case of error. - */ - virtual void readCallback(arrayOfFunPtr callbacks, uint8_t callbacksCount, funPtr *callback) override; - - /*! - * @brief Read an callback function id and return address of callback function. - * - * @param[in] callback1 Pointer to existing callback. - * @param[out] callback2 Callback which is deserialized. - */ - virtual void readCallback(funPtr callbacks1, funPtr *callback2) override; //@} }; diff --git a/erpc_c/infra/erpc_client_manager.h b/erpc_c/infra/erpc_client_manager.h index 1a1dd801..2a301642 100644 --- a/erpc_c/infra/erpc_client_manager.h +++ b/erpc_c/infra/erpc_client_manager.h @@ -25,6 +25,8 @@ */ extern "C" { +#else +#include "erpc_common.h" #endif typedef void (*client_error_handler_t)(erpc_status_t err, diff --git a/erpc_c/infra/erpc_client_server_common.hpp b/erpc_c/infra/erpc_client_server_common.hpp index 0c172461..68ee2a94 100644 --- a/erpc_c/infra/erpc_client_server_common.hpp +++ b/erpc_c/infra/erpc_client_server_common.hpp @@ -10,8 +10,8 @@ #ifndef _EMBEDDED_RPC__CLIENTSERVERCOMMON_H_ #define _EMBEDDED_RPC__CLIENTSERVERCOMMON_H_ -#include "erpc_config_internal.h" #include "erpc_codec.hpp" +#include "erpc_config_internal.h" #if ERPC_MESSAGE_LOGGING #include "erpc_message_loggers.hpp" #endif @@ -66,7 +66,7 @@ class ClientServerCommon #endif #if ERPC_MESSAGE_LOGGING #ifdef ERPC_OTHER_INHERITANCE - , + , #else #define ERPC_OTHER_INHERITANCE 1 : @@ -75,7 +75,7 @@ class ClientServerCommon #endif #if ERPC_PRE_POST_ACTION #ifdef ERPC_OTHER_INHERITANCE - , + , #else #define ERPC_OTHER_INHERITANCE 1 : @@ -83,12 +83,15 @@ class ClientServerCommon PrePostAction() #endif #ifdef ERPC_OTHER_INHERITANCE - , + , #else #define ERPC_OTHER_INHERITANCE 1 : #endif - m_messageFactory(NULL), m_codecFactory(NULL), m_transport(NULL){}; + m_messageFactory(NULL) + , m_codecFactory(NULL) + , m_transport(NULL) + {}; /*! * @brief ClientServerCommon destructor diff --git a/erpc_c/infra/erpc_codec.hpp b/erpc_c/infra/erpc_codec.hpp index 14356fcd..c436f38b 100644 --- a/erpc_c/infra/erpc_codec.hpp +++ b/erpc_c/infra/erpc_codec.hpp @@ -15,8 +15,8 @@ #include "erpc_message_buffer.hpp" #include "erpc_transport.hpp" +#include #include -#include /*! * @addtogroup infra_codec @@ -257,23 +257,6 @@ class Codec * @param[in] isNull Null flag to send. */ virtual void writeNullFlag(bool isNull) = 0; - - /*! - * @brief Writes an order ID of callback function. - * - * @param[in] callbacks Pointer to array of callbacks. - * @param[in] callbacksCount Size of array of callbacks. - * @param[in] callback Callback which ID should be serialized. - */ - virtual void writeCallback(arrayOfFunPtr callbacks, uint8_t callbacksCount, funPtr callback) = 0; - - /*! - * @brief Writes an order ID of callback function. - * - * @param[in] callback1 Pointer to existing callback. - * @param[out] callback2 Callback which ID should be serialized. - */ - virtual void writeCallback(funPtr callback1, funPtr callback2) = 0; //@} //! @name Decoding @@ -410,23 +393,6 @@ class Codec */ virtual void readNullFlag(bool &isNull) = 0; - /*! - * @brief Read an callback function id and return address of callback function. - * - * @param[in] callbacks Pointer to array of callbacks. - * @param[in] callbacksCount Size of array of callbacks. - * @param[out] callback Callback which is deserialized. Null in case of error. - */ - virtual void readCallback(arrayOfFunPtr callbacks, uint8_t callbacksCount, funPtr *callback) = 0; - - /*! - * @brief Read an callback function id and return address of callback function. - * - * @param[in] callback1 Pointer to existing callback. - * @param[out] callback2 Callback which is deserialized. - */ - virtual void readCallback(funPtr callbacks1, funPtr *callback2) = 0; - protected: MessageBuffer m_buffer; /*!< Message buffer object */ MessageBuffer::Cursor m_cursor; /*!< Copy data to message buffers. */ diff --git a/erpc_c/infra/erpc_framed_transport.hpp b/erpc_c/infra/erpc_framed_transport.hpp index dac35770..580b0ab8 100644 --- a/erpc_c/infra/erpc_framed_transport.hpp +++ b/erpc_c/infra/erpc_framed_transport.hpp @@ -114,7 +114,7 @@ class FramedTransport : public Transport * * @return Crc16* Pointer to CRC-16 object containing crc-16 compute function. */ - virtual Crc16 *getCrc16() override; + virtual Crc16 *getCrc16(void) override; protected: Crc16 *m_crcImpl; /*!< CRC object. */ diff --git a/erpc_c/infra/erpc_manually_constructed.hpp b/erpc_c/infra/erpc_manually_constructed.hpp index 119c4a02..de4f9f7e 100644 --- a/erpc_c/infra/erpc_manually_constructed.hpp +++ b/erpc_c/infra/erpc_manually_constructed.hpp @@ -161,7 +161,7 @@ class ManuallyConstructed * @brief Returns information if object is free or is used. * * @return true Object is constructed and used. - * @return false Object wasn't constructer or it is destructed and free. + * @return false Object wasn't constructed or it was destructed already. */ bool isUsed(void) { return m_isConstructed; } diff --git a/erpc_c/infra/erpc_message_buffer.hpp b/erpc_c/infra/erpc_message_buffer.hpp index bfd67edd..d815ca74 100644 --- a/erpc_c/infra/erpc_message_buffer.hpp +++ b/erpc_c/infra/erpc_message_buffer.hpp @@ -308,9 +308,9 @@ class MessageBuffer Cursor &operator+=(uint16_t n); /*! - * @brief Substract operator return local buffer. + * @brief Subtract operator return local buffer. * - * @param[in] n Substracting with n. + * @param[in] n Subtracting with n. * * @return Current cursor instance. */ @@ -324,7 +324,7 @@ class MessageBuffer Cursor &operator++(void); /*! - * @brief Substract -1 operator. + * @brief Subtract -1 operator. * * @return Current cursor instance. */ diff --git a/erpc_c/infra/erpc_static_queue.hpp b/erpc_c/infra/erpc_static_queue.hpp index 2bedfeba..d1996fbb 100644 --- a/erpc_c/infra/erpc_static_queue.hpp +++ b/erpc_c/infra/erpc_static_queue.hpp @@ -11,6 +11,7 @@ #define __embedded_rpc__static_queue__ #include +#include /*! * @addtogroup infra_utility diff --git a/erpc_c/infra/erpc_transport_arbitrator.hpp b/erpc_c/infra/erpc_transport_arbitrator.hpp index 34bad73b..891ed7a3 100644 --- a/erpc_c/infra/erpc_transport_arbitrator.hpp +++ b/erpc_c/infra/erpc_transport_arbitrator.hpp @@ -65,7 +65,7 @@ class TransportArbitrator : public Transport * * @return Transport * Returns shared client/server transport. */ - Transport *getSharedTransport(void) { return m_sharedTransport; } + Transport * getSharedTransport(void) { return m_sharedTransport; } /*! * @brief This function set codec. @@ -79,7 +79,7 @@ class TransportArbitrator : public Transport * * @return Codec * Pointer to codec used within transport. */ - Codec *getCodec(void) { return m_codec; } + Codec * getCodec(void) { return m_codec; } /*! * @brief Prototype for receiving message. @@ -140,7 +140,7 @@ class TransportArbitrator : public Transport * * @return Crc16* Pointer to CRC-16 object containing crc-16 compute function. */ - virtual Crc16 *getCrc16(void) override; + virtual Crc16 * getCrc16(void) override; /*! * @brief Check if the underlying shared transport has a message diff --git a/erpc_c/infra/erpc_utils.cpp b/erpc_c/infra/erpc_utils.cpp new file mode 100644 index 00000000..f59acbb6 --- /dev/null +++ b/erpc_c/infra/erpc_utils.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 2023 ACRIOS Systems s.r.o. + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "erpc_utils.hpp" + +bool erpc::findIndexOfFunction(const arrayOfFunctionPtr_t sourceArrayOfFunctionPtr, uint16_t sourceArrayLength, + const functionPtr_t functionPtr, uint16_t &retVal) +{ + uint32_t index; + bool find = false; + for (index = 0; index < sourceArrayLength; index++) + { + if (sourceArrayOfFunctionPtr[index] == functionPtr) + { + retVal = index; + find = true; + break; + } + } + return find; +} diff --git a/erpc_c/infra/erpc_utils.hpp b/erpc_c/infra/erpc_utils.hpp new file mode 100644 index 00000000..9b2f97d5 --- /dev/null +++ b/erpc_c/infra/erpc_utils.hpp @@ -0,0 +1,17 @@ +/* + * Copyright 2023 ACRIOS Systems s.r.o. + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +namespace erpc { +typedef void *functionPtr_t; +typedef functionPtr_t *arrayOfFunctionPtr_t; + +bool findIndexOfFunction(const arrayOfFunctionPtr_t sourceArrayOfFunctionPtr, uint16_t sourceArrayLength, + const functionPtr_t functionPtr, uint16_t &retVal); +} diff --git a/erpc_c/port/erpc_serial.cpp b/erpc_c/port/erpc_serial.cpp index 9f94799d..2423ca8e 100644 --- a/erpc_c/port/erpc_serial.cpp +++ b/erpc_c/port/erpc_serial.cpp @@ -135,7 +135,7 @@ int serial_setup(int fd, speed_t speed) #ifdef __APPLE__ return ioctl(fd, IOSSIOSPEED, &speed); -#endif //#ifdef __APPLE__ +#endif // #ifdef __APPLE__ #endif // _WIN32 return 0; diff --git a/erpc_c/setup/erpc_transport_setup.h b/erpc_c/setup/erpc_transport_setup.h index bf36bda6..d72db62f 100644 --- a/erpc_c/setup/erpc_transport_setup.h +++ b/erpc_c/setup/erpc_transport_setup.h @@ -151,7 +151,6 @@ void erpc_transport_lpi2c_slave_deinit(erpc_transport_t transport); */ erpc_transport_t erpc_transport_lpspi_slave_init(void *baseAddr, uint32_t baudRate, uint32_t srcClock_Hz); - /*! * @brief Deinitialize LPSPI slave transport. * diff --git a/erpc_c/transports/erpc_dspi_slave_transport.cpp b/erpc_c/transports/erpc_dspi_slave_transport.cpp index 1c5a9487..b0f68a5b 100644 --- a/erpc_c/transports/erpc_dspi_slave_transport.cpp +++ b/erpc_c/transports/erpc_dspi_slave_transport.cpp @@ -8,9 +8,10 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include "erpc_dspi_slave_transport.hpp" + #include #include -#include "erpc_dspi_slave_transport.hpp" extern "C" { #include "board.h" diff --git a/erpc_c/transports/erpc_i2c_slave_transport.cpp b/erpc_c/transports/erpc_i2c_slave_transport.cpp index 991f864f..7fa3b52a 100644 --- a/erpc_c/transports/erpc_i2c_slave_transport.cpp +++ b/erpc_c/transports/erpc_i2c_slave_transport.cpp @@ -6,9 +6,10 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include "erpc_i2c_slave_transport.hpp" + #include #include -#include "erpc_i2c_slave_transport.hpp" extern "C" { #include "board.h" diff --git a/erpc_c/transports/erpc_i2c_slave_transport.hpp b/erpc_c/transports/erpc_i2c_slave_transport.hpp index bd10280a..425b2807 100644 --- a/erpc_c/transports/erpc_i2c_slave_transport.hpp +++ b/erpc_c/transports/erpc_i2c_slave_transport.hpp @@ -9,8 +9,8 @@ #ifndef _EMBEDDED_RPC__I2C_SLAVE_TRANSPORT_H_ #define _EMBEDDED_RPC__I2C_SLAVE_TRANSPORT_H_ -#include #include "erpc_config_internal.h" +#include #if ERPC_THREADS #include "erpc_threading.h" #endif diff --git a/erpc_c/transports/erpc_mu_transport.hpp b/erpc_c/transports/erpc_mu_transport.hpp index b2c38afe..16a819e1 100644 --- a/erpc_c/transports/erpc_mu_transport.hpp +++ b/erpc_c/transports/erpc_mu_transport.hpp @@ -48,7 +48,8 @@ extern "C" { #define MU_REG_COUNT (MU_RR_COUNT) /*!< Count of MU tx/rx registers to be used by this transport layer */ #endif /* ERPC_TRANSPORT_MU_USE_MCMGR */ -#if (defined(MIMXRT1187_cm7_SERIES) || defined(MIMXRT1187_cm33_SERIES) || defined(MIMXRT1189_cm7_SERIES) || defined(MIMXRT1189_cm33_SERIES)) +#if (defined(MIMXRT1187_cm7_SERIES) || defined(MIMXRT1187_cm33_SERIES) || defined(MIMXRT1189_cm7_SERIES) || \ + defined(MIMXRT1189_cm33_SERIES)) #define MU_TX_SHIFT (1UL << (MU_REG_COUNT - 1U)) #define MU_RX_SHIFT (1UL << (MU_REG_COUNT - 1U)) #define MU_RX_INTR_MASK (MU_RX_INTR(MU_RX_SHIFT)) diff --git a/erpc_c/transports/erpc_rpmsg_linux_transport.hpp b/erpc_c/transports/erpc_rpmsg_linux_transport.hpp index f849e951..ce13725c 100644 --- a/erpc_c/transports/erpc_rpmsg_linux_transport.hpp +++ b/erpc_c/transports/erpc_rpmsg_linux_transport.hpp @@ -38,7 +38,7 @@ class RPMsgLinuxTransport : public Transport * * @return RPMsgEndpoint * Rpmsg endpoint. */ - RPMsgEndpoint *getRpmsgEndpoint(void){ return m_endPoint; } + RPMsgEndpoint *getRpmsgEndpoint(void) { return m_endPoint; } /*! * @brief This function initializes Linux environment for sending and receiving messages. diff --git a/erpc_c/transports/erpc_rpmsg_lite_transport.hpp b/erpc_c/transports/erpc_rpmsg_lite_transport.hpp index ab4cb3c6..6537eae6 100644 --- a/erpc_c/transports/erpc_rpmsg_lite_transport.hpp +++ b/erpc_c/transports/erpc_rpmsg_lite_transport.hpp @@ -10,8 +10,8 @@ #ifndef _EMBEDDED_RPC__RPMSG_LITE_TRANSPORT_H_ #define _EMBEDDED_RPC__RPMSG_LITE_TRANSPORT_H_ -#include "erpc_crc16.hpp" #include "erpc_config_internal.h" +#include "erpc_crc16.hpp" #include "erpc_message_buffer.hpp" #include "erpc_rpmsg_lite_base_transport.hpp" #include "erpc_static_queue.hpp" diff --git a/erpc_c/transports/erpc_rpmsg_tty_rtos_transport.hpp b/erpc_c/transports/erpc_rpmsg_tty_rtos_transport.hpp index a1baf11b..30d3ee02 100644 --- a/erpc_c/transports/erpc_rpmsg_tty_rtos_transport.hpp +++ b/erpc_c/transports/erpc_rpmsg_tty_rtos_transport.hpp @@ -129,7 +129,7 @@ class RPMsgTTYRTOSTransport : public RPMsgBaseTransport * * @return Crc16* Pointer to CRC-16 object containing crc-16 compute function. */ - virtual Crc16 *getCrc16(void); + virtual Crc16 * getCrc16(void) override; protected: uint32_t m_dst_addr; /*!< Destination address used by rpmsg. */ diff --git a/erpc_c/transports/erpc_spi_master_transport.cpp b/erpc_c/transports/erpc_spi_master_transport.cpp index da4f36ee..20a216de 100644 --- a/erpc_c/transports/erpc_spi_master_transport.cpp +++ b/erpc_c/transports/erpc_spi_master_transport.cpp @@ -8,9 +8,10 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include #include "erpc_spi_master_transport.hpp" +#include + extern "C" { #include "board.h" #include "fsl_gpio.h" diff --git a/erpc_c/transports/erpc_spi_master_transport.hpp b/erpc_c/transports/erpc_spi_master_transport.hpp index 8614b623..e90e27a2 100644 --- a/erpc_c/transports/erpc_spi_master_transport.hpp +++ b/erpc_c/transports/erpc_spi_master_transport.hpp @@ -10,9 +10,10 @@ #ifndef _EMBEDDED_RPC__SPI_MASTER_TRANSPORT_H_ #define _EMBEDDED_RPC__SPI_MASTER_TRANSPORT_H_ +#include "erpc_framed_transport.hpp" + #include #include -#include "erpc_framed_transport.hpp" extern "C" { #include "fsl_spi.h" diff --git a/erpc_c/transports/erpc_spi_slave_transport.cpp b/erpc_c/transports/erpc_spi_slave_transport.cpp index dadd77de..f4d034b2 100644 --- a/erpc_c/transports/erpc_spi_slave_transport.cpp +++ b/erpc_c/transports/erpc_spi_slave_transport.cpp @@ -8,9 +8,10 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include "erpc_spi_slave_transport.hpp" + #include #include -#include "erpc_spi_slave_transport.hpp" extern "C" { #include "board.h" diff --git a/erpc_c/transports/erpc_spi_slave_transport.hpp b/erpc_c/transports/erpc_spi_slave_transport.hpp index 4a6de45a..bc4e22b9 100644 --- a/erpc_c/transports/erpc_spi_slave_transport.hpp +++ b/erpc_c/transports/erpc_spi_slave_transport.hpp @@ -10,8 +10,8 @@ #ifndef _EMBEDDED_RPC__SPI_SLAVE_TRANSPORT_H_ #define _EMBEDDED_RPC__SPI_SLAVE_TRANSPORT_H_ -#include #include "erpc_config_internal.h" +#include #if ERPC_THREADS #include "erpc_threading.h" #endif diff --git a/erpc_c/transports/erpc_usb_cdc_transport.hpp b/erpc_c/transports/erpc_usb_cdc_transport.hpp index a32df59d..ee4abf69 100644 --- a/erpc_c/transports/erpc_usb_cdc_transport.hpp +++ b/erpc_c/transports/erpc_usb_cdc_transport.hpp @@ -9,8 +9,8 @@ #ifndef _EMBEDDED_RPC__USB_CDC_TRANSPORT_H_ #define _EMBEDDED_RPC__USB_CDC_TRANSPORT_H_ -#include #include "erpc_config_internal.h" +#include #if !ERPC_THREADS_IS(NONE) #include "erpc_threading.h" #endif diff --git a/erpcgen/Makefile b/erpcgen/Makefile index a6aa0b7a..9118d5c2 100644 --- a/erpcgen/Makefile +++ b/erpcgen/Makefile @@ -71,11 +71,18 @@ SOURCES += $(OBJS_ROOT)/erpcgen_parser.tab.cpp \ .SECONDARY: $(OBJS_ROOT)/erpcgen_parser.tab.cpp \ $(OBJS_ROOT)/erpcgen_lexer.cpp \ $(OBJS_ROOT)/erpcgen/src/templates/c_common_header.c \ + $(OBJS_ROOT)/erpcgen/src/templates/cpp_interface_header.c \ + $(OBJS_ROOT)/erpcgen/src/templates/cpp_interface_source.c \ + $(OBJS_ROOT)/erpcgen/src/templates/cpp_client_header.c \ + $(OBJS_ROOT)/erpcgen/src/templates/cpp_client_source.c \ + $(OBJS_ROOT)/erpcgen/src/templates/cpp_server_header.c \ + $(OBJS_ROOT)/erpcgen/src/templates/cpp_server_source.c \ + $(OBJS_ROOT)/erpcgen/src/templates/cpp_coders.c \ + $(OBJS_ROOT)/erpcgen/src/templates/cpp_common_functions.c \ + $(OBJS_ROOT)/erpcgen/src/templates/c_client_header.c \ $(OBJS_ROOT)/erpcgen/src/templates/c_client_source.c \ $(OBJS_ROOT)/erpcgen/src/templates/c_server_header.c \ $(OBJS_ROOT)/erpcgen/src/templates/c_server_source.c \ - $(OBJS_ROOT)/erpcgen/src/templates/c_coders.c \ - $(OBJS_ROOT)/erpcgen/src/templates/c_common_functions.c \ $(OBJS_ROOT)/erpcgen/src/templates/c_crc.c \ $(OBJS_ROOT)/erpcgen/src/templates/py_init.c \ $(OBJS_ROOT)/erpcgen/src/templates/py_common.c \ @@ -86,11 +93,18 @@ SOURCES += $(OBJS_ROOT)/erpcgen_parser.tab.cpp \ $(OBJS_ROOT)/erpcgen/src/templates/py_global_init.c SOURCES += $(OBJS_ROOT)/erpcgen/src/templates/c_common_header.c \ + $(OBJS_ROOT)/erpcgen/src/templates/cpp_interface_header.c \ + $(OBJS_ROOT)/erpcgen/src/templates/cpp_interface_source.c \ + $(OBJS_ROOT)/erpcgen/src/templates/cpp_client_header.c \ + $(OBJS_ROOT)/erpcgen/src/templates/cpp_client_source.c \ + $(OBJS_ROOT)/erpcgen/src/templates/cpp_server_header.c \ + $(OBJS_ROOT)/erpcgen/src/templates/cpp_server_source.c \ + $(OBJS_ROOT)/erpcgen/src/templates/cpp_coders.c \ + $(OBJS_ROOT)/erpcgen/src/templates/cpp_common_functions.c \ + $(OBJS_ROOT)/erpcgen/src/templates/c_client_header.c \ $(OBJS_ROOT)/erpcgen/src/templates/c_client_source.c \ $(OBJS_ROOT)/erpcgen/src/templates/c_server_header.c \ $(OBJS_ROOT)/erpcgen/src/templates/c_server_source.c \ - $(OBJS_ROOT)/erpcgen/src/templates/c_coders.c \ - $(OBJS_ROOT)/erpcgen/src/templates/c_common_functions.c \ $(OBJS_ROOT)/erpcgen/src/templates/c_crc.c \ $(OBJS_ROOT)/erpcgen/src/templates/py_init.c \ $(OBJS_ROOT)/erpcgen/src/templates/py_common.c \ diff --git a/erpcgen/VisualStudio_v14/.gitignore b/erpcgen/VisualStudio_v14/.gitignore index 43daf212..024f1d9a 100644 --- a/erpcgen/VisualStudio_v14/.gitignore +++ b/erpcgen/VisualStudio_v14/.gitignore @@ -4,12 +4,17 @@ erpcgen_parser.tab.cpp erpcgen_parser.tab.hpp # templates -c_client_source.cpp -c_coders.cpp +cpp_client_source.cpp +cpp_client_header.cpp +cpp_server_header.cpp +cpp_server_source.cpp +cpp_coders.cpp c_common_header.cpp +c_client_source.cpp +c_client_header.cpp c_server_header.cpp c_server_source.cpp -c_common_functions.cpp +cpp_common_functions.cpp c_defines.cpp c_crc.cpp py_client.cpp diff --git a/erpcgen/VisualStudio_v14/erpcgen.vcxproj b/erpcgen/VisualStudio_v14/erpcgen.vcxproj index df0c94cb..9d37fc2e 100644 --- a/erpcgen/VisualStudio_v14/erpcgen.vcxproj +++ b/erpcgen/VisualStudio_v14/erpcgen.vcxproj @@ -97,12 +97,19 @@ - python.exe ..\bin\txt_to_c.py --output .\c_coders.cpp ..\src\templates\c_coders.template -python.exe ..\bin\txt_to_c.py --output .\c_client_source.cpp ..\src\templates\c_client_source.template + python.exe ..\bin\txt_to_c.py --output .\cpp_coders.cpp ..\src\templates\cpp_coders.template python.exe ..\bin\txt_to_c.py --output .\c_common_header.cpp ..\src\templates\c_common_header.template +python.exe ..\bin\txt_to_c.py --output .\cpp_interface_header.cpp ..\src\templates\cpp_interface_header.template +python.exe ..\bin\txt_to_c.py --output .\cpp_interface_source.cpp ..\src\templates\cpp_interface_source.template +python.exe ..\bin\txt_to_c.py --output .\cpp_client_header.cpp ..\src\templates\cpp_client_header.template +python.exe ..\bin\txt_to_c.py --output .\cpp_client_source.cpp ..\src\templates\cpp_client_source.template +python.exe ..\bin\txt_to_c.py --output .\cpp_server_source.cpp ..\src\templates\cpp_server_source.template +python.exe ..\bin\txt_to_c.py --output .\cpp_server_header.cpp ..\src\templates\cpp_server_header.template +python.exe ..\bin\txt_to_c.py --output .\c_client_header.cpp ..\src\templates\c_client_header.template +python.exe ..\bin\txt_to_c.py --output .\c_client_source.cpp ..\src\templates\c_client_source.template python.exe ..\bin\txt_to_c.py --output .\c_server_source.cpp ..\src\templates\c_server_source.template python.exe ..\bin\txt_to_c.py --output .\c_server_header.cpp ..\src\templates\c_server_header.template -python.exe ..\bin\txt_to_c.py --output .\c_common_functions.cpp ..\src\templates\c_common_functions.template +python.exe ..\bin\txt_to_c.py --output .\cpp_common_functions.cpp ..\src\templates\cpp_common_functions.template python.exe ..\bin\txt_to_c.py --output .\c_crc.cpp ..\src\templates\c_crc.template python.exe ..\bin\txt_to_c.py --output .\py_client.cpp ..\src\templates\py_client.template python.exe ..\bin\txt_to_c.py --output .\py_coders.cpp ..\src\templates\py_coders.template @@ -137,12 +144,19 @@ python.exe ..\bin\txt_to_c.py --output .\py_global_init.cpp ..\src\templates\py_ %(AdditionalLibraryDirectories) - python.exe ..\bin\txt_to_c.py --output .\c_coders.cpp ..\src\templates\c_coders.template -python.exe ..\bin\txt_to_c.py --output .\c_client_source.cpp ..\src\templates\c_client_source.template + python.exe ..\bin\txt_to_c.py --output .\cpp_coders.cpp ..\src\templates\cpp_coders.template python.exe ..\bin\txt_to_c.py --output .\c_common_header.cpp ..\src\templates\c_common_header.template +python.exe ..\bin\txt_to_c.py --output .\cpp_interface_header.cpp ..\src\templates\cpp_interface_header.template +python.exe ..\bin\txt_to_c.py --output .\cpp_interface_source.cpp ..\src\templates\cpp_interface_source.template +python.exe ..\bin\txt_to_c.py --output .\cpp_client_header.cpp ..\src\templates\cpp_client_header.template +python.exe ..\bin\txt_to_c.py --output .\cpp_client_source.cpp ..\src\templates\cpp_client_source.template +python.exe ..\bin\txt_to_c.py --output .\cpp_server_source.cpp ..\src\templates\cpp_server_source.template +python.exe ..\bin\txt_to_c.py --output .\cpp_server_header.cpp ..\src\templates\cpp_server_header.template +python.exe ..\bin\txt_to_c.py --output .\c_client_header.cpp ..\src\templates\c_client_header.template +python.exe ..\bin\txt_to_c.py --output .\c_client_source.cpp ..\src\templates\c_client_source.template python.exe ..\bin\txt_to_c.py --output .\c_server_source.cpp ..\src\templates\c_server_source.template python.exe ..\bin\txt_to_c.py --output .\c_server_header.cpp ..\src\templates\c_server_header.template -python.exe ..\bin\txt_to_c.py --output .\c_common_functions.cpp ..\src\templates\c_common_functions.template +python.exe ..\bin\txt_to_c.py --output .\cpp_common_functions.cpp ..\src\templates\cpp_common_functions.template python.exe ..\bin\txt_to_c.py --output .\c_crc.cpp ..\src\templates\c_crc.template python.exe ..\bin\txt_to_c.py --output .\py_client.cpp ..\src\templates\py_client.template python.exe ..\bin\txt_to_c.py --output .\py_coders.cpp ..\src\templates\py_coders.template @@ -229,13 +243,20 @@ python.exe ..\bin\txt_to_c.py --output .\py_global_init.cpp ..\src\templates\py_ - - + + + + + + + + + - + 4005;4244;%(DisableSpecificWarnings) diff --git a/erpcgen/VisualStudio_v14/erpcgen.vcxproj.filters b/erpcgen/VisualStudio_v14/erpcgen.vcxproj.filters index 29c6416c..1d72bbdb 100644 --- a/erpcgen/VisualStudio_v14/erpcgen.vcxproj.filters +++ b/erpcgen/VisualStudio_v14/erpcgen.vcxproj.filters @@ -164,13 +164,34 @@ Source Files\cpptemplate - + Source Files - + Source Files - + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + Source Files @@ -254,7 +275,7 @@ Source Files - + Source Files @@ -282,4 +303,4 @@ - \ No newline at end of file + diff --git a/erpcgen/src/CGenerator.cpp b/erpcgen/src/CGenerator.cpp index 71dd8960..676dab38 100644 --- a/erpcgen/src/CGenerator.cpp +++ b/erpcgen/src/CGenerator.cpp @@ -15,6 +15,7 @@ #include "format_string.hpp" #include +#include #include #include @@ -31,11 +32,19 @@ static const char *const kIdentifierChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHI // Templates strings converted from text files by txt_to_c.py. extern const char *const kCCommonHeader; -extern const char *const kCServerHeader; +extern const char *const kCppCommonHeader; +extern const char *const kCppInterfaceHeader; +extern const char *const kCppInterfaceSource; +extern const char *const kCppClientHeader; +extern const char *const kCppClientSource; +extern const char *const kCppServerHeader; +extern const char *const kCppServerSource; +extern const char *const kCppCoders; +extern const char *const kCppCommonFunctions; +extern const char *const kCClientHeader; extern const char *const kCClientSource; +extern const char *const kCServerHeader; extern const char *const kCServerSource; -extern const char *const kCCoders; -extern const char *const kCCommonFunctions; extern const char *const kCCrc; // number which makes list temporary variables unique. @@ -70,81 +79,138 @@ CGenerator::CGenerator(InterfaceDefinition *def) void CGenerator::generateOutputFiles(const string &fileName) { - generateClientSourceFile(fileName); + generateCommonCHeaderFiles(fileName); + generateCommonCppHeaderFiles(fileName); + + generateInterfaceCppHeaderFile(fileName); + generateInterfaceCppSourceFile(fileName); + + generateClientCppHeaderFile(fileName); + generateClientCppSourceFile(fileName); + + generateServerCppHeaderFile(fileName); + generateServerCppSourceFile(fileName); - generateServerHeaderFile(fileName); - generateServerSourceFile(fileName); + generateClientCHeaderFile(fileName); + generateClientCSourceFile(fileName); - generateCommonHeaderFiles(fileName); + generateServerCHeaderFile(fileName); + generateServerCSourceFile(fileName); } -void CGenerator::generateTypesHeaderFile() +void CGenerator::generateCommonCHeaderFiles(string fileName) { - string typesHeaderFileName = m_templateData["commonTypesFile"]->getvalue(); + fileName += "_common.h"; + m_templateData["commonGuardMacro"] = generateIncludeGuardName(fileName); + m_templateData["commonCHeaderName"] = fileName; + m_templateData["cCommonHeaderFile"] = true; + generateOutputFile(fileName, "c_common_header", m_templateData, kCCommonHeader); +} - m_templateData["commonGuardMacro"] = generateIncludeGuardName(typesHeaderFileName); - m_templateData["genCommonTypesFile"] = true; - m_templateData["commonTypesFile"] = ""; +void CGenerator::generateCommonCppHeaderFiles(string fileName) +{ + fileName += "_common.hpp"; + m_templateData["commonGuardMacro"] = generateIncludeGuardName(fileName); + m_templateData["commonCppHeaderName"] = fileName; + m_templateData["cCommonHeaderFile"] = false; + generateOutputFile(fileName, "c_common_header", m_templateData, kCCommonHeader); +} - generateOutputFile(typesHeaderFileName, "c_common_header", m_templateData, kCCommonHeader); +void CGenerator::generateInterfaceCppHeaderFile(string fileName) +{ + fileName += "_interface.hpp"; + m_templateData["interfaceCppGuardMacro"] = generateIncludeGuardName(fileName); + m_templateData["interfaceCppHeaderName"] = fileName; + generateOutputFile(fileName, "cpp_interface_header", m_templateData, kCppInterfaceHeader); } -void CGenerator::generateCommonHeaderFiles(const string &fileName) +void CGenerator::generateInterfaceCppSourceFile(string fileName) { - m_templateData["commonGuardMacro"] = generateIncludeGuardName(fileName + ".h"); - m_templateData["genCommonTypesFile"] = false; + fileName += "_interface.cpp"; + m_templateData["interfaceCppSourceName"] = fileName; + generateOutputFile(fileName, "cpp_interface_source", m_templateData, kCppInterfaceSource); +} - generateOutputFile(fileName + ".h", "c_common_header", m_templateData, kCCommonHeader); +void CGenerator::generateClientCppHeaderFile(string fileName) +{ + fileName += "_client.hpp"; + m_templateData["clientCppGuardMacro"] = generateIncludeGuardName(fileName); + m_templateData["clientCppHeaderName"] = fileName; + generateOutputFile(fileName, "cpp_client_header", m_templateData, kCppClientHeader); } -void CGenerator::generateClientSourceFile(string fileName) +void CGenerator::generateClientCppSourceFile(string fileName) { - m_templateData["source"] = "client"; fileName += "_client.cpp"; - m_templateData["clientSourceName"] = fileName; + m_templateData["clientCppSourceName"] = fileName; + + generateOutputFile(fileName, "cpp_client_source", m_templateData, kCppClientSource); +} + +void CGenerator::generateServerCppHeaderFile(string fileName) +{ + fileName += "_server.hpp"; + m_templateData["serverCppGuardMacro"] = generateIncludeGuardName(fileName); + m_templateData["serverCppHeaderName"] = fileName; + generateOutputFile(fileName, "cpp_server_header", m_templateData, kCppServerHeader); +} + +void CGenerator::generateServerCppSourceFile(string fileName) +{ + fileName += "_server.cpp"; + m_templateData["serverCppSourceName"] = fileName; + + generateOutputFile(fileName, "cpp_server_source", m_templateData, kCppServerSource); +} - // TODO: temporary workaround for tests - m_templateData["unitTest"] = (fileName.compare("test_unit_test_common_client.cpp") == 0 ? false : true); +void CGenerator::generateClientCHeaderFile(string fileName) +{ + fileName = "c_" + fileName + "_client.h"; + m_templateData["clientCGuardMacro"] = generateIncludeGuardName(fileName); + m_templateData["clientCHeaderName"] = fileName; + generateOutputFile(fileName, "c_client_header", m_templateData, kCClientHeader); +} + +void CGenerator::generateClientCSourceFile(string fileName) +{ + fileName = "c_" + fileName + "_client.cpp"; + m_templateData["clientCSourceName"] = fileName; generateOutputFile(fileName, "c_client_source", m_templateData, kCClientSource); } -void CGenerator::generateServerHeaderFile(string fileName) +void CGenerator::generateServerCHeaderFile(string fileName) { - fileName += "_server.h"; - m_templateData["serverGuardMacro"] = generateIncludeGuardName(fileName); - m_templateData["serverHeaderName"] = fileName; + fileName = "c_" + fileName + "_server.h"; + m_templateData["serverCGuardMacro"] = generateIncludeGuardName(fileName); + m_templateData["serverCHeaderName"] = fileName; generateOutputFile(fileName, "c_server_header", m_templateData, kCServerHeader); } -void CGenerator::generateServerSourceFile(string fileName) +void CGenerator::generateServerCSourceFile(string fileName) { - m_templateData["source"] = "server"; - fileName += "_server.cpp"; - m_templateData["serverSourceName"] = fileName; - - // TODO: temporary workaround for tests - m_templateData["unitTest"] = (fileName.compare("test_unit_test_common_server.cpp") == 0 ? false : true); + fileName = "c_" + fileName + "_server.cpp"; + m_templateData["serverCSourceName"] = fileName; generateOutputFile(fileName, "c_server_source", m_templateData, kCServerSource); } void CGenerator::generateCrcFile() { - string filenName = "erpc_crc16.hpp"; - m_templateData["crcGuardMacro"] = generateIncludeGuardName(filenName); - m_templateData["crcHeaderName"] = filenName; - generateOutputFile(filenName, "c_crc", m_templateData, kCCrc); + string fileName = "erpc_crc16.hpp"; + m_templateData["crcGuardMacro"] = generateIncludeGuardName(fileName); + m_templateData["crcHeaderName"] = fileName; + generateOutputFile(fileName, "c_crc", m_templateData, kCCrc); } void CGenerator::parseSubtemplates() { - string templateName = "c_coders"; + string templateName = "cpp_coders"; try { - parse(kCCoders, m_templateData); - templateName = "c_common_functions"; - parse(kCCommonFunctions, m_templateData); + parse(kCppCoders, m_templateData); + templateName = "cpp_common_functions"; + parse(kCppCommonFunctions, m_templateData); } catch (TemplateException &e) { @@ -414,7 +480,7 @@ void CGenerator::generate() } /* Generate file with shim code version. */ m_templateData["versionGuardMacro"] = - generateIncludeGuardName(format_string("erpc_generated_shim_code_crc_%d", m_idlCrc16).c_str()); + generateIncludeGuardName(format_string("erpc_generated_shim_code_crc_%d", m_idlCrc16)); m_templateData["generateInfraErrorChecks"] = generateInfraErrorChecks; m_templateData["generateAllocErrorChecks"] = generateAllocErrorChecks; @@ -426,7 +492,6 @@ void CGenerator::generate() m_templateData["structs"] = empty; m_templateData["unions"] = empty; m_templateData["consts"] = empty; - m_templateData["functions"] = empty; m_templateData["nonExternalStructUnion"] = false; @@ -448,13 +513,6 @@ void CGenerator::generate() } // check if structure/function parameters annotations are valid. - for (Symbol *symbol : getDataTypesFromSymbolScope(m_globals, DataType::data_type_t::kFunctionType)) - { - FunctionType *functionType = dynamic_cast(symbol); - assert(functionType); - scanStructForAnnotations(&functionType->getParameters(), true); - } - for (Symbol *symbol : getDataTypesFromSymbolScope(m_globals, DataType::data_type_t::kStructType)) { StructType *structType = dynamic_cast(symbol); @@ -470,6 +528,11 @@ void CGenerator::generate() { scanStructForAnnotations(&function->getParameters(), true); } + + for (FunctionType *functionType : interface->getFunctionTypes()) + { + scanStructForAnnotations(&functionType->getParameters(), true); + } } // transform alias data types @@ -489,15 +552,20 @@ void CGenerator::generate() // for common header, only C specific makeSymbolsDeclarationTemplateData(); - // check if types header annotation is used - if (m_def->hasProgramSymbol()) - { - m_templateData["commonTypesFile"] = getAnnStringValue(program, TYPES_HEADER_ANNOTATION); - } - else + data_list interfacesFilesList; + string commonFilesFilename; + for (Group *group : m_groups) { - m_templateData["commonTypesFile"] = ""; + commonFilesFilename = getGroupCommonFileName(group); + for (auto iface : group->getInterfaces()) + { + data_map interfaceFile; + interfaceFile["interfaceName"] = iface->getName(); + interfaceFile["interfaceCommonFileName"] = commonFilesFilename; + interfacesFilesList.push_back(interfaceFile); + } } + m_templateData["interfacesFiles"] = interfacesFilesList; for (Group *group : m_groups) { @@ -506,17 +574,10 @@ void CGenerator::generate() groupTemplate["includes"] = makeGroupIncludesTemplateData(group); groupTemplate["symbolsMap"] = makeGroupSymbolsTemplateData(group); groupTemplate["interfaces"] = makeGroupInterfacesTemplateData(group); - groupTemplate["callbacks"] = makeGroupCallbacksTemplateData(group); group->setTemplate(groupTemplate); generateGroupOutputFiles(group); } - - // generate types header if used - if (!m_templateData["commonTypesFile"]->getvalue().empty()) - { - generateTypesHeaderFile(); - } } void CGenerator::makeConstTemplateData() @@ -537,7 +598,7 @@ void CGenerator::makeConstTemplateData() if (nullptr == constVarValue) { throw semantic_error( - format_string("line %d: Const pointing to null Value object.", constVar->getLastLine()).c_str()); + format_string("line %d: Const pointing to null Value object.", constVar->getLastLine())); } /* Use char[] for constants. */ @@ -558,8 +619,7 @@ void CGenerator::makeConstTemplateData() if (constVarValue->getType() != kIntegerValue) { throw semantic_error(format_string("line %d: Const enum pointing to non-integer Value object.", - constVar->getLastLine()) - .c_str()); + constVar->getLastLine())); } EnumType *constEnum = dynamic_cast(constVarType); @@ -576,9 +636,8 @@ void CGenerator::makeConstTemplateData() if (value.compare("") == 0) { value = "(" + constVarType->getName() + ") " + constVarValue->toString(); - Log::warning(format_string("Enum value '%s' is not pointing to any '%s' variable \n", - constVarValue->toString().c_str(), constVarType->getName().c_str()) - .c_str()); + Log::warning("Enum value '%s' is not pointing to any '%s' variable \n", + constVarValue->toString().c_str(), constVarType->getName().c_str()); } } else @@ -688,81 +747,6 @@ void CGenerator::makeAliasesTemplateData() } } - /* type definitions of functions and table of functions */ - data_list functions; - for (auto functionTypeSymbol : getDataTypesFromSymbolScope(m_globals, DataType::data_type_t::kFunctionType)) - { - FunctionType *functionType = dynamic_cast(functionTypeSymbol); - assert(functionType); - data_map functionInfo; - - // aware of external function definitions - if (!findAnnotation(functionType, EXTERNAL_ANNOTATION)) - { - AliasType *a = new AliasType(getFunctionPrototype(nullptr, functionType), functionType); - a->setMlComment(functionType->getMlComment()); - a->setIlComment(functionType->getIlComment()); - - /* Function type definition need be inserted after all parameters types definitions. */ - DataType *callbackParamType = functionType->getReturnStructMemberType()->getDataType(); - for (StructMember *callbackParam : functionType->getParameters().getMembers()) - { - DataType *callbackParamDataType = callbackParam->getDataType(); - if (!callbackParamType || callbackParamDataType->getFirstLine() > callbackParamType->getFirstLine()) - { - callbackParamType = callbackParamDataType; - } - } - if (!callbackParamType || !callbackParamType->isAlias()) - { - /* order isn't important */ - aliasTypeVector.insert(aliasTypeVector.begin() + i++, a); - } - else - { - /* skip structure, unions and functions type definitions */ - for (unsigned int aliasTypesIt = i; aliasTypesIt < aliasTypeVector.size(); ++aliasTypesIt) - { - if (callbackParamType == aliasTypeVector[aliasTypesIt]) - { - // Add aliases in IDL declaration order. - unsigned int nextIt = aliasTypesIt + 1; - while (nextIt < aliasTypeVector.size()) - { - AliasType *nextAlias = dynamic_cast(aliasTypeVector[nextIt]); - assert(nextAlias); - if (nextAlias->getElementType()->isFunction()) - { - ++nextIt; - } - else - { - break; - } - } - - aliasTypeVector.insert(aliasTypeVector.begin() + nextIt, a); - break; - } - } - } - } - - /* Table template data. */ - data_list callbacks; - for (Function *fun : functionType->getCallbackFuns()) - { - data_map callbacksInfo; - callbacksInfo["name"] = fun->getName(); - callbacks.push_back(callbacksInfo); - } - functionInfo["callbacks"] = callbacks; - /* Function type name. */ - functionInfo["name"] = functionType->getName(); - functions.push_back(functionInfo); - } - m_templateData["functions"] = functions; - for (auto it : aliasTypeVector) { AliasType *aliasType = dynamic_cast(it); @@ -1016,43 +1000,6 @@ data_map CGenerator::makeGroupSymbolsTemplateData(Group *group) return symbolsTemplate; } -data_list CGenerator::makeGroupCallbacksTemplateData(Group *group) -{ - data_list functionTypes; - std::map functionTypeMap; - - // need go trough functions instead of group symbols. - for (Interface *interface : group->getInterfaces()) - { - for (Function *function : interface->getFunctions()) - { - FunctionType *functionType = function->getFunctionType(); - if (functionType) - { - bool isPresent = (functionTypeMap.find(functionType) != functionTypeMap.end()); - if (isPresent) - { - ++functionTypeMap[functionType]; - } - else - { - functionTypeMap[functionType] = 1; - } - } - } - } - - for (std::map::iterator it = functionTypeMap.begin(); it != functionTypeMap.end(); ++it) - { - if (it->second > 1) - { - functionTypes.push_back(getFunctionTypeTemplateData(group, it->first)); - } - } - - return functionTypes; -} - data_map CGenerator::getStructDeclarationTemplateData(StructType *structType) { data_map info; @@ -1082,8 +1029,8 @@ data_map CGenerator::getStructDeclarationTemplateData(StructType *structType) DataType *trueDataType = member->getDataType()->getTrueDataType(); // Check if member is byRef type. Add "*" for type and allocate space for data on server side. - if (member->isByref() && - (trueDataType->isStruct() || trueDataType->isUnion() || trueDataType->isScalar() || trueDataType->isEnum())) + if (member->isByref() && (trueDataType->isStruct() || trueDataType->isUnion() || trueDataType->isScalar() || + trueDataType->isEnum() || trueDataType->isFunction())) { memberName = "*" + memberName; } @@ -1157,8 +1104,7 @@ data_map CGenerator::getStructDefinitionTemplateData(Group *group, StructType *s { throw syntax_error( format_string("line %d: Struct member shall use byref option. Member is using forward declared type.", - member->getFirstLine()) - .c_str()); + member->getFirstLine())); } // Handle nullable annotation bool isNullable = @@ -1364,14 +1310,16 @@ void CGenerator::setTemplateComments(Symbol *symbol, data_map &symbolInfo) bool CGenerator::isServerNullParam(StructMember *param) { DataType *paramTrueDataType = param->getDataType()->getTrueDataType(); - return (!paramTrueDataType->isScalar() && !paramTrueDataType->isEnum() && !paramTrueDataType->isArray()); + return (!paramTrueDataType->isScalar() && !paramTrueDataType->isEnum() && !paramTrueDataType->isArray() && + !paramTrueDataType->isFunction()); } bool CGenerator::isPointerParam(StructMember *param) { DataType *paramTrueDataType = param->getDataType()->getTrueDataType(); - return (isServerNullParam(param) || ((paramTrueDataType->isScalar() || paramTrueDataType->isEnum()) && - param->getDirection() != param_direction_t::kInDirection)); + return (isServerNullParam(param) || + ((paramTrueDataType->isScalar() || paramTrueDataType->isEnum() || paramTrueDataType->isFunction()) && + param->getDirection() != param_direction_t::kInDirection)); } bool CGenerator::isNullableParam(StructMember *param) @@ -1383,6 +1331,8 @@ data_map CGenerator::getFunctionBaseTemplateData(Group *group, FunctionBase *fn) { data_map info; Symbol *fnSymbol = dynamic_cast(fn); + data_list externalInterfacesDataList; + list externalInterfacesList; // reset list numbering. listCounter = 0; @@ -1393,6 +1343,8 @@ data_map CGenerator::getFunctionBaseTemplateData(Group *group, FunctionBase *fn) setTemplateComments(fnSymbol, info); info["needTempVariableServerI32"] = false; info["needTempVariableClientI32"] = false; + info["needTempVariableServerU16"] = false; + info["needTempVariableClientU16"] = false; info["needNullVariableOnServer"] = false; /* Is function declared as external? */ @@ -1444,7 +1396,8 @@ data_map CGenerator::getFunctionBaseTemplateData(Group *group, FunctionBase *fn) info["needTempVariableClientI32"] = needTempVariableI32; returnInfo["resultVariable"] = resultVariable; returnInfo["errorReturnValue"] = getErrorReturnValue(fn); - returnInfo["isNullReturnType"] = (!trueDataType->isScalar() && !trueDataType->isEnum()); + returnInfo["isNullReturnType"] = + (!trueDataType->isScalar() && !trueDataType->isEnum() && !trueDataType->isFunction()); } info["returnValue"] = returnInfo; @@ -1542,7 +1495,7 @@ data_map CGenerator::getFunctionBaseTemplateData(Group *group, FunctionBase *fn) // Special case when scalar variables are @nullable string nullableName = getOutputName(param); paramInfo["nullableName"] = nullableName; - if (paramTrueType->isScalar() || paramTrueType->isEnum()) + if (paramTrueType->isScalar() || paramTrueType->isEnum() || paramTrueType->isFunction()) { paramInfo["nullVariable"] = getTypenameName(paramTrueType, "*_" + nullableName); } @@ -1580,12 +1533,41 @@ data_map CGenerator::getFunctionBaseTemplateData(Group *group, FunctionBase *fn) } } + string ifaceScope = ""; + if (paramTrueType->isFunction()) + { + FunctionType *funType = dynamic_cast(paramTrueType); + if (funType->getCallbackFuns().size() > 1) + { + info["needTempVariableServerU16"] = true; + info["needTempVariableClientU16"] = true; + } + if (funType->getInterface() != fn->getInterface()) + { + ifaceScope = funType->getInterface()->getName(); + } + } + paramInfo["mallocServer"] = firstAllocOnServerWhenIsNeed(name, param); setCallingFreeFunctions(param, paramInfo, false); // Use shared memory feature instead of serializing/deserializing data. bool isShared = (isPointerParam(param) && findAnnotation(param, SHARED_ANNOTATION) != nullptr); + + string pureCName = ""; + if ((param->getDirection() != param_direction_t::kInDirection) && paramTrueType->isFunction()) + { + pureCName += "&"; + } + if (paramTrueType->isFunction()) + { + pureCName += "_"; + } + pureCName += name; + paramInfo["shared"] = isShared; + paramInfo["pureName"] = name; + paramInfo["pureNameC"] = pureCName; string encodeDecodeName; if (isShared) { @@ -1602,6 +1584,12 @@ data_map CGenerator::getFunctionBaseTemplateData(Group *group, FunctionBase *fn) paramInfo["variable"] = getTypenameName(paramType, name); paramInfo["name"] = name; + if (ifaceScope != "") + { + externalInterfacesList.push_back(ifaceScope); + } + paramInfo["ifaceScope"] = ifaceScope; + paramInfo["isFunction"] = paramTrueType->isFunction(); Log::debug("Calling EncodeDecode param %s with paramType %s.\n", param->getName().c_str(), paramType->getName().c_str()); @@ -1632,6 +1620,11 @@ data_map CGenerator::getFunctionBaseTemplateData(Group *group, FunctionBase *fn) paramsToFree.push_back(paramInfo); } } + externalInterfacesList.unique(); + for (auto externalInterface : externalInterfacesList) + { + externalInterfacesDataList.push_back(externalInterface); + } if (paramsToClient.size() > 0) { info["isReturnValue"] = true; @@ -1644,6 +1637,7 @@ data_map CGenerator::getFunctionBaseTemplateData(Group *group, FunctionBase *fn) info["paramsToFree"] = paramsToFree; info["parametersToClient"] = paramsToClient; info["parametersToServer"] = paramsToServer; + info["externalInterfaces"] = externalInterfacesDataList; return info; } @@ -1659,9 +1653,9 @@ data_map CGenerator::getFunctionTemplateData(Group *group, Function *fn) if (fn->getFunctionType()) { int similarFunctions = 0; - for (Interface *interface : group->getInterfaces()) + for (Interface *_interface : group->getInterfaces()) { - for (Function *function : interface->getFunctions()) + for (Function *function : _interface->getFunctions()) { if (fn->getFunctionType() == function->getFunctionType()) { @@ -1679,6 +1673,7 @@ data_map CGenerator::getFunctionTemplateData(Group *group, Function *fn) if (useCommonFunction) { std::string callbackFName = getOutputName(fn->getFunctionType()); + info["callbackFNameNoGroup"] = callbackFName; if (!group->getName().empty()) { callbackFName += "_" + group->getName(); @@ -1690,13 +1685,36 @@ data_map CGenerator::getFunctionTemplateData(Group *group, Function *fn) else { info["isCallback"] = false; - string serverProto = getFunctionServerCall(fn); - info["serverPrototype"] = serverProto; + info["serverPrototype"] = getFunctionServerCall(fn); info["serviceId"] = ""; } + string serverProtoC = getFunctionServerCall(fn, true); + info["serverPrototypeC"] = serverProtoC; string proto = getFunctionPrototype(group, fn); info["prototype"] = proto; + string protoCpp = getFunctionPrototype(group, fn, getOutputName(fn->getInterface()) + "_client", "", true); + info["prototypeCpp"] = protoCpp; + string protoInterface = getFunctionPrototype(group, fn, "", "", true); + info["prototypeInterface"] = protoInterface; + + data_list callbackParameters; + for (auto parameter : fn->getParameters().getMembers()) + { + if (parameter->getDataType()->isFunction()) + { + data_map paramData; + FunctionType *funType = dynamic_cast(parameter->getDataType()); + paramData["name"] = parameter->getName(); + paramData["type"] = funType->getName(); + paramData["interface"] = funType->getCallbackFuns()[0]->getInterface()->getName() + "_interface"; + paramData["in"] = ((parameter->getDirection() == param_direction_t::kInDirection)); + paramData["out"] = ((parameter->getDirection() == param_direction_t::kOutDirection)); + callbackParameters.push_back(paramData); + } + } + info["callbackParameters"] = callbackParameters; + info["name"] = getOutputName(fn); info["id"] = fn->getUniqueId(); @@ -1723,7 +1741,7 @@ data_map CGenerator::getFunctionTypeTemplateData(Group *group, FunctionType *fn) } } - string proto = getFunctionPrototype(group, fn, name); + string proto = getFunctionPrototype(group, fn, "", name); info = getFunctionBaseTemplateData(group, fn); info["prototype"] = proto; info["name"] = name; @@ -1733,7 +1751,7 @@ data_map CGenerator::getFunctionTypeTemplateData(Group *group, FunctionType *fn) { data_map functionInfo = getFunctionTemplateData(group, function); // set serverPrototype function with parameters of common function. - string serverProto = getFunctionServerCall(function, fn); + string serverProto = getFunctionServerCall(function, true); functionInfo["serverPrototype"] = serverProto; functionInfos.push_back(functionInfo); } @@ -1910,17 +1928,23 @@ string CGenerator::getErrorReturnValue(FunctionBase *fn) } } -string CGenerator::getFunctionServerCall(Function *fn, FunctionType *functionType) +string CGenerator::getFunctionServerCall(Function *fn, bool isCCall) { string proto = ""; - if (!fn->getReturnType()->isVoid()) + if (!isCCall) { - proto += "result = "; + if (!fn->getReturnType()->isVoid()) + { + proto += "result = "; + } + proto += "m_handler->"; } proto += getOutputName(fn); proto += "("; - auto params = (functionType) ? functionType->getParameters().getMembers() : fn->getParameters().getMembers(); + FunctionType *funcType = fn->getFunctionType(); + + auto params = (funcType) ? funcType->getParameters().getMembers() : fn->getParameters().getMembers(); if (params.size()) { @@ -1931,20 +1955,28 @@ string CGenerator::getFunctionServerCall(Function *fn, FunctionType *functionTyp DataType *trueDataType = it->getDataType()->getTrueDataType(); /* Builtin types and function types. */ - if (((trueDataType->isScalar()) || trueDataType->isEnum()) && + if (((trueDataType->isScalar()) || trueDataType->isEnum() || trueDataType->isFunction()) && it->getDirection() != param_direction_t::kInDirection && findAnnotation(it, NULLABLE_ANNOTATION)) { // On server side is created new variable for handle null : "_" + name proto += "_"; } else if ((it->getDirection() != param_direction_t::kInDirection) && - (((trueDataType->isScalar()) || trueDataType->isEnum()) || + (((trueDataType->isScalar()) || trueDataType->isEnum() || trueDataType->isFunction()) || (findAnnotation(it, SHARED_ANNOTATION)))) { - proto += "&"; + if (!isCCall) + { + proto += "&"; + } + } + std::string paramName = getOutputName(fn->getParameters().getMembers()[n]); + if ((paramName.empty()) || (funcType && funcType->getCallbackFuns().size() > 1)) + { + paramName = getOutputName(it); } - proto += getOutputName(it); + proto += paramName; if (!isLast) { @@ -1956,34 +1988,40 @@ string CGenerator::getFunctionServerCall(Function *fn, FunctionType *functionTyp return proto + ");"; } -string CGenerator::getFunctionPrototype(Group *group, FunctionBase *fn, const std::string name) +string CGenerator::getFunctionPrototype(Group *group, FunctionBase *fn, const std::string &interfaceName, + const string &name, bool insideInterfaceCall) { DataType *dataTypeReturn = fn->getReturnType(); string proto = getExtraPointerInReturn(dataTypeReturn); + string ifaceVar = interfaceName; if (proto == "*") { proto += " "; } - Symbol *symbol = dynamic_cast(fn); - assert(symbol); + if (ifaceVar != "") + { + ifaceVar += "::"; + } FunctionType *funType = dynamic_cast(fn); if (name.empty()) { + Symbol *symbol = dynamic_cast(fn); + assert(symbol); string functionName = getOutputName(symbol); if (funType) /* Need add '(*name)' for function type definition. */ { - proto += "(*" + functionName + ")"; + proto += "(" + ifaceVar + "*" + functionName + ")"; } else /* Use function name only. */ { - proto += functionName; + proto += ifaceVar + functionName; } } else { - proto += name; + proto += ifaceVar + name; } proto += "("; @@ -1992,7 +2030,7 @@ string CGenerator::getFunctionPrototype(Group *group, FunctionBase *fn, const st // add interface id and function id parameters for common callbacks shim code function if (!name.empty()) { - proto += "uint32_t serviceID, uint32_t functionID"; + proto += "ClientManager *m_clientManager, uint32_t serviceID, uint32_t functionID"; if (params.size() > 0) { proto += ", "; @@ -2011,9 +2049,8 @@ string CGenerator::getFunctionPrototype(Group *group, FunctionBase *fn, const st /* Add '*' to data types. */ if (((trueDataType->isBuiltin() || trueDataType->isEnum()) && - (it->getDirection() != param_direction_t::kInDirection && !trueDataType->isString())) || - (trueDataType->isFunction() && (it->getDirection() == param_direction_t::kOutDirection || - it->getDirection() == param_direction_t::kInoutDirection))) + ((it->getDirection() != param_direction_t::kInDirection) && !trueDataType->isString())) || + (trueDataType->isFunction() && (it->getDirection() != param_direction_t::kInDirection))) { paramSignature = "* " + paramSignature; } @@ -2087,6 +2124,18 @@ string CGenerator::getFunctionPrototype(Group *group, FunctionBase *fn, const st } } + if (insideInterfaceCall) + { + if (trueDataType->isFunction()) + { + FunctionType *funcType = dynamic_cast(trueDataType); + if (fn->getInterface() != funcType->getInterface()) + { + proto += funcType->getInterface()->getName() + "_interface::"; + } + } + } + proto += paramSignature; if (!isLast) { @@ -2290,7 +2339,7 @@ void CGenerator::getEncodeDecodeBuiltin(Group *group, BuiltinType *t, data_map & } data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataType *t, StructType *structType, - bool inDataContainer, StructMember *structMember, bool &needTempVariable, + bool inDataContainer, StructMember *structMember, bool &needTempVariableI32, bool isFunctionParam) { // prepare data for template @@ -2362,7 +2411,7 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT templateData["sharedType"] = "union"; if (setDiscriminatorTemp(u, structType, structMember, isFunctionParam, templateData)) { - needTempVariable = true; + needTempVariableI32 = true; } break; @@ -2376,7 +2425,7 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT // Check if member is byRef type. Add "*" for type and allocate space for data on server side. if (structMember && structMember->isByref() && !isFunctionParam && - (t->isStruct() || t->isUnion() || t->isScalar() || t->isEnum())) + (t->isStruct() || t->isUnion() || t->isScalar() || t->isEnum() || t->isFunction())) { templateData["freeingCall2"] = m_templateData["freeData"]; templateData["memberAllocation"] = allocateCall(name, t); @@ -2389,13 +2438,13 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT templateData["name"] = localName; - if (t->isScalar() || t->isEnum()) + if (t->isScalar() || t->isEnum() || t->isFunction()) { templateData["pointerScalarTypes"] = false; if (!inDataContainer && structMember && structMember->getDirection() != param_direction_t::kInDirection) { DataType *trueDataType = t->getTrueDataType(); - if (trueDataType->isScalar() || trueDataType->isEnum()) + if (trueDataType->isScalar() || trueDataType->isEnum() || t->isFunction()) { templateData["pointerScalarTypes"] = true; } @@ -2408,7 +2457,7 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT AliasType *aliasType = dynamic_cast(t); assert(aliasType); return getEncodeDecodeCall(name, group, aliasType->getElementType(), structType, inDataContainer, - structMember, needTempVariable, isFunctionParam); + structMember, needTempVariableI32, isFunctionParam); } case DataType::data_type_t::kArrayType: { static uint8_t arrayCounter; @@ -2431,7 +2480,7 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT templateData["forLoopCount"] = format_string("arrayCount%d", arrayCounter); templateData["protoNext"] = getEncodeDecodeCall(format_string("%s[arrayCount%d]", arrayName.c_str(), arrayCounter++), group, - elementType, structType, true, structMember, needTempVariable, isFunctionParam); + elementType, structType, true, structMember, needTempVariableI32, isFunctionParam); templateData["size"] = format_string("%dU", arrayType->getElementCount()); templateData["sizeTemp"] = format_string("%dU", arrayType->getElementCount()); templateData["isElementArrayType"] = trueElementType->isArray(); @@ -2449,7 +2498,7 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT break; } case DataType::data_type_t::kEnumType: { - needTempVariable = true; + needTempVariableI32 = true; templateData["decode"] = m_templateData["decodeEnumType"]; templateData["encode"] = m_templateData["encodeEnumType"]; string typeName = getOutputName(t); @@ -2468,6 +2517,8 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT assert(funType); const FunctionType::c_function_list_t &callbacks = funType->getCallbackFuns(); templateData["callbacksCount"] = callbacks.size(); + templateData["cbTypeName"] = funType->getName(); + templateData["cbParamOutName"] = name; if (callbacks.size() > 1) { templateData["callbacks"] = "_" + funType->getName(); @@ -2478,11 +2529,11 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT } else { - throw semantic_error(format_string("line %d: Function has function type parameter (callback " - "parameter), but in IDL is missing function definition, which can " - "be passed there.", - structMember->getFirstLine()) - .c_str()); + throw semantic_error( + format_string("line %d: Function has function type parameter (callback " + "parameter), but in IDL is missing function definition, which can " + "be passed there.", + structMember->getFirstLine())); } templateData["encode"] = m_templateData["encodeFunctionType"]; templateData["decode"] = m_templateData["decodeFunctionType"]; @@ -2630,7 +2681,7 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT templateData["size"] = size; templateData["useBinaryCoder"] = isBinaryList(listType); templateData["protoNext"] = getEncodeDecodeCall(nextName, group, elementType, structType, true, - structMember, needTempVariable, isFunctionParam); + structMember, needTempVariableI32, isFunctionParam); break; } case DataType::data_type_t::kStructType: { @@ -2661,7 +2712,7 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT // set discriminator name if (setDiscriminatorTemp(unionType, structType, structMember, isFunctionParam, templateData)) { - needTempVariable = true; + needTempVariableI32 = true; } /* NonEncapsulated unions as a function/structure param/member. */ @@ -2756,7 +2807,7 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT caseMembers.push_back(memberData); if (casesNeedTempVariable) { - needTempVariable = true; + needTempVariableI32 = true; } } } @@ -2806,7 +2857,7 @@ string CGenerator::getExtraDirectionPointer(StructMember *structMember) param_direction_t::kOutDirection) // between out and inout can be differences in future. Maybe not. { if (!trueDataType->isBuiltin() && !trueDataType->isEnum() && !trueDataType->isList() && - !trueDataType->isArray()) + !trueDataType->isArray() && !trueDataType->isFunction()) { result = "*"; } @@ -2818,7 +2869,7 @@ string CGenerator::getExtraDirectionPointer(StructMember *structMember) else if (structMemberDir == param_direction_t::kInoutDirection) { if (!trueDataType->isBuiltin() && !trueDataType->isEnum() && !trueDataType->isList() && - !trueDataType->isArray()) + !trueDataType->isArray() && !trueDataType->isFunction()) { result = "*"; } @@ -2862,7 +2913,7 @@ data_map CGenerator::firstAllocOnServerWhenIsNeed(const string &name, StructMemb if (structMemberDir == param_direction_t::kInoutDirection) { if (!trueDataType->isBuiltin() && !trueDataType->isEnum() && !trueDataType->isList() && - !trueDataType->isArray()) + !trueDataType->isArray() && !trueDataType->isFunction()) { return allocateCall(name, structMember); } @@ -2876,7 +2927,8 @@ data_map CGenerator::firstAllocOnServerWhenIsNeed(const string &name, StructMemb } else if (structMember->getDirection() == param_direction_t::kOutDirection) { - if (!trueDataType->isBuiltin() && !trueDataType->isEnum() && !trueDataType->isArray()) + if (!trueDataType->isBuiltin() && !trueDataType->isEnum() && !trueDataType->isArray() && + !trueDataType->isFunction()) { return allocateCall(name, structMember); } @@ -2963,8 +3015,7 @@ void CGenerator::setCallingFreeFunctions(Symbol *symbol, data_map &info, bool re { if (!returnType) { - if (trueDataType->isStruct() || trueDataType->isUnion() || - (trueDataType->isFunction() && ((structMember->getDirection() == param_direction_t::kOutDirection)))) + if (trueDataType->isStruct() || trueDataType->isUnion()) { string name = getOutputName(structMember, false); firstFreeingCall1["firstFreeingCall"] = m_templateData["freeData"]; @@ -3232,7 +3283,7 @@ void CGenerator::setNoSharedAnn(Symbol *parentSymbol, Symbol *childSymbol) bool CGenerator::setDiscriminatorTemp(UnionType *unionType, StructType *structType, StructMember *structMember, bool isFunctionParam, data_map &templateData) { - bool needTempVariable = false; + bool needTempVariableI32 = false; if (structType) { string discriminatorName; @@ -3283,7 +3334,7 @@ bool CGenerator::setDiscriminatorTemp(UnionType *unionType, StructType *structTy } else { - needTempVariable = true; + needTempVariableI32 = true; templateData["castDiscriminator"] = true; templateData["discriminatorType"] = disType->getName(); } @@ -3295,7 +3346,7 @@ bool CGenerator::setDiscriminatorTemp(UnionType *unionType, StructType *structTy templateData["dataLiteral"] = ""; templateData["castDiscriminator"] = false; } - return needTempVariable; + return needTempVariableI32; } string CGenerator::getScalarTypename(DataType *dataType) diff --git a/erpcgen/src/CGenerator.hpp b/erpcgen/src/CGenerator.hpp index 23003ebc..e6a9949f 100644 --- a/erpcgen/src/CGenerator.hpp +++ b/erpcgen/src/CGenerator.hpp @@ -62,11 +62,11 @@ class CGenerator : public Generator cpptempl::data_list m_symbolsTemplate; /*!< List of all symbol templates */ std::vector - m_listBinaryTypes; /*!< - * Contains binary types transformed to list. - * More ListType are present when @length annotation is used for binary type. - * If binary without @length is used then it is placed on first place in this vector. - */ + m_listBinaryTypes; /*!< + * Contains binary types transformed to list. + * More ListType are present when @length annotation is used for binary type. + * If binary without @length is used then it is placed on first place in this vector. + */ std::vector m_structListTypes; /*!< * Contains list types transformed to struct{list<>}. @@ -92,39 +92,88 @@ class CGenerator : public Generator void generateOutputFiles(const std::string &fileNameExtension) override; /*! - * @brief This function generate output common types header file. + * @brief This function generate header file output with common eRPC code. * - * @param[in] fileName Name for output client source file. + * @param[in] fileName Name for common eRPC header file output. + */ + void generateCommonCHeaderFiles(std::string fileName); + + /*! + * @brief This function generate header file output with common eRPC code. + * + * @param[in] fileName Name for common eRPC header file output. + */ + void generateCommonCppHeaderFiles(std::string fileName); + + /*! + * @brief This function generate output interface header file. + * + * @param[in] fileName Name for output interface header file. + */ + void generateInterfaceCppHeaderFile(std::string fileName); + + /*! + * @brief This function generate output interface source file. + * + * @param[in] fileName Name for output interface source file. + */ + void generateInterfaceCppSourceFile(std::string fileName); + + /*! + * @brief This function generate output client header file for cpp. + * + * @param[in] fileName Name for output client header file. */ - void generateTypesHeaderFile(); + void generateClientCppHeaderFile(std::string fileName); /*! - * @brief This function generate output common header file. + * @brief This function generate output client source file for cpp. * * @param[in] fileName Name for output client source file. */ - void generateCommonHeaderFiles(const std::string &fileName); + void generateClientCppSourceFile(std::string fileName); + + /*! + * @brief This function generate output server header file for cpp. + * + * @param[in] fileName Name for output server header file. + */ + void generateServerCppHeaderFile(std::string fileName); + + /*! + * @brief This function generate output server source file for cpp. + * + * @param[in] fileName Name for output server source file. + */ + void generateServerCppSourceFile(std::string fileName); + + /*! + * @brief This function generate output client header file for C. + * + * @param[in] fileName Name for output client header file. + */ + void generateClientCHeaderFile(std::string fileName); /*! - * @brief This function generate output client source file. + * @brief This function generate output client source file for C. * * @param[in] fileName Name for output client source file. */ - void generateClientSourceFile(std::string fileName); + void generateClientCSourceFile(std::string fileName); /*! - * @brief This function generate output server header file. + * @brief This function generate output server header file for C. * * @param[in] fileName Name for output server header file. */ - void generateServerHeaderFile(std::string fileName); + void generateServerCHeaderFile(std::string fileName); /*! - * @brief This function generate output server source file. + * @brief This function generate output server source file for C. * * @param[in] fileName Name for output server source file. */ - void generateServerSourceFile(std::string fileName); + void generateServerCSourceFile(std::string fileName); /*! * @brief This function generate output crc16 source file. @@ -204,7 +253,7 @@ class CGenerator : public Generator * * @return Contains interface function data. */ - cpptempl::data_map getFunctionTypeTemplateData(Group *group, FunctionType *fn); + cpptempl::data_map getFunctionTypeTemplateData(Group *group, FunctionType *fn) override; /*! * @brief This function will get symbol comments and convert to language specific ones @@ -420,21 +469,24 @@ class CGenerator : public Generator * * @param[in] group Group to which function belongs. * @param[in] fn Function for prototyping. - * @param[in] name Name used for FunctionType. + * @param[in] interfaceName Interface name used for function declaration. + * @param[in] name Name used for shared code in case of function type. + * @param[in] insideInterfaceCall interfaceClass specific. * * @return String prototype representation for given function. */ - std::string getFunctionPrototype(Group *group, FunctionBase *fn, const std::string name = ""); + std::string getFunctionPrototype(Group *group, FunctionBase *fn, const std::string &interfaceName = "", + const std::string &name = "", bool insideInterfaceCall = false) override; /*! * @brief This function return interface function representation called by server side. * * @param[in] fn Function for interface function representation. - * @param[in] functionType Inside FunctionType common shim code server call need use FunctionType parameters names. + * @param[in] isCCall C and C++ code is similar, but not same. * * @return String representation for given function. */ - std::string getFunctionServerCall(Function *fn, FunctionType *functionType = nullptr); + std::string getFunctionServerCall(Function *fn, bool isCCall = false); /*! * @brief This function return name with guard. @@ -480,13 +532,13 @@ class CGenerator : public Generator * @param[in] structType Structure holdings structure members. * @param[in] inDataContainer Is inside data container (struct, list, array). * @param[in] structMember Null for return. - * @param[out] needTempVariable Return true, when data type contains enum, function, union type. + * @param[out] needTempVariableI32 Return true, when data type contains enum, function, union type. * @param[in] isFunctionParam True for function param else false (structure member). * * @return Template data for decode or encode data type. */ cpptempl::data_map getEncodeDecodeCall(const std::string &name, Group *group, DataType *t, StructType *structType, - bool inDataContainer, StructMember *structMember, bool &needTempVariable, + bool inDataContainer, StructMember *structMember, bool &needTempVariableI32, bool isFunctionParam); /*! diff --git a/erpcgen/src/Generator.cpp b/erpcgen/src/Generator.cpp index 86e1c082..8530b4ed 100644 --- a/erpcgen/src/Generator.cpp +++ b/erpcgen/src/Generator.cpp @@ -20,6 +20,7 @@ #include #include #include +#include using namespace erpcgen; using namespace cpptempl; @@ -38,6 +39,7 @@ Generator::Generator(InterfaceDefinition *def, generator_type_t generatorType) string scopeName = "erpcShim"; string scopeNameC; string scopeNamePrefix = ""; + string namespaceVal = scopeName; m_templateData["erpcVersion"] = ERPC_VERSION; m_templateData["erpcVersionNumber"] = ERPC_VERSION_NUMBER; @@ -90,6 +92,11 @@ Generator::Generator(InterfaceDefinition *def, generator_type_t generatorType) { scopeName = getAnnStringValue(program, SCOPE_NAME_ANNOTATION); } + + if (findAnnotation(program, NAMESPACE_ANNOTATION) != nullptr) + { + namespaceVal = getAnnStringValue(program, NAMESPACE_ANNOTATION); + } } m_templateData["scopeName"] = scopeName; @@ -102,6 +109,7 @@ Generator::Generator(InterfaceDefinition *def, generator_type_t generatorType) } m_templateData["scopeNameC"] = scopeNameC; m_templateData["scopeNamePrefix"] = scopeNamePrefix; + m_templateData["namespace"] = namespaceVal; // get group annotation with vector of theirs interfaces m_groups.clear(); @@ -430,12 +438,21 @@ data_list Generator::makeGroupInterfacesTemplateData(Group *group) // TODO: for C only? ifaceInfo["serviceClassName"] = getOutputName(iface) + "_service"; + ifaceInfo["clientClassName"] = getOutputName(iface) + "_client"; + ifaceInfo["serverClassName"] = getOutputName(iface) + "_server"; + ifaceInfo["interfaceClassName"] = getOutputName(iface) + "_interface"; Log::info("%d: (%d) %s\n", n++, iface->getUniqueId(), iface->getName().c_str()); /* Has interface function declared as non-external? */ data_list functions = getFunctionsTemplateData(group, iface); ifaceInfo["functions"] = functions; + data_list callbacksInt; + data_list callbacksExt; + data_list callbacksAll; + getCallbacksTemplateData(group, iface, callbacksInt, callbacksExt, callbacksAll); + ifaceInfo["callbacksInt"] = callbacksInt; + ifaceInfo["callbacksAll"] = callbacksAll; ifaceInfo["isNonExternalInterface"] = false; for (unsigned int i = 0; i < functions.size(); ++i) { @@ -455,20 +472,29 @@ data_list Generator::makeGroupInterfacesTemplateData(Group *group) return interfaces; } -void Generator::generateGroupOutputFiles(Group *group) +string Generator::getGroupCommonFileName(Group *group) { - // generate output files only for groups with interfaces or for IDLs with no interfaces at all + string fileName = ""; if (!group->getInterfaces().empty() || (m_groups.size() == 1 && group->getName() == "")) { string groupName = group->getName(); - string fileName = stripExtension(m_def->getOutputFilename()); + fileName = stripExtension(m_def->getOutputFilename()); m_templateData["outputFilename"] = fileName; if (groupName != "") { fileName += "_" + groupName; } Log::info("File name %s\n", fileName.c_str()); - m_templateData["commonHeaderName"] = fileName; + } + return fileName; +} + +void Generator::generateGroupOutputFiles(Group *group) +{ + // generate output files only for groups with interfaces or for IDLs with no interfaces at all + if (!group->getInterfaces().empty() || (m_groups.size() == 1 && group->getName() == "")) + { + string fileName = getGroupCommonFileName(group); // group templates m_templateData["group"] = group->getTemplate(); @@ -567,10 +593,8 @@ string Generator::getOutputName(Symbol *symbol, bool check) auto it = reserverdWords.find(annName); if (it != reserverdWords.end()) { - throw semantic_error( - format_string("line %d: Wrong symbol name '%s'. Cannot use program language reserved words.", line, - annName.c_str()) - .c_str()); + throw semantic_error(format_string( + "line %d: Wrong symbol name '%s'. Cannot use program language reserved words.", line, annName.c_str())); } } @@ -641,3 +665,88 @@ Generator::datatype_vector_t Generator::getDataTypesFromSymbolScope(SymbolScope return vector; } + +void Generator::getCallbacksTemplateData(Group *group, const Interface *iface, data_list &callbackTypesInt, + data_list &callbackTypesExt, data_list &callbackTypesAll) +{ + list callbackTypes; + list interfacesNames; + list callbackTypesNames; + interfacesNames.push_back(iface->getName()); + for (auto function : iface->getFunctions()) + { + for (auto param : function->getParameters().getMembers()) + { + DataType *datatype = param->getDataType()->getTrueDataType(); + if (datatype->isFunction()) + { + FunctionType *funType = dynamic_cast(datatype); + if (funType->getInterface() != iface) + { + interfacesNames.push_back(funType->getInterface()->getName()); + } + if ((std::find(callbackTypesNames.begin(), callbackTypesNames.end(), funType->getName()) == + callbackTypesNames.end())) + { + callbackTypes.push_back(funType); + callbackTypesNames.push_back(funType->getName()); + } + } + } + } + for (auto functionType : iface->getFunctionTypes()) + { + if ((std::find(callbackTypesNames.begin(), callbackTypesNames.end(), functionType->getName()) == + callbackTypesNames.end())) + { + callbackTypes.push_back(functionType); + callbackTypesNames.push_back(functionType->getName()); + } + } + + for (auto functionType : callbackTypes) + { + data_list functionsInt; + data_list functionsExt; + data_list functionsAll; + for (auto fun : functionType->getCallbackFuns()) + { + if ((std::find(interfacesNames.begin(), interfacesNames.end(), fun->getInterface()->getName()) != + interfacesNames.end())) + { + data_map function; + function["name"] = fun->getName(); + if (fun->getInterface() == iface) + { + functionsInt.push_back(function); + } + else + { + functionsExt.push_back(function); + } + functionsAll.push_back(function); + } + } + if (!functionsAll.empty()) + { + data_map callbackType; + callbackType["name"] = functionType->getName(); + callbackType["typenameName"] = getFunctionPrototype(nullptr, functionType); + callbackType["interfaceTypenameName"] = + getFunctionPrototype(nullptr, functionType, iface->getName() + "_interface"); + if (!functionsInt.empty()) + { + callbackType["callbacks"] = functionsInt; + callbackType["callbacksData"] = getFunctionTypeTemplateData(group, functionType); + callbackTypesInt.push_back(callbackType); + } + if (!functionsExt.empty()) + { + callbackType["callbacks"] = functionsExt; + callbackTypesExt.push_back(callbackType); + } + callbackType["callbacks"] = functionsAll; + callbackTypesAll.push_back(callbackType); + } + } +} diff --git a/erpcgen/src/Generator.hpp b/erpcgen/src/Generator.hpp index 64167de9..dd9ad734 100644 --- a/erpcgen/src/Generator.hpp +++ b/erpcgen/src/Generator.hpp @@ -201,12 +201,25 @@ class Generator * * @param[in] group Pointer to a group. * @param[in] fn From this are set interface function template data. - * @param[in] fnIndex Function index. * * @return Contains interface function data. */ virtual cpptempl::data_map getFunctionTemplateData(Group *group, Function *fn) = 0; + /*! + * @brief This function returns function type (callbacks type) template data. + * + * This function returns function type (callbacks type) template data with all data, which + * are necessary for generating output code for output files. Shim code is generating + * common function for serialization/deserialization of data. + * + * @param[in] group Group to which function belongs. + * @param[in] fn From this are set function type template data. + * + * @return Contains interface function data. + */ + virtual cpptempl::data_map getFunctionTypeTemplateData(Group *group, FunctionType *fn) = 0; + /*! * @brief This function will get symbol comments and convert to language specific ones * @@ -238,6 +251,14 @@ class Generator */ virtual void generateOutputFiles(const std::string &fileNameExtension) = 0; + /** + * @brief Function return common fileName part for group generated files. + * + * @param group Pointer to a group. + * @return string Common filename part of group generated files. + */ + std::string getGroupCommonFileName(Group *group); + /*! * @brief This function generates output files for defined interfaces. * @@ -347,6 +368,20 @@ class Generator */ datatype_vector_t getDataTypesFromSymbolScope(SymbolScope *scope, DataType::data_type_t datatype); + /*! + * @brief This function return interface function prototype. + * + * @param[in] group Group to which function belongs. + * @param[in] fn Function for prototyping. + * @param[in] interfaceName Interface name used for function declaration. + * @param[in] name Name used for shared code in case of function type. + * @param[in] insideInterfaceCall interfaceClass specific. + * + * @return String prototype representation for given function. + */ + virtual std::string getFunctionPrototype(Group *group, FunctionBase *fn, const std::string &interfaceName = "", + const std::string &name = "", bool insideInterfaceCall = false) = 0; + private: /*! * @brief This function return interface functions list. @@ -359,6 +394,18 @@ class Generator * @return Contains interface functions data. */ cpptempl::data_list getFunctionsTemplateData(Group *group, Interface *iface); + + /*! + * @brief Get the Callbacks template data and dived them to the interface scope list. + * + * @param[in] group Group to which callbacks belongs. + * @param[in] iface Use callbacks belongs to this interface. + * @param[out] callbackTypesInt Template data for current interface scope callbacks + * @param[out] callbackTypesExt Template data for others interface scope callbacks + * @param[out] callbackTypesAll Template data of all callbacks. + */ + void getCallbacksTemplateData(Group *group, const Interface *iface, cpptempl::data_list &callbackTypesInt, + cpptempl::data_list &callbackTypesExt, cpptempl::data_list &callbackTypesAll); }; } // namespace erpcgen diff --git a/erpcgen/src/PythonGenerator.cpp b/erpcgen/src/PythonGenerator.cpp index d42865e5..e56dc373 100644 --- a/erpcgen/src/PythonGenerator.cpp +++ b/erpcgen/src/PythonGenerator.cpp @@ -122,6 +122,7 @@ void PythonGenerator::generate() m_templateData["structs"] = empty; m_templateData["unions"] = empty; m_templateData["consts"] = empty; + m_templateData["functions"] = empty; parseSubtemplates(); @@ -146,8 +147,6 @@ void PythonGenerator::generate() makeEnumsTemplateData(); - makeFunctionsTemplateData(); - for (Group *group : m_groups) { data_map groupTemplate; @@ -173,7 +172,7 @@ data_map PythonGenerator::getFunctionTemplateData(Group *group, Function *fn) { (void)group; data_map info; - string proto = getFunctionPrototype(fn); + string proto = getFunctionPrototype(nullptr, fn); info["name"] = getOutputName(fn); info["prototype"] = proto; @@ -266,12 +265,22 @@ data_map PythonGenerator::getFunctionTemplateData(Group *group, Function *fn) return info; } -string PythonGenerator::getFunctionPrototype(Function *fn) +string PythonGenerator::getFunctionPrototype(Group *group, FunctionBase *fn, const string &interfaceName, + const string &name, bool insideInterfaceCall) { - string proto = getOutputName(fn); + FunctionType *functionType = dynamic_cast(fn); + if (functionType) + { + return ""; /*Todo: implement*/ + } + Function *function = dynamic_cast(fn); + + assert(function); + + string proto = getOutputName(function); proto += "(self"; - auto params = fn->getParameters().getMembers(); + auto params = function->getParameters().getMembers(); if (params.size()) { for (auto it : params) @@ -572,32 +581,6 @@ void PythonGenerator::setOneStructMemberTemplateData(StructMember *member, data_ setTemplateComments(member, member_info); } -void PythonGenerator::makeFunctionsTemplateData() -{ - /* type definitions of functions and table of functions */ - Log::info("Functions:\n"); - data_list functions; - for (Symbol *functionTypeSymbol : getDataTypesFromSymbolScope(m_globals, DataType::data_type_t::kFunctionType)) - { - FunctionType *functionType = dynamic_cast(functionTypeSymbol); - data_map functionInfo; - - /* Table template data. */ - data_list callbacks; - for (Function *fun : functionType->getCallbackFuns()) - { - data_map callbacksInfo; - callbacksInfo["name"] = fun->getName(); - callbacks.push_back(callbacksInfo); - } - functionInfo["callbacks"] = callbacks; - /* Function type name. */ - functionInfo["name"] = functionType->getName(); - functions.push_back(functionInfo); - } - m_templateData["functions"] = functions; -} - data_map PythonGenerator::getTypeInfo(DataType *t) { data_map info; @@ -643,9 +626,9 @@ data_map PythonGenerator::getTypeInfo(DataType *t) } else { - throw semantic_error(format_string("Function has function type parameter (callback parameter), but in " - "IDL is missing function definition, which can be passed there.") - .c_str()); + throw semantic_error( + "Function has function type parameter (callback parameter), but in " + "IDL is missing function definition, which can be passed there."); } break; } @@ -687,7 +670,7 @@ data_map PythonGenerator::getTypeInfo(DataType *t) StructMember *discriminatorMember = dynamic_cast(discriminatorSym); if (!discriminatorMember) { - throw internal_error(format_string("union discriminator is not a struct member")); + throw internal_error("union discriminator is not a struct member"); } info["discriminatorType"] = getTypeInfo(discriminatorMember->getDataType()); } @@ -842,7 +825,7 @@ string PythonGenerator::convertComment(const string &comment, comment_type_t com { (void)commentType; // Longer patterns are ordered earlier than similar shorter patterns. - static const char *const kCommentBegins[] = { "//!<", "//!", "///<", "///", "/*!<", "/*!", "/**<", "/**", 0 }; + static const char *const kCommentBegins[] = { "//!<", "//!", "///<", "///", "/*!<", "/*!", "/**<", "/**", "/*", 0 }; static const char *const kCommentEnds[] = { "*/", 0 }; string result = stripWhitespace(comment); @@ -870,7 +853,7 @@ string PythonGenerator::convertComment(const string &comment, comment_type_t com // Check if we failed to find a matching comment begin. if (kCommentBegins[i] == 0) { - throw internal_error("unable to convert Doxygen comment"); + throw internal_error("Unable to convert Doxygen comment in:" + result); } // Search for a matching comment end to strip. There may not be a comment end. @@ -941,7 +924,7 @@ string PythonGenerator::convertComment(const string &comment, comment_type_t com return result; } -bool PythonGenerator::checkWhitspaceChar(char c) +bool PythonGenerator::checkWhitespaceChar(char c) { if (c == ' ' || c == '\t' || c == '\n' || c == '\r') { @@ -961,7 +944,7 @@ string PythonGenerator::stripWhitespace(const string &s) { char c = result[i]; - if ((i < (int)result.size() - 1 && c == ' ' && !checkWhitspaceChar(result[i + 1])) || !checkWhitspaceChar(c)) + if ((i < (int)result.size() - 1 && c == ' ' && !checkWhitespaceChar(result[i + 1])) || !checkWhitespaceChar(c)) { break; } @@ -975,7 +958,7 @@ string PythonGenerator::stripWhitespace(const string &s) for (n = 0, i = (int)result.size() - 1; i > 0; --i, ++n) { char c = result[i]; - if (!checkWhitspaceChar(c)) + if (!checkWhitespaceChar(c)) { break; } diff --git a/erpcgen/src/PythonGenerator.hpp b/erpcgen/src/PythonGenerator.hpp index 3e392526..e31ee6a4 100644 --- a/erpcgen/src/PythonGenerator.hpp +++ b/erpcgen/src/PythonGenerator.hpp @@ -117,12 +117,25 @@ class PythonGenerator : public Generator * * @param[in] group Pointer to a group. * @param[in] fn From this are set interface function template data. - * @param[in] fnIndex Function index. * * @return Contains interface function data. */ cpptempl::data_map getFunctionTemplateData(Group *group, Function *fn) override; + /*! + * @brief This function returns function type (callbacks type) template data. + * + * This function returns function type (callbacks type) template data with all data, which + * are necessary for generating output code for output files. Shim code is generating + * common function for serialization/deserialization of data. + * + * @param[in] group Group to which function belongs. + * @param[in] fn From this are set function type template data. + * + * @return Contains interface function data. + */ + cpptempl::data_map getFunctionTypeTemplateData(Group *group, FunctionType *fn) override { return {}; }; + /*! * @brief This function will get symbol comments and convert to language specific ones * @@ -134,11 +147,16 @@ class PythonGenerator : public Generator /*! * @brief This function return interface function prototype. * + * @param[in] group Group to which function belongs. * @param[in] fn Function for prototyping. + * @param[in] interfaceName Interface name used for function declaration. + * @param[in] name Name used for shared code in case of function type. + * @param[in] insideInterfaceCall interfaceClass specific. * * @return String prototype representation for given function. */ - std::string getFunctionPrototype(Function *fn); + std::string getFunctionPrototype(Group *group, FunctionBase *fn, const std::string &interfaceName = "", + const std::string &name = "", bool insideInterfaceCall = false) override; /*! * @brief This function sets const template data. @@ -185,13 +203,6 @@ class PythonGenerator : public Generator */ void makeAliasesTemplateData(); - /*! - * @brief This function sets function type template data. - * - * This is used for registering callback functions in generated output. - */ - void makeFunctionsTemplateData(); - /*! * @brief This function sets struct member information to struct data map variable. * @@ -263,7 +274,7 @@ class PythonGenerator : public Generator * * @param[in] c Checked character. */ - bool checkWhitspaceChar(char c); + bool checkWhitespaceChar(char c); /*! * Stores reserved words for Python program language. diff --git a/erpcgen/src/SymbolScanner.cpp b/erpcgen/src/SymbolScanner.cpp index f5c12370..21c6c2ec 100644 --- a/erpcgen/src/SymbolScanner.cpp +++ b/erpcgen/src/SymbolScanner.cpp @@ -45,8 +45,7 @@ void SymbolScanner::handleRoot(AstNode *node, bottom_up) forwardTypes += format_string("type name %s: line %d", it->first.c_str(), it->second->getFirstLine()); } throw syntax_error(format_string("Missing type definitions for one or more forward type declarations: %s", - forwardTypes.c_str()) - .c_str()); + forwardTypes.c_str())); } } @@ -147,37 +146,43 @@ DataType *SymbolScanner::getDataTypeForConst(AstNode *typeNode) AstNode *SymbolScanner::handleType(AstNode *node, top_down) { - // Extract new type name. - AstNode *ident = (*node)[0]; - const Token &tok = ident->getToken(); - const string &name = tok.getStringValue(); - Log::debug("type: %s\n", name.c_str()); - - // Find existing type. - AstNode *typeNode = (*node)[1]; - DataType *dataType = nullptr; - if (!containsStructEnumDeclaration(typeNode)) + if (m_currentInterface == nullptr) { - dataType = lookupDataType(typeNode); - } + // Extract new type name. + AstNode *ident = (*node)[0]; + const Token &tok = ident->getToken(); + const string &name = tok.getStringValue(); + Log::debug("type: %s\n", name.c_str()); - AliasType *type = new AliasType(tok, dataType); + // Find existing type. + AstNode *typeNode = (*node)[1]; + DataType *dataType = nullptr; + if (!containsStructEnumDeclaration(typeNode)) + { + dataType = lookupDataType(typeNode); + } - // Get comment if exist. - addDoxygenComments(type, node->getChild(3), node->getChild(4)); + AliasType *type = new AliasType(tok, dataType); - m_currentAlias = type; + // Get comment if exist. + addDoxygenComments(type, node->getChild(3), node->getChild(4)); + + m_currentAlias = type; + } return nullptr; } AstNode *SymbolScanner::handleType(AstNode *node, bottom_up) { - if (m_currentAlias) + if (m_currentInterface == nullptr) { - addAnnotations(node->getChild(2), m_currentAlias); - addGlobalSymbol(m_currentAlias); - m_currentAlias = nullptr; + if (m_currentAlias) + { + addAnnotations(node->getChild(2), m_currentAlias); + addGlobalSymbol(m_currentAlias); + m_currentAlias = nullptr; + } } return nullptr; } @@ -637,9 +642,8 @@ AstNode *SymbolScanner::handleStruct(AstNode *node, top_down) AstNode *structNameNode = (*node)[0]; if (!structNameNode && m_currentAlias == nullptr) { - throw semantic_error( - format_string("line %d: illegal anonymous struct definition at file level", node->getToken().getFirstLine()) - .c_str()); + throw semantic_error(format_string("line %d: illegal anonymous struct definition at file level", + node->getToken().getFirstLine())); } // Create the struct symbol. @@ -661,10 +665,10 @@ AstNode *SymbolScanner::handleStruct(AstNode *node, top_down) } else { - throw syntax_error(format_string("line %d: Structure definition type name didn't match data type of " - "forward declaration from line %d.", - tok.getFirstLine(), forwardDecl->second->getFirstLine()) - .c_str()); + throw syntax_error( + format_string("line %d: Structure definition type name didn't match data type of " + "forward declaration from line %d.", + tok.getFirstLine(), forwardDecl->second->getFirstLine())); } } else @@ -817,10 +821,10 @@ AstNode *SymbolScanner::handleUnion(AstNode *node, top_down) } else { - throw syntax_error(format_string("line %d: Union definition type name didn't match data type of " - "forward declaration from line %d.", - tok->getFirstLine(), forwardDecl->second->getFirstLine()) - .c_str()); + throw syntax_error( + format_string("line %d: Union definition type name didn't match data type of " + "forward declaration from line %d.", + tok->getFirstLine(), forwardDecl->second->getFirstLine())); } } else @@ -1013,6 +1017,55 @@ AstNode *SymbolScanner::handleInterface(AstNode *node, bottom_up) { addAnnotations(node->getChild(2), m_currentInterface); + /* Check if function callbacks were not used in other interfaces*/ + for (Symbol *funSymbol : m_globals->getSymbolsOfType(Symbol::symbol_type_t::kInterfaceSymbol)) + { + Interface *interface = dynamic_cast(funSymbol); + assert(interface); + + if (interface == m_currentInterface) + { + continue; + } + + for (Function *func : interface->getFunctions()) + { + for (StructMember *param : func->getParameters().getMembers()) + { + DataType *dataType = param->getDataType()->getTrueDataType(); + if (dataType->isFunction()) + { + FunctionType *funcType = dynamic_cast(dataType); + assert(funcType); + + if ((m_currentInterface->getName() == funcType->getInterface()->getName()) && + (m_currentInterface != funcType->getInterface())) + { + bool found = false; + for (FunctionType *funcTypeCurrent : m_currentInterface->getFunctionTypes()) + { + if (funcTypeCurrent->getName() == funcType->getName()) + { + found = true; + delete funcType->getInterface(); + delete funcType; + param->setDataType(funcTypeCurrent); + break; + } + } + if (found == false) + { + throw syntax_error( + format_string("line %d, Callback name %s doesn't exists in interface %s.\n", + funcType->getLocation().m_firstLine, funcType->getName().c_str(), + funcType->getInterface()->getName().c_str())); + } + } + } + } + } + } + // Interfaces cannot be nested, so we can just clear this. If they were nestable, we would // have to keep a stack of open interfaces. m_currentInterface = nullptr; @@ -1027,10 +1080,16 @@ AstNode *SymbolScanner::handleFunction(AstNode *node, top_down) const Token &tok = ident->getToken(); const string &name = tok.getStringValue(); Log::debug("function: %s\n", name.c_str()); + bool isFunctionType = node->getChild(4) != nullptr; // Create function symbol. FunctionBase *func; - if (m_currentInterface) /* function definition */ + if (isFunctionType) + { + func = new FunctionType(tok, m_currentInterface); + m_currentInterface->addFunctionType(dynamic_cast(func)); + } + else { if (m_currentInterface->getFunctions().size() == 0) { @@ -1042,11 +1101,6 @@ AstNode *SymbolScanner::handleFunction(AstNode *node, top_down) } m_currentInterface->addFunction(dynamic_cast(func)); } - else /* function type */ - { - func = new FunctionType(tok); - addGlobalSymbol(dynamic_cast(func)); - } m_currentStruct = &(func->getParameters()); @@ -1123,21 +1177,30 @@ AstNode *SymbolScanner::handleFunction(AstNode *node, top_down) } /* Get comment if exist. */ - addDoxygenComments(dynamic_cast(func), node->getChild(5), node->getChild(6)); + addDoxygenComments(dynamic_cast(func), node->getChild(6), node->getChild(7)); return nullptr; } AstNode *SymbolScanner::handleFunction(AstNode *node, bottom_up) { + bool isFunctionType = node->getChild(4) != nullptr; - if (m_currentInterface) /* function definition */ + if (isFunctionType) /* function type */ + { + FunctionType *func = m_currentInterface->getFunctionTypes().back(); + func->getParameters().getScope().setParent(&m_currentInterface->getScope()); + + /* Function annotations. */ + addAnnotations(node->getChild(5), func); + } + else /* function definition */ { Function *func = m_currentInterface->getFunctions().back(); func->getParameters().getScope().setParent(&m_currentInterface->getScope()); /* Function annotations. */ - addAnnotations(node->getChild(4), func); + addAnnotations(node->getChild(5), func); /* Add missing callbacks parameters. */ FunctionType *callbackFunctionType = func->getFunctionType(); @@ -1162,25 +1225,6 @@ AstNode *SymbolScanner::handleFunction(AstNode *node, bottom_up) } } } - else /* function type */ - { - FunctionType *func = nullptr; - for (Symbol *funSymbol : m_globals->getSymbolsOfType(Symbol::symbol_type_t::kTypenameSymbol)) - { - DataType *datatype = dynamic_cast(funSymbol); - assert(datatype); - - if (datatype->isFunction()) - { - func = dynamic_cast(datatype); - } - } - assert(func); - func->getParameters().getScope().setParent(m_globals); - - /* Function annotations. */ - addAnnotations(node->getChild(4), func); - } // Handle annotations for function params scanStructForAnnotations(); @@ -1198,34 +1242,27 @@ AstNode *SymbolScanner::handleParam(AstNode *node, top_down) StructMember *callbackParam = nullptr; Function *fun = nullptr; FunctionType *funType = nullptr; - if (m_currentInterface) + bool isFunctionType = m_currentInterface->getFunctions().empty(); + if (!isFunctionType) { fun = m_currentInterface->getFunctions().back(); - for (Symbol *funSymbol : m_globals->getSymbolsOfType(Symbol::symbol_type_t::kTypenameSymbol)) + for (FunctionType *funType : m_currentInterface->getFunctionTypes()) { - DataType *datatype = dynamic_cast(funSymbol); - assert(datatype); - - if (datatype->isFunction()) + FunctionType::c_function_list_t &callbacks = funType->getCallbackFuns(); + if (find(callbacks.begin(), callbacks.end(), fun) != callbacks.end()) { - funType = dynamic_cast(datatype); - assert(funType); - FunctionType::c_function_list_t &callbacks = funType->getCallbackFuns(); - if (find(callbacks.begin(), callbacks.end(), fun) != callbacks.end()) + if (fun->getParameters().getMembers().size() > funType->getParameters().getMembers().size()) { - if (fun->getParameters().getMembers().size() > funType->getParameters().getMembers().size()) - { - throw syntax_error(format_string("line %d: Function definition contains more parameters than " - "function type definition from %d.\n", - fun->getFirstLine(), funType->getFirstLine()) - .c_str()); - } - else - { - callbackParam = funType->getParameters().getMembers()[fun->getParameters().getMembers().size()]; - } - break; + throw syntax_error( + format_string("line %d: Function definition contains more parameters than " + "function type definition from %d.\n", + fun->getFirstLine(), funType->getFirstLine())); } + else + { + callbackParam = funType->getParameters().getMembers()[fun->getParameters().getMembers().size()]; + } + break; } } } @@ -1260,7 +1297,48 @@ AstNode *SymbolScanner::handleParam(AstNode *node, top_down) /* Extract param data type. */ AstNode *typeNode = (*node)[1]; assert(typeNode); - DataType *dataType = lookupDataType(typeNode); + DataType *dataType = nullptr; + const Token &typeToken = typeNode->getToken(); + if (typeToken.getToken() == TOK_IFACE_SCOPE) + { + /* Find if interface and function definition exist already or create temporary. */ + AstNode *iface = typeNode->getChild(0); + AstNode *type = typeNode->getChild(1); + std::string ifaceName = iface->getToken().getStringValue(); + std::string functionTypeName = type->getToken().getStringValue(); + for (Symbol *funSymbol : m_globals->getSymbolsOfType(Symbol::symbol_type_t::kInterfaceSymbol)) + { + Interface *interface = dynamic_cast(funSymbol); + assert(interface); + + if (interface->getName() == ifaceName) + { + for (FunctionType *funcType : interface->getFunctionTypes()) + { + if (funcType->getName() == functionTypeName) + { + dataType = funcType; + break; + } + } + if (dataType == nullptr) + { + throw syntax_error(format_string("line %d: Callback name %s doesn't exists.\n", + type->getToken().getFirstLine(), functionTypeName.c_str())); + } + break; + } + } + if (dataType == nullptr) + { + /* create temporary */ + dataType = new FunctionType(type->getToken(), new Interface(iface->getToken())); + } + } + else + { + dataType = lookupDataType(typeNode); + } /* Extract param name. */ if (ident) @@ -1268,7 +1346,7 @@ AstNode *SymbolScanner::handleParam(AstNode *node, top_down) Token &tok = ident->getToken(); param = new StructMember(tok, dataType); } - else if (m_currentInterface && !funType) // Functions need param names. Types of functions don't. + else if (!isFunctionType) // Functions need param names. Types of functions don't. { throw syntax_error( format_string("line %d: Missing function param name.\n", node->getToken().getFirstLine())); @@ -1368,15 +1446,25 @@ DataType *SymbolScanner::lookupDataType(const AstNode *typeNode) const Token &typeToken = typeNode->getToken(); switch (typeToken.getToken()) { - case TOK_ARRAY: + case TOK_ARRAY: { return createArrayType(typeNode); + } - case TOK_IDENT: - return lookupDataTypeByName(typeToken, m_globals); - - case TOK_LIST: + case TOK_IDENT: { + DataType *dataType = nullptr; + if (m_currentInterface != nullptr) + { + dataType = lookupDataTypeByName(typeToken, &m_currentInterface->getScope()); + } + if (dataType == nullptr) + { + dataType = lookupDataTypeByName(typeToken, m_globals); + } + return dataType; + } + case TOK_LIST: { return createListType(typeNode); - + } case TOK_UNION: { assert(nullptr != m_currentStruct); return lookupDataTypeByName(typeNode->getChild(3)->getToken(), &(m_currentStruct->getScope()), false); @@ -1414,7 +1502,7 @@ DataType *SymbolScanner::createArrayType(const AstNode *typeNode) return array; } -Value *SymbolScanner::getValueFromSymbol(Token &tok) +Value *SymbolScanner::getValueFromSymbol(const Token &tok) { if (tok.getValue() != nullptr) { @@ -1572,8 +1660,7 @@ Annotation::program_lang_t SymbolScanner::getAnnotationLang(AstNode *annotation) } throw semantic_error(format_string("line %d: Unsupported programming language '%s' specified.", - annotation->getToken().getFirstLine(), lang.c_str()) - .c_str()); + annotation->getToken().getFirstLine(), lang.c_str())); } return Annotation::program_lang_t::kAll; @@ -1751,8 +1838,7 @@ void SymbolScanner::addForwardDeclaration(DataType *dataType) { throw semantic_error(format_string("line %d: Declaring type '%s' already declared here '%d'", dataType->getFirstLine(), dataType->getName().c_str(), - symbol->getFirstLine()) - .c_str()); + symbol->getFirstLine())); } auto findDataTypeIT = m_forwardDeclarations.find(dataType->getName()); @@ -1762,8 +1848,7 @@ void SymbolScanner::addForwardDeclaration(DataType *dataType) { throw semantic_error(format_string("line %d: Declaring type '%s' already declared here '%d'", dataType->getFirstLine(), dataType->getName().c_str(), - findDataTypeIT->second->getFirstLine()) - .c_str()); + findDataTypeIT->second->getFirstLine())); } else { @@ -1782,8 +1867,7 @@ void SymbolScanner::removeForwardDeclaration(DataType *dataType) { throw semantic_error(format_string("line %d: Declaring type '%s' already declared here '%d'", dataType->getFirstLine(), dataType->getName().c_str(), - findDataTypeIT->second->getFirstLine()) - .c_str()); + findDataTypeIT->second->getFirstLine())); } m_forwardDeclarations.erase(findDataTypeIT); } @@ -1796,8 +1880,7 @@ void SymbolScanner::addGlobalSymbol(Symbol *symbol) { throw semantic_error(format_string("line %d: Declaring symbol '%s' already declared here '%d'", symbol->getFirstLine(), symbol->getName().c_str(), - findDataTypeIT->second->getFirstLine()) - .c_str()); + findDataTypeIT->second->getFirstLine())); } m_globals->addSymbol(symbol); } diff --git a/erpcgen/src/SymbolScanner.hpp b/erpcgen/src/SymbolScanner.hpp index 7a2e32a9..5b72e808 100644 --- a/erpcgen/src/SymbolScanner.hpp +++ b/erpcgen/src/SymbolScanner.hpp @@ -458,7 +458,7 @@ class SymbolScanner : public AstWalker * @exception syntax_error Thrown, when token value is null or when symbol is not defined in global symbol scope. * @exception semantic_error Thrown, when symbol type is not constant or enum member. */ - Value *getValueFromSymbol(Token &tok); + Value *getValueFromSymbol(const Token &tok); /*! * @brief This function returns the data type for a constant variable diff --git a/erpcgen/src/UniqueIdChecker.cpp b/erpcgen/src/UniqueIdChecker.cpp index 48d102e6..b06dd22e 100644 --- a/erpcgen/src/UniqueIdChecker.cpp +++ b/erpcgen/src/UniqueIdChecker.cpp @@ -26,7 +26,7 @@ using namespace std; // Code //////////////////////////////////////////////////////////////////////////////// -void UniqueIdChecker::makeIdsUnique(erpcgen::InterfaceDefinition &def) +void UniqueIdChecker::makeIdsUnique(InterfaceDefinition &def) { initUsedInterfaceIds(def.getGlobals().getSymbolsOfType(Symbol::symbol_type_t::kInterfaceSymbol)); diff --git a/erpcgen/src/UniqueIdChecker.hpp b/erpcgen/src/UniqueIdChecker.hpp index 942b680d..c9390b57 100644 --- a/erpcgen/src/UniqueIdChecker.hpp +++ b/erpcgen/src/UniqueIdChecker.hpp @@ -38,7 +38,7 @@ class UniqueIdChecker * * @param[in] def Interface definition variable. */ - void makeIdsUnique(erpcgen::InterfaceDefinition &def); + void makeIdsUnique(InterfaceDefinition &def); private: /*! @@ -46,14 +46,14 @@ class UniqueIdChecker * * @param[in] ifaces Vector of interfaces. */ - void initUsedInterfaceIds(erpcgen::SymbolScope::symbol_vector_t ifaces); + void initUsedInterfaceIds(SymbolScope::symbol_vector_t ifaces); /*! * @brief This function will go through interface functions and set initial value of id number. * * @param[in] iface Interface. */ - void initUsedFunctionIds(erpcgen::Interface *iface); + void initUsedFunctionIds(Interface *iface); /*! * @brief This helper function sets a function symbol's unique id from the specified annotation. diff --git a/erpcgen/src/annotations.h b/erpcgen/src/annotations.h index afa0cc60..c88f138f 100644 --- a/erpcgen/src/annotations.h +++ b/erpcgen/src/annotations.h @@ -40,6 +40,9 @@ //! Specify the symbol name. #define NAME_ANNOTATION "name" +//! Specify the namespace of program code. +#define NAMESPACE_ANNOTATION "namespace" + //! Turn off error checking code for allocations in generated output #define NO_ALLOC_ERRORS_ANNOTATION "no_alloc_errors" @@ -76,7 +79,4 @@ //! Shared memory area end address #define SHARED_MEMORY_END_ANNOTATION "shared_memory_end" -//! Place all types definitions (e.g. typedef, structs, etc.) into one file -#define TYPES_HEADER_ANNOTATION "types_header" - #endif /* _EMBEDDED_RPC__ANNOTATIONS_H_ */ diff --git a/erpcgen/src/erpcgen.cpp b/erpcgen/src/erpcgen.cpp index af7b132b..056a8ec6 100644 --- a/erpcgen/src/erpcgen.cpp +++ b/erpcgen/src/erpcgen.cpp @@ -98,19 +98,19 @@ class erpcgenTool { kCLanguage, kPythonLanguage, - }; /*!< Generated outputs format. */ + }; /*!< Generated outputs format. */ typedef vector string_vector_t; /*!< Vector of positional arguments. */ - int m_argc; /*!< Number of command line arguments. */ - char **m_argv; /*!< String value for each command line argument. */ - StdoutLogger *m_logger; /*!< Singleton logger instance. */ - verbose_type_t m_verboseType; /*!< Which type of log is need to set (warning, info, debug). */ - const char *m_outputFilePath; /*!< Path to the output file. */ - const char *m_ErpcFile; /*!< ERPC file. */ - string_vector_t m_positionalArgs; /*!< Positional arguments. */ - languages_t m_outputLanguage; /*!< Output language we're generating. */ - InterfaceDefinition::codec_t m_codec; /*!< Used codec type. */ + int m_argc; /*!< Number of command line arguments. */ + char **m_argv; /*!< String value for each command line argument. */ + StdoutLogger *m_logger; /*!< Singleton logger instance. */ + verbose_type_t m_verboseType; /*!< Which type of log is need to set (warning, info, debug). */ + const char *m_outputFilePath; /*!< Path to the output file. */ + const char *m_ErpcFile; /*!< ERPC file. */ + string_vector_t m_positionalArgs; /*!< Positional arguments. */ + languages_t m_outputLanguage; /*!< Output language we're generating. */ + InterfaceDefinition::codec_t m_codec; /*!< Used codec type. */ public: /*! @@ -205,7 +205,7 @@ class erpcgenTool } else { - Log::error(format_string("error: unknown language %s", lang.c_str()).c_str()); + Log::error("error: unknown language %s", lang.c_str()); return 1; } break; @@ -219,7 +219,7 @@ class erpcgenTool } else { - Log::error(format_string("error: unknown codec type %s", codec.c_str()).c_str()); + Log::error("error: unknown codec type %s", codec.c_str()); return 1; } break; diff --git a/erpcgen/src/erpcgen_lexer.l b/erpcgen/src/erpcgen_lexer.l index 1c0a1b20..9bbdd998 100644 --- a/erpcgen/src/erpcgen_lexer.l +++ b/erpcgen/src/erpcgen_lexer.l @@ -237,6 +237,8 @@ void { return TOK_VOID; } "->" { return TOK_ARROW; } +"::" { return TOK_IFACE_SCOPE; } + [@{}()\[\]<>=,;:+\-*/%^~&|] { return yytext[0]; } \"(ESC|[^\"])*\" { diff --git a/erpcgen/src/erpcgen_parser.y b/erpcgen/src/erpcgen_parser.y index 46586703..f49eb396 100644 --- a/erpcgen/src/erpcgen_parser.y +++ b/erpcgen/src/erpcgen_parser.y @@ -155,6 +155,7 @@ token_loc_t mergeLocation(const token_loc_t & l1, const token_loc_t & l2); %token TOK_ML_COMMENT "doxygen ml. comment" %token TOK_IL_COMMENT "doxygen il. comment" %token TOK_PROGRAM "program" +%token TOK_IFACE_SCOPE "::" %token END 0 "end of file" // virtual tokens used for AST @@ -210,6 +211,8 @@ token_loc_t mergeLocation(const token_loc_t & l1, const token_loc_t & l2); %type function_return_type %type function_type_base_def %type function_type_def +%type function_cb_type_def +%type function_cb_type_list %type ident %type ident_opt %type int_const_expr @@ -225,6 +228,7 @@ token_loc_t mergeLocation(const token_loc_t & l1, const token_loc_t & l2); %type program %type root_def %type simple_data_type +%type simple_data_type_scope %type string_literal %type struct_def %type struct_data_type @@ -339,11 +343,6 @@ definition_base : const_def { $$ = $interface_def; } - | - function_type_def - { - $$ = $function_type_def; - } ; import_stmt : TOK_IMPORT TOK_STRING_LITERAL @@ -451,7 +450,7 @@ interface_def : TOK_INTERFACE[iface] ident[name] '{' function_def_list_opt[f ; function_def_list_opt - : function_def_list + : function_def_list { $$ = $function_def_list; } @@ -465,7 +464,12 @@ function_def_list_opt * TOK_CHILDREN -> ( function_def* ) */ function_def_list - : function_def + : function_cb_type_list function_def + { + $function_cb_type_list->appendChild($function_def); + $$ = $function_cb_type_list; + } + | function_def { $$ = new AstNode(Token(TOK_CHILDREN)); $$->appendChild($function_def); @@ -477,13 +481,39 @@ function_def_list } ; +function_cb_type_def + : doxy_ml_comment_opt annotation_list_opt TOK_TYPE function_type_def comma_semi_opt doxy_il_comment_opt + { + $$ = $function_type_def; + $$->appendChild(new AstNode(*$TOK_TYPE)); + $$->appendChild($annotation_list_opt); + $$->appendChild($doxy_ml_comment_opt); + $$->appendChild($doxy_il_comment_opt); + } + ; + +function_cb_type_list + : function_cb_type_def + { + $$ = new AstNode(Token(TOK_CHILDREN)); + $$->appendChild($function_cb_type_def); + } + | function_cb_type_list[fun_type_list] function_cb_type_def + { + $fun_type_list->appendChild($function_cb_type_def); + $$ = $fun_type_list; + } + ; + function_def : doxy_ml_comment_opt annotation_list_opt function_type_base_def comma_semi_opt doxy_il_comment_opt { $$ = $function_type_base_def; + $$->appendChild(NULL); /* Compatibility with function type definition */ $$->appendChild($annotation_list_opt); $$->appendChild($doxy_ml_comment_opt); $$->appendChild($doxy_il_comment_opt); } + ; function_type_base_def : function_type_def @@ -592,7 +622,7 @@ param_list_in : param_def_in /* * TOK_PARAM -> ( ident simple_data_type ( TOK_CHILDREN -> TOK_ANNOTATION* ) ) */ -param_def : param_dir[dir] simple_data_type[datatype] ident_opt[name] annotation_list_opt[annotations] +param_def : param_dir[dir] simple_data_type_scope[datatype] ident_opt[name] annotation_list_opt[annotations] { $$ = new AstNode(Token(TOK_PARAM, NULL, @name)); $$->appendChild($name); @@ -603,7 +633,7 @@ param_def : param_dir[dir] simple_data_type[datatype] ident_opt[name] an } ; -param_def_in : param_dir_in[dir] simple_data_type[datatype] ident_opt[name] annotation_list_opt[annotations] +param_def_in : param_dir_in[dir] simple_data_type_scope[datatype] ident_opt[name] annotation_list_opt[annotations] { $$ = new AstNode(Token(TOK_PARAM, NULL, @name)); $$->appendChild($name); @@ -892,6 +922,19 @@ union_member } ; +simple_data_type_scope + : ident TOK_IFACE_SCOPE typename + { + $$ = new AstNode(Token(TOK_IFACE_SCOPE)); + $$->appendChild($ident); + $$->appendChild($typename); + } + | simple_data_type + { + $$ = $simple_data_type; + } + ; + simple_data_type : list_type { @@ -905,7 +948,6 @@ simple_data_type { $$ = $typename; } - ; data_type : simple_data_type diff --git a/erpcgen/src/templates/c_client_header.template b/erpcgen/src/templates/c_client_header.template new file mode 100644 index 00000000..fb83a8b2 --- /dev/null +++ b/erpcgen/src/templates/c_client_header.template @@ -0,0 +1,70 @@ +{% if mlComment != "" %} +{$mlComment} + +{% endif %} +{$commonHeader()} + +#if !defined({$clientCGuardMacro}) +#define {$clientCGuardMacro} + +#include "{$commonCHeaderName}" +#include "erpc_client_manager.h" +{% for iface in group.interfaces %} +{% for fn in iface.functions %} +{% for externalInterface in fn.externalInterfaces %} +{% for interfaceFile in interfacesFiles %} +{% if externalInterface == interfaceFile.interfaceName %} +#include "c_{$interfaceFile.interfaceCommonFileName}_client.h" +{% endif %} +{% endfor -- interfacesFiles %} +{% endfor -- externalInterface %} +{% endfor -- fn %} +{% endfor -- iface %} + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#if !defined({$getFunctionDeclarationMacroName()}) +#define {$getFunctionDeclarationMacroName()} + +{% for iface in group.interfaces %} +{% for cb in iface.callbacksInt%} +typedef {$cb.typenameName}; +{% endfor %} + +/*! @brief {$iface.name} identifiers */ +enum _{$iface.name}_ids +{ + k{$iface.name}_service_id = {$iface.id}, +{% for fn in iface.functions %} + k{$iface.name}_{$fn.name}_id = {$fn.id}, +{% endfor %} +}; + +{% endfor %} +{% for iface in group.interfaces if iface.isNonExternalInterface == true %} +{$> iface.mlComment} +//! @name {$iface.name} +//@{ +{% for fn in iface.functions if fn.isNonExternalFunction == true %} +{$> fn.mlComment} +{$fn.prototype};{$fn.ilComment}{$loop.addNewLineIfNotLast} +{% endfor -- functions %} +//@}{$iface.ilComment} + +{% endfor -- iface %} +#endif // {$getFunctionDeclarationMacroName()} + +{% for iface in group.interfaces %} +void init{$iface.clientClassName}(erpc_client_t client); + +void deinit{$iface.clientClassName}(void); + +{% endfor -- iface %} +#if defined(__cplusplus) +} +#endif + +#endif // {$clientCGuardMacro} diff --git a/erpcgen/src/templates/c_client_source.template b/erpcgen/src/templates/c_client_source.template index 7d1c8ac6..619e65cf 100644 --- a/erpcgen/src/templates/c_client_source.template +++ b/erpcgen/src/templates/c_client_source.template @@ -1,197 +1,102 @@ +{% set source = "client" >%} {% if mlComment != "" %} {$mlComment} {% endif %} {$commonHeader()} -#include "erpc_client_manager.h" -#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC -#include "erpc_port.h" -#endif -#include "{$codecHeader}" -extern "C" -{ -#include "{$commonHeaderName}.h" -{% if groupNames %} -// import callbacks declaration from other groups -{% for name in groupNames if name != group.name %} -#include "{$outputFilename}_{$name}.h" -{% endfor %} -{% endif %} -} +#include "{$clientCHeaderName}" +#include "{$clientCppHeaderName}" +#include "erpc_manually_constructed.hpp" +{% set utils = false >%} +{% for iface in group.interfaces %} +{% if (count(iface.callbacksAll) > 0) && (utils == false) %} +#include "erpc_utils.hpp" +{% set utils = true >%} +{% endif %} +{% endfor %} -{$checkVersion()} -{$>checkCrc()} using namespace erpc; using namespace std; +{$usingNamespace() >} +{% for iface in group.interfaces %} +{% if count(iface.callbacksAll) > 0 %} -extern ClientManager *g_client; -{$generateCrcVariable()} -{$> setSharedMemAddresses()} -{% if unitTest %} -{$> callbackTable(functions)} -{% endif %} -{$> constantsDefinitions(consts)} -{$> symbolHeader(group.symbolsMap.symbolsToServer, "serial", "def")} -{$> symbolSource(group.symbolsMap.symbolsToServer, "serial", "def")} -{$> symbolHeader(group.symbolsMap.symbolsToClient, "deserial", "def")} -{$> symbolSource(group.symbolsMap.symbolsToClient, "deserial", "def")} -{$> symbolHeader(group.symbolsMap.symbolsToServer, "serial", "noSharedMem")} -{$> symbolSource(group.symbolsMap.symbolsToServer, "serial", "noSharedMem")} -{$> symbolHeader(group.symbolsMap.symbolsToClient, "deserial", "noSharedMem")} -{$> symbolSource(group.symbolsMap.symbolsToClient, "deserial", "noSharedMem")} -{% def clientShimCode(fn, serverIDName, functionIDName) ------------------------- clientShimCode(fn, serverIDName, functionIDName) %} -{% set clientIndent = "" >%} -{% if generateErrorChecks %} - erpc_status_t err = kErpcStatus_Success; - -{% endif -- generateErrorChecks %} -{% if fn.isReturnValue %} -{% if fn.needTempVariableClientI32 %} - int32_t _tmp_local_i32; +{% for cb in iface.callbacksAll %} +static const {$cb.name} _{$cb.name}[{$count(cb.callbacks)}] = { {% for c in cb.callbacks %}{$c.name}{% if !loop.last %}, {% endif -- loop.last %}{% endfor -- f.callbacks %} }; +{% endfor %} {% endif %} -{% endif %} -{% if fn.returnValue.type.isNotVoid %} - {$fn.returnValue.resultVariable}{% if fn.returnValue.isNullReturnType %} = NULL{% endif %}; -{% endif -- isNotVoid %} +{% endfor %} -#if ERPC_PRE_POST_ACTION - pre_post_action_cb preCB = g_client->getPreCB(); - if (preCB) - { - preCB(); - } +{% for iface in group.interfaces %} +#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC +{$iface.clientClassName} *s_{$iface.clientClassName} = nullptr; +#else +ERPC_MANUALLY_CONSTRUCTED_STATIC({$iface.clientClassName}, s_{$iface.clientClassName}); #endif +{% endfor -- iface %} +{% for iface in group.interfaces %} +{% for fn in iface.functions %} - // Get a new request. -{% if !fn.isReturnValue %} - RequestContext request = g_client->createRequest(true); -{% else %} - RequestContext request = g_client->createRequest(false); -{% endif -- isReturnValue %} - - // Encode the request. -{% if codecClass == "Codec" %} - {$codecClass} * codec = request.getCodec(); -{% else %} - {$codecClass} * codec = static_cast<{$codecClass} *>(request.getCodec()); +{$fn.prototype} +{ +{% if count(fn.callbackParameters) > 0 %} + uint16_t _fnIndex; +{% for cb in fn.callbackParameters%} + {% if cb.interface != ""%}{$cb.interface}{% else %}{$iface.interfaceClassName}{% endif %}::{$cb.type} _{$cb.name} = NULL; +{% endfor %} +{% endif%} +{% if fn.returnValue.type.isNotVoid %} + {$fn.returnValue.resultVariable}{% if fn.returnValue.isNullReturnType %} = NULL{% endif %}; {% endif %} +{% if count(fn.callbackParameters) > 0 %} +{% for cb in fn.callbackParameters if cb.in %} -{% if generateAllocErrorChecks %} -{% set clientIndent = " " >%} - if (codec == NULL) + if (findIndexOfFunction((arrayOfFunctionPtr_t)_{$cb.type}, sizeof(_{$cb.type})/sizeof({$cb.type}), (functionPtr_t){$cb.name}, _fnIndex)) { - err = kErpcStatus_MemoryError; + {% if cb.interface != ""%}{$cb.interface}{% else %}{$iface.interfaceClassName}{% endif %}::get_callbackAddress_{$cb.type}(_fnIndex, &_{$cb.name}); } - else - { -{% endif -- generateErrorChecks %} -{$clientIndent} codec->startWriteMessage({% if not fn.isReturnValue %}message_type_t::kOnewayMessage{% else %}message_type_t::kInvocationMessage{% endif %}, {$serverIDName}, {$functionIDName}, request.getSequence()); - -{% if fn.isSendValue %} -{% for param in fn.parameters if (param.serializedDirection == "" || param.serializedDirection == OutDirection || param.referencedName != "") %} -{% if param.isNullable %} -{$ addIndent(clientIndent & " ", f_paramIsNullableEncode(param))} - -{% else -- isNullable %} -{% if param.direction != OutDirection %} -{$addIndent(clientIndent & " ", param.coderCall.encode(param.coderCall))} - -{% endif -- param != OutDirection %} -{% endif -- isNullable %} -{% endfor -- fn parameters %} -{% endif -- isSendValue %} -{$clientIndent} // Send message to server -{$clientIndent} // Codec status is checked inside this function. -{$clientIndent} g_client->performRequest(request); -{% if fn.isReturnValue %} -{% for param in fn.parametersToClient if (param.serializedDirection == "" || param.serializedDirection == InDirection || param.referencedName != "") %} - -{% if param.isNullable %} -{% if ((source == "client") && (param.direction != ReturnDirection) && (empty(param.lengthName) == false)) %} -{% set lengthNameCon = ") && (" & param.lengthName & " != NULL)" >%} -{% else %} -{% set lengthNameCon = "" >%} -{% endif %} -{$clientIndent} if ({% if lengthNameCon != "" %}({% endif %}{$param.nullableName} != NULL{$lengthNameCon}) -{$clientIndent} { -{$addIndent(clientIndent & " ", param.coderCall.decode(param.coderCall))} - } -{% else -- notNullable %} -{$addIndent(clientIndent & " ", param.coderCall.decode(param.coderCall))} -{% endif -- isNullable %} -{% endfor -- fn parametersToClient %} -{% if fn.returnValue.type.isNotVoid %} - -{% if fn.returnValue.isNullable %} -{$clientIndent} bool isNull; -{$addIndent(clientIndent & " ", f_paramIsNullableDecode(fn.returnValue))} -{% else -- isNullable %} -{$> addIndent(clientIndent & " ", allocMem(fn.returnValue.firstAlloc))} -{$addIndent(clientIndent & " ", fn.returnValue.coderCall.decode(fn.returnValue.coderCall))} -{% endif -- isNullable %} -{% endif -- isNotVoid %} -{% endif -- isReturnValue %} -{% if generateErrorChecks %} - -{$clientIndent} err = codec->getStatus(); -{% endif -- generateErrorChecks %} -{% if generateAllocErrorChecks %} - } -{% endif -- generateAllocErrorChecks %} - - // Dispose of the request. - g_client->releaseRequest(request); -{% if generateErrorChecks %} - - // Invoke error handler callback function - g_client->callErrorHandler(err, {$functionIDName}); -{% endif -- generateErrorChecks %} - -#if ERPC_PRE_POST_ACTION - pre_post_action_cb postCB = g_client->getPostCB(); - if (postCB) - { - postCB(); - } -#endif +{% endfor %} -{% if generateErrorChecks && fn.returnValue.type.isNotVoid %} -{% if empty(fn.returnValue.errorReturnValue) == false && fn.returnValue.isNullReturnType == false %} +{%endif%} + {% if fn.returnValue.type.isNotVoid %}result = {% endif %}s_{$iface.clientClassName}->{$fn.name}({% for param in fn.parameters %}{% if !loop.first %}, {% endif %}{$param.pureNameC}{% endfor %}); +{% for cb in fn.callbackParameters if cb.out %} - if (err != kErpcStatus_Success) + if ({% if cb.interface != ""%}{$cb.interface}{% else %}{$iface.interfaceClassName}{% endif %}::get_callbackIdx_{$cb.type}(&_{$cb.name}, _fnIndex)) { - result = {$fn.returnValue.errorReturnValue}; + *{$cb.name}=_{$cb.type}[_fnIndex]; } -{% endif %} -{% endif -- generateErrorChecks %} +{% endfor %} +{% if fn.returnValue.type.isNotVoid %} - return{% if fn.returnValue.type.isNotVoid %} result{% endif -- isNotVoid %}; -{% enddef --------------------------------------------------------------------------------- clientShimCode(fn, serverIDName, functionIDName) %} -{% for callbackType in group.callbacks %} -// Common function for serializing and deserializing callback functions of same type. -static {$callbackType.prototype}; + return result; +{% endif %} +} +{% endfor -- fn %} +{% endfor -- iface %} +{% for iface in group.interfaces %} -{% endfor %} -{% for callbackType in group.callbacks %} -// Common function for serializing and deserializing callback functions of same type. -static {$callbackType.prototype} +void init{$iface.clientClassName}(erpc_client_t client) { -{$ clientShimCode(callbackType, "serviceID", "functionID") >} +#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC + erpc_assert(s_{$iface.clientClassName} == nullptr); + s_{$iface.clientClassName} = new {$iface.clientClassName}(reinterpret_cast(client)); +#else + erpc_assert(!s_{$iface.clientClassName}.isUsed()); + s_{$iface.clientClassName}.construct(reinterpret_cast(client)); +#endif } -{% endfor %} -{% for iface in group.interfaces %} -{% for fn in iface.functions %} - -// {$iface.name} interface {$fn.name} function client shim. -{$fn.prototype} +void deinit{$iface.clientClassName}(void) { -{% if fn.isCallback %} - {% if fn.returnValue.type.isNotVoid %}return {% endif %}{$fn.callbackFName}(k{$iface.name}_service_id, k{$iface.name}_{$fn.name}_id{% for param in fn.parameters %}, {$param.name}{% endfor %}); -{% else -- fn.isCallback >%} -{$ clientShimCode(fn, "k"& iface.name & "_service_id", "k" & iface.name & "_" & fn.name & "_id") >} -{% endif -- fn.isCallback >%} +#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC + if (s_{$iface.clientClassName} != nullptr) + { + delete s_{$iface.clientClassName}; + s_{$iface.clientClassName} = nullptr; + } +#else + s_{$iface.clientClassName}.destroy(); +#endif } -{% endfor -- fn %} {% endfor -- iface %} diff --git a/erpcgen/src/templates/c_common_header.template b/erpcgen/src/templates/c_common_header.template index 8c093ba7..2083bbd2 100644 --- a/erpcgen/src/templates/c_common_header.template +++ b/erpcgen/src/templates/c_common_header.template @@ -13,33 +13,38 @@ #endif {% endif -- usedUnionType %} -{% if not commonTypesFile == "" %} -// Common types header file -#include "{$commonTypesFile}" -{% else %} +{% for inc in includes %} +#include "{$inc}" +{% endfor -- includes %} + +{% if cCommonHeaderFile %} +#if defined(__cplusplus) +extern "C" +{ +#endif #include #include #include +{% else %} +#include +#include +#include +{% endif %} + #include "erpc_version.h" {% if empty(crc16) == false %} #include "{$crcHeaderName}" {% endif -- empty(crc16) == false %} -{% for inc in includes %} -#include "{$inc}" -{% endfor -- includes %} {$checkVersion()} {$>checkCrc()} -{% endif -- not commonTypesFile %} -{% if commonTypesFile == "" %} + #if !defined(ERPC_TYPE_DEFINITIONS{$scopeNamePrefix}{$scopeNameC}) #define ERPC_TYPE_DEFINITIONS{$scopeNamePrefix}{$scopeNameC} {% if not empty(enums) %} // Enumerators data types declarations {% for enum in enums %} -{% if enum.name != "" %} -{% endif %} {$> enum.mlComment} {% if enum.name %}typedef {% endif --enum.name %}enum{$addIndent(" ", enum.name)} { @@ -103,38 +108,12 @@ extern const {$c.typeAndName};{$c.ilComment}{$loop.addNewLineIfNotLast} {% endif -- consts %} #endif // ERPC_TYPE_DEFINITIONS{$scopeNamePrefix}{$scopeNameC} -{% endif -- commonTypesFile %} - -{% if not genCommonTypesFile %} -{% for iface in group.interfaces %} -/*! @brief {$iface.name} identifiers */ -enum _{$iface.name}_ids -{ - k{$iface.name}_service_id = {$iface.id}, -{% for fn in iface.functions %} - k{$iface.name}_{$fn.name}_id = {$fn.id}, -{% endfor %} -}; - -{% endfor %} -#if defined(__cplusplus) -extern "C" { -#endif -{% for iface in group.interfaces if iface.isNonExternalInterface == true %} - -{$> iface.mlComment} -//! @name {$iface.name} -//@{ -{% for fn in iface.functions if fn.isNonExternalFunction == true %} -{$> fn.mlComment} -{$fn.prototype};{$fn.ilComment}{$loop.addNewLineIfNotLast} -{% endfor -- functions %} -//@}{$iface.ilComment} -{% endfor -- iface %} +{% if cCommonHeaderFile %} #if defined(__cplusplus) } #endif -{% endif -- genCommonTypesFile %} +{% else %} +{% endif %} #endif // {$commonGuardMacro} diff --git a/erpcgen/src/templates/c_server_header.template b/erpcgen/src/templates/c_server_header.template index 082ea3e9..e2a7afcb 100644 --- a/erpcgen/src/templates/c_server_header.template +++ b/erpcgen/src/templates/c_server_header.template @@ -1,51 +1,63 @@ -{% if mlComment != ""%} +{% if mlComment != "" %} {$mlComment} {% endif %} {$commonHeader()} -#if !defined({$serverGuardMacro}) -#define {$serverGuardMacro} +#if !defined({$serverCGuardMacro}) +#define {$serverCGuardMacro} -#ifdef __cplusplus -#include "erpc_server.hpp" -#include "{$codecHeader}" +#include "{$commonCHeaderName}" +{% for iface in group.interfaces %} +{% for fn in iface.functions %} +{% for externalInterface in fn.externalInterfaces %} +{% for interfaceFile in interfacesFiles %} +{% if externalInterface == interfaceFile.interfaceName %} +#include "c_{$interfaceFile.interfaceCommonFileName}_client.h" +{% endif %} +{% endfor -- interfacesFiles %} +{% endfor -- externalInterface %} +{% endfor -- fn %} +{% endfor -- iface %} + +#if defined(__cplusplus) extern "C" { -#include "{$commonHeaderName}.h" -#include -#include -} +#endif -{$checkVersion()} -{$>checkCrc()} -{% for iface in group.interfaces %} +typedef void * erpc_service_t; -/*! - * @brief Service subclass for {$iface.name}. - */ -class {$iface.serviceClassName} : public erpc::Service -{ -public: - {$iface.serviceClassName}() : Service(k{$iface.name}_service_id) {} +#if !defined({$getFunctionDeclarationMacroName()}) +#define {$getFunctionDeclarationMacroName()} - /*! @brief Call the correct server shim based on method unique ID. */ - virtual erpc_status_t handleInvocation(uint32_t methodId, uint32_t sequence, erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory); +{% for iface in group.interfaces %} +{% for cb in iface.callbacksInt%} +typedef {$cb.typenameName}; +{% endfor %} -private: +/*! @brief {$iface.name} identifiers */ +enum _{$iface.name}_ids +{ + k{$iface.name}_service_id = {$iface.id}, {% for fn in iface.functions %} - /*! @brief Server shim for {$fn.name} of {$iface.name} interface. */ - erpc_status_t {$fn.name}_shim(erpc::{$codecClass} * codec, erpc::MessageBufferFactory *messageFactory, uint32_t sequence);{$loop.addNewLineIfNotLast} -{% endfor -- fn %} + k{$iface.name}_{$fn.name}_id = {$fn.id}, +{% endfor %} }; -{% endfor -- iface %} -extern "C" { -#else -#include "{$commonHeaderName}.h" -#endif // __cplusplus +{% endfor %} +{% for iface in group.interfaces if iface.isNonExternalInterface == true %} +{$> iface.mlComment} +//! @name {$iface.name} +//@{ +{% for fn in iface.functions if fn.isNonExternalFunction == true %} +{$> fn.mlComment} +{$fn.prototype};{$fn.ilComment}{$loop.addNewLineIfNotLast} +{% endfor -- functions %} +//@}{$iface.ilComment} -typedef void * erpc_service_t; +{% endfor -- iface %} + +#endif // {$getFunctionDeclarationMacroName()} {% for iface in group.interfaces %} /*! @brief Return {$iface.serviceClassName} service object. */ @@ -55,8 +67,9 @@ erpc_service_t create_{$iface.serviceClassName}(void); void destroy_{$iface.serviceClassName}(erpc_service_t service); {% endfor -- iface %} -#ifdef __cplusplus + +#if defined(__cplusplus) } -#endif // __cplusplus +#endif -#endif // {$serverGuardMacro} +#endif // {$serverCGuardMacro} diff --git a/erpcgen/src/templates/c_server_source.template b/erpcgen/src/templates/c_server_source.template index bad5bfe9..48d9d5ba 100644 --- a/erpcgen/src/templates/c_server_source.template +++ b/erpcgen/src/templates/c_server_source.template @@ -1,255 +1,88 @@ -{% if mlComment != ""%} +{% if mlComment != "" %} {$mlComment} {% endif %} {$commonHeader()} +{% set source = "server" >%} -#include "{$serverHeaderName}" -#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC #include -#include "erpc_port.h" -#endif +#include "{$serverCHeaderName}" +#include "{$serverCppHeaderName}" #include "erpc_manually_constructed.hpp" -{% if empty(group.includes) == false %} -extern "C" -{ -{% for inc in group.includes %} -#include "{$inc}" -{% endfor -- group.includes %} -} -{% endif -- empty(group.includes) %} +{% set utils = false >%} +{% for iface in group.interfaces %} +{% if (count(iface.callbacksAll) > 0) && (utils == false) %} +#include "erpc_utils.hpp" +{% set utils = true >%} +{% endif %} +{% endfor %} -{$checkVersion()} -{$>checkCrc()} using namespace erpc; using namespace std; - -#if ERPC_NESTED_CALLS_DETECTION -extern bool nestingDetection; -#endif - +{$usingNamespace() >} {% for iface in group.interfaces %} -ERPC_MANUALLY_CONSTRUCTED_STATIC({$iface.serviceClassName}, s_{$iface.serviceClassName}); - -{% endfor -- iface %} -{$generateCrcVariable()} -{$> setSharedMemAddresses()} -{% if unitTest %} -{$> callbackTable(functions)} -{% endif %} -{$> constantsDefinitions(consts)} -{$> symbolHeader(group.symbolsMap.symbolsToServer, "deserial", "def")} -{$> symbolSource(group.symbolsMap.symbolsToServer, "deserial", "def")} -{$> symbolHeader(group.symbolsMap.symbolsToClient, "serial", "def")} -{$> symbolSource(group.symbolsMap.symbolsToClient, "serial", "def")} -{$> symbolFreeSpaceHeader(group.symbolsMap.symbolsServerFree, "def")} -{$> symbolFreeSpaceSource(group.symbolsMap.symbolsServerFree, "def")} -{$> symbolHeader(group.symbolsMap.symbolsToServer, "deserial", "noSharedMem")} -{$> symbolSource(group.symbolsMap.symbolsToServer, "deserial", "noSharedMem")} -{$> symbolHeader(group.symbolsMap.symbolsToClient, "serial", "noSharedMem")} -{$> symbolSource(group.symbolsMap.symbolsToClient, "serial", "noSharedMem")} -{$> symbolFreeSpaceHeader(group.symbolsMap.symbolsServerFree, "noSharedMem")} -{$> symbolFreeSpaceSource(group.symbolsMap.symbolsServerFree, "noSharedMem")} -{% def serverShimCode(fn, serverIDName, functionIDName) ------------------------- serverShimCode(fn, serverIDName, functionIDName) %} -{% set serverIndent = "" >%} -{% if (fn.isReturnValue || fn.isSendValue) && generateErrorChecks %} - erpc_status_t err = kErpcStatus_Success; +{% if count(iface.callbacksAll) > 0 %} -{% endif -- isReturnValue || isSendValue %} -{% for param in fn.parameters %} - {$param.variable}{% if param.isNullParam %} = NULL{% endif %}; -{% if !empty(param.nullVariable) %} - {$param.nullVariable} = NULL; +{% for cb in iface.callbacksAll %} +static const {$cb.name} _{$cb.name}[{$count(cb.callbacks)}] = { {% for c in cb.callbacks %}{$c.name}{% if !loop.last %}, {% endif -- loop.last %}{% endfor -- f.callbacks %} }; +{% endfor %} {% endif %} -{% if !param.shared %} -{% if param.isNullable == false && param.direction != OutDirection %} -{$> addIndent(" ", allocMem(param.mallocServer))} -{% endif -- !param.isNullable && param.direction != OutDirection %} -{% endif -- shared %} -{% endfor -- param %} -{% if fn.needNullVariableOnServer %} - bool isNull; -{% endif -- needNullVariableOnServer %} -{% if fn.needTempVariableServerI32 %} - int32_t _tmp_local_i32; -{% endif %} -{% if fn.returnValue.type.isNotVoid %} - {$fn.returnValue.resultVariable}{% if fn.returnValue.isNullReturnType %} = NULL{% endif %}; -{% endif %} -{% if fn.isReturnValue || fn.isSendValue %} - -{% endif %} - // startReadMessage() was already called before this shim was invoked. - -{% if fn.isSendValue %} -{% for param in fn.parameters if (param.serializedDirection == "" || param.serializedDirection == OutDirection || param.referencedName != "") %} -{% if param.isNullable %} -{$addIndent(" ", f_paramIsNullableDecode(param))} - -{% else -- notNullable %} -{% if param.direction != OutDirection %} -{$addIndent(" ", param.coderCall.decode(param.coderCall))} - -{% endif -- param != OutDirection %} -{% endif -- isNullable %} -{% endfor -- parametersToServer %} -{% endif -- isSendValue %} -{% for param in fn.parametersToClient %} -{% if !param.shared %} -{% if param.isNullable == false && param.direction == OutDirection && empty(param.mallocServer) == false %} -{$> addIndent(" ", allocMem(param.mallocServer))} - -{% endif -- !param.isNullable && param.direction == OutDirection %} -{% endif -- shared %} -{% endfor -- param %} -{% if (fn.isReturnValue || fn.isSendValue) && generateErrorChecks %} -{% set serverIndent = " " >%} - err = codec->getStatus(); - if (err == kErpcStatus_Success) - { -{% endif -- generateErrorChecks %} -{$serverIndent} // Invoke the actual served function. -#if ERPC_NESTED_CALLS_DETECTION -{$serverIndent} nestingDetection = true; -#endif -{% if serverIDName == "serviceID" %} -{% for callbackFunction in callbackType.functions %} -{$serverIndent} {% if loop.first == false %}else {% endif %}if (({$serverIDName} == {$callbackFunction.serviceId}) && ({$functionIDName} == {$callbackFunction.id})) -{$serverIndent} { -{$serverIndent} {$callbackFunction.serverPrototype} -{$serverIndent} } -{% endfor -- callbackFunction in callbackType.functions %} -{% else -- serverIDName == "serviceID" %} -{$serverIndent} {$fn.serverPrototype} -{% endif --serverIDName == "serviceID" %} -#if ERPC_NESTED_CALLS_DETECTION -{$serverIndent} nestingDetection = false; -#endif -{% if fn.isReturnValue %} - -{$serverIndent} // preparing MessageBuffer for serializing data -{$serverIndent} {% if generateErrorChecks %}err = {% endif %}messageFactory->prepareServerBufferForSend(codec->getBuffer()); -{% if generateErrorChecks %} - } - - if (err == kErpcStatus_Success) - { -{% endif -- generateErrorChecks %} -{$serverIndent} // preparing codec for serializing data -{$serverIndent} codec->reset(); - -{$serverIndent} // Build response message. -{$serverIndent} codec->startWriteMessage(message_type_t::kReplyMessage, {$serverIDName}, {$functionIDName}, sequence); -{% for param in fn.parametersToClient if (param.serializedDirection == "" || param.serializedDirection == InDirection || param.referencedName != "") %} - -{% if param.isNullable %} -{$serverIndent} if ({% if source == "server" && empty(param.nullVariable) == false %}_{% endif %}{$param.name} != NULL) -{$serverIndent} { -{$addIndent(serverIndent & " ", param.coderCall.encode(param.coderCall))} -{$serverIndent} } -{% else -- isNullable %} -{$addIndent(serverIndent & " ", param.coderCall.encode(param.coderCall))} -{% endif -- isNullable %} -{% endfor -- parametersToClient %} -{% if fn.returnValue.type.isNotVoid %} - -{% if fn.returnValue.isNullable %} -{$addIndent(serverIndent & " ", f_paramIsNullableEncode(fn.returnValue))} -{% else -- isNullable %} -{$addIndent(serverIndent & " ", fn.returnValue.coderCall.encode(fn.returnValue.coderCall))} -{% endif -- isNullable %} -{% endif -- notVoid %} -{% if generateErrorChecks %} - - err = codec->getStatus(); -{% endif generateErrorChecks %} -{% endif -- isReturnValue %} -{% if (fn.isReturnValue || fn.isSendValue) && generateErrorChecks %} - } - -{% endif -- fn.isReturnValue || fn.isSendValue %} -{% for param in fn.paramsToFree %} -{$> addIndent(" ", param.coderCall.freeingCall(param.coderCall))} -{$> addIndent(" ", param.firstFreeingCall1.firstFreeingCall(param.firstFreeingCall1))} - -{% endfor -- parameters %} -{% if fn.returnValue.type.isNotVoid %} -{% set needFreeingCall = fn.returnValue.coderCall.freeingCall(fn.returnValue.coderCall) %} -{% set needFirstFreeingCall = fn.returnValue.firstFreeingCall1.firstFreeingCall(fn.returnValue.firstFreeingCall1) %} -{% if empty(needFreeingCall) == false || empty(needFirstFreeingCall) == false %} -{$> addIndent(" ", needFreeingCall)} -{$> addIndent(" ", needFirstFreeingCall)} - -{% endif -- !empty(needFreeingCall) || !empty(needFirstFreeingCall) %} -{% endif -- notVoid %} -{% if (fn.isReturnValue || fn.isSendValue) && generateErrorChecks %} - return err; -{% else %} - return codec->getStatus(); -{% endif %} -{% enddef --------------------------------------------------------------------------------- serverShimCode(fn, serverIDName, functionIDName) %} -{% for callbackType in group.callbacks %} - -// Common function for serializing and deserializing callback functions of same type. -static erpc_status_t {$callbackType.name}_shim(uint32_t serviceID, uint32_t functionID, {$codecClass} * codec, MessageBufferFactory *messageFactory, uint32_t sequence); {% endfor %} -{% for callbackType in group.callbacks %} +{% for iface in group.interfaces %} -// Common function for serializing and deserializing callback functions of same type. -static erpc_status_t {$callbackType.name}_shim(uint32_t serviceID, uint32_t functionID, {$codecClass} * codec, MessageBufferFactory *messageFactory, uint32_t sequence) +class {$iface.serverClassName}: public {$iface.interfaceClassName} { -{$ serverShimCode(callbackType, "serviceID", "functionID") >} -} -{% endfor %} -{% for iface in group.interfaces -- service subclass method impl %} + public: + virtual ~{$iface.serverClassName}() {}; -// Call the correct server shim based on method unique ID. -erpc_status_t {$iface.serviceClassName}::handleInvocation(uint32_t methodId, uint32_t sequence, Codec * codec, MessageBufferFactory *messageFactory) -{ - erpc_status_t erpcStatus; -{% if codecClass != "Codec" %} - {$codecClass} *_codec = static_cast<{$codecClass} *>(codec); -{% endif %} - switch (methodId) - { {% for fn in iface.functions %} - case k{$iface.name}_{$fn.name}_id: - { - erpcStatus = {$fn.name}_shim({%if codecClass == "Codec" %}codec{% else %}_codec{% endif %}, messageFactory, sequence); - break; - } -{% endfor -- fn %} - default: + {$fn.prototypeInterface} { - erpcStatus = kErpcStatus_InvalidArgument; - break; +{% if count(fn.callbackParameters) > 0 %} + uint16_t _fnIndex; +{% for cb in fn.callbackParameters%} + ::{$cb.type} _{$cb.name} = NULL; +{% endfor %} +{% endif %} +{% if fn.returnValue.type.isNotVoid %} + {$fn.returnValue.resultVariable}{% if fn.returnValue.isNullReturnType %} = NULL{% endif %}; +{% endif %} +{% if count(fn.callbackParameters) > 0 %} +{% for cb in fn.callbackParameters if cb.in %} + + if ({% if cb.interface != ""%}{$cb.interface}{% else %}{$iface.interfaceClassName}{% endif %}::get_callbackIdx_{$cb.type}(&{$cb.name}, _fnIndex)) + { + _{$cb.name}=::_{$cb.type}[_fnIndex]; + } +{% endfor %} + +{% endif%} + {% if fn.returnValue.type.isNotVoid %}result = {% endif %}::{$fn.name}({% for param in fn.parameters %}{% if !loop.first %}, {% endif %}{$param.pureNameC}{% endfor %}); +{% for cb in fn.callbackParameters if cb.out %} + + if (findIndexOfFunction((arrayOfFunctionPtr_t)::_{$cb.type}, sizeof(::_{$cb.type})/sizeof(::{$cb.type}), (functionPtr_t)_{$cb.name}, _fnIndex)) + { + {% if cb.interface != ""%}{$cb.interface}{% else %}{$iface.interfaceClassName}{% endif %}::get_callbackAddress_{$cb.type}(_fnIndex, {$cb.name}); + } +{% endfor %} +{% if fn.returnValue.type.isNotVoid %} + + return result; +{% endif %} } - } - - return erpcStatus; -} -{% for fn in iface.functions %} - -// Server shim for {$fn.name} of {$iface.name} interface. -erpc_status_t {$iface.serviceClassName}::{$fn.name}_shim({$codecClass} * codec, MessageBufferFactory *messageFactory, uint32_t sequence) -{ -{% if fn.isCallback %} - return {$fn.callbackFName}_shim(k{$iface.name}_service_id, k{$iface.name}_{$fn.name}_id, codec, messageFactory, sequence); -{% else -- fn.isCallback >%} -{$ serverShimCode(fn, "k"& iface.name & "_service_id", "k" & iface.name & "_" & fn.name & "_id") >} -{% endif -- fn.isCallback >%} -} {% endfor -- fn %} -{% endfor -- iface %} -{% for iface in group.interfaces %} +}; + +ERPC_MANUALLY_CONSTRUCTED_STATIC({$iface.serviceClassName}, s_{$iface.serviceClassName}); +ERPC_MANUALLY_CONSTRUCTED_STATIC({$iface.serverClassName}, s_{$iface.serverClassName}); erpc_service_t create_{$iface.serviceClassName}(void) { erpc_service_t service; #if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC - service = new (nothrow) {$iface.serviceClassName}(); + service = new (nothrow) {$iface.serviceClassName}(new (nothrow){$iface.serverClassName}()); #else if (s_{$iface.serviceClassName}.isUsed()) { @@ -257,7 +90,8 @@ erpc_service_t create_{$iface.serviceClassName}(void) } else { - s_{$iface.serviceClassName}.construct(); + s_{$iface.serverClassName}.construct(); + s_{$iface.serviceClassName}.construct(s_{$iface.serverClassName}.get()); service = s_{$iface.serviceClassName}.get(); } #endif @@ -268,12 +102,16 @@ erpc_service_t create_{$iface.serviceClassName}(void) void destroy_{$iface.serviceClassName}(erpc_service_t service) { #if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC - erpc_assert(service != NULL); - delete ({$iface.serviceClassName} *)service; + if (service) + { + delete ({$iface.serverClassName} *)((({$iface.serviceClassName} *)service)->getHandler()); + delete ({$iface.serviceClassName} *)service; + } #else (void)service; erpc_assert(service == s_{$iface.serviceClassName}.get()); s_{$iface.serviceClassName}.destroy(); + s_{$iface.serverClassName}.destroy(); #endif } diff --git a/erpcgen/src/templates/cpp_client_header.template b/erpcgen/src/templates/cpp_client_header.template new file mode 100644 index 00000000..85d166bb --- /dev/null +++ b/erpcgen/src/templates/cpp_client_header.template @@ -0,0 +1,36 @@ +{% if mlComment != "" %} +{$mlComment} + +{% endif %} +{$commonHeader()} + +#if !defined({$clientCppGuardMacro}) +#define {$clientCppGuardMacro} + +#include "{$interfaceCppHeaderName}" + +#include "erpc_client_manager.h" +{$fillNamespaceBegin()>} + +{% for iface in group.interfaces %} +class {$iface.clientClassName}: public {$iface.interfaceClassName} +{ + public: + {$iface.clientClassName}(erpc::ClientManager *manager); + + virtual ~{$iface.clientClassName}(); +{% for fn in iface.functions if fn.isNonExternalFunction == true %} + +{% if fn.mlComment %} + {$fn.mlComment} +{% endif %} + virtual {$fn.prototypeInterface}; +{% endfor -- fn %} + + protected: + erpc::ClientManager *m_clientManager; +}; + +{% endfor -- iface %} +{$fillNamespaceEnd()} +#endif // {$clientCppGuardMacro} diff --git a/erpcgen/src/templates/cpp_client_source.template b/erpcgen/src/templates/cpp_client_source.template new file mode 100644 index 00000000..ddffe9e0 --- /dev/null +++ b/erpcgen/src/templates/cpp_client_source.template @@ -0,0 +1,198 @@ +{% set source = "client" >%} +{% if mlComment != "" %} +{$mlComment} + +{% endif %} +{$commonHeader()} + +#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC +#include "erpc_port.h" +#endif +#include "{$codecHeader}" +#include "{$clientCppHeaderName}" +#include "erpc_manually_constructed.hpp" + +{$checkVersion()} +{$>checkCrc()} +using namespace erpc; +using namespace std; +{$usingNamespace() >} +{$generateCrcVariable()} +{$> setSharedMemAddresses()} +{$> constantsDefinitions(consts)} +{$> symbolHeader(group.symbolsMap.symbolsToServer, "serial", "def")} +{$> symbolSource(group.symbolsMap.symbolsToServer, "serial", "def")} +{$> symbolHeader(group.symbolsMap.symbolsToClient, "deserial", "def")} +{$> symbolSource(group.symbolsMap.symbolsToClient, "deserial", "def")} +{$> symbolHeader(group.symbolsMap.symbolsToServer, "serial", "noSharedMem")} +{$> symbolSource(group.symbolsMap.symbolsToServer, "serial", "noSharedMem")} +{$> symbolHeader(group.symbolsMap.symbolsToClient, "deserial", "noSharedMem")} +{$> symbolSource(group.symbolsMap.symbolsToClient, "deserial", "noSharedMem")} + +{% def clientShimCode(client, fn, serverIDName, functionIDName) ------------------------- clientShimCode(fn, serverIDName, functionIDName) %} +{% set clientIndent = "" >%} +{% if generateErrorChecks %} + erpc_status_t err = kErpcStatus_Success; + +{% endif -- generateErrorChecks %} +{% if fn.isReturnValue %} +{% if fn.needTempVariableClientI32 %} + int32_t _tmp_local_i32; +{% endif %} +{% endif %} +{% if fn.needTempVariableClientU16 %} + uint16_t _tmp_local_u16; +{% endif %} +{% if fn.returnValue.type.isNotVoid %} + {$fn.returnValue.resultVariable}{% if fn.returnValue.isNullReturnType %} = NULL{% endif %}; +{% endif -- isNotVoid %} + +#if ERPC_PRE_POST_ACTION + pre_post_action_cb preCB = {$client}->getPreCB(); + if (preCB) + { + preCB(); + } +#endif + + // Get a new request. +{% if !fn.isReturnValue %} + RequestContext request = {$client}->createRequest(true); +{% else %} + RequestContext request = {$client}->createRequest(false); +{% endif -- isReturnValue %} + + // Encode the request. +{% if codecClass == "Codec" %} + {$codecClass} * codec = request.getCodec(); +{% else %} + {$codecClass} * codec = static_cast<{$codecClass} *>(request.getCodec()); +{% endif %} + +{% if generateAllocErrorChecks %} +{% set clientIndent = " " >%} + if (codec == NULL) + { + err = kErpcStatus_MemoryError; + } + else + { +{% endif -- generateErrorChecks %} +{$clientIndent} codec->startWriteMessage({% if not fn.isReturnValue %}message_type_t::kOnewayMessage{% else %}message_type_t::kInvocationMessage{% endif %}, {$serverIDName}, {$functionIDName}, request.getSequence()); + +{% if fn.isSendValue %} +{% for param in fn.parameters if (param.serializedDirection == "" || param.serializedDirection == OutDirection || param.referencedName != "") %} +{% if param.isNullable %} +{$ addIndent(clientIndent & " ", f_paramIsNullableEncode(param))} + +{% else -- isNullable %} +{% if param.direction != OutDirection %} +{$addIndent(clientIndent & " ", param.coderCall.encode(param.coderCall))} + +{% endif -- param != OutDirection %} +{% endif -- isNullable %} +{% endfor -- fn parameters %} +{% endif -- isSendValue %} +{$clientIndent} // Send message to server +{$clientIndent} // Codec status is checked inside this function. +{$clientIndent} {$client}->performRequest(request); +{% if fn.isReturnValue %} +{% for param in fn.parametersToClient if (param.serializedDirection == "" || param.serializedDirection == InDirection || param.referencedName != "") %} + +{% if param.isNullable %} +{% if ((source == "client") && (param.direction != ReturnDirection) && (empty(param.lengthName) == false)) %} +{% set lengthNameCon = ") && (" & param.lengthName & " != NULL)" >%} +{% else %} +{% set lengthNameCon = "" >%} +{% endif %} +{$clientIndent} if ({% if lengthNameCon != "" %}({% endif %}{$param.nullableName} != NULL{$lengthNameCon}) +{$clientIndent} { +{$addIndent(clientIndent & " ", param.coderCall.decode(param.coderCall))} + } +{% else -- notNullable %} +{$addIndent(clientIndent & " ", param.coderCall.decode(param.coderCall))} +{% endif -- isNullable %} +{% endfor -- fn parametersToClient %} +{% if fn.returnValue.type.isNotVoid %} + +{% if fn.returnValue.isNullable %} +{$clientIndent} bool isNull; +{$addIndent(clientIndent & " ", f_paramIsNullableDecode(fn.returnValue))} +{% else -- isNullable %} +{$> addIndent(clientIndent & " ", allocMem(fn.returnValue.firstAlloc))} +{$addIndent(clientIndent & " ", fn.returnValue.coderCall.decode(fn.returnValue.coderCall))} +{% endif -- isNullable %} +{% endif -- isNotVoid %} +{% endif -- isReturnValue %} +{% if generateErrorChecks %} + +{$clientIndent} err = codec->getStatus(); +{% endif -- generateErrorChecks %} +{% if generateAllocErrorChecks %} + } +{% endif -- generateAllocErrorChecks %} + + // Dispose of the request. + {$client}->releaseRequest(request); +{% if generateErrorChecks %} + + // Invoke error handler callback function + {$client}->callErrorHandler(err, {$functionIDName}); +{% endif -- generateErrorChecks %} + +#if ERPC_PRE_POST_ACTION + pre_post_action_cb postCB = {$client}->getPostCB(); + if (postCB) + { + postCB(); + } +#endif + +{% if generateErrorChecks && fn.returnValue.type.isNotVoid %} +{% if empty(fn.returnValue.errorReturnValue) == false && fn.returnValue.isNullReturnType == false %} + + if (err != kErpcStatus_Success) + { + result = {$fn.returnValue.errorReturnValue}; + } +{% endif %} +{% endif -- generateErrorChecks %} + + return{% if fn.returnValue.type.isNotVoid %} result{% endif -- isNotVoid %}; +{% enddef --------------------------------------------------------------------------------- clientShimCode(fn, serverIDName, functionIDName) %} +{% for iface in group.interfaces %} +{% for cb in iface.callbacksInt if (count(cb.callbacks) > 1) %} + +// Common function for serializing and deserializing callback functions of same type. +static {$cb.callbacksData.prototype}; +{% endfor %} +{% for cb in iface.callbacksInt if (count(cb.callbacks) > 1) %} + +// Common function for serializing and deserializing callback functions of same type. +static {$cb.callbacksData.prototype} +{ +{$ clientShimCode("m_clientManager", cb.callbacksData, "serviceID", "functionID") >} +} +{% endfor %} + +{$iface.clientClassName}::{$iface.clientClassName}(ClientManager *manager) +:m_clientManager(manager) +{ +} + +{$iface.clientClassName}::~{$iface.clientClassName}() +{ +} +{% for fn in iface.functions %} + +// {$iface.name} interface {$fn.name} function client shim. +{$fn.prototypeCpp} +{ +{% if fn.isCallback %} + {% if fn.returnValue.type.isNotVoid %}return {% endif %}{$fn.callbackFName}(m_clientManager, m_serviceId, {$getClassFunctionIdName(fn)}{% for param in fn.parameters %}, {$param.pureName}{% endfor %}); +{% else -- fn.isCallback >%} +{$ clientShimCode("m_clientManager", fn, "m_serviceId", getClassFunctionIdName(fn)) >} +{% endif -- fn.isCallback >%} +} +{% endfor -- fn %} +{% endfor -- iface %} diff --git a/erpcgen/src/templates/c_coders.template b/erpcgen/src/templates/cpp_coders.template similarity index 92% rename from erpcgen/src/templates/c_coders.template rename to erpcgen/src/templates/cpp_coders.template index 4bf37fa7..1dd7dacc 100644 --- a/erpcgen/src/templates/c_coders.template +++ b/erpcgen/src/templates/cpp_coders.template @@ -5,7 +5,7 @@ char * {$info.stringLocalName}_local; codec->readString({$info.stringLocalName}_len, &{$info.stringLocalName}_local); {% if info.stringAllocSize != info.stringLocalName & "_len" %} - if ({$info.stringLocalName}_len <= {$info.stringAllocSize}) + if (({$info.stringAllocSize} >= 0) && ({$info.stringLocalName}_len <= static_cast({$info.stringAllocSize}))) { {% set indent = " " >%} {% else %} @@ -209,9 +209,13 @@ switch ({% if info.dataLiteral != "" %}{$info.dataLiteral}{% endif %}{$info.disc {% def decodeFunctionType(info) %} {% if info.callbacksCount == 1 %} -codec->readCallback((funPtr)({$info.callbacks}), (funPtr *)(&{$info.name})); +{% if param.direction != InDirection %}*{% endif %}{$info.name} = &{% if param.ifaceScope != ""%}{$param.ifaceScope}{% else %}{$iface.name}{% endif %}_interface::{$info.callbacks}; {% else -- info.callbacksCount == 1 %} -codec->readCallback((arrayOfFunPtr)({$info.callbacks}), {$info.callbacksCount}, (funPtr *)(&{$info.name})); +codec->read(_tmp_local_u16); +if (!{% if param.ifaceScope != ""%}{$param.ifaceScope}{% else %}{$iface.name}{% endif %}_interface::get_callbackAddress_{$info.cbTypeName}(_tmp_local_u16, {% if param.direction == InDirection %}&{% endif %}{$info.cbParamOutName})) +{ + codec->updateStatus(kErpcStatus_UnknownCallback); +} {% endif -- info.callbacksCount == 1 %} {% enddef -------------------------- FunctionType %} @@ -257,7 +261,8 @@ codec->readData({$info.name}, {$info.sizeTemp} * sizeof({$info.builtinTypeName}) uint32_t {$info.stringLocalName}_len = strlen((const char*){$info.name}); {% if info.stringAllocSize != info.stringLocalName & "_len" %} - erpc_assert({$info.stringLocalName}_len <= {$info.stringAllocSize}); + erpc_assert({$info.stringAllocSize} >= 0); + erpc_assert({$info.stringLocalName}_len <= static_cast({$info.stringAllocSize})); {% endif %} codec->writeString({$info.stringLocalName}_len, (const char*){$info.name}); @@ -340,9 +345,12 @@ switch ({$info.dataLiteral}{$info.discriminatorName}) {% def encodeFunctionType(info) %} {% if info.callbacksCount == 1 %} -codec->writeCallback((funPtr)({$info.callbacks}), (funPtr)({$info.name})); +/* No need to serialize code for {$info.name} when only one cb exists. */ +// (void){% if param.ifaceScope != ""%}{$param.ifaceScope}{% else %}{$iface.name}{% endif %}_interface::get_callbackIdx_{$info.cbTypeName}(&{$info.name}, _tmp_local_u16); +// codec->write(_tmp_local_u16); {% else -- info.callbacksCount == 1 %} -codec->writeCallback((arrayOfFunPtr)({$info.callbacks}), {$info.callbacksCount}, (funPtr)({$info.name})); +(void){% if param.ifaceScope != ""%}{$param.ifaceScope}{% else %}{$iface.name}{% endif %}_interface::get_callbackIdx_{$info.cbTypeName}(&{$info.name}, _tmp_local_u16); +codec->write(_tmp_local_u16); {% endif -- info.callbacksCount == 1 %} {% enddef -------------------------- FunctionType %} diff --git a/erpcgen/src/templates/c_common_functions.template b/erpcgen/src/templates/cpp_common_functions.template similarity index 95% rename from erpcgen/src/templates/c_common_functions.template rename to erpcgen/src/templates/cpp_common_functions.template index ee3c79fd..5891ab3e 100644 --- a/erpcgen/src/templates/c_common_functions.template +++ b/erpcgen/src/templates/cpp_common_functions.template @@ -36,6 +36,28 @@ extern const uint32_t erpc_generated_crc = {$crc16}; {% endif -- empty(crc16) == false %} {% enddef --checkCrc %} +{# ---------------- namespace ---------------- #} +{% def fillNamespaceBegin() %} +{% if empty(namespace) == false %} + +namespace {$namespace} +{ +{% endif -- empty(crc16) == false %} +{% enddef --checkCrc %} + +{% def fillNamespaceEnd() %} +{% if empty(namespace) == false %} +} // {$namespace} + +{% endif -- empty(crc16) == false %} +{% enddef --checkCrc %} + +{% def usingNamespace() %} +{% if empty(namespace) == false %} +using namespace {$namespace}; +{% endif -- empty(crc16) == false %} +{% enddef --checkCrc %} + {# ---------------- constantsDefinitions ---------------- #} {% def constantsDefinitions(consts) %} {% if not empty(consts) %} @@ -349,17 +371,6 @@ static void free_{$union.name}_union(int32_t discriminator, {$union.name} * data } {% enddef -- unionFreeSpaceSource %} -{# ---------------- callbacksTable ---------------- #} -{% def callbackTable(functionsTypes) %} -{% if functionsTypes %} -{% for f in functionsTypes %} -{% if count(f.callbacks) > 1 %} -static const {$f.name} _{$f.name}[] = { {% for c in f.callbacks %}{$c.name}{% if !loop.last %}, {% endif -- loop.last %}{% endfor -- f.callbacks %} }; -{% endif -- f.callbacks.size() %} -{% endfor -- functionsTypes %} -{% endif -- functionsTypes %} -{% enddef ------------------------------- callbackTable %} - {# ---------------- allocMem ---------------- #} {% def allocMem(info) %} {% if empty(info) == false %} @@ -524,3 +535,11 @@ else {% if source == "server" && !empty(param.nullVariable) %}_{% endif %}{$param.nullableName} = NULL; } {% enddef ------------------------------- f_paramIsNullableDecode %} + +{% def getFunctionDeclarationMacroName() %} +ERPC_FUNCTIONS_DEFINITIONS{% if group.name %}_{% endif %}{$upper(group.name)}{%>%} +{% enddef ------------------------------- getFunctionDeclarationMacroName %} + +{% def getClassFunctionIdName(fn) %} +m_{$fn.name}Id{%>%} +{% enddef ------------------------------- getClassFunctionIdName %} diff --git a/erpcgen/src/templates/cpp_interface_header.template b/erpcgen/src/templates/cpp_interface_header.template new file mode 100644 index 00000000..27c52834 --- /dev/null +++ b/erpcgen/src/templates/cpp_interface_header.template @@ -0,0 +1,60 @@ +{% if mlComment != "" %} +{$mlComment} + +{% endif %} +{$commonHeader()} + +#if !defined({$interfaceCppGuardMacro}) +#define {$interfaceCppGuardMacro} + +#include "{$commonCppHeaderName}" +{% for iface in group.interfaces %} +{% for fn in iface.functions %} +{% for externalInterface in fn.externalInterfaces %} +{% for interfaceFile in interfacesFiles %} +{% if externalInterface == interfaceFile.interfaceName %} +#include "{$interfaceFile.interfaceCommonFileName}_interface.hpp" +{% endif %} +{% endfor -- interfacesFiles %} +{% endfor -- externalInterface %} +{% endfor -- fn %} +{% endfor -- iface %} +{$fillNamespaceBegin()} +{% for iface in group.interfaces %} + +// Abstract base class for {$iface.name} +class {$iface.interfaceClassName} +{ + public: +{%if count(iface.callbacksInt) > 0%} +{% for cb in iface.callbacksInt%} + typedef {$cb.interfaceTypenameName}; +{% endfor %} + +{%endif %} + static const uint8_t m_serviceId = {$iface.id}; +{% for fn in iface.functions %} + static const uint8_t {$getClassFunctionIdName(fn)} = {$fn.id}; +{% endfor -- fn %} + + virtual ~{$iface.interfaceClassName}(void); +{% for fn in iface.functions if fn.isNonExternalFunction == true %} + +{% if fn.mlComment %} + {$fn.mlComment} +{% endif %} + virtual {$fn.prototypeInterface} = 0; +{% endfor -- fn %} +{% for cb in iface.callbacksInt %} + + static bool get_callbackAddress_{$cb.name}(uint16_t index, {$cb.name} *callback); + static bool get_callbackIdx_{$cb.name}(const {$cb.name} *callback, uint16_t &index); +{% endfor %} +private: +{% for cb in iface.callbacksInt %} + static {$cb.name} _{$cb.name}[{$count(cb.callbacks)}]; +{% endfor %} +}; +{% endfor -- iface %} +{$fillNamespaceEnd()} +#endif // {$interfaceCppGuardMacro} diff --git a/erpcgen/src/templates/cpp_interface_source.template b/erpcgen/src/templates/cpp_interface_source.template new file mode 100644 index 00000000..86d37e07 --- /dev/null +++ b/erpcgen/src/templates/cpp_interface_source.template @@ -0,0 +1,57 @@ +{% if mlComment != "" %} +{$mlComment} + +{% endif %} +{$commonHeader()} + +#include "{$interfaceCppHeaderName}" + +{$checkVersion()} +{$>checkCrc()} + +using namespace std; +{$usingNamespace() >} + +{% for iface in group.interfaces -- service subclass method impl %} +{$iface.interfaceClassName}::~{$iface.interfaceClassName}(void) +{ +} +{% for cb in iface.callbacksInt %} +{$iface.interfaceClassName}::{$cb.name} {$iface.interfaceClassName}::_{$cb.name}[{$count(cb.callbacks)}] = { {% for c in cb.callbacks %}&{$iface.interfaceClassName}::{$c.name}{% if !loop.last %}, {% endif -- loop.last %}{% endfor -- f.callbacks %} }; +{% endfor %} +{% for cb in iface.callbacksInt %} + +bool {$iface.interfaceClassName}::get_callbackAddress_{$cb.name}(uint16_t index, {$cb.name} *callback) +{ + bool find; + + if (indexcheckCrc()} +{$fillNamespaceBegin()>} + +{% for iface in group.interfaces %} +/*! + * @brief Service subclass for {$iface.name}. + */ +class {$iface.serviceClassName} : public erpc::Service +{ +public: + {$iface.serviceClassName}({$iface.interfaceClassName} *_{$iface.interfaceClassName}); + + virtual ~{$iface.serviceClassName}(); + + /*! @brief return service interface handler. */ + {$iface.interfaceClassName}* getHandler(void); + + /*! @brief Call the correct server shim based on method unique ID. */ + virtual erpc_status_t handleInvocation(uint32_t methodId, uint32_t sequence, erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory); + +private: + {$iface.interfaceClassName} *m_handler; +{% for fn in iface.functions %} + /*! @brief Server shim for {$fn.name} of {$iface.name} interface. */ + erpc_status_t {$fn.name}_shim(erpc::{$codecClass} * codec, erpc::MessageBufferFactory *messageFactory, uint32_t sequence);{$loop.addNewLineIfNotLast} +{% endfor -- fn %} +}; + +{% endfor -- iface %} +{$fillNamespaceEnd()} +#endif // {$serverCppGuardMacro} diff --git a/erpcgen/src/templates/cpp_server_source.template b/erpcgen/src/templates/cpp_server_source.template new file mode 100644 index 00000000..a7eb79e3 --- /dev/null +++ b/erpcgen/src/templates/cpp_server_source.template @@ -0,0 +1,253 @@ +{% set source = "server" >%} +{% if mlComment != ""%} +{$mlComment} + +{% endif %} +{$commonHeader()} + +#include "{$serverCppHeaderName}" +#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC +#include +#include "erpc_port.h" +#endif +#include "erpc_manually_constructed.hpp" + +{$checkVersion()} +{$>checkCrc()} +using namespace erpc; +using namespace std; +{$usingNamespace() >} + +#if ERPC_NESTED_CALLS_DETECTION +extern bool nestingDetection; +#endif + +{$generateCrcVariable()} +{$> setSharedMemAddresses()} +{$> constantsDefinitions(consts)} +{$> symbolHeader(group.symbolsMap.symbolsToServer, "deserial", "def")} +{$> symbolSource(group.symbolsMap.symbolsToServer, "deserial", "def")} +{$> symbolHeader(group.symbolsMap.symbolsToClient, "serial", "def")} +{$> symbolSource(group.symbolsMap.symbolsToClient, "serial", "def")} +{$> symbolFreeSpaceHeader(group.symbolsMap.symbolsServerFree, "def")} +{$> symbolFreeSpaceSource(group.symbolsMap.symbolsServerFree, "def")} +{$> symbolHeader(group.symbolsMap.symbolsToServer, "deserial", "noSharedMem")} +{$> symbolSource(group.symbolsMap.symbolsToServer, "deserial", "noSharedMem")} +{$> symbolHeader(group.symbolsMap.symbolsToClient, "serial", "noSharedMem")} +{$> symbolSource(group.symbolsMap.symbolsToClient, "serial", "noSharedMem")} +{$> symbolFreeSpaceHeader(group.symbolsMap.symbolsServerFree, "noSharedMem")} +{$> symbolFreeSpaceSource(group.symbolsMap.symbolsServerFree, "noSharedMem")} +{% def serverShimCode(iface, handler, fn, serverIDName, functionIDName) ------------------------- serverShimCode(fn, serverIDName, functionIDName) %} +{% set serverIndent = "" >%} +{% if (fn.isReturnValue || fn.isSendValue) && generateErrorChecks %} + erpc_status_t err = kErpcStatus_Success; + +{% endif -- isReturnValue || isSendValue %} +{% for param in fn.parameters %} + {% if param.isFunction %}{% if param.ifaceScope != ""%}{$param.ifaceScope}{% else %}{$iface.name}{% endif %}_interface::{% endif %}{$param.variable}{% if param.isNullParam %} = NULL{% endif %}; +{% if !empty(param.nullVariable) %} + {$param.nullVariable} = NULL; +{% endif %} +{% if !param.shared %} +{% if param.isNullable == false && param.direction != OutDirection %} +{$> addIndent(" ", allocMem(param.mallocServer))} +{% endif -- !param.isNullable && param.direction != OutDirection %} +{% endif -- shared %} +{% endfor -- param %} +{% if fn.needNullVariableOnServer %} + bool isNull; +{% endif -- needNullVariableOnServer %} +{% if fn.needTempVariableServerI32 %} + int32_t _tmp_local_i32; +{% endif %} +{% if fn.needTempVariableServerU16 %} + uint16_t _tmp_local_u16; +{% endif %} +{% if fn.returnValue.type.isNotVoid %} + {$fn.returnValue.resultVariable}{% if fn.returnValue.isNullReturnType %} = NULL{% endif %}; +{% endif %} +{% if fn.isReturnValue || fn.isSendValue %} + +{% endif %} + // startReadMessage() was already called before this shim was invoked. + +{% if fn.isSendValue %} +{% for param in fn.parameters if (param.serializedDirection == "" || param.serializedDirection == OutDirection || param.referencedName != "") %} +{% if param.isNullable %} +{$addIndent(" ", f_paramIsNullableDecode(param))} + +{% else -- notNullable %} +{% if param.direction != OutDirection %} +{$addIndent(" ", param.coderCall.decode(param.coderCall))} + +{% endif -- param != OutDirection %} +{% endif -- isNullable %} +{% endfor -- parametersToServer %} +{% endif -- isSendValue %} +{% for param in fn.parametersToClient %} +{% if !param.shared %} +{% if param.isNullable == false && param.direction == OutDirection && empty(param.mallocServer) == false %} +{$> addIndent(" ", allocMem(param.mallocServer))} + +{% endif -- !param.isNullable && param.direction == OutDirection %} +{% endif -- shared %} +{% endfor -- param %} +{% if (fn.isReturnValue || fn.isSendValue) && generateErrorChecks %} +{% set serverIndent = " " >%} + err = codec->getStatus(); + if (err == kErpcStatus_Success) + { +{% endif -- generateErrorChecks %} +{$serverIndent} // Invoke the actual served function. +#if ERPC_NESTED_CALLS_DETECTION +{$serverIndent} nestingDetection = true; +#endif +{% if serverIDName == "serviceID" %} +{% for callbackFunction in fn.functions %} +{$serverIndent} {% if loop.first == false %}else {% endif %}if (({$serverIDName} == {$callbackFunction.serviceId}) && ({$functionIDName} == {$callbackFunction.id})) +{$serverIndent} { +{$serverIndent} m_handler->{$callbackFunction.serverPrototype} +{$serverIndent} } +{% endfor -- callbackFunction in callbackType.functions %} +{% else -- serverIDName == "serviceID" %} +{$serverIndent} {$fn.serverPrototype} +{% endif --serverIDName == "serviceID" %} +#if ERPC_NESTED_CALLS_DETECTION +{$serverIndent} nestingDetection = false; +#endif +{% if fn.isReturnValue %} + +{$serverIndent} // preparing MessageBuffer for serializing data +{$serverIndent} {% if generateErrorChecks %}err = {% endif %}messageFactory->prepareServerBufferForSend(codec->getBuffer()); +{% if generateErrorChecks %} + } + + if (err == kErpcStatus_Success) + { +{% endif -- generateErrorChecks %} +{$serverIndent} // preparing codec for serializing data +{$serverIndent} codec->reset(); + +{$serverIndent} // Build response message. +{$serverIndent} codec->startWriteMessage(message_type_t::kReplyMessage, {$serverIDName}, {$functionIDName}, sequence); +{% for param in fn.parametersToClient if (param.serializedDirection == "" || param.serializedDirection == InDirection || param.referencedName != "") %} + +{% if param.isNullable %} +{$serverIndent} if ({% if source == "server" && empty(param.nullVariable) == false %}_{% endif %}{$param.name} != NULL) +{$serverIndent} { +{$addIndent(serverIndent & " ", param.coderCall.encode(param.coderCall))} +{$serverIndent} } +{% else -- isNullable %} +{$addIndent(serverIndent & " ", param.coderCall.encode(param.coderCall))} +{% endif -- isNullable %} +{% endfor -- parametersToClient %} +{% if fn.returnValue.type.isNotVoid %} + +{% if fn.returnValue.isNullable %} +{$addIndent(serverIndent & " ", f_paramIsNullableEncode(fn.returnValue))} +{% else -- isNullable %} +{$addIndent(serverIndent & " ", fn.returnValue.coderCall.encode(fn.returnValue.coderCall))} +{% endif -- isNullable %} +{% endif -- notVoid %} +{% if generateErrorChecks %} + + err = codec->getStatus(); +{% endif generateErrorChecks %} +{% endif -- isReturnValue %} +{% if (fn.isReturnValue || fn.isSendValue) && generateErrorChecks %} + } + +{% endif -- fn.isReturnValue || fn.isSendValue %} +{% for param in fn.paramsToFree %} +{$> addIndent(" ", param.coderCall.freeingCall(param.coderCall))} +{$> addIndent(" ", param.firstFreeingCall1.firstFreeingCall(param.firstFreeingCall1))} + +{% endfor -- parameters %} +{% if fn.returnValue.type.isNotVoid %} +{% set needFreeingCall = fn.returnValue.coderCall.freeingCall(fn.returnValue.coderCall) %} +{% set needFirstFreeingCall = fn.returnValue.firstFreeingCall1.firstFreeingCall(fn.returnValue.firstFreeingCall1) %} +{% if empty(needFreeingCall) == false || empty(needFirstFreeingCall) == false %} +{$> addIndent(" ", needFreeingCall)} +{$> addIndent(" ", needFirstFreeingCall)} + +{% endif -- !empty(needFreeingCall) || !empty(needFirstFreeingCall) %} +{% endif -- notVoid %} +{% if (fn.isReturnValue || fn.isSendValue) && generateErrorChecks %} + return err; +{% else %} + return codec->getStatus(); +{% endif %} +{% enddef --------------------------------------------------------------------------------- serverShimCode(fn, serverIDName, functionIDName) %} +{% for iface in group.interfaces %} +{% for cb in iface.callbacksInt if (count(cb.callbacks) > 1) %} +// Common function for serializing and deserializing callback functions of same type. +static erpc_status_t {$iface.interfaceClassName}_{$cb.name}_shim({$iface.interfaceClassName} *m_handler, uint32_t serviceID, uint32_t functionID, {$codecClass} * codec, MessageBufferFactory *messageFactory, uint32_t sequence); +{% endfor %} +{% endfor %} +{% for iface in group.interfaces %} +{% for cb in iface.callbacksInt if (count(cb.callbacks) > 1) %} + +// Common function for serializing and deserializing callback functions of same type. +static erpc_status_t {$iface.interfaceClassName}_{$cb.name}_shim({$iface.interfaceClassName} *m_handler, uint32_t serviceID, uint32_t functionID, {$codecClass} * codec, MessageBufferFactory *messageFactory, uint32_t sequence) +{ +{$ serverShimCode(iface, "m_handler", cb.callbacksData, "serviceID", "functionID") >} +} +{% endfor %} +{% endfor %} +{% for iface in group.interfaces -- service subclass method impl %} + +{$iface.serviceClassName}::{$iface.serviceClassName}({$iface.interfaceClassName} *_{$iface.interfaceClassName}) + : erpc::Service({$iface.interfaceClassName}::m_serviceId) + , m_handler(_{$iface.interfaceClassName}) +{ +} + +{$iface.serviceClassName}::~{$iface.serviceClassName}() +{ +} + +// return service interface handler. +{$iface.interfaceClassName}* {$iface.serviceClassName}::getHandler(void) +{ + return m_handler; +} + +// Call the correct server shim based on method unique ID. +erpc_status_t {$iface.serviceClassName}::handleInvocation(uint32_t methodId, uint32_t sequence, Codec * codec, MessageBufferFactory *messageFactory) +{ + erpc_status_t erpcStatus; +{% if codecClass != "Codec" %} + {$codecClass} *_codec = static_cast<{$codecClass} *>(codec); +{% endif %} + switch (methodId) + { +{% for fn in iface.functions %} + case {$iface.interfaceClassName}::{$getClassFunctionIdName(fn)}: + { + erpcStatus = {$fn.name}_shim({%if codecClass == "Codec" %}codec{% else %}_codec{% endif %}, messageFactory, sequence); + break; + } + +{% endfor -- fn %} + default: + { + erpcStatus = kErpcStatus_InvalidArgument; + break; + } + } + + return erpcStatus; +} +{% for fn in iface.functions %} + +// Server shim for {$fn.name} of {$iface.name} interface. +erpc_status_t {$iface.serviceClassName}::{$fn.name}_shim({$codecClass} * codec, MessageBufferFactory *messageFactory, uint32_t sequence) +{ +{% if fn.isCallback %} + return {$iface.interfaceClassName}_{$fn.callbackFNameNoGroup}_shim(m_handler, {$iface.interfaceClassName}::m_serviceId, {$iface.interfaceClassName}::{$getClassFunctionIdName(fn)}, codec, messageFactory, sequence); +{% else -- fn.isCallback >%} +{$ serverShimCode(iface, "m_handler", fn, iface.interfaceClassName & "::m_serviceId", iface.interfaceClassName & "::" & getClassFunctionIdName(fn)) >} +{% endif -- fn.isCallback >%} +} +{% endfor -- fn %} +{% endfor -- iface %} diff --git a/erpcgen/src/types/Function.hpp b/erpcgen/src/types/Function.hpp index b72d159e..ad4a3e11 100644 --- a/erpcgen/src/types/Function.hpp +++ b/erpcgen/src/types/Function.hpp @@ -21,6 +21,7 @@ //////////////////////////////////////////////////////////////////////////////// namespace erpcgen { +class Interface; /*! * @brief Function base declaration. @@ -33,15 +34,23 @@ class FunctionBase /*! * @brief Constructor. */ - FunctionBase() + FunctionBase(Interface *interface) : m_parameters("(fn)") , m_returnType(nullptr) , m_isOneway(false) + , m_interface(interface) { } virtual ~FunctionBase(){}; + /*! + * @brief This function returns parent Interface. + * + * @return parent Interface. + */ + Interface *getInterface() const { return m_interface; } + /*! * @brief This function returns function parameters. * @@ -105,9 +114,9 @@ class FunctionBase StructType m_parameters; /*!< Function parameters are saved as structure members. */ StructMember *m_returnType; /*!< Function return data type. */ bool m_isOneway; /*!< If false then communication is bidirectional. */ + Interface *m_interface; /*!< Parent interface. */ }; -class Interface; class FunctionType; /*! * @brief Function declaration. @@ -123,13 +132,12 @@ class Function : public FunctionBase, public Symbol * This function set symbol token to given token. * * @param[in] tok Given token. - * @param[in] m_interface Parent interface. + * @param[in] interface Parent interface. */ Function(const Token &tok, Interface *interface) - : FunctionBase() + : FunctionBase(interface) , Symbol(symbol_type_t::kFunctionSymbol, tok) , m_uniqueId(++s_idCounter) - , m_interface(interface) , m_functionType(nullptr) { } @@ -140,14 +148,13 @@ class Function : public FunctionBase, public Symbol * This function set symbol token to given token, uniqueId and idCounter to given uniqueId. * * @param[in] tok Given token. - * @param[in] m_interface Parent interface. + * @param[in] interface Parent interface. * @param[in] uniqueId Given unique function id. */ Function(const Token &tok, Interface *interface, uint32_t uniqueId) - : FunctionBase() + : FunctionBase(interface) , Symbol(symbol_type_t::kFunctionSymbol, tok) , m_uniqueId(uniqueId) - , m_interface(interface) , m_functionType(nullptr) { s_idCounter = uniqueId; @@ -167,13 +174,6 @@ class Function : public FunctionBase, public Symbol */ void setUniqueId(uint32_t newId) { m_uniqueId = newId; } - /*! - * @brief This function returns parent Interface. - * - * @return parent Interface. - */ - Interface *getInterface() const { return m_interface; } - /*! * @brief This function returns description about the interface function. * @@ -206,10 +206,9 @@ class Function : public FunctionBase, public Symbol protected: uint32_t m_uniqueId; /*!< Function unique id. */ - Interface *m_interface; /*!< Parent interface. */ - FunctionType *m_functionType; /*!< Parent interface. */ + FunctionType *m_functionType; /*!< Function type. */ - static uint32_t s_idCounter; /*!< Function id counter. Each function will increase this. */ + static uint32_t s_idCounter; /*!< Function id counter. Each function will increase this. */ }; } // namespace erpcgen diff --git a/erpcgen/src/types/FunctionType.hpp b/erpcgen/src/types/FunctionType.hpp index 15bc512b..2c944213 100644 --- a/erpcgen/src/types/FunctionType.hpp +++ b/erpcgen/src/types/FunctionType.hpp @@ -39,9 +39,10 @@ class FunctionType : public FunctionBase, public DataType * This function set symbol token to given token. * * @param[in] tok Given token. + * @param[in] m_interface Parent interface. */ - explicit FunctionType(const Token &tok) - : FunctionBase() + FunctionType(const Token &tok, Interface *interface) + : FunctionBase(interface) , DataType(tok, data_type_t::kFunctionType) , m_callbackFuns() { diff --git a/erpcgen/src/types/Group.hpp b/erpcgen/src/types/Group.hpp index bc7ae551..d2cf95a0 100644 --- a/erpcgen/src/types/Group.hpp +++ b/erpcgen/src/types/Group.hpp @@ -41,6 +41,7 @@ class Group explicit Group(const std::string &name) : m_name(name) { + m_template["name"] = name; } /*! diff --git a/erpcgen/src/types/Interface.hpp b/erpcgen/src/types/Interface.hpp index ffc400a1..c4a82a83 100644 --- a/erpcgen/src/types/Interface.hpp +++ b/erpcgen/src/types/Interface.hpp @@ -29,7 +29,8 @@ namespace erpcgen { class Interface : public Symbol { public: - typedef std::vector function_vector_t; /*!< Vector of Interface functions. */ + typedef std::vector function_vector_t; /*!< Vector of Interface functions. */ + typedef std::vector function_types_vector_t; /*!< Vector of Interface function types. */ /*! * @brief Constructor. @@ -55,6 +56,16 @@ class Interface : public Symbol */ void addFunction(Function *func); + /*! + * @brief This function will add function type to the interface. + * + * The function will add function type given by pointer func to the interface members vector m_functionTypes. + * Also this member will be added as symbol to interface symbol scope m_scope. + * + * @param[in] func Function pointer, which is added to interface members vector. + */ + void addFunctionType(FunctionType *func); + /*! * @brief This function return symbol scope. * @@ -67,7 +78,14 @@ class Interface : public Symbol * * @return Interface functions vector. */ - function_vector_t &getFunctions() { return m_functions; } + const function_vector_t &getFunctions() const { return m_functions; } + + /*! + * @brief This function return interface function types vector. + * + * @return Interface function types vector. + */ + const function_types_vector_t &getFunctionTypes() const { return m_functionTypes; } /*! * @brief This function get unique id of interface. @@ -101,11 +119,12 @@ class Interface : public Symbol virtual std::string getDescription() const override; protected: - SymbolScope m_scope; /*!< Scope which interface belongs to. */ - function_vector_t m_functions; /*!< Vector of interface functions. */ - uint32_t m_uniqueId; /*!< Interface unique id. */ + SymbolScope m_scope; /*!< Scope which interface belongs to. */ + function_vector_t m_functions; /*!< Vector of interface functions. */ + function_types_vector_t m_functionTypes; /*!< Vector of interface function types. */ + uint32_t m_uniqueId; /*!< Interface unique id. */ - static uint32_t s_idCounter; /*!< Interface id counter. Each interface will increase this. */ + static uint32_t s_idCounter; /*!< Interface id counter. Each interface will increase this. */ }; } // namespace erpcgen diff --git a/erpcgen/src/types/Type.cpp b/erpcgen/src/types/Type.cpp index 0b89d67e..b218760e 100644 --- a/erpcgen/src/types/Type.cpp +++ b/erpcgen/src/types/Type.cpp @@ -514,6 +514,14 @@ void Interface::addFunction(Function *func) m_functions.push_back(func); } +void Interface::addFunctionType(FunctionType *func) +{ + assert(func); + + m_scope.addSymbol(func); + m_functionTypes.push_back(func); +} + string Interface::getDescription() const { string fns; diff --git a/erpcgen/test/conftest.py b/erpcgen/test/conftest.py index 324dd9bf..759c3157 100644 --- a/erpcgen/test/conftest.py +++ b/erpcgen/test/conftest.py @@ -284,8 +284,8 @@ def _run(cwd, captureOutput, pytestConfig, args, compilerType): # Enable all warnings except for unused functions. defaultArgs = ["-c", "-Wall", "-Werror", "-Wno-unused-function"] defaultArgs += self._args - argsCC = [self._pathCC, "-std=gnu11"] + defaultArgs - argsCXX = [self._pathCXX, "-std=gnu++11"] + defaultArgs + argsCC = [self._pathCC, "-std=gnu17"] + defaultArgs + argsCXX = [self._pathCXX, "-std=gnu++17"] + defaultArgs incl = [] for i in self._includes: @@ -294,15 +294,24 @@ def _run(cwd, captureOutput, pytestConfig, args, compilerType): argsCXX += incl argsCC += incl + hasCSource = False + hasCppSource = False for s in self._sources: if str(s).split(".")[-1] == "cpp": argsCXX.append(str(s)) + hasCppSource = True else: argsCC.append(str(s)) + hasCSource = True - output = [_run(self._cwd, captureOutput, pytestConfig, argsCC, "C")] - output.append(_run(self._cwd, captureOutput, - pytestConfig, argsCXX, "CXX")) + output = [] + + if hasCSource: + output.append(_run(self._cwd, captureOutput, + pytestConfig, argsCC, "C")) + if hasCppSource: + output.append(_run(self._cwd, captureOutput, + pytestConfig, argsCXX, "CXX")) return output @@ -481,29 +490,58 @@ def run(self): pass -class ErpcgenCCompileTest(ErpcgenCompileTest): - # @brief Tests that generated C code will compile successfully. - # - # An objects directory is created under the test case directory. It is used to hold the - # .o files written by the compiler. A .c file with the main() function is also written to - # the objects directory. +class ErpcgenCCppCompileTest(ErpcgenCompileTest): + # @brief Compile with C and CPP main. + def __init__(self, spec: ErpcgenTestSpec, name: str, caseDir: str, outDir: str): + super(ErpcgenCCppCompileTest, self).__init__( + spec, name, caseDir, outDir) + self._caseDir = caseDir + self._out_dir = outDir + + def run(self): + ErpcgenCCompileTest(self._caseDir, self._out_dir).run() + ErpcgenCppCompileTest(self._caseDir, self._out_dir).run() + + +class ErpcgenCCppCompileTestCommon(object): MAIN_CODE = textwrap.dedent(""" int main(void) { return 0; } """) - def __init__(self, spec: ErpcgenTestSpec, name: str, caseDir: str, outDir: str): - super(ErpcgenCCompileTest, self).__init__(spec, name, caseDir, outDir) - self._objs_dir = caseDir.mkdir(OBJECTS_DIR_NAME) - self._compiler = CCompiler(self._objs_dir) + def __init__(self, outDir: str): + self._out_dir = outDir + self._objs_dir = None + self._compiler = None + + def getMainSourceCode(self): + raise ErpcgenTestException( + "Missing implementation for getting main source code") + + def getMainFilename(self): + raise ErpcgenTestException( + "Missing implementation for getting main filename") + + def getObjectsDir(self): + raise ErpcgenTestException( + "Missing implementation for getting objects dir") + + def getCompiler(self): + raise ErpcgenTestException( + "Missing implementation for getting compiler") + def run(self): # TODO run compiler tests on Windows if sys.platform == 'win32': return + self._compiler = self.getCompiler() + + self._objs_dir = self.getObjectsDir() + # Add include directories. self._compiler.add_include(erpc_dir.join("erpc_c", "port")) self._compiler.add_include(erpc_dir.join("erpc_c", "config")) @@ -515,21 +553,70 @@ def run(self): if '.cpp' in file: self._compiler.add_source(self._out_dir.join(file)) - # Add all header includes into main code - headers = ['#include "'+f + - '"' for f in os.listdir(str(self._out_dir)) if '.h' in f] - self.MAIN_CODE = '\n'.join(headers) + self.MAIN_CODE - - # Add both .c and .cpp copies of the main file. - for main_filename in ("main_c.c", "main_cxx.cpp"): - main = self._objs_dir.join(main_filename) - main.write(self.MAIN_CODE) - self._compiler.add_source(main) + mainCode = self.getMainSourceCode() + mainFilename = self.getMainFilename() + main = self._objs_dir.join(mainFilename) + main.write(mainCode) + self._compiler.add_source(main) # Run the compiler. self._compiler.run() +class ErpcgenCCompileTest(ErpcgenCCppCompileTestCommon): + # @brief Tests that generated C code will compile successfully. + # + # An objects directory is created under the test case directory. It is used to hold the + # .o files written by the compiler. A .c file with the main() function is also written to + # the objects directory. + + def __init__(self, caseDir: str, outDir: str): + super(ErpcgenCCompileTest, self).__init__(outDir) + self._objs_dir = caseDir.mkdir(OBJECTS_DIR_NAME + "_c") + self._compiler = CCompiler(self._objs_dir) + + def getMainSourceCode(self): + headers = ['#include "'+f + + '"' for f in os.listdir(str(self._out_dir)) if f[-2:] == '.h'] + return '\n'.join(headers) + self.MAIN_CODE + + def getMainFilename(self): + return "main.c" + + def getObjectsDir(self): + return self._objs_dir + + def getCompiler(self): + return self._compiler + + +class ErpcgenCppCompileTest(ErpcgenCCppCompileTestCommon): + # @brief Tests that generated Cpp code will compile successfully. + # + # An objects directory is created under the test case directory. It is used to hold the + # .o files written by the compiler. A .cpp file with the main() function is also written to + # the objects directory. + + def __init__(self, caseDir: str, outDir: str): + super(ErpcgenCppCompileTest, self).__init__(outDir) + self._objs_dir = caseDir.mkdir(OBJECTS_DIR_NAME + "_cpp") + self._compiler = CCompiler(self._objs_dir) + + def getMainSourceCode(self): + headers = ['#include "'+f + + '"' for f in os.listdir(str(self._out_dir)) if f[-4:] == '.hpp'] + return '\n'.join(headers) + self.MAIN_CODE + + def getMainFilename(self): + return "main.cpp" + + def getObjectsDir(self): + return self._objs_dir + + def getCompiler(self): + return self._compiler + + class ErpcgenPythonCompileTest(ErpcgenCompileTest): # @brief Tests that generated Python code can be successfully compiled. # @@ -572,7 +659,7 @@ class ErpcgenTestCase(object): # Map of language names to compilation test classes. COMPILE_TEST_CLASSES = { - 'c': ErpcgenCCompileTest, + 'c': ErpcgenCCppCompileTest, 'py': ErpcgenPythonCompileTest, } diff --git a/erpcgen/test/test_builtin_types.yml b/erpcgen/test/test_builtin_types.yml index a1abf140..5b53c484 100644 --- a/erpcgen/test/test_builtin_types.yml +++ b/erpcgen/test/test_builtin_types.yml @@ -21,7 +21,7 @@ idl: | interface myintf { {fns[fore]} somefunc({type} i) {fns[after]} } -test.h: +c_test_client.h: - if: not type in ('bool', 'float', 'double') then: - void somefunc({type}_t i); @@ -46,7 +46,7 @@ idl: | interface myintf { somefunc() -> {type} } -test.h: +c_test_client.h: - if: not type in ('bool', 'float', 'double') then: - '{type}_t somefunc(void);' @@ -71,7 +71,7 @@ idl: | struct structwithint { {type} i } -test.h: +test_common.h: - 'struct structwithint {' - if: not type in ('bool', 'float', 'double') then: diff --git a/erpcgen/test/test_comments.yml b/erpcgen/test/test_comments.yml index 0db04396..ea322664 100644 --- a/erpcgen/test/test_comments.yml +++ b/erpcgen/test/test_comments.yml @@ -73,7 +73,7 @@ idl: | sendReceiveStruct(A a) -> A ///< 33 comment; } /*!<30 comment */ -test.h: +test_common.h: - "/*" - not: "!" - "* Comment" @@ -127,6 +127,8 @@ test.h: - //! 10 comment - //!11 comment - //!< 12 comment + +c_test_client.h: - /*! @brief DoxygenComments identifiers */ - //! 28 comment - //!29 comment @@ -136,7 +138,7 @@ test.h: - ///< 33 comment; - - //@} /*!<30 comment */ - - // _test_h_ + - // _c_test_client_h_ test_client.cpp: - "/*" @@ -158,7 +160,7 @@ test_client.cpp: - // DoxygenComments interface sendReceiveList function client shim. - // DoxygenComments interface sendReceiveStruct function client shim. -test_server.h: +test_server.hpp: - "/*" - not: "!" - "* Comment" @@ -173,7 +175,7 @@ test_server.h: - "*/" - /*! @brief Call the correct server shim based on method unique ID. */ - /*! @brief Server shim for sendReceiveList of DoxygenComments interface. */ - - // _test_server_h_ + - // _test_server_hpp_ test_server.cpp: - "/*" diff --git a/erpcgen/test/test_enum.yml b/erpcgen/test/test_enum.yml index a0a294ea..76e6611b 100644 --- a/erpcgen/test/test_enum.yml +++ b/erpcgen/test/test_enum.yml @@ -11,7 +11,7 @@ idl: | B, C } -test.h: +test_common.h: # named enums get a typedef - if: name then: @@ -38,7 +38,7 @@ idl: | B, C } -test.h: +test_common.h: # named enums get a typedef - if: name then: @@ -68,7 +68,7 @@ idl: | B = 30, C = {c_val} } -test.h: +test_common.h: # named enums get a typedef - if: name then: @@ -99,7 +99,7 @@ idl: | enum {name} { A{a_val}{opt_comma} } -test.h: +test_common.h: # named enums get a typedef - if: name then: @@ -123,7 +123,7 @@ idl: | A = 0, B = -1 } -test.h: +test_common.h: # named enums get a typedef - if: name then: @@ -148,7 +148,7 @@ idl: | D= 1*five, E = 2*five, } -test.h: +test_common.h: # named enums get a typedef - A = 0 - B = 5 diff --git a/erpcgen/test/test_error_checks_c.yml b/erpcgen/test/test_error_checks_c.yml index ad1c0d66..28e751bd 100644 --- a/erpcgen/test/test_error_checks_c.yml +++ b/erpcgen/test/test_error_checks_c.yml @@ -25,9 +25,9 @@ test_client.cpp: - if (codec == NULL) - err = kErpcStatus_MemoryError; - codec->startWriteMessage - - g_client->performRequest + - m_clientManager->performRequest - err = codec->getStatus(); - - g_client->callErrorHandler(err, + - m_clientManager->callErrorHandler(err, - if: type[1] != 'NULL' then: - if (err != kErpcStatus_Success) @@ -115,9 +115,9 @@ test_client.cpp: - not: if (result == NULL) - not: codec->updateStatus; - codec->startWriteMessage - - g_client->performRequest + - m_clientManager->performRequest - err = codec->getStatus(); - - g_client->callErrorHandler(err, kErrorTest_f_id) + - m_clientManager->callErrorHandler(err, m_fId) - if: type[1] != 'NULL' then: - if (err != kErpcStatus_Success) @@ -164,9 +164,9 @@ test_client.cpp: - if (codec == NULL) - err = kErpcStatus_MemoryError; - codec->startWriteMessage - - g_client->performRequest + - m_clientManager->performRequest - err = codec->getStatus(); - - g_client->callErrorHandler(err, + - m_clientManager->callErrorHandler(err, - if: type[1] != 'NULL' then: - if (err != kErpcStatus_Success) @@ -214,7 +214,7 @@ test_client.cpp: - if (codec == NULL) - err = kErpcStatus_MemoryError; - codec->startWriteMessage - - g_client->performRequest + - m_clientManager->performRequest - err = codec->getStatus(); test_server.cpp: @@ -261,9 +261,9 @@ test_client.cpp: - not: if (codec == NULL) - not: err = kErpcStatus_MemoryError; - codec->startWriteMessage - - g_client->performRequest + - m_clientManager->performRequest - err = codec->getStatus(); - - g_client->callErrorHandler(err, + - m_clientManager->callErrorHandler(err, test_server.cpp: - erpc_status_t err = kErpcStatus_Success; @@ -312,10 +312,10 @@ test_client.cpp: - err = kErpcStatus_MemoryError; - else - codec->startWriteMessage - - g_client->performRequest(request); + - m_clientManager->performRequest(request); - err = codec->getStatus(); - - g_client->releaseRequest(request); - - g_client->callErrorHandler(err, kErrorTest_f_id); + - m_clientManager->releaseRequest(request); + - m_clientManager->callErrorHandler(err, m_fId); test_server.cpp: - erpc_status_t err = kErpcStatus_Success; diff --git a/erpcgen/test/test_error_return_c.yml b/erpcgen/test/test_error_return_c.yml index 73ba7041..8c2571c3 100644 --- a/erpcgen/test/test_error_return_c.yml +++ b/erpcgen/test/test_error_return_c.yml @@ -28,7 +28,7 @@ idl: | f() -> {type[0]} } test_client.cpp: - - g_client->releaseRequest(request); + - m_clientManager->releaseRequest(request); - if: type[1] != 'NULL' then: - if (err != kErpcStatus_Success) @@ -71,7 +71,7 @@ idl: | f() -> {type[0]} } test_client.cpp: - - g_client->releaseRequest(request); + - m_clientManager->releaseRequest(request); - if: type[0] != 'A' and type[0] != 'string' then: - if (err != kErpcStatus_Success) diff --git a/erpcgen/test/test_expressions.yml b/erpcgen/test/test_expressions.yml index 6b3f5dcf..1d3ee2f6 100644 --- a/erpcgen/test/test_expressions.yml +++ b/erpcgen/test/test_expressions.yml @@ -15,7 +15,7 @@ idl: | const int32 a = 2 const int32 b = a * two + three -1 -test.h: +test_common.h: # named enums get a typedef - if: name then: diff --git a/erpcgen/test/test_extern_c.yml b/erpcgen/test/test_extern_c.yml index 6e778483..0b9d9575 100644 --- a/erpcgen/test/test_extern_c.yml +++ b/erpcgen/test/test_extern_c.yml @@ -2,7 +2,7 @@ name: extern c empty desc: do the extern "C" blocks get produced for empty input idl: "" -test.h: +test_common.h: - | #if defined(__cplusplus) extern "C" { @@ -19,7 +19,7 @@ idl: | interface Foo { foofn() -> void } -test.h: +test_common.h: - | #if defined(__cplusplus) extern "C" { diff --git a/erpcgen/test/test_forward_declaration_c.yml b/erpcgen/test/test_forward_declaration_c.yml index c39f0594..79b01021 100644 --- a/erpcgen/test/test_forward_declaration_c.yml +++ b/erpcgen/test/test_forward_declaration_c.yml @@ -1,42 +1,3 @@ ---- -name: struct before function -desc: forward declaration of structure before function which is using type. -params: - dir: - - "in" - - "out" -idl: - struct forwardStruct; - - oneway forwardCallback_t(forwardStruct s); - - struct forwardStruct - { - forwardCallback_t pCallback; /*!< Pointer to callback function */ - } - - interface foo - { - myFun({dir} forwardCallback_t pCallback1_t) -> void - - forwardCallback_t forwardCallback; - } - -test.h: - - typedef struct forwardStruct forwardStruct; - - typedef void (*forwardCallback_t)(const forwardStruct * s); - - - struct forwardStruct - - "{" - - forwardCallback_t pCallback; - - "};" -test_server.cpp: - - if: dir == 'in' - then: - - not: erpc_free(pCallback1_t); - else: - - erpc_free(pCallback1_t); - --- name: struct before struct desc: forward declaration of structure before structure which is using type. @@ -58,7 +19,7 @@ idl: myFun(in forwardStruct s) -> void } -test.h: +test_common.h: - typedef struct struct2 struct2; - typedef struct forwardStruct forwardStruct; @@ -102,7 +63,7 @@ idl: | { myFun(in forwardUnion u @discriminator(discriminator), unionCases discriminator) -> void } -test.h: +test_common.h: - typedef struct structure structure; - typedef union forwardUnion forwardUnion; diff --git a/erpcgen/test/test_import.yml b/erpcgen/test/test_import.yml index 03c4095c..ab41d3b9 100644 --- a/erpcgen/test/test_import.yml +++ b/erpcgen/test/test_import.yml @@ -4,10 +4,16 @@ desc: C/Py import test is the same. idl: | import "imports/test2.erpc" -test.h: +c_test_client.h: - void hello1(int32_t a); - void hello2(int32_t a); - void hello3(int32_t a); - void hello4(int32_t a); - void hello5(int32_t a); +c_test_server.h: + - void hello1(int32_t a); + - void hello2(int32_t a); + - void hello3(int32_t a); + - void hello4(int32_t a); + - void hello5(int32_t a); diff --git a/erpcgen/test/test_include.yml b/erpcgen/test/test_include.yml index c1d886b4..8bc3ece5 100644 --- a/erpcgen/test/test_include.yml +++ b/erpcgen/test/test_include.yml @@ -21,24 +21,5 @@ idl: | interface foo { bar(in string x) -> void } -test.h: +test_common.h: - '#include "stdio.h"' ---- -name: C include two interfaces -desc: -idl: | - program test; - - @include("stdio.h") - @include("stdio.h") - interface fooA { - barA(in string xA) -> void - } - - @include("stdio.h") - interface fooB { - barB(in string xB) -> void - } -test_server.cpp: - - '#include "stdio.h"' - - not: '#include "stdio.h"' \ No newline at end of file diff --git a/erpcgen/test/test_includes/test_includes_union.h b/erpcgen/test/test_includes/test_includes_union.h index 97cef1a0..01e78bea 100644 --- a/erpcgen/test/test_includes/test_includes_union.h +++ b/erpcgen/test/test_includes/test_includes_union.h @@ -6,10 +6,15 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#ifndef TEST_INCLUDES_UNION +#define TEST_INCLUDES_UNION + +#include typedef union unionType { int32_t x; float y; }unionType; + +#endif diff --git a/erpcgen/test/test_name_c.yml b/erpcgen/test/test_name_c.yml index 0354379c..4d4196bb 100644 --- a/erpcgen/test/test_name_c.yml +++ b/erpcgen/test/test_name_c.yml @@ -31,22 +31,27 @@ idl: | oneway functionName2(S a @name(m)) } -test.h: +test_common.h: - enum EnumName - D - struct StructName StructName - StructName type - struct StructName - int32_t d + +c_test_client.h: - function(const StructName * m) test_client.cpp: - write_StructName_struct - write_StructName_struct - data->d - - void function(const StructName * m) + - void I_client::function(const StructName * m) - write_StructName_struct(codec, m) - - void functionName2(const StructName * m) + - void I_client::functionName2(const StructName * m) + +c_test_server.h: + - function(const StructName * m) test_server.cpp: - read_StructName_struct @@ -58,5 +63,7 @@ test_server.cpp: - function(m); - erpc_free(m); - functionName2(m); + +c_test_server.cpp: + - ERPC_MANUALLY_CONSTRUCTED_STATIC(I_service, s_I_service); - create_I_service - - s_I_service diff --git a/erpcgen/test/test_nullable_c.yml b/erpcgen/test/test_nullable_c.yml index c60c69cc..1ee80060 100644 --- a/erpcgen/test/test_nullable_c.yml +++ b/erpcgen/test/test_nullable_c.yml @@ -11,7 +11,7 @@ idl: | bar({dir} string a @nullable @max_length(8)) -> void } test_client.cpp: - - re: void bar\(\w*\s*char \* a\) + - re: void foo_client::bar\(\w*\s*char \* a\) - if (a == NULL) - codec->writeNullFlag(true) - if: dir in ('in', 'inout') @@ -58,7 +58,7 @@ idl: | bar({dir} ustring a @nullable @max_length(8)) -> void } test_client.cpp: - - re: void bar\(\w*\s*unsigned\s*char\s*\* a\) + - re: void foo_client::bar\(\w*\s*unsigned\s*char\s*\* a\) - if (a == NULL) - codec->writeNullFlag(true) - if: dir in ('in', 'inout') @@ -113,11 +113,12 @@ idl: | interface foo { bar(Vector v @nullable) -> void } -test.h: +test_common.h: - '{type[1]} v[3]' +c_test_client.h: - void bar(const Vector * v); test_client.cpp: - - re: void bar\(const Vector \* v\) + - re: void foo_client::bar\(const Vector \* v\) - if (v == NULL) - writeNullFlag(true) - "{" @@ -152,7 +153,7 @@ test_client.cpp: - writeNullFlag(false) - write_list_bool_1_t_struct - '}' - - void bar(const erpc_pair * s) + - void foo_client::bar(const erpc_pair * s) - write_erpc_pair_struct test_server.cpp: - void read_erpc_pair_struct @@ -182,7 +183,7 @@ test_client.cpp: - writeNullFlag(false) - write_binary_t_struct - '}' - - void bar(const erpc_pair * s) + - void foo_client::bar(const erpc_pair * s) - write_erpc_pair_struct test_server.cpp: - void read_erpc_pair_struct @@ -339,9 +340,9 @@ idl: | test_client.cpp: - if: dir == 'inout' then: - - void bar(const bool * l, uint32_t * c) + - void foo_client::bar(const bool * l, uint32_t * c) else: - - void bar(const bool * l, uint32_t c) + - void foo_client::bar(const bool * l, uint32_t c) - if: dir == 'inout' and ann == '@nullable' then: - if ((l == NULL) || (c == NULL)) @@ -404,7 +405,7 @@ idl: | } test_client.cpp: - - void bar(bool * l, uint32_t * c) + - void foo_client::bar(bool * l, uint32_t * c) - if: ann == '@nullable' then: - if ((l == NULL) || (c == NULL)) diff --git a/erpcgen/test/test_redundant_definitions.yml b/erpcgen/test/test_redundant_definitions.yml index ea947b13..230f77dd 100644 --- a/erpcgen/test/test_redundant_definitions.yml +++ b/erpcgen/test/test_redundant_definitions.yml @@ -40,7 +40,7 @@ idl: | interface foo { bar(in Vector vector_x, out Wector vector_y) -> void } -test.h: +test_common.h: - typedef struct Vector Vector - typedef struct Wector Wector - struct Vector @@ -50,7 +50,7 @@ test_server.cpp: - read_Vector_struct - not: read_Wector_struct - write_Wector_struct -test_client.cpp: +test_client.cpp: - write_Vector_struct - not: read_Vector_struct - read_Wector_struct @@ -124,44 +124,52 @@ idl: | interface fooA { barA(out Vector vector_x, in Wector vector_y) -> void } -test.h: +test_common.h: - typedef struct Vector Vector - typedef struct Wector Wector - typedef struct NoGroup NoGroup; - struct Vector - struct Wector - struct NoGroup +c_test_server.h: - enum _foo_ids - void bar(const NoGroup * noGroup_z) test_server.cpp: - read_NoGroup_struct - not: write_NoGroup_struct - - not: Vector_struct + - not: Vector_struct - not: Wector_struct - foo_service::bar_shim -test_client.cpp: +c_test_client.h: + - enum _foo_ids + - void bar(const NoGroup * noGroup_z) +test_client.cpp: - not: read_NoGroup_struct - write_NoGroup_struct - - not: Vector_struct + - not: Vector_struct - not: Wector_struct - bar(const NoGroup * noGroup_z) -test_A.h: +test_A_common.h: - typedef struct Vector Vector - typedef struct Wector Wector - typedef struct NoGroup NoGroup; - struct Vector - struct Wector - struct NoGroup +c_test_A_server.h: - enum _fooA_ids - void barA(Vector * vector_x, const Wector * vector_y) -test_A_server.cpp: +test_A_server.cpp: - read_Wector_struct - not: write_Wector_struct - write_Vector_struct - not: read_Vector_struct - not: NoGroup_struct - fooA_service::barA_shim -test_A_client.cpp: +c_test_A_client.h: + - enum _fooA_ids + - void barA(Vector * vector_x, const Wector * vector_y) +test_A_client.cpp: - write_Wector_struct - not: read_Wector_struct - read_Vector_struct @@ -200,14 +208,14 @@ idl: | interface foo_B { bar_B(out VectorB b) -> void } -test.h: +test_A_common.h: - typedef struct VectorA VectorA - typedef struct VectorB VectorB - struct VectorA - struct VectorB - not: bar_A(const VectorA * a) - not: bar_AA(const VectorA * aa, VectorB * bb) -test_A.h: +c_test_A_client.h: - not: typedef - bar_A(const VectorA * a) - bar_AA(const VectorA * aa, VectorB * bb) @@ -216,10 +224,10 @@ test_A_server.cpp: - write_VectorB_struct - not: write_VectorA_struct - not: read_VectorB_struct -test_B.h: +c_test_B_client.h: - not: typedef - bar_B(VectorB * b) -test_B_server.cpp: +test_B_server.cpp: - write_VectorB_struct - not: read_VectorB_struct - not: VectorA_struct @@ -235,4 +243,4 @@ test_B_server.cpp: # interface foo { # bar(zz discriminator, Scalar scalar_y @discriminator(discriminator)) -> void -# } \ No newline at end of file +# } diff --git a/erpcgen/test/test_scope_c.yml b/erpcgen/test/test_scope_c.yml index e9775256..b0d20a20 100644 --- a/erpcgen/test/test_scope_c.yml +++ b/erpcgen/test/test_scope_c.yml @@ -5,7 +5,7 @@ idl: | interface test { bar(int32 x) -> void } -test.h: +test_common.h: - | #if !defined(ERPC_TYPE_DEFINITIONS_ERPCSHIM) #define ERPC_TYPE_DEFINITIONS_ERPCSHIM @@ -21,7 +21,7 @@ idl: | interface test { bar(int32 x) -> void } -test.h: +test_common.h: - | #if !defined(ERPC_TYPE_DEFINITIONS_TEST) #define ERPC_TYPE_DEFINITIONS_TEST @@ -38,7 +38,7 @@ idl: | interface test { bar(int32 x) -> void } -test.h: +test_common.h: - | #if !defined(ERPC_TYPE_DEFINITIONS_MYSCOPE) #define ERPC_TYPE_DEFINITIONS_MYSCOPE @@ -55,7 +55,7 @@ idl: | interface test { bar(int32 x) -> void } -test.h: +test_common.h: - | #if !defined(ERPC_TYPE_DEFINITIONS) #define ERPC_TYPE_DEFINITIONS diff --git a/erpcgen/test/test_service_c.yml b/erpcgen/test/test_service_c.yml index 5865cfac..5446b86f 100644 --- a/erpcgen/test/test_service_c.yml +++ b/erpcgen/test/test_service_c.yml @@ -8,17 +8,18 @@ idl: | oneway f() } -test_server.h: +c_test_server.h: - erpc_service_t create_ErrorTest_service(void); - void destroy_ErrorTest_service(erpc_service_t service); -test_server.cpp: +c_test_server.cpp: - ERPC_MANUALLY_CONSTRUCTED_STATIC(ErrorTest_service, s_ErrorTest_service); + - ERPC_MANUALLY_CONSTRUCTED_STATIC(ErrorTest_server, s_ErrorTest_server); - erpc_service_t create_ErrorTest_service(void) - "{" - erpc_service_t service; - "#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC" - - service = new (nothrow) ErrorTest_service(); + - service = new (nothrow) ErrorTest_service(new (nothrow)ErrorTest_server()); - "#else" - if (s_ErrorTest_service.isUsed()) - "{" @@ -26,7 +27,8 @@ test_server.cpp: - "}" - else - "{" - - s_ErrorTest_service.construct(); + - s_ErrorTest_server.construct(); + - s_ErrorTest_service.construct(s_ErrorTest_server.get()); - service = s_ErrorTest_service.get(); - "}" - "#endif" @@ -35,11 +37,15 @@ test_server.cpp: - void destroy_ErrorTest_service(erpc_service_t service) - "{" - "#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC" - - erpc_assert(service != NULL); + - if (service) + - "{" + - delete (ErrorTest_server *)(((ErrorTest_service *)service)->getHandler()); - delete (ErrorTest_service *)service; + - "}" - "#else" - (void)service; - erpc_assert(service == s_ErrorTest_service.get()); - s_ErrorTest_service.destroy(); + - s_ErrorTest_server.destroy(); - "#endif" - "}" diff --git a/erpcgen/test/test_struct.yml b/erpcgen/test/test_struct.yml index afb5f5ce..b376b48f 100644 --- a/erpcgen/test/test_struct.yml +++ b/erpcgen/test/test_struct.yml @@ -20,7 +20,7 @@ idl: | interface B { testF(inout A b) ->void } -test.h: +test_common.h: - typedef struct A A; - struct A - if: type in ('bool', 'float', 'double') @@ -41,7 +41,7 @@ idl: | interface foo { bar(ListType x) -> ListType } -test.h: +test_common.h: - typedef struct list_int32_1_t list_int32_1_t; - typedef list_int32_1_t ListType; - struct list_int32_1_t @@ -52,7 +52,7 @@ test_client.cpp: - read_list_int32_1_t_struct - if(NULL == data) - return; - - ListType * bar(const ListType * x) + - ListType * foo_client::bar(const ListType * x) test_server.cpp: - read_list_int32_1_t_struct - if(NULL == data) @@ -72,7 +72,7 @@ idl: | interface foo { bar(Vector x, binary y) -> void } -test.h: +test_common.h: - typedef struct binary_t binary_t; - typedef struct Vector Vector; - struct binary_t @@ -97,7 +97,7 @@ idl: | foo(Vector a) -> void bar() -> Vector } -test.h: +test_common.h: - typedef struct binary_t binary_t; - typedef struct Vector Vector; - struct binary_t diff --git a/erpcgen/test/test_types_header.yml b/erpcgen/test/test_types_header.yml deleted file mode 100644 index 97b461b9..00000000 --- a/erpcgen/test/test_types_header.yml +++ /dev/null @@ -1,33 +0,0 @@ ---- -name: types header file -desc: places all type definitions into separate header file "test_types.h" -idl: | - @types_header("test_types.h") - program test - - struct Vector { - int8 a - int16 b - int32 c - } - - interface test { - bar(Vector x) -> void - } -test.h: - - '#include "test_types.h"' - - not: // Aliases data types declarations - - not: typedef struct Vector Vector; - - not: // Structures data types declarations - - not: struct Vector - - void bar(const Vector * x); -test_types.h: - - '#if !defined(_test_types_h_)' - - '#include ' - - '#include ' - - '#include ' - - // Aliases data types declarations - - typedef struct Vector Vector; - - // Structures/unions data types declarations - - struct Vector - - not: void bar(const Vector * x); diff --git a/erpcgen/test/test_union_c.yml b/erpcgen/test/test_union_c.yml index 2673fa9f..04b04e78 100644 --- a/erpcgen/test/test_union_c.yml +++ b/erpcgen/test/test_union_c.yml @@ -21,7 +21,7 @@ idl: | myUnion(fruitType discriminator, unionType unionVariable @discriminator(discriminator)) -> void } -test.h: +test_common.h: - not: typedef union unionType unionType; - not: union unionType - not: int32 x; @@ -72,7 +72,7 @@ idl: | myUnion(fruitType discriminator, unionType unionVariable @discriminator(discriminator)) -> void } -test.h: +test_common.h: - typedef union unionType unionType; - union unionType - "{" @@ -95,6 +95,8 @@ test.h: - int32_t blah; - "};" - "};" + +c_test_client.h: - void myUnion(fruitType discriminator, const unionType * unionVariable); test_client.cpp: @@ -146,10 +148,12 @@ test_client.cpp: - break; - "}" - "}" - - void myUnion(fruitType discriminator, const unionType * unionVariable) + - void foo_client::myUnion(fruitType discriminator, const unionType * unionVariable) - not: codec->read(static_cast(discriminator)); - write_unionType_union(codec, static_cast(discriminator), unionVariable) +c_test_server.h: + - void myUnion(fruitType discriminator, const unionType * unionVariable); test_server.cpp: - static void read_unionType_union(erpc::Codec * codec, int32_t & discriminator, unionType * data); @@ -268,15 +272,20 @@ idl: | myUnion(structType structVariable) -> void } -test.h: +test_common.h: - struct structType - fruitType discriminator - unionType unionVariable + +c_test_client.h: - void myUnion(const structType * structVariable); test_client.cpp: - write_unionType_union(codec, static_cast(data->discriminator), &data->unionVariable); +c_test_server.h: + - void myUnion(const structType * structVariable); + test_server.cpp: - int32_t _tmp_local_i32; - read_unionType_union(codec, _tmp_local_i32, &data->unionVariable); diff --git a/erpcsniffer/src/Sniffer.cpp b/erpcsniffer/src/Sniffer.cpp index 16e25c8f..b517280c 100644 --- a/erpcsniffer/src/Sniffer.cpp +++ b/erpcsniffer/src/Sniffer.cpp @@ -667,7 +667,7 @@ string Sniffer::getDataTypeName(DataType *dataType) } } -string Sniffer::getPrototype(erpcgen::Function *function) +string Sniffer::getPrototype(Function *function) { string prototype = getDataTypeName(function->getReturnType()); if (function->isOneway()) diff --git a/erpcsniffer/src/erpcsniffer.cpp b/erpcsniffer/src/erpcsniffer.cpp index 361080d8..342e6a12 100644 --- a/erpcsniffer/src/erpcsniffer.cpp +++ b/erpcsniffer/src/erpcsniffer.cpp @@ -118,11 +118,11 @@ class erpcsnifferTool const char *m_outputFilePath; /*!< Path to the output file. */ const char *m_ErpcFile; /*!< ERPC file. */ string_vector_t m_positionalArgs; - transports_t m_transport; /*!< Transport used for receiving messages. */ - uint64_t m_quantity; /*!< Quantity of logs to store. */ - uint32_t m_baudrate; /*!< Baudrate rate speed. */ - const char *m_port; /*!< Name or number of port. Based on used transport. */ - const char *m_host; /*!< Host name */ + transports_t m_transport; /*!< Transport used for receiving messages. */ + uint64_t m_quantity; /*!< Quantity of logs to store. */ + uint32_t m_baudrate; /*!< Baudrate rate speed. */ + const char *m_port; /*!< Name or number of port. Based on used transport. */ + const char *m_host; /*!< Host name */ public: /*! @@ -225,7 +225,7 @@ class erpcsnifferTool } else { - Log::error(format_string("error: unknown transport type %s", transport.c_str()).c_str()); + Log::error("error: unknown transport type %s", transport.c_str()); return 1; } break; diff --git a/run_tests.sh b/run_tests.sh index a98162bd..a523782c 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -7,10 +7,11 @@ make clean if [ "$1" = "clang" ]; then echo "Compiling by clang compiler." CC=clang CXX=clang++ make all + python3 test/run_unit_tests.py clang else echo "Compiling by default gnu compiler." CC=gcc CXX=g++ make all + python3 test/run_unit_tests.py gcc fi pytest erpcgen/test/ -python3 test/run_unit_tests.py diff --git a/test/common/gtestListener.hpp b/test/common/gtestListener.hpp index 8ceed314..1c64134f 100644 --- a/test/common/gtestListener.hpp +++ b/test/common/gtestListener.hpp @@ -10,9 +10,9 @@ #ifndef _EMBEDDED_RPC__GTESTLISTENER_H_ #define _EMBEDDED_RPC__GTESTLISTENER_H_ +#include "c_test_unit_test_common_client.h" #include "gtest.h" #include "myAlloc.hpp" -#include "test_unit_test_common.h" //////////////////////////////////////////////////////////////////////////////// // Classes @@ -26,10 +26,10 @@ class LeakChecker : public ::testing::EmptyTestEventListener { int serverAlloc = getServerAllocated(); - EXPECT_EQ(MyAlloc::allocated(), 0) - << "Leaked (on client side) : " << MyAlloc::allocated() << " unit(s) need be freed!"; + EXPECT_EQ(::MyAlloc::allocated(), 0) + << "Leaked (on client side) : " << ::MyAlloc::allocated() << " unit(s) need be freed!"; EXPECT_EQ(serverAlloc, 0) << "Leaked (on server side) : " << serverAlloc << " unit(s) need be freed!"; - MyAlloc::allocated(0); + ::MyAlloc::allocated(0); } }; diff --git a/test/common/myAlloc.hpp b/test/common/myAlloc.hpp index ad30476d..b2d11bdc 100644 --- a/test/common/myAlloc.hpp +++ b/test/common/myAlloc.hpp @@ -10,6 +10,8 @@ #ifndef _EMBEDDED_RPC__MYALLOC_H_ #define _EMBEDDED_RPC__MYALLOC_H_ +#if defined(__cplusplus) + #include "erpc_port.h" //////////////////////////////////////////////////////////////////////////////// @@ -38,15 +40,13 @@ class MyAlloc static int allocated_; }; -namespace std { -using ::MyAlloc; -} - //////////////////////////////////////////////////////////////////////////////// // Definitions //////////////////////////////////////////////////////////////////////////////// -#define erpc_malloc(X) MyAlloc::my_malloc(X) -#define erpc_free(X) MyAlloc::my_free((X)) +#define erpc_malloc(X) ::MyAlloc::my_malloc(X) +#define erpc_free(X) ::MyAlloc::my_free((X)) + +#endif // __cplusplus #endif // _EMBEDDED_RPC__MYALLOC_H_ diff --git a/test/common/unit_test_arbitrator_app0.cpp b/test/common/unit_test_arbitrator_app0.cpp index a15b6ad5..ee20aa6e 100644 --- a/test/common/unit_test_arbitrator_app0.cpp +++ b/test/common/unit_test_arbitrator_app0.cpp @@ -12,11 +12,12 @@ #include "erpc_transport_setup.h" #include "FreeRTOS.h" -#include "gtest.h" #include "semphr.h" #include "task.h" -#include "test_firstInterface.h" -#include "test_secondInterface_server.h" + +#include "c_test_firstInterface_client.h" +#include "c_test_secondInterface_server.h" +#include "gtest.h" #include "unit_test.h" #ifdef __cplusplus @@ -237,8 +238,8 @@ int main(void) { int fake_argc = 1; const auto fake_arg0 = "dummy"; - char* fake_argv0 = const_cast(fake_arg0); - char** fake_argv = &fake_argv0; + char *fake_argv0 = const_cast(fake_arg0); + char **fake_argv = &fake_argv0; ::testing::InitGoogleTest(&fake_argc, fake_argv); BOARD_InitHardware(); @@ -271,6 +272,7 @@ int main(void) } } +extern "C" { void quitSecondInterfaceServer() { /* removing the service from the server */ @@ -281,3 +283,4 @@ void quitSecondInterfaceServer() erpc_server_stop(server); increaseWaitQuit(); } +} diff --git a/test/common/unit_test_arbitrator_app1.cpp b/test/common/unit_test_arbitrator_app1.cpp index 5d81c78b..24720b7d 100644 --- a/test/common/unit_test_arbitrator_app1.cpp +++ b/test/common/unit_test_arbitrator_app1.cpp @@ -14,8 +14,9 @@ #include "FreeRTOS.h" #include "semphr.h" #include "task.h" -#include "test_firstInterface_server.h" -#include "test_secondInterface.h" + +#include "c_test_firstInterface_server.h" +#include "c_test_secondInterface_client.h" #include "unit_test.h" #ifdef __cplusplus @@ -206,6 +207,7 @@ int main(void) } } +extern "C" { void stopSecondSide() { ++stopTest; @@ -252,3 +254,4 @@ int testClient() } return 0; } +} diff --git a/test/common/unit_test_client.cpp b/test/common/unit_test_client.cpp index 09830b11..e685f6cc 100644 --- a/test/common/unit_test_client.cpp +++ b/test/common/unit_test_client.cpp @@ -26,10 +26,12 @@ int main(void); } #include "board.h" + +#include "c_test_unit_test_common_client.h" #include "gtest.h" #include "gtestListener.hpp" #include "myAlloc.hpp" -#include "test_unit_test_common.h" +#include "unit_test_wrapped.h" #ifdef UNITY_DUMP_RESULTS #include "corn_g_test.h" @@ -83,7 +85,7 @@ class MinimalistPrinter : public ::testing::EmptyTestEventListener // Definitions //////////////////////////////////////////////////////////////////////////////// -int MyAlloc::allocated_ = 0; +int ::MyAlloc::allocated_ = 0; #if defined(RPMSG) #define APP_ERPC_READY_EVENT_DATA (1) @@ -111,8 +113,8 @@ int main(void) { int fake_argc = 1; const auto fake_arg0 = "dummy"; - char* fake_argv0 = const_cast(fake_arg0); - char** fake_argv = &fake_argv0; + char *fake_argv0 = const_cast(fake_arg0); + char **fake_argv = &fake_argv0; ::testing::InitGoogleTest(&fake_argc, fake_argv); ::testing::TestEventListeners &listeners = ::testing::UnitTest::GetInstance()->listeners(); @@ -191,6 +193,8 @@ int main(void) #endif client = erpc_client_init(transport, message_buffer_factory); + initInterfaces_common(client); + initInterfaces(client); int i = RUN_ALL_TESTS(); quit(); @@ -204,3 +208,8 @@ int main(void) return i; } + +void initInterfaces_common(erpc_client_t client) +{ + initCommon_client(client); +} diff --git a/test/common/unit_test_serial_client.cpp b/test/common/unit_test_serial_client.cpp index 38c37c35..57b31d96 100644 --- a/test/common/unit_test_serial_client.cpp +++ b/test/common/unit_test_serial_client.cpp @@ -11,10 +11,11 @@ #include "erpc_serial_transport.hpp" #include "Logging.hpp" +#include "c_test_unit_test_common_client.h" #include "gtest.h" #include "gtestListener.hpp" #include "myAlloc.hpp" -#include "test_unit_test_common.h" +#include "unit_test_wrapped.h" using namespace erpc; @@ -42,7 +43,7 @@ MyMessageBufferFactory g_msgFactory; BasicCodecFactory g_basicCodecFactory; ClientManager *g_client; -int MyAlloc::allocated_ = 0; +int ::MyAlloc::allocated_ = 0; //////////////////////////////////////////////////////////////////////////////// // Set up global fixture @@ -69,6 +70,9 @@ int main(int argc, char **argv) g_client->setMessageBufferFactory(&g_msgFactory); g_client->setTransport(&g_transport); g_client->setCodecFactory(&g_basicCodecFactory); + erpc_client_t client = reinterpret_cast(g_client); + initInterfaces_common(client); + initInterfaces(client); int ret = RUN_ALL_TESTS(); quit(); @@ -78,6 +82,11 @@ int main(int argc, char **argv) return ret; } +void initInterfaces_common(erpc_client_t client) +{ + initCommon_client(client); +} + //////////////////////////////////////////////////////////////////////////////// // EOF //////////////////////////////////////////////////////////////////////////////// diff --git a/test/common/unit_test_serial_server.cpp b/test/common/unit_test_serial_server.cpp index 0dc4f61e..b6969c32 100644 --- a/test/common/unit_test_serial_server.cpp +++ b/test/common/unit_test_serial_server.cpp @@ -11,13 +11,15 @@ #include "erpc_simple_server.hpp" #include "Logging.hpp" +#include "c_test_unit_test_common_server.h" #include "myAlloc.hpp" -#include "test_unit_test_common_server.h" +#include "test_unit_test_common_server.hpp" #include "unit_test.h" #include using namespace erpc; +using namespace erpcShim; class MyMessageBufferFactory : public MessageBufferFactory { @@ -43,7 +45,7 @@ MyMessageBufferFactory g_msgFactory; BasicCodecFactory g_basicCodecFactory; SimpleServer g_server; -int MyAlloc::allocated_ = 0; +int ::MyAlloc::allocated_ = 0; Common_service *svc_common; @@ -78,12 +80,43 @@ int main(int argc, const char *argv[]) return 0; } +//////////////////////////////////////////////////////////////////////////////// +// Common service implementations here +//////////////////////////////////////////////////////////////////////////////// +void quit() +{ + remove_common_service(&g_server); + remove_services(&g_server); + exit(0); +} + +int32_t getServerAllocated() +{ + int result = ::MyAlloc::allocated(); + ::MyAlloc::allocated(0); + return result; +} + +class Common_server : public Common_interface +{ +public: + void quit(void) { ::quit(); } + + int32_t getServerAllocated(void) + { + int32_t result; + result = ::getServerAllocated(); + + return result; + } +}; + //////////////////////////////////////////////////////////////////////////////// // Server helper functions //////////////////////////////////////////////////////////////////////////////// void add_common_service(SimpleServer *server) { - svc_common = new Common_service(); + svc_common = new Common_service(new Common_server()); server->addService(svc_common); } @@ -91,28 +124,13 @@ void add_common_service(SimpleServer *server) void remove_common_service(SimpleServer *server) { server->removeService(svc_common); + delete svc_common->getHandler(); delete svc_common; } extern "C" void erpc_add_service_to_server(void *service) {} extern "C" void erpc_remove_service_from_server(void *service) {} -//////////////////////////////////////////////////////////////////////////////// -// Common service implementations here -//////////////////////////////////////////////////////////////////////////////// -void quit() -{ - remove_common_service(&g_server); - remove_services(&g_server); - exit(0); -} - -int32_t getServerAllocated() -{ - int result = MyAlloc::allocated(); - MyAlloc::allocated(0); - return result; -} //////////////////////////////////////////////////////////////////////////////// // EOF //////////////////////////////////////////////////////////////////////////////// diff --git a/test/common/unit_test_server.cpp b/test/common/unit_test_server.cpp index c10dda3a..7c54afa8 100644 --- a/test/common/unit_test_server.cpp +++ b/test/common/unit_test_server.cpp @@ -15,6 +15,7 @@ extern "C" { #if defined(UART) #include "fsl_lpuart_cmsis.h" + #include "app_core0.h" #else #if defined(RPMSG) @@ -22,6 +23,7 @@ extern "C" { #endif #define APP_ERPC_READY_EVENT_DATA (1) #include "mcmgr.h" + #include "app_core1.h" #endif #if defined(__CC_ARM) || defined(__ARMCC_VERSION) @@ -31,15 +33,16 @@ int main(void); #endif #include "board.h" + +#include "c_test_unit_test_common_server.h" #include "myAlloc.hpp" -#include "test_unit_test_common_server.h" #include "unit_test_wrapped.h" //////////////////////////////////////////////////////////////////////////////// // Variables //////////////////////////////////////////////////////////////////////////////// -int MyAlloc::allocated_ = 0; +int ::MyAlloc::allocated_ = 0; erpc_service_t service_common = NULL; erpc_server_t server; @@ -117,6 +120,12 @@ void add_common_service(erpc_server_t server) erpc_add_service_to_server(server, service_common); } +void remove_common_services_from_server(erpc_server_t server, erpc_service_t service) +{ + erpc_remove_service_from_server(server, service); + destroy_Common_service(service); +} + //////////////////////////////////////////////////////////////////////////////// // Common service implementations here //////////////////////////////////////////////////////////////////////////////// @@ -134,7 +143,7 @@ void quit() int32_t getServerAllocated() { - int result = MyAlloc::allocated(); - MyAlloc::allocated(0); + int result = ::MyAlloc::allocated(); + ::MyAlloc::allocated(0); return result; } diff --git a/test/common/unit_test_tcp_arbitrator_client.cpp b/test/common/unit_test_tcp_arbitrator_client.cpp index 0c1330a1..f29664d3 100644 --- a/test/common/unit_test_tcp_arbitrator_client.cpp +++ b/test/common/unit_test_tcp_arbitrator_client.cpp @@ -13,13 +13,14 @@ #include "erpc_transport_arbitrator.hpp" #include "Logging.hpp" +#include "c_test_firstInterface_client.h" +#include "c_test_unit_test_common_client.h" #include "gtest.h" -#include "test_firstInterface.h" -#include "test_secondInterface.h" #include "unit_test.h" +#include "unit_test_wrapped.h" + #include #include - #include using namespace erpc; @@ -154,6 +155,8 @@ int main(int argc, char **argv) add_services(&g_server); g_client->setServer(&g_server); + erpc_client_t client = reinterpret_cast(g_client); + initInterfaces(client); int i = -1; err = (erpc_status_t)-1; @@ -190,6 +193,7 @@ int main(int argc, char **argv) return i; } +extern "C" { void quitSecondInterfaceServer() { // removing SecondInterface service from the server @@ -198,3 +202,4 @@ void quitSecondInterfaceServer() g_server.stop(); increaseWaitQuit(); } +} diff --git a/test/common/unit_test_tcp_arbitrator_server.cpp b/test/common/unit_test_tcp_arbitrator_server.cpp index d196b0b4..b1956165 100644 --- a/test/common/unit_test_tcp_arbitrator_server.cpp +++ b/test/common/unit_test_tcp_arbitrator_server.cpp @@ -13,10 +13,10 @@ #include "erpc_transport_arbitrator.hpp" #include "Logging.hpp" +#include "c_test_secondInterface_server.h" #include "myAlloc.hpp" -#include "test_firstInterface.h" -#include "test_secondInterface.h" #include "unit_test.h" +#include "unit_test_wrapped.h" #include @@ -146,6 +146,8 @@ int main(int argc, char **argv) g_server.setMessageBufferFactory(&g_msgFactory); add_services(&g_server); g_client->setServer(&g_server); + erpc_client_t client = reinterpret_cast(g_client); + initInterfaces(client); err = (erpc_status_t)-1; @@ -181,6 +183,7 @@ int main(int argc, char **argv) return isTestPassing; } +extern "C" { void stopSecondSide() { ++stopTest; @@ -208,6 +211,7 @@ void whenReady() { waitClient++; } +} int testClient() { diff --git a/test/common/unit_test_tcp_client.cpp b/test/common/unit_test_tcp_client.cpp index 0dca069c..403873b4 100644 --- a/test/common/unit_test_tcp_client.cpp +++ b/test/common/unit_test_tcp_client.cpp @@ -11,10 +11,11 @@ #include "erpc_tcp_transport.hpp" #include "Logging.hpp" +#include "c_test_unit_test_common_client.h" #include "gtest.h" #include "gtestListener.hpp" #include "myAlloc.hpp" -#include "test_unit_test_common.h" +#include "unit_test_wrapped.h" using namespace erpc; @@ -47,7 +48,7 @@ ClientManager *g_client; Crc16 g_crc16; -int MyAlloc::allocated_ = 0; +int ::MyAlloc::allocated_ = 0; //////////////////////////////////////////////////////////////////////////////// // Set up global fixture @@ -90,6 +91,9 @@ int main(int argc, char **argv) #if USE_MESSAGE_LOGGING g_client->addMessageLogger(&g_messageLogger); #endif // USE_MESSAGE_LOGGING + erpc_client_t client = reinterpret_cast(g_client); + initInterfaces_common(client); + initInterfaces(client); int ret = RUN_ALL_TESTS(); quit(); @@ -100,6 +104,11 @@ int main(int argc, char **argv) return ret; } +void initInterfaces_common(erpc_client_t client) +{ + initCommon_client(client); +} + //////////////////////////////////////////////////////////////////////////////// // EOF //////////////////////////////////////////////////////////////////////////////// diff --git a/test/common/unit_test_tcp_server.cpp b/test/common/unit_test_tcp_server.cpp index d689d380..fb732ee6 100644 --- a/test/common/unit_test_tcp_server.cpp +++ b/test/common/unit_test_tcp_server.cpp @@ -11,11 +11,13 @@ #include "erpc_tcp_transport.hpp" #include "Logging.hpp" +#include "c_test_unit_test_common_server.h" #include "myAlloc.hpp" -#include "test_unit_test_common_server.h" +#include "test_unit_test_common_server.hpp" #include "unit_test.h" using namespace erpc; +using namespace erpcShim; class MyMessageBufferFactory : public MessageBufferFactory { @@ -43,7 +45,7 @@ SimpleServer g_server; Crc16 g_crc16; -int MyAlloc::allocated_ = 0; +int ::MyAlloc::allocated_ = 0; Common_service *svc_common; @@ -87,12 +89,43 @@ int main(int argc, const char *argv[]) return 0; } +//////////////////////////////////////////////////////////////////////////////// +// Common service implementations here +//////////////////////////////////////////////////////////////////////////////// +void quit() +{ + remove_common_service(&g_server); + remove_services(&g_server); + g_server.stop(); +} + +int32_t getServerAllocated() +{ + int result = ::MyAlloc::allocated(); + ::MyAlloc::allocated(0); + return result; +} + +class Common_server : public Common_interface +{ +public: + void quit(void) { ::quit(); } + + int32_t getServerAllocated(void) + { + int32_t result; + result = ::getServerAllocated(); + + return result; + } +}; + //////////////////////////////////////////////////////////////////////////////// // Server helper functions //////////////////////////////////////////////////////////////////////////////// void add_common_service(SimpleServer *server) { - svc_common = new Common_service(); + svc_common = new Common_service(new Common_server()); server->addService(svc_common); } @@ -100,28 +133,13 @@ void add_common_service(SimpleServer *server) void remove_common_service(SimpleServer *server) { server->removeService(svc_common); + delete svc_common->getHandler(); delete svc_common; } extern "C" void erpc_add_service_to_server(void *service) {} extern "C" void erpc_remove_service_from_server(void *service) {} -//////////////////////////////////////////////////////////////////////////////// -// Common service implementations here -//////////////////////////////////////////////////////////////////////////////// -void quit() -{ - remove_common_service(&g_server); - remove_services(&g_server); - g_server.stop(); -} - -int32_t getServerAllocated() -{ - int result = MyAlloc::allocated(); - MyAlloc::allocated(0); - return result; -} //////////////////////////////////////////////////////////////////////////////// // EOF //////////////////////////////////////////////////////////////////////////////// diff --git a/test/common/unit_test_wrapped.h b/test/common/unit_test_wrapped.h index 72c386ce..21f38dbf 100644 --- a/test/common/unit_test_wrapped.h +++ b/test/common/unit_test_wrapped.h @@ -9,13 +9,20 @@ #ifndef _EMBEDDED_RPC__UNIT_TEST_WRAPPED_H_ #define _EMBEDDED_RPC__UNIT_TEST_WRAPPED_H_ +#include "erpc_client_manager.h" +#include "erpc_server_setup.h" + //////////////////////////////////////////////////////////////////////////////// // Function Prototypes //////////////////////////////////////////////////////////////////////////////// +typedef void *erpc_service_t; #ifdef __cplusplus extern "C" { #endif +void initInterfaces(erpc_client_t client); +void initInterfaces_common(erpc_client_t client); + void add_services_to_server(erpc_server_t server); void remove_services_from_server(erpc_server_t server); void remove_common_services_from_server(erpc_server_t server, erpc_service_t service); diff --git a/test/mk/erpc_src.mk b/test/mk/erpc_src.mk index ace22ad9..fbaa7788 100644 --- a/test/mk/erpc_src.mk +++ b/test/mk/erpc_src.mk @@ -44,6 +44,7 @@ SOURCES += $(UT_COMMON_SRC)/addOne.cpp \ $(ERPC_C_ROOT)/infra/erpc_message_buffer.cpp \ $(ERPC_C_ROOT)/infra/erpc_message_loggers.cpp \ $(ERPC_C_ROOT)/infra/erpc_transport_arbitrator.cpp \ + $(ERPC_C_ROOT)/infra/erpc_utils.cpp \ $(ERPC_C_ROOT)/port/erpc_port_stdlib.cpp \ $(ERPC_C_ROOT)/port/erpc_threading_pthreads.cpp \ $(ERPC_C_ROOT)/transports/erpc_tcp_transport.cpp diff --git a/test/mk/test.mk b/test/mk/test.mk index 8853482b..028524db 100644 --- a/test/mk/test.mk +++ b/test/mk/test.mk @@ -45,7 +45,7 @@ UNIT_OUT_DIR = $(OUTPUT_ROOT)/$(DEBUG_OR_RELEASE)/$(os_name)/test/ ERPC_NAME ?= test ERPC_NAME_APP ?= $(ERPC_NAME) -TEST_DIR = $(OUTPUT_ROOT)/test/$(TEST_NAME)/$(os_name)/$(TRANSPORT)/gcc/$(TEST_NAME)_$(APP_TYPE)/$(DEBUG_OR_RELEASE) +TEST_DIR = $(OUTPUT_ROOT)/test/$(TEST_NAME)/$(os_name)/$(TRANSPORT)/$(CC)/$(TEST_NAME)_$(APP_TYPE)/$(DEBUG_OR_RELEASE) RPC_OBJS_ROOT = $(TEST_DIR) TARGET_OUTPUT_ROOT = $(RPC_OBJS_ROOT) @@ -75,12 +75,16 @@ INCLUDES += $(TARGET_OUTPUT_ROOT) \ #------------------------------- IDL_FILE = $(CUR_DIR).erpc -ifneq "$(TEST_NAME)" "test_arbitrator" +ifeq (,$(filter $(TEST_NAME),test_arbitrator test_callbacks)) INCLUDES += $(ERPC_ROOT)/test/common/config SOURCES += $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_$(APP_TYPE).cpp \ $(ERPC_OUT_DIR)/$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp \ + $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_interface.cpp \ + $(ERPC_OUT_DIR)/$(ERPC_NAME)_unit_test_common_interface.cpp \ + $(ERPC_OUT_DIR)/c_$(ERPC_NAME_APP)_$(APP_TYPE).cpp \ + $(ERPC_OUT_DIR)/c_$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp \ $(CUR_DIR)_$(APP_TYPE)_impl.cpp \ $(UT_COMMON_SRC)/unit_test_$(TRANSPORT)_$(APP_TYPE).cpp @@ -91,7 +95,7 @@ all: $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_$(APP_TYPE).cpp $(ERPC_OUT_DIR)/$(ERPC_NAM # Define dependency. $(OUTPUT_ROOT)/test/$(TEST_NAME)/$(CUR_DIR)_$(APP_TYPE)_impl.cpp: $(UT_COMMON_SRC)/unit_test_$(TRANSPORT)_$(APP_TYPE).cpp $(UT_COMMON_SRC)/unit_test_$(TRANSPORT)_$(APP_TYPE).cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_$(APP_TYPE).cpp -$(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_$(APP_TYPE).cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp +$(ERPC_OUT_DIR)/$(ERPC_NAME)_unit_test_common_interface.cpp $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_interface.cpp $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_$(APP_TYPE).cpp $(ERPC_OUT_DIR)/c_$(ERPC_NAME_APP)_$(APP_TYPE).cpp $(ERPC_OUT_DIR)/c_$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp # Run erpcgen for C. $(ERPC_OUT_DIR)/$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp: $(IDL_FILE) @@ -110,12 +114,16 @@ ifeq "$(is_mingw)" "1" LIBRARIES += -lws2_32 endif else +ifeq (,$(filter $(TEST_NAME),test_arbitrator)) + INCLUDES += $(ERPC_ROOT)/test/common/config +else + INCLUDES += $(OUTPUT_ROOT)/test/$(TEST_NAME)/config +endif + ERPC_C_ROOT = $(ERPC_ROOT)/erpc_c include $(ERPC_ROOT)/test/mk/erpc_src.mk - INCLUDES += $(OUTPUT_ROOT)/test/$(TEST_NAME)/config - ifeq "$(TYPE)" "CLIENT" include $(TEST_ROOT)/$(TEST_NAME)/client.mk else diff --git a/test/mk/unit_test.mk b/test/mk/unit_test.mk index 0d7ce17a..92a8c62c 100644 --- a/test/mk/unit_test.mk +++ b/test/mk/unit_test.mk @@ -27,8 +27,8 @@ CLIENT_NAME = $(TEST_NAME)_client SERVER_NAME = $(TEST_NAME)_server ERPCGEN_PATH = $(ERPC_ROOT)/$(BUILD_TYPE)/$(os_name)/erpcgen/erpcgen UT_OUTPUT_DIR = $(OUTPUT_ROOT)/test/$(TEST_NAME) -TCP_CLIENT_PATH = $(UT_OUTPUT_DIR)/$(os_name)/tcp/gcc/$(CLIENT_NAME)/$(DEBUG_OR_RELEASE)/$(CLIENT_NAME)_tcp_test -TCP_SERVER_PATH = $(UT_OUTPUT_DIR)/$(os_name)/tcp/gcc/$(SERVER_NAME)/$(DEBUG_OR_RELEASE)/$(SERVER_NAME)_tcp_test +TCP_CLIENT_PATH = $(UT_OUTPUT_DIR)/$(os_name)/tcp/$(CC)/$(CLIENT_NAME)/$(DEBUG_OR_RELEASE)/$(CLIENT_NAME)_tcp_test +TCP_SERVER_PATH = $(UT_OUTPUT_DIR)/$(os_name)/tcp/$(CC)/$(SERVER_NAME)/$(DEBUG_OR_RELEASE)/$(SERVER_NAME)_tcp_test test_server_serial = test_server_serial test_client_serial = test_client_serial diff --git a/test/run_unit_tests.py b/test/run_unit_tests.py index 229a4883..a65d897a 100644 --- a/test/run_unit_tests.py +++ b/test/run_unit_tests.py @@ -12,20 +12,21 @@ # then run # $./run_unit_tests.py [tcp] # to run this script with optional transport layer argument -import subprocess +from subprocess import call import re import os import sys -import time -#define output text colour class + class bcolors: + # define output text colour class GREEN = '\033[36m' BLUE = '\033[38;5;097m' - ORANGE= '\033[38;5;172m' + ORANGE = '\033[38;5;172m' RED = '\033[31m' ENDC = '\033[0m' + def isTestDir(dir): regex = re.compile('test_*') if os.path.isdir(dir) and re.match(regex, dir): @@ -33,16 +34,19 @@ def isTestDir(dir): else: return False + testClientCommand = "run-tcp-client" testServerCommand = "run-tcp-server" transportLayer = "tcp" target = "release" +compilerC = "" +compilerCpp = "" make = "make" # Process command line options # Check for 2 or more arguments because argv[0] is the script name if len(sys.argv) > 2: - print ("Too many arguments. Please specify only the transport layer to use. Options are: tcp") + print("Too many arguments. Please specify only the transport layer to use. Options are: tcp") sys.exit(1) if len(sys.argv) >= 2: for arg in sys.argv[1:]: @@ -54,12 +58,19 @@ def isTestDir(dir): target = "debug" elif arg == "-r": target = "release" + elif arg == "clang": + compilerC = "clang" + compilerCpp = "clang++" + elif arg == "gcc": + compilerC = "gcc" + compilerCpp = "gcc++" elif "-m" in arg: make = arg[2:] else: print("Invalid argument/s. Options are: tcp, -r, -d\n") sys.exit(1) + unitTestPath = "./test/" # enter Unit Test Directory os.chdir(unitTestPath) @@ -72,13 +83,24 @@ def isTestDir(dir): build = "build=" + target testsExitStatus = 0 +clientCmd = [make, build, testClientCommand] +serverCmd = [make, build, testServerCommand] +compilerParamC = "" +compilerParamCpp = "" +if compilerC != "": + compilerParamC = "CC="+compilerC + compilerParamCpp = "CXX="+compilerParamCpp + clientCmd.append(compilerParamC) + serverCmd.append(compilerParamC) + clientCmd.append(compilerParamCpp) + serverCmd.append(compilerParamCpp) + for dir in testDirs: - print(bcolors.BLUE + "\nRunning " + bcolors.ORANGE + dir + bcolors.BLUE +" unit tests with " - + bcolors.ORANGE + transportLayer + bcolors.BLUE + " transport layer." + bcolors.ENDC) + print(bcolors.BLUE + "\nRunning " + bcolors.ORANGE + dir + bcolors.BLUE + " unit tests with " + + bcolors.ORANGE + transportLayer + bcolors.BLUE + " transport layer." + bcolors.ENDC) os.chdir(dir) - subprocess.Popen([make, build, testServerCommand]) - time.sleep(0.1) - testsExitStatus += subprocess.call([make, build, testClientCommand]) + call(serverCmd) + testsExitStatus += call(clientCmd) os.chdir('..') # For completeness, change back to erpc/ directory diff --git a/test/test_annotations/external.h b/test/test_annotations/external.h index 2ccab8a7..f6d7bef0 100644 --- a/test/test_annotations/external.h +++ b/test/test_annotations/external.h @@ -14,6 +14,8 @@ // Definitions //////////////////////////////////////////////////////////////////////////////// +#include + // Enumerators data types declarations typedef enum myEnum { diff --git a/test/test_annotations/test_annotations_client_impl.cpp b/test/test_annotations/test_annotations_client_impl.cpp index a354d1de..3407606b 100644 --- a/test/test_annotations/test_annotations_client_impl.cpp +++ b/test/test_annotations/test_annotations_client_impl.cpp @@ -6,13 +6,19 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include "c_test_client.h" #include "gtest.h" -#include "test.h" +#include "unit_test_wrapped.h" //////////////////////////////////////////////////////////////////////////////// // Unit test Implementation code //////////////////////////////////////////////////////////////////////////////// +void initInterfaces(erpc_client_t client) +{ + initAnnotateTest_client(client); +} + TEST(test_annotations, AnnotationServiceID) { EXPECT_EQ(kAnnotateTest_service_id, 5); diff --git a/test/test_annotations/test_annotations_server_impl.cpp b/test/test_annotations/test_annotations_server_impl.cpp index 66c7d202..74f4761d 100644 --- a/test/test_annotations/test_annotations_server_impl.cpp +++ b/test/test_annotations/test_annotations_server_impl.cpp @@ -8,13 +8,18 @@ #include "erpc_server_setup.h" -#include "test_server.h" -#include "test_unit_test_common_server.h" +#include "c_test_server.h" +#include "c_test_unit_test_common_server.h" +#include "test_server.hpp" +#include "test_unit_test_common_server.hpp" #include "unit_test.h" #include "unit_test_wrapped.h" #include +using namespace erpc; +using namespace erpcShim; + AnnotateTest_service *svc; //////////////////////////////////////////////////////////////////////////////// @@ -35,6 +40,30 @@ myInt testIfMyIntAndConstExist(myInt a) return a; } +class AnnotateTest_server : public AnnotateTest_interface +{ +public: + int32_t add(int32_t a, int32_t b) + { + int32_t result; + result = ::add(a, b); + + return result; + } + + void testIfFooStructExist(const fooStruct *a) { ::testIfFooStructExist(a); } + + void testIfMyEnumExist(myEnum a) { ::testIfMyEnumExist(a); } + + myInt testIfMyIntAndConstExist(myInt a) + { + myInt result; + result = ::testIfMyIntAndConstExist(a); + + return result; + } +}; + //////////////////////////////////////////////////////////////////////////////// // Add service to server code //////////////////////////////////////////////////////////////////////////////// @@ -44,7 +73,7 @@ void add_services(erpc::SimpleServer *server) /* Define services to add using dynamic memory allocation * Exapmle:ArithmeticService_service * svc = new ArithmeticService_service(); */ - svc = new AnnotateTest_service(); + svc = new AnnotateTest_service(new AnnotateTest_server()); /* Add services * Example: server->addService (svc); */ @@ -63,6 +92,7 @@ void remove_services(erpc::SimpleServer *server) server->removeService(svc); /* Delete unused service */ + delete svc->getHandler(); delete svc; } @@ -81,12 +111,6 @@ void remove_services_from_server(erpc_server_t server) erpc_remove_service_from_server(server, service_test); destroy_AnnotateTest_service(service_test); } - -void remove_common_services_from_server(erpc_server_t server, erpc_service_t service) -{ - erpc_remove_service_from_server(server, service); - destroy_Common_service(service); -} #ifdef __cplusplus } #endif diff --git a/test/test_arbitrator/client.mk b/test/test_arbitrator/client.mk index 8c7d6f02..a9a9851d 100644 --- a/test/test_arbitrator/client.mk +++ b/test/test_arbitrator/client.mk @@ -16,7 +16,11 @@ #------------------------------------------------------------------------------- SOURCES += $(ERPC_OUT_DIR)/$(ERPC_NAME)_firstInterface_$(APP_TYPE).cpp \ - $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_server.cpp\ + $(ERPC_OUT_DIR)/$(ERPC_NAME)_firstInterface_interface.cpp \ + $(ERPC_OUT_DIR)/c_$(ERPC_NAME)_firstInterface_$(APP_TYPE).cpp \ + $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_server.cpp \ + $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_interface.cpp \ + $(ERPC_OUT_DIR)/c_$(ERPC_NAME)_secondInterface_server.cpp \ $(CUR_DIR)_$(APP_TYPE)_impl.cpp \ $(UT_COMMON_SRC)/unit_test_$(TRANSPORT)_arbitrator_$(APP_TYPE).cpp @@ -27,6 +31,9 @@ all: $(ERPC_OUT_DIR)/$(ERPC_NAME)_firstInterface_$(APP_TYPE).cpp $(ERPC_OUT_DIR) $(OUTPUT_ROOT)/test/$(TEST_NAME)/$(CUR_DIR)_$(APP_TYPE)_impl.cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME)_firstInterface_$(APP_TYPE).cpp $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_server.cpp $(UT_COMMON_SRC)/unit_test_$(TRANSPORT)_arbitrator_$(APP_TYPE).cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME)_firstInterface_$(APP_TYPE).cpp $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_server.cpp $(ERPC_OUT_DIR)/$(ERPC_NAME)_firstInterface_$(APP_TYPE).cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_server.cpp +$(ERPC_OUT_DIR)/c_$(ERPC_NAME)_firstInterface_$(APP_TYPE).cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_server.cpp +$(ERPC_OUT_DIR)/c_$(ERPC_NAME)_secondInterface_server.cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_server.cpp +$(ERPC_OUT_DIR)/$(ERPC_NAME)_firstInterface_interface.cpp $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_interface.cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_server.cpp # Run erpcgen for C. $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_server.cpp: $(IDL_FILE) diff --git a/test/test_arbitrator/server.mk b/test/test_arbitrator/server.mk index 07bca589..566799c1 100644 --- a/test/test_arbitrator/server.mk +++ b/test/test_arbitrator/server.mk @@ -16,7 +16,11 @@ #------------------------------------------------------------------------------- SOURCES += $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_client.cpp \ + $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_interface.cpp \ + $(ERPC_OUT_DIR)/c_$(ERPC_NAME)_secondInterface_client.cpp \ $(ERPC_OUT_DIR)/$(ERPC_NAME)_firstInterface_$(APP_TYPE).cpp \ + $(ERPC_OUT_DIR)/$(ERPC_NAME)_firstInterface_interface.cpp \ + $(ERPC_OUT_DIR)/c_$(ERPC_NAME)_firstInterface_$(APP_TYPE).cpp \ $(CUR_DIR)_$(APP_TYPE)_impl.cpp \ $(UT_COMMON_SRC)/unit_test_$(TRANSPORT)_arbitrator_$(APP_TYPE).cpp @@ -27,6 +31,10 @@ all: $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_client.cpp $(ERPC_OUT_DIR)/$(E $(OUTPUT_ROOT)/test/$(TEST_NAME)/$(CUR_DIR)_$(APP_TYPE)_impl.cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_client.cpp $(ERPC_OUT_DIR)/$(ERPC_NAME)_firstInterface_$(APP_TYPE).cpp $(UT_COMMON_SRC)/unit_test_$(TRANSPORT)_arbitrator_$(APP_TYPE).cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_client.cpp $(ERPC_OUT_DIR)/$(ERPC_NAME)_firstInterface_$(APP_TYPE).cpp $(ERPC_OUT_DIR)/$(ERPC_NAME)_firstInterface_$(APP_TYPE).cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_client.cpp +$(ERPC_OUT_DIR)/c_$(ERPC_NAME)_secondInterface_client.cpp : $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_client.cpp +$(ERPC_OUT_DIR)/c_$(ERPC_NAME)_firstInterface_$(APP_TYPE).cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_client.cpp +$(ERPC_OUT_DIR)/$(ERPC_NAME)_firstInterface_interface.cpp $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_interface.cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_client.cpp + # Run erpcgen for C. $(ERPC_OUT_DIR)/$(ERPC_NAME)_secondInterface_client.cpp: $(IDL_FILE) diff --git a/test/test_arbitrator/test_arbitrator.erpc b/test/test_arbitrator/test_arbitrator.erpc index 62202f09..890c45cc 100644 --- a/test/test_arbitrator/test_arbitrator.erpc +++ b/test/test_arbitrator/test_arbitrator.erpc @@ -8,6 +8,7 @@ @crc @output_dir("erpc_outputs/") +@namespace("") program test; import "../common/unit_test_common.erpc" diff --git a/test/test_arbitrator/test_arbitrator_client_impl.cpp b/test/test_arbitrator/test_arbitrator_client_impl.cpp index ec009e76..22839f2b 100644 --- a/test/test_arbitrator/test_arbitrator_client_impl.cpp +++ b/test/test_arbitrator/test_arbitrator_client_impl.cpp @@ -8,14 +8,19 @@ #include "erpc_simple_server.hpp" +#include "c_test_firstInterface_client.h" +#include "c_test_secondInterface_server.h" #include "gtest.h" -#include "test_firstInterface.h" -#include "test_secondInterface_server.h" +#include "test_secondInterface_server.hpp" +#include "unit_test.h" +#include "unit_test_wrapped.h" //////////////////////////////////////////////////////////////////////////////// // Unit test Implementation code //////////////////////////////////////////////////////////////////////////////// +using namespace erpc; + #define number 15 #define nestedCallsCount 10 volatile int j = 0; @@ -23,6 +28,11 @@ volatile int numbers[number]; volatile bool enabled = false; SecondInterface_service *svc; +void initInterfaces(erpc_client_t client) +{ + initFirstInterface_client(client); +} + TEST(test_arbitrator, FirstSendReceiveInt) { for (int i = 0; i < number; i++) @@ -99,12 +109,38 @@ void enableFirstSide() enabled = true; } +class SecondInterface_server : public SecondInterface_interface +{ +public: + void secondSendInt(int32_t a) { ::secondSendInt(a); } + + int32_t secondReceiveInt(void) + { + int32_t result; + result = ::secondReceiveInt(); + + return result; + } + + void quitSecondInterfaceServer(void) { ::quitSecondInterfaceServer(); } + + void enableFirstSide(void) { ::enableFirstSide(); } + + int32_t callFirstSide(void) + { + int32_t result; + result = ::callFirstSide(); + + return result; + } +}; + void add_services(erpc::SimpleServer *server) { /* Define services to add using dynamic memory allocation * Exapmle:ArithmeticService_service * svc = new ArithmeticService_service(); */ - svc = new SecondInterface_service(); + svc = new SecondInterface_service(new SecondInterface_server()); /* Add services * Example: server->addService(svc); @@ -124,5 +160,6 @@ void remove_services(erpc::SimpleServer *server) server->removeService(svc); /* Delete unused service */ + delete svc->getHandler(); delete svc; } diff --git a/test/test_arbitrator/test_arbitrator_server_impl.cpp b/test/test_arbitrator/test_arbitrator_server_impl.cpp index f4ccc399..cb039760 100644 --- a/test/test_arbitrator/test_arbitrator_server_impl.cpp +++ b/test/test_arbitrator/test_arbitrator_server_impl.cpp @@ -8,18 +8,28 @@ #include "erpc_simple_server.hpp" -#include "test_firstInterface_server.h" -#include "test_secondInterface.h" +#include "c_test_firstInterface_server.h" +#include "c_test_secondInterface_client.h" +#include "test_firstInterface_server.hpp" +#include "unit_test_wrapped.h" //////////////////////////////////////////////////////////////////////////////// // Unit test Implementation code //////////////////////////////////////////////////////////////////////////////// +using namespace erpc; + #define number 15 volatile int i = 0; volatile int numbers[number]; FirstInterface_service *svc; +extern "C" { +void initInterfaces(erpc_client_t client) +{ + initSecondInterface_client(client); +} + void firstSendInt(int32_t a) { numbers[i] = a; @@ -41,13 +51,60 @@ int32_t callSecondSide() { return callFirstSide() + 1; } +} + +class FirstInterface_server : public FirstInterface_interface +{ +public: + void whenReady(void) { ::whenReady(); } + + void firstSendInt(int32_t a) { ::firstSendInt(a); } + + int32_t firstReceiveInt(void) + { + int32_t result; + result = ::firstReceiveInt(); + + return result; + } + + void stopSecondSide(void) { ::stopSecondSide(); } + + int32_t getResultFromSecondSide(void) + { + int32_t result; + result = ::getResultFromSecondSide(); + + return result; + } + + void testCasesAreDone(void) { ::testCasesAreDone(); } + + void quitFirstInterfaceServer(void) { ::quitFirstInterfaceServer(); } + + int32_t nestedCallTest(void) + { + int32_t result; + result = ::nestedCallTest(); + + return result; + } + + int32_t callSecondSide(void) + { + int32_t result; + result = ::callSecondSide(); + + return result; + } +}; void add_services(erpc::SimpleServer *server) { /* Define services to add using dynamic memory allocation * Exapmle:ArithmeticService_service * svc = new ArithmeticService_service(); */ - svc = new FirstInterface_service(); + svc = new FirstInterface_service(new FirstInterface_server()); /* Add services * Example: server->addService(svc); @@ -67,5 +124,6 @@ void remove_services(erpc::SimpleServer *server) server->removeService(svc); /* Delete unused service */ + delete svc->getHandler(); delete svc; } diff --git a/test/test_arrays/test_arrays_client_impl.cpp b/test/test_arrays/test_arrays_client_impl.cpp index 6b1ca2d7..4b80e35b 100644 --- a/test/test_arrays/test_arrays_client_impl.cpp +++ b/test/test_arrays/test_arrays_client_impl.cpp @@ -6,8 +6,9 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include "c_test_client.h" #include "gtest.h" -#include "test.h" +#include "unit_test_wrapped.h" #include @@ -15,6 +16,11 @@ // Unit test Implementation code //////////////////////////////////////////////////////////////////////////////// +void initInterfaces(erpc_client_t client) +{ + initPointersService_client(client); +} + TEST(test_arrays, sendReceivedInt32) { uint32_t array_count = 12; diff --git a/test/test_arrays/test_arrays_server_impl.cpp b/test/test_arrays/test_arrays_server_impl.cpp index c0e70ca0..b48f66fb 100644 --- a/test/test_arrays/test_arrays_server_impl.cpp +++ b/test/test_arrays/test_arrays_server_impl.cpp @@ -8,14 +8,18 @@ #include "erpc_server_setup.h" -#include "test_server.h" -#include "test_unit_test_common_server.h" +#include "c_test_server.h" +#include "c_test_unit_test_common_server.h" +#include "test_server.hpp" #include "unit_test.h" #include "unit_test_wrapped.h" #include #include +using namespace erpc; +using namespace erpcShim; + PointersService_service *svc; //////////////////////////////////////////////////////////////////////////////// @@ -374,16 +378,185 @@ void test_array_allDirection(const int32_t a[5], const int32_t b[5], int32_t c[5 void testFunction(){}; +class PointersService_server : public PointersService_interface +{ +public: + int32_t (*sendReceivedInt32(const int32_t arrayNumbers[12]))[12] + { + int32_t(*result)[12] = NULL; + result = ::sendReceivedInt32(arrayNumbers); + + return result; + } + + int32_t (*sendReceived2Int32(int32_t arrayNumbers[12][10]))[12][10] + { + int32_t(*result)[12][10] = NULL; + result = ::sendReceived2Int32(arrayNumbers); + + return result; + } + + char *(*sendReceivedString(char *arrayStrings[12]))[12] + { + char *(*result)[12] = NULL; + result = ::sendReceivedString(arrayStrings); + + return result; + } + + char *(*sendReceived2String(char *arrayStrings[3][5]))[3][5] + { + char *(*result)[3][5] = NULL; + result = ::sendReceived2String(arrayStrings); + + return result; + } + + enumColor (*sendReceivedEnum(const enumColor arrayEnums[3]))[3] + { + enumColor(*result)[3] = NULL; + result = ::sendReceivedEnum(arrayEnums); + + return result; + } + + enumColor (*sendReceived2Enum(enumColor arrayEnums[3][3]))[3][3] + { + enumColor(*result)[3][3] = NULL; + result = ::sendReceived2Enum(arrayEnums); + + return result; + } + + list_int32_1_t (*sendReceivedList(const list_int32_1_t arrayLists[2]))[2] + { + list_int32_1_t(*result)[2] = NULL; + result = ::sendReceivedList(arrayLists); + + return result; + } + + list_int32_1_t (*sendReceived2List(list_int32_1_t arrayLists[2][2]))[2][2] + { + list_int32_1_t(*result)[2][2] = NULL; + result = ::sendReceived2List(arrayLists); + + return result; + } + + ArrayIntType *sendReceivedInt32Type(const ArrayIntType arrayNumbers) + { + ArrayIntType *result = NULL; + result = ::sendReceivedInt32Type(arrayNumbers); + + return result; + } + + Array2IntType *sendReceived2Int32Type(Array2IntType arrayNumbers) + { + Array2IntType *result = NULL; + result = ::sendReceived2Int32Type(arrayNumbers); + + return result; + } + + ArrayStringType *sendReceivedStringType(ArrayStringType arrayStrings) + { + ArrayStringType *result = NULL; + result = ::sendReceivedStringType(arrayStrings); + + return result; + } + + Array2StringType *sendReceived2StringType(Array2StringType arrayStrings) + { + Array2StringType *result = NULL; + result = ::sendReceived2StringType(arrayStrings); + + return result; + } + + ArrayEnumType *sendReceivedEnumType(const ArrayEnumType arrayEnums) + { + ArrayEnumType *result = NULL; + result = ::sendReceivedEnumType(arrayEnums); + + return result; + } + + Array2EnumType *sendReceived2EnumType(Array2EnumType arrayEnums) + { + Array2EnumType *result = NULL; + result = ::sendReceived2EnumType(arrayEnums); + + return result; + } + + ArrayStructType *sendReceivedStructType(const ArrayStructType arrayStructs) + { + ArrayStructType *result = NULL; + result = ::sendReceivedStructType(arrayStructs); + + return result; + } + + Array2StructType *sendReceived2StructType(Array2StructType arrayStructs) + { + Array2StructType *result = NULL; + result = ::sendReceived2StructType(arrayStructs); + + return result; + } + + ArrayListType *sendReceivedListType(const ArrayListType arrayLists) + { + ArrayListType *result = NULL; + result = ::sendReceivedListType(arrayLists); + + return result; + } + + Array2ListType *sendReceived2ListType(Array2ListType arrayLists) + { + Array2ListType *result = NULL; + result = ::sendReceived2ListType(arrayLists); + + return result; + } + + AllTypes (*sendReceiveStruct(const AllTypes arrayStructs[2]))[2] + { + AllTypes(*result)[2] = NULL; + result = ::sendReceiveStruct(arrayStructs); + + return result; + } + + AllTypes (*sendReceive2Struct(AllTypes arrayStructs[1][1]))[1][1] + { + AllTypes(*result)[1][1] = NULL; + result = ::sendReceive2Struct(arrayStructs); + + return result; + } + + void test_array_allDirection(const int32_t a[5], const int32_t b[5], int32_t c[5], int32_t d[5]) + { + ::test_array_allDirection(a, b, c, d); + } +}; + //////////////////////////////////////////////////////////////////////////////// // Add service to server code //////////////////////////////////////////////////////////////////////////////// void add_services(erpc::SimpleServer *server) { - // define services to add on heap - // allocate on heap so service doesn't go out of scope at end of method - svc = new PointersService_service(); - + /* Define services to add using dynamic memory allocation + * Exapmle:ArithmeticService_service * svc = new ArithmeticService_service(); + */ + svc = new PointersService_service(new PointersService_server()); // add services server->addService(svc); } @@ -400,6 +573,7 @@ void remove_services(erpc::SimpleServer *server) server->removeService(svc); /* Delete unused service */ + delete svc->getHandler(); delete svc; } @@ -418,12 +592,6 @@ void remove_services_from_server(erpc_server_t server) erpc_remove_service_from_server(server, service_test); destroy_PointersService_service(service_test); } - -void remove_common_services_from_server(erpc_server_t server, erpc_service_t service) -{ - erpc_remove_service_from_server(server, service); - destroy_Common_service(service); -} #ifdef __cplusplus } #endif diff --git a/test/test_binary/test_binary_client_impl.cpp b/test/test_binary/test_binary_client_impl.cpp index 917a457f..58d74128 100644 --- a/test/test_binary/test_binary_client_impl.cpp +++ b/test/test_binary/test_binary_client_impl.cpp @@ -6,8 +6,9 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include "c_test_client.h" #include "gtest.h" -#include "test.h" +#include "unit_test_wrapped.h" using namespace std; @@ -15,6 +16,11 @@ using namespace std; // Unit test Implementation code //////////////////////////////////////////////////////////////////////////////// +void initInterfaces(erpc_client_t client) +{ + initBinary_client(client); +} + /*TEST(test_binary, sendReceiveBinary) { binary *result, send; diff --git a/test/test_binary/test_binary_server_impl.cpp b/test/test_binary/test_binary_server_impl.cpp index b073d243..7e1ad36a 100644 --- a/test/test_binary/test_binary_server_impl.cpp +++ b/test/test_binary/test_binary_server_impl.cpp @@ -8,13 +8,16 @@ #include "erpc_server_setup.h" -#include "test_server.h" -#include "test_unit_test_common_server.h" +#include "c_test_server.h" +#include "test_server.hpp" #include "unit_test.h" #include "unit_test_wrapped.h" #include +using namespace erpc; +using namespace erpcShim; + Binary_service *svc; //////////////////////////////////////////////////////////////////////////////// @@ -70,6 +73,21 @@ void test_binary_allDirectionLength(const uint8_t *a, const binary_t *b, binary_ free((void *)a); free((void *)b); }*/ +class Binary_server : public Binary_interface +{ +public: + void sendBinary(const binary_t *a) { ::sendBinary(a); } + + void test_binary_allDirection(const binary_t *a, const binary_t *b, binary_t *e) + { + ::test_binary_allDirection(a, b, e); + } + + void test_binary_allDirectionLength(const uint8_t *a, const binary_t *b, binary_t *d, uint32_t p1) + { + ::test_binary_allDirectionLength(a, b, d, p1); + } +}; //////////////////////////////////////////////////////////////////////////////// // Add service to server code @@ -80,7 +98,7 @@ void add_services(erpc::SimpleServer *server) /* Define services to add using dynamic memory allocation * Exapmle:ArithmeticService_service * svc = new ArithmeticService_service(); */ - svc = new Binary_service(); + svc = new Binary_service(new Binary_server()); /* Add services * Example: server->addService(svc); @@ -100,6 +118,7 @@ void remove_services(erpc::SimpleServer *server) server->removeService(svc); /* Delete unused service */ + delete svc->getHandler(); delete svc; } @@ -119,11 +138,6 @@ void remove_services_from_server(erpc_server_t server) destroy_Binary_service(service_test); } -void remove_common_services_from_server(erpc_server_t server, erpc_service_t service) -{ - erpc_remove_service_from_server(server, service); - destroy_Common_service(service); -} #ifdef __cplusplus } #endif diff --git a/test/test_builtin/test_builtin_client_impl.cpp b/test/test_builtin/test_builtin_client_impl.cpp index a318947f..e355192c 100644 --- a/test/test_builtin/test_builtin_client_impl.cpp +++ b/test/test_builtin/test_builtin_client_impl.cpp @@ -6,8 +6,9 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include "c_test_client.h" #include "gtest.h" -#include "test.h" +#include "unit_test_wrapped.h" #include @@ -17,6 +18,11 @@ using namespace std; // Unit test Implementation code //////////////////////////////////////////////////////////////////////////////// +void initInterfaces(erpc_client_t client) +{ + initBuiltinServices_client(client); +} + int32_t int32A = 2; int32_t int32B = -20; diff --git a/test/test_builtin/test_builtin_server_impl.cpp b/test/test_builtin/test_builtin_server_impl.cpp index 0cd2bf57..5daced06 100644 --- a/test/test_builtin/test_builtin_server_impl.cpp +++ b/test/test_builtin/test_builtin_server_impl.cpp @@ -8,14 +8,17 @@ #include "erpc_server_setup.h" -#include "test_server.h" -#include "test_unit_test_common_server.h" +#include "c_test_server.h" +#include "test_server.hpp" #include "unit_test.h" #include "unit_test_wrapped.h" #include #include +using namespace erpc; +using namespace erpcShim; + BuiltinServices_service *svc; //////////////////////////////////////////////////////////////////////////////// @@ -150,6 +153,94 @@ char *returnHello() return hello; } +class BuiltinServices_server : public BuiltinServices_interface +{ +public: + void test_int32_in(int32_t a) { ::test_int32_in(a); } + + void test_int32_in2(int32_t b) { ::test_int32_in2(b); } + + void test_int32_out(int32_t *c) { ::test_int32_out(c); } + + void test_int32_inout(int32_t *e) { ::test_int32_inout(e); } + + int32_t test_int32_return(void) + { + int32_t result; + result = ::test_int32_return(); + + return result; + } + + int32_t test_int32_allDirection(int32_t a, int32_t b, int32_t *c, int32_t *e) + { + int32_t result; + result = ::test_int32_allDirection(a, b, c, e); + + return result; + } + + void test_float_inout(float a, float *b) { ::test_float_inout(a, b); } + + void test_double_inout(double a, double *b) { ::test_double_inout(a, b); } + + void test_string_in(const char *a) { ::test_string_in(a); } + + void test_string_in2(const char *b) { ::test_string_in2(b); } + + void test_string_out(char *c) { ::test_string_out(c); } + + void test_string_inout(char *e) { ::test_string_inout(e); } + + char *test_string_return(void) + { + char *result = NULL; + result = ::test_string_return(); + + return result; + } + + char *test_string_allDirection(const char *a, const char *b, char *c, char *e) + { + char *result = NULL; + result = ::test_string_allDirection(a, b, c, e); + + return result; + } + + char *test_string_empty(const char *a, const char *b, char *c, char *e) + { + char *result = NULL; + result = ::test_string_empty(a, b, c, e); + + return result; + } + + int32_t sendHello(const char *str) + { + int32_t result; + result = ::sendHello(str); + + return result; + } + + int32_t sendTwoStrings(const char *myStr1, const char *myStr2) + { + int32_t result; + result = ::sendTwoStrings(myStr1, myStr2); + + return result; + } + + char *returnHello(void) + { + char *result = NULL; + result = ::returnHello(); + + return result; + } +}; + //////////////////////////////////////////////////////////////////////////////// // Add service to server code //////////////////////////////////////////////////////////////////////////////// @@ -158,7 +249,7 @@ void add_services(erpc::SimpleServer *server) { // define services to add on heap // allocate on heap so service doesn't go out of scope at end of method - svc = new BuiltinServices_service(); + svc = new BuiltinServices_service(new BuiltinServices_server()); // add services server->addService(svc); @@ -176,6 +267,7 @@ void remove_services(erpc::SimpleServer *server) server->removeService(svc); /* Delete unused service */ + delete svc->getHandler(); delete svc; } @@ -194,12 +286,6 @@ void remove_services_from_server(erpc_server_t server) erpc_remove_service_from_server(server, service_test); destroy_BuiltinServices_service(service_test); } - -void remove_common_services_from_server(erpc_server_t server, erpc_service_t service) -{ - erpc_remove_service_from_server(server, service); - destroy_Common_service(service); -} #ifdef __cplusplus } #endif diff --git a/test/test_callbacks/callbacks1.h b/test/test_callbacks/callbacks1.h deleted file mode 100644 index b1d511c7..00000000 --- a/test/test_callbacks/callbacks1.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright 2017 NXP - * All rights reserved. - * - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -void callback1a(int32_t a, int32_t b); - -void callback1b(int32_t param1, int32_t param2); diff --git a/test/test_callbacks/callbacks2.h b/test/test_callbacks/callbacks2.h deleted file mode 100644 index f3f4120c..00000000 --- a/test/test_callbacks/callbacks2.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright 2017 NXP - * All rights reserved. - * - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -void callback2(int32_t param1, int32_t param2); diff --git a/test/test_callbacks/client.mk b/test/test_callbacks/client.mk new file mode 100644 index 00000000..749e4209 --- /dev/null +++ b/test/test_callbacks/client.mk @@ -0,0 +1,44 @@ +#------------------------------------------------------------------------------- +# Copyright (C) 2016 Freescale Semiconductor, Inc. +# Copyright 2016 NXP +# All Rights Reserved. +# +# THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +# SHALL FREESCALE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +# OF SUCH DAMAGE. +#------------------------------------------------------------------------------- + +SOURCES += $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_$(APP_TYPE).cpp \ + $(ERPC_OUT_DIR)/c_$(ERPC_NAME_APP)_$(APP_TYPE).cpp \ + $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_interface.cpp \ + $(ERPC_OUT_DIR)/$(ERPC_NAME)_core1_interface.cpp \ + $(ERPC_OUT_DIR)/$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp \ + $(ERPC_OUT_DIR)/$(ERPC_NAME)_unit_test_common_interface.cpp \ + $(ERPC_OUT_DIR)/c_$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp \ + $(CUR_DIR)_$(APP_TYPE)_impl.cpp \ + $(UT_COMMON_SRC)/unit_test_$(TRANSPORT)_$(APP_TYPE).cpp + +.PHONY: all +all: $(ERPC_OUT_DIR)/$(ERPC_NAME)_core0_$(APP_TYPE).cpp $(ERPC_OUT_DIR)/c_$(ERPC_NAME)_core0_$(APP_TYPE).cpp $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_interface.cpp $(ERPC_OUT_DIR)/$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp $(ERPC_OUT_DIR)/c_$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp $(ERPC_OUT_DIR)/$(ERPC_NAME)_core1_interface.cpp + +# Define dependency. +$(OUTPUT_ROOT)/test/$(TEST_NAME)/$(CUR_DIR)_$(APP_TYPE)_impl.cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME)_core0_$(APP_TYPE).cpp $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_interface.cpp +$(UT_COMMON_SRC)/unit_test_$(TRANSPORT)_$(APP_TYPE).cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME)_core0_$(APP_TYPE).cpp $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_interface.cpp +$(ERPC_OUT_DIR)/$(ERPC_NAME)_core0_$(APP_TYPE).cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_interface.cpp +$(ERPC_OUT_DIR)/c_$(ERPC_NAME)_core0_$(APP_TYPE).cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME)_core0_$(APP_TYPE).cpp +$(ERPC_OUT_DIR)/$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_$(APP_TYPE).cpp +$(ERPC_OUT_DIR)/c_$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp +$(ERPC_OUT_DIR)/$(ERPC_NAME)_core1_interface.cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_interface.cpp +$(ERPC_OUT_DIR)/$(ERPC_NAME)_unit_test_common_interface.cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_interface.cpp + +# Run erpcgen for C. +$(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_interface.cpp: $(IDL_FILE) + @$(call printmessage,orange,Running erpcgen-c $(TEST_NAME), $(subst $(ERPC_ROOT)/,,$<)) + $(at)$(ERPCGEN) -gc -o $(RPC_OBJS_ROOT)/ $(IDL_FILE) diff --git a/test/test_callbacks/server.mk b/test/test_callbacks/server.mk new file mode 100644 index 00000000..1d3d056d --- /dev/null +++ b/test/test_callbacks/server.mk @@ -0,0 +1,44 @@ +#------------------------------------------------------------------------------- +# Copyright (C) 2016 Freescale Semiconductor, Inc. +# Copyright 2016 NXP +# All Rights Reserved. +# +# THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +# SHALL FREESCALE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +# OF SUCH DAMAGE. +#------------------------------------------------------------------------------- + +SOURCES += $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_server.cpp \ + $(ERPC_OUT_DIR)/c_$(ERPC_NAME_APP)_server.cpp \ + $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_interface.cpp \ + $(ERPC_OUT_DIR)/$(ERPC_NAME)_core1_interface.cpp \ + $(ERPC_OUT_DIR)/$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp \ + $(ERPC_OUT_DIR)/$(ERPC_NAME)_unit_test_common_interface.cpp \ + $(ERPC_OUT_DIR)/c_$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp \ + $(CUR_DIR)_$(APP_TYPE)_impl.cpp \ + $(UT_COMMON_SRC)/unit_test_$(TRANSPORT)_$(APP_TYPE).cpp + +.PHONY: all +all: $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_server.cpp $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_interface.cpp $(ERPC_OUT_DIR)/$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp $(ERPC_OUT_DIR)/c_$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp $(ERPC_OUT_DIR)/$(ERPC_NAME)_core1_interface.cpp + +# Define dependency. +$(OUTPUT_ROOT)/test/$(TEST_NAME)/$(CUR_DIR)_$(APP_TYPE)_impl.cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_server.cpp $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_interface.cpp +$(UT_COMMON_SRC)/unit_test_$(TRANSPORT)_$(APP_TYPE).cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_server.cpp $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_interface.cpp +$(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_interface.cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_server.cpp +$(ERPC_OUT_DIR)/c_$(ERPC_NAME_APP)_server.cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_interface.cpp +$(ERPC_OUT_DIR)/$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_interface.cpp +$(ERPC_OUT_DIR)/c_$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME)_unit_test_common_$(APP_TYPE).cpp +$(ERPC_OUT_DIR)/$(ERPC_NAME)_core1_interface.cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_interface.cpp +$(ERPC_OUT_DIR)/$(ERPC_NAME)_unit_test_common_interface.cpp: $(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_interface.cpp + +# Run erpcgen for C. +$(ERPC_OUT_DIR)/$(ERPC_NAME_APP)_server.cpp: $(IDL_FILE) + @$(call printmessage,orange,Running erpcgen-c $(TEST_NAME), $(subst $(ERPC_ROOT)/,,$<)) + $(at)$(ERPCGEN) -gc -o $(RPC_OBJS_ROOT)/ $(IDL_FILE) diff --git a/test/test_callbacks/test_callbacks.erpc b/test/test_callbacks/test_callbacks.erpc index 0ae0aeff..9c7db83e 100644 --- a/test/test_callbacks/test_callbacks.erpc +++ b/test/test_callbacks/test_callbacks.erpc @@ -10,17 +10,17 @@ program test import "../common/unit_test_common.erpc" -oneway callback1_t(int32 a, int32 b) -oneway callback2_t(int32, int32) -callback3_t(int32 arg1, int32 arg2) -> int32 - @c:include("test_core1.h") @group("core0") interface ClientCore0Services { - myFun(in callback1_t pCallback1_in, out callback1_t pCallback1_out) -> void + type oneway callback1_t(int32 a, int32 b) + type callback3_t(int32 arg1, int32 arg2) -> int32 + type oneway callback2_t(int32, int32) + + myFun(in callback1_t pCallback1_in, out callback1_t pCallback1_out) -> int32 - myFun2(callback2_t pCallback2_in, out callback2_t pCallback2_out) -> void + myFun2(ClientCore1Services::callback2_t pCallback2_in, out ClientCore1Services::callback2_t pCallback2_out) -> void myFun3(callback3_t callback, in int32 arg1, in int32 arg2) -> int32 @@ -29,17 +29,16 @@ interface ClientCore0Services callback3_t my_mul; callback3_t my_div; - @c:include("callbacks1.h") callback1_t callback1a; - @c:include("callbacks1.h") callback1_t callback1b(param1, param2); } @group("core1") interface ClientCore1Services { - @c:include("callbacks2.h") + type oneway callback2_t(int32, int32) + callback2_t callback2(param1, param2); } diff --git a/test/test_callbacks/test_callbacks_client_impl.cpp b/test/test_callbacks/test_callbacks_client_impl.cpp index b85a6e46..76f11b94 100644 --- a/test/test_callbacks/test_callbacks_client_impl.cpp +++ b/test/test_callbacks/test_callbacks_client_impl.cpp @@ -5,9 +5,9 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include "c_test_core0_client.h" #include "gtest.h" -#include "test_core0.h" -#include "test_core1_server.h" +#include "unit_test_wrapped.h" void callback2(int32_t param1, int32_t param2) {} @@ -15,6 +15,11 @@ void callback2(int32_t param1, int32_t param2) {} // Unit test Implementation code //////////////////////////////////////////////////////////////////////////////// +void initInterfaces(erpc_client_t client) +{ + initClientCore0Services_client(client); +} + TEST(test_callbacks, In_Out_table_1) { callback1_t pCallback1_out = NULL; diff --git a/test/test_callbacks/test_callbacks_server_impl.cpp b/test/test_callbacks/test_callbacks_server_impl.cpp index 7f6884d2..cfb1be71 100644 --- a/test/test_callbacks/test_callbacks_server_impl.cpp +++ b/test/test_callbacks/test_callbacks_server_impl.cpp @@ -6,15 +6,19 @@ */ #include "erpc_server_setup.h" +#include "erpc_utils.hpp" -#include "test_core0_server.h" -#include "test_core1.h" -#include "test_unit_test_common_server.h" +#include "c_test_core0_server.h" +#include "c_test_core1_server.h" +#include "test_core0_server.hpp" #include "unit_test.h" #include "unit_test_wrapped.h" #include +using namespace erpc; +using namespace erpcShim; + ClientCore0Services_service *svc; //////////////////////////////////////////////////////////////////////////////// @@ -24,18 +28,17 @@ ClientCore0Services_service *svc; callback1_t *cb1 = NULL; callback2_t *cb2 = NULL; -void myFun(const callback1_t pCallback1_in, callback1_t *pCallback1_out) +int32_t myFun(const callback1_t pCallback1_in, callback1_t *pCallback1_out) { - cb1 = NULL; pCallback1_in(1, 2); - *pCallback1_out = (callback1_t)cb1; + *pCallback1_out = pCallback1_in; + return 0; } void myFun2(const callback2_t pCallback2_in, callback2_t *pCallback2_out) { - cb2 = NULL; pCallback2_in(1, 2); - *pCallback2_out = (callback2_t)cb2; + *pCallback2_out = pCallback2_in; } void callback1a(int32_t a, int32_t b) @@ -83,6 +86,110 @@ int32_t my_div(int32_t arg1, int32_t arg2) return 0; } +static const callback1_t _callback1_t[2] = { callback1a, callback1b }; +static const callback2_t _callback2_t[1] = { callback2 }; +static const callback3_t _callback3_t[4] = { my_add, my_sub, my_mul, my_div }; + +class ClientCore0Services_server : public ClientCore0Services_interface +{ +public: + int32_t myFun(const callback1_t pCallback1_in, callback1_t *pCallback1_out) + { + uint16_t _fnIndex; + ::callback1_t _pCallback1_in = NULL; + ::callback1_t _pCallback1_out = NULL; + int32_t result; + + if (ClientCore0Services_interface::get_callbackIdx_callback1_t(&pCallback1_in, _fnIndex)) + { + _pCallback1_in = ::_callback1_t[_fnIndex]; + } + + result = ::myFun(_pCallback1_in, &_pCallback1_out); + + if (findIndexOfFunction((arrayOfFunctionPtr_t)::_callback1_t, sizeof(::_callback1_t) / sizeof(::callback1_t), + (functionPtr_t)_pCallback1_out, _fnIndex)) + { + ClientCore0Services_interface::get_callbackAddress_callback1_t(_fnIndex, pCallback1_out); + } + + return result; + } + + void myFun2(const ClientCore1Services_interface::callback2_t pCallback2_in, + ClientCore1Services_interface::callback2_t *pCallback2_out) + { + uint16_t _fnIndex; + ::callback2_t _pCallback2_in = NULL; + ::callback2_t _pCallback2_out = NULL; + + if (ClientCore1Services_interface::get_callbackIdx_callback2_t(&pCallback2_in, _fnIndex)) + { + _pCallback2_in = ::_callback2_t[_fnIndex]; + } + + ::myFun2(_pCallback2_in, &_pCallback2_out); + + if (findIndexOfFunction((arrayOfFunctionPtr_t)::_callback2_t, sizeof(::_callback2_t) / sizeof(::callback2_t), + (functionPtr_t)_pCallback2_out, _fnIndex)) + { + ClientCore1Services_interface::get_callbackAddress_callback2_t(_fnIndex, pCallback2_out); + } + } + + int32_t myFun3(const callback3_t callback, int32_t arg1, int32_t arg2) + { + uint16_t _fnIndex; + ::callback3_t _callback = NULL; + int32_t result; + + if (ClientCore0Services_interface::get_callbackIdx_callback3_t(&callback, _fnIndex)) + { + _callback = ::_callback3_t[_fnIndex]; + } + + result = ::myFun3(_callback, arg1, arg2); + + return result; + } + + int32_t my_add(int32_t arg1, int32_t arg2) + { + int32_t result; + result = ::my_add(arg1, arg2); + + return result; + } + + int32_t my_sub(int32_t arg1, int32_t arg2) + { + int32_t result; + result = ::my_sub(arg1, arg2); + + return result; + } + + int32_t my_mul(int32_t arg1, int32_t arg2) + { + int32_t result; + result = ::my_mul(arg1, arg2); + + return result; + } + + int32_t my_div(int32_t arg1, int32_t arg2) + { + int32_t result; + result = ::my_div(arg1, arg2); + + return result; + } + + void callback1a(int32_t a, int32_t b) { ::callback1a(a, b); } + + void callback1b(int32_t param1, int32_t param2) { ::callback1b(param1, param2); } +}; + //////////////////////////////////////////////////////////////////////////////// // Add service to server code //////////////////////////////////////////////////////////////////////////////// @@ -91,7 +198,7 @@ void add_services(erpc::SimpleServer *server) { // define services to add on heap // allocate on heap so service doesn't go out of scope at end of method - svc = new ClientCore0Services_service(); + svc = new ClientCore0Services_service(new ClientCore0Services_server()); // add services server->addService(svc); @@ -109,6 +216,7 @@ void remove_services(erpc::SimpleServer *server) server->removeService(svc); /* Delete unused service */ + delete svc->getHandler(); delete svc; } @@ -127,12 +235,6 @@ void remove_services_from_server(erpc_server_t server) erpc_remove_service_from_server(server, service_test); destroy_ClientCore0Services_service(service_test); } - -void remove_common_services_from_server(erpc_server_t server, erpc_service_t service) -{ - erpc_remove_service_from_server(server, service); - destroy_Common_service(service); -} #ifdef __cplusplus } #endif diff --git a/test/test_const/test_const_client_impl.cpp b/test/test_const/test_const_client_impl.cpp index 3db9141a..cd3e6e26 100644 --- a/test/test_const/test_const_client_impl.cpp +++ b/test/test_const/test_const_client_impl.cpp @@ -7,12 +7,15 @@ */ #include "gtest.h" -#include "test.h" +#include "test_common.h" +#include "unit_test_wrapped.h" //////////////////////////////////////////////////////////////////////////////// // Unit test Implementation code //////////////////////////////////////////////////////////////////////////////// +void initInterfaces(erpc_client_t client) {} + TEST(test_const, CheckConsts) { EXPECT_EQ(a, 3); diff --git a/test/test_const/test_const_server_impl.cpp b/test/test_const/test_const_server_impl.cpp index 91c52740..90a83e7f 100644 --- a/test/test_const/test_const_server_impl.cpp +++ b/test/test_const/test_const_server_impl.cpp @@ -8,8 +8,8 @@ #include "erpc_server_setup.h" -#include "test_server.h" -#include "test_unit_test_common_server.h" +#include "c_test_server.h" +#include "c_test_unit_test_common_server.h" #include "unit_test.h" #include "unit_test_wrapped.h" @@ -53,12 +53,6 @@ extern "C" { #endif void add_services_to_server(erpc_server_t server) {} void remove_services_from_server(erpc_server_t server) {} - -void remove_common_services_from_server(erpc_server_t server, erpc_service_t service) -{ - erpc_remove_service_from_server(server, service); - destroy_Common_service(service); -} #ifdef __cplusplus } #endif diff --git a/test/test_enums/test_enums_client_impl.cpp b/test/test_enums/test_enums_client_impl.cpp index 10530f7d..fda78c0e 100644 --- a/test/test_enums/test_enums_client_impl.cpp +++ b/test/test_enums/test_enums_client_impl.cpp @@ -6,13 +6,19 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include "c_test_client.h" #include "gtest.h" -#include "test.h" +#include "unit_test_wrapped.h" //////////////////////////////////////////////////////////////////////////////// // Unit test Implementation code //////////////////////////////////////////////////////////////////////////////// +void initInterfaces(erpc_client_t client) +{ + initEnumsService_client(client); +} + enumColor enumColorA = green; enumColor enumColorB = red; diff --git a/test/test_enums/test_enums_server_impl.cpp b/test/test_enums/test_enums_server_impl.cpp index 9d437a83..7bd98846 100644 --- a/test/test_enums/test_enums_server_impl.cpp +++ b/test/test_enums/test_enums_server_impl.cpp @@ -8,13 +8,17 @@ #include "erpc_server_setup.h" -#include "test_server.h" -#include "test_unit_test_common_server.h" +#include "c_test_server.h" +#include "c_test_unit_test_common_server.h" +#include "test_server.hpp" #include "unit_test.h" #include "unit_test_wrapped.h" #include +using namespace erpc; +using namespace erpcShim; + EnumsService_service *svc; //////////////////////////////////////////////////////////////////////////////// @@ -75,6 +79,50 @@ enumErrorCode test_enumErrorCode_allDirection(enumErrorCode a, enumErrorCode b, return a; } +class EnumsService_server : public EnumsService_interface +{ +public: + void test_enumColor_in(enumColor a) { ::test_enumColor_in(a); } + + void test_enumColor_in2(enumColor b) { ::test_enumColor_in2(b); } + + void test_enumColor_out(enumColor *c) { ::test_enumColor_out(c); } + + void test_enumColor_inout(enumColor *e) { ::test_enumColor_inout(e); } + + enumColor test_enumColor_return(void) + { + enumColor result; + result = ::test_enumColor_return(); + + return result; + } + + enumColor test_enumColor_allDirection(enumColor a, enumColor b, enumColor *c, enumColor *e) + { + enumColor result; + result = ::test_enumColor_allDirection(a, b, c, e); + + return result; + } + + enumColor2 test_enumColor2_allDirection(enumColor2 a, enumColor2 b, enumColor2 *c, enumColor2 *e) + { + enumColor2 result; + result = ::test_enumColor2_allDirection(a, b, c, e); + + return result; + } + + enumErrorCode test_enumErrorCode_allDirection(enumErrorCode a, enumErrorCode b, enumErrorCode *c, enumErrorCode *e) + { + enumErrorCode result; + result = ::test_enumErrorCode_allDirection(a, b, c, e); + + return result; + } +}; + //////////////////////////////////////////////////////////////////////////////// // Add service to server code //////////////////////////////////////////////////////////////////////////////// @@ -83,7 +131,7 @@ void add_services(erpc::SimpleServer *server) { // define services to add on heap // allocate on heap so service doesn't go out of scope at end of method - svc = new EnumsService_service(); + svc = new EnumsService_service(new EnumsService_server()); // add services server->addService(svc); @@ -101,6 +149,7 @@ void remove_services(erpc::SimpleServer *server) server->removeService(svc); /* Delete unused service */ + delete svc->getHandler(); delete svc; } @@ -119,12 +168,6 @@ void remove_services_from_server(erpc_server_t server) erpc_remove_service_from_server(server, service_test); destroy_EnumsService_service(service_test); } - -void remove_common_services_from_server(erpc_server_t server, erpc_service_t service) -{ - erpc_remove_service_from_server(server, service); - destroy_Common_service(service); -} #ifdef __cplusplus } #endif diff --git a/test/test_lists/test_lists_client_impl.cpp b/test/test_lists/test_lists_client_impl.cpp index 22e44e80..f648712a 100644 --- a/test/test_lists/test_lists_client_impl.cpp +++ b/test/test_lists/test_lists_client_impl.cpp @@ -6,8 +6,9 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include "c_test_client.h" #include "gtest.h" -#include "test.h" +#include "unit_test_wrapped.h" #include @@ -17,6 +18,11 @@ using namespace std; // Unit test Implementation code //////////////////////////////////////////////////////////////////////////////// +void initInterfaces(erpc_client_t client) +{ + initPointersService_client(client); +} + TEST(test_list, SendReceivedInt32) { list_int32_1_t *received_list, send_list; diff --git a/test/test_lists/test_lists_server_impl.cpp b/test/test_lists/test_lists_server_impl.cpp index 8950ee43..7f5e517b 100644 --- a/test/test_lists/test_lists_server_impl.cpp +++ b/test/test_lists/test_lists_server_impl.cpp @@ -8,14 +8,18 @@ #include "erpc_server_setup.h" -#include "test_server.h" -#include "test_unit_test_common_server.h" +#include "c_test_server.h" +#include "c_test_unit_test_common_server.h" +#include "test_server.hpp" #include "unit_test.h" #include "unit_test_wrapped.h" #include #include +using namespace erpc; +using namespace erpcShim; + PointersService_service *svc; //////////////////////////////////////////////////////////////////////////////// @@ -309,6 +313,111 @@ int32_t sendGapAdvertisingData(const gapAdvertisingData_t *ad) return 33; } +class PointersService_server : public PointersService_interface +{ +public: + list_int32_1_t *sendReceivedInt32(const list_int32_1_t *listNumbers) + { + list_int32_1_t *result = NULL; + result = ::sendReceivedInt32(listNumbers); + + return result; + } + + list_int32_2_t *sendReceived2Int32(const list_int32_2_t *listNumbers) + { + list_int32_2_t *result = NULL; + result = ::sendReceived2Int32(listNumbers); + + return result; + } + + list_enumColor_1_t *sendReceivedEnum(const list_enumColor_1_t *listColors) + { + list_enumColor_1_t *result = NULL; + result = ::sendReceivedEnum(listColors); + + return result; + } + + list_enumColor_2_t *sendReceived2Enum(const list_enumColor_2_t *listColors) + { + list_enumColor_2_t *result = NULL; + result = ::sendReceived2Enum(listColors); + + return result; + } + + list_C_1_t *sendReceivedStruct(const list_C_1_t *listColors) + { + list_C_1_t *result = NULL; + result = ::sendReceivedStruct(listColors); + + return result; + } + + list_C_2_t *sendReceived2Struct(const list_C_2_t *listColors) + { + list_C_2_t *result = NULL; + result = ::sendReceived2Struct(listColors); + + return result; + } + + list_string_1_t *sendReceivedString(const list_string_1_t *listNumbers) + { + list_string_1_t *result = NULL; + result = ::sendReceivedString(listNumbers); + + return result; + } + + list_string_2_t *sendReceived2String(const list_string_2_t *listNumbers) + { + list_string_2_t *result = NULL; + result = ::sendReceived2String(listNumbers); + + return result; + } + + void test_list_allDirection(const list_uint32_1_t *a, const list_uint32_1_t *b, list_uint32_1_t *e) + { + ::test_list_allDirection(a, b, e); + } + + int32_t testLengthAnnotation(const int32_t *myList, uint32_t len) + { + int32_t result; + result = ::testLengthAnnotation(myList, len); + + return result; + } + + int32_t testLengthAnnotationInStruct(const listStruct *s) + { + int32_t result; + result = ::testLengthAnnotationInStruct(s); + + return result; + } + + listStruct *returnSentStructLengthAnnotation(const listStruct *s) + { + listStruct *result = NULL; + result = ::returnSentStructLengthAnnotation(s); + + return result; + } + + int32_t sendGapAdvertisingData(const gapAdvertisingData_t *ad) + { + int32_t result; + result = ::sendGapAdvertisingData(ad); + + return result; + } +}; + //////////////////////////////////////////////////////////////////////////////// // Add service to server code //////////////////////////////////////////////////////////////////////////////// @@ -317,7 +426,7 @@ void add_services(erpc::SimpleServer *server) { // define services to add on heap // allocate on heap so service doesn't go out of scope at end of method - svc = new PointersService_service(); + svc = new PointersService_service(new PointersService_server()); // add services server->addService(svc); @@ -335,6 +444,7 @@ void remove_services(erpc::SimpleServer *server) server->removeService(svc); /* Delete unused service */ + delete svc->getHandler(); delete svc; } @@ -354,11 +464,6 @@ void remove_services_from_server(erpc_server_t server) destroy_PointersService_service(service_test); } -void remove_common_services_from_server(erpc_server_t server, erpc_service_t service) -{ - erpc_remove_service_from_server(server, service); - destroy_Common_service(service); -} #ifdef __cplusplus } #endif diff --git a/test/test_shared/test_shared_client_impl.cpp b/test/test_shared/test_shared_client_impl.cpp index db39dfc2..8fea5a99 100644 --- a/test/test_shared/test_shared_client_impl.cpp +++ b/test/test_shared/test_shared_client_impl.cpp @@ -5,13 +5,19 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include "c_test_client.h" #include "gtest.h" -#include "test.h" +#include "unit_test_wrapped.h" //////////////////////////////////////////////////////////////////////////////// // Unit test Implementation code //////////////////////////////////////////////////////////////////////////////// +void initInterfaces(erpc_client_t client) +{ + initSharedService_client(client); +} + TEST(test_shared, sendReceiveBaseSharedStruct) { BaseSharedStruct sm = { 4, 5 }; diff --git a/test/test_shared/test_shared_server_impl.cpp b/test/test_shared/test_shared_server_impl.cpp index 5b3b9fb7..5890d6f8 100644 --- a/test/test_shared/test_shared_server_impl.cpp +++ b/test/test_shared/test_shared_server_impl.cpp @@ -7,13 +7,17 @@ #include "erpc_server_setup.h" -#include "test_server.h" -#include "test_unit_test_common_server.h" +#include "c_test_server.h" +#include "c_test_unit_test_common_server.h" +#include "test_server.hpp" #include "unit_test.h" #include "unit_test_wrapped.h" #include +using namespace erpc; +using namespace erpcShim; + SharedService_service *svc; //////////////////////////////////////////////////////////////////////////////// @@ -29,6 +33,20 @@ BaseSharedStruct *sendReceiveBaseSharedStruct(const BaseSharedStruct *s) void inoutBaseSharedStruct(BaseSharedStruct **s) {} /* end typedef unit tests */ +class SharedService_server : public SharedService_interface +{ +public: + BaseSharedStruct *sendReceiveBaseSharedStruct(const BaseSharedStruct *a) + { + BaseSharedStruct *result = NULL; + result = ::sendReceiveBaseSharedStruct(a); + + return result; + } + + void inoutBaseSharedStruct(BaseSharedStruct **a) { ::inoutBaseSharedStruct(a); } +}; + //////////////////////////////////////////////////////////////////////////////// // Add service to server code //////////////////////////////////////////////////////////////////////////////// @@ -37,7 +55,7 @@ void add_services(erpc::SimpleServer *server) { // define services to add on heap // allocate on heap so service doesn't go out of scope at end of method - svc = new SharedService_service(); + svc = new SharedService_service(new SharedService_server()); // add services server->addService(svc); @@ -55,6 +73,7 @@ void remove_services(erpc::SimpleServer *server) server->removeService(svc); /* Delete unused service */ + delete svc->getHandler(); delete svc; } @@ -74,11 +93,6 @@ void remove_services_from_server(erpc_server_t server) destroy_SharedService_service(service_test); } -void remove_common_services_from_server(erpc_server_t server, erpc_service_t service) -{ - erpc_remove_service_from_server(server, service); - destroy_Common_service(service); -} #ifdef __cplusplus } #endif diff --git a/test/test_struct/test_struct_client_impl.cpp b/test/test_struct/test_struct_client_impl.cpp index bcb87b8c..7fbdd9f1 100644 --- a/test/test_struct/test_struct_client_impl.cpp +++ b/test/test_struct/test_struct_client_impl.cpp @@ -6,8 +6,9 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include "c_test_ArithmeticService_client.h" #include "gtest.h" -#include "test_ArithmeticService.h" +#include "unit_test_wrapped.h" #include @@ -17,6 +18,12 @@ using namespace std; // Unit test Implementation code //////////////////////////////////////////////////////////////////////////////// +void initInterfaces(erpc_client_t client) +{ + initArithmeticService1_client(client); + initArithmeticService2_client(client); +} + TEST(test_struct, GetMember1) { C c = { 4, 5 }; diff --git a/test/test_struct/test_struct_server_impl.cpp b/test/test_struct/test_struct_server_impl.cpp index 27ebbae5..9214bcfd 100644 --- a/test/test_struct/test_struct_server_impl.cpp +++ b/test/test_struct/test_struct_server_impl.cpp @@ -8,14 +8,18 @@ #include "erpc_server_setup.h" -#include "test_ArithmeticService_server.h" -#include "test_unit_test_common_server.h" +#include "c_test_ArithmeticService_server.h" +#include "c_test_unit_test_common_server.h" +#include "test_ArithmeticService_server.hpp" #include "unit_test.h" #include "unit_test_wrapped.h" #include #include +using namespace erpc; +using namespace erpcShim; + ArithmeticService1_service *svc1; ArithmeticService2_service *svc2; @@ -179,6 +183,131 @@ bool testSendingByrefMembers(const StructWithByrefMembers *s) return false; } +class ArithmeticService1_server : public ArithmeticService1_interface +{ +public: + int32_t getMember(const C *c) + { + int32_t result; + result = ::getMember(c); + + return result; + } + + B *returnStruct(float a, float b) + { + B *result = NULL; + result = ::returnStruct(a, b); + + return result; + } + + B *getMemberTest2(const A *a) + { + B *result = NULL; + result = ::getMemberTest2(a); + + return result; + } + + int32_t sendNestedStruct(const D *d) + { + int32_t result; + result = ::sendNestedStruct(d); + + return result; + } + + int32_t checkString(const primate *p) + { + int32_t result; + result = ::checkString(p); + + return result; + } + + stringStruct *returnStrings(void) + { + stringStruct *result = NULL; + result = ::returnStrings(); + + return result; + } +}; + +class ArithmeticService2_server : public ArithmeticService2_interface +{ +public: + int32_t sendManyInts(const F *f) + { + int32_t result; + result = ::sendManyInts(f); + + return result; + } + + int32_t sendManyUInts(const G *g) + { + int32_t result; + result = ::sendManyUInts(g); + + return result; + } + + char *getStudentName(const student *stud) + { + char *result = NULL; + result = ::getStudentName(stud); + + return result; + } + + float getStudentTestAverage(const student *stud) + { + float result; + result = ::getStudentTestAverage(stud); + + return result; + } + + int32_t getStudentYear(const student *stud) + { + int32_t result; + result = ::getStudentYear(stud); + + return result; + } + + int32_t getStudentAge(const student *stud) + { + int32_t result; + result = ::getStudentAge(stud); + + return result; + } + + student *createStudent(const char *name, const float test_scores[3], school_year_t year, int32_t age) + { + student *result = NULL; + result = ::createStudent(name, test_scores, year, age); + + return result; + } + + void test_struct_allDirection(const AllTypes *a, const AllTypes *b, AllTypes *e) + { + ::test_struct_allDirection(a, b, e); + } + + bool testSendingByrefMembers(const StructWithByrefMembers *s) + { + bool result; + result = ::testSendingByrefMembers(s); + + return result; + } +}; + //////////////////////////////////////////////////////////////////////////////// // Add service to server code //////////////////////////////////////////////////////////////////////////////// @@ -187,8 +316,8 @@ void add_services(erpc::SimpleServer *server) { // define services to add on heap // allocate on heap so service doesn't go out of scope at end of method - svc1 = new ArithmeticService1_service(); - svc2 = new ArithmeticService2_service(); + svc1 = new ArithmeticService1_service(new ArithmeticService1_server()); + svc2 = new ArithmeticService2_service(new ArithmeticService2_server()); // add services server->addService(svc1); @@ -208,6 +337,8 @@ void remove_services(erpc::SimpleServer *server) server->removeService(svc2); /* Delete unused service */ + delete svc1->getHandler(); + delete svc2->getHandler(); delete svc1; delete svc2; } @@ -233,11 +364,6 @@ void remove_services_from_server(erpc_server_t server) destroy_ArithmeticService2_service(service2); } -void remove_common_services_from_server(erpc_server_t server, erpc_service_t service) -{ - erpc_remove_service_from_server(server, service); - destroy_Common_service(service); -} #ifdef __cplusplus } #endif diff --git a/test/test_typedef/test_typedef_client_impl.cpp b/test/test_typedef/test_typedef_client_impl.cpp index 7138825d..64ebeb30 100644 --- a/test/test_typedef/test_typedef_client_impl.cpp +++ b/test/test_typedef/test_typedef_client_impl.cpp @@ -6,8 +6,9 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include "c_test_client.h" #include "gtest.h" -#include "test.h" +#include "unit_test_wrapped.h" #include @@ -15,6 +16,11 @@ // Unit test Implementation code //////////////////////////////////////////////////////////////////////////////// +void initInterfaces(erpc_client_t client) +{ + initTypedefService_client(client); +} + TEST(test_typedef, SendReceiveInt) { int32type a = 10, b = 2 * a + 1, pB; diff --git a/test/test_typedef/test_typedef_server_impl.cpp b/test/test_typedef/test_typedef_server_impl.cpp index c1e02bd6..eeeabca9 100644 --- a/test/test_typedef/test_typedef_server_impl.cpp +++ b/test/test_typedef/test_typedef_server_impl.cpp @@ -8,14 +8,18 @@ #include "erpc_server_setup.h" -#include "test_server.h" -#include "test_unit_test_common_server.h" +#include "c_test_server.h" +#include "c_test_unit_test_common_server.h" +#include "test_server.hpp" #include "unit_test.h" #include "unit_test_wrapped.h" #include #include +using namespace erpc; +using namespace erpcShim; + TypedefService_service *svc; //////////////////////////////////////////////////////////////////////////////// @@ -129,6 +133,58 @@ MultiListArray arrayNumbers, uint32_t arrayNumbers_1_count, uint32_t arrayNumber }*/ /* end typedef unit tests */ +class TypedefService_server : public TypedefService_interface +{ +public: + int32type sendReceiveInt(int32type a) + { + int32type result; + result = ::sendReceiveInt(a); + + return result; + } + + Colors sendReceiveEnum(Colors a) + { + Colors result; + result = ::sendReceiveEnum(a); + + return result; + } + + B *sendReceiveStruct(const B *a) + { + B *result = NULL; + result = ::sendReceiveStruct(a); + + return result; + } + + ListType *sendReceiveListType(const ListType *listNumbers) + { + ListType *result = NULL; + result = ::sendReceiveListType(listNumbers); + + return result; + } + + ListType2 *sendReceive2ListType(const ListType2 *listNumbers) + { + ListType2 *result = NULL; + result = ::sendReceive2ListType(listNumbers); + + return result; + } + + newString sendReceiveString(newString hello) + { + newString result = NULL; + result = ::sendReceiveString(hello); + + return result; + } +}; + //////////////////////////////////////////////////////////////////////////////// // Add service to server code //////////////////////////////////////////////////////////////////////////////// @@ -137,7 +193,7 @@ void add_services(erpc::SimpleServer *server) { // define services to add on heap // allocate on heap so service doesn't go out of scope at end of method - svc = new TypedefService_service(); + svc = new TypedefService_service(new TypedefService_server()); // add services server->addService(svc); @@ -155,6 +211,7 @@ void remove_services(erpc::SimpleServer *server) server->removeService(svc); /* Delete unused service */ + delete svc->getHandler(); delete svc; } @@ -174,11 +231,6 @@ void remove_services_from_server(erpc_server_t server) destroy_TypedefService_service(service_test); } -void remove_common_services_from_server(erpc_server_t server, erpc_service_t service) -{ - erpc_remove_service_from_server(server, service); - destroy_Common_service(service); -} #ifdef __cplusplus } #endif diff --git a/test/test_unions/test_unions_client_impl.cpp b/test/test_unions/test_unions_client_impl.cpp index 167374e7..17d29af3 100644 --- a/test/test_unions/test_unions_client_impl.cpp +++ b/test/test_unions/test_unions_client_impl.cpp @@ -6,8 +6,9 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include "c_test_client.h" #include "gtest.h" -#include "test.h" +#include "unit_test_wrapped.h" #include @@ -17,6 +18,11 @@ using namespace std; // Unit test Implementation code //////////////////////////////////////////////////////////////////////////////// +void initInterfaces(erpc_client_t client) +{ + initArithmeticService_client(client); +} + TEST(test_unions, testGenericCallback) { gapGenericEvent_t event = { diff --git a/test/test_unions/test_unions_server_impl.cpp b/test/test_unions/test_unions_server_impl.cpp index 457d9957..ea53611b 100644 --- a/test/test_unions/test_unions_server_impl.cpp +++ b/test/test_unions/test_unions_server_impl.cpp @@ -8,14 +8,18 @@ #include "erpc_server_setup.h" -#include "test_server.h" -#include "test_unit_test_common_server.h" +#include "c_test_server.h" +#include "c_test_unit_test_common_server.h" +#include "test_server.hpp" #include "unit_test.h" #include "unit_test_wrapped.h" #include #include +using namespace erpc; +using namespace erpcShim; + ArithmeticService_service *svc; //////////////////////////////////////////////////////////////////////////////// @@ -207,6 +211,42 @@ InnerList *testInnerList(const InnerList *il) return newList; } +class ArithmeticService_server : public ArithmeticService_interface +{ +public: + gapGenericEvent_t *testGenericCallback(const gapGenericEvent_t *event) + { + gapGenericEvent_t *result = NULL; + result = ::testGenericCallback(event); + + return result; + } + + foo *sendMyFoo(const foo *f) + { + foo *result = NULL; + result = ::sendMyFoo(f); + + return result; + } + + foo *sendMyUnion(fruit discriminator, const unionType *unionVariable) + { + foo *result = NULL; + result = ::sendMyUnion(discriminator, unionVariable); + + return result; + } + + InnerList *testInnerList(const InnerList *il) + { + InnerList *result = NULL; + result = ::testInnerList(il); + + return result; + } +}; + //////////////////////////////////////////////////////////////////////////////// // Add service to server code //////////////////////////////////////////////////////////////////////////////// @@ -215,7 +255,7 @@ void add_services(erpc::SimpleServer *server) { // define services to add on heap // allocate on heap so service doesn't go out of scope at end of method - svc = new ArithmeticService_service(); + svc = new ArithmeticService_service(new ArithmeticService_server()); // add services server->addService(svc); @@ -233,6 +273,7 @@ void remove_services(erpc::SimpleServer *server) server->removeService(svc); /* Delete unused service */ + delete svc->getHandler(); delete svc; } @@ -252,11 +293,6 @@ void remove_services_from_server(erpc_server_t server) destroy_ArithmeticService_service(service_test); } -void remove_common_services_from_server(erpc_server_t server, erpc_service_t service) -{ - erpc_remove_service_from_server(server, service); - destroy_Common_service(service); -} #ifdef __cplusplus } #endif