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

📄 logprint.c

📁 Android 一些工具
💻 C
📖 第 1 页 / 共 2 页
字号:
            eventDataLen -= strLen;            break;        }    case EVENT_TYPE_LIST:        /* N items, all different types */        {            unsigned char count;            int i;            if (eventDataLen < 1)                return -1;            count = *eventData++;            eventDataLen--;            if (outBufLen > 0) {                *outBuf++ = '[';                outBufLen--;            } else {                goto no_room;            }            for (i = 0; i < count; i++) {                result = android_log_printBinaryEvent(&eventData, &eventDataLen,                        &outBuf, &outBufLen);                if (result != 0)                    goto bail;                if (i < count-1) {                    if (outBufLen > 0) {                        *outBuf++ = ',';                        outBufLen--;                    } else {                        goto no_room;                    }                }            }            if (outBufLen > 0) {                *outBuf++ = ']';                outBufLen--;            } else {                goto no_room;            }        }        break;    default:        fprintf(stderr, "Unknown binary event type %d\n", type);        return -1;    }bail:    *pEventData = eventData;    *pEventDataLen = eventDataLen;    *pOutBuf = outBuf;    *pOutBufLen = outBufLen;    return result;no_room:    result = 1;    goto bail;}/** * Convert a binary log entry to ASCII form. * * For convenience we mimic the processLogBuffer API.  There is no * pre-defined output length for the binary data, since we're free to format * it however we choose, which means we can't really use a fixed-size buffer * here. */int android_log_processBinaryLogBuffer(struct logger_entry *buf,    AndroidLogEntry *entry, const EventTagMap* map, char* messageBuf,    int messageBufLen){    size_t inCount;    unsigned int tagIndex;    const unsigned char* eventData;    entry->tv_sec = buf->sec;    entry->tv_nsec = buf->nsec;    entry->priority = ANDROID_LOG_INFO;    entry->pid = buf->pid;    entry->tid = buf->tid;    /*     * Pull the tag out.     */    eventData = (const unsigned char*) buf->msg;    inCount = buf->len;    if (inCount < 4)        return -1;    tagIndex = get4LE(eventData);    eventData += 4;    inCount -= 4;    if (map != NULL) {        entry->tag = android_lookupEventTag(map, tagIndex);    } else {        entry->tag = NULL;    }    /*     * If we don't have a map, or didn't find the tag number in the map,     * stuff a generated tag value into the start of the output buffer and     * shift the buffer pointers down.     */    if (entry->tag == NULL) {        int tagLen;        tagLen = snprintf(messageBuf, messageBufLen, "[%d]", tagIndex);        entry->tag = messageBuf;        messageBuf += tagLen+1;        messageBufLen -= tagLen+1;    }    /*     * Format the event log data into the buffer.     */    char* outBuf = messageBuf;    size_t outRemaining = messageBufLen-1;      /* leave one for nul byte */    int result;    result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf,                &outRemaining);    if (result < 0) {        fprintf(stderr, "Binary log entry conversion failed\n");        return -1;    } else if (result == 1) {        if (outBuf > messageBuf) {            /* leave an indicator */            *(outBuf-1) = '!';        } else {            /* no room to output anything at all */            *outBuf++ = '!';            outRemaining--;        }        /* pretend we ate all the data */        inCount = 0;    }    /* eat the silly terminating '\n' */    if (inCount == 1 && *eventData == '\n') {        eventData++;        inCount--;    }    if (inCount != 0) {        fprintf(stderr,            "Warning: leftover binary log data (%d bytes)\n", inCount);    }    /*     * Terminate the buffer.  The NUL byte does not count as part of     * entry->messageLen.     */    *outBuf = '\0';    entry->messageLen = outBuf - messageBuf;    assert(entry->messageLen == (messageBufLen-1) - outRemaining);    entry->message = messageBuf;    return 0;}/** * Formats a log message into a buffer * * Uses defaultBuffer if it can, otherwise malloc()'s a new buffer * If return value != defaultBuffer, caller must call free() * Returns NULL on malloc error */char *android_log_formatLogLine (    AndroidLogFormat *p_format,    char *defaultBuffer,    size_t defaultBufferSize,    const AndroidLogEntry *entry,    size_t *p_outLength){#if defined(HAVE_LOCALTIME_R)    struct tm tmBuf;#endif    struct tm* ptm;    char timeBuf[32];    char headerBuf[128];    char prefixBuf[128], suffixBuf[128];    char priChar;    int prefixSuffixIsHeaderFooter = 0;    char * ret = NULL;    priChar = filterPriToChar(entry->priority);    /*     * Get the current date/time in pretty form     *     * It's often useful when examining a log with "less" to jump to     * a specific point in the file by searching for the date/time stamp.     * For this reason it's very annoying to have regexp meta characters     * in the time stamp.  Don't use forward slashes, parenthesis,     * brackets, asterisks, or other special chars here.     */#if defined(HAVE_LOCALTIME_R)    ptm = localtime_r(&(entry->tv_sec), &tmBuf);#else    ptm = localtime(&(entry->tv_sec));#endif    //strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", ptm);    strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm);    /*     * Construct a buffer containing the log header and log message.     */    size_t prefixLen, suffixLen;    switch (p_format->format) {        case FORMAT_TAG:            prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),                "%c/%-8s: ", priChar, entry->tag);            strcpy(suffixBuf, "\n"); suffixLen = 1;            break;        case FORMAT_PROCESS:            prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),                "%c(%5d) ", priChar, entry->pid);            suffixLen = snprintf(suffixBuf, sizeof(suffixBuf),                "  (%s)\n", entry->tag);            break;        case FORMAT_THREAD:            prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),                "%c(%5d:%p) ", priChar, entry->pid, (void*)entry->tid);            strcpy(suffixBuf, "\n");            suffixLen = 1;            break;        case FORMAT_RAW:            prefixBuf[0] = 0;            prefixLen = 0;            strcpy(suffixBuf, "\n");            suffixLen = 1;            break;        case FORMAT_TIME:            prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),                "%s.%03ld %c/%-8s(%5d): ", timeBuf, entry->tv_nsec / 1000000,                priChar, entry->tag, entry->pid);            strcpy(suffixBuf, "\n");            suffixLen = 1;            break;        case FORMAT_THREADTIME:            prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),                "%s.%03ld %5d %5d %c %-8s: ", timeBuf, entry->tv_nsec / 1000000,                (int)entry->pid, (int)entry->tid, priChar, entry->tag);            strcpy(suffixBuf, "\n");            suffixLen = 1;            break;        case FORMAT_LONG:            prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),                "[ %s.%03ld %5d:%p %c/%-8s ]\n",                timeBuf, entry->tv_nsec / 1000000, entry->pid,                (void*)entry->tid, priChar, entry->tag);            strcpy(suffixBuf, "\n\n");            suffixLen = 2;            prefixSuffixIsHeaderFooter = 1;            break;        case FORMAT_BRIEF:        default:            prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),                "%c/%-8s(%5d): ", priChar, entry->tag, entry->pid);            strcpy(suffixBuf, "\n");            suffixLen = 1;            break;    }    /* the following code is tragically unreadable */    size_t numLines;    size_t i;    char *p;    size_t bufferSize;    const char *pm;    if (prefixSuffixIsHeaderFooter) {        // we're just wrapping message with a header/footer        numLines = 1;    } else {        pm = entry->message;        numLines = 0;        // The line-end finding here must match the line-end finding        // in for ( ... numLines...) loop below        while (pm < (entry->message + entry->messageLen)) {            if (*pm++ == '\n') numLines++;        }        // plus one line for anything not newline-terminated at the end        if (pm > entry->message && *(pm-1) != '\n') numLines++;    }    // this is an upper bound--newlines in message may be counted    // extraneously    bufferSize = (numLines * (prefixLen + suffixLen)) + entry->messageLen + 1;    if (defaultBufferSize >= bufferSize) {        ret = defaultBuffer;    } else {        ret = (char *)malloc(bufferSize);        if (ret == NULL) {            return ret;        }    }    ret[0] = '\0';       /* to start strcat off */    p = ret;    pm = entry->message;    if (prefixSuffixIsHeaderFooter) {        strcat(p, prefixBuf);        p += prefixLen;        strncat(p, entry->message, entry->messageLen);        p += entry->messageLen;        strcat(p, suffixBuf);        p += suffixLen;    } else {        while(pm < (entry->message + entry->messageLen)) {            const char *lineStart;            size_t lineLen;            lineStart = pm;            // Find the next end-of-line in message            while (pm < (entry->message + entry->messageLen)                    && *pm != '\n') pm++;            lineLen = pm - lineStart;            strcat(p, prefixBuf);            p += prefixLen;            strncat(p, lineStart, lineLen);            p += lineLen;            strcat(p, suffixBuf);            p += suffixLen;            if (*pm == '\n') pm++;        }    }    if (p_outLength != NULL) {        *p_outLength = p - ret;    }    return ret;}/** * Either print or do not print log line, based on filter * * Returns count bytes written */int android_log_filterAndPrintLogLine(    AndroidLogFormat *p_format,    int fd,    const AndroidLogEntry *entry){    int ret;    char defaultBuffer[512];    char *outBuffer = NULL;    size_t totalLen;    if (0 == android_log_shouldPrintLine(p_format, entry->tag,            entry->priority)) {        return 0;    }    outBuffer = android_log_formatLogLine(p_format, defaultBuffer,            sizeof(defaultBuffer), entry, &totalLen);    if (!outBuffer)        return -1;    do {        ret = write(fd, outBuffer, totalLen);    } while (ret < 0 && errno == EINTR);    if (ret < 0) {        fprintf(stderr, "+++ LOG: write failed (errno=%d)\n", errno);        ret = 0;        goto done;    }    if (((size_t)ret) < totalLen) {        fprintf(stderr, "+++ LOG: write partial (%d of %d)\n", ret,                (int)totalLen);        goto done;    }done:    if (outBuffer != defaultBuffer) {        free(outBuffer);    }    return ret;}void logprint_run_tests(){#if 0    fprintf(stderr, "tests disabled\n");#else    int err;    const char *tag;    AndroidLogFormat *p_format;    p_format = android_log_format_new();    fprintf(stderr, "running tests\n");    tag = "random";    android_log_addFilterRule(p_format,"*:i");    assert (ANDROID_LOG_INFO == filterPriForTag(p_format, "random"));    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);    android_log_addFilterRule(p_format, "*");    assert (ANDROID_LOG_DEBUG == filterPriForTag(p_format, "random"));    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);    android_log_addFilterRule(p_format, "*:v");    assert (ANDROID_LOG_VERBOSE == filterPriForTag(p_format, "random"));    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);    android_log_addFilterRule(p_format, "*:i");    assert (ANDROID_LOG_INFO == filterPriForTag(p_format, "random"));    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);    android_log_addFilterRule(p_format, "random");    assert (ANDROID_LOG_VERBOSE == filterPriForTag(p_format, "random"));    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);    android_log_addFilterRule(p_format, "random:v");    assert (ANDROID_LOG_VERBOSE == filterPriForTag(p_format, "random"));    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);    android_log_addFilterRule(p_format, "random:d");    assert (ANDROID_LOG_DEBUG == filterPriForTag(p_format, "random"));    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);    android_log_addFilterRule(p_format, "random:w");    assert (ANDROID_LOG_WARN == filterPriForTag(p_format, "random"));    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);    android_log_addFilterRule(p_format, "crap:*");    assert (ANDROID_LOG_VERBOSE== filterPriForTag(p_format, "crap"));    assert(android_log_shouldPrintLine(p_format, "crap", ANDROID_LOG_VERBOSE) > 0);    // invalid expression    err = android_log_addFilterRule(p_format, "random:z");    assert (err < 0);    assert (ANDROID_LOG_WARN == filterPriForTag(p_format, "random"));    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);    // Issue #550946    err = android_log_addFilterString(p_format, " ");    assert(err == 0);    assert(ANDROID_LOG_WARN == filterPriForTag(p_format, "random"));    // note trailing space    err = android_log_addFilterString(p_format, "*:s random:d ");    assert(err == 0);    assert(ANDROID_LOG_DEBUG == filterPriForTag(p_format, "random"));    err = android_log_addFilterString(p_format, "*:s random:z");    assert(err < 0);#if 0    char *ret;    char defaultBuffer[512];    ret = android_log_formatLogLine(p_format,        defaultBuffer, sizeof(defaultBuffer), 0, ANDROID_LOG_ERROR, 123,        123, 123, "random", "nofile", strlen("Hello"), "Hello", NULL);#endif    fprintf(stderr, "tests complete\n");#endif}

⌨️ 快捷键说明

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