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 ret = true;
55 s = substring(s, 1, -1);
56 }
57 bool expr_fail = false;
58 for (int i = 0, n = tokenize_console(s); i < n; ++i) {
59 int o;
60 string k, v;
61 s = argv(i);
62 #define X(expr) \
63 if (expr) \
64 continue; \
65 expr_fail = true; \
66 break;
67
68 #define BINOP(op, len, expr) \
69 if ((o = strstrofs(s, op, 0)) >= 0) { \
70 k = substring(s, 0, o); \
71 v = substring(s, o + len, -1); \
72 X(expr); \
73 }
74 BINOP(">=", 2, cvar(k) >= stof(v));
75 BINOP("<=", 2, cvar(k) <= stof(v));
76 BINOP(">", 1, cvar(k) > stof(v));
77 BINOP("<", 1, cvar(k) < stof(v));
78 BINOP("==", 2, cvar(k) == stof(v));
79 BINOP("!=", 2, cvar(k) != stof(v));
80 BINOP("===", 3, cvar_string(k) == v);
81 BINOP("!==", 3, cvar_string(k) != v);
82 {
83 k = s;
84 bool b = true;
85 if (str2chr(k, 0) == '!') {
86 k = substring(s, 1, -1);
87 b = false;
88 }
89 float f = stof(k);
90 bool isnum = ftos(f) == k;
91 X(boolean(isnum ? f : cvar(k)) == b);
92 }
93 #undef BINOP
94 #undef X
95 }
96 if (!expr_fail) {
97 ret = !ret;
98 }
99 // now ret is true if we want to keep the item, and false if we want to get rid of it
100 return ret;
101}
102
104void RegisterCvars_Set(string name, string def, string desc, bool archive, string file)
105{
106 localcmd(sprintf("\nset %1$s \"$%1$s\" \"%2$s\"\n", name, MakeConsoleSafe(desc)));
107 if (archive)
108 localcmd(sprintf("\nseta %1$s \"$%1$s\"\n", name));
109}
110
113void RegisterCvars_Save(string name, string def, string desc, bool archive, string file)
114{
115 if (!archive) return;
116 fputs(RegisterCvars_Save_fd, sprintf("seta %s \"%s\"\n", name, def));
117}
118
129
130const noref bool default_bool = false;
131const noref int default_int = 0;
132const noref float default_float = 0;
133const noref string default_string = "";
134const noref vector default_vector = '0 0 0';
135
136#define repr_cvar_bool(x) ((x) ? "1" : "0")
137#define repr_cvar_int(x) (ftos(x))
138#define repr_cvar_float(x) (ftos(x))
139#define repr_cvar_string(x) (x)
140#define repr_cvar_vector(x) (sprintf("%v", x))
141
142//pseudo prototypes:
143// void AUTOCVAR(<cvar_name>, <qc_var_type>, default_cvar_value, string desc)
144// void AUTOCVAR_SAVE(<cvar_name>, <qc_var_type>, default_cvar_value, string desc)
145// where default_cvar_value has type <qc_var_type>
146// e.g.: AUTOCVAR(mycvar, float, 2.5, "cvar description")
147
148#define __AUTOCVAR(file, archive, var, type, desc, default) \
149 ACCUMULATE void RegisterCvars(void(string, string, string, bool, string) f) \
150 { \
151 f( #var, repr_cvar_##type(default), desc, archive, file); \
152 } \
153 type autocvar_##var = default
154#define AUTOCVAR_5(file, archive, var, type, desc) \
155 __AUTOCVAR(file, archive, var, type, desc, default_##type)
156#define AUTOCVAR_6(file, archive, var, type, default, desc) \
157 __AUTOCVAR(file, archive, var, type, desc, default)
158#define _AUTOCVAR(...) EVAL__AUTOCVAR(OVERLOAD(AUTOCVAR, __FILE__, __VA_ARGS__))
159#define EVAL__AUTOCVAR(...) __VA_ARGS__
160#define AUTOCVAR_SAVE(...) _AUTOCVAR(true, __VA_ARGS__)
161#define AUTOCVAR(...) _AUTOCVAR(false, __VA_ARGS__)
const float FILE_WRITE
const noref string default_string
Definition cvar.qh:133
ERASEABLE void RegisterCvars_Save(string name, string def, string desc, bool archive, string file)
Definition cvar.qh:113
#define BINOP(op, len, expr)
const noref vector default_vector
Definition cvar.qh:134
const noref int default_int
Definition cvar.qh:131
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:104
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:111
const noref float default_float
Definition cvar.qh:132
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:130
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:92
#define STATIC_INIT_LATE(func)
directly after STATIC_INIT
Definition static.qh:37