1b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* 2b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland 3b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * 4b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Licensed under the Apache License, Version 2.0 (the "License"); 5b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * you may not use this file except in compliance with the License. 6b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * You may obtain a copy of the License at 7b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * 8b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * http://www.apache.org/licenses/LICENSE-2.0 9b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * 10b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Unless required by applicable law or agreed to in writing, software 11b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * distributed under the License is distributed on an "AS IS" BASIS, 12b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * See the License for the specific language governing permissions and 14b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * limitations under the License. 15b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */ 16b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** 17b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @file picodbg.c 18b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * 19b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Provides functions and macros to debug the Pico system and to trace 20b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * the execution of its code. 21b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * 22b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland 23b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * All rights reserved. 24b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * 25b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * History: 26b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * - 2009-04-20 -- initial version 27b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */ 28b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 29b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#ifdef __cplusplus 30b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenextern "C" { 31b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif 32b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if 0 33b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 34b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif 35b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 36b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 37b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if defined(PICO_DEBUG) 38b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 39b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Two variants of colored console output are implemented: 40b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen COLOR_MODE_WINDOWS 41b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen uses the Windows API function SetConsoleTextAttribute 42b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen COLOR_MODE_ANSI 43b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen uses ANSI escape codes */ 44b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if defined(_WIN32) 45b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define COLOR_MODE_WINDOWS 46b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#else 47b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define COLOR_MODE_ANSI 48b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif 49b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 50b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 51b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <stdio.h> 52b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <stdlib.h> 53b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 54b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <stdarg.h> 55b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <string.h> 56b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 57b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picodbg.h" 58b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 59b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 60b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Maximum length of a formatted tracing message */ 61b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define MAX_MESSAGE_LEN 999 62b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 63b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Maximum length of contextual information */ 64b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define MAX_CONTEXT_LEN 499 65b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 66b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Maximum length of filename filter */ 67b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define MAX_FILTERFN_LEN 16 68b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 69b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Delimiter used in debug messages */ 70b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define MSG_DELIM "|" 71b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 72b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Standard output file for debug messages */ 73b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define STDDBG stdout /* or stderr */ 74b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 75b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Default setup */ 76b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICODBG_DEFAULT_LEVEL PICODBG_LOG_LEVEL_WARN 77b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICODBG_DEFAULT_FILTERFN "" 78b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICODBG_DEFAULT_FORMAT \ 79b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen (PICODBG_SHOW_LEVEL | PICODBG_SHOW_SRCNAME | PICODBG_SHOW_FUNCTION) 80b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICODBG_DEFAULT_COLOR 1 81b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 82b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 83b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Current log level */ 84b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic int logLevel = PICODBG_DEFAULT_LEVEL; 85b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 86b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Current log filter (filename) */ 87b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic char logFilterFN[MAX_FILTERFN_LEN + 1]; 88b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 89b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Current log file or NULL if no log file is set */ 90b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic FILE *logFile = NULL; 91b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 92b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Current output format */ 93b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic int logFormat = PICODBG_DEFAULT_FORMAT; 94b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 95b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Color mode for console output (0 : disable colors, != 0 : enable colors */ 96b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic int optColor = 0; 97b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 98b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Buffer for context information */ 99b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic char ctxbuf[MAX_CONTEXT_LEN + 1]; 100b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 101b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Buffer to format tracing messages */ 102b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic char msgbuf[MAX_MESSAGE_LEN + 1]; 103b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 104b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 105b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *** Support for colored text output to console *****/ 106b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 107b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 108b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Console text colors */ 109b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenenum color_t { 110b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen /* order matches Windows color codes */ 111b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen ColorBlack, 112b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen ColorBlue, 113b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen ColorGreen, 114b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen ColorCyan, 115b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen ColorRed, 116b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen ColorPurple, 117b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen ColorBrown, 118b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen ColorLightGray, 119b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen ColorDarkGray, 120b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen ColorLightBlue, 121b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen ColorLightGreen, 122b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen ColorLightCyan, 123b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen ColorLightRed, 124b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen ColorLightPurple, 125b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen ColorYellow, 126b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen ColorWhite 127b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}; 128b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 129b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 130b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic enum color_t picodbg_getLevelColor(int level) 131b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 132b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen switch (level) { 133b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case PICODBG_LOG_LEVEL_ERROR: return ColorLightRed; 134b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case PICODBG_LOG_LEVEL_WARN : return ColorYellow; 135b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case PICODBG_LOG_LEVEL_INFO : return ColorGreen; 136b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case PICODBG_LOG_LEVEL_DEBUG: return ColorLightGray; 137b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case PICODBG_LOG_LEVEL_TRACE: return ColorDarkGray; 138b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 139b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return ColorWhite; 140b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 141b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 142b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 143b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if defined(COLOR_MODE_WINDOWS) 144b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 145b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define WIN32_LEAN_AND_MEAN 146b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <windows.h> 147b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 148b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic int picodbg_setTextAttr(FILE *stream, int attr) 149b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 150b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen HANDLE hConsole; 151b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 152b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (stream == stdout) { 153b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 154b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } else if (stream == stderr) { 155b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen hConsole = GetStdHandle(STD_ERROR_HANDLE); 156b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } else { 157b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen hConsole = INVALID_HANDLE_VALUE; 158b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 159b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 160b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (hConsole != INVALID_HANDLE_VALUE) { 161b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen /* do nothing if console output is redirected to a file */ 162b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (GetFileType(hConsole) == FILE_TYPE_CHAR) { 163b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen CONSOLE_SCREEN_BUFFER_INFO csbi; 164b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen GetConsoleScreenBufferInfo(hConsole, &csbi); 165b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen SetConsoleTextAttribute(hConsole, (WORD) attr); 166b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return (int) csbi.wAttributes; 167b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 168b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 169b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 170b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return 0; 171b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 172b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 173b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#elif defined(COLOR_MODE_ANSI) 174b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 175b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic int picodbg_setTextAttr(FILE *stream, int attr) 176b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 177b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen const char *c = ""; 178b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 179b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (attr == -1) { 180b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen c = "0"; 181b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } else switch (attr) { 182b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case ColorBlack: c = "0;30"; break; 183b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case ColorRed: c = "0;31"; break; 184b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case ColorGreen: c = "0;32"; break; 185b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case ColorBrown: c = "0;33"; break; 186b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case ColorBlue: c = "0;34"; break; 187b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case ColorPurple: c = "0;35"; break; 188b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case ColorCyan: c = "0;36"; break; 189b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case ColorLightGray: c = "0;37"; break; 190b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case ColorDarkGray: c = "1;30"; break; 191b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case ColorLightRed: c = "1;31"; break; 192b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case ColorLightGreen: c = "1;32"; break; 193b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case ColorYellow: c = "1;33"; break; 194b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case ColorLightBlue: c = "1;34"; break; 195b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case ColorLightPurple: c = "1;35"; break; 196b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case ColorLightCyan: c = "1;36"; break; 197b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case ColorWhite: c = "1;37"; break; 198b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 199b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 200b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen fprintf(stream, "\x1b[%sm", c); 201b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return -1; 202b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 203b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 204b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#else 205b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 206b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic int picodbg_setTextAttr(FILE *stream, int attr) 207b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 208b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen /* avoid 'unreferenced formal parameter' */ 209b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen (void) stream; 210b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen (void) attr; 211b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return 0; 212b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 213b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 214b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif 215b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 216b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 217b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *** Auxiliary routines *****/ 218b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 219b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 220b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic const char *picodbg_fileTitle(const char *file) 221b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 222b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen const char *name = file, *str = file; 223b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 224b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen /* try to extract file name without path in a platform independent 225b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen way, i.e., skip all chars preceding path separator chars like 226b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen '/' (Unix, MacOSX), '\' (Windows, DOS), and ':' (MacOS9) */ 227b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen while (*str) { 228b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if ((*str == '\\') || (*str == '/') || (*str == ':')) { 229b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen name = str + 1; 230b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 231b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen str++; 232b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 233b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 234b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return name; 235b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 236b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 237b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 238b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic void picodbg_logToStream(int level, int donewline, 239b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen const char *context, const char *msg) 240b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 241b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen int oldAttr = 0; 242b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 243b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (optColor) { 244b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen oldAttr = picodbg_setTextAttr(STDDBG, picodbg_getLevelColor(level)); 245b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 246b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 247b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen fprintf(STDDBG, "%s%s", context, msg); 248b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (donewline) fprintf(STDDBG, "\n"); 249b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (logFile != NULL) { 250b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen fprintf(logFile, "%s%s", context, msg); 251b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (donewline) fprintf(logFile, "\n"); 252b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 253b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 254b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (optColor) { 255b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picodbg_setTextAttr(STDDBG, oldAttr); 256b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 257b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 258b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 259b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 260b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *** Exported routines *****/ 261b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 262b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 263b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picodbg_initialize(int level) 264b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 265b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen logLevel = level; 266b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcpy(logFilterFN, PICODBG_DEFAULT_FILTERFN); 267b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen logFile = NULL; 268b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen logFormat = PICODBG_DEFAULT_FORMAT; 269b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen optColor = PICODBG_DEFAULT_COLOR; 270b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen PICODBG_ASSERT_RANGE(level, 0, PICODBG_LOG_LEVEL_TRACE); 271b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 272b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 273b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 274b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picodbg_terminate() 275b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 276b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (logFile != NULL) { 277b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen fclose(logFile); 278b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 279b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 280b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen logLevel = 0; 281b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen logFile = NULL; 282b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 283b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 284b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 285b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picodbg_setLogLevel(int level) 286b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 287b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen PICODBG_ASSERT_RANGE(level, 0, PICODBG_LOG_LEVEL_TRACE); 288b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen logLevel = level; 289b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 290b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 291b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 292b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picodbg_setLogFilterFN(const char *name) 293b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 294b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcpy(logFilterFN, name); 295b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 296b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 297b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 298b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picodbg_setLogFile(const char *name) 299b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 300b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (logFile != NULL) { 301b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen fclose(logFile); 302b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 303b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 304b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if ((name != NULL) && (strlen(name) > 0)) { 305b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen logFile = fopen(name, "wt"); 306b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } else { 307b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen logFile = NULL; 308b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 309b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 310b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 311b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 312b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picodbg_enableColors(int flag) 313b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 314b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen optColor = (flag != 0); 315b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 316b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 317b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 318b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picodbg_setOutputFormat(unsigned int format) 319b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 320b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen logFormat = format; 321b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 322b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 323b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 324b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenconst char *picodbg_varargs(const char *format, ...) 325b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 326b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen int len; 327b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 328b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen va_list argptr; 329b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen va_start(argptr, format); 330b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 331b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen len = vsprintf(msgbuf, format, argptr); 332b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen PICODBG_ASSERT_RANGE(len, 0, MAX_MESSAGE_LEN); 333b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 334b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return msgbuf; 335b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 336b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 337b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 338b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picodbg_log(int level, int donewline, const char *file, int line, 339b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen const char *func, const char *msg) 340b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 341b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen char cb[MAX_CONTEXT_LEN + 1]; 342b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 343b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen PICODBG_ASSERT_RANGE(level, 0, PICODBG_LOG_LEVEL_TRACE); 344b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 345b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if ((level <= logLevel) && 346b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen ((strlen(logFilterFN) == 0) || !strcmp(logFilterFN, picodbg_fileTitle(file)))) { 347b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen /* compose output format string */ 348b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcpy(ctxbuf, "*** "); 349b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (logFormat & PICODBG_SHOW_LEVEL) { 350b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen switch (level) { 351b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case PICODBG_LOG_LEVEL_ERROR: 352b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(ctxbuf, "error" MSG_DELIM); 353b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 354b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case PICODBG_LOG_LEVEL_WARN: 355b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(ctxbuf, "warn " MSG_DELIM); 356b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 357b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case PICODBG_LOG_LEVEL_INFO: 358b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(ctxbuf, "info " MSG_DELIM); 359b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 360b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case PICODBG_LOG_LEVEL_DEBUG: 361b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(ctxbuf, "debug" MSG_DELIM); 362b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 363b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen case PICODBG_LOG_LEVEL_TRACE: 364b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(ctxbuf, "trace" MSG_DELIM); 365b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 366b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen default: 367b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 368b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 369b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 370b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (logFormat & PICODBG_SHOW_DATE) { 371b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen /* nyi */ 372b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 373b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (logFormat & PICODBG_SHOW_TIME) { 374b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen /* nyi */ 375b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 376b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (logFormat & PICODBG_SHOW_SRCNAME) { 377b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(cb, "%-10s", picodbg_fileTitle(file)); 378b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(ctxbuf, cb); 379b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (logFormat & PICODBG_SHOW_SRCLINE) { 380b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(cb, "(%d)", line); 381b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(ctxbuf, cb); 382b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 383b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(ctxbuf, MSG_DELIM); 384b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 385b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (logFormat & PICODBG_SHOW_FUNCTION) { 386b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (strlen(func) > 0) { 387b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(cb, "%-18s", func); 388b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(ctxbuf, cb); 389b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(ctxbuf, MSG_DELIM); 390b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 391b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 392b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 393b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picodbg_logToStream(level, donewline, ctxbuf, msg); 394b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 395b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 396b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 397b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 398b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picodbg_log_msg(int level, const char *file, const char *msg) 399b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 400b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen PICODBG_ASSERT_RANGE(level, 0, PICODBG_LOG_LEVEL_TRACE); 401b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 402b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if ((level <= logLevel) && 403b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen ((strlen(logFilterFN) == 0) || !strcmp(logFilterFN, picodbg_fileTitle(file)))) { 404b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picodbg_logToStream(level, 0, "", msg); 405b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 406b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 407b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 408b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 409b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picodbg_assert(const char *file, int line, const char *func, const char *expr) 410b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 411b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (strlen(func) > 0) { 412b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen fprintf(STDDBG, "assertion failed: %s, file %s, function %s, line %d", 413b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen expr, picodbg_fileTitle(file), func, line); 414b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } else { 415b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen fprintf(STDDBG, "assertion failed: %s, file %s, line %d", 416b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen expr, picodbg_fileTitle(file), line); 417b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 418b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picodbg_terminate(); 419b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen abort(); 420b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 421b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 422b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 423b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#else 424b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 425b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* To prevent warning about "translation unit is empty" when 426b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen diagnostic output is disabled. */ 427b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic void picodbg_dummy(void) { 428b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picodbg_dummy(); 429b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 430b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 431b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif /* defined(PICO_DEBUG) */ 432b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 433b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#ifdef __cplusplus 434b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 435b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif 436b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 437b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 438b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* end */ 439