From patchwork Mon May 28 15:01:23 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Colin Ian King X-Patchwork-Id: 161625 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id DF6E8B6FA4 for ; Tue, 29 May 2012 01:01:28 +1000 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1SZ1Rn-0002fk-Nr for incoming@patchwork.ozlabs.org; Mon, 28 May 2012 15:01:27 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1SZ1Rl-0002fX-Hq for fwts-devel@lists.ubuntu.com; Mon, 28 May 2012 15:01:25 +0000 Received: from cpc19-craw6-2-0-cust5.croy.cable.virginmedia.com ([77.102.228.6] helo=localhost) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1SZ1Rl-0008OC-5G for fwts-devel@lists.ubuntu.com; Mon, 28 May 2012 15:01:25 +0000 From: Colin King To: fwts-devel@lists.ubuntu.com Subject: [PATCH 1/2] lib: add xml logging Date: Mon, 28 May 2012 16:01:23 +0100 Message-Id: <1338217284-8752-1-git-send-email-colin.king@canonical.com> X-Mailer: git-send-email 1.7.10 X-BeenThere: fwts-devel@lists.ubuntu.com X-Mailman-Version: 2.1.13 Precedence: list List-Id: Firmware Test Suite Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: fwts-devel-bounces@lists.ubuntu.com Errors-To: fwts-devel-bounces@lists.ubuntu.com From: Colin Ian King Signed-off-by: Colin Ian King Acked-by: Keng-Yu Lin Acked-by: Ivan Hu --- doc/fwts.1 | 2 +- src/lib/include/fwts_log.h | 1 + src/lib/src/Makefile.am | 1 + src/lib/src/fwts_framework.c | 4 +- src/lib/src/fwts_log.c | 3 + src/lib/src/fwts_log_xml.c | 186 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 195 insertions(+), 2 deletions(-) create mode 100644 src/lib/src/fwts_log_xml.c diff --git a/doc/fwts.1 b/doc/fwts.1 index 0d773cd..09eee56 100644 --- a/doc/fwts.1 +++ b/doc/fwts.1 @@ -150,7 +150,7 @@ specify the information in each log line. The following specifiers are available e.g. \-\-log\-format="%date %time [%field] (%owner): " .TP .B \-\-log\-type -specify the log type. Currently plaintext and json log types are available and the +specify the log type. Currently plaintext, json and xml log types are available and the default is plaintext. .TP .B \-\-lp\-tags diff --git a/src/lib/include/fwts_log.h b/src/lib/include/fwts_log.h index 8903bab..8027d41 100644 --- a/src/lib/include/fwts_log.h +++ b/src/lib/include/fwts_log.h @@ -81,6 +81,7 @@ typedef struct fwts_log_ops_t { fwts_log_ops fwts_log_plaintext_ops; fwts_log_ops fwts_log_json_ops; +fwts_log_ops fwts_log_xml_ops; extern fwts_log_field fwts_log_filter; extern const char *fwts_log_format; diff --git a/src/lib/src/Makefile.am b/src/lib/src/Makefile.am index cae1f91..acea9cb 100644 --- a/src/lib/src/Makefile.am +++ b/src/lib/src/Makefile.am @@ -39,6 +39,7 @@ libfwts_la_SOURCES = \ fwts_log.c \ fwts_log_plaintext.c \ fwts_log_json.c \ + fwts_log_xml.c \ fwts_memorymap.c \ fwts_microcode.c \ fwts_mmap.c \ diff --git a/src/lib/src/fwts_framework.c b/src/lib/src/fwts_framework.c index 1fcd88e..2b42982 100644 --- a/src/lib/src/fwts_framework.c +++ b/src/lib/src/fwts_framework.c @@ -76,7 +76,7 @@ static fwts_option fwts_framework_options[] = { { "json-data-path", "j:", 1, "Specify path to fwts json data files - default is /usr/share/fwts." }, { "lp-tags-log", "", 0, "Output LaunchPad bug tags in results log." }, { "disassemble-aml", "", 0, "Disassemble AML from DSDT and SSDT tables." }, - { "log-type", "", 1, "Specify log type (plaintext or json)." }, + { "log-type", "", 1, "Specify log type (plaintext, json or xml)." }, { NULL, NULL, 0, NULL } }; @@ -1040,6 +1040,8 @@ int fwts_framework_options_handler(fwts_framework *fw, int argc, char * const ar fw->log_type = LOG_TYPE_PLAINTEXT; else if (!strcmp(optarg, "json")) fw->log_type = LOG_TYPE_JSON; + else if (!strcmp(optarg, "xml")) + fw->log_type = LOG_TYPE_XML; else { fprintf(stderr, "--log-type can be either plaintext or json.\n"); return FWTS_ERROR; diff --git a/src/lib/src/fwts_log.c b/src/lib/src/fwts_log.c index 5331fff..2b11441 100644 --- a/src/lib/src/fwts_log.c +++ b/src/lib/src/fwts_log.c @@ -390,6 +390,9 @@ fwts_log *fwts_log_open(const char *owner, const char *name, const char *mode, f case LOG_TYPE_PLAINTEXT: newlog->ops = &fwts_log_plaintext_ops; break; + case LOG_TYPE_XML: + newlog->ops = &fwts_log_xml_ops; + break; case LOG_TYPE_NONE: default: newlog->ops = &fwts_log_plaintext_ops; diff --git a/src/lib/src/fwts_log_xml.c b/src/lib/src/fwts_log_xml.c new file mode 100644 index 0000000..57b530b --- /dev/null +++ b/src/lib/src/fwts_log_xml.c @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2010-2012 Canonical + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "fwts.h" + +#define MAX_XML_STACK (64) +#define XML_INDENT (4) + +typedef struct { + const char *name; +} fwts_log_xml_stack_t; + +static fwts_log_xml_stack_t xml_stack[MAX_XML_STACK]; +static int xml_stack_index = 0; + +/* + * fwts_log_vprintf_xml() + * vprintf to a log + */ +static int fwts_log_vprintf_xml(fwts_log *log, + const fwts_log_field field, + const fwts_log_level level, + const char *status, + const char *label, + const char *prefix, + const char *fmt, + va_list args) +{ + char buffer[4096]; + struct tm tm; + time_t now; + char *str; + + if (!((field & LOG_FIELD_MASK) & fwts_log_filter)) + return 0; + + if (field & (LOG_NEWLINE | LOG_SEPARATOR | LOG_DEBUG)) + return 0; + + time(&now); + localtime_r(&now, &tm); + + fprintf(log->fp, "%*s\n", xml_stack_index * XML_INDENT, ""); + + fprintf(log->fp, "%*s%d\n", + (xml_stack_index + 1) * XML_INDENT, + "", log->line_number); + + fprintf(log->fp, "%*s%2.2d/%2.2d/%-2.2d\n", + (xml_stack_index + 1) * XML_INDENT, + "", tm.tm_mday, tm.tm_mon + 1, (tm.tm_year+1900) % 100); + + fprintf(log->fp, "%*s\n", + (xml_stack_index + 1) * XML_INDENT, + "", tm.tm_hour, tm.tm_min, tm.tm_sec); + + fprintf(log->fp, "%*s%s\n", + (xml_stack_index + 1) * XML_INDENT, + "", fwts_log_field_to_str_full(field)); + + str = fwts_log_level_to_str(level); + if (!strcmp(str, " ")) + str = "None"; + + fprintf(log->fp, "%*s%s\n", + (xml_stack_index + 1) * XML_INDENT, "", str); + + fprintf(log->fp, "%*s%s\n", + (xml_stack_index + 1) * XML_INDENT, + "", *status ? status : "None"); + + fprintf(log->fp, "%*s%s\n", + (xml_stack_index + 1) * XML_INDENT, + "", label && *label ? label : "None"); + + vsnprintf(buffer, sizeof(buffer), fmt, args); + fprintf(log->fp, "%*s%s\n", + (xml_stack_index + 1) * XML_INDENT, + "", buffer); + + fprintf(log->fp, "%*s\n", xml_stack_index * XML_INDENT, ""); + fflush(log->fp); + + log->line_number++; + + return 0; +} + +/* + * fwts_log_underline_xml() + * write an underline across log, using character ch as the underline + */ +static void fwts_log_underline_xml(fwts_log *log, const int ch) +{ + /* No-op for xml */ +} + +/* + * fwts_log_newline() + * write newline to log + */ +static void fwts_log_newline_xml(fwts_log *log) +{ + /* No-op for xml */ +} + +static void fwts_log_section_begin_xml(fwts_log *log, const char *name) +{ + xml_stack[xml_stack_index].name = name; + + fprintf(log->fp, "%*s<%s>\n", xml_stack_index * XML_INDENT, "", name); + fflush(log->fp); + + if (xml_stack_index < MAX_XML_STACK) + xml_stack_index++; + else { + fprintf(stderr, "xml log stack overflow pushing section %s.\n", name); + exit(EXIT_FAILURE); + } +} + +static void fwts_log_section_end_xml(fwts_log *log) +{ + if (xml_stack_index > 0) { + xml_stack_index--; + fprintf(log->fp, "%*s\n", xml_stack_index * XML_INDENT, + "", xml_stack[xml_stack_index].name); + fflush(log->fp); + } else { + fprintf(stderr, "xml log stack underflow.\n"); + exit(EXIT_FAILURE); + } + +} + +static void fwts_log_open_xml(fwts_log *log) +{ + char *xml_header = "\n"; + + fwrite(xml_header, 1, strlen(xml_header), log->fp); + fflush(log->fp); + + fwts_log_section_begin_xml(log, "fwts"); +} + +static void fwts_log_close_xml(fwts_log *log) +{ + fwts_log_section_end_xml(log); + + fwrite("\n", 1, 1, log->fp); + fflush(log->fp); +} + +fwts_log_ops fwts_log_xml_ops = { + .vprintf = fwts_log_vprintf_xml, + .underline = fwts_log_underline_xml, + .newline = fwts_log_newline_xml, + .section_begin = fwts_log_section_begin_xml, + .section_end = fwts_log_section_end_xml, + .open = fwts_log_open_xml, + .close = fwts_log_close_xml +};