Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of azure_c_shared_utility by
xlogging.h
00001 // Copyright (c) Microsoft. All rights reserved. 00002 // Licensed under the MIT license. See LICENSE file in the project root for full license information. 00003 00004 #ifndef XLOGGING_H 00005 #define XLOGGING_H 00006 00007 #include "azure_c_shared_utility/agenttime.h" 00008 #include "azure_c_shared_utility/optimize_size.h" 00009 00010 #if defined(ESP8266_RTOS) 00011 #include "c_types.h" 00012 #endif 00013 00014 #if defined(ARDUINO_ARCH_ESP8266) 00015 #include "esp8266/azcpgmspace.h" 00016 #endif 00017 00018 #ifdef __cplusplus 00019 #include <cstdio> 00020 extern "C" { 00021 #else 00022 #include <stdio.h> 00023 #endif /* __cplusplus */ 00024 00025 #ifdef TIZENRT 00026 #undef LOG_INFO 00027 #endif 00028 00029 typedef enum LOG_CATEGORY_TAG 00030 { 00031 AZ_LOG_ERROR, 00032 AZ_LOG_INFO, 00033 AZ_LOG_TRACE 00034 } LOG_CATEGORY; 00035 00036 #if defined _MSC_VER 00037 #define FUNC_NAME __FUNCDNAME__ 00038 #else 00039 #define FUNC_NAME __func__ 00040 #endif 00041 00042 typedef void(*LOGGER_LOG)(LOG_CATEGORY log_category, const char* file, const char* func, int line, unsigned int options, const char* format, ...); 00043 typedef void(*LOGGER_LOG_GETLASTERROR)(const char* file, const char* func, int line, const char* format, ...); 00044 00045 #define LOG_NONE 0x00 00046 #define LOG_LINE 0x01 00047 00048 /*no logging is useful when time and fprintf are mocked*/ 00049 #ifdef NO_LOGGING 00050 #define LOG(...) 00051 #define LogInfo(...) 00052 #define LogError(...) 00053 #define xlogging_get_log_function() NULL 00054 #define xlogging_set_log_function(...) 00055 #define LogErrorWinHTTPWithGetLastErrorAsString(...) 00056 #define UNUSED(x) (void)(x) 00057 #elif (defined MINIMAL_LOGERROR) 00058 #define LOG(...) 00059 #define LogInfo(...) 00060 #define LogError(...) printf("error %s: line %d\n",__FILE__,__LINE__); 00061 #define xlogging_get_log_function() NULL 00062 #define xlogging_set_log_function(...) 00063 #define LogErrorWinHTTPWithGetLastErrorAsString(...) 00064 #define UNUSED(x) (void)(x) 00065 00066 #elif defined(ESP8266_RTOS) 00067 #define LogInfo(FORMAT, ...) do { \ 00068 static const char flash_str[] ICACHE_RODATA_ATTR STORE_ATTR = FORMAT; \ 00069 printf(flash_str, ##__VA_ARGS__); \ 00070 printf("\n");\ 00071 } while((void)0,0) 00072 00073 #define LogError LogInfo 00074 #define LOG(log_category, log_options, FORMAT, ...) { \ 00075 static const char flash_str[] ICACHE_RODATA_ATTR STORE_ATTR = (FORMAT); \ 00076 printf(flash_str, ##__VA_ARGS__); \ 00077 printf("\r\n"); \ 00078 } 00079 00080 00081 #elif defined(ARDUINO_ARCH_ESP8266) 00082 /* 00083 The ESP8266 compiler doesn't do a good job compiling this code; it doesn't understand that the 'format' is 00084 a 'const char*' and moves it to RAM as a global variable, increasing the .bss size. So we create a 00085 specific LogInfo that explicitly pins the 'format' on the PROGMEM (flash) using a _localFORMAT variable 00086 with the macro PSTR. 00087 #define ICACHE_FLASH_ATTR __attribute__((section(".irom0.text"))) 00088 #define PROGMEM ICACHE_RODATA_ATTR 00089 #define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];})) 00090 const char* __localFORMAT = PSTR(FORMAT); 00091 On the other hand, vsprintf does not support the pinned 'format' and os_printf does not work with va_list, 00092 so we compacted the log in the macro LogInfo. 00093 */ 00094 #define LOG(log_category, log_options, FORMAT, ...) { \ 00095 const char* __localFORMAT = PSTR(FORMAT); \ 00096 os_printf(__localFORMAT, ##__VA_ARGS__); \ 00097 os_printf("\r\n"); \ 00098 } 00099 00100 #define LogInfo(FORMAT, ...) { \ 00101 const char* __localFORMAT = PSTR(FORMAT); \ 00102 os_printf(__localFORMAT, ##__VA_ARGS__); \ 00103 os_printf("\r\n"); \ 00104 } 00105 #define LogError LogInfo 00106 00107 #else /* !ARDUINO_ARCH_ESP8266 */ 00108 00109 #if defined _MSC_VER 00110 #define LOG(log_category, log_options, format, ...) { LOGGER_LOG l = xlogging_get_log_function(); if (l != NULL) l(log_category, __FILE__, FUNC_NAME, __LINE__, log_options, format, __VA_ARGS__); } 00111 #else 00112 #define LOG(log_category, log_options, format, ...) { LOGGER_LOG l = xlogging_get_log_function(); if (l != NULL) l(log_category, __FILE__, FUNC_NAME, __LINE__, log_options, format, ##__VA_ARGS__); } 00113 #endif 00114 00115 #if defined _MSC_VER 00116 #define LogInfo(FORMAT, ...) do{LOG(AZ_LOG_INFO, LOG_LINE, FORMAT, __VA_ARGS__); }while((void)0,0) 00117 #else 00118 #define LogInfo(FORMAT, ...) do{LOG(AZ_LOG_INFO, LOG_LINE, FORMAT, ##__VA_ARGS__); }while((void)0,0) 00119 #endif 00120 00121 #if defined _MSC_VER 00122 00123 #if !defined(WINCE) 00124 extern void xlogging_set_log_function_GetLastError(LOGGER_LOG_GETLASTERROR log_function); 00125 extern LOGGER_LOG_GETLASTERROR xlogging_get_log_function_GetLastError(void); 00126 #define LogLastError(FORMAT, ...) do{ LOGGER_LOG_GETLASTERROR l = xlogging_get_log_function_GetLastError(); if(l!=NULL) l(__FILE__, FUNC_NAME, __LINE__, FORMAT, __VA_ARGS__); }while((void)0,0) 00127 #endif 00128 00129 #define LogError(FORMAT, ...) do{ LOG(AZ_LOG_ERROR, LOG_LINE, FORMAT, __VA_ARGS__); }while((void)0,0) 00130 #define TEMP_BUFFER_SIZE 1024 00131 #define MESSAGE_BUFFER_SIZE 260 00132 #define LogErrorWinHTTPWithGetLastErrorAsString(FORMAT, ...) do { \ 00133 DWORD errorMessageID = GetLastError(); \ 00134 char messageBuffer[MESSAGE_BUFFER_SIZE]; \ 00135 LogError(FORMAT, __VA_ARGS__); \ 00136 if (errorMessageID == 0) \ 00137 {\ 00138 LogError("GetLastError() returned 0. Make sure you are calling this right after the code that failed. "); \ 00139 } \ 00140 else\ 00141 {\ 00142 int size = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, \ 00143 GetModuleHandle("WinHttp"), errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), messageBuffer, MESSAGE_BUFFER_SIZE, NULL); \ 00144 if (size == 0)\ 00145 {\ 00146 size = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), messageBuffer, MESSAGE_BUFFER_SIZE, NULL); \ 00147 if (size == 0)\ 00148 {\ 00149 LogError("GetLastError Code: %d. ", errorMessageID); \ 00150 }\ 00151 else\ 00152 {\ 00153 LogError("GetLastError: %s.", messageBuffer); \ 00154 }\ 00155 }\ 00156 else\ 00157 {\ 00158 LogError("GetLastError: %s.", messageBuffer); \ 00159 }\ 00160 }\ 00161 } while((void)0,0) 00162 #else 00163 #define LogError(FORMAT, ...) do{ LOG(AZ_LOG_ERROR, LOG_LINE, FORMAT, ##__VA_ARGS__); }while((void)0,0) 00164 #endif 00165 00166 extern void xlogging_set_log_function(LOGGER_LOG log_function); 00167 extern LOGGER_LOG xlogging_get_log_function(void); 00168 00169 #endif /* ARDUINO_ARCH_ESP8266 */ 00170 00171 00172 /** 00173 * @brief Print the memory content byte pre byte in hexadecimal and as a char it the byte correspond to any printable ASCII chars. 00174 * 00175 * This function prints the 'size' bytes in the 'buf' to the log. It will print in portions of 16 bytes, 00176 * and will print the byte as a hexadecimal value, and, it is a printable, this function will print 00177 * the correspondent ASCII character. 00178 * Non printable characters will shows as a single '.'. 00179 * For this function, printable characters are all characters between ' ' (0x20) and '~' (0x7E). 00180 * 00181 * @param buf Pointer to the memory address with the buffer to print. 00182 * @param size Number of bytes to print. 00183 */ 00184 extern void xlogging_dump_buffer(const void* buf, size_t size); 00185 00186 #ifdef __cplusplus 00187 } // extern "C" 00188 #endif /* __cplusplus */ 00189 00190 #endif /* XLOGGING_H */
Generated on Tue Jul 12 2022 19:14:38 by
