info: introduce di_logger

This can be used by parsers (EDID, CTA, DisplayID, etc) to report
errors.

Signed-off-by: Simon Ser <contact@emersion.fr>
This commit is contained in:
Simon Ser 2022-08-02 12:18:19 +02:00
parent 8e7308358e
commit 7834b6ba22
7 changed files with 87 additions and 48 deletions

49
edid.c
View file

@ -1,6 +1,5 @@
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
@ -8,6 +7,7 @@
#include "bits.h"
#include "dmt.h"
#include "edid.h"
#include "log.h"
/**
* The size of an EDID block, defined in section 2.2.
@ -27,31 +27,13 @@
*/
static const uint8_t header[] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
static void
va_add_failure(struct di_edid *edid, const char fmt[], va_list args)
{
if (!edid->failure_msg_file) {
edid->failure_msg_file = open_memstream(&edid->failure_msg,
&edid->failure_msg_size);
if (!edid->failure_msg_file) {
return;
}
fprintf(edid->failure_msg_file, "Block 0, Base EDID:\n");
}
fprintf(edid->failure_msg_file, " ");
vfprintf(edid->failure_msg_file, fmt, args);
fprintf(edid->failure_msg_file, "\n");
}
static void
add_failure(struct di_edid *edid, const char fmt[], ...)
{
va_list args;
va_start(args, fmt);
va_add_failure(edid, fmt, args);
_di_logger_va_add_failure(edid->logger, fmt, args);
va_end(args);
}
@ -65,7 +47,7 @@ add_failure_until(struct di_edid *edid, int revision, const char fmt[], ...)
}
va_start(args, fmt);
va_add_failure(edid, fmt, args);
_di_logger_va_add_failure(edid->logger, fmt, args);
va_end(args);
}
@ -679,9 +661,10 @@ parse_ext(struct di_edid *edid, const uint8_t data[static EDID_BLOCK_SIZE])
}
struct di_edid *
_di_edid_parse(const void *data, size_t size)
_di_edid_parse(const void *data, size_t size, FILE *failure_msg_file)
{
struct di_edid *edid;
struct di_logger logger;
int version, revision;
size_t exts_len, i;
const uint8_t *standard_timing_data, *byte_desc_data, *ext_data;
@ -722,6 +705,12 @@ _di_edid_parse(const void *data, size_t size)
return NULL;
}
logger = (struct di_logger) {
.f = failure_msg_file,
.section = "Block 0, Base EDID",
};
edid->logger = &logger;
edid->version = version;
edid->revision = revision;
@ -755,16 +744,7 @@ _di_edid_parse(const void *data, size_t size)
}
}
if (edid->failure_msg_file) {
if (fflush(edid->failure_msg_file) != 0) {
_di_edid_destroy(edid);
return NULL;
}
fclose(edid->failure_msg_file);
edid->failure_msg_file = NULL;
}
edid->logger = NULL;
return edid;
}
@ -774,11 +754,6 @@ _di_edid_destroy(struct di_edid *edid)
size_t i;
struct di_edid_ext *ext;
if (edid->failure_msg_file) {
fclose(edid->failure_msg_file);
}
free(edid->failure_msg);
for (i = 0; i < edid->standard_timings_len; i++) {
free(edid->standard_timings[i]);
}

View file

@ -58,9 +58,7 @@ struct di_edid {
struct di_edid_ext *exts[EDID_MAX_BLOCK_COUNT];
size_t exts_len;
char *failure_msg;
size_t failure_msg_size;
FILE *failure_msg_file;
struct di_logger *logger;
};
struct di_edid_display_descriptor {
@ -86,7 +84,7 @@ struct di_edid_ext {
* di_edid_destroy().
*/
struct di_edid *
_di_edid_parse(const void *data, size_t size);
_di_edid_parse(const void *data, size_t size, FILE *failure_msg_file);
/**
* Destroy an EDID data structure.

View file

@ -9,6 +9,8 @@
struct di_info {
struct di_edid *edid;
char *failure_msg;
};
#endif

21
include/log.h Normal file
View file

@ -0,0 +1,21 @@
#ifndef LOG_H
#define LOG_H
/**
* Private logging utilities.
*/
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
struct di_logger {
FILE *f;
const char *section;
bool initialized;
};
void
_di_logger_va_add_failure(struct di_logger *logger, const char fmt[], va_list args);
#endif

39
info.c
View file

@ -5,32 +5,57 @@
#include "edid.h"
#include "info.h"
#include "log.h"
struct di_info *
di_info_parse_edid(const void *data, size_t size)
{
struct di_edid *edid;
struct di_info *info;
char *failure_msg = NULL;
size_t failure_msg_size;
FILE *failure_msg_file;
edid = _di_edid_parse(data, size);
if (!edid)
failure_msg_file = open_memstream(&failure_msg,
&failure_msg_size);
if (!failure_msg_file)
return NULL;
edid = _di_edid_parse(data, size, failure_msg_file);
if (!edid)
goto err_failure_msg_file;
info = calloc(1, sizeof(*info));
if (!info) {
_di_edid_destroy(edid);
return NULL;
}
if (!info)
goto err_edid;
info->edid = edid;
if (fflush(failure_msg_file) != 0)
goto err_info;
fclose(failure_msg_file);
if (failure_msg && failure_msg[0] != '\0')
info->failure_msg = failure_msg;
else
free(failure_msg);
return info;
err_info:
free(info);
err_edid:
_di_edid_destroy(edid);
err_failure_msg_file:
fclose(failure_msg_file);
free(failure_msg);
return NULL;
}
void
di_info_destroy(struct di_info *info)
{
_di_edid_destroy(info->edid);
free(info->failure_msg);
free(info);
}
@ -43,7 +68,7 @@ di_info_get_edid(const struct di_info *info)
const char *
di_info_get_failure_msg(const struct di_info *info)
{
return info->edid->failure_msg;
return info->failure_msg;
}
char *

17
log.c Normal file
View file

@ -0,0 +1,17 @@
#include "log.h"
void
_di_logger_va_add_failure(struct di_logger *logger, const char fmt[], va_list args)
{
if (!logger->initialized) {
if (ftell(logger->f) > 0) {
fprintf(logger->f, "\n");
}
fprintf(logger->f, "%s:\n", logger->section);
logger->initialized = true;
}
fprintf(logger->f, " ");
vfprintf(logger->f, fmt, args);
fprintf(logger->f, "\n");
}

View file

@ -39,6 +39,7 @@ di_lib = library(
'dmt-table.c',
'edid.c',
'info.c',
'log.c',
],
include_directories: include_directories('include'),
link_args: symbols_flag,