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: TYBLE16_simple_data_logger TYBLE16_MP3_Air
mbed_trace.c
00001 /* 00002 * Copyright (c) 2014-2015 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include <stdio.h> 00017 #include <string.h> 00018 #include <stdarg.h> 00019 00020 #ifdef MBED_CONF_MBED_TRACE_ENABLE 00021 #undef MBED_CONF_MBED_TRACE_ENABLE 00022 #endif 00023 #define MBED_CONF_MBED_TRACE_ENABLE 1 00024 #ifndef MBED_CONF_MBED_TRACE_FEA_IPV6 00025 #define MBED_CONF_MBED_TRACE_FEA_IPV6 1 00026 #endif 00027 00028 #include "mbed-trace/mbed_trace.h" 00029 #if MBED_CONF_MBED_TRACE_FEA_IPV6 == 1 00030 #include "mbed-client-libservice/ip6string.h" 00031 #include "mbed-client-libservice/common_functions.h" 00032 #endif 00033 00034 #if defined(YOTTA_CFG_MBED_TRACE_MEM) 00035 #define MBED_TRACE_MEM_INCLUDE YOTTA_CFG_MBED_TRACE_MEM_INCLUDE 00036 #define MBED_TRACE_MEM_ALLOC YOTTA_CFG_MBED_TRACE_MEM_ALLOC 00037 #define MBED_TRACE_MEM_FREE YOTTA_CFG_MBED_TRACE_MEM_FREE 00038 #else /* YOTTA_CFG_MEMLIB */ 00039 // Default options 00040 #ifndef MBED_TRACE_MEM_INCLUDE 00041 #define MBED_TRACE_MEM_INCLUDE <stdlib.h> 00042 #endif 00043 #include MBED_TRACE_MEM_INCLUDE 00044 #ifndef MBED_TRACE_MEM_ALLOC 00045 #define MBED_TRACE_MEM_ALLOC malloc 00046 #endif 00047 #ifndef MBED_TRACE_MEM_FREE 00048 #define MBED_TRACE_MEM_FREE free 00049 #endif 00050 #endif /* YOTTA_CFG_MEMLIB */ 00051 00052 #define VT100_COLOR_ERROR "\x1b[31m" 00053 #define VT100_COLOR_WARN "\x1b[33m" 00054 #define VT100_COLOR_INFO "\x1b[39m" 00055 #define VT100_COLOR_DEBUG "\x1b[90m" 00056 00057 /** default max trace line size in bytes */ 00058 #ifdef MBED_TRACE_LINE_LENGTH 00059 #define DEFAULT_TRACE_LINE_LENGTH MBED_TRACE_LINE_LENGTH 00060 #elif defined YOTTA_CFG_MBED_TRACE_LINE_LENGTH 00061 #warning YOTTA_CFG_MBED_TRACE_LINE_LENGTH is deprecated and will be removed in the future! Use MBED_TRACE_LINE_LENGTH instead. 00062 #define DEFAULT_TRACE_LINE_LENGTH YOTTA_CFG_MBED_TRACE_LINE_LENGTH 00063 #else 00064 #define DEFAULT_TRACE_LINE_LENGTH 1024 00065 #endif 00066 00067 /** default max temporary buffer size in bytes, used in 00068 trace_ipv6, trace_ipv6_prefix and trace_array */ 00069 #ifdef MBED_TRACE_TMP_LINE_LENGTH 00070 #define DEFAULT_TRACE_TMP_LINE_LEN MBED_TRACE_TMP_LINE_LENGTH 00071 #elif defined YOTTA_CFG_MBED_TRACE_TMP_LINE_LEN 00072 #warning The YOTTA_CFG_MBED_TRACE_TMP_LINE_LEN flag is deprecated and will be removed in the future! Use MBED_TRACE_TMP_LINE_LENGTH instead. 00073 #define DEFAULT_TRACE_TMP_LINE_LEN YOTTA_CFG_MBED_TRACE_TMP_LINE_LEN 00074 #elif defined YOTTA_CFG_MTRACE_TMP_LINE_LEN 00075 #warning The YOTTA_CFG_MTRACE_TMP_LINE_LEN flag is deprecated and will be removed in the future! Use MBED_TRACE_TMP_LINE_LENGTH instead. 00076 #define DEFAULT_TRACE_TMP_LINE_LEN YOTTA_CFG_MTRACE_TMP_LINE_LEN 00077 #else 00078 #define DEFAULT_TRACE_TMP_LINE_LEN 128 00079 #endif 00080 00081 /** default max filters (include/exclude) length in bytes */ 00082 #ifdef MBED_TRACE_FILTER_LENGTH 00083 #define DEFAULT_TRACE_FILTER_LENGTH MBED_TRACE_FILTER_LENGTH 00084 #else 00085 #define DEFAULT_TRACE_FILTER_LENGTH 24 00086 #endif 00087 00088 /** default trace configuration bitmask */ 00089 #ifdef MBED_TRACE_CONFIG 00090 #define DEFAULT_TRACE_CONFIG MBED_TRACE_CONFIG 00091 #else 00092 #define DEFAULT_TRACE_CONFIG TRACE_MODE_COLOR | TRACE_ACTIVE_LEVEL_ALL | TRACE_CARRIAGE_RETURN 00093 #endif 00094 00095 /** default print function, just redirect str to printf */ 00096 static void mbed_trace_realloc(char **buffer, int *length_ptr, int new_length); 00097 static void mbed_trace_default_print(const char *str); 00098 static void mbed_trace_reset_tmp(void); 00099 00100 typedef struct trace_s { 00101 /** trace configuration bits */ 00102 uint8_t trace_config; 00103 /** exclude filters list, related group name */ 00104 char *filters_exclude; 00105 /** include filters list, related group name */ 00106 char *filters_include; 00107 /** Filters length */ 00108 int filters_length; 00109 /** trace line */ 00110 char *line; 00111 /** trace line length */ 00112 int line_length; 00113 /** temporary data */ 00114 char *tmp_data; 00115 /** temporary data array length */ 00116 int tmp_data_length; 00117 /** temporary data pointer */ 00118 char *tmp_data_ptr; 00119 00120 /** prefix function, which can be used to put time to the trace line */ 00121 char *(*prefix_f)(size_t); 00122 /** suffix function, which can be used to some string to the end of trace line */ 00123 char *(*suffix_f)(void); 00124 /** print out function. Can be redirect to flash for example. */ 00125 void (*printf)(const char *); 00126 /** print out function for TRACE_LEVEL_CMD */ 00127 void (*cmd_printf)(const char *); 00128 /** mutex wait function which can be called to lock against a mutex. */ 00129 void (*mutex_wait_f)(void); 00130 /** mutex release function which must be used to release the mutex locked by mutex_wait_f. */ 00131 void (*mutex_release_f)(void); 00132 /** number of times the mutex has been locked */ 00133 int mutex_lock_count; 00134 } trace_t; 00135 00136 static trace_t m_trace = { 00137 .trace_config = DEFAULT_TRACE_CONFIG, 00138 .filters_exclude = 0, 00139 .filters_include = 0, 00140 .filters_length = DEFAULT_TRACE_FILTER_LENGTH, 00141 .line = 0, 00142 .line_length = DEFAULT_TRACE_LINE_LENGTH, 00143 .tmp_data = 0, 00144 .tmp_data_length = DEFAULT_TRACE_TMP_LINE_LEN, 00145 .tmp_data_ptr = 0, 00146 .prefix_f = 0, 00147 .suffix_f = 0, 00148 .printf = mbed_trace_default_print, 00149 .cmd_printf = 0, 00150 .mutex_wait_f = 0, 00151 .mutex_release_f = 0, 00152 .mutex_lock_count = 0 00153 }; 00154 00155 int mbed_trace_init(void) 00156 { 00157 if (m_trace.line == NULL) { 00158 m_trace.line = MBED_TRACE_MEM_ALLOC(m_trace.line_length); 00159 } 00160 00161 if (m_trace.tmp_data == NULL) { 00162 m_trace.tmp_data = MBED_TRACE_MEM_ALLOC(m_trace.tmp_data_length); 00163 } 00164 m_trace.tmp_data_ptr = m_trace.tmp_data; 00165 00166 if (m_trace.filters_exclude == NULL) { 00167 m_trace.filters_exclude = MBED_TRACE_MEM_ALLOC(m_trace.filters_length); 00168 } 00169 if (m_trace.filters_include == NULL) { 00170 m_trace.filters_include = MBED_TRACE_MEM_ALLOC(m_trace.filters_length); 00171 } 00172 00173 if (m_trace.line == NULL || 00174 m_trace.tmp_data == NULL || 00175 m_trace.filters_exclude == NULL || 00176 m_trace.filters_include == NULL) { 00177 //memory allocation fail 00178 mbed_trace_free(); 00179 return -1; 00180 } 00181 memset(m_trace.tmp_data, 0, m_trace.tmp_data_length); 00182 memset(m_trace.filters_exclude, 0, m_trace.filters_length); 00183 memset(m_trace.filters_include, 0, m_trace.filters_length); 00184 memset(m_trace.line, 0, m_trace.line_length); 00185 00186 return 0; 00187 } 00188 void mbed_trace_free(void) 00189 { 00190 // release memory 00191 MBED_TRACE_MEM_FREE(m_trace.line); 00192 MBED_TRACE_MEM_FREE(m_trace.tmp_data); 00193 MBED_TRACE_MEM_FREE(m_trace.filters_exclude); 00194 MBED_TRACE_MEM_FREE(m_trace.filters_include); 00195 00196 // reset to default values 00197 m_trace.trace_config = DEFAULT_TRACE_CONFIG; 00198 m_trace.filters_exclude = 0; 00199 m_trace.filters_include = 0; 00200 m_trace.filters_length = DEFAULT_TRACE_FILTER_LENGTH; 00201 m_trace.line = 0; 00202 m_trace.line_length = DEFAULT_TRACE_LINE_LENGTH; 00203 m_trace.tmp_data = 0; 00204 m_trace.tmp_data_length = DEFAULT_TRACE_TMP_LINE_LEN; 00205 m_trace.prefix_f = 0; 00206 m_trace.suffix_f = 0; 00207 m_trace.printf = mbed_trace_default_print; 00208 m_trace.cmd_printf = 0; 00209 m_trace.mutex_wait_f = 0; 00210 m_trace.mutex_release_f = 0; 00211 m_trace.mutex_lock_count = 0; 00212 } 00213 static void mbed_trace_realloc(char **buffer, int *length_ptr, int new_length) 00214 { 00215 MBED_TRACE_MEM_FREE(*buffer); 00216 *buffer = MBED_TRACE_MEM_ALLOC(new_length); 00217 *length_ptr = new_length; 00218 } 00219 void mbed_trace_buffer_sizes(int lineLength, int tmpLength) 00220 { 00221 if (lineLength > 0) { 00222 mbed_trace_realloc(&(m_trace.line), &m_trace.line_length, lineLength); 00223 } 00224 if (tmpLength > 0) { 00225 mbed_trace_realloc(&(m_trace.tmp_data), &m_trace.tmp_data_length, tmpLength); 00226 mbed_trace_reset_tmp(); 00227 } 00228 } 00229 void mbed_trace_config_set(uint8_t config) 00230 { 00231 m_trace.trace_config = config; 00232 } 00233 uint8_t mbed_trace_config_get(void) 00234 { 00235 return m_trace.trace_config; 00236 } 00237 void mbed_trace_prefix_function_set(char *(*pref_f)(size_t)) 00238 { 00239 m_trace.prefix_f = pref_f; 00240 } 00241 void mbed_trace_suffix_function_set(char *(*suffix_f)(void)) 00242 { 00243 m_trace.suffix_f = suffix_f; 00244 } 00245 void mbed_trace_print_function_set(void (*printf)(const char *)) 00246 { 00247 m_trace.printf = printf; 00248 } 00249 void mbed_trace_cmdprint_function_set(void (*printf)(const char *)) 00250 { 00251 m_trace.cmd_printf = printf; 00252 } 00253 void mbed_trace_mutex_wait_function_set(void (*mutex_wait_f)(void)) 00254 { 00255 m_trace.mutex_wait_f = mutex_wait_f; 00256 } 00257 void mbed_trace_mutex_release_function_set(void (*mutex_release_f)(void)) 00258 { 00259 m_trace.mutex_release_f = mutex_release_f; 00260 } 00261 void mbed_trace_exclude_filters_set(char *filters) 00262 { 00263 if (filters) { 00264 (void)strncpy(m_trace.filters_exclude, filters, m_trace.filters_length); 00265 } else { 00266 m_trace.filters_exclude[0] = 0; 00267 } 00268 } 00269 const char *mbed_trace_exclude_filters_get(void) 00270 { 00271 return m_trace.filters_exclude; 00272 } 00273 const char *mbed_trace_include_filters_get(void) 00274 { 00275 return m_trace.filters_include; 00276 } 00277 void mbed_trace_include_filters_set(char *filters) 00278 { 00279 if (filters) { 00280 (void)strncpy(m_trace.filters_include, filters, m_trace.filters_length); 00281 } else { 00282 m_trace.filters_include[0] = 0; 00283 } 00284 } 00285 static int8_t mbed_trace_skip(int8_t dlevel, const char *grp) 00286 { 00287 if (dlevel >= 0 && grp != 0) { 00288 // filter debug prints only when dlevel is >0 and grp is given 00289 00290 /// @TODO this could be much better.. 00291 if (m_trace.filters_exclude[0] != '\0' && 00292 strstr(m_trace.filters_exclude, grp) != 0) { 00293 //grp was in exclude list 00294 return 1; 00295 } 00296 if (m_trace.filters_include[0] != '\0' && 00297 strstr(m_trace.filters_include, grp) == 0) { 00298 //grp was in include list 00299 return 1; 00300 } 00301 } 00302 return 0; 00303 } 00304 static void mbed_trace_default_print(const char *str) 00305 { 00306 puts(str); 00307 } 00308 void mbed_tracef(uint8_t dlevel, const char *grp, const char *fmt, ...) 00309 { 00310 va_list ap; 00311 va_start(ap, fmt); 00312 mbed_vtracef(dlevel, grp, fmt, ap); 00313 va_end(ap); 00314 } 00315 void mbed_vtracef(uint8_t dlevel, const char *grp, const char *fmt, va_list ap) 00316 { 00317 if (m_trace.mutex_wait_f) { 00318 m_trace.mutex_wait_f(); 00319 m_trace.mutex_lock_count++; 00320 } 00321 00322 if (NULL == m_trace.line) { 00323 goto end; 00324 } 00325 00326 m_trace.line[0] = 0; //by default trace is empty 00327 00328 if (mbed_trace_skip(dlevel, grp) || fmt == 0 || grp == 0 || !m_trace.printf) { 00329 //return tmp data pointer back to the beginning 00330 mbed_trace_reset_tmp(); 00331 goto end; 00332 } 00333 if ((m_trace.trace_config & TRACE_MASK_LEVEL) & dlevel) { 00334 bool color = (m_trace.trace_config & TRACE_MODE_COLOR) != 0; 00335 bool plain = (m_trace.trace_config & TRACE_MODE_PLAIN) != 0; 00336 bool cr = (m_trace.trace_config & TRACE_CARRIAGE_RETURN) != 0; 00337 00338 int retval = 0, bLeft = m_trace.line_length; 00339 char *ptr = m_trace.line; 00340 if (plain == true || dlevel == TRACE_LEVEL_CMD) { 00341 //add trace data 00342 retval = vsnprintf(ptr, bLeft, fmt, ap); 00343 if (dlevel == TRACE_LEVEL_CMD && m_trace.cmd_printf) { 00344 m_trace.cmd_printf(m_trace.line); 00345 m_trace.cmd_printf("\n"); 00346 } else { 00347 //print out whole data 00348 m_trace.printf(m_trace.line); 00349 } 00350 } else { 00351 if (color) { 00352 if (cr) { 00353 retval = snprintf(ptr, bLeft, "\r\x1b[2K"); 00354 if (retval >= bLeft) { 00355 retval = 0; 00356 } 00357 if (retval > 0) { 00358 ptr += retval; 00359 bLeft -= retval; 00360 } 00361 } 00362 if (bLeft > 0) { 00363 //include color in ANSI/VT100 escape code 00364 switch (dlevel) { 00365 case (TRACE_LEVEL_ERROR): 00366 retval = snprintf(ptr, bLeft, "%s", VT100_COLOR_ERROR); 00367 break; 00368 case (TRACE_LEVEL_WARN): 00369 retval = snprintf(ptr, bLeft, "%s", VT100_COLOR_WARN); 00370 break; 00371 case (TRACE_LEVEL_INFO): 00372 retval = snprintf(ptr, bLeft, "%s", VT100_COLOR_INFO); 00373 break; 00374 case (TRACE_LEVEL_DEBUG): 00375 retval = snprintf(ptr, bLeft, "%s", VT100_COLOR_DEBUG); 00376 break; 00377 default: 00378 color = 0; //avoid unneeded color-terminate code 00379 retval = 0; 00380 break; 00381 } 00382 if (retval >= bLeft) { 00383 retval = 0; 00384 } 00385 if (retval > 0 && color) { 00386 ptr += retval; 00387 bLeft -= retval; 00388 } 00389 } 00390 00391 } 00392 if (bLeft > 0 && m_trace.prefix_f) { 00393 //find out length of body 00394 size_t sz = 0; 00395 va_list ap2; 00396 va_copy(ap2, ap); 00397 sz = vsnprintf(NULL, 0, fmt, ap2) + retval + (retval ? 4 : 0); 00398 va_end(ap2); 00399 //add prefix string 00400 retval = snprintf(ptr, bLeft, "%s", m_trace.prefix_f(sz)); 00401 if (retval >= bLeft) { 00402 retval = 0; 00403 } 00404 if (retval > 0) { 00405 ptr += retval; 00406 bLeft -= retval; 00407 } 00408 } 00409 if (bLeft > 0) { 00410 //add group tag 00411 switch (dlevel) { 00412 case (TRACE_LEVEL_ERROR): 00413 retval = snprintf(ptr, bLeft, "[ERR ][%-4s]: ", grp); 00414 break; 00415 case (TRACE_LEVEL_WARN): 00416 retval = snprintf(ptr, bLeft, "[WARN][%-4s]: ", grp); 00417 break; 00418 case (TRACE_LEVEL_INFO): 00419 retval = snprintf(ptr, bLeft, "[INFO][%-4s]: ", grp); 00420 break; 00421 case (TRACE_LEVEL_DEBUG): 00422 retval = snprintf(ptr, bLeft, "[DBG ][%-4s]: ", grp); 00423 break; 00424 default: 00425 retval = snprintf(ptr, bLeft, " "); 00426 break; 00427 } 00428 if (retval >= bLeft) { 00429 retval = 0; 00430 } 00431 if (retval > 0) { 00432 ptr += retval; 00433 bLeft -= retval; 00434 } 00435 } 00436 if (retval > 0 && bLeft > 0) { 00437 //add trace text 00438 retval = vsnprintf(ptr, bLeft, fmt, ap); 00439 if (retval >= bLeft) { 00440 retval = 0; 00441 } 00442 if (retval > 0) { 00443 ptr += retval; 00444 bLeft -= retval; 00445 } 00446 } 00447 00448 if (retval > 0 && bLeft > 0 && m_trace.suffix_f) { 00449 //add suffix string 00450 retval = snprintf(ptr, bLeft, "%s", m_trace.suffix_f()); 00451 if (retval >= bLeft) { 00452 retval = 0; 00453 } 00454 if (retval > 0) { 00455 ptr += retval; 00456 bLeft -= retval; 00457 } 00458 } 00459 00460 if (retval > 0 && bLeft > 0 && color) { 00461 //add zero color VT100 when color mode 00462 retval = snprintf(ptr, bLeft, "\x1b[0m"); 00463 if (retval >= bLeft) { 00464 retval = 0; 00465 } 00466 if (retval > 0) { 00467 // not used anymore 00468 //ptr += retval; 00469 //bLeft -= retval; 00470 } 00471 } 00472 //print out whole data 00473 m_trace.printf(m_trace.line); 00474 } 00475 //return tmp data pointer back to the beginning 00476 mbed_trace_reset_tmp(); 00477 } 00478 00479 end: 00480 if (m_trace.mutex_release_f) { 00481 // Store the mutex lock count to temp variable so that it won't get 00482 // clobbered during last loop iteration when mutex gets released 00483 int count = m_trace.mutex_lock_count; 00484 m_trace.mutex_lock_count = 0; 00485 // Since the helper functions (eg. mbed_trace_array) are used like this: 00486 // mbed_tracef(TRACE_LEVEL_INFO, "grp", "%s", mbed_trace_array(some_array)) 00487 // The helper function MUST acquire the mutex if it modifies any buffers. However 00488 // it CANNOT unlock the mutex because that would allow another thread to acquire 00489 // the mutex after helper function unlocks it and before mbed_tracef acquires it 00490 // for itself. This means that here we have to unlock the mutex as many times 00491 // as it was acquired by trace function and any possible helper functions. 00492 do { 00493 m_trace.mutex_release_f(); 00494 } while (--count > 0); 00495 } 00496 } 00497 static void mbed_trace_reset_tmp(void) 00498 { 00499 m_trace.tmp_data_ptr = m_trace.tmp_data; 00500 } 00501 const char *mbed_trace_last(void) 00502 { 00503 return m_trace.line; 00504 } 00505 /* Helping functions */ 00506 #define tmp_data_left() m_trace.tmp_data_length-(m_trace.tmp_data_ptr-m_trace.tmp_data) 00507 #if MBED_CONF_MBED_TRACE_FEA_IPV6 == 1 00508 char *mbed_trace_ipv6(const void *addr_ptr) 00509 { 00510 /** Acquire mutex. It is released before returning from mbed_vtracef. */ 00511 if (m_trace.mutex_wait_f) { 00512 m_trace.mutex_wait_f(); 00513 m_trace.mutex_lock_count++; 00514 } 00515 char *str = m_trace.tmp_data_ptr; 00516 if (str == NULL) { 00517 return ""; 00518 } 00519 if (tmp_data_left() < 41) { 00520 return ""; 00521 } 00522 if (addr_ptr == NULL) { 00523 return "<null>"; 00524 } 00525 str[0] = 0; 00526 m_trace.tmp_data_ptr += ip6tos(addr_ptr, str) + 1; 00527 return str; 00528 } 00529 char *mbed_trace_ipv6_prefix(const uint8_t *prefix, uint8_t prefix_len) 00530 { 00531 /** Acquire mutex. It is released before returning from mbed_vtracef. */ 00532 if (m_trace.mutex_wait_f) { 00533 m_trace.mutex_wait_f(); 00534 m_trace.mutex_lock_count++; 00535 } 00536 char *str = m_trace.tmp_data_ptr; 00537 if (str == NULL) { 00538 return ""; 00539 } 00540 if (tmp_data_left() < 45) { 00541 return ""; 00542 } 00543 00544 if ((prefix_len != 0 && prefix == NULL) || prefix_len > 128) { 00545 return "<err>"; 00546 } 00547 00548 m_trace.tmp_data_ptr += ip6_prefix_tos(prefix, prefix_len, str) + 1; 00549 return str; 00550 } 00551 #endif //MBED_CONF_MBED_TRACE_FEA_IPV6 00552 char *mbed_trace_array(const uint8_t *buf, uint16_t len) 00553 { 00554 /** Acquire mutex. It is released before returning from mbed_vtracef. */ 00555 if (m_trace.mutex_wait_f) { 00556 m_trace.mutex_wait_f(); 00557 m_trace.mutex_lock_count++; 00558 } 00559 int i, bLeft = tmp_data_left(); 00560 char *str, *wptr; 00561 str = m_trace.tmp_data_ptr; 00562 if (len == 0 || str == NULL || bLeft == 0) { 00563 return ""; 00564 } 00565 if (buf == NULL) { 00566 return "<null>"; 00567 } 00568 wptr = str; 00569 wptr[0] = 0; 00570 const uint8_t *ptr = buf; 00571 char overflow = 0; 00572 for (i = 0; i < len; i++) { 00573 if (bLeft <= 3) { 00574 overflow = 1; 00575 break; 00576 } 00577 int retval = snprintf(wptr, bLeft, "%02x:", *ptr++); 00578 if (retval <= 0 || retval > bLeft) { 00579 break; 00580 } 00581 bLeft -= retval; 00582 wptr += retval; 00583 } 00584 if (wptr > str) { 00585 if (overflow) { 00586 // replace last character as 'star', 00587 // which indicate buffer len is not enough 00588 *(wptr - 1) = '*'; 00589 } else { 00590 //null to replace last ':' character 00591 *(wptr - 1) = 0; 00592 } 00593 } 00594 m_trace.tmp_data_ptr = wptr; 00595 return str; 00596 }
Generated on Tue Jul 12 2022 13:54:34 by
