ovni/src/emu/clkoff.c
Rodrigo Arias ddbb7dd9f4 Add include-what-you-use
Adds forwards declarations in headers and includes all headers in
sources, even if they are found by transitive includes.
2023-03-24 12:08:45 +00:00

147 lines
2.5 KiB
C

/* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include "clkoff.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
static struct clkoff_entry *
cfind(struct clkoff *off, const char *name)
{
struct clkoff_entry *entry = NULL;
HASH_FIND_STR(off->entries, name, entry);
return entry;
}
static int
cadd(struct clkoff *table, struct clkoff_entry e)
{
if (cfind(table, e.name) != NULL) {
err("entry with name '%s' already exists", e.name);
return -1;
}
struct clkoff_entry *entry = calloc(1, sizeof(struct clkoff_entry));
if (entry == NULL) {
err("calloc failed");
return -1;
}
memcpy(entry, &e, sizeof(*entry));
HASH_ADD_STR(table->entries, name, entry);
table->nentries++;
return 0;
}
static int
cparse(struct clkoff *table, FILE *file)
{
/* Ignore header line */
char buf[1024];
if (fgets(buf, 1024, file) == NULL) {
err("missing header line in clock offset");
return -1;
}
for (int line = 1; ; line++) {
errno = 0;
struct clkoff_entry e = { 0 };
if (fgets(buf, 1024, file) == NULL)
break;
/* Empty line */
if (buf[0] == '\n')
continue;
int ret = sscanf(buf, "%ld %s %lf %lf %lf",
&e.index, e.name,
&e.median, &e.mean, &e.stdev);
if (ret == EOF && errno == 0)
break;
if (ret == EOF && errno != 0) {
err("fscanf() failed in line %d", line);
return -1;
}
if (ret != 5) {
err("fscanf() read %d instead of 5 fields in line %d",
ret, line);
return -1;
}
if (cadd(table, e) != 0) {
err("cannot add entry of line %d",
line);
return -1;
}
}
return 0;
}
static int
cindex(struct clkoff *table)
{
if (table->nentries < 1) {
err("no entries");
return -1;
}
table->index = calloc(table->nentries, sizeof(struct clkoff_entry *));
if (table->index == NULL) {
err("calloc failed");
return -1;
}
struct clkoff_entry *e;
int i = 0;
for (e = table->entries; e; e = e->hh.next)
table->index[i++] = e;
return 0;
}
void
clkoff_init(struct clkoff *table)
{
memset(table, 0, sizeof(struct clkoff));
}
int
clkoff_load(struct clkoff *table, FILE *file)
{
if (cparse(table, file) != 0) {
err("failed parsing clock table");
return -1;
}
/* Create index array */
if (cindex(table) != 0) {
err("failed indexing table");
return -1;
}
return 0;
}
int
clkoff_count(struct clkoff *table)
{
return table->nentries;
}
struct clkoff_entry *
clkoff_get(struct clkoff *table, int i)
{
return table->index[i];
}