Mercurial > repos > blastem
annotate config.c @ 550:96489fb27dbf
Apart from the Z80 core, BlastEm now supports 32-bit x86
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 19 Feb 2014 00:22:27 -0800 |
parents | 6fc71114d145 |
children | 80a67be1770b |
rev | line source |
---|---|
467
140af5509ce7
Added copyright notice to source files and added GPL license text in COPYING
Mike Pavone <pavone@retrodev.com>
parents:
431
diff
changeset
|
1 /* |
140af5509ce7
Added copyright notice to source files and added GPL license text in COPYING
Mike Pavone <pavone@retrodev.com>
parents:
431
diff
changeset
|
2 Copyright 2013 Michael Pavone |
495
39cad98d2789
Allow OpenGL support to be disabled at compile time. Move generic utility functions out of config.c
Mike Pavone <pavone@retrodev.com>
parents:
467
diff
changeset
|
3 This file is part of BlastEm. |
467
140af5509ce7
Added copyright notice to source files and added GPL license text in COPYING
Mike Pavone <pavone@retrodev.com>
parents:
431
diff
changeset
|
4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. |
140af5509ce7
Added copyright notice to source files and added GPL license text in COPYING
Mike Pavone <pavone@retrodev.com>
parents:
431
diff
changeset
|
5 */ |
430
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
6 #include "tern.h" |
495
39cad98d2789
Allow OpenGL support to be disabled at compile time. Move generic utility functions out of config.c
Mike Pavone <pavone@retrodev.com>
parents:
467
diff
changeset
|
7 #include "util.h" |
430
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
8 #include <stdio.h> |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
9 #include <stdlib.h> |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
10 #include <string.h> |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
11 |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
12 #define MAX_NEST 30 //way more than I'll ever need |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
13 |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
14 tern_node * parse_config(char * config_data) |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
15 { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
16 char *state, *curline; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
17 char *prefix = NULL; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
18 int nest_level = 0; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
19 char * prefix_parts[MAX_NEST]; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
20 int line = 1; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
21 tern_node * head = NULL; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
22 while ((curline = strtok_r(config_data, "\n", &state))) |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
23 { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
24 config_data = NULL; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
25 curline = strip_ws(curline); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
26 int len = strlen(curline); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
27 if (!len) { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
28 continue; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
29 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
30 if (curline[0] == '#') { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
31 continue; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
32 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
33 if (curline[0] == '}') { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
34 if (!nest_level) { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
35 fprintf(stderr, "unexpected } on line %d\n", line); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
36 exit(1); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
37 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
38 if (prefix) { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
39 free(prefix); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
40 prefix = NULL; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
41 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
42 nest_level--; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
43 curline = strip_ws(curline+1); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
44 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
45 char * end = curline + len - 1; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
46 if (*end == '{') { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
47 *end = 0; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
48 curline = strip_ws(curline); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
49 prefix_parts[nest_level++] = curline; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
50 if (prefix) { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
51 free(prefix); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
52 prefix = NULL; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
53 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
54 } else { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
55 if (nest_level && !prefix) { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
56 prefix = alloc_concat_m(nest_level, prefix_parts); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
57 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
58 char * val = strip_ws(split_keyval(curline)); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
59 char * key = curline; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
60 if (*key) { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
61 if (prefix) { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
62 key = alloc_concat(prefix, key); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
63 } |
431
440efd7d27a9
Read key bindings from config file
Mike Pavone <pavone@retrodev.com>
parents:
430
diff
changeset
|
64 head = tern_insert_ptr(head, key, strdup(val)); |
430
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
65 if (prefix) { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
66 free(key); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
67 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
68 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
69 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
70 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
71 if (prefix) { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
72 free(prefix); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
73 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
74 return head; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
75 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
76 |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
77 tern_node * parse_config_file(char * config_path) |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
78 { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
79 tern_node * ret = NULL; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
80 FILE * config_file = fopen(config_path, "r"); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
81 if (!config_file) { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
82 goto open_fail; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
83 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
84 long config_size = file_size(config_file); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
85 if (!config_size) { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
86 goto config_empty; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
87 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
88 char * config_data = malloc(config_size); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
89 if (fread(config_data, 1, config_size, config_file) != config_size) { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
90 goto config_read_fail; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
91 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
92 ret = parse_config(config_data); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
93 config_read_fail: |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
94 free(config_data); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
95 config_empty: |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
96 fclose(config_file); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
97 open_fail: |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
98 return ret; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
99 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
100 |
496
6fc71114d145
Extract function to determine executable directory from load_config so it can be used elsewhere
Mike Pavone <pavone@retrodev.com>
parents:
495
diff
changeset
|
101 tern_node * load_config() |
430
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
102 { |
496
6fc71114d145
Extract function to determine executable directory from load_config so it can be used elsewhere
Mike Pavone <pavone@retrodev.com>
parents:
495
diff
changeset
|
103 char * exe_dir; |
430
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
104 char * home = getenv("HOME"); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
105 if (!home) { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
106 goto load_in_app_dir; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
107 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
108 char * path = alloc_concat(home, "/.config/blastem/blastem.cfg"); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
109 tern_node * ret = parse_config_file(path); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
110 if (ret) { |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
111 goto success; |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
112 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
113 free(path); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
114 load_in_app_dir: |
496
6fc71114d145
Extract function to determine executable directory from load_config so it can be used elsewhere
Mike Pavone <pavone@retrodev.com>
parents:
495
diff
changeset
|
115 exe_dir = get_exe_dir(); |
6fc71114d145
Extract function to determine executable directory from load_config so it can be used elsewhere
Mike Pavone <pavone@retrodev.com>
parents:
495
diff
changeset
|
116 if (!exe_dir) { |
6fc71114d145
Extract function to determine executable directory from load_config so it can be used elsewhere
Mike Pavone <pavone@retrodev.com>
parents:
495
diff
changeset
|
117 goto no_config; |
430
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
118 } |
496
6fc71114d145
Extract function to determine executable directory from load_config so it can be used elsewhere
Mike Pavone <pavone@retrodev.com>
parents:
495
diff
changeset
|
119 path = alloc_concat(exe_dir, "/default.cfg"); |
430
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
120 ret = parse_config_file(path); |
496
6fc71114d145
Extract function to determine executable directory from load_config so it can be used elsewhere
Mike Pavone <pavone@retrodev.com>
parents:
495
diff
changeset
|
121 free(path); |
430
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
122 success: |
496
6fc71114d145
Extract function to determine executable directory from load_config so it can be used elsewhere
Mike Pavone <pavone@retrodev.com>
parents:
495
diff
changeset
|
123 if (ret) { |
6fc71114d145
Extract function to determine executable directory from load_config so it can be used elsewhere
Mike Pavone <pavone@retrodev.com>
parents:
495
diff
changeset
|
124 return ret; |
430
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
125 } |
496
6fc71114d145
Extract function to determine executable directory from load_config so it can be used elsewhere
Mike Pavone <pavone@retrodev.com>
parents:
495
diff
changeset
|
126 no_config: |
430
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
127 fputs("Failed to find a config file in ~/.config/blastem/blastem.cfg or in the blastem executable directory\n", stderr); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
128 exit(1); |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
129 } |
7f84090ab1cd
Add config file parser and default config file
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
130 |