Azure IoT common library
Fork of azure_c_shared_utility by
consolelogger.c@27:8656a313842b, 2017-05-22 (annotated)
- Committer:
- AzureIoTClient
- Date:
- Mon May 22 10:35:55 2017 -0700
- Revision:
- 27:8656a313842b
- Parent:
- 25:8507bf644fdf
1.1.15
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Azure.IoT Build | 6:c55b013dfc2a | 1 | // Copyright (c) Microsoft. All rights reserved. |
Azure.IoT Build | 6:c55b013dfc2a | 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
Azure.IoT Build | 6:c55b013dfc2a | 3 | |
Azure.IoT Build | 6:c55b013dfc2a | 4 | #include <stdarg.h> |
Azure.IoT Build | 6:c55b013dfc2a | 5 | #include <stdio.h> |
AzureIoTClient | 19:2e0811512ceb | 6 | #include <time.h> |
Azure.IoT Build | 6:c55b013dfc2a | 7 | #include "azure_c_shared_utility/xlogging.h" |
AzureIoTClient | 25:8507bf644fdf | 8 | #include "azure_c_shared_utility/consolelogger.h" |
Azure.IoT Build | 6:c55b013dfc2a | 9 | |
AzureIoTClient | 27:8656a313842b | 10 | #if (defined(_MSC_VER)) && (!(defined WINCE)) |
AzureIoTClient | 27:8656a313842b | 11 | #include "windows.h" |
AzureIoTClient | 27:8656a313842b | 12 | |
AzureIoTClient | 27:8656a313842b | 13 | /*returns a string as if printed by vprintf*/ |
AzureIoTClient | 27:8656a313842b | 14 | static char* vprintf_alloc(const char* format, va_list va) |
AzureIoTClient | 27:8656a313842b | 15 | { |
AzureIoTClient | 27:8656a313842b | 16 | char* result; |
AzureIoTClient | 27:8656a313842b | 17 | int neededSize = vsnprintf(NULL, 0, format, va); |
AzureIoTClient | 27:8656a313842b | 18 | if (neededSize < 0) |
AzureIoTClient | 27:8656a313842b | 19 | { |
AzureIoTClient | 27:8656a313842b | 20 | result = NULL; |
AzureIoTClient | 27:8656a313842b | 21 | } |
AzureIoTClient | 27:8656a313842b | 22 | else |
AzureIoTClient | 27:8656a313842b | 23 | { |
AzureIoTClient | 27:8656a313842b | 24 | result = (char*)malloc(neededSize + 1); |
AzureIoTClient | 27:8656a313842b | 25 | if (result == NULL) |
AzureIoTClient | 27:8656a313842b | 26 | { |
AzureIoTClient | 27:8656a313842b | 27 | /*return as is*/ |
AzureIoTClient | 27:8656a313842b | 28 | } |
AzureIoTClient | 27:8656a313842b | 29 | else |
AzureIoTClient | 27:8656a313842b | 30 | { |
AzureIoTClient | 27:8656a313842b | 31 | if (vsnprintf(result, neededSize + 1, format, va) != neededSize) |
AzureIoTClient | 27:8656a313842b | 32 | { |
AzureIoTClient | 27:8656a313842b | 33 | free(result); |
AzureIoTClient | 27:8656a313842b | 34 | result = NULL; |
AzureIoTClient | 27:8656a313842b | 35 | } |
AzureIoTClient | 27:8656a313842b | 36 | } |
AzureIoTClient | 27:8656a313842b | 37 | } |
AzureIoTClient | 27:8656a313842b | 38 | return result; |
AzureIoTClient | 27:8656a313842b | 39 | } |
AzureIoTClient | 27:8656a313842b | 40 | |
AzureIoTClient | 27:8656a313842b | 41 | /*returns a string as if printed by printf*/ |
AzureIoTClient | 27:8656a313842b | 42 | static char* printf_alloc(const char* format, ...) |
AzureIoTClient | 27:8656a313842b | 43 | { |
AzureIoTClient | 27:8656a313842b | 44 | char* result; |
AzureIoTClient | 27:8656a313842b | 45 | va_list va; |
AzureIoTClient | 27:8656a313842b | 46 | va_start(va, format); |
AzureIoTClient | 27:8656a313842b | 47 | result = vprintf_alloc(format, va); |
AzureIoTClient | 27:8656a313842b | 48 | va_end(va); |
AzureIoTClient | 27:8656a313842b | 49 | return result; |
AzureIoTClient | 27:8656a313842b | 50 | } |
AzureIoTClient | 27:8656a313842b | 51 | |
AzureIoTClient | 27:8656a313842b | 52 | /*returns NULL if it fails*/ |
AzureIoTClient | 27:8656a313842b | 53 | static char* lastErrorToString(DWORD lastError) |
AzureIoTClient | 27:8656a313842b | 54 | { |
AzureIoTClient | 27:8656a313842b | 55 | char* result; |
AzureIoTClient | 27:8656a313842b | 56 | if (lastError == 0) |
AzureIoTClient | 27:8656a313842b | 57 | { |
AzureIoTClient | 27:8656a313842b | 58 | result = printf_alloc(""); /*no error should appear*/ |
AzureIoTClient | 27:8656a313842b | 59 | if (result == NULL) |
AzureIoTClient | 27:8656a313842b | 60 | { |
AzureIoTClient | 27:8656a313842b | 61 | (void)printf("failure in printf_alloc"); |
AzureIoTClient | 27:8656a313842b | 62 | } |
AzureIoTClient | 27:8656a313842b | 63 | else |
AzureIoTClient | 27:8656a313842b | 64 | { |
AzureIoTClient | 27:8656a313842b | 65 | /*return as is*/ |
AzureIoTClient | 27:8656a313842b | 66 | } |
AzureIoTClient | 27:8656a313842b | 67 | } |
AzureIoTClient | 27:8656a313842b | 68 | else |
AzureIoTClient | 27:8656a313842b | 69 | { |
AzureIoTClient | 27:8656a313842b | 70 | char temp[MESSAGE_BUFFER_SIZE]; |
AzureIoTClient | 27:8656a313842b | 71 | if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, lastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), temp, MESSAGE_BUFFER_SIZE, NULL) == 0) |
AzureIoTClient | 27:8656a313842b | 72 | { |
AzureIoTClient | 27:8656a313842b | 73 | result = printf_alloc("GetLastError()=0X%x", lastError); |
AzureIoTClient | 27:8656a313842b | 74 | if (result == NULL) |
AzureIoTClient | 27:8656a313842b | 75 | { |
AzureIoTClient | 27:8656a313842b | 76 | (void)printf("failure in printf_alloc\n"); |
AzureIoTClient | 27:8656a313842b | 77 | /*return as is*/ |
AzureIoTClient | 27:8656a313842b | 78 | } |
AzureIoTClient | 27:8656a313842b | 79 | else |
AzureIoTClient | 27:8656a313842b | 80 | { |
AzureIoTClient | 27:8656a313842b | 81 | /*return as is*/ |
AzureIoTClient | 27:8656a313842b | 82 | } |
AzureIoTClient | 27:8656a313842b | 83 | } |
AzureIoTClient | 27:8656a313842b | 84 | else |
AzureIoTClient | 27:8656a313842b | 85 | { |
AzureIoTClient | 27:8656a313842b | 86 | /*eliminate the \r or \n from the string*/ |
AzureIoTClient | 27:8656a313842b | 87 | /*one replace of each is enough*/ |
AzureIoTClient | 27:8656a313842b | 88 | char* whereAreThey; |
AzureIoTClient | 27:8656a313842b | 89 | if ((whereAreThey = strchr(temp, '\r')) != NULL) |
AzureIoTClient | 27:8656a313842b | 90 | { |
AzureIoTClient | 27:8656a313842b | 91 | *whereAreThey = '\0'; |
AzureIoTClient | 27:8656a313842b | 92 | } |
AzureIoTClient | 27:8656a313842b | 93 | if ((whereAreThey = strchr(temp, '\n')) != NULL) |
AzureIoTClient | 27:8656a313842b | 94 | { |
AzureIoTClient | 27:8656a313842b | 95 | *whereAreThey = '\0'; |
AzureIoTClient | 27:8656a313842b | 96 | } |
AzureIoTClient | 27:8656a313842b | 97 | |
AzureIoTClient | 27:8656a313842b | 98 | result = printf_alloc("GetLastError()==0X%x (%s)", lastError, temp); |
AzureIoTClient | 27:8656a313842b | 99 | |
AzureIoTClient | 27:8656a313842b | 100 | if (result == NULL) |
AzureIoTClient | 27:8656a313842b | 101 | { |
AzureIoTClient | 27:8656a313842b | 102 | (void)printf("failure in printf_alloc\n"); |
AzureIoTClient | 27:8656a313842b | 103 | /*return as is*/ |
AzureIoTClient | 27:8656a313842b | 104 | } |
AzureIoTClient | 27:8656a313842b | 105 | else |
AzureIoTClient | 27:8656a313842b | 106 | { |
AzureIoTClient | 27:8656a313842b | 107 | /*return as is*/ |
AzureIoTClient | 27:8656a313842b | 108 | } |
AzureIoTClient | 27:8656a313842b | 109 | } |
AzureIoTClient | 27:8656a313842b | 110 | } |
AzureIoTClient | 27:8656a313842b | 111 | return result; |
AzureIoTClient | 27:8656a313842b | 112 | } |
AzureIoTClient | 27:8656a313842b | 113 | /*this function will use 1x printf (in the happy case) .*/ |
AzureIoTClient | 27:8656a313842b | 114 | /*more than 1x printf / function call can mean intermingled LogErrors in a multithreaded env*/ |
AzureIoTClient | 27:8656a313842b | 115 | /*the function will also attempt to produce some human readable strings for GetLastError*/ |
AzureIoTClient | 27:8656a313842b | 116 | void consolelogger_log_with_GetLastError(const char* file, const char* func, int line, const char* format, ...) |
AzureIoTClient | 27:8656a313842b | 117 | { |
AzureIoTClient | 27:8656a313842b | 118 | DWORD lastError; |
AzureIoTClient | 27:8656a313842b | 119 | char* lastErrorAsString; |
AzureIoTClient | 27:8656a313842b | 120 | int lastErrorAsString_should_be_freed; |
AzureIoTClient | 27:8656a313842b | 121 | time_t t; |
AzureIoTClient | 27:8656a313842b | 122 | int systemMessage_should_be_freed; |
AzureIoTClient | 27:8656a313842b | 123 | char* systemMessage; |
AzureIoTClient | 27:8656a313842b | 124 | int userMessage_should_be_freed; |
AzureIoTClient | 27:8656a313842b | 125 | char* userMessage; |
AzureIoTClient | 27:8656a313842b | 126 | |
AzureIoTClient | 27:8656a313842b | 127 | va_list args; |
AzureIoTClient | 27:8656a313842b | 128 | va_start(args, format); |
AzureIoTClient | 27:8656a313842b | 129 | |
AzureIoTClient | 27:8656a313842b | 130 | /*this is what this case will do: |
AzureIoTClient | 27:8656a313842b | 131 | 1. snip the last error |
AzureIoTClient | 27:8656a313842b | 132 | 2. create a string with what that last error means |
AzureIoTClient | 27:8656a313842b | 133 | 3. printf the system message (__FILE__, __LINE__ etc) + the last error + whatever the user wanted |
AzureIoTClient | 27:8656a313842b | 134 | */ |
AzureIoTClient | 27:8656a313842b | 135 | /*1. snip the last error*/ |
AzureIoTClient | 27:8656a313842b | 136 | lastError = GetLastError(); |
AzureIoTClient | 27:8656a313842b | 137 | |
AzureIoTClient | 27:8656a313842b | 138 | /*2. create a string with what that last error means*/ |
AzureIoTClient | 27:8656a313842b | 139 | lastErrorAsString = lastErrorToString(lastError); |
AzureIoTClient | 27:8656a313842b | 140 | if (lastErrorAsString == NULL) |
AzureIoTClient | 27:8656a313842b | 141 | { |
AzureIoTClient | 27:8656a313842b | 142 | (void)printf("failure in lastErrorToString"); |
AzureIoTClient | 27:8656a313842b | 143 | lastErrorAsString = ""; |
AzureIoTClient | 27:8656a313842b | 144 | lastErrorAsString_should_be_freed = 0; |
AzureIoTClient | 27:8656a313842b | 145 | } |
AzureIoTClient | 27:8656a313842b | 146 | else |
AzureIoTClient | 27:8656a313842b | 147 | { |
AzureIoTClient | 27:8656a313842b | 148 | lastErrorAsString_should_be_freed = 1; |
AzureIoTClient | 27:8656a313842b | 149 | } |
AzureIoTClient | 27:8656a313842b | 150 | |
AzureIoTClient | 27:8656a313842b | 151 | t = time(NULL); |
AzureIoTClient | 27:8656a313842b | 152 | systemMessage = printf_alloc("Error: Time:%.24s File:%s Func:%s Line:%d %s", ctime(&t), file, func, line, lastErrorAsString); |
AzureIoTClient | 27:8656a313842b | 153 | |
AzureIoTClient | 27:8656a313842b | 154 | if (systemMessage == NULL) |
AzureIoTClient | 27:8656a313842b | 155 | { |
AzureIoTClient | 27:8656a313842b | 156 | systemMessage = ""; |
AzureIoTClient | 27:8656a313842b | 157 | (void)printf("Error: [FAILED] Time:%.24s File : %s Func : %s Line : %d %s", ctime(&t), file, func, line, lastErrorAsString); |
AzureIoTClient | 27:8656a313842b | 158 | systemMessage_should_be_freed = 0; |
AzureIoTClient | 27:8656a313842b | 159 | } |
AzureIoTClient | 27:8656a313842b | 160 | else |
AzureIoTClient | 27:8656a313842b | 161 | { |
AzureIoTClient | 27:8656a313842b | 162 | systemMessage_should_be_freed = 1; |
AzureIoTClient | 27:8656a313842b | 163 | } |
AzureIoTClient | 27:8656a313842b | 164 | |
AzureIoTClient | 27:8656a313842b | 165 | userMessage = vprintf_alloc(format, args); |
AzureIoTClient | 27:8656a313842b | 166 | if (userMessage == NULL) |
AzureIoTClient | 27:8656a313842b | 167 | { |
AzureIoTClient | 27:8656a313842b | 168 | (void)printf("[FAILED] "); |
AzureIoTClient | 27:8656a313842b | 169 | (void)vprintf(format, args); |
AzureIoTClient | 27:8656a313842b | 170 | (void)printf("\n"); |
AzureIoTClient | 27:8656a313842b | 171 | userMessage_should_be_freed = 0; |
AzureIoTClient | 27:8656a313842b | 172 | } |
AzureIoTClient | 27:8656a313842b | 173 | else |
AzureIoTClient | 27:8656a313842b | 174 | { |
AzureIoTClient | 27:8656a313842b | 175 | /*3. printf the system message(__FILE__, __LINE__ etc) + the last error + whatever the user wanted*/ |
AzureIoTClient | 27:8656a313842b | 176 | (void)printf("%s %s\n", systemMessage, userMessage); |
AzureIoTClient | 27:8656a313842b | 177 | userMessage_should_be_freed = 1; |
AzureIoTClient | 27:8656a313842b | 178 | } |
AzureIoTClient | 27:8656a313842b | 179 | |
AzureIoTClient | 27:8656a313842b | 180 | if (userMessage_should_be_freed == 1) |
AzureIoTClient | 27:8656a313842b | 181 | { |
AzureIoTClient | 27:8656a313842b | 182 | free(userMessage); |
AzureIoTClient | 27:8656a313842b | 183 | } |
AzureIoTClient | 27:8656a313842b | 184 | |
AzureIoTClient | 27:8656a313842b | 185 | if (systemMessage_should_be_freed == 1) |
AzureIoTClient | 27:8656a313842b | 186 | { |
AzureIoTClient | 27:8656a313842b | 187 | free(systemMessage); |
AzureIoTClient | 27:8656a313842b | 188 | } |
AzureIoTClient | 27:8656a313842b | 189 | |
AzureIoTClient | 27:8656a313842b | 190 | if (lastErrorAsString_should_be_freed == 1) |
AzureIoTClient | 27:8656a313842b | 191 | { |
AzureIoTClient | 27:8656a313842b | 192 | free(lastErrorAsString); |
AzureIoTClient | 27:8656a313842b | 193 | } |
AzureIoTClient | 27:8656a313842b | 194 | va_end(args); |
AzureIoTClient | 27:8656a313842b | 195 | } |
AzureIoTClient | 27:8656a313842b | 196 | #endif |
AzureIoTClient | 27:8656a313842b | 197 | |
AzureIoTClient | 25:8507bf644fdf | 198 | #if defined(__GNUC__) |
AzureIoTClient | 25:8507bf644fdf | 199 | __attribute__ ((format (printf, 6, 7))) |
AzureIoTClient | 25:8507bf644fdf | 200 | #endif |
AzureIoTClient | 27:8656a313842b | 201 | void consolelogger_log(LOG_CATEGORY log_category, const char* file, const char* func, int line, unsigned int options, const char* format, ...) |
Azure.IoT Build | 6:c55b013dfc2a | 202 | { |
AzureIoTClient | 27:8656a313842b | 203 | time_t t; |
AzureIoTClient | 8:3db46d1e5471 | 204 | va_list args; |
AzureIoTClient | 8:3db46d1e5471 | 205 | va_start(args, format); |
AzureIoTClient | 7:1af47e3a19b6 | 206 | |
AzureIoTClient | 27:8656a313842b | 207 | t = time(NULL); |
AzureIoTClient | 7:1af47e3a19b6 | 208 | |
AzureIoTClient | 7:1af47e3a19b6 | 209 | switch (log_category) |
AzureIoTClient | 7:1af47e3a19b6 | 210 | { |
AzureIoTClient | 18:6d8a413a4d9a | 211 | case AZ_LOG_INFO: |
AzureIoTClient | 7:1af47e3a19b6 | 212 | (void)printf("Info: "); |
AzureIoTClient | 7:1af47e3a19b6 | 213 | break; |
AzureIoTClient | 18:6d8a413a4d9a | 214 | case AZ_LOG_ERROR: |
AzureIoTClient | 8:3db46d1e5471 | 215 | (void)printf("Error: Time:%.24s File:%s Func:%s Line:%d ", ctime(&t), file, func, line); |
AzureIoTClient | 7:1af47e3a19b6 | 216 | break; |
AzureIoTClient | 7:1af47e3a19b6 | 217 | default: |
AzureIoTClient | 7:1af47e3a19b6 | 218 | break; |
AzureIoTClient | 7:1af47e3a19b6 | 219 | } |
AzureIoTClient | 7:1af47e3a19b6 | 220 | |
AzureIoTClient | 27:8656a313842b | 221 | (void)vprintf(format, args); |
AzureIoTClient | 27:8656a313842b | 222 | va_end(args); |
Azure.IoT Build | 6:c55b013dfc2a | 223 | |
Azure.IoT Build | 6:c55b013dfc2a | 224 | (void)log_category; |
AzureIoTClient | 27:8656a313842b | 225 | if (options & LOG_LINE) |
AzureIoTClient | 27:8656a313842b | 226 | { |
AzureIoTClient | 27:8656a313842b | 227 | (void)printf("\r\n"); |
AzureIoTClient | 27:8656a313842b | 228 | } |
Azure.IoT Build | 6:c55b013dfc2a | 229 | } |
AzureIoTClient | 27:8656a313842b | 230 |