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

1.1       root        1: /*
1.1.1.4 ! root        2:  * Hatari - log.c
        !             3:  *
        !             4:  * This file is distributed under the GNU Public License, version 2 or at
        !             5:  * your option any later version. Read the file gpl.txt for details.
        !             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 HatariTraceFlags. Multiple trace levels can be set at once, by setting
        !            14:  * the corresponding bits in HatariTraceFlags
        !            15:  */
        !            16: const char Log_rcsid[] = "Hatari $Id: log.c,v 1.19 2008/10/29 20:12:17 eerot Exp $";
1.1       root       17: 
                     18: #include <stdio.h>
                     19: #include <stdarg.h>
1.1.1.4 ! root       20: #include <stdlib.h>
        !            21: #include <string.h>
        !            22: #include <ctype.h>
1.1       root       23: 
                     24: #include "main.h"
                     25: #include "configuration.h"
                     26: #include "dialog.h"
                     27: #include "log.h"
                     28: #include "screen.h"
1.1.1.3   root       29: #include "file.h"
1.1       root       30: 
                     31: 
1.1.1.4 ! root       32: struct {
        !            33:        Uint32 Level;
        !            34:        const char *Name;
        !            35: }
        !            36: TraceOptions[] = {
        !            37:        { HATARI_TRACE_VIDEO_SYNC       , "video_sync" } ,
        !            38:        { HATARI_TRACE_VIDEO_RES        , "video_res" } ,
        !            39:        { HATARI_TRACE_VIDEO_COLOR      , "video_color" } ,
        !            40:        { HATARI_TRACE_VIDEO_BORDER_V   , "video_border_v" } ,
        !            41:        { HATARI_TRACE_VIDEO_BORDER_H   , "video_border_h" } ,
        !            42:        { HATARI_TRACE_VIDEO_ADDR       , "video_addr" } ,
        !            43:        { HATARI_TRACE_VIDEO_HBL        , "video_hbl" } ,
        !            44:        { HATARI_TRACE_VIDEO_VBL        , "video_vbl" } ,
        !            45:        { HATARI_TRACE_VIDEO_STE        , "video_ste" } ,
        !            46:        { HATARI_TRACE_VIDEO_ALL        , "video_all" } ,
        !            47: 
        !            48:        { HATARI_TRACE_MFP_EXCEPTION    , "mfp_exception" } ,
        !            49:        { HATARI_TRACE_MFP_START        , "mfp_start" } ,
        !            50:        { HATARI_TRACE_MFP_READ         , "mfp_read" } ,
        !            51:        { HATARI_TRACE_MFP_WRITE        , "mfp_write" } ,
        !            52:        { HATARI_TRACE_MFP_ALL          , "mfp_all" } ,
        !            53: 
        !            54:        { HATARI_TRACE_PSG_WRITE_REG    , "psg_write_reg" } ,
        !            55:        { HATARI_TRACE_PSG_WRITE_DATA   , "psg_write_data" } ,
        !            56:        { HATARI_TRACE_PSG_ALL          , "psg_all" } ,
        !            57: 
        !            58:        { HATARI_TRACE_CPU_PAIRING      , "cpu_pairing" } ,
        !            59:        { HATARI_TRACE_CPU_DISASM       , "cpu_disasm" } ,
        !            60:        { HATARI_TRACE_CPU_EXCEPTION    , "cpu_exception" } ,
        !            61:        { HATARI_TRACE_CPU_ALL          , "cpu_all" } ,
        !            62: 
        !            63:        { HATARI_TRACE_INT              , "int" } ,
        !            64: 
        !            65:        { HATARI_TRACE_FDC              , "fdc" } ,
        !            66: 
        !            67:        { HATARI_TRACE_IKBD_CMDS        , "ikbd_cmds" } ,
        !            68:        { HATARI_TRACE_IKBD_ACIA        , "ikbd_acia" } ,
        !            69:        { HATARI_TRACE_IKBD_EXEC        , "ikbd_exec" } ,
        !            70:        { HATARI_TRACE_IKBD_ALL         , "ikbd_all" } ,
        !            71: 
        !            72:        { HATARI_TRACE_BLITTER          , "blitter" } ,
        !            73: 
        !            74:        { HATARI_TRACE_OS_BIOS          , "bios" },
        !            75:        { HATARI_TRACE_OS_XBIOS         , "xbios" },
        !            76:        { HATARI_TRACE_OS_GEMDOS        , "gemdos" },
        !            77:        { HATARI_TRACE_OS_VDI           , "vdi" },
        !            78:        { HATARI_TRACE_OS_ALL           , "os_all" } ,
        !            79: 
        !            80:        { HATARI_TRACE_ALL              , "all" }
        !            81: };
        !            82: 
        !            83: 
        !            84: Uint32 HatariTraceFlags = HATARI_TRACE_NONE;
        !            85: FILE *TraceFile = NULL;
        !            86: 
        !            87: static FILE *hLogFile = NULL;
        !            88: static LOGTYPE TextLogLevel;
        !            89: static LOGTYPE AlertDlgLogLevel;
1.1       root       90: 
                     91: /*-----------------------------------------------------------------------*/
1.1.1.3   root       92: /**
1.1.1.4 ! root       93:  * Initialize the logging and tracing functionality (open the log files etc.).
        !            94:  * 
        !            95:  * Return zero if that fails.
1.1.1.3   root       96:  */
1.1.1.4 ! root       97: int Log_Init(void)
1.1       root       98: {
1.1.1.4 ! root       99:        TextLogLevel = ConfigureParams.Log.nTextLogLevel;
        !           100:        AlertDlgLogLevel = ConfigureParams.Log.nAlertDlgLogLevel;
        !           101: 
1.1.1.3   root      102:        hLogFile = File_Open(ConfigureParams.Log.sLogFileName, "w");
1.1.1.4 ! root      103:        TraceFile = File_Open(ConfigureParams.Log.sTraceFileName, "w");
        !           104:    
        !           105:        return (hLogFile && TraceFile);
1.1       root      106: }
                    107: 
                    108: 
                    109: /*-----------------------------------------------------------------------*/
1.1.1.3   root      110: /**
1.1.1.4 ! root      111:  * Un-Initialize - close log files etc.
1.1.1.3   root      112:  */
1.1       root      113: void Log_UnInit(void)
                    114: {
1.1.1.3   root      115:        hLogFile = File_Close(hLogFile);
1.1.1.4 ! root      116:        TraceFile = File_Close(TraceFile);
1.1       root      117: }
                    118: 
                    119: 
                    120: /*-----------------------------------------------------------------------*/
1.1.1.3   root      121: /**
                    122:  * Output string to log file
                    123:  */
1.1       root      124: void Log_Printf(LOGTYPE nType, const char *psFormat, ...)
                    125: {
                    126:        va_list argptr;
                    127: 
1.1.1.4 ! root      128:        if (hLogFile && nType <= TextLogLevel)
1.1       root      129:        {
                    130:                va_start(argptr, psFormat);
                    131:                vfprintf(hLogFile, psFormat, argptr);
                    132:                va_end(argptr);
1.1.1.4 ! root      133:                /* Add a new-line if necessary: */
        !           134:                if (psFormat[strlen(psFormat)-1] != '\n')
        !           135:                        fputs("\n", hLogFile);
1.1       root      136:        }
                    137: }
                    138: 
                    139: 
                    140: /*-----------------------------------------------------------------------*/
1.1.1.3   root      141: /**
                    142:  * Show logging alert dialog box and output string to log file
                    143:  */
1.1       root      144: void Log_AlertDlg(LOGTYPE nType, const char *psFormat, ...)
                    145: {
                    146:        va_list argptr;
                    147: 
                    148:        /* Output to log file: */
1.1.1.4 ! root      149:        if (hLogFile && nType <= TextLogLevel)
1.1       root      150:        {
                    151:                va_start(argptr, psFormat);
                    152:                vfprintf(hLogFile, psFormat, argptr);
                    153:                va_end(argptr);
                    154:                /* Add a new-line if necessary: */
                    155:                if (psFormat[strlen(psFormat)-1] != '\n')
                    156:                        fputs("\n", hLogFile);
                    157:        }
                    158: 
                    159:        /* Show alert dialog box: */
1.1.1.4 ! root      160:        if (sdlscrn && nType <= AlertDlgLogLevel)
1.1       root      161:        {
                    162:                char *psTmpBuf;
                    163:                psTmpBuf = malloc(2048);
                    164:                if (!psTmpBuf)
                    165:                {
                    166:                        perror("Log_AlertDlg");
                    167:                        return;
                    168:                }
                    169:                va_start(argptr, psFormat);
                    170:                vsnprintf(psTmpBuf, 2048, psFormat, argptr);
                    171:                va_end(argptr);
                    172:                DlgAlert_Notice(psTmpBuf);
                    173:                free(psTmpBuf);
                    174:        }
                    175: }
1.1.1.4 ! root      176: 
        !           177: 
        !           178: /*-----------------------------------------------------------------------*/
        !           179: /**
        !           180:  * parse what log level should be used and return it
        !           181:  */
        !           182: LOGTYPE Log_ParseOptions(const char *arg)
        !           183: {
        !           184:        const char *levels[] = {
        !           185:                "fatal", "error", "warn", "info", "todo", "debug", NULL
        !           186:        };
        !           187:        LOGTYPE level = LOG_FATAL;
        !           188:        const char **level_str;
        !           189:        char *input, *str;
        !           190: 
        !           191:        input = strdup(arg);
        !           192:        str = input;
        !           193:        while (*str)
        !           194:        {
        !           195:                *str++ = tolower(*arg++);
        !           196:        }
        !           197:        for (level_str = levels; *level_str; level_str++, level++)
        !           198:        {
        !           199:                if (strcmp(input, *level_str) == 0)
        !           200:                {
        !           201:                        free(input);
        !           202:                        return level;
        !           203:                }
        !           204:        }
        !           205:        free(input);
        !           206:        return level;
        !           207: }
        !           208: 
        !           209: /*-----------------------------------------------------------------------*/
        !           210: /**
        !           211:  * Parse a list of comma separated strings.
        !           212:  * If the string is prefixed with an optional '+',
        !           213:  * corresponding trace flag is turned on.
        !           214:  * If the string is prefixed with a '-',
        !           215:  * corresponding trace flag is turned off.
        !           216:  * Result is stored in HatariTraceFlags.
        !           217:  */
        !           218: bool Log_SetTraceOptions (const char *OptionsStr)
        !           219: {
        !           220:        char *OptionsCopy;
        !           221:        char *cur, *sep;
        !           222:        int i;
        !           223:        int Mode;                               /* 0=add, 1=del */
        !           224:        int MaxOptions;
        !           225: 
        !           226:        MaxOptions = sizeof(TraceOptions) / sizeof(TraceOptions[0]);
        !           227:        
        !           228:        /* special case for "help" : display the list of possible trace levels */
        !           229:        if (strcmp (OptionsStr, "help") == 0)
        !           230:        {
        !           231:                fprintf(stderr, "\nList of available trace levels :\n");
        !           232:                
        !           233:                for (i = 0; i < MaxOptions; i++)
        !           234:                        fprintf(stderr, "  %s\n", TraceOptions[i].Name);
        !           235:                
        !           236:                fprintf(stderr, "Multiple trace levels can be separated by ','\n");
        !           237:                fprintf(stderr, "Levels can be prefixed by '+' or '-' to be mixed.\n");
        !           238:                fprintf(stderr, "Giving just trace level 'none' disables all traces.\n\n");
        !           239:                return FALSE;
        !           240:        }
        !           241: 
        !           242: #ifndef HATARI_TRACE_ACTIVATED
        !           243:        fprintf(stderr, "\nError: Trace option has not been activated during compile time.\n");
        !           244:        return FALSE;
        !           245: #endif
        !           246:        
        !           247:        HatariTraceFlags = HATARI_TRACE_NONE;
        !           248:        if (strcmp (OptionsStr, "none") == 0)
        !           249:        {
        !           250:                return TRUE;
        !           251:        }
        !           252:        
        !           253:        OptionsCopy = strdup(OptionsStr);
        !           254:        if (!OptionsCopy)
        !           255:        {
        !           256:                fprintf(stderr, "strdup error in ParseTraceOptions\n");
        !           257:                return FALSE;
        !           258:        }
        !           259:        
        !           260:        cur = OptionsCopy;
        !           261:        while (cur)
        !           262:        {
        !           263:                sep = strchr(cur, ',');
        !           264:                if (sep)                        /* end of next options */
        !           265:                        *sep++ = '\0';
        !           266:                
        !           267:                Mode = 0;                               /* default is 'add' */
        !           268:                if (*cur == '+')
        !           269:                { Mode = 0; cur++; }
        !           270:                else if (*cur == '-')
        !           271:                { Mode = 1; cur++; }
        !           272:                
        !           273:                for (i = 0; i < MaxOptions; i++)
        !           274:                {
        !           275:                        if (strcmp(cur, TraceOptions[i].Name) == 0)
        !           276:                                break;
        !           277:                }
        !           278:                
        !           279:                if (i < MaxOptions)             /* option found */
        !           280:                {
        !           281:                        if (Mode == 0)
        !           282:                                HatariTraceFlags |= TraceOptions[i].Level;
        !           283:                        else
        !           284:                                HatariTraceFlags &= (~TraceOptions[i].Level);
        !           285:                }
        !           286:                else
        !           287:                {
        !           288:                        fprintf(stderr, "unknown trace option %s\n", cur);
        !           289:                        free(OptionsCopy);
        !           290:                        return FALSE;
        !           291:                }
        !           292:                
        !           293:                cur = sep;
        !           294:        }
        !           295:        
        !           296:        //fprintf(stderr, "trace parse <%x>\n", HatariTraceFlags);
        !           297:        
        !           298:        free (OptionsCopy);
        !           299:        return TRUE;
        !           300: }

unix.superglobalmegacorp.com

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