main.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. #include "sti/sti.h"
  2. #include <stdio.h>
  3. #include <errno.h>
  4. #include <sys/stat.h>
  5. #include <unistd.h>
  6. #include <fcntl.h>
  7. #define MAX(a,b) ((a) > (b) ? (a) : (b))
  8. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  9. #define h(...) dprintf(ofh, __VA_ARGS__);
  10. #define d(...) dprintf(ofd, __VA_ARGS__);
  11. #define OPTION_TYPE_LIST \
  12. X(invalid, NULL, 0) \
  13. X(float, float, sizeof(float) ) \
  14. X(vec2, vec2, (sizeof(float)*2) ) \
  15. X(Color4, Color4, sizeof(char*) ) \
  16. X(string, char*, sizeof(char*) ) \
  17. X(bool, bool, sizeof(char) ) \
  18. X(int, int, sizeof(int) ) \
  19. enum {
  20. #define X(a, ...) OT_##a,
  21. OPTION_TYPE_LIST
  22. #undef X
  23. OT_MAX_VALUE,
  24. };
  25. const char* OT_name_list[] = {
  26. #define X(a, b, ...) [OT_##a] = #a,
  27. OPTION_TYPE_LIST
  28. #undef X
  29. };
  30. const char* OT_type_list[] = {
  31. #define X(a, b, ...) [OT_##a] = #b,
  32. OPTION_TYPE_LIST
  33. #undef X
  34. };
  35. const int OT_size_list[] = {
  36. #define X(a, b, c, ...) [OT_##a] = c,
  37. OPTION_TYPE_LIST
  38. #undef X
  39. };
  40. typedef struct Option {
  41. int type;
  42. char* name;
  43. char rescale;
  44. int value_cnt;
  45. void* values;
  46. } Option;
  47. typedef struct {
  48. char* name;
  49. int max_values;
  50. VEC(Option*) members;
  51. } OptsStruct;
  52. static int extract_type(sexp* x) {
  53. char* name = sexp_str(x, 0);
  54. for(int i = 0; i < OT_MAX_VALUE; i++) {
  55. if(!strcmp(OT_type_list[i], name)) {
  56. return i;
  57. }
  58. }
  59. return OT_invalid;
  60. }
  61. static char* extract_name(sexp* x) {
  62. return sexp_str(x, 1);
  63. }
  64. static void copy_invalid(sexp* x, void* dst) {}
  65. static void copy_float(sexp* x, void* dst) {
  66. float* f = (float*)dst;
  67. f[0] = sexp_float(x, 0);
  68. }
  69. static void copy_vec2(sexp* x, void* dst) {
  70. float* f = (float*)dst;
  71. f[0] = sexp_float(x, 0);
  72. f[1] = sexp_float(x, 1);
  73. }
  74. static void copy_Color4(sexp* x, void* dst) {
  75. *(char**)dst = x->str;
  76. /*
  77. float* f = (float*)dst;
  78. f[0] = sexp_float(x, 0);
  79. f[1] = sexp_float(x, 1);
  80. f[2] = sexp_float(x, 2);
  81. f[3] = sexp_float(x, 3);*/
  82. }
  83. static void copy_string(sexp* x, void* dst) {
  84. *(char**)dst = x->str;
  85. }
  86. static void copy_bool(sexp* x, void* dst) {
  87. *(char*)dst = !!sexp_uint(x, 0);
  88. }
  89. static void copy_int(sexp* x, void* dst) {
  90. *(int*)dst = sexp_int(x, 0);
  91. }
  92. static void si_invalid(void* src, int ofd) {
  93. d("lol, fix your shit\n");
  94. }
  95. static void si_float(void* src, int ofd) {
  96. float* f = (float*)src;
  97. d("%f", *f)
  98. }
  99. static void si_vec2(void* src, int ofd) {
  100. float* f = (float*)src;
  101. d("((vec2){%f, %f})", f[0], f[1])
  102. }
  103. static void si_Color4(void* src, int ofd) {
  104. d("C4H(%s)", *(char**)src)
  105. }
  106. static void si_string(void* src, int ofd) {
  107. d("strdup(\"%s\")", *(char**)src)
  108. }
  109. static void si_bool(void* src, int ofd) {
  110. char* b = (char*)src;
  111. d("%d", !!*b)
  112. }
  113. static void si_int(void* src, int ofd) {
  114. int* b = (int*)src;
  115. d("%d", *b)
  116. }
  117. static void copyfn_invalid(char* srcptr, char* srcprop, int ofd) {
  118. d("lol, fix your shit\n");
  119. }
  120. static void copyfn_float(char* srcptr, char* srcprop, int ofd) {
  121. d("%s->%s", srcptr, srcprop);
  122. }
  123. static void copyfn_vec2(char* srcptr, char* srcprop, int ofd) {
  124. d("%s->%s", srcptr, srcprop);
  125. }
  126. static void copyfn_Color4(char* srcptr, char* srcprop, int ofd) {
  127. d("%s->%s", srcptr, srcprop);
  128. }
  129. static void copyfn_string(char* srcptr, char* srcprop, int ofd) {
  130. d("strdup(%s->%s)", srcptr, srcprop);
  131. }
  132. static void copyfn_bool(char* srcptr, char* srcprop, int ofd) {
  133. d("%s->%s", srcptr, srcprop);
  134. }
  135. static void copyfn_int(char* srcptr, char* srcprop, int ofd) {
  136. d("%s->%s", srcptr, srcprop);
  137. }
  138. // these functions need to output complete lines, including leading tabs and trailing newlines
  139. static void freefn_invalid(char* ptr, char* prop, int ofd) {
  140. d("lol, fix your shit\n");
  141. }
  142. static void freefn_float(char* ptr, char* prop, int ofd) {}
  143. static void freefn_vec2(char* ptr, char* prop, int ofd) {}
  144. static void freefn_Color4(char* ptr, char* prop, int ofd) {}
  145. static void freefn_bool(char* ptr, char* prop, int ofd) {}
  146. static void freefn_int(char* ptr, char* prop, int ofd) {}
  147. static void freefn_string(char* ptr, char* prop, int ofd) {
  148. d("\tfree(%s->%s);\n", ptr, prop);
  149. }
  150. static void rescalefn_invalid(char* raw, char* prop, char* scale, char* out, int ofd) {
  151. d("lol, fix your shit\n");
  152. }
  153. static void rescalefn_float(char* raw, char* prop, char* scale, char* out, int ofd) {
  154. d("\t%s->%s = %s->%s * %s;\n", out, prop, raw, prop, scale);
  155. }
  156. static void rescalefn_vec2(char* raw, char* prop, char* scale, char* out, int ofd) {
  157. d("\t%s->%s.x = %s->%s.x * %s;\n", out, prop, raw, prop, scale);
  158. d("\t%s->%s.y = %s->%s.y * %s;\n", out, prop, raw, prop, scale);
  159. }
  160. static void rescalefn_Color4(char* raw, char* prop, char* scale, char* out, int ofd) {}
  161. static void rescalefn_bool(char* raw, char* prop, char* scale, char* out, int ofd) {}
  162. static void rescalefn_int(char* raw, char* prop, char* scale, char* out, int ofd) {}
  163. static void rescalefn_string(char* raw, char* prop, char* scale, char* out, int ofd) {}
  164. OptsStruct* parse_optstruct(sexp* xos) {
  165. OptsStruct* os = calloc(1, sizeof(*os));
  166. os->name = VEC_ITEM(&xos->args, 0)->str;
  167. os->max_values = 0;
  168. for(int oi = 1; oi < VEC_LEN(&xos->args); oi++) {
  169. sexp* xo = VEC_ITEM(&xos->args, oi);
  170. Option* o = calloc(1, sizeof(*o));
  171. VEC_PUSH(&os->members, o);
  172. o->type = extract_type(xo);
  173. o->name = extract_name(xo);
  174. o->rescale = xo->brace == '<';
  175. o->value_cnt = VEC_LEN(&xo->args) - 2;
  176. os->max_values = MAX(os->max_values, o->value_cnt);
  177. o->values = calloc(1, OT_size_list[o->type] * o->value_cnt);
  178. for(int a = 0; a < o->value_cnt; a++) {
  179. sexp* xa = VEC_ITEM(&xo->args, a + 2);
  180. switch(o->type) {
  181. #define X(n, t, sz, ...) case OT_##n: copy_##n(xa, o->values + a * sz); break;
  182. OPTION_TYPE_LIST
  183. #undef X
  184. }
  185. }
  186. }
  187. return os;
  188. }
  189. int main(int argc, char* argv[]) {
  190. if(argc < 4) {
  191. fprintf(stderr, "Usage: %s <cfg.sex> <output_header.h> <output_source.c>\n", argv[0]);
  192. return 2;
  193. }
  194. sexp* root = sexp_parse_file(argv[1]);
  195. // sexp_print(1, root);
  196. VEC(OptsStruct*) structs;
  197. VEC_INIT(&structs);
  198. VEC_EACH(&root->args, i, a) {
  199. VEC_PUSH(&structs, parse_optstruct(a));
  200. }
  201. unlink(argv[3]);
  202. unlink(argv[2]);
  203. int ofd = open(argv[3], O_WRONLY | O_CREAT | O_EXCL, 0644);
  204. if(ofd == -1) {
  205. fprintf(stderr, "Could not create file '%s': %s\n", argv[3], strerror(errno));
  206. return 1;
  207. }
  208. int ofh = open(argv[2], O_WRONLY | O_CREAT | O_EXCL, 0644);
  209. if(ofh == -1) {
  210. fprintf(stderr, "Could not create file '%s': %s\n", argv[2], strerror(errno));
  211. return 1;
  212. }
  213. h("#ifndef __gputk__opts_structs_h__\n#define __gputk__opts_structs_h__\n")
  214. h("\n\n")
  215. h("/***********************************************\n")
  216. h("/ THIS FILE IS AUTOGENERATED. DO NOT EDIT. /\n")
  217. h("/ see '%s' for details\n", argv[1]);
  218. h("***********************************************/\n")
  219. h("\n\n")
  220. h("#define GUI_CONTROL_OPTS_STRUCT_LIST \\\n");
  221. VEC_EACH(&structs, i, st) {
  222. h("\tX(GUI%sOpts, %s) \\\n", st->name, st->name)
  223. }
  224. h("\n\n");
  225. VEC_EACH(&structs, i, st) {
  226. h("typedef struct GUI%sOpts {\n", st->name);
  227. VEC_EACH(&st->members, mi, m) {
  228. h("\t%s %s;\n", OT_type_list[m->type], m->name);
  229. }
  230. h("} GUI%sOpts;\n\n", st->name);
  231. }
  232. h("\n\n")
  233. VEC_EACH(&structs, i, st) {
  234. h("int GUI%sOpts_LoadDefaults(GUI%sOpts* o, int version);\n", st->name, st->name);
  235. h("int GUI%sOpts_LoadScaledDefaults(GUI%sOpts* o, int maxVersion, float scale);\n", st->name, st->name);
  236. h("void GUI%sOpts_Copy(GUI%sOpts* dst, GUI%sOpts* src);\n", st->name, st->name, st->name);
  237. h("void GUI%sOpts_Free(GUI%sOpts* o);\n", st->name, st->name);
  238. h("void GUI%sOpts_UIRescale(GUI%sOpts* raw, float scale, GUI%sOpts* out);\n", st->name, st->name, st->name);
  239. h("\n")
  240. }
  241. d("\n\n")
  242. d("/***********************************************\n")
  243. d("/ THIS FILE IS AUTOGENERATED. DO NOT EDIT. /\n")
  244. d("/ see '%s' for details\n", argv[1]);
  245. d("***********************************************/\n")
  246. d("\n\n")
  247. d("#include <stdlib.h>\n")
  248. d("\n\n")
  249. d("#include \"opts_structs.h\"\n")
  250. d("\n\n")
  251. VEC_EACH(&structs, i, st) {
  252. d("int GUI%sOpts_LoadDefaults(GUI%sOpts* o, int version) {\n", st->name, st->name);
  253. d("\n\tif(version < 0) return %d;\n\n", st->max_values);
  254. d("\tversion = version > %d ? %d : version;\n", st->max_values - 1, st->max_values - 1);
  255. d("\tswitch(version) {\n")
  256. for(int v = 0; v < st->max_values; v++) {
  257. d("\t\tcase %d:\n", v);
  258. VEC_EACH(&st->members, mi, m) {
  259. d("\t\t\to->%s = ", m->name);
  260. int mv = MIN(v, m->value_cnt - 1);
  261. switch(m->type) {
  262. #define X(n, t, sz, ...) case OT_##n: si_##n(m->values + sz * mv, ofd); break;
  263. OPTION_TYPE_LIST
  264. #undef X
  265. }
  266. d(";\n")
  267. }
  268. d("\t\t\tbreak;\n")
  269. }
  270. d("\t};\n");
  271. d("\treturn 0;\n};\n");
  272. }
  273. VEC_EACH(&structs, i, st) {
  274. d("int GUI%sOpts_LoadScaledDefaults(GUI%sOpts o[], int maxVersion, float scale) {\n", st->name, st->name);
  275. d("\tfor(int v = 0; v < maxVersion; v++) {\n")
  276. d("\t\tGUI%sOpts tmp;\n", st->name);
  277. d("\t\tGUI%sOpts_LoadDefaults(&tmp, v);\n", st->name);
  278. d("\t\tGUI%sOpts_UIRescale(&tmp, scale, &o[v]);\n", st->name);
  279. d("\t};\n");
  280. d("\treturn 0;\n};\n");
  281. }
  282. VEC_EACH(&structs, i, st) {
  283. d("void GUI%sOpts_Copy(GUI%sOpts* dst, GUI%sOpts* src) {\n", st->name, st->name, st->name);
  284. VEC_EACH(&st->members, mi, m) {
  285. d("\tdst->%s = ", m->name);
  286. switch(m->type) {
  287. #define X(n, t, sz, ...) case OT_##n: copyfn_##n("src", m->name, ofd); break;
  288. OPTION_TYPE_LIST
  289. #undef X
  290. }
  291. d(";\n")
  292. }
  293. d("};\n");
  294. }
  295. VEC_EACH(&structs, i, st) {
  296. d("void GUI%sOpts_Free(GUI%sOpts* o) {\n", st->name, st->name);
  297. VEC_EACH(&st->members, mi, m) {
  298. switch(m->type) {
  299. #define X(n, t, sz, ...) case OT_##n: freefn_##n("o", m->name, ofd); break;
  300. OPTION_TYPE_LIST
  301. #undef X
  302. }
  303. }
  304. d("};\n");
  305. }
  306. VEC_EACH(&structs, i, st) {
  307. d("void GUI%sOpts_UIRescale(GUI%sOpts* raw, float scale, GUI%sOpts* out) {\n", st->name, st->name, st->name);
  308. VEC_EACH(&st->members, mi, m) {
  309. if(!m->rescale) continue;
  310. switch(m->type) {
  311. #define X(n, t, sz, ...) case OT_##n: rescalefn_##n("raw", m->name, "scale", "out", ofd); break;
  312. OPTION_TYPE_LIST
  313. #undef X
  314. }
  315. }
  316. d("};\n");
  317. }
  318. h("\n\n\n")
  319. h("#endif // __gputk__opts_structs_h__")
  320. return 0;
  321. }