Xonotic
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 
8 void RegisterCvars(void(string name, string def, string desc, bool archive, string file) f) {}
9 
11 bool 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 
24 string 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 
48 bool 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 
103 ERASEABLE
104 void 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 
112 ERASEABLE
113 void 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 
120 {
122  RegisterCvars_Save_fd = fopen(sprintf("default%s.cfg", PROGNAME), FILE_WRITE);
123  if (RegisterCvars_Save_fd >= 0)
124  {
126  fclose(RegisterCvars_Save_fd);
127  }
128 }
129 
130 const noref bool default_bool = false;
131 const noref int default_int = 0;
132 const noref float default_float = 0;
133 const noref string default_string = "";
134 const 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__)
ERASEABLE void RegisterCvars(void(string name, string def, string desc, bool archive, string file) f)
Definition: cvar.qh:8
#define str2chr
Definition: dpextensions.qh:45
STATIC_INIT_LATE(Cvars)
Definition: cvar.qh:119
ERASEABLE void RegisterCvars_Save(string name, string def, string desc, bool archive, string file)
Definition: cvar.qh:113
int RegisterCvars_Save_fd
Definition: cvar.qh:111
ERASEABLE string MakeConsoleSafe(string input)
escape the string to make it safe for consoles
Definition: cvar.qh:24
#define ERASEABLE
Definition: _all.inc:35
#define BINOP(op, len, expr)
const noref string default_string
Definition: cvar.qh:133
ERASEABLE void RegisterCvars_Set(string name, string def, string desc, bool archive, string file)
Definition: cvar.qh:104
const noref int default_int
Definition: cvar.qh:131
const noref bool default_bool
Definition: cvar.qh:130
#define strstrofs
Definition: dpextensions.qh:42
vector(float skel, float bonenum) _skel_get_boneabs_hidden
const noref vector default_vector
Definition: cvar.qh:134
#define tokenize_console
Definition: dpextensions.qh:24
const float FILE_WRITE
Definition: csprogsdefs.qc:233
ERASEABLE bool cvar_value_issafe(string s)
Definition: cvar.qh:11
vector v
Definition: ent_cs.qc:116
const noref float default_float
Definition: cvar.qh:132
ERASEABLE bool expr_evaluate(string s)
Evaluate an expression of the form: [+ | -]? [var[op]val | [op]var | val | var] ...
Definition: cvar.qh:48
#define X(expr)