]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/lib/cvar.qh
Merge branch 'terencehill/quickmenu_file_example' into 'master'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / cvar.qh
1 #ifndef CVAR_H
2 #define CVAR_H
3
4 #include "nil.qh"
5 #include "progname.qh"
6 #include "static.qh"
7
8 void RegisterCvars(void(string name, string def, string desc, bool archive, string file) f) {}
9
10 bool cvar_value_issafe(string s)
11 {
12         if (strstrofs(s, "\"", 0) >= 0) return false;
13         if (strstrofs(s, "\\", 0) >= 0) return false;
14         if (strstrofs(s, ";", 0) >= 0) return false;
15         if (strstrofs(s, "$", 0) >= 0) return false;
16         if (strstrofs(s, "\r", 0) >= 0) return false;
17         if (strstrofs(s, "\n", 0) >= 0) return false;
18         return true;
19 }
20
21 /** escape the string to make it safe for consoles */
22 string MakeConsoleSafe(string input)
23 {
24         input = strreplace("\n", "", input);
25         input = strreplace("\\", "\\\\", input);
26         input = strreplace("$", "$$", input);
27         input = strreplace("\"", "\\\"", input);
28         return input;
29 }
30
31 void cvar_describe(string name, string desc)
32 {
33         localcmd(sprintf("\nset %1$s \"$%1$s\" \"%2$s\"\n", name, MakeConsoleSafe(desc)));
34 }
35
36 void cvar_archive(string name)
37 {
38         localcmd(sprintf("\nseta %1$s \"$%1$s\"\n", name));
39 }
40
41 void RegisterCvars_Set(string name, string def, string desc, bool archive, string file)
42 {
43         cvar_describe(name, desc);
44         if (archive) cvar_archive(name);
45 }
46
47 int RegisterCvars_Save_fd;
48 void RegisterCvars_Save(string name, string def, string desc, bool archive, string file)
49 {
50         if (!archive) return;
51         fputs(RegisterCvars_Save_fd, sprintf("seta %s \"%s\"\n", name, def));
52 }
53
54 STATIC_INIT_LATE(Cvars)
55 {
56         RegisterCvars(RegisterCvars_Set);
57         RegisterCvars_Save_fd = fopen(sprintf("default%s.cfg", PROGNAME), FILE_WRITE);
58         if (RegisterCvars_Save_fd >= 0)
59         {
60                 RegisterCvars(RegisterCvars_Save);
61                 fclose(RegisterCvars_Save_fd);
62         }
63 }
64
65 const noref bool default_bool = false;
66 const noref int default_int = 0;
67 const noref float default_float = 0;
68 const noref string default_string = "";
69 const noref vector default_vector = '0 0 0';
70
71 #define repr_cvar_bool(x) ((x) ? "1" : "0")
72 #define repr_cvar_int(x) (ftos(x))
73 #define repr_cvar_float(x) (ftos(x))
74 #define repr_cvar_string(x) (x)
75 #define repr_cvar_vector(x) (sprintf("%v", x))
76
77 #define __AUTOCVAR(file, archive, var, type, desc, default) \
78         [[accumulate]] void RegisterCvars(void(string, string, string, bool, string) f) \
79         { \
80                 f( #var, repr_cvar_##type(default), desc, archive, file); \
81         } \
82         type autocvar_##var = default
83 #define AUTOCVAR_5(file, archive, var, type, desc) \
84         __AUTOCVAR(file, archive, var, type, desc, default_##type)
85 #define AUTOCVAR_6(file, archive, var, type, default, desc) \
86         __AUTOCVAR(file, archive, var, type, desc, default)
87 #define _AUTOCVAR(...) EVAL(OVERLOAD(AUTOCVAR, __FILE__, __VA_ARGS__))
88 #define AUTOCVAR_SAVE(...) _AUTOCVAR(true, __VA_ARGS__)
89 #define AUTOCVAR(...) _AUTOCVAR(false, __VA_ARGS__)
90
91 #endif