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