]> git.xonotic.org Git - xonotic/darkplaces.git/blob - com_infostring.c
Fix an IO exception on exit when using -condebug because FS_Close was trying to log...
[xonotic/darkplaces.git] / com_infostring.c
1 /*
2 Copyright (C) 2006-2021 DarkPlaces contributors
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 */
20
21 #include "darkplaces.h"
22
23 char *InfoString_GetValue(const char *buffer, const char *key, char *value, size_t valuelength)
24 {
25         int pos = 0, j;
26         size_t keylength;
27         if (!key)
28                 key = "";
29         keylength = strlen(key);
30         if (valuelength < 1 || !value)
31         {
32                 Con_Printf("InfoString_GetValue: no room in value\n");
33                 return NULL;
34         }
35         value[0] = 0;
36         if (strchr(key, '\\'))
37         {
38                 Con_Printf("InfoString_GetValue: key name \"%s\" contains \\ which is not possible in an infostring\n", key);
39                 return NULL;
40         }
41         if (strchr(key, '\"'))
42         {
43                 Con_Printf("InfoString_SetValue: key name \"%s\" contains \" which is not allowed in an infostring\n", key);
44                 return NULL;
45         }
46         if (!key[0])
47         {
48                 Con_Printf("InfoString_GetValue: can not look up a key with no name\n");
49                 return NULL;
50         }
51         while (buffer[pos] == '\\')
52         {
53                 if (!memcmp(buffer + pos+1, key, keylength) &&
54                                 (buffer[pos+1 + keylength] == 0 ||
55                                  buffer[pos+1 + keylength] == '\\'))
56                 {
57                         pos += 1 + (int)keylength;           // Skip \key
58                         if (buffer[pos] == '\\') pos++; // Skip \ before value.
59                         for (j = 0;buffer[pos+j] && buffer[pos+j] != '\\' && j < (int)valuelength - 1;j++)
60                                 value[j] = buffer[pos+j];
61                         value[j] = 0;
62                         return value;
63                 }
64                 if (buffer[pos] == '\\') pos++; // Skip \ before value.
65                 for (pos++;buffer[pos] && buffer[pos] != '\\';pos++);
66                 if (buffer[pos] == '\\') pos++; // Skip \ before value.
67                 for (pos++;buffer[pos] && buffer[pos] != '\\';pos++);
68         }
69         // if we reach this point the key was not found
70         return NULL;
71 }
72
73 void InfoString_SetValue(char *buffer, size_t bufferlength, const char *key, const char *value)
74 {
75         int pos = 0, pos2;
76         size_t keylength;
77         if (!key)
78                 key = "";
79         if (!value)
80                 value = "";
81         keylength = strlen(key);
82         if (strchr(key, '\\') || strchr(value, '\\'))
83         {
84                 Con_Printf("InfoString_SetValue: \"%s\" \"%s\" contains \\ which is not possible to store in an infostring\n", key, value);
85                 return;
86         }
87         if (strchr(key, '\"') || strchr(value, '\"'))
88         {
89                 Con_Printf("InfoString_SetValue: \"%s\" \"%s\" contains \" which is not allowed in an infostring\n", key, value);
90                 return;
91         }
92         if (!key[0])
93         {
94                 Con_Printf("InfoString_SetValue: can not set a key with no name\n");
95                 return;
96         }
97         while (buffer[pos] == '\\')
98         {
99                 if (!memcmp(buffer + pos+1, key, keylength) &&
100                                 (buffer[pos+1 + keylength] == 0 ||
101                                  buffer[pos+1 + keylength] == '\\'))
102                         break;
103                 if (buffer[pos] == '\\') pos++; // Skip \ before value.
104                 for (;buffer[pos] && buffer[pos] != '\\';pos++);
105                 if (buffer[pos] == '\\') pos++; // Skip \ before value.
106                 for (;buffer[pos] && buffer[pos] != '\\';pos++);
107         }
108         // if we found the key, find the end of it because we will be replacing it
109         pos2 = pos;
110         if (buffer[pos] == '\\')
111         {
112                 pos2 += 1 + (int)keylength;  // Skip \key
113                 if (buffer[pos2] == '\\') pos2++; // Skip \ before value.
114                 for (;buffer[pos2] && buffer[pos2] != '\\';pos2++);
115         }
116         if (bufferlength <= pos + 1 + strlen(key) + 1 + strlen(value) + strlen(buffer + pos2))
117         {
118                 Con_Printf("InfoString_SetValue: no room for \"%s\" \"%s\" in infostring\n", key, value);
119                 return;
120         }
121         if (value[0])
122         {
123                 // set the key/value and append the remaining text
124                 char tempbuffer[MAX_INPUTLINE];
125                 strlcpy(tempbuffer, buffer + pos2, sizeof(tempbuffer));
126                 dpsnprintf(buffer + pos, bufferlength - pos, "\\%s\\%s%s", key, value, tempbuffer);
127         }
128         else
129         {
130                 // just remove the key from the text
131                 strlcpy(buffer + pos, buffer + pos2, bufferlength - pos);
132         }
133 }
134
135 void InfoString_Print(char *buffer)
136 {
137         int i;
138         char key[MAX_INPUTLINE];
139         char value[MAX_INPUTLINE];
140         while (*buffer)
141         {
142                 if (*buffer != '\\')
143                 {
144                         Con_Printf("InfoString_Print: corrupt string\n");
145                         return;
146                 }
147                 for (buffer++, i = 0;*buffer && *buffer != '\\';buffer++)
148                         if (i < (int)sizeof(key)-1)
149                                 key[i++] = *buffer;
150                 key[i] = 0;
151                 if (*buffer != '\\')
152                 {
153                         Con_Printf("InfoString_Print: corrupt string\n");
154                         return;
155                 }
156                 for (buffer++, i = 0;*buffer && *buffer != '\\';buffer++)
157                         if (i < (int)sizeof(value)-1)
158                                 value[i++] = *buffer;
159                 value[i] = 0;
160                 // empty value is an error case
161                 Con_Printf("%20s %s\n", key, value[0] ? value : "NO VALUE");
162         }
163 }