Files
failnix/targets/wasm-tacle/parallel/PapaBench/sw/lib/c/logger.c

194 lines
5.4 KiB
C

/*
logger.c
Copyright (C) 2003 Antoine Drouin
This file is part of paparazzi.
paparazzi 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, or (at your option)
any later version.
paparazzi 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 paparazzi; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include <sys/types.h>
#include <dirent.h>
#include <libgen.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include <glib.h>
#include "logger.h"
//static GList* logger_parse_messages(struct PprzProtocol* protocol, xmlDocPtr doc, xmlNodePtr cur);
static GList *logger_parse_message( struct PprzProtocol *protocol, GList *msgs,
const guchar *buf );
struct Logger *logger_new( const gchar *out_file, xmlDocPtr doc )
{
const gchar *opening = "<data>\n";
struct Logger *this = g_new( struct Logger, 1 );
if ( this ) {
GError *err = NULL;
gchar *copy = strdup( out_file );
gchar *out_dir = dirname( copy );
DIR *d;
if ( !( d = opendir( out_dir ) ) ) {
if ( errno == ENOENT ) {
if ( mkdir( out_dir, S_IRWXU | S_IRWXG ) ) {
g_message( "log directory %s doesn't exist and could not create it", out_dir );
/* FIXME : FREE */
return NULL;
}
} else {
g_message( "could not acces log directory %s %s", out_dir,
g_strerror( errno ) );
/* FIXME : FREE */
return NULL;
}
}
closedir( d );
g_free( copy );
xmlSaveFormatFile ( out_file, doc, 1 );
/* FIXME : check result */
this->channel = g_io_channel_new_file( out_file, "a", &err );
if ( err ) {
g_message( "could not open log file %s : %s", out_file, err->message );
g_error_free( err );
g_free( this );
return NULL;
}
g_io_channel_write_chars( this->channel, opening, strlen( opening ), NULL,
NULL );
}
return this;
}
void logger_free( struct Logger *this )
{
const gchar *closing = "</data>\n</log>\n";
g_io_channel_write_chars( this->channel, closing, strlen( closing ), NULL,
NULL );
g_io_channel_flush( this->channel, NULL );
// g_io_channel_free(this->channel);
g_free( this );
}
void logger_log( struct Logger *this, struct PprzMsg *msg )
{
GString *str;
pprz_protocol_ascii_of_msg( msg, &str );
if ( str ) {
GError *err = NULL;
guint len;
g_io_channel_write_chars ( this->channel, str->str, str->len, &len, &err );
if ( err ) {
g_warning( "log write failed %s", err->message );
g_error_free( err );
g_string_free( str, TRUE );
return;
}
g_string_free( str, TRUE );
g_io_channel_flush( this->channel, &err );
if ( err ) {
g_warning( "log flush failed %s", err->message );
g_error_free( err );
return;
}
}
}
GList *logger_parse_log( const gchar *filename,
struct PprzProtocol **protocol )
{
xmlDocPtr doc;
xmlNodePtr cur;
GList *msgs = NULL;
const gchar *protocol_closure = "</protocol>";
gchar *contents, *data_start;
gsize len;
GError *err;
gboolean res = g_file_get_contents( filename, &contents, &len, &err );
if ( !res ) {
g_message( "could not read file %s : %s", filename, err->message );
g_error_free( err );
return NULL;
}
if ( !( data_start = g_strstr_len( contents, len, protocol_closure ) ) ) {
g_free( contents );
g_message( "protocol closing not found" );
return NULL;
}
data_start += strlen( protocol_closure );
if ( !( doc = xmlParseMemory( contents, data_start - contents ) ) ) {
g_free( contents );
g_message( "error parsing protocol xml" );
return NULL;
}
if ( !( cur = xmlDocGetRootElement( doc ) ) ) {
g_free( contents );
g_message( "empty protocol" );
return NULL;
}
if ( !( *protocol = pprz_protocol_new_from_xml( doc, cur ) ) ) {
g_free( contents );
g_message( "error interpreting protocol" );
return NULL;
}
msgs = logger_parse_message( *protocol, msgs, data_start );
g_free( contents );
return msgs;
}
/* static GList* logger_parse_messages(struct PprzProtocol* protocol, xmlDocPtr doc, xmlNodePtr cur) { */
/* if (!cur) return NULL; */
/* if (xmlStrcmp(cur->name, (const xmlChar *) "data")) */
/* return cur->next?logger_parse_messages(protocol, doc, cur->next):NULL; */
/* cur = cur->xmlChildrenNode; */
/* if (xmlStrcmp(cur->name, (const xmlChar *) "text")) */
/* return NULL; */
/* return logger_parse_message(protocol, NULL, cur->content); */
/* } */
static GList *logger_parse_message( struct PprzProtocol *protocol, GList *msgs,
const guchar *buf )
{
guchar *next;
struct PprzMsg *msg = pprz_protocol_msg_new_of_ascii( protocol, buf );
if ( msg )
msgs = g_list_append( msgs, msg );
if ( ( next = index( buf, '\n' ) ) )
return logger_parse_message( protocol, msgs, next + 1 );
return msgs;
}