diff --git a/src/deh_soc.c b/src/deh_soc.c index ee339763e4f91eb90c5d7b94f4b744085191d6c3..8d91652e7833480749e60e9f72c15691566a1132 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -66,6 +66,101 @@ fixed_t get_number(const char *word) return i;*/ } +static boolean check_string_token(char *word) +{ + word++; + + while (*word != '"' && *word != 0) + { + if (*word == '\\') + word++; + word++; + } + + if (*word == 0) + { + deh_warning("Unterminated string"); + return false; + } + + return true; +} + +static boolean parse_string_token(action_string_t *string, char *word) +{ + int token_length = strlen(word); + int length = token_length - 2; + if (length <= 0) + return false; + + string->chars = Z_Calloc(length + 1, PU_STATIC, NULL); + string->length = 0; + + char *chars = string->chars; + + char *str = word + 1; + char *str_end = word + token_length - 1; + + while (str < str_end) + { + // Parse escape characters + if (*str == '\\') + { + str++; + + if (*str == 'n') + *chars = '\n'; + else if (*str == '"') + *chars = '"'; + else if (*str == '\\') + *chars = '\\'; + else + { + Z_Free(string->chars); + deh_warning("Invalid escape character in string token"); + return false; + } + } + else + *chars = *str; + + string->length++; + chars++; + str++; + } + + return true; +} + +static boolean parse_word(action_val_t *value, char *word) +{ + if (*word == '"') + { + if (!check_string_token(word)) + { + *value = ACTION_NULL_VAL; + return false; + } + + action_string_t string; + + if (!parse_string_token(&string, word)) + { + *value = ACTION_NULL_VAL; + return false; + } + + *value = ACTION_STRING_VAL(string); + } + else + { + strupr(word); + *value = ACTION_INTEGER_VAL(get_number(word)); + } + + return true; +} + #define PARAMCHECK(n) do { if (!params[n]) { deh_warning("Too few parameters, need %d", n); return; }} while (0) /* ======================================================================== */ @@ -2722,43 +2817,32 @@ void readframe(MYFILE *f, INT32 num) if (s[0] == '\n') break; + // First remove trailing newline, if there is one + tmp = strchr(s, '\n'); + if (tmp) + *tmp = '\0'; + tmp = strchr(s, '#'); if (tmp) *tmp = '\0'; if (s == tmp) continue; // Skip comment lines, but don't break. - word1 = strtok(s, " "); - if (word1) - strupr(word1); - else - break; + // Set / reset word + word1 = s; - word2 = strtok(NULL, " = "); - if (word2) - strupr(word2); + // Get the part before the " = " + tmp = strchr(s, '='); + if (tmp) + *(tmp-1) = '\0'; else break; - if (word2[strlen(word2)-1] == '\n') - word2[strlen(word2)-1] = '\0'; + strupr(word1); - if (fastcmp(word1, "SPRITENUMBER") || fastcmp(word1, "SPRITENAME")) - { - states[num].sprite = get_sprite(word2); - } - else if (fastcmp(word1, "SPRITESUBNUMBER") || fastcmp(word1, "SPRITEFRAME")) - { - states[num].frame = (INT32)get_number(word2); // So the FF_ flags get calculated - } - else if (fastcmp(word1, "DURATION")) - { - states[num].tics = (INT32)get_number(word2); // So TICRATE can be used - } - else if (fastcmp(word1, "NEXT")) - { - states[num].nextstate = get_state(word2); - } - else if (fastcmp(word1, "ACTION")) + // Now get the part after + word2 = tmp += 2; + + if (fastcmp(word1, "ACTION")) { size_t z; boolean found = false; @@ -2810,10 +2894,31 @@ void readframe(MYFILE *f, INT32 num) { unsigned varSlot = (word1[3] - 0x30) - 1; Action_FreeValue(states[num].vars[varSlot]); - states[num].vars[varSlot] = ACTION_INTEGER_VAL((INT32)get_number(word2)); + parse_word(&states[num].vars[varSlot], word2); } else - deh_warning("Frame %d: unknown word '%s'", num, word1); + { + strupr(word2); + + if (fastcmp(word1, "SPRITENUMBER") || fastcmp(word1, "SPRITENAME")) + { + states[num].sprite = get_sprite(word2); + } + else if (fastcmp(word1, "SPRITESUBNUMBER") || fastcmp(word1, "SPRITEFRAME")) + { + states[num].frame = (INT32)get_number(word2); // So the FF_ flags get calculated + } + else if (fastcmp(word1, "DURATION")) + { + states[num].tics = (INT32)get_number(word2); // So TICRATE can be used + } + else if (fastcmp(word1, "NEXT")) + { + states[num].nextstate = get_state(word2); + } + else + deh_warning("Frame %d: unknown word '%s'", num, word1); + } } } while (!myfeof(f));