blob: 42261a624cee23741afffc3d54a2f15eb07f49e5 [file] [log] [blame]
Kevin O'Connor59d6ca52012-05-31 00:20:55 -04001// Access to pseudo "file" interface for configuration information.
2//
3// Copyright (C) 2012 Kevin O'Connor <kevin@koconnor.net>
4//
5// This file may be distributed under the terms of the GNU LGPLv3 license.
6
7#include "config.h" // CONFIG_*
Kevin O'Connor9dea5902013-09-14 20:23:54 -04008#include "malloc.h" // free
Kevin O'Connor2d2fa312013-09-14 21:55:26 -04009#include "output.h" // dprintf
Kevin O'Connor41639f82013-09-14 19:37:36 -040010#include "romfile.h" // struct romfile_s
Kevin O'Connorfa9c66a2013-09-14 19:10:40 -040011#include "string.h" // memcmp
Kevin O'Connor59d6ca52012-05-31 00:20:55 -040012
Kevin O'Connor70c94dd2013-03-08 19:39:49 -050013static struct romfile_s *RomfileRoot VARVERIFY32INIT;
Kevin O'Connor59d6ca52012-05-31 00:20:55 -040014
15void
16romfile_add(struct romfile_s *file)
17{
Kevin O'Connorc40e3fa2013-02-09 14:55:30 -050018 dprintf(3, "Add romfile: %s (size=%d)\n", file->name, file->size);
Kevin O'Connor59d6ca52012-05-31 00:20:55 -040019 file->next = RomfileRoot;
20 RomfileRoot = file;
21}
22
23// Search for the specified file.
24static struct romfile_s *
25__romfile_findprefix(const char *prefix, int prefixlen, struct romfile_s *prev)
26{
27 struct romfile_s *cur = RomfileRoot;
28 if (prev)
29 cur = prev->next;
30 while (cur) {
31 if (memcmp(prefix, cur->name, prefixlen) == 0)
32 return cur;
33 cur = cur->next;
34 }
35 return NULL;
36}
37
38struct romfile_s *
39romfile_findprefix(const char *prefix, struct romfile_s *prev)
40{
41 return __romfile_findprefix(prefix, strlen(prefix), prev);
42}
43
44struct romfile_s *
45romfile_find(const char *name)
46{
47 return __romfile_findprefix(name, strlen(name) + 1, NULL);
48}
49
50// Helper function to find, malloc_tmphigh, and copy a romfile. This
51// function adds a trailing zero to the malloc'd copy.
52void *
53romfile_loadfile(const char *name, int *psize)
54{
55 struct romfile_s *file = romfile_find(name);
56 if (!file)
57 return NULL;
58
59 int filesize = file->size;
60 if (!filesize)
61 return NULL;
62
63 char *data = malloc_tmphigh(filesize+1);
64 if (!data) {
65 warn_noalloc();
66 return NULL;
67 }
68
69 dprintf(5, "Copying romfile '%s' (len %d)\n", name, filesize);
70 int ret = file->copy(file, data, filesize);
71 if (ret < 0) {
72 free(data);
73 return NULL;
74 }
75 if (psize)
76 *psize = filesize;
77 data[filesize] = '\0';
78 return data;
79}
80
81// Attempt to load an integer from the given file - return 'defval'
Kevin O'Connor296ce222014-01-15 13:33:48 -050082// if unsuccessful.
Kevin O'Connor59d6ca52012-05-31 00:20:55 -040083u64
84romfile_loadint(const char *name, u64 defval)
85{
86 struct romfile_s *file = romfile_find(name);
87 if (!file)
88 return defval;
89
90 int filesize = file->size;
91 if (!filesize || filesize > sizeof(u64) || (filesize & (filesize-1)))
92 // Doesn't look like a valid integer.
93 return defval;
94
95 u64 val = 0;
96 int ret = file->copy(file, &val, sizeof(val));
97 if (ret < 0)
98 return defval;
99 return val;
100}