⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prlog.c

📁 Netscape NSPR库源码
💻 C
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//*  * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape Portable Runtime (NSPR). *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1998-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. *//* * Contributors: * * This Original Code has been modified by IBM Corporation. * Modifications made by IBM described herein are * Copyright (c) International Business Machines Corporation, 2000. * Modifications to Mozilla code or documentation identified per * MPL Section 3.3 * * Date         Modified by     Description of modification * 04/10/2000   IBM Corp.       Added DebugBreak() definitions for OS/2 */#include "primpl.h"#include "prenv.h"#include "prprf.h"#include <string.h>/* * Lock used to lock the log. * * We can't define _PR_LOCK_LOG simply as PR_Lock because PR_Lock may * contain assertions.  We have to avoid assertions in _PR_LOCK_LOG * because PR_ASSERT calls PR_LogPrint, which in turn calls _PR_LOCK_LOG. * This can lead to infinite recursion. */static PRLock *_pr_logLock;#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS)#define _PR_LOCK_LOG() PR_Lock(_pr_logLock);#define _PR_UNLOCK_LOG() PR_Unlock(_pr_logLock);#elif defined(_PR_GLOBAL_THREADS_ONLY)#define _PR_LOCK_LOG() { _PR_LOCK_LOCK(_pr_logLock)#define _PR_UNLOCK_LOG() _PR_LOCK_UNLOCK(_pr_logLock); }#else#define _PR_LOCK_LOG() \{ \    PRIntn _is; \    PRThread *_me = _PR_MD_CURRENT_THREAD(); \    if (!_PR_IS_NATIVE_THREAD(_me)) \        _PR_INTSOFF(_is); \    _PR_LOCK_LOCK(_pr_logLock)#define _PR_UNLOCK_LOG() \    _PR_LOCK_UNLOCK(_pr_logLock); \    PR_ASSERT(_me == _PR_MD_CURRENT_THREAD()); \    if (!_PR_IS_NATIVE_THREAD(_me)) \        _PR_INTSON(_is); \}#endif#if defined(XP_PC)#define strcasecmp stricmp#define strncasecmp strnicmp#endif/* * On NT, we can't define _PUT_LOG as PR_Write or _PR_MD_WRITE, * because every asynchronous file io operation leads to a fiber context * switch.  So we define _PUT_LOG as fputs (from stdio.h).  A side * benefit is that fputs handles the LF->CRLF translation.  This * code can also be used on other platforms with file stream io. */#if defined(WIN32) || defined(XP_OS2)#define _PR_USE_STDIO_FOR_LOGGING#endif/*** Coerce Win32 log output to use OutputDebugString() when** NSPR_LOG_FILE is set to "WinDebug".*/#if defined(XP_PC)#define WIN32_DEBUG_FILE (FILE*)-2#endif/* Macros used to reduce #ifdef pollution */#if defined(_PR_USE_STDIO_FOR_LOGGING)#define _PUT_LOG(fd, buf, nb) {fputs(buf, fd); fflush(fd);}#elif defined(_PR_PTHREADS)#define _PUT_LOG(fd, buf, nb) PR_Write(fd, buf, nb)#elif defined(XP_MAC)#define _PUT_LOG(fd, buf, nb) _PR_MD_WRITE_SYNC(fd, buf, nb)#else#define _PUT_LOG(fd, buf, nb) _PR_MD_WRITE(fd, buf, nb)#endif/************************************************************************/static PRLogModuleInfo *logModules;static char *logBuf = NULL;static char *logp;static char *logEndp;#ifdef _PR_USE_STDIO_FOR_LOGGINGstatic FILE *logFile = NULL;#elsestatic PRFileDesc *logFile = 0;#endif#define LINE_BUF_SIZE           512#define DEFAULT_BUF_SIZE        16384#ifdef _PR_NEED_STRCASECMP/* * strcasecmp is defined in /usr/ucblib/libucb.a on some platforms * such as NCR and Unixware.  Linking with both libc and libucb * may cause some problem, so I just provide our own implementation * of strcasecmp here. */static const unsigned char uc[] ={    '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',    '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',    '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',    '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',    ' ',    '!',    '"',    '#',    '$',    '%',    '&',    '\'',    '(',    ')',    '*',    '+',    ',',    '-',    '.',    '/',    '0',    '1',    '2',    '3',    '4',    '5',    '6',    '7',    '8',    '9',    ':',    ';',    '<',    '=',    '>',    '?',    '@',    'A',    'B',    'C',    'D',    'E',    'F',    'G',    'H',    'I',    'J',    'K',    'L',    'M',    'N',    'O',    'P',    'Q',    'R',    'S',    'T',    'U',    'V',    'W',    'X',    'Y',    'Z',    '[',    '\\',   ']',    '^',    '_',    '`',    'A',    'B',    'C',    'D',    'E',    'F',    'G',    'H',    'I',    'J',    'K',    'L',    'M',    'N',    'O',    'P',    'Q',    'R',    'S',    'T',    'U',    'V',    'W',    'X',    'Y',    'Z',    '{',    '|',    '}',    '~',    '\177'};PRIntn strcasecmp(const char *a, const char *b){    const unsigned char *ua = (const unsigned char *)a;    const unsigned char *ub = (const unsigned char *)b;    if( ((const char *)0 == a) || (const char *)0 == b )         return (PRIntn)(a-b);    while( (uc[*ua] == uc[*ub]) && ('\0' != *a) )    {        a++;        ua++;        ub++;    }    return (PRIntn)(uc[*ua] - uc[*ub]);}#endif /* _PR_NEED_STRCASECMP */void _PR_InitLog(void){    char *ev;    _pr_logLock = PR_NewLock();    ev = PR_GetEnv("NSPR_LOG_MODULES");    if (ev && ev[0]) {        char module[64];  /* Security-Critical: If you change this                           * size, you must also change the sscanf                           * format string to be size-1.                           */        PRBool isSync = PR_FALSE;        PRIntn evlen = strlen(ev), pos = 0;        PRInt32 bufSize = DEFAULT_BUF_SIZE;        while (pos < evlen) {            PRIntn level = 1, count = 0, delta = 0;            count = sscanf(&ev[pos], "%63[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789]%n:%d%n",                           module, &delta, &level, &delta);            pos += delta;            if (count == 0) break;            /*            ** If count == 2, then we got module and level. If count            ** == 1, then level defaults to 1 (module enabled).            */            if (strcasecmp(module, "sync") == 0) {                isSync = PR_TRUE;            } else if (strcasecmp(module, "bufsize") == 0) {                if (level >= LINE_BUF_SIZE) {                    bufSize = level;                }            } else {                PRLogModuleInfo *lm = logModules;                PRBool skip_modcheck =                    (0 == strcasecmp (module, "all")) ? PR_TRUE : PR_FALSE;                while (lm != NULL) {                    if (skip_modcheck) lm -> level = (PRLogModuleLevel)level;                    else if (strcasecmp(module, lm->name) == 0) {                        lm->level = (PRLogModuleLevel)level;                        break;                    }                    lm = lm->next;                }            }            /*found:*/            count = sscanf(&ev[pos], " , %n", &delta);            pos += delta;            if (count == EOF) break;        }        PR_SetLogBuffering(isSync ? bufSize : 0);        ev = PR_GetEnv("NSPR_LOG_FILE");        if (ev && ev[0]) {            if (!PR_SetLogFile(ev)) {#ifdef XP_PC                char* str = PR_smprintf("Unable to create nspr log file '%s'\n", ev);                if (str) {                    OutputDebugString(str);                    PR_smprintf_free(str);                }#else                fprintf(stderr, "Unable to create nspr log file '%s'\n", ev);#endif            }        } else {#ifdef _PR_USE_STDIO_FOR_LOGGING            logFile = stderr;#else            logFile = _pr_stderr;#endif        }    }}void _PR_LogCleanup(void){    PRLogModuleInfo *lm = logModules;    PR_LogFlush();#ifdef _PR_USE_STDIO_FOR_LOGGING    if (logFile && logFile != stdout && logFile != stderr) {        fclose(logFile);    }#else    if (logFile && logFile != _pr_stdout && logFile != _pr_stderr) {        PR_Close(logFile);    }#endif    while (lm != NULL) {        PRLogModuleInfo *next = lm->next;        free((/*const*/ char *)lm->name);        PR_Free(lm);        lm = next;    }    logModules = NULL;    if (_pr_logLock) {        PR_DestroyLock(_pr_logLock);        _pr_logLock = NULL;    }}static void _PR_SetLogModuleLevel( PRLogModuleInfo *lm ){    char *ev;    ev = PR_GetEnv("NSPR_LOG_MODULES");    if (ev && ev[0]) {        char module[64];  /* Security-Critical: If you change this                           * size, you must also change the sscanf                           * format string to be size-1.                           */        PRIntn evlen = strlen(ev), pos = 0;        while (pos < evlen) {            PRIntn level = 1, count = 0, delta = 0;            count = sscanf(&ev[pos], "%63[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789]%n:%d%n",                           module, &delta, &level, &delta);            pos += delta;            if (count == 0) break;            /*            ** If count == 2, then we got module and level. If count            ** == 1, then level defaults to 1 (module enabled).            */            if (lm != NULL)            {                if ((strcasecmp(module, "all") == 0)                    || (strcasecmp(module, lm->name) == 0))                {                    lm->level = (PRLogModuleLevel)level;                }            }            count = sscanf(&ev[pos], " , %n", &delta);            pos += delta;            if (count == EOF) break;        }    }} /* end _PR_SetLogModuleLevel() */PR_IMPLEMENT(PRLogModuleInfo*) PR_NewLogModule(const char *name){    PRLogModuleInfo *lm;        if (!_pr_initialized) _PR_ImplicitInitialization();    lm = PR_NEWZAP(PRLogModuleInfo);    if (lm) {        lm->name = strdup(name);        lm->level = PR_LOG_NONE;        lm->next = logModules;        logModules = lm;    }    _PR_SetLogModuleLevel(lm);    return lm;}PR_IMPLEMENT(PRBool) PR_SetLogFile(const char *file){#ifdef _PR_USE_STDIO_FOR_LOGGING    FILE *newLogFile;#ifdef XP_PC    if ( strcmp( file, "WinDebug") == 0)    {        logFile = WIN32_DEBUG_FILE;        return(PR_TRUE);    }#endif    newLogFile = fopen(file, "w");    if (newLogFile) {        /* We do buffering ourselves. */        setvbuf(newLogFile, NULL, _IONBF, 0);        if (logFile && logFile != stdout && logFile != stderr) {            fclose(logFile);        }        logFile = newLogFile;    }    return (PRBool) (newLogFile != 0);#else    PRFileDesc *newLogFile;    newLogFile = PR_Open(file, PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE, 0666);    if (newLogFile) {        if (logFile && logFile != _pr_stdout && logFile != _pr_stderr) {            PR_Close(logFile);        }        logFile = newLogFile;#if defined(XP_MAC)        SetLogFileTypeCreator(file);#endif    }    return (PRBool) (newLogFile != 0);#endif /* _PR_USE_STDIO_FOR_LOGGING */}PR_IMPLEMENT(void) PR_SetLogBuffering(PRIntn buffer_size){    PR_LogFlush();    if (logBuf)        PR_DELETE(logBuf);    logBuf = 0;    if (buffer_size >= LINE_BUF_SIZE) {        logp = logBuf = (char*) PR_MALLOC(buffer_size);        logEndp = logp + buffer_size;    }}PR_IMPLEMENT(void) PR_LogPrint(const char *fmt, ...){    va_list ap;    char line[LINE_BUF_SIZE];    PRUint32 nb;    PRThread *me;    if (!_pr_initialized) _PR_ImplicitInitialization();    if (!logFile) {        return;    }    va_start(ap, fmt);    me = PR_GetCurrentThread();    nb = PR_snprintf(line, sizeof(line)-1, "%ld[%p]: ",#if defined(_PR_DCETHREADS)             /* The problem is that for _PR_DCETHREADS, pthread_t is not a               * pointer, but a structure; so you can't easily print it...              */                     me ? &(me->id): 0L, me);#elif defined(_PR_BTHREADS)		     me, me);#else                     me ? me->id : 0L, me);#endif    nb += PR_vsnprintf(line+nb, sizeof(line)-nb-1, fmt, ap);    if (nb && (line[nb-1] != '\n')) {#ifndef XP_MAC        line[nb++] = '\n';#else        line[nb++] = '\015';#endif         line[nb] = '\0';    } else {#ifdef XP_MAC        line[nb-1] = '\015';#endif    }    va_end(ap);    _PR_LOCK_LOG();    if (logBuf == 0) {#ifdef XP_PC        if ( logFile == WIN32_DEBUG_FILE)            OutputDebugString( line );        else            _PUT_LOG(logFile, line, nb);#else        _PUT_LOG(logFile, line, nb);#endif    } else {        if (logp + nb > logEndp) {            _PUT_LOG(logFile, logBuf, logp - logBuf);            logp = logBuf;        }        memcpy(logp, line, nb);        logp += nb;    }    _PR_UNLOCK_LOG();    PR_LogFlush();}PR_IMPLEMENT(void) PR_LogFlush(void){    if (logBuf && logFile) {        _PR_LOCK_LOG();            if (logp > logBuf) {                _PUT_LOG(logFile, logBuf, logp - logBuf);                logp = logBuf;            }        _PR_UNLOCK_LOG();    }}PR_IMPLEMENT(void) PR_Abort(void){    PR_LogPrint("Aborting");    abort();}#if defined(XP_OS2)/* * Added definitions for DebugBreak() for 2 different OS/2 compilers. * Doing the int3 on purpose for Visual Age so that a developer can * step over the instruction if so desired.  Not always possible if * trapping due to exception handling IBM-AKR */#if defined(XP_OS2_VACPP)#include <builtin.h>static void DebugBreak(void) { _interrupt(3); }#elif defined(XP_OS2_EMX)/* Force a trap */static void DebugBreak(void) { int *pTrap=NULL; *pTrap = 1; }#elsestatic void DebugBreak(void) { }#endif#endif /* XP_OS2 */PR_IMPLEMENT(void) PR_Assert(const char *s, const char *file, PRIntn ln){    PR_LogPrint("Assertion failure: %s, at %s:%d\n", s, file, ln);#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)    fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln);#endif#ifdef XP_MAC    dprintf("Assertion failure: %s, at %s:%d\n", s, file, ln);#endif#if defined(WIN32) || defined(XP_OS2)    DebugBreak();#endif#ifndef XP_MAC    abort();#endif}#ifdef XP_MACPR_IMPLEMENT(void) PR_Init_Log(void){	_PR_InitLog();}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -