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

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
1.1.1.6 ! root       13:  * of LogTraceFlags. Multiple trace levels can be set at once, by setting
        !            14:  * the corresponding bits in LogTraceFlags.
1.1.1.4   root       15:  */
1.1.1.5   root       16: const char Log_fileid[] = "Hatari log.c : " __DATE__ " " __TIME__;
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[] = {
1.1.1.6 ! root       37:        { TRACE_NONE             , "none" },
1.1.1.4   root       38: 
1.1.1.6 ! root       39:        { TRACE_VIDEO_SYNC       , "video_sync" } ,
        !            40:        { TRACE_VIDEO_RES        , "video_res" } ,
        !            41:        { TRACE_VIDEO_COLOR      , "video_color" } ,
        !            42:        { TRACE_VIDEO_BORDER_V   , "video_border_v" } ,
        !            43:        { TRACE_VIDEO_BORDER_H   , "video_border_h" } ,
        !            44:        { TRACE_VIDEO_ADDR       , "video_addr" } ,
        !            45:        { TRACE_VIDEO_HBL        , "video_hbl" } ,
        !            46:        { TRACE_VIDEO_VBL        , "video_vbl" } ,
        !            47:        { TRACE_VIDEO_STE        , "video_ste" } ,
        !            48:        { TRACE_VIDEO_ALL        , "video_all" } ,
        !            49: 
        !            50:        { TRACE_MFP_EXCEPTION    , "mfp_exception" } ,
        !            51:        { TRACE_MFP_START        , "mfp_start" } ,
        !            52:        { TRACE_MFP_READ         , "mfp_read" } ,
        !            53:        { TRACE_MFP_WRITE        , "mfp_write" } ,
        !            54:        { TRACE_MFP_ALL          , "mfp_all" } ,
        !            55: 
        !            56:        { TRACE_PSG_READ         , "psg_read" } ,
        !            57:        { TRACE_PSG_WRITE        , "psg_write" } ,
        !            58:        { TRACE_PSG_ALL          , "psg_all" } ,
        !            59: 
        !            60:        { TRACE_CPU_PAIRING      , "cpu_pairing" } ,
        !            61:        { TRACE_CPU_DISASM       , "cpu_disasm" } ,
        !            62:        { TRACE_CPU_EXCEPTION    , "cpu_exception" } ,
        !            63:        { TRACE_CPU_ALL          , "cpu_all" } ,
        !            64: 
        !            65:        { TRACE_INT              , "int" } ,
        !            66: 
        !            67:        { TRACE_FDC              , "fdc" } ,
        !            68: 
        !            69:        { TRACE_IKBD_CMDS        , "ikbd_cmds" } ,
        !            70:        { TRACE_IKBD_ACIA        , "ikbd_acia" } ,
        !            71:        { TRACE_IKBD_EXEC        , "ikbd_exec" } ,
        !            72:        { TRACE_IKBD_ALL         , "ikbd_all" } ,
        !            73: 
        !            74:        { TRACE_BLITTER          , "blitter" } ,
        !            75: 
        !            76:        { TRACE_OS_BIOS          , "bios" },
        !            77:        { TRACE_OS_XBIOS         , "xbios" },
        !            78:        { TRACE_OS_GEMDOS        , "gemdos" },
        !            79:        { TRACE_OS_VDI           , "vdi" },
        !            80:        { TRACE_OS_ALL           , "os_all" } ,
        !            81: 
        !            82:        { TRACE_IOMEM_RD         , "io_read" } ,
        !            83:        { TRACE_IOMEM_WR         , "io_write" } ,
        !            84:        { TRACE_IOMEM_ALL        , "io_all" } ,
1.1.1.5   root       85: 
1.1.1.6 ! root       86:        { TRACE_DMASND           , "dmasound" } ,
        !            87: 
        !            88:        { TRACE_ALL              , "all" }
1.1.1.4   root       89: };
                     90: 
                     91: 
1.1.1.6 ! root       92: Uint32 LogTraceFlags = TRACE_NONE;
1.1.1.4   root       93: FILE *TraceFile = NULL;
                     94: 
                     95: static FILE *hLogFile = NULL;
                     96: static LOGTYPE TextLogLevel;
                     97: static LOGTYPE AlertDlgLogLevel;
1.1       root       98: 
                     99: /*-----------------------------------------------------------------------*/
1.1.1.3   root      100: /**
1.1.1.4   root      101:  * Initialize the logging and tracing functionality (open the log files etc.).
                    102:  * 
                    103:  * Return zero if that fails.
1.1.1.3   root      104:  */
1.1.1.4   root      105: int Log_Init(void)
1.1       root      106: {
1.1.1.4   root      107:        TextLogLevel = ConfigureParams.Log.nTextLogLevel;
                    108:        AlertDlgLogLevel = ConfigureParams.Log.nAlertDlgLogLevel;
                    109: 
1.1.1.3   root      110:        hLogFile = File_Open(ConfigureParams.Log.sLogFileName, "w");
1.1.1.4   root      111:        TraceFile = File_Open(ConfigureParams.Log.sTraceFileName, "w");
                    112:    
                    113:        return (hLogFile && TraceFile);
1.1       root      114: }
                    115: 
                    116: 
                    117: /*-----------------------------------------------------------------------*/
1.1.1.3   root      118: /**
1.1.1.4   root      119:  * Un-Initialize - close log files etc.
1.1.1.3   root      120:  */
1.1       root      121: void Log_UnInit(void)
                    122: {
1.1.1.3   root      123:        hLogFile = File_Close(hLogFile);
1.1.1.4   root      124:        TraceFile = File_Close(TraceFile);
1.1       root      125: }
                    126: 
                    127: 
                    128: /*-----------------------------------------------------------------------*/
1.1.1.3   root      129: /**
                    130:  * Output string to log file
                    131:  */
1.1       root      132: void Log_Printf(LOGTYPE nType, const char *psFormat, ...)
                    133: {
                    134:        va_list argptr;
                    135: 
1.1.1.4   root      136:        if (hLogFile && nType <= TextLogLevel)
1.1       root      137:        {
                    138:                va_start(argptr, psFormat);
                    139:                vfprintf(hLogFile, psFormat, argptr);
                    140:                va_end(argptr);
1.1.1.4   root      141:                /* Add a new-line if necessary: */
                    142:                if (psFormat[strlen(psFormat)-1] != '\n')
                    143:                        fputs("\n", hLogFile);
1.1       root      144:        }
                    145: }
                    146: 
                    147: 
                    148: /*-----------------------------------------------------------------------*/
1.1.1.3   root      149: /**
                    150:  * Show logging alert dialog box and output string to log file
                    151:  */
1.1       root      152: void Log_AlertDlg(LOGTYPE nType, const char *psFormat, ...)
                    153: {
                    154:        va_list argptr;
                    155: 
                    156:        /* Output to log file: */
1.1.1.4   root      157:        if (hLogFile && nType <= TextLogLevel)
1.1       root      158:        {
                    159:                va_start(argptr, psFormat);
                    160:                vfprintf(hLogFile, psFormat, argptr);
                    161:                va_end(argptr);
                    162:                /* Add a new-line if necessary: */
                    163:                if (psFormat[strlen(psFormat)-1] != '\n')
                    164:                        fputs("\n", hLogFile);
                    165:        }
                    166: 
                    167:        /* Show alert dialog box: */
1.1.1.4   root      168:        if (sdlscrn && nType <= AlertDlgLogLevel)
1.1       root      169:        {
                    170:                char *psTmpBuf;
                    171:                psTmpBuf = malloc(2048);
                    172:                if (!psTmpBuf)
                    173:                {
                    174:                        perror("Log_AlertDlg");
                    175:                        return;
                    176:                }
                    177:                va_start(argptr, psFormat);
                    178:                vsnprintf(psTmpBuf, 2048, psFormat, argptr);
                    179:                va_end(argptr);
                    180:                DlgAlert_Notice(psTmpBuf);
                    181:                free(psTmpBuf);
                    182:        }
                    183: }
1.1.1.4   root      184: 
                    185: 
                    186: /*-----------------------------------------------------------------------*/
                    187: /**
                    188:  * parse what log level should be used and return it
                    189:  */
                    190: LOGTYPE Log_ParseOptions(const char *arg)
                    191: {
                    192:        const char *levels[] = {
                    193:                "fatal", "error", "warn", "info", "todo", "debug", NULL
                    194:        };
                    195:        LOGTYPE level = LOG_FATAL;
                    196:        const char **level_str;
                    197:        char *input, *str;
                    198: 
                    199:        input = strdup(arg);
                    200:        str = input;
                    201:        while (*str)
                    202:        {
                    203:                *str++ = tolower(*arg++);
                    204:        }
                    205:        for (level_str = levels; *level_str; level_str++, level++)
                    206:        {
                    207:                if (strcmp(input, *level_str) == 0)
                    208:                {
                    209:                        free(input);
                    210:                        return level;
                    211:                }
                    212:        }
                    213:        free(input);
                    214:        return level;
                    215: }
                    216: 
                    217: /*-----------------------------------------------------------------------*/
                    218: /**
                    219:  * Parse a list of comma separated strings.
                    220:  * If the string is prefixed with an optional '+',
                    221:  * corresponding trace flag is turned on.
                    222:  * If the string is prefixed with a '-',
                    223:  * corresponding trace flag is turned off.
1.1.1.6 ! root      224:  * Result is stored in LogTraceFlags.
        !           225:  * Return error string or NULL for success.
1.1.1.4   root      226:  */
1.1.1.6 ! root      227: const char* Log_SetTraceOptions (const char *OptionsStr)
1.1.1.4   root      228: {
1.1.1.6 ! root      229: #if ENABLE_TRACING
        !           230: 
1.1.1.4   root      231:        char *OptionsCopy;
                    232:        char *cur, *sep;
                    233:        int i;
                    234:        int Mode;                               /* 0=add, 1=del */
                    235:        int MaxOptions;
                    236: 
                    237:        MaxOptions = sizeof(TraceOptions) / sizeof(TraceOptions[0]);
                    238:        
                    239:        /* special case for "help" : display the list of possible trace levels */
                    240:        if (strcmp (OptionsStr, "help") == 0)
                    241:        {
                    242:                fprintf(stderr, "\nList of available trace levels :\n");
                    243:                
                    244:                for (i = 0; i < MaxOptions; i++)
                    245:                        fprintf(stderr, "  %s\n", TraceOptions[i].Name);
                    246:                
                    247:                fprintf(stderr, "Multiple trace levels can be separated by ','\n");
                    248:                fprintf(stderr, "Levels can be prefixed by '+' or '-' to be mixed.\n");
                    249:                fprintf(stderr, "Giving just trace level 'none' disables all traces.\n\n");
1.1.1.6 ! root      250:                return NULL;
1.1.1.4   root      251:        }
                    252:        
1.1.1.6 ! root      253:        LogTraceFlags = TRACE_NONE;
1.1.1.4   root      254:        if (strcmp (OptionsStr, "none") == 0)
                    255:        {
1.1.1.6 ! root      256:                return NULL;
1.1.1.4   root      257:        }
                    258:        
                    259:        OptionsCopy = strdup(OptionsStr);
                    260:        if (!OptionsCopy)
                    261:        {
1.1.1.6 ! root      262:                return "strdup error in ParseTraceOptions";
1.1.1.4   root      263:        }
                    264:        
                    265:        cur = OptionsCopy;
                    266:        while (cur)
                    267:        {
                    268:                sep = strchr(cur, ',');
                    269:                if (sep)                        /* end of next options */
                    270:                        *sep++ = '\0';
                    271:                
                    272:                Mode = 0;                               /* default is 'add' */
                    273:                if (*cur == '+')
                    274:                { Mode = 0; cur++; }
                    275:                else if (*cur == '-')
                    276:                { Mode = 1; cur++; }
                    277:                
                    278:                for (i = 0; i < MaxOptions; i++)
                    279:                {
                    280:                        if (strcmp(cur, TraceOptions[i].Name) == 0)
                    281:                                break;
                    282:                }
                    283:                
                    284:                if (i < MaxOptions)             /* option found */
                    285:                {
                    286:                        if (Mode == 0)
1.1.1.6 ! root      287:                                LogTraceFlags |= TraceOptions[i].Level;
1.1.1.4   root      288:                        else
1.1.1.6 ! root      289:                                LogTraceFlags &= (~TraceOptions[i].Level);
1.1.1.4   root      290:                }
                    291:                else
                    292:                {
1.1.1.6 ! root      293:                        fprintf(stderr, "Unknown trace type '%s'\n", cur);
1.1.1.4   root      294:                        free(OptionsCopy);
1.1.1.6 ! root      295:                        return "Unknown trace type.";
1.1.1.4   root      296:                }
                    297:                
                    298:                cur = sep;
                    299:        }
                    300:        
1.1.1.6 ! root      301:        //fprintf(stderr, "trace parse <%x>\n", LogTraceFlags);
1.1.1.4   root      302:        
                    303:        free (OptionsCopy);
1.1.1.6 ! root      304:        return NULL;
        !           305: 
        !           306: #else  /* ENABLE_TRACING */
        !           307:        return "Hatari has been compiled without ENABLE_TRACING!";
        !           308: #endif
1.1.1.4   root      309: }

unix.superglobalmegacorp.com

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