script, ui: added "sv_min_startmap_health" cvar
[k8vavoom.git] / source / infostr.cpp
blob50ae426c98e8eeaa05189b0f8b248e1522e0b9d3
1 //**************************************************************************
2 //**
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
9 //**
10 //** Copyright (C) 1999-2006 Jānis Legzdiņš
11 //** Copyright (C) 2018-2023 Ketmar Dark
12 //**
13 //** This program is free software: you can redistribute it and/or modify
14 //** it under the terms of the GNU General Public License as published by
15 //** the Free Software Foundation, version 3 of the License ONLY.
16 //**
17 //** This program is distributed in the hope that it will be useful,
18 //** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 //** GNU General Public License for more details.
21 //**
22 //** You should have received a copy of the GNU General Public License
23 //** along with this program. If not, see <http://www.gnu.org/licenses/>.
24 //**
25 //**************************************************************************
26 //**
27 //** INFO STRINGS
28 //**
29 //**************************************************************************
30 #include "gamedefs.h"
31 #include "infostr.h"
34 #define MAX_INFO_STRING (1000*1000)
37 //==========================================================================
39 // Info_ValueForKey
41 // Searches the string for the given key and returns the associated value,
42 // or an empty string.
44 //==========================================================================
45 VStr Info_ValueForKey (VStr s, VStr key) {
46 if (s.IsEmpty() || key.IsEmpty()) return VStr();
47 //if (s.Length() >= MAX_INFO_STRING) Host_Error("Info_ValueForKey: oversize infostring");
49 int i = 0;
50 if (s[i] == '\\') ++i;
51 for (;;) {
52 int Start = i;
53 while (s[i] != '\\') {
54 if (!s[i]) return VStr();
55 ++i;
57 VStr pkey(s, Start, i-Start);
58 ++i;
60 Start = i;
61 while (s[i] != '\\' && s[i]) ++i;
63 if (!key.ICmp(pkey)) return VStr(s, Start, i-Start);
65 if (!s[i]) return VStr();
66 ++i;
71 //==========================================================================
73 // Info_RemoveKey
75 //==========================================================================
76 void Info_RemoveKey (VStr &s, VStr key) {
77 if (s.IsEmpty()) return;
78 //if (s.Length() >= MAX_INFO_STRING) Host_Error("Info_RemoveKey: oversize infostring");
79 if (strchr(*key, '\\')) { GCon->Logf("Can't use a key with a \\ (%s)", *key.quote()); return; }
81 int i = 0;
82 for (;;) {
83 int start = i;
84 if (s[i] == '\\') ++i;
85 int KeyStart = i;
86 while (s[i] != '\\') {
87 if (!s[i]) return;
88 ++i;
90 VStr pkey(s, KeyStart, i-KeyStart);
91 ++i;
93 int ValStart = i;
94 while (s[i] != '\\' && s[i]) ++i;
95 VStr value(s, ValStart, i-ValStart);
97 if (!key.Cmp(pkey)) {
98 s = VStr(s, 0, start)+VStr(s, i, s.Length()-i); // remove this part
99 return;
102 if (!s[i]) return;
107 //==========================================================================
109 // Info_SetValueForKey
111 // Changes or adds a key/value pair
113 //==========================================================================
114 void Info_SetValueForKey (VStr &s, VStr key, VStr value) {
115 //if (s.Length() >= MAX_INFO_STRING) Host_Error("Info_SetValueForKey: oversize infostring");
117 if (strchr(*key, '\\')) { GCon->Logf("Can't use keys with a \\ (%s)", *key.quote()); return;}
118 if (strchr(*value, '\\')) { GCon->Logf("Can't use values with a \\ (%s)", *value.quote()); return; }
120 if (strchr(*key, '\"')) { GCon->Logf("Can't use keys with a \" (%s)", *key.quote()); return;}
121 if (strchr(*value, '\"')) { GCon->Logf("Can't use values with a \" (%s)", *value.quote()); return; }
123 // this next line is kinda trippy
124 VStr v = Info_ValueForKey(s, key);
125 if (v.IsNotEmpty()) {
126 // key exists, make sure we have enough room for new value, if we don't, don't change it!
127 if (value.Length()-v.Length()+s.Length() > MAX_INFO_STRING) {
128 GCon->Logf("Info string '%s' length exceeded (%s:%s)", *key.quote(), *v.quote(), *value.quote());
129 return;
133 Info_RemoveKey(s, key);
134 if (value.IsEmpty()) return;
136 VStr newi = VStr("\\")+key+"\\"+value;
137 if (newi.Length()+s.Length() > MAX_INFO_STRING) {
138 GCon->Logf("Info string '%s' length exceeded: (%s:%s)", *key.quote(), *s.quote(), *newi.quote());
139 return;
142 s += newi;