text: // ----------------------------------------------------------------------------
  // Copyright 2016-2017 ARM Ltd.
  //  
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //  
  //     http://www.apache.org/licenses/LICENSE-2.0
  //  
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  // ----------------------------------------------------------------------------
  
  /* Logging macros */
  
  #ifndef __PV_LOG_H__
  #define __PV_LOG_H__
  
  #ifdef __cplusplus
  extern "C" {
  #endif
  
  #define __PV_LOG_H__INSIDE
  #include <stdio.h>
  #include <inttypes.h>
  #include <string.h>
  #include <stdbool.h>
  #include "pal.h"
  #include "mbed-trace/mbed_trace.h"
  
  #define __SA_PV_FILE__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
  
  extern palMutexID_t g_pv_logger_mutex;
  /**
  * Calls to mbed trace print function
  *
  * - The function sets mbed trace level according to log level, compose buffer with general data (line,color, file..) and message
  * and calls to mbed_vtracef.
  */
  void pv_log_trace(int level, const char* filename, int line, const char *func, const char *format, ...);
  /**
  * Print buffer with mbed trace function
  *
  */
  void pv_log_trace_buffer(int level, const char* filename, int line, const char *func, const char *color, const char *name, const uint8_t *buff, uint32_t buff_size);
  
  #define _SA_PV_LOG_FUNC_ENTER(level, filename, line, func, format, ...) _SA_PV_LOG(level, filename, line, func, "===> " format, ##__VA_ARGS__)
  
  /**  Exit function logging
   *
   * - Should be called in the end of a function, assuming the function doesn't exit early due to an error.
   * - Should display values of output variables (with meaning, no need to print buffers).
   * - Usage example (with INFO level): SA_PV_LOG_INFO_FUNC_EXIT("argPointerToInt = %d, argPointerToUnsigned32 = %" PRIu32 "", *argPointerToInt, (uint32_t)*argPointerToUnsigned32);
   */
  #define _SA_PV_LOG_FUNC_EXIT(level, filename, line, func, format, ...) _SA_PV_LOG(level, filename, line, func, "<=== " format, ##__VA_ARGS__)
  
  // CRITICAL always being output
  #define SA_PV_LOG_CRITICAL(format, ...) \
          _SA_PV_LOG(TRACE_LEVEL_CMD, __SA_PV_FILE__, __LINE__, __func__, format, ##__VA_ARGS__)
  #define SA_PV_LOG_BYTE_BUFF_CRITICAL(name, buff, buff_size) \
          _SA_PV_BYTE_BUFF_LOG(TRACE_LEVEL_CMD, __SA_PV_FILE__, __LINE__, __func__, name, buff, buff_size)
  #define SA_PV_LOG_CRITICAL_FUNC_EXIT(format, ...) \
          _SA_PV_LOG_FUNC_EXIT(TRACE_LEVEL_CMD, __SA_PV_FILE__, __LINE__, __func__, format, ##__VA_ARGS__)
  
  #if (MBED_TRACE_MAX_LEVEL >= TRACE_LEVEL_ERROR)
  #define SA_PV_LOG_ERR(format, ...) \
          _SA_PV_LOG(TRACE_LEVEL_ERROR, __SA_PV_FILE__, __LINE__, __func__, format, ##__VA_ARGS__)
  #define SA_PV_LOG_BYTE_BUFF_ERR(name, buff, buff_size) \
          _SA_PV_BYTE_BUFF_LOG(TRACE_LEVEL_ERROR, __SA_PV_FILE__, __LINE__, __func__, name, buff, buff_size)
  #define SA_PV_LOG_ERR_FUNC_EXIT(format, ...) \
          _SA_PV_LOG_FUNC_EXIT(TRACE_LEVEL_ERROR, __SA_PV_FILE__, __LINE__, __func__, format, ##__VA_ARGS__)
  
  #else
  #define SA_PV_LOG_ERR(format, arg...) do {} while (0)
  #define SA_PV_LOG_BYTE_BUFF_ERR(format, arg...) do {} while (0)
  #define SA_PV_LOG_ERR_FUNC_EXIT(format, ...) do {} while (0)
  #endif
  
  #if (MBED_TRACE_MAX_LEVEL >= TRACE_LEVEL_WARN)
  #define SA_PV_LOG_WARN(format, ...) \
          _SA_PV_LOG(TRACE_LEVEL_WARN, __SA_PV_FILE__, __LINE__, __func__, format, ##__VA_ARGS__)
  #define SA_PV_LOG_BYTE_BUFF_WARN(name, buff, buff_size) \
          _SA_PV_BYTE_BUFF_LOG(TRACE_LEVEL_WARN, __SA_PV_FILE__, __LINE__, __func__, name, buff, buff_size)
  #define SA_PV_LOG_WARN_FUNC_EXIT(format, ...) \
          _SA_PV_LOG_FUNC_EXIT(TRACE_LEVEL_WARN, __SA_PV_FILE__, __LINE__, __func__, format, ##__VA_ARGS__)
  #else
  #define SA_PV_LOG_WARN(format, ...) do {} while (0)
  #define SA_PV_LOG_BYTE_BUFF_WARN(format, ...) do {} while (0)
  #define SA_PV_LOG_WARN_FUNC_EXIT(format, ...) do {} while (0)
  #endif
  
  #if (MBED_TRACE_MAX_LEVEL >= TRACE_LEVEL_INFO)
  #define SA_PV_LOG_INFO(format, ...) \
          _SA_PV_LOG(TRACE_LEVEL_INFO, __SA_PV_FILE__, __LINE__, __func__, format, ##__VA_ARGS__)
  #define SA_PV_LOG_INFO_FUNC_ENTER(format, ...) \
          _SA_PV_LOG_FUNC_ENTER(TRACE_LEVEL_INFO, __SA_PV_FILE__, __LINE__, __func__, format, ##__VA_ARGS__)
  #define SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS() \
          SA_PV_LOG_INFO_FUNC_ENTER("")
  #define SA_PV_LOG_INFO_FUNC_EXIT(format, ...) \
          _SA_PV_LOG_FUNC_EXIT(TRACE_LEVEL_INFO, __SA_PV_FILE__, __LINE__, __func__, format, ##__VA_ARGS__)
  #define SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS() \
          SA_PV_LOG_INFO_FUNC_EXIT("")
  #define SA_PV_LOG_BYTE_BUFF_INFO(name, buff, buff_size) \
          _SA_PV_BYTE_BUFF_LOG(TRACE_LEVEL_INFO, __SA_PV_FILE__, __LINE__, __func__, name, buff, buff_size)
  #else
  #define SA_PV_LOG_INFO(format, ...) do {} while (0)
  #define SA_PV_LOG_INFO_FUNC_ENTER(format, ...) do {} while (0)
  #define SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS() do {} while (0)
  #define SA_PV_LOG_INFO_FUNC_EXIT(format, ...) do {} while (0)
  #define SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS() do {} while (0)
  #define SA_PV_LOG_BYTE_BUFF_INFO(format, ...) do {} while (0)
  #endif
  
  #if (MBED_TRACE_MAX_LEVEL >= TRACE_LEVEL_DEBUG)
  #define SA_PV_LOG_TRACE(format, ...) \
          _SA_PV_LOG(TRACE_LEVEL_DEBUG, __SA_PV_FILE__, __LINE__, __func__, format, ##__VA_ARGS__)
  #define SA_PV_LOG_TRACE_FUNC_ENTER(format, ...) \
          _SA_PV_LOG_FUNC_ENTER(TRACE_LEVEL_DEBUG, __SA_PV_FILE__, __LINE__, __func__, format, ##__VA_ARGS__)
  #define SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS() \
          SA_PV_LOG_TRACE_FUNC_ENTER("")
  #define SA_PV_LOG_TRACE_FUNC_EXIT(format, ...) \
          _SA_PV_LOG_FUNC_EXIT(TRACE_LEVEL_DEBUG, __SA_PV_FILE__, __LINE__, __func__, format, ##__VA_ARGS__)
  #define SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS() \
          SA_PV_LOG_TRACE_FUNC_EXIT("")
  #define SA_PV_LOG_BYTE_BUFF_TRACE(name, buff, buff_size) \
          _SA_PV_BYTE_BUFF_LOG(TRACE_LEVEL_DEBUG, __SA_PV_FILE__, __LINE__, __func__, name, buff, buff_size)
  
  #else
  #define SA_PV_LOG_TRACE(format, ...) do {} while (0)
  #define SA_PV_LOG_TRACE_FUNC_ENTER(format, ...) do {} while (0)
  #define SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS() do {} while (0)
  #define SA_PV_LOG_TRACE_FUNC_EXIT(format, ...) do {} while (0)
  #define SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS() do {} while (0)
  #define SA_PV_LOG_BYTE_BUFF_TRACE(format, ...) do {} while (0)
  #endif
  
  #if (MBED_TRACE_MAX_LEVEL >= TRACE_LEVEL_DEBUG)
  #define SA_PV_LOG_DATA(format, ...) \
          _SA_PV_LOG(TRACE_LEVEL_DEBUG, __SA_PV_FILE__, __LINE__, __func__, format, ##__VA_ARGS__)
  #define SA_PV_LOG_DATA_FUNC_ENTER(format, ...) \
    _SA_PV_LOG_FUNC_ENTER(TRACE_LEVEL_DEBUG, __SA_PV_FILE__, __LINE__, __func__, format, ##__VA_ARGS__)
  #define SA_PV_LOG_DATA_FUNC_ENTER_NO_ARGS() \
          SA_PV_LOG_DATA_FUNC_ENTER("")
  #define SA_PV_LOG_DATA_FUNC_EXIT(format, ...) \
          _SA_PV_LOG_FUNC_EXIT(TRACE_LEVEL_DEBUG, __SA_PV_FILE__, __LINE__, __func__, format, ##__VA_ARGS__)
  #define SA_PV_LOG_DATA_FUNC_EXIT_NO_ARGS() \
          SA_PV_LOG_DATA_FUNC_EXIT("")
  #define SA_PV_LOG_BYTE_BUFF_DATA(name, buff, buff_size) \
          _SA_PV_BYTE_BUFF_LOG(TRACE_LEVEL_DEBUG, __SA_PV_FILE__, __LINE__, __func__, name, buff, buff_size)
  #else
  #define SA_PV_LOG_DATA(format, ...) do {} while (0)
  #define SA_PV_LOG_DATA_FUNC_ENTER(format, ...) do {} while (0)
  #define SA_PV_LOG_DATA_FUNC_ENTER_NO_ARGS() do {} while (0)
  #define SA_PV_LOG_DATA_FUNC_EXIT(format, ...) do {} while (0)
  #define SA_PV_LOG_DATA_FUNC_EXIT_NO_ARGS() do {} while (0)
  #define SA_PV_LOG_BYTE_BUFF_DATA(format, ...) do {} while (0)
  #endif
  
  /* Should only be called once, additional calls do nothing. */
  #define _SA_PV_LOG(level, file, line, func, format, ...) \
  do{ \
          mbed_tracef(level, "fcc","%s:%d:%s:" format, file, line, func, ##__VA_ARGS__);\
  } while (0)
  
  #define _SA_PV_BYTE_BUFF_LOG(level, file, line, func, name, buff, buff_size) ( mbed_tracef(level, "fcc", "%s"name, mbed_trace_array(buff, buff_size)))
  
  #undef __PV_LOG_H__INSIDE
  
  #ifdef __cplusplus
  }
  #endif
  #endif /*__PV_LOG_H__*/
  
  