Annotation of hatari/src/debug/log.c, revision 1.1.1.4

1.1       root        1: /*
                      2:  * Hatari - log.c
                      3:  *
1.1.1.4 ! root        4:  * This file is distributed under the GNU General Public License, version 2
        !             5:  * or at your option any later version. Read the file gpl.txt for details.
1.1       root        6:  *
                      7:  * Logger functions.
                      8:  *
                      9:  * When Hatari runs, it can output information, debug, warning and error texts
                     10:  * to the error log file and/or displays them in alert dialog boxes.
                     11:  *
                     12:  * It can also dynamically output trace messages, based on the content
                     13:  * of LogTraceFlags. Multiple trace levels can be set at once, by setting
                     14:  * the corresponding bits in LogTraceFlags.
                     15:  */
                     16: const char Log_fileid[] = "Hatari log.c : " __DATE__ " " __TIME__;
                     17: 
                     18: #include <stdio.h>
                     19: #include <stdarg.h>
                     20: #include <stdlib.h>
                     21: #include <string.h>
                     22: #include <ctype.h>
                     23: 
                     24: #include "main.h"
                     25: #include "configuration.h"
                     26: #include "dialog.h"
                     27: #include "log.h"
                     28: #include "screen.h"
                     29: #include "file.h"
1.1.1.2   root       30: #include "vdi.h"
1.1       root       31: 
1.1.1.3   root       32: #if ENABLE_TRACING
1.1       root       33: static struct {
1.1.1.2   root       34:        Uint64 Level;
1.1       root       35:        const char *Name;
                     36: }
                     37: TraceOptions[] = {
                     38:        { TRACE_NONE             , "none" },
                     39: 
                     40:        { TRACE_VIDEO_SYNC       , "video_sync" } ,
                     41:        { TRACE_VIDEO_RES        , "video_res" } ,
                     42:        { TRACE_VIDEO_COLOR      , "video_color" } ,
                     43:        { TRACE_VIDEO_BORDER_V   , "video_border_v" } ,
                     44:        { TRACE_VIDEO_BORDER_H   , "video_border_h" } ,
                     45:        { TRACE_VIDEO_ADDR       , "video_addr" } ,
                     46:        { TRACE_VIDEO_HBL        , "video_hbl" } ,
                     47:        { TRACE_VIDEO_VBL        , "video_vbl" } ,
                     48:        { TRACE_VIDEO_STE        , "video_ste" } ,
                     49:        { TRACE_VIDEO_ALL        , "video_all" } ,
                     50: 
                     51:        { TRACE_MFP_EXCEPTION    , "mfp_exception" } ,
                     52:        { TRACE_MFP_START        , "mfp_start" } ,
                     53:        { TRACE_MFP_READ         , "mfp_read" } ,
                     54:        { TRACE_MFP_WRITE        , "mfp_write" } ,
                     55:        { TRACE_MFP_ALL          , "mfp_all" } ,
                     56: 
                     57:        { TRACE_PSG_READ         , "psg_read" } ,
                     58:        { TRACE_PSG_WRITE        , "psg_write" } ,
                     59:        { TRACE_PSG_ALL          , "psg_all" } ,
                     60: 
                     61:        { TRACE_CPU_PAIRING      , "cpu_pairing" } ,
                     62:        { TRACE_CPU_DISASM       , "cpu_disasm" } ,
                     63:        { TRACE_CPU_EXCEPTION    , "cpu_exception" } ,
                     64:        { TRACE_CPU_ALL          , "cpu_all" } ,
                     65: 
                     66:        { TRACE_INT              , "int" } ,
                     67: 
                     68:        { TRACE_FDC              , "fdc" } ,
                     69: 
1.1.1.4 ! root       70:        { TRACE_ACIA             , "acia" } ,
        !            71: 
1.1       root       72:        { TRACE_IKBD_CMDS        , "ikbd_cmds" } ,
                     73:        { TRACE_IKBD_ACIA        , "ikbd_acia" } ,
                     74:        { TRACE_IKBD_EXEC        , "ikbd_exec" } ,
                     75:        { TRACE_IKBD_ALL         , "ikbd_all" } ,
                     76: 
                     77:        { TRACE_BLITTER          , "blitter" } ,
                     78: 
                     79:        { TRACE_OS_BIOS          , "bios" },
                     80:        { TRACE_OS_XBIOS         , "xbios" },
                     81:        { TRACE_OS_GEMDOS        , "gemdos" },
                     82:        { TRACE_OS_VDI           , "vdi" },
1.1.1.2   root       83:        { TRACE_OS_AES           , "aes" },
1.1       root       84:        { TRACE_OS_ALL           , "os_all" } ,
                     85: 
                     86:        { TRACE_IOMEM_RD         , "io_read" } ,
                     87:        { TRACE_IOMEM_WR         , "io_write" } ,
                     88:        { TRACE_IOMEM_ALL        , "io_all" } ,
                     89: 
                     90:        { TRACE_DMASND           , "dmasound" } ,
                     91: 
                     92:        { TRACE_CROSSBAR         , "crossbar" } ,
                     93: 
1.1.1.2   root       94:        { TRACE_VIDEL            , "videl" } ,
                     95: 
                     96:        { TRACE_DSP_HOST_INTERFACE, "dsp_host_interface" },
                     97:        { TRACE_DSP_HOST_COMMAND , "dsp_host_command" },
                     98:        { TRACE_DSP_HOST_SSI     , "dsp_host_ssi" },
                     99:        { TRACE_DSP_INTERRUPT    , "dsp_interrupt" },
                    100:        { TRACE_DSP_DISASM       , "dsp_disasm" },
                    101:        { TRACE_DSP_DISASM_REG   , "dsp_disasm_reg" },
                    102:        { TRACE_DSP_DISASM_MEM   , "dsp_disasm_mem" },
                    103:        { TRACE_DSP_STATE        , "dsp_state" },
                    104:        { TRACE_DSP_ALL          , "dsp_all" },
                    105: 
1.1.1.3   root      106:        { TRACE_DSP_SYMBOLS      , "dsp_symbols" },
                    107:        { TRACE_CPU_SYMBOLS      , "cpu_symbols" },
                    108: 
1.1.1.4 ! root      109:        { TRACE_NVRAM            , "nvram" } ,
        !           110: 
1.1       root      111:        { TRACE_ALL              , "all" }
                    112: };
1.1.1.3   root      113: #endif /* ENABLE_TRACING */
1.1       root      114: 
                    115: 
1.1.1.2   root      116: Uint64 LogTraceFlags = TRACE_NONE;
1.1       root      117: FILE *TraceFile = NULL;
                    118: 
                    119: static FILE *hLogFile = NULL;
                    120: static LOGTYPE TextLogLevel;
                    121: static LOGTYPE AlertDlgLogLevel;
                    122: 
                    123: /*-----------------------------------------------------------------------*/
                    124: /**
                    125:  * Initialize the logging and tracing functionality (open the log files etc.).
                    126:  * 
                    127:  * Return zero if that fails.
                    128:  */
                    129: int Log_Init(void)
                    130: {
                    131:        TextLogLevel = ConfigureParams.Log.nTextLogLevel;
                    132:        AlertDlgLogLevel = ConfigureParams.Log.nAlertDlgLogLevel;
                    133: 
                    134:        hLogFile = File_Open(ConfigureParams.Log.sLogFileName, "w");
                    135:        TraceFile = File_Open(ConfigureParams.Log.sTraceFileName, "w");
                    136:    
                    137:        return (hLogFile && TraceFile);
                    138: }
                    139: 
                    140: /**
                    141:  * Set Alert log level temporarily without config change.
                    142:  * 
                    143:  * Return old level for restoring the original level with this.
                    144:  */
                    145: int Log_SetAlertLevel(int level)
                    146: {
                    147:        int old = AlertDlgLogLevel;
                    148:        AlertDlgLogLevel = level;
                    149:        return old;
                    150: }
                    151: 
                    152: 
                    153: /*-----------------------------------------------------------------------*/
                    154: /**
                    155:  * Un-Initialize - close log files etc.
                    156:  */
                    157: void Log_UnInit(void)
                    158: {
                    159:        hLogFile = File_Close(hLogFile);
                    160:        TraceFile = File_Close(TraceFile);
                    161: }
                    162: 
                    163: 
                    164: /*-----------------------------------------------------------------------*/
                    165: /**
                    166:  * Output string to log file
                    167:  */
                    168: void Log_Printf(LOGTYPE nType, const char *psFormat, ...)
                    169: {
                    170:        va_list argptr;
                    171: 
                    172:        if (hLogFile && nType <= TextLogLevel)
                    173:        {
                    174:                va_start(argptr, psFormat);
                    175:                vfprintf(hLogFile, psFormat, argptr);
                    176:                va_end(argptr);
                    177:                /* Add a new-line if necessary: */
                    178:                if (psFormat[strlen(psFormat)-1] != '\n')
                    179:                        fputs("\n", hLogFile);
                    180:        }
                    181: }
                    182: 
                    183: 
                    184: /*-----------------------------------------------------------------------*/
                    185: /**
                    186:  * Show logging alert dialog box and output string to log file
                    187:  */
                    188: void Log_AlertDlg(LOGTYPE nType, const char *psFormat, ...)
                    189: {
                    190:        va_list argptr;
                    191: 
                    192:        /* Output to log file: */
                    193:        if (hLogFile && nType <= TextLogLevel)
                    194:        {
                    195:                va_start(argptr, psFormat);
                    196:                vfprintf(hLogFile, psFormat, argptr);
                    197:                va_end(argptr);
                    198:                /* Add a new-line if necessary: */
                    199:                if (psFormat[strlen(psFormat)-1] != '\n')
                    200:                        fputs("\n", hLogFile);
                    201:        }
                    202: 
                    203:        /* Show alert dialog box: */
                    204:        if (sdlscrn && nType <= AlertDlgLogLevel)
                    205:        {
                    206:                char *psTmpBuf;
                    207:                psTmpBuf = malloc(2048);
                    208:                if (!psTmpBuf)
                    209:                {
                    210:                        perror("Log_AlertDlg");
                    211:                        return;
                    212:                }
                    213:                va_start(argptr, psFormat);
                    214:                vsnprintf(psTmpBuf, 2048, psFormat, argptr);
                    215:                va_end(argptr);
                    216:                DlgAlert_Notice(psTmpBuf);
                    217:                free(psTmpBuf);
                    218:        }
                    219: }
                    220: 
                    221: 
                    222: /*-----------------------------------------------------------------------*/
                    223: /**
                    224:  * parse what log level should be used and return it
                    225:  */
                    226: LOGTYPE Log_ParseOptions(const char *arg)
                    227: {
                    228:        const char *levels[] = {
                    229:                "fatal", "error", "warn", "info", "todo", "debug", NULL
                    230:        };
                    231:        LOGTYPE level = LOG_FATAL;
                    232:        const char **level_str;
                    233:        char *input, *str;
                    234: 
                    235:        input = strdup(arg);
                    236:        str = input;
                    237:        while (*str)
                    238:        {
                    239:                *str++ = tolower(*arg++);
                    240:        }
                    241:        for (level_str = levels; *level_str; level_str++, level++)
                    242:        {
                    243:                if (strcmp(input, *level_str) == 0)
                    244:                {
                    245:                        free(input);
                    246:                        return level;
                    247:                }
                    248:        }
                    249:        free(input);
                    250:        return level;
                    251: }
                    252: 
                    253: 
                    254: #if ENABLE_TRACING
                    255: 
                    256: /*-----------------------------------------------------------------------*/
                    257: /**
                    258:  * Parse a list of comma separated strings.
                    259:  * If the string is prefixed with an optional '+',
                    260:  * corresponding trace flag is turned on.
                    261:  * If the string is prefixed with a '-',
                    262:  * corresponding trace flag is turned off.
                    263:  * Result is stored in LogTraceFlags.
                    264:  * Return error string (""=silent 'error') or NULL for success.
                    265:  */
                    266: const char* Log_SetTraceOptions (const char *OptionsStr)
                    267: {
                    268:        char *OptionsCopy;
                    269:        char *cur, *sep;
                    270:        int i;
                    271:        int Mode;                               /* 0=add, 1=del */
                    272:        int MaxOptions;
                    273: 
                    274:        MaxOptions = ARRAYSIZE(TraceOptions);
                    275:        
                    276:        /* special case for "help" : display the list of possible trace levels */
                    277:        if (strcmp (OptionsStr, "help") == 0)
                    278:        {
                    279:                fprintf(stderr, "\nList of available trace levels :\n");
                    280:                
                    281:                for (i = 0; i < MaxOptions; i++)
                    282:                        fprintf(stderr, "  %s\n", TraceOptions[i].Name);
                    283:                
                    284:                fprintf(stderr, "Multiple trace levels can be separated by ','\n");
                    285:                fprintf(stderr, "Levels can be prefixed by '+' or '-' to be mixed.\n");
                    286:                fprintf(stderr, "Giving just trace level 'none' disables all traces.\n\n");
                    287:                return "";
                    288:        }
                    289:        
                    290:        LogTraceFlags = TRACE_NONE;
                    291:        if (strcmp (OptionsStr, "none") == 0)
                    292:        {
                    293:                return NULL;
                    294:        }
                    295:        
                    296:        OptionsCopy = strdup(OptionsStr);
                    297:        if (!OptionsCopy)
                    298:        {
                    299:                return "strdup error in ParseTraceOptions";
                    300:        }
                    301:        
                    302:        cur = OptionsCopy;
                    303:        while (cur)
                    304:        {
                    305:                sep = strchr(cur, ',');
                    306:                if (sep)                        /* end of next options */
                    307:                        *sep++ = '\0';
                    308:                
                    309:                Mode = 0;                               /* default is 'add' */
                    310:                if (*cur == '+')
                    311:                { Mode = 0; cur++; }
                    312:                else if (*cur == '-')
                    313:                { Mode = 1; cur++; }
                    314:                
                    315:                for (i = 0; i < MaxOptions; i++)
                    316:                {
                    317:                        if (strcmp(cur, TraceOptions[i].Name) == 0)
                    318:                                break;
                    319:                }
                    320:                
                    321:                if (i < MaxOptions)             /* option found */
                    322:                {
                    323:                        if (Mode == 0)
                    324:                                LogTraceFlags |= TraceOptions[i].Level;
                    325:                        else
                    326:                                LogTraceFlags &= (~TraceOptions[i].Level);
                    327:                }
                    328:                else
                    329:                {
                    330:                        fprintf(stderr, "Unknown trace type '%s'\n", cur);
                    331:                        free(OptionsCopy);
                    332:                        return "Unknown trace type.";
                    333:                }
                    334:                
                    335:                cur = sep;
                    336:        }
1.1.1.2   root      337: 
                    338:        /* Enable Hatari flags needed for tracing selected items.
                    339:         * 
                    340:         * Doesn't enable bBiosInterception for X/Bios because
                    341:         * that implies other things in addition to tracing.
                    342:         */
                    343:        if (LogTraceFlags & (TRACE_OS_AES|TRACE_OS_VDI))
                    344:                bVdiAesIntercept = true;
                    345: 
1.1       root      346:        //fprintf(stderr, "trace parse <%x>\n", LogTraceFlags);
                    347:        
                    348:        free (OptionsCopy);
                    349:        return NULL;
                    350: }
                    351: 
                    352: 
                    353: /**
                    354:  * Readline match callback for trace type name completion.
                    355:  * STATE = 0 -> different text from previous one.
                    356:  * Return next match or NULL if no matches.
                    357:  */
                    358: char *Log_MatchTrace(const char *text, int state)
                    359: {
                    360:        static int i, len;
                    361:        const char *name;
                    362:        
                    363:        if (!state) {
                    364:                /* first match */
                    365:                len = strlen(text);
                    366:                i = 0;
                    367:        }
                    368:        /* next match */
                    369:        while (i < ARRAYSIZE(TraceOptions)) {
                    370:                name = TraceOptions[i++].Name;
                    371:                if (strncasecmp(name, text, len) == 0)
                    372:                        return (strdup(name));
                    373:        }
                    374:        return NULL;
                    375: }
                    376: 
                    377: #else  /* !ENABLE_TRACING */
                    378: 
                    379: /** dummy */
                    380: const char* Log_SetTraceOptions (const char *OptionsStr)
                    381: {
                    382:        return "Hatari has been compiled without ENABLE_TRACING!";
                    383: }
                    384: 
                    385: /** dummy */
                    386: char *Log_MatchTrace(const char *text, int state)
                    387: {
                    388:        return NULL;
                    389: }
                    390: 
                    391: #endif /* !ENABLE_TRACING */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.