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.
Dependents: STM32F746_iothub_client_sample_mqtt f767zi_mqtt iothub_client_sample_amqp iothub_client_sample_http ... more
consolelogger.c
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 #include <stdarg.h> 00005 #include <stdio.h> 00006 #include <time.h> 00007 #include "azure_c_shared_utility/xlogging.h" 00008 #include "azure_c_shared_utility/consolelogger.h" 00009 00010 #if (defined(_MSC_VER)) && (!(defined WINCE)) 00011 #include "windows.h" 00012 00013 /*returns a string as if printed by vprintf*/ 00014 static char* vprintf_alloc(const char* format, va_list va) 00015 { 00016 char* result; 00017 int neededSize = vsnprintf(NULL, 0, format, va); 00018 if (neededSize < 0) 00019 { 00020 result = NULL; 00021 } 00022 else 00023 { 00024 result = (char*)malloc(neededSize + 1); 00025 if (result == NULL) 00026 { 00027 /*return as is*/ 00028 } 00029 else 00030 { 00031 if (vsnprintf(result, neededSize + 1, format, va) != neededSize) 00032 { 00033 free(result); 00034 result = NULL; 00035 } 00036 } 00037 } 00038 return result; 00039 } 00040 00041 /*returns a string as if printed by printf*/ 00042 static char* printf_alloc(const char* format, ...) 00043 { 00044 char* result; 00045 va_list va; 00046 va_start(va, format); 00047 result = vprintf_alloc(format, va); 00048 va_end(va); 00049 return result; 00050 } 00051 00052 /*returns NULL if it fails*/ 00053 static char* lastErrorToString(DWORD lastError) 00054 { 00055 char* result; 00056 if (lastError == 0) 00057 { 00058 result = printf_alloc(""); /*no error should appear*/ 00059 if (result == NULL) 00060 { 00061 (void)printf("failure in printf_alloc"); 00062 } 00063 else 00064 { 00065 /*return as is*/ 00066 } 00067 } 00068 else 00069 { 00070 char temp[MESSAGE_BUFFER_SIZE]; 00071 if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, lastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), temp, MESSAGE_BUFFER_SIZE, NULL) == 0) 00072 { 00073 result = printf_alloc("GetLastError()=0X%x", lastError); 00074 if (result == NULL) 00075 { 00076 (void)printf("failure in printf_alloc\n"); 00077 /*return as is*/ 00078 } 00079 else 00080 { 00081 /*return as is*/ 00082 } 00083 } 00084 else 00085 { 00086 /*eliminate the \r or \n from the string*/ 00087 /*one replace of each is enough*/ 00088 char* whereAreThey; 00089 if ((whereAreThey = strchr(temp, '\r')) != NULL) 00090 { 00091 *whereAreThey = '\0'; 00092 } 00093 if ((whereAreThey = strchr(temp, '\n')) != NULL) 00094 { 00095 *whereAreThey = '\0'; 00096 } 00097 00098 result = printf_alloc("GetLastError()==0X%x (%s)", lastError, temp); 00099 00100 if (result == NULL) 00101 { 00102 (void)printf("failure in printf_alloc\n"); 00103 /*return as is*/ 00104 } 00105 else 00106 { 00107 /*return as is*/ 00108 } 00109 } 00110 } 00111 return result; 00112 } 00113 /*this function will use 1x printf (in the happy case) .*/ 00114 /*more than 1x printf / function call can mean intermingled LogErrors in a multithreaded env*/ 00115 /*the function will also attempt to produce some human readable strings for GetLastError*/ 00116 void consolelogger_log_with_GetLastError(const char* file, const char* func, int line, const char* format, ...) 00117 { 00118 DWORD lastError; 00119 char* lastErrorAsString; 00120 int lastErrorAsString_should_be_freed; 00121 time_t t; 00122 int systemMessage_should_be_freed; 00123 char* systemMessage; 00124 int userMessage_should_be_freed; 00125 char* userMessage; 00126 00127 va_list args; 00128 va_start(args, format); 00129 00130 /*this is what this case will do: 00131 1. snip the last error 00132 2. create a string with what that last error means 00133 3. printf the system message (__FILE__, __LINE__ etc) + the last error + whatever the user wanted 00134 */ 00135 /*1. snip the last error*/ 00136 lastError = GetLastError(); 00137 00138 /*2. create a string with what that last error means*/ 00139 lastErrorAsString = lastErrorToString(lastError); 00140 if (lastErrorAsString == NULL) 00141 { 00142 (void)printf("failure in lastErrorToString"); 00143 lastErrorAsString = ""; 00144 lastErrorAsString_should_be_freed = 0; 00145 } 00146 else 00147 { 00148 lastErrorAsString_should_be_freed = 1; 00149 } 00150 00151 t = time(NULL); 00152 systemMessage = printf_alloc("Error: Time:%.24s File:%s Func:%s Line:%d %s", ctime(&t), file, func, line, lastErrorAsString); 00153 00154 if (systemMessage == NULL) 00155 { 00156 systemMessage = ""; 00157 (void)printf("Error: [FAILED] Time:%.24s File : %s Func : %s Line : %d %s", ctime(&t), file, func, line, lastErrorAsString); 00158 systemMessage_should_be_freed = 0; 00159 } 00160 else 00161 { 00162 systemMessage_should_be_freed = 1; 00163 } 00164 00165 userMessage = vprintf_alloc(format, args); 00166 if (userMessage == NULL) 00167 { 00168 (void)printf("[FAILED] "); 00169 (void)vprintf(format, args); 00170 (void)printf("\n"); 00171 userMessage_should_be_freed = 0; 00172 } 00173 else 00174 { 00175 /*3. printf the system message(__FILE__, __LINE__ etc) + the last error + whatever the user wanted*/ 00176 (void)printf("%s %s\n", systemMessage, userMessage); 00177 userMessage_should_be_freed = 1; 00178 } 00179 00180 if (userMessage_should_be_freed == 1) 00181 { 00182 free(userMessage); 00183 } 00184 00185 if (systemMessage_should_be_freed == 1) 00186 { 00187 free(systemMessage); 00188 } 00189 00190 if (lastErrorAsString_should_be_freed == 1) 00191 { 00192 free(lastErrorAsString); 00193 } 00194 va_end(args); 00195 } 00196 #endif 00197 00198 #if defined(__GNUC__) 00199 __attribute__ ((format (printf, 6, 7))) 00200 #endif 00201 void consolelogger_log(LOG_CATEGORY log_category, const char* file, const char* func, int line, unsigned int options, const char* format, ...) 00202 { 00203 time_t t; 00204 va_list args; 00205 va_start(args, format); 00206 00207 t = time(NULL); 00208 00209 switch (log_category) 00210 { 00211 case AZ_LOG_INFO: 00212 (void)printf("Info: "); 00213 break; 00214 case AZ_LOG_ERROR: 00215 (void)printf("Error: Time:%.24s File:%s Func:%s Line:%d ", ctime(&t), file, func, line); 00216 break; 00217 default: 00218 break; 00219 } 00220 00221 (void)vprintf(format, args); 00222 va_end(args); 00223 00224 (void)log_category; 00225 if (options & LOG_LINE) 00226 { 00227 (void)printf("\r\n"); 00228 } 00229 } 00230
Generated on Wed Jul 13 2022 23:38:02 by
1.7.2