mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-16 02:56:09 -04:00
C client: simplify key-value splitting
This commit is contained in:
parent
26081a0074
commit
e3905c9a3f
@ -125,14 +125,10 @@ void Entity_SetModel(struct Entity* entity, STRING_PURE String* model) {
|
||||
entity->ModelScale = Vector3_Create1(1.0f);
|
||||
entity->ModelBlock = BLOCK_AIR;
|
||||
|
||||
Int32 sep = String_IndexOf(model, '|', 0);
|
||||
String name, scale;
|
||||
if (sep == -1) {
|
||||
if (!String_UNSAFE_Split_KV(model, '|', &name, &scale)) {
|
||||
name = *model;
|
||||
scale = String_MakeNull();
|
||||
} else {
|
||||
name = String_UNSAFE_Substring(model, 0, sep);
|
||||
scale = String_UNSAFE_SubstringAt(model, sep + 1);
|
||||
}
|
||||
|
||||
/* 'giant' model kept for backwards compatibility */
|
||||
|
23
src/Input.c
23
src/Input.c
@ -305,26 +305,21 @@ void Hotkeys_Init(void) {
|
||||
for (i = 0; i < Options_Keys.Count; i++) {
|
||||
String key = StringsBuffer_UNSAFE_Get(&Options_Keys, i);
|
||||
if (!String_CaselessStarts(&key, &prefix)) continue;
|
||||
Int32 keySplit = String_IndexOf(&key, '&', prefix.length);
|
||||
if (keySplit < 0) continue; /* invalid key */
|
||||
|
||||
String strKey = String_UNSAFE_Substring(&key, prefix.length, keySplit - prefix.length);
|
||||
String strFlags = String_UNSAFE_SubstringAt(&key, keySplit + 1);
|
||||
|
||||
/* key&modifiers = more-input&text */
|
||||
key.length -= prefix.length; key.buffer += prefix.length;
|
||||
String value = StringsBuffer_UNSAFE_Get(&Options_Values, i);
|
||||
Int32 valueSplit = String_IndexOf(&value, '&', 0);
|
||||
if (valueSplit < 0) continue; /* invalid value */
|
||||
|
||||
String strMoreInput = String_UNSAFE_Substring(&value, 0, valueSplit - 0);
|
||||
String strText = String_UNSAFE_SubstringAt(&value, valueSplit + 1);
|
||||
String strKey, strFlags, strMore, strText;
|
||||
if (!String_UNSAFE_Split_KV(&key, '&', &strKey, &strFlags)) continue;
|
||||
if (!String_UNSAFE_Split_KV(&value, '&', &strMore, &strText)) continue;
|
||||
|
||||
/* Then try to parse the key and value */
|
||||
Key hotkey = Utils_ParseEnum(&strKey, Key_None, Key_Names, Array_Elems(Key_Names));
|
||||
UInt8 flags; bool moreInput;
|
||||
if (hotkey == Key_None || !strText.length || !Convert_TryParseUInt8(&strFlags, &flags)
|
||||
|| !Convert_TryParseBool(&strMoreInput, &moreInput)) { continue; }
|
||||
UInt8 flags; bool more;
|
||||
if (hotkey == Key_None || !Convert_TryParseUInt8(&strFlags, &flags)
|
||||
|| !Convert_TryParseBool(&strMore, &more)) { continue; }
|
||||
|
||||
Hotkeys_Add(hotkey, flags, &strText, moreInput);
|
||||
Hotkeys_Add(hotkey, flags, &strText, more);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1548,14 +1548,10 @@ static void HotkeyListScreen_EntryClick(struct GuiElem* elem, struct GuiElem* w)
|
||||
Gui_ReplaceActive(EditHotkeyScreen_MakeInstance(original)); return;
|
||||
}
|
||||
|
||||
Int32 sepIndex = String_IndexOf(&text, '+', 0);
|
||||
String key = text, value;
|
||||
UInt8 flags = 0;
|
||||
|
||||
if (sepIndex >= 0) {
|
||||
key = String_UNSAFE_Substring(&text, 0, sepIndex - 1);
|
||||
value = String_UNSAFE_SubstringAt(&text, sepIndex + 1);
|
||||
|
||||
if (String_UNSAFE_Split_KV(&text, '+', &key, &value)) {
|
||||
String ctrl = String_FromConst("Ctrl");
|
||||
String shift = String_FromConst("Shift");
|
||||
String alt = String_FromConst("Alt");
|
||||
|
@ -173,6 +173,7 @@ void Options_Load(void) {
|
||||
/* ReadLine reads single byte at a time */
|
||||
UInt8 buffer[2048]; struct Stream buffered;
|
||||
Stream_ReadonlyBuffered(&buffered, &stream, buffer, sizeof(buffer));
|
||||
String key, value;
|
||||
|
||||
for (;;) {
|
||||
res = Stream_ReadLine(&buffered, &line);
|
||||
@ -180,13 +181,7 @@ void Options_Load(void) {
|
||||
if (res) { Chat_LogError(res, "reading from", &path); break; }
|
||||
|
||||
if (!line.length || line.buffer[0] == '#') continue;
|
||||
Int32 sepIndex = String_IndexOf(&line, '=', 0);
|
||||
if (sepIndex <= 0) continue;
|
||||
String key = String_UNSAFE_Substring(&line, 0, sepIndex);
|
||||
|
||||
sepIndex++;
|
||||
if (sepIndex == line.length) continue;
|
||||
String value = String_UNSAFE_SubstringAt(&line, sepIndex);
|
||||
if (!String_UNSAFE_Split_KV(&line, '=', &key, &value)) continue;
|
||||
|
||||
if (!Options_HasChanged(&key)) {
|
||||
Options_Insert(&key, &value);
|
||||
|
@ -240,18 +240,12 @@ static bool WoM_ReadLine(STRING_REF String* page, Int32* start, STRING_TRANSIENT
|
||||
}
|
||||
|
||||
static void WoM_ParseConfig(STRING_PURE String* page) {
|
||||
String line;
|
||||
String line, key, value;
|
||||
Int32 start = 0;
|
||||
|
||||
while (WoM_ReadLine(page, &start, &line)) {
|
||||
Platform_Log(&line);
|
||||
Int32 sepIndex = String_IndexOf(&line, '=', 0);
|
||||
if (sepIndex == -1) continue;
|
||||
|
||||
String key = String_UNSAFE_Substring(&line, 0, sepIndex);
|
||||
String_UNSAFE_TrimEnd(&key);
|
||||
String value = String_UNSAFE_SubstringAt(&line, sepIndex + 1);
|
||||
String_UNSAFE_TrimStart(&value);
|
||||
if (!String_UNSAFE_Split_KV(&line, '=', &key, &value)) continue;
|
||||
|
||||
if (String_CaselessEqualsConst(&key, "environment.cloud")) {
|
||||
PackedCol col = WoM_ParseCol(&value, WorldEnv_DefaultCloudsCol);
|
||||
|
@ -115,7 +115,7 @@ int main(void) {
|
||||
}
|
||||
|
||||
UInt16 port;
|
||||
if (!Convert_TryParseUInt16(&args[3], &Game_Port)) {
|
||||
if (!Convert_TryParseUInt16(&args[3], &port)) {
|
||||
Platform_LogConst("Invalid port"); return 1;
|
||||
}
|
||||
Game_Port = port;
|
||||
|
@ -154,7 +154,7 @@ static void SPConnection_BeginConnect(void) {
|
||||
}
|
||||
Event_RaiseVoid(&BlockEvents_PermissionsChanged);
|
||||
|
||||
/* For when user drops a map file onto ClassicalSharp.exe */
|
||||
/* For when user drops a map file onto ClassiCube.exe */
|
||||
String path = Game_Username;
|
||||
if (String_IndexOf(&path, Directory_Separator, 0) >= 0 && File_Exists(&path)) {
|
||||
LoadLevelScreen_LoadMap(&path);
|
||||
|
14
src/String.c
14
src/String.c
@ -82,6 +82,20 @@ void String_UNSAFE_Split(STRING_REF String* str, char c, STRING_TRANSIENT String
|
||||
for (; i < maxSubs; i++) { subs[i] = String_MakeNull(); }
|
||||
}
|
||||
|
||||
bool String_UNSAFE_Split_KV(STRING_REF String* str, char c, STRING_TRANSIENT String* key, STRING_TRANSIENT String* value) {
|
||||
/* key [c] value or key[c]value */
|
||||
Int32 idx = String_IndexOf(str, c, 0);
|
||||
if (idx <= 0) return false; /* missing [c] or no key */
|
||||
if ((idx + 1) >= str->length) return false; /* missing value */
|
||||
|
||||
*key = String_UNSAFE_Substring(str, 0, idx); idx++;
|
||||
*value = String_UNSAFE_SubstringAt(str, idx);
|
||||
|
||||
String_UNSAFE_TrimEnd(key);
|
||||
String_UNSAFE_TrimStart(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool String_Equals(STRING_PURE String* a, STRING_PURE String* b) {
|
||||
if (a->length != b->length) return false;
|
||||
|
@ -43,13 +43,10 @@ String String_FromReadonly(STRING_REF const char* buffer);
|
||||
|
||||
void String_StripCols(STRING_TRANSIENT String* str);
|
||||
void String_Copy(STRING_TRANSIENT String* dst, STRING_PURE String* src);
|
||||
/* Returns a string that points directly to a substring of the given string.
|
||||
NOTE: THIS IS UNSAFE - IT MAINTAINS A REFERENCE TO THE ORIGINAL BUFFER, AND THE SUBSTRING IS NOT NULL TERMINATED */
|
||||
String String_UNSAFE_Substring(STRING_REF String* str, Int32 offset, Int32 length);
|
||||
#define String_UNSAFE_SubstringAt(str, offset) (String_UNSAFE_Substring(str, offset, (str)->length - (offset)))
|
||||
/* Splits a string into a sequence of substrings
|
||||
NOTE: THIS IS UNSAFE - IT MAINTAINS A REFERENCE TO THE ORIGINAL BUFFER, AND THE SUBSTRING IS NOT NULL TERMINATED */
|
||||
void String_UNSAFE_Split(STRING_REF String* str, char c, STRING_TRANSIENT String* subs, Int32* subsCount);
|
||||
bool String_UNSAFE_Split_KV(STRING_REF String* str, char c, STRING_TRANSIENT String* key, STRING_TRANSIENT String* value);
|
||||
|
||||
bool String_Equals(STRING_PURE String* a, STRING_PURE String* b);
|
||||
bool String_CaselessEquals(STRING_PURE String* a, STRING_PURE String* b);
|
||||
|
@ -323,14 +323,13 @@ bool TextureCache_GetStream(STRING_PURE String* url, struct Stream* stream) {
|
||||
void TexturePack_GetFromTags(STRING_PURE String* url, STRING_TRANSIENT String* result, struct EntryList* list) {
|
||||
TexCache_Crc32(url);
|
||||
Int32 i;
|
||||
String line, key, value;
|
||||
|
||||
for (i = 0; i < list->Entries.Count; i++) {
|
||||
String entry = StringsBuffer_UNSAFE_Get(&list->Entries, i);
|
||||
if (!String_CaselessStarts(&entry, &crc32)) continue;
|
||||
line = StringsBuffer_UNSAFE_Get(&list->Entries, i);
|
||||
if (!String_UNSAFE_Split_KV(&line, ' ', &key, &value)) continue;
|
||||
|
||||
Int32 sepIndex = String_IndexOf(&entry, ' ', 0);
|
||||
if (sepIndex == -1) continue;
|
||||
|
||||
String value = String_UNSAFE_SubstringAt(&entry, sepIndex + 1);
|
||||
if (!String_CaselessEquals(&key, &crc32)) continue;
|
||||
String_AppendString(result, &value);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user