X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fmisc.c;h=8bc457216de7448418ad5cebd885728e562b5b60;hb=refs%2Fheads%2Fmaster-next-major-release;hp=536d90b53816d3b4ab11e26f28ed0f54edd9842e;hpb=e498c78309eb6b3b2cc1820833120862569858b7;p=rocksndiamonds.git diff --git a/src/libgame/misc.c b/src/libgame/misc.c index 536d90b5..ed4bd5d6 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -620,12 +620,12 @@ static unsigned int mainCounter(int mode) return current_ms - base_ms; } -void InitCounter() // set counter back to zero +void InitCounter(void) // set counter back to zero { mainCounter(INIT_COUNTER); } -unsigned int Counter() // get milliseconds since last call of InitCounter() +unsigned int Counter(void) // get milliseconds since last call of InitCounter() { return mainCounter(READ_COUNTER); } @@ -1220,6 +1220,18 @@ char *getStringCopyNStatic(const char *s, int n) return s_copy; } +char *getStringToUpper(const char *s) +{ + char *s_copy = checked_malloc(strlen(s) + 1); + char *s_ptr = s_copy; + + while (*s) + *s_ptr++ = toupper(*s++); + *s_ptr = '\0'; + + return s_copy; +} + char *getStringToLower(const char *s) { char *s_copy = checked_malloc(strlen(s) + 1); @@ -1232,6 +1244,55 @@ char *getStringToLower(const char *s) return s_copy; } +static char *getStringVPrint(char *format, va_list ap) +{ + char s[MAX_LINE_LEN]; + + vsnprintf(s, MAX_LINE_LEN, format, ap); // may truncate output string + + return getStringCopy(s); +} + +char *getStringPrint(char *format, ...) +{ + va_list ap; + char *s; + + va_start(ap, format); + s = getStringVPrint(format, ap); + va_end(ap); + + return s; +} + +void setStringPrint(char **s, char *format, ...) +{ + va_list ap; + + checked_free(*s); + + va_start(ap, format); + *s = getStringVPrint(format, ap); + va_end(ap); +} + +void appendStringPrint(char **s_old, char *format, ...) +{ + va_list ap; + char *s_new; + + va_start(ap, format); + s_new = getStringVPrint(format, ap); + va_end(ap); + + char *s_combined = getStringCat2(*s_old, s_new); + + checked_free(*s_old); + checked_free(s_new); + + *s_old = s_combined; +} + void setString(char **old_value, const char *new_value) { checked_free(*old_value); @@ -1239,6 +1300,296 @@ void setString(char **old_value, const char *new_value) *old_value = getStringCopy(new_value); } +char **getSplitStringArray(const char *s, const char *separators, int max_tokens) +{ + const char *s_ptr, *s_last = s; + byte separator_table[256] = { FALSE }; + int num_tokens; + char **tokens = NULL; + + if (s == NULL) + return NULL; + + if (separators == NULL) + return NULL; + + if (max_tokens < 1) + max_tokens = INT_MAX; + + // if string is empty, return empty array + if (*s == '\0') + { + tokens = checked_malloc(sizeof(char *)); + tokens[0] = NULL; + + return tokens; + } + + // initialize separator table for all characters in separators string + for (s_ptr = separators; *s_ptr != '\0'; s_ptr++) + separator_table[*(byte *)s_ptr] = TRUE; + + // count number of tokens in string + for (num_tokens = 1, s_ptr = s; *s_ptr != '\0'; s_ptr++) + if (separator_table[*(byte *)s_ptr] && num_tokens < max_tokens) + num_tokens++; + + // allocate array for determined number of tokens + tokens = checked_malloc((num_tokens + 1) * sizeof(char *)); + + // copy all but last separated sub-strings to array + for (num_tokens = 0, s_ptr = s; *s_ptr != '\0'; s_ptr++) + { + if (separator_table[*(byte *)s_ptr] && num_tokens + 1 < max_tokens) + { + tokens[num_tokens++] = getStringCopyN(s_last, s_ptr - s_last); + s_last = s_ptr + 1; + } + } + + // copy last separated sub-string to array + tokens[num_tokens++] = getStringCopyN(s_last, s_ptr - s_last); + + // terminate array + tokens[num_tokens] = NULL; + + return tokens; +} + +int getStringArrayLength(char **s_array) +{ + int num_strings = 0; + + if (s_array == NULL) + return 0; + + while (s_array[num_strings] != NULL) + num_strings++; + + return num_strings; +} + +void freeStringArray(char **s_array) +{ + int i; + + if (s_array == NULL) + return; + + for (i = 0; s_array[i] != NULL; i++) + checked_free(s_array[i]); + + checked_free(s_array); +} + +char *getEscapedString(const char *s) +{ + const unsigned char *s_ptr = (unsigned char *)s; + char *s_escaped; + char *s_escaped_ptr; + + if (s == NULL) + return NULL; + + /* Each source byte needs maximally four target chars (\777) */ + s_escaped = checked_malloc(strlen(s) * 4 + 1); + s_escaped_ptr = s_escaped; + + while (*s_ptr != '\0') + { + switch (*s_ptr) + { + case '\b': + *s_escaped_ptr++ = '\\'; + *s_escaped_ptr++ = 'b'; + break; + + case '\f': + *s_escaped_ptr++ = '\\'; + *s_escaped_ptr++ = 'f'; + break; + + case '\n': + *s_escaped_ptr++ = '\\'; + *s_escaped_ptr++ = 'n'; + break; + + case '\r': + *s_escaped_ptr++ = '\\'; + *s_escaped_ptr++ = 'r'; + break; + + case '\t': + *s_escaped_ptr++ = '\\'; + *s_escaped_ptr++ = 't'; + break; + + case '\v': + *s_escaped_ptr++ = '\\'; + *s_escaped_ptr++ = 'v'; + break; + + case '\\': + *s_escaped_ptr++ = '\\'; + *s_escaped_ptr++ = '\\'; + break; + + case '"': + *s_escaped_ptr++ = '\\'; + *s_escaped_ptr++ = '"'; + break; + + default: + if ((*s_ptr < ' ') || (*s_ptr >= 0177)) + { + *s_escaped_ptr++ = '\\'; + *s_escaped_ptr++ = '0' + (((*s_ptr) >> 6) & 07); + *s_escaped_ptr++ = '0' + (((*s_ptr) >> 3) & 07); + *s_escaped_ptr++ = '0' + ( (*s_ptr) & 07); + } + else + { + *s_escaped_ptr++ = *s_ptr; + } + break; + } + + s_ptr++; + } + + *s_escaped_ptr = '\0'; + + return s_escaped; +} + +char *getUnescapedString(const char *s) +{ + const char *s_ptr = s; + const char *octal_ptr; + char *s_unescaped; + char *s_unescaped_ptr; + + if (s == NULL) + return NULL; + + s_unescaped = checked_malloc(strlen(s) + 1); + s_unescaped_ptr = s_unescaped; + + while (*s_ptr != '\0') + { + if (*s_ptr == '\\') + { + s_ptr++; + + switch (*s_ptr) + { + case '\0': + Warn("getUnescapedString: trailing \\"); + goto out; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + *s_unescaped_ptr = 0; + octal_ptr = s_ptr; + + while (s_ptr < octal_ptr + 3 && *s_ptr >= '0' && *s_ptr <= '7') + { + *s_unescaped_ptr = (*s_unescaped_ptr * 8) + (*s_ptr - '0'); + s_ptr++; + } + + s_unescaped_ptr++; + s_ptr--; + break; + + case 'b': + *s_unescaped_ptr++ = '\b'; + break; + + case 'f': + *s_unescaped_ptr++ = '\f'; + break; + + case 'n': + *s_unescaped_ptr++ = '\n'; + break; + + case 'r': + *s_unescaped_ptr++ = '\r'; + break; + + case 't': + *s_unescaped_ptr++ = '\t'; + break; + + case 'v': + *s_unescaped_ptr++ = '\v'; + break; + + default: + /* also handles \" and \\ */ + *s_unescaped_ptr++ = *s_ptr; + break; + } + } + else + { + *s_unescaped_ptr++ = *s_ptr; + } + + s_ptr++; + } + + out: + *s_unescaped_ptr = '\0'; + + return s_unescaped; +} + +char *chugString(char *s) +{ + if (s == NULL) + return NULL; + + char *start; + + for (start = (char *)s; *start && isspace(*start); start++) + ; + + memmove(s, start, strlen(start) + 1); + + return s; +} + +char *chompString(char *s) +{ + if (s == NULL) + return NULL; + + int len = strlen(s); + + while (len--) + { + if (isspace(s[len])) + s[len] = '\0'; + else + break; + } + + return s; +} + +char *stripString(char *s) +{ + return chugString(chompString(s)); +} + boolean strEqual(const char *s1, const char *s2) { return (s1 == NULL && s2 == NULL ? TRUE : @@ -1353,6 +1704,7 @@ void GetOptions(int argc, char *argv[], options.player_name = NULL; options.identifier = NULL; options.level_nr = NULL; + options.drop_file = NULL; options.display_nr = 0; @@ -1519,6 +1871,15 @@ void GetOptions(int argc, char *argv[], if (option_arg == next_option) options_left++; } + else if (strncmp(option, "-drop-file", option_len) == 0) + { + if (option_arg == NULL) + FailWithHelp("option '%s' requires an argument", option_str); + + options.drop_file = getStringCopy(option_arg); + if (option_arg == next_option) + options_left++; + } else if (strncmp(option, "-verbose", option_len) == 0) { options.verbose = TRUE; @@ -1662,6 +2023,19 @@ void clear_mem(void *ptr, unsigned int size) #endif } +void *get_memcpy(const void *m, size_t size) +{ + void *m_copy; + + if (m == NULL) + return NULL; + + m_copy = checked_malloc(size); + memcpy(m_copy, m, size); + + return m_copy; +} + // ---------------------------------------------------------------------------- // various helper functions @@ -2591,7 +2965,7 @@ boolean get_boolean_from_string(char *s) return result; } -int get_switch3_from_string(char *s) +int get_switch_3_state_from_string(char *s) { char *s_lower = getStringToLower(s); int result = FALSE; @@ -2602,7 +2976,9 @@ int get_switch3_from_string(char *s) get_integer_from_string(s) == 1) result = TRUE; else if (strEqual(s_lower, "auto")) - result = AUTO; + result = STATE_AUTO; + else if (strEqual(s_lower, "ask")) + result = STATE_ASK; free(s_lower); @@ -2734,7 +3110,7 @@ static void dumpList(ListNode *node_first) #define MAX_BUFFER_SIZE 4096 -File *openFile(char *filename, char *mode) +File *openFile(const char *filename, const char *mode) { File *file = checked_calloc(sizeof(File)); @@ -2890,7 +3266,7 @@ char *getStringFromFile(File *file, char *line, int size) return fgets(line, size, file->file); } -int copyFile(char *filename_from, char *filename_to) +int copyFile(const char *filename_from, const char *filename_to) { File *file_from, *file_to; @@ -2920,7 +3296,7 @@ int copyFile(char *filename_from, char *filename_to) return 0; } -boolean touchFile(char *filename) +boolean touchFile(const char *filename) { FILE *file;