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
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 Tue Jul 12 2022 19:14:38 by
