logprint.c revision d2c8f52189f8c2a13b88a107c6495f9d83196d2d
14f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/* //device/libs/cutils/logprint.c
24f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project**
34f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project** Copyright 2006, The Android Open Source Project
44f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project**
54f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
64f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project** you may not use this file except in compliance with the License.
74f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project** You may obtain a copy of the License at
84f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project**
94f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project**
114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project** See the License for the specific language governing permissions and
154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project** limitations under the License.
164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project*/
174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#define _GNU_SOURCE /* for asprintf */
194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <ctype.h>
214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <stdio.h>
224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <errno.h>
234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <stdlib.h>
244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <stdint.h>
254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <string.h>
264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <assert.h>
274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <arpa/inet.h>
284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <cutils/logd.h>
304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <cutils/logprint.h>
314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projecttypedef struct FilterInfo_t {
334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    char *mTag;
344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    android_LogPriority mPri;
354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    struct FilterInfo_t *p_next;
364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} FilterInfo;
374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstruct AndroidLogFormat_t {
394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    android_LogPriority global_pri;
404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    FilterInfo *filters;
414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    AndroidLogPrintFormat format;
424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project};
434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic FilterInfo * filterinfo_new(const char * tag, android_LogPriority pri)
454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    FilterInfo *p_ret;
474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    p_ret = (FilterInfo *)calloc(1, sizeof(FilterInfo));
494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    p_ret->mTag = strdup(tag);
504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    p_ret->mPri = pri;
514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return p_ret;
534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void filterinfo_free(FilterInfo *p_info)
564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (p_info == NULL) {
584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        return;
594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    free(p_info->mTag);
624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    p_info->mTag = NULL;
634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/*
664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Note: also accepts 0-9 priorities
674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * returns ANDROID_LOG_UNKNOWN if the character is unrecognized
684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */
694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic android_LogPriority filterCharToPri (char c)
704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    android_LogPriority pri;
724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    c = tolower(c);
744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (c >= '0' && c <= '9') {
764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        if (c >= ('0'+ANDROID_LOG_SILENT)) {
774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            pri = ANDROID_LOG_VERBOSE;
784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        } else {
794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            pri = (android_LogPriority)(c - '0');
804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    } else if (c == 'v') {
824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        pri = ANDROID_LOG_VERBOSE;
834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    } else if (c == 'd') {
844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        pri = ANDROID_LOG_DEBUG;
854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    } else if (c == 'i') {
864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        pri = ANDROID_LOG_INFO;
874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    } else if (c == 'w') {
884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        pri = ANDROID_LOG_WARN;
894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    } else if (c == 'e') {
904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        pri = ANDROID_LOG_ERROR;
914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    } else if (c == 'f') {
924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        pri = ANDROID_LOG_FATAL;
934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    } else if (c == 's') {
944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        pri = ANDROID_LOG_SILENT;
954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    } else if (c == '*') {
964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        pri = ANDROID_LOG_DEFAULT;
974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    } else {
984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        pri = ANDROID_LOG_UNKNOWN;
994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
1004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return pri;
1024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
1034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char filterPriToChar (android_LogPriority pri)
1054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
1064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    switch (pri) {
1074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        case ANDROID_LOG_VERBOSE:       return 'V';
1084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        case ANDROID_LOG_DEBUG:         return 'D';
1094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        case ANDROID_LOG_INFO:          return 'I';
1104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        case ANDROID_LOG_WARN:          return 'W';
1114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        case ANDROID_LOG_ERROR:         return 'E';
1124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        case ANDROID_LOG_FATAL:         return 'F';
1134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        case ANDROID_LOG_SILENT:        return 'S';
1144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        case ANDROID_LOG_DEFAULT:
1164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        case ANDROID_LOG_UNKNOWN:
1174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        default:                        return '?';
1184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
1194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
1204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic android_LogPriority filterPriForTag(
1224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        AndroidLogFormat *p_format, const char *tag)
1234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
1244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    FilterInfo *p_curFilter;
1254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    for (p_curFilter = p_format->filters
1274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            ; p_curFilter != NULL
1284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            ; p_curFilter = p_curFilter->p_next
1294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    ) {
1304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        if (0 == strcmp(tag, p_curFilter->mTag)) {
1314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            if (p_curFilter->mPri == ANDROID_LOG_DEFAULT) {
1324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                return p_format->global_pri;
1334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            } else {
1344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                return p_curFilter->mPri;
1354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            }
1364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
1374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
1384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return p_format->global_pri;
1404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
1414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/** for debugging */
1434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void dumpFilters(AndroidLogFormat *p_format)
1444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
1454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    FilterInfo *p_fi;
1464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    for (p_fi = p_format->filters ; p_fi != NULL ; p_fi = p_fi->p_next) {
1484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        char cPri = filterPriToChar(p_fi->mPri);
1494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        if (p_fi->mPri == ANDROID_LOG_DEFAULT) {
1504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            cPri = filterPriToChar(p_format->global_pri);
1514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
1524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        fprintf(stderr,"%s:%c\n", p_fi->mTag, cPri);
1534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
1544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    fprintf(stderr,"*:%c\n", filterPriToChar(p_format->global_pri));
1564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
1584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/**
1604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * returns 1 if this log line should be printed based on its priority
1614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * and tag, and 0 if it should not
1624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */
1634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectint android_log_shouldPrintLine (
1644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        AndroidLogFormat *p_format, const char *tag, android_LogPriority pri)
1654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
1664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return pri >= filterPriForTag(p_format, tag);
1674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
1684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source ProjectAndroidLogFormat *android_log_format_new()
1704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
1714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    AndroidLogFormat *p_ret;
1724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    p_ret = calloc(1, sizeof(AndroidLogFormat));
1744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    p_ret->global_pri = ANDROID_LOG_VERBOSE;
1764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    p_ret->format = FORMAT_BRIEF;
1774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return p_ret;
1794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
1804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid android_log_format_free(AndroidLogFormat *p_format)
1824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
1834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    FilterInfo *p_info, *p_info_old;
1844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    p_info = p_format->filters;
1864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    while (p_info != NULL) {
1884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        p_info_old = p_info;
1894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        p_info = p_info->p_next;
1904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        free(p_info_old);
1924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
1934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    free(p_format);
1954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
1964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid android_log_setPrintFormat(AndroidLogFormat *p_format,
2004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        AndroidLogPrintFormat format)
2014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
2024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    p_format->format=format;
2034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
2044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/**
2064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Returns FORMAT_OFF on invalid string
2074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */
2084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source ProjectAndroidLogPrintFormat android_log_formatFromString(const char * formatString)
2094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
2104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    static AndroidLogPrintFormat format;
2114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (strcmp(formatString, "brief") == 0) format = FORMAT_BRIEF;
2134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    else if (strcmp(formatString, "process") == 0) format = FORMAT_PROCESS;
2144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    else if (strcmp(formatString, "tag") == 0) format = FORMAT_TAG;
2154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    else if (strcmp(formatString, "thread") == 0) format = FORMAT_THREAD;
2164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    else if (strcmp(formatString, "raw") == 0) format = FORMAT_RAW;
2174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    else if (strcmp(formatString, "time") == 0) format = FORMAT_TIME;
2184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    else if (strcmp(formatString, "threadtime") == 0) format = FORMAT_THREADTIME;
2194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    else if (strcmp(formatString, "long") == 0) format = FORMAT_LONG;
2204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    else format = FORMAT_OFF;
2214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return format;
2234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
2244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/**
2264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * filterExpression: a single filter expression
2274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * eg "AT:d"
2284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *
2294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * returns 0 on success and -1 on invalid expression
2304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *
2314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Assumes single threaded execution
2324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */
2334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectint android_log_addFilterRule(AndroidLogFormat *p_format,
2354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        const char *filterExpression)
2364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
2374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    size_t i=0;
2384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    size_t tagNameLength;
2394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    android_LogPriority pri = ANDROID_LOG_DEFAULT;
2404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    tagNameLength = strcspn(filterExpression, ":");
2424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (tagNameLength == 0) {
2444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        goto error;
2454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
2464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if(filterExpression[tagNameLength] == ':') {
2484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        pri = filterCharToPri(filterExpression[tagNameLength+1]);
2494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        if (pri == ANDROID_LOG_UNKNOWN) {
2514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            goto error;
2524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
2534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
2544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if(0 == strncmp("*", filterExpression, tagNameLength)) {
2564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        // This filter expression refers to the global filter
2574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        // The default level for this is DEBUG if the priority
2584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        // is unspecified
2594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        if (pri == ANDROID_LOG_DEFAULT) {
2604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            pri = ANDROID_LOG_DEBUG;
2614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
2624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        p_format->global_pri = pri;
2644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    } else {
2654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        // for filter expressions that don't refer to the global
2664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        // filter, the default is verbose if the priority is unspecified
2674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        if (pri == ANDROID_LOG_DEFAULT) {
2684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            pri = ANDROID_LOG_VERBOSE;
2694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
2704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        char *tagName;
2724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project// Presently HAVE_STRNDUP is never defined, so the second case is always taken
2744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project// Darwin doesn't have strnup, everything else does
2754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#ifdef HAVE_STRNDUP
2764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        tagName = strndup(filterExpression, tagNameLength);
2774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#else
2784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        //a few extra bytes copied...
2794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        tagName = strdup(filterExpression);
2804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        tagName[tagNameLength] = '\0';
2814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif /*HAVE_STRNDUP*/
2824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        FilterInfo *p_fi = filterinfo_new(tagName, pri);
2844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        free(tagName);
2854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        p_fi->p_next = p_format->filters;
2874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        p_format->filters = p_fi;
2884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
2894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return 0;
2914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projecterror:
2924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return -1;
2934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
2944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/**
2974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * filterString: a comma/whitespace-separated set of filter expressions
2984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *
2994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * eg "AT:d *:i"
3004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *
3014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * returns 0 on success and -1 on invalid expression
3024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *
3034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Assumes single threaded execution
3044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *
3054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */
3064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectint android_log_addFilterString(AndroidLogFormat *p_format,
3084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        const char *filterString)
3094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
3104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    char *filterStringCopy = strdup (filterString);
3114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    char *p_cur = filterStringCopy;
3124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    char *p_ret;
3134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    int err;
3144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    // Yes, I'm using strsep
3164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    while (NULL != (p_ret = strsep(&p_cur, " \t,"))) {
3174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        // ignore whitespace-only entries
3184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        if(p_ret[0] != '\0') {
3194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            err = android_log_addFilterRule(p_format, p_ret);
3204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            if (err < 0) {
3224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                goto error;
3234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            }
3244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
3254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
3264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    free (filterStringCopy);
3284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return 0;
3294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projecterror:
3304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    free (filterStringCopy);
3314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return -1;
3324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic inline char * strip_end(char *str)
3354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
3364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    char *end = str + strlen(str) - 1;
3374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    while (end >= str && isspace(*end))
3394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        *end-- = '\0';
3404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return str;
3414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/**
3444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Splits a wire-format buffer into an AndroidLogEntry
3454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * entry allocated by caller. Pointers will point directly into buf
3464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *
3474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Returns 0 on success and -1 on invalid wire format (entry will be
3484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * in unspecified state)
3494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */
3504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectint android_log_processLogBuffer(struct logger_entry *buf,
3514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                                 AndroidLogEntry *entry)
3524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
3534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    entry->tv_sec = buf->sec;
3544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    entry->tv_nsec = buf->nsec;
3554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    entry->pid = buf->pid;
3564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    entry->tid = buf->tid;
3574bf3c02e026077d14a4512c7c2f71937da3c2d50Kenny Root
3584bf3c02e026077d14a4512c7c2f71937da3c2d50Kenny Root    /*
3594bf3c02e026077d14a4512c7c2f71937da3c2d50Kenny Root     * format: <priority:1><tag:N>\0<message:N>\0
3604bf3c02e026077d14a4512c7c2f71937da3c2d50Kenny Root     *
3614bf3c02e026077d14a4512c7c2f71937da3c2d50Kenny Root     * tag str
362e1ede1530ff21d3b8920c0cbbebb42ccff4fa22dNick Kralevich     *   starts at buf->msg+1
3634bf3c02e026077d14a4512c7c2f71937da3c2d50Kenny Root     * msg
364e1ede1530ff21d3b8920c0cbbebb42ccff4fa22dNick Kralevich     *   starts at buf->msg+1+len(tag)+1
365a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey     *
366a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey     * The message may have been truncated by the kernel log driver.
367a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey     * When that happens, we must null-terminate the message ourselves.
3684bf3c02e026077d14a4512c7c2f71937da3c2d50Kenny Root     */
369e1ede1530ff21d3b8920c0cbbebb42ccff4fa22dNick Kralevich    if (buf->len < 3) {
370e1ede1530ff21d3b8920c0cbbebb42ccff4fa22dNick Kralevich        // An well-formed entry must consist of at least a priority
371e1ede1530ff21d3b8920c0cbbebb42ccff4fa22dNick Kralevich        // and two null characters
372e1ede1530ff21d3b8920c0cbbebb42ccff4fa22dNick Kralevich        fprintf(stderr, "+++ LOG: entry too small\n");
3734bf3c02e026077d14a4512c7c2f71937da3c2d50Kenny Root        return -1;
3744bf3c02e026077d14a4512c7c2f71937da3c2d50Kenny Root    }
3754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
376a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey    int msgStart = -1;
377a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey    int msgEnd = -1;
378a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey
379e1ede1530ff21d3b8920c0cbbebb42ccff4fa22dNick Kralevich    int i;
380e1ede1530ff21d3b8920c0cbbebb42ccff4fa22dNick Kralevich    for (i = 1; i < buf->len; i++) {
381e1ede1530ff21d3b8920c0cbbebb42ccff4fa22dNick Kralevich        if (buf->msg[i] == '\0') {
382a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey            if (msgStart == -1) {
383a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey                msgStart = i + 1;
384a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey            } else {
385a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey                msgEnd = i;
386a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey                break;
387a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey            }
388e1ede1530ff21d3b8920c0cbbebb42ccff4fa22dNick Kralevich        }
389e1ede1530ff21d3b8920c0cbbebb42ccff4fa22dNick Kralevich    }
390a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey
391a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey    if (msgStart == -1) {
392a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey        fprintf(stderr, "+++ LOG: malformed log message\n");
39363f4a84104c228c74cdf132f5cef4f5184ae04bbNick Kralevich        return -1;
39463f4a84104c228c74cdf132f5cef4f5184ae04bbNick Kralevich    }
395a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey    if (msgEnd == -1) {
396a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey        // incoming message not null-terminated; force it
397a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey        msgEnd = buf->len - 1;
398a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey        buf->msg[msgEnd] = '\0';
399a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey    }
400a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey
401e1ede1530ff21d3b8920c0cbbebb42ccff4fa22dNick Kralevich    entry->priority = buf->msg[0];
402e1ede1530ff21d3b8920c0cbbebb42ccff4fa22dNick Kralevich    entry->tag = buf->msg + 1;
403a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey    entry->message = buf->msg + msgStart;
404a820a0e587b1f6be7283588b744cd33ba5723bdfJeff Sharkey    entry->messageLen = msgEnd - msgStart;
40563f4a84104c228c74cdf132f5cef4f5184ae04bbNick Kralevich
4064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return 0;
4074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
4084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
4094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/*
4104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Extract a 4-byte value from a byte stream.
4114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */
4124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic inline uint32_t get4LE(const uint8_t* src)
4134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
4144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
4154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
4164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
4174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/*
4184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Extract an 8-byte value from a byte stream.
4194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */
4204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic inline uint64_t get8LE(const uint8_t* src)
4214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
4224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    uint32_t low, high;
4234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
4244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
4254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24);
4264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return ((long long) high << 32) | (long long) low;
4274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
4284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
4294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
4304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/*
4314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Recursively convert binary log data to printable form.
4324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *
4334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * This needs to be recursive because you can have lists of lists.
4344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *
4354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * If we run out of room, we stop processing immediately.  It's important
4364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * for us to check for space on every output element to avoid producing
4374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * garbled output.
4384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *
4394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Returns 0 on success, 1 on buffer full, -1 on failure.
4404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */
4414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic int android_log_printBinaryEvent(const unsigned char** pEventData,
4424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    size_t* pEventDataLen, char** pOutBuf, size_t* pOutBufLen)
4434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
4444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    const unsigned char* eventData = *pEventData;
4454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    size_t eventDataLen = *pEventDataLen;
4464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    char* outBuf = *pOutBuf;
4474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    size_t outBufLen = *pOutBufLen;
4484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    unsigned char type;
4494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    size_t outCount;
4504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    int result = 0;
4514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
4524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (eventDataLen < 1)
4534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        return -1;
4544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    type = *eventData++;
4554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    eventDataLen--;
4564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
4574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    //fprintf(stderr, "--- type=%d (rem len=%d)\n", type, eventDataLen);
4584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
4594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    switch (type) {
4604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    case EVENT_TYPE_INT:
4614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        /* 32-bit signed int */
4624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        {
4634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            int ival;
4644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
4654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            if (eventDataLen < 4)
4664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                return -1;
4674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            ival = get4LE(eventData);
4684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            eventData += 4;
4694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            eventDataLen -= 4;
4704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
4714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            outCount = snprintf(outBuf, outBufLen, "%d", ival);
4724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            if (outCount < outBufLen) {
4734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                outBuf += outCount;
4744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                outBufLen -= outCount;
4754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            } else {
4764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                /* halt output */
4774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                goto no_room;
4784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            }
4794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
4804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        break;
4814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    case EVENT_TYPE_LONG:
4824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        /* 64-bit signed long */
4834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        {
4844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            long long lval;
4854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
4864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            if (eventDataLen < 8)
4874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                return -1;
4884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            lval = get8LE(eventData);
4894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            eventData += 8;
4904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            eventDataLen -= 8;
4914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
4924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            outCount = snprintf(outBuf, outBufLen, "%lld", lval);
4934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            if (outCount < outBufLen) {
4944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                outBuf += outCount;
4954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                outBufLen -= outCount;
4964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            } else {
4974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                /* halt output */
4984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                goto no_room;
4994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            }
5004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
5014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        break;
5024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    case EVENT_TYPE_STRING:
5034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        /* UTF-8 chars, not NULL-terminated */
5044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        {
5054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            unsigned int strLen;
5064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
5074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            if (eventDataLen < 4)
5084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                return -1;
5094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            strLen = get4LE(eventData);
5104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            eventData += 4;
5114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            eventDataLen -= 4;
5124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
5134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            if (eventDataLen < strLen)
5144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                return -1;
5154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
5164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            if (strLen < outBufLen) {
5174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                memcpy(outBuf, eventData, strLen);
5184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                outBuf += strLen;
5194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                outBufLen -= strLen;
5204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            } else if (outBufLen > 0) {
5214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                /* copy what we can */
5224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                memcpy(outBuf, eventData, outBufLen);
5234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                outBuf += outBufLen;
5244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                outBufLen -= outBufLen;
5254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                goto no_room;
5264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            }
5274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            eventData += strLen;
5284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            eventDataLen -= strLen;
5294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            break;
5304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
5314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    case EVENT_TYPE_LIST:
5324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        /* N items, all different types */
5334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        {
5344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            unsigned char count;
5354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            int i;
5364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
5374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            if (eventDataLen < 1)
5384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                return -1;
5394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
5404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            count = *eventData++;
5414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            eventDataLen--;
5424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
5434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            if (outBufLen > 0) {
5444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                *outBuf++ = '[';
5454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                outBufLen--;
5464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            } else {
5474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                goto no_room;
5484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            }
5494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
5504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            for (i = 0; i < count; i++) {
5514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                result = android_log_printBinaryEvent(&eventData, &eventDataLen,
5524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                        &outBuf, &outBufLen);
5534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                if (result != 0)
5544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                    goto bail;
5554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
5564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                if (i < count-1) {
5574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                    if (outBufLen > 0) {
5584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                        *outBuf++ = ',';
5594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                        outBufLen--;
5604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                    } else {
5614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                        goto no_room;
5624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                    }
5634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                }
5644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            }
5654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
5664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            if (outBufLen > 0) {
5674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                *outBuf++ = ']';
5684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                outBufLen--;
5694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            } else {
5704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                goto no_room;
5714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            }
5724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
5734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        break;
5744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    default:
5754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        fprintf(stderr, "Unknown binary event type %d\n", type);
5764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        return -1;
5774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
5784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
5794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectbail:
5804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *pEventData = eventData;
5814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *pEventDataLen = eventDataLen;
5824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *pOutBuf = outBuf;
5834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *pOutBufLen = outBufLen;
5844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return result;
5854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
5864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectno_room:
5874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    result = 1;
5884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    goto bail;
5894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
5904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
5914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/**
5924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Convert a binary log entry to ASCII form.
5934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *
5944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * For convenience we mimic the processLogBuffer API.  There is no
5954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * pre-defined output length for the binary data, since we're free to format
5964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * it however we choose, which means we can't really use a fixed-size buffer
5974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * here.
5984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */
5994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectint android_log_processBinaryLogBuffer(struct logger_entry *buf,
6004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    AndroidLogEntry *entry, const EventTagMap* map, char* messageBuf,
6014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    int messageBufLen)
6024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
6034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    size_t inCount;
6044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    unsigned int tagIndex;
6054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    const unsigned char* eventData;
6064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
6074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    entry->tv_sec = buf->sec;
6084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    entry->tv_nsec = buf->nsec;
6094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    entry->priority = ANDROID_LOG_INFO;
6104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    entry->pid = buf->pid;
6114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    entry->tid = buf->tid;
6124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
6134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    /*
6144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     * Pull the tag out.
6154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     */
6164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    eventData = (const unsigned char*) buf->msg;
6174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    inCount = buf->len;
6184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (inCount < 4)
6194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        return -1;
6204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    tagIndex = get4LE(eventData);
6214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    eventData += 4;
6224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    inCount -= 4;
6234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
6244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (map != NULL) {
6254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        entry->tag = android_lookupEventTag(map, tagIndex);
6264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    } else {
6274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        entry->tag = NULL;
6284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
6294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
6304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    /*
6314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     * If we don't have a map, or didn't find the tag number in the map,
6324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     * stuff a generated tag value into the start of the output buffer and
6334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     * shift the buffer pointers down.
6344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     */
6354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (entry->tag == NULL) {
6364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        int tagLen;
6374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
6384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        tagLen = snprintf(messageBuf, messageBufLen, "[%d]", tagIndex);
6394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        entry->tag = messageBuf;
6404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        messageBuf += tagLen+1;
6414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        messageBufLen -= tagLen+1;
6424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
6434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
6444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    /*
6454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     * Format the event log data into the buffer.
6464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     */
6474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    char* outBuf = messageBuf;
6484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    size_t outRemaining = messageBufLen-1;      /* leave one for nul byte */
6494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    int result;
6504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf,
6514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                &outRemaining);
6524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (result < 0) {
6534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        fprintf(stderr, "Binary log entry conversion failed\n");
6544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        return -1;
6554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    } else if (result == 1) {
6564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        if (outBuf > messageBuf) {
6574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            /* leave an indicator */
6584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            *(outBuf-1) = '!';
6594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        } else {
6604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            /* no room to output anything at all */
6614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            *outBuf++ = '!';
6624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            outRemaining--;
6634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
6644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        /* pretend we ate all the data */
6654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        inCount = 0;
6664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
6674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
6684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    /* eat the silly terminating '\n' */
6694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (inCount == 1 && *eventData == '\n') {
6704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        eventData++;
6714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        inCount--;
6724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
6734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
6744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (inCount != 0) {
6754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        fprintf(stderr,
676d2c8f52189f8c2a13b88a107c6495f9d83196d2dAndrew Hsieh            "Warning: leftover binary log data (%zu bytes)\n", inCount);
6774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
6784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
6794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    /*
6804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     * Terminate the buffer.  The NUL byte does not count as part of
6814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     * entry->messageLen.
6824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     */
6834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *outBuf = '\0';
6844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    entry->messageLen = outBuf - messageBuf;
6854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert(entry->messageLen == (messageBufLen-1) - outRemaining);
6864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
6874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    entry->message = messageBuf;
6884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
6894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return 0;
6904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
6914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
6924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/**
6934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Formats a log message into a buffer
6944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *
6954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Uses defaultBuffer if it can, otherwise malloc()'s a new buffer
6964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * If return value != defaultBuffer, caller must call free()
6974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Returns NULL on malloc error
6984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */
6994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
7004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectchar *android_log_formatLogLine (
7014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    AndroidLogFormat *p_format,
7024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    char *defaultBuffer,
7034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    size_t defaultBufferSize,
7044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    const AndroidLogEntry *entry,
7054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    size_t *p_outLength)
7064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
7074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if defined(HAVE_LOCALTIME_R)
7084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    struct tm tmBuf;
7094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif
7104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    struct tm* ptm;
7114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    char timeBuf[32];
7124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    char headerBuf[128];
7134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    char prefixBuf[128], suffixBuf[128];
7144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    char priChar;
7154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    int prefixSuffixIsHeaderFooter = 0;
7164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    char * ret = NULL;
7174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
7184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    priChar = filterPriToChar(entry->priority);
7194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
7204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    /*
7214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     * Get the current date/time in pretty form
7224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     *
7234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     * It's often useful when examining a log with "less" to jump to
7244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     * a specific point in the file by searching for the date/time stamp.
7254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     * For this reason it's very annoying to have regexp meta characters
7264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     * in the time stamp.  Don't use forward slashes, parenthesis,
7274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     * brackets, asterisks, or other special chars here.
7284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     */
7294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if defined(HAVE_LOCALTIME_R)
7304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    ptm = localtime_r(&(entry->tv_sec), &tmBuf);
7314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#else
7324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    ptm = localtime(&(entry->tv_sec));
7334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif
7344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    //strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", ptm);
7354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm);
7364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
7374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    /*
7384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     * Construct a buffer containing the log header and log message.
7394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project     */
7404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    size_t prefixLen, suffixLen;
7414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
7424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    switch (p_format->format) {
7434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        case FORMAT_TAG:
7444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),
7454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                "%c/%-8s: ", priChar, entry->tag);
7464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            strcpy(suffixBuf, "\n"); suffixLen = 1;
7474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            break;
7484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        case FORMAT_PROCESS:
7494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),
7504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                "%c(%5d) ", priChar, entry->pid);
7514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            suffixLen = snprintf(suffixBuf, sizeof(suffixBuf),
7524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                "  (%s)\n", entry->tag);
7534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            break;
7544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        case FORMAT_THREAD:
7554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),
756d2c8f52189f8c2a13b88a107c6495f9d83196d2dAndrew Hsieh                "%c(%5d:%5d) ", priChar, entry->pid, entry->tid);
7574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            strcpy(suffixBuf, "\n");
7584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            suffixLen = 1;
7594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            break;
7604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        case FORMAT_RAW:
7614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            prefixBuf[0] = 0;
7624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            prefixLen = 0;
7634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            strcpy(suffixBuf, "\n");
7644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            suffixLen = 1;
7654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            break;
7664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        case FORMAT_TIME:
7674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),
7684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                "%s.%03ld %c/%-8s(%5d): ", timeBuf, entry->tv_nsec / 1000000,
7694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                priChar, entry->tag, entry->pid);
7704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            strcpy(suffixBuf, "\n");
7714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            suffixLen = 1;
7724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            break;
7734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        case FORMAT_THREADTIME:
7744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),
7754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                "%s.%03ld %5d %5d %c %-8s: ", timeBuf, entry->tv_nsec / 1000000,
776d2c8f52189f8c2a13b88a107c6495f9d83196d2dAndrew Hsieh                entry->pid, entry->tid, priChar, entry->tag);
7774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            strcpy(suffixBuf, "\n");
7784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            suffixLen = 1;
7794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            break;
7804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        case FORMAT_LONG:
7814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),
782d2c8f52189f8c2a13b88a107c6495f9d83196d2dAndrew Hsieh                "[ %s.%03ld %5d:%5d %c/%-8s ]\n",
7834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                timeBuf, entry->tv_nsec / 1000000, entry->pid,
784d2c8f52189f8c2a13b88a107c6495f9d83196d2dAndrew Hsieh                entry->tid, priChar, entry->tag);
7854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            strcpy(suffixBuf, "\n\n");
7864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            suffixLen = 2;
7874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            prefixSuffixIsHeaderFooter = 1;
7884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            break;
7894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        case FORMAT_BRIEF:
7904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        default:
7914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),
7924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                "%c/%-8s(%5d): ", priChar, entry->tag, entry->pid);
7934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            strcpy(suffixBuf, "\n");
7944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            suffixLen = 1;
7954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            break;
7964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
797b45b5c9f227473050ef785d11e518e947c8754fbKeith Preston    /* snprintf has a weird return value.   It returns what would have been
798b45b5c9f227473050ef785d11e518e947c8754fbKeith Preston     * written given a large enough buffer.  In the case that the prefix is
799b45b5c9f227473050ef785d11e518e947c8754fbKeith Preston     * longer then our buffer(128), it messes up the calculations below
800b45b5c9f227473050ef785d11e518e947c8754fbKeith Preston     * possibly causing heap corruption.  To avoid this we double check and
801b45b5c9f227473050ef785d11e518e947c8754fbKeith Preston     * set the length at the maximum (size minus null byte)
802b45b5c9f227473050ef785d11e518e947c8754fbKeith Preston     */
803b45b5c9f227473050ef785d11e518e947c8754fbKeith Preston    if(prefixLen >= sizeof(prefixBuf))
804b45b5c9f227473050ef785d11e518e947c8754fbKeith Preston        prefixLen = sizeof(prefixBuf) - 1;
805b45b5c9f227473050ef785d11e518e947c8754fbKeith Preston    if(suffixLen >= sizeof(suffixBuf))
806b45b5c9f227473050ef785d11e518e947c8754fbKeith Preston        suffixLen = sizeof(suffixBuf) - 1;
8074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
8084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    /* the following code is tragically unreadable */
8094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
8104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    size_t numLines;
8114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    size_t i;
8124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    char *p;
8134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    size_t bufferSize;
8144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    const char *pm;
8154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
8164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (prefixSuffixIsHeaderFooter) {
8174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        // we're just wrapping message with a header/footer
8184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        numLines = 1;
8194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    } else {
8204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        pm = entry->message;
8214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        numLines = 0;
8224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
8234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        // The line-end finding here must match the line-end finding
8244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        // in for ( ... numLines...) loop below
8254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        while (pm < (entry->message + entry->messageLen)) {
8264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            if (*pm++ == '\n') numLines++;
8274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
8284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        // plus one line for anything not newline-terminated at the end
8294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        if (pm > entry->message && *(pm-1) != '\n') numLines++;
8304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
8314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
8324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    // this is an upper bound--newlines in message may be counted
8334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    // extraneously
8344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    bufferSize = (numLines * (prefixLen + suffixLen)) + entry->messageLen + 1;
8354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
8364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (defaultBufferSize >= bufferSize) {
8374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        ret = defaultBuffer;
8384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    } else {
8394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        ret = (char *)malloc(bufferSize);
8404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
8414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        if (ret == NULL) {
8424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            return ret;
8434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
8444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
8454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
8464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    ret[0] = '\0';       /* to start strcat off */
8474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
8484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    p = ret;
8494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    pm = entry->message;
8504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
8514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (prefixSuffixIsHeaderFooter) {
8524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        strcat(p, prefixBuf);
8534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        p += prefixLen;
8544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        strncat(p, entry->message, entry->messageLen);
8554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        p += entry->messageLen;
8564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        strcat(p, suffixBuf);
8574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        p += suffixLen;
8584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    } else {
8594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        while(pm < (entry->message + entry->messageLen)) {
8604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            const char *lineStart;
8614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            size_t lineLen;
8624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            lineStart = pm;
8634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
8644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            // Find the next end-of-line in message
8654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            while (pm < (entry->message + entry->messageLen)
8664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                    && *pm != '\n') pm++;
8674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            lineLen = pm - lineStart;
8684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
8694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            strcat(p, prefixBuf);
8704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            p += prefixLen;
8714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            strncat(p, lineStart, lineLen);
8724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            p += lineLen;
8734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            strcat(p, suffixBuf);
8744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            p += suffixLen;
8754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
8764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            if (*pm == '\n') pm++;
8774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
8784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
8794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
8804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (p_outLength != NULL) {
8814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        *p_outLength = p - ret;
8824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
8834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
8844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return ret;
8854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
8864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
8874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/**
8884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Either print or do not print log line, based on filter
8894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *
8904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Returns count bytes written
8914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */
8924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
893e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onoratoint android_log_printLogLine(
8944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    AndroidLogFormat *p_format,
8954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    int fd,
8964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    const AndroidLogEntry *entry)
8974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
8984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    int ret;
8994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    char defaultBuffer[512];
9004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    char *outBuffer = NULL;
9014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    size_t totalLen;
9024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    outBuffer = android_log_formatLogLine(p_format, defaultBuffer,
9044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            sizeof(defaultBuffer), entry, &totalLen);
9054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (!outBuffer)
9074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        return -1;
9084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    do {
9104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        ret = write(fd, outBuffer, totalLen);
9114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    } while (ret < 0 && errno == EINTR);
9124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (ret < 0) {
9144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        fprintf(stderr, "+++ LOG: write failed (errno=%d)\n", errno);
9154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        ret = 0;
9164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        goto done;
9174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
9184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (((size_t)ret) < totalLen) {
9204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        fprintf(stderr, "+++ LOG: write partial (%d of %d)\n", ret,
9214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                (int)totalLen);
9224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        goto done;
9234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
9244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectdone:
9264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (outBuffer != defaultBuffer) {
9274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        free(outBuffer);
9284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
9294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return ret;
9314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
9324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid logprint_run_tests()
9364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
9374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if 0
9384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    fprintf(stderr, "tests disabled\n");
9404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#else
9424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    int err;
9444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    const char *tag;
9454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    AndroidLogFormat *p_format;
9464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    p_format = android_log_format_new();
9484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    fprintf(stderr, "running tests\n");
9504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    tag = "random";
9524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    android_log_addFilterRule(p_format,"*:i");
9544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert (ANDROID_LOG_INFO == filterPriForTag(p_format, "random"));
9564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
9574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    android_log_addFilterRule(p_format, "*");
9584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert (ANDROID_LOG_DEBUG == filterPriForTag(p_format, "random"));
9594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
9604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    android_log_addFilterRule(p_format, "*:v");
9614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert (ANDROID_LOG_VERBOSE == filterPriForTag(p_format, "random"));
9624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
9634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    android_log_addFilterRule(p_format, "*:i");
9644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert (ANDROID_LOG_INFO == filterPriForTag(p_format, "random"));
9654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
9664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    android_log_addFilterRule(p_format, "random");
9684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert (ANDROID_LOG_VERBOSE == filterPriForTag(p_format, "random"));
9694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
9704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    android_log_addFilterRule(p_format, "random:v");
9714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert (ANDROID_LOG_VERBOSE == filterPriForTag(p_format, "random"));
9724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
9734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    android_log_addFilterRule(p_format, "random:d");
9744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert (ANDROID_LOG_DEBUG == filterPriForTag(p_format, "random"));
9754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
9764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    android_log_addFilterRule(p_format, "random:w");
9774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert (ANDROID_LOG_WARN == filterPriForTag(p_format, "random"));
9784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
9794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    android_log_addFilterRule(p_format, "crap:*");
9814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert (ANDROID_LOG_VERBOSE== filterPriForTag(p_format, "crap"));
9824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert(android_log_shouldPrintLine(p_format, "crap", ANDROID_LOG_VERBOSE) > 0);
9834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    // invalid expression
9854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    err = android_log_addFilterRule(p_format, "random:z");
9864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert (err < 0);
9874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert (ANDROID_LOG_WARN == filterPriForTag(p_format, "random"));
9884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
9894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    // Issue #550946
9914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    err = android_log_addFilterString(p_format, " ");
9924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert(err == 0);
9934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert(ANDROID_LOG_WARN == filterPriForTag(p_format, "random"));
9944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
9954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    // note trailing space
9964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    err = android_log_addFilterString(p_format, "*:s random:d ");
9974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert(err == 0);
9984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert(ANDROID_LOG_DEBUG == filterPriForTag(p_format, "random"));
9994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
10004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    err = android_log_addFilterString(p_format, "*:s random:z");
10014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    assert(err < 0);
10024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
10034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
10044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if 0
10054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    char *ret;
10064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    char defaultBuffer[512];
10074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
10084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    ret = android_log_formatLogLine(p_format,
10094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        defaultBuffer, sizeof(defaultBuffer), 0, ANDROID_LOG_ERROR, 123,
10104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        123, 123, "random", "nofile", strlen("Hello"), "Hello", NULL);
10114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif
10124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
10134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
10144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    fprintf(stderr, "tests complete\n");
10154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif
10164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
1017