blob: 94e1ed513c8f7b6209810c2232dc3c78b6aac88d [file] [log] [blame]
// Access to pseudo "file" interface for configuration information.
//
// Copyright (C) 2012 Kevin O'Connor <kevin@koconnor.net>
//
// This file may be distributed under the terms of the GNU LGPLv3 license.
#include "config.h" // CONFIG_*
#include "util.h" // dprintf
#include "romfile.h" // struct romfile_s
#include "string.h" // memcmp
static struct romfile_s *RomfileRoot VARVERIFY32INIT;
void
romfile_add(struct romfile_s *file)
{
dprintf(3, "Add romfile: %s (size=%d)\n", file->name, file->size);
file->next = RomfileRoot;
RomfileRoot = file;
}
// Search for the specified file.
static struct romfile_s *
__romfile_findprefix(const char *prefix, int prefixlen, struct romfile_s *prev)
{
struct romfile_s *cur = RomfileRoot;
if (prev)
cur = prev->next;
while (cur) {
if (memcmp(prefix, cur->name, prefixlen) == 0)
return cur;
cur = cur->next;
}
return NULL;
}
struct romfile_s *
romfile_findprefix(const char *prefix, struct romfile_s *prev)
{
return __romfile_findprefix(prefix, strlen(prefix), prev);
}
struct romfile_s *
romfile_find(const char *name)
{
return __romfile_findprefix(name, strlen(name) + 1, NULL);
}
// Helper function to find, malloc_tmphigh, and copy a romfile. This
// function adds a trailing zero to the malloc'd copy.
void *
romfile_loadfile(const char *name, int *psize)
{
struct romfile_s *file = romfile_find(name);
if (!file)
return NULL;
int filesize = file->size;
if (!filesize)
return NULL;
char *data = malloc_tmphigh(filesize+1);
if (!data) {
warn_noalloc();
return NULL;
}
dprintf(5, "Copying romfile '%s' (len %d)\n", name, filesize);
int ret = file->copy(file, data, filesize);
if (ret < 0) {
free(data);
return NULL;
}
if (psize)
*psize = filesize;
data[filesize] = '\0';
return data;
}
// Attempt to load an integer from the given file - return 'defval'
// if unsuccesful.
u64
romfile_loadint(const char *name, u64 defval)
{
struct romfile_s *file = romfile_find(name);
if (!file)
return defval;
int filesize = file->size;
if (!filesize || filesize > sizeof(u64) || (filesize & (filesize-1)))
// Doesn't look like a valid integer.
return defval;
u64 val = 0;
int ret = file->copy(file, &val, sizeof(val));
if (ret < 0)
return defval;
return val;
}