nnextstr.cpp
1 //------------------------------------------------------------------------- 2 /* 3 Copyright (C) 2010-2019 EDuke32 developers and contributors 4 Copyright (C) 2019 Nuke.YKT 5 Copyright (C) NoOne 6 7 ***************************************************************** 8 NoOne: A very basic string parser. Update or replace eventually. 9 ***************************************************************** 10 11 This file is part of NBlood. 12 13 NBlood is free software; you can redistribute it and/or 14 modify it under the terms of the GNU General Public License version 2 15 as published by the Free Software Foundation. 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. 20 21 See the GNU General Public License for more details. 22 23 You should have received a copy of the GNU General Public License 24 along with this program; if not, write to the Free Software 25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 */ 27 //------------------------------------------------------------------------- 28 #ifdef NOONE_EXTENSIONS 29 #include "common_game.h" 30 #include "nnextstr.h" 31 #include "nnexts.h" 32 33 struct NAMED_TYPE 34 { 35 unsigned int id; 36 const char* text; 37 }; 38 39 static const NAMED_TYPE gBoolNames[] = 40 { 41 { false, "0" }, 42 { true, "1" }, 43 { false, "No" }, 44 { true, "Yes" }, 45 { false, "False" }, 46 { true, "True" }, 47 }; 48 49 const char* enumStrGetChar(int nOffs, char* out, const char* str, char expcr) 50 { 51 int j = ClipLow(nOffs, 0); 52 int i = 0; 53 54 out[0] = '\0'; 55 56 if (j > 0) 57 { 58 // search for start 59 while (str[i] && j > 0) 60 { 61 if (str[i++] == expcr) 62 j--; 63 } 64 } 65 66 while (str[i] && str[i] != expcr) 67 out[j++] = str[i++]; 68 69 70 out[j] = '\0'; 71 72 return (out[0]) ? out : NULL; 73 } 74 75 int enumStr(int nOffs, const char* str, char* key, char* val) 76 { 77 if (!str) 78 return 0; 79 80 const char* pStr; 81 char buffer1[256], buffer2[256], string[256]; 82 int t; 83 84 if (isarray(str)) 85 { 86 t = Bstrlen(str); 87 Bstrcpy(string, str); 88 string[t] = '\0'; 89 90 pStr = &string[(string[0] == '(')]; 91 if (string[t - 1] == ')') 92 string[t - 1] = '\0'; 93 94 removeSpaces(string); 95 96 if (enumStrGetChar(nOffs, buffer1, pStr, ',')) 97 { 98 if (key) 99 { 100 if (enumStrGetChar(0, buffer2, buffer1, '=')) 101 Bsprintf(key, "%s", buffer2); 102 else 103 key[0] = '\0'; 104 } 105 106 if (val) 107 { 108 if (enumStrGetChar(1, buffer2, buffer1, '=')) 109 { 110 Bsprintf(val, "%s", buffer2); 111 t = ClipLow(Bstrlen(val), 1); 112 if (val[0] == '(' && val[t - 1] != ')') 113 { 114 char tval[256]; 115 116 nOffs++; 117 while ( 1 ) 118 { 119 if ((nOffs = enumStr(nOffs, str, tval)) != 0) 120 { 121 t = Bstrlen(tval); Bstrcat(val, ","); Bstrcat(val, tval); 122 if (tval[t - 1] != ')') 123 continue; 124 } 125 else 126 { 127 ThrowError("End of array is not found in \"%s\"", str); 128 } 129 130 return nOffs; 131 } 132 } 133 134 } 135 else 136 val[0] = '\0'; 137 } 138 139 return ++nOffs; 140 } 141 } 142 143 return 0; 144 } 145 146 int enumStr(int nOffs, const char* str, char* val) 147 { 148 if (!str) 149 return 0; 150 151 const char* pStr; 152 char string[256]; 153 int t; 154 155 t = Bstrlen(str); 156 Bstrcpy(string, str); 157 string[t] = '\0'; 158 159 pStr = &string[(string[0] == '(')]; 160 if (string[t - 1] == ')') 161 string[t - 1] = '\0'; 162 163 removeSpaces(string); 164 if (enumStrGetChar(nOffs, val, pStr, ',')) 165 return ++nOffs; 166 167 return 0; 168 } 169 170 void removeSpaces(char* str) 171 { 172 if (str) 173 { 174 int t = Bstrlen(str); 175 for (int i = t - 1; i >= 0; i--) 176 { 177 if (!isspace(str[i])) 178 continue; 179 180 for (int j = i; j < t; j++) { str[j] = str[j + 1]; } 181 } 182 } 183 } 184 185 int btoi(const char* str) 186 { 187 if (str) 188 { 189 int i; 190 const NAMED_TYPE* pEntry = gBoolNames; 191 for (i = 0; i < LENGTH(gBoolNames); i++) 192 { 193 if (Bstrcasecmp(str, pEntry->text) == 0) 194 return (bool)pEntry->id; 195 196 pEntry++; 197 } 198 } 199 200 return -1; 201 } 202 char isbool(const char* str) { return (str && btoi(str) != -1); } 203 char isarray(const char* str, int* nLen) 204 { 205 if (nLen) 206 *nLen = 0; 207 208 if (str) 209 { 210 int l = Bstrlen(str); 211 if (l && str[0] == '(' && str[l - 1] == ')') 212 { 213 if (nLen) 214 { 215 *nLen = *nLen + 1; 216 const char* pStr = str; 217 while ((pStr = Bstrchr(pStr, ',')) != NULL) 218 pStr++, * nLen = *nLen + 1; 219 } 220 221 return true; 222 } 223 } 224 225 return false; 226 } 227 228 char isperc(const char* str) 229 { 230 if (str) 231 { 232 int l = Bstrlen(str); 233 if (--l > 0 && str[l] == '%') 234 { 235 while (--l > 0) 236 { 237 if (!isdigit(str[l])) 238 return false; 239 } 240 241 if (isdigit(str[l]) || str[l] == '-' || str[l] == '+') 242 return true; 243 } 244 } 245 246 return false; 247 } 248 249 char isfix(const char* str, char flags) 250 { 251 if (str) 252 { 253 int l = Bstrlen(str); 254 if (l > 0) 255 { 256 if (!isdigit(str[0])) 257 { 258 switch (str[0]) 259 { 260 case '-': 261 if (!(flags & 0x01)) return false; 262 break; 263 case '+': 264 if (!(flags & 0x02)) return false; 265 break; 266 default: 267 return false; 268 269 } 270 } 271 272 while (--l > 0) 273 { 274 if (!isdigit(str[l])) 275 return false; 276 } 277 278 return true; 279 } 280 } 281 282 return false; 283 284 } 285 286 287 char isufix(const char* str) 288 { 289 return isfix(str, 0); 290 } 291 #endif