Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
cvar.qh
Go to the documentation of this file.
1#pragma once
2
3#include "nil.qh"
4#include "progname.qh"
5#include "static.qh"
6
8void RegisterCvars(void(string name, string def, string desc, bool archive, string file) f) {}
9
11bool cvar_value_issafe(string s)
12{
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, "$", 0) >= 0) return false;
17 if (strstrofs(s, "\r", 0) >= 0) return false;
18 if (strstrofs(s, "\n", 0) >= 0) return false;
19 return true;
20}
21
24string MakeConsoleSafe(string input)
25{
26 input = strreplace("\n", "", input);
27 input = strreplace("\\", "\\\\", input);
28 input = strreplace("$", "$$", input);
29 input = strreplace("\"", "\\\"", input);
30 return input;
31}
32
48bool expr_evaluate(string s)
49{
50 bool ret = false;
51 if (str2chr(s, 0) == '+')
52 s = substring(s, 1, -1);
53 else if (str2chr(s, 0) == '-')
54 {
55 ret = true;
56 s = substring(s, 1, -1);
57 }
58 bool expr_fail = false;
59 for (int i = 0, n = tokenize_console(s); i < n; ++i)
60 {
61 int o;
62 string k, v;
63 s = argv(i);
64 #define X(expr) \
65 if (expr) \
66 continue; \
67 expr_fail = true; \
68 break
69
70 #define BINOP(op, len, expr) \
71 if ((o = strstrofs(s, op, 0)) >= 0) \
72 { \
73 k = substring(s, 0, o); \
74 v = substring(s, o + len, -1); \
75 X(expr); \
76 }
77 BINOP(">=", 2, cvar(k) >= stof(v))
78 BINOP("<=", 2, cvar(k) <= stof(v))
79 BINOP(">", 1, cvar(k) > stof(v))
80 BINOP("<", 1, cvar(k) < stof(v))
81 BINOP("==", 2, cvar(k) == stof(v))
82 BINOP("!=", 2, cvar(k) != stof(v))
83 BINOP("===", 3, cvar_string(k) == v)
84 BINOP("!==", 3, cvar_string(k) != v)
85 {
86 k = s;
87 bool b = true;
88 if (str2chr(k, 0) == '!')
89 {
90 k = substring(s, 1, -1);
91 b = false;
92 }
93 float f = stof(k);
94 X(boolean((ftos(f) == k) ? f : cvar(k)) == b);
95 }
96 #undef BINOP
97 #undef X
98 }
99 if (!expr_fail)
100 ret = !ret;
101 // now ret is true if we want to keep the item, and false if we want to get rid of it
102 return ret;
103}
104
106void RegisterCvars_Set(string name, string def, string desc, bool archive, string file)
107{
108 localcmd(sprintf("\nset %1$s \"$%1$s\" \"%2$s\"\n", name, MakeConsoleSafe(desc)));
109 if (archive)
110 localcmd(sprintf("\nseta %1$s \"$%1$s\"\n", name));
111}
112
115void RegisterCvars_Save(string name, string def, string desc, bool archive, string file)
116{
117 if (!archive)
118 return;
119 fputs(RegisterCvars_Save_fd, sprintf("seta %s \"%s\"\n", name, def));
120}
121
132
133const noref bool default_bool = false;
134const noref int default_int = 0;
135const noref float default_float = 0;
136const noref string default_string = "";
137const noref vector default_vector = '0 0 0';
138
139#define repr_cvar_bool(x) ((x) ? "1" : "0")
140#define repr_cvar_int(x) (itos(x))
141#define repr_cvar_float(x) (ftos(x))
142#define repr_cvar_string(x) (x)
143#define repr_cvar_vector(x) (sprintf("%v", x))
144
145//pseudo prototypes:
146// void AUTOCVAR(<cvar_name>, <qc_var_type>, default_cvar_value, string desc)
147// void AUTOCVAR_SAVE(<cvar_name>, <qc_var_type>, default_cvar_value, string desc)
148// where default_cvar_value has type <qc_var_type>
149// e.g.: AUTOCVAR(mycvar, float, 2.5, "cvar description")
150
151#define __AUTOCVAR(file, archive, var, type, desc, default) \
152 ACCUMULATE void RegisterCvars(void(string, string, string, bool, string) f) \
153 { \
154 f( #var, repr_cvar_##type(default), desc, archive, file); \
155 } \
156 type autocvar_##var = default
157#define AUTOCVAR_5(file, archive, var, type, desc) \
158 __AUTOCVAR(file, archive, var, type, desc, default_##type)
159#define AUTOCVAR_6(file, archive, var, type, default, desc) \
160 __AUTOCVAR(file, archive, var, type, desc, default)
161#define _AUTOCVAR(...) EVAL__AUTOCVAR(OVERLOAD(AUTOCVAR, __FILE__, __VA_ARGS__))
162#define EVAL__AUTOCVAR(...) __VA_ARGS__
163#define AUTOCVAR_SAVE(...) _AUTOCVAR(true, __VA_ARGS__)
164#define AUTOCVAR(...) _AUTOCVAR(false, __VA_ARGS__)
const float FILE_WRITE
const noref string default_string
Definition cvar.qh:136
ERASEABLE void RegisterCvars_Save(string name, string def, string desc, bool archive, string file)
Definition cvar.qh:115
#define BINOP(op, len, expr)
const noref vector default_vector
Definition cvar.qh:137
const noref int default_int
Definition cvar.qh:134
ERASEABLE bool expr_evaluate(string s)
Evaluate an expression of the form: [+ | -]?
Definition cvar.qh:48
ERASEABLE void RegisterCvars_Set(string name, string def, string desc, bool archive, string file)
Definition cvar.qh:106
ERASEABLE void RegisterCvars(void(string name, string def, string desc, bool archive, string file) f)
Definition cvar.qh:8
int RegisterCvars_Save_fd
Definition cvar.qh:113
const noref float default_float
Definition cvar.qh:135
ERASEABLE string MakeConsoleSafe(string input)
Escape the string to make it safe for consoles.
Definition cvar.qh:24
const noref bool default_bool
Definition cvar.qh:133
ERASEABLE bool cvar_value_issafe(string s)
Definition cvar.qh:11
#define X(expr)
#define str2chr
#define strstrofs
#define tokenize_console
#define ERASEABLE
Definition _all.inc:37
string name
Definition menu.qh:30
void localcmd(string command,...)
void fclose(float fhandle)
float stof(string val,...)
void fputs(float fhandle, string s)
string substring(string s, float start, float length)
float cvar(string name)
float fopen(string filename, float mode)
const string cvar_string(string name)
string ftos(float f)
string argv(float n)
#define PROGNAME
Definition progname.qh:4
vector
Definition self.qh:96
#define STATIC_INIT_LATE(func)
directly after STATIC_INIT
Definition static.qh:38