X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fsetup.c;h=922f8314aa1689dd47c52eea6af5dd96f2f84211;hb=db0cf963a41d958dc11ee1d3cfb2b1f88cba7f76;hp=114087ac0ea6e17cb7f0dc0f719367ebe3a4320f;hpb=548bc4ec64319d780a7bc38a6d0141bf526c7e16;p=rocksndiamonds.git diff --git a/src/libgame/setup.c b/src/libgame/setup.c index 114087ac..922f8314 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -498,31 +498,19 @@ char *getLevelSetInfoFilename() return NULL; } -char *getLevelSetMessageFilename() +char *getLevelSetTitleMessageFilename(int nr, boolean initial) { static char *filename = NULL; - char *basenames[] = - { - "MESSAGE", - "MESSAGE.TXT", - "MESSAGE.txt", - "Message", - "Message.txt", - "message", - "message.txt", + char basename[32]; - NULL - }; - int i; + sprintf(basename, "%s_%d.txt", + (initial ? "titlemessage_initial" : "titlemessage"), nr + 1); - for (i = 0; basenames[i] != NULL; i++) - { - checked_free(filename); - filename = getPath2(getCurrentLevelDir(), basenames[i]); + checked_free(filename); + filename = getPath2(getCurrentLevelDir(), basename); - if (fileExists(filename)) - return filename; - } + if (fileExists(filename)) + return filename; return NULL; } @@ -1619,29 +1607,42 @@ static void printSetupFileHash(SetupFileHash *hash) } #endif -static void *loadSetupFileData(char *filename, boolean use_hash) +#define ALLOW_TOKEN_VALUE_SEPARATOR_BEING_WHITESPACE 1 +#define CHECK_TOKEN_VALUE_SEPARATOR__WARN_IF_MISSING 0 + +static void loadSetupFileData(void *setup_file_data, char *filename, + boolean top_recursion_level, boolean is_hash) { - char line[MAX_LINE_LEN], previous_line[MAX_LINE_LEN]; + static SetupFileHash *include_filename_hash = NULL; + char line[MAX_LINE_LEN], line_raw[MAX_LINE_LEN], previous_line[MAX_LINE_LEN]; char *token, *value, *line_ptr; - void *setup_file_data, *insert_ptr = NULL; + void *insert_ptr = NULL; boolean read_continued_line = FALSE; boolean token_value_separator_found; -#if 1 +#if CHECK_TOKEN_VALUE_SEPARATOR__WARN_IF_MISSING boolean token_value_separator_warning = FALSE; #endif FILE *file; + int line_nr = 0; + int token_count = 0; if (!(file = fopen(filename, MODE_READ))) { Error(ERR_WARN, "cannot open configuration file '%s'", filename); - return NULL; + return; } - if (use_hash) - setup_file_data = newSetupFileHash(); - else - insert_ptr = setup_file_data = newSetupFileList("", ""); + /* use "insert pointer" to store list end for constant insertion complexity */ + if (!is_hash) + insert_ptr = setup_file_data; + + /* on top invocation, create hash to mark included files (to prevent loops) */ + if (top_recursion_level) + include_filename_hash = newSetupFileHash(); + + /* mark this file as already included (to prevent including it again) */ + setHashEntry(include_filename_hash, getBaseNamePtr(filename), "true"); while (!feof(file)) { @@ -1649,11 +1650,18 @@ static void *loadSetupFileData(char *filename, boolean use_hash) if (!fgets(line, MAX_LINE_LEN, file)) break; - /* cut trailing newline or carriage return */ + /* check if line was completely read and is terminated by line break */ + if (strlen(line) > 0 && line[strlen(line) - 1] == '\n') + line_nr++; + + /* cut trailing line break (this can be newline and/or carriage return) */ for (line_ptr = &line[strlen(line)]; line_ptr >= line; line_ptr--) if ((*line_ptr == '\n' || *line_ptr == '\r') && *(line_ptr + 1) == '\0') *line_ptr = '\0'; + /* copy raw input line for later use (mainly debugging output) */ + strcpy(line_raw, line); + if (read_continued_line) { /* cut leading whitespaces from input line */ @@ -1714,6 +1722,7 @@ static void *loadSetupFileData(char *filename, boolean use_hash) for (line_ptr = token; *line_ptr; line_ptr++) { #if 1 + /* first look for an explicit token/value separator, like ':' or '=' */ if (*line_ptr == ':' || *line_ptr == '=') #else if (*line_ptr == ' ' || *line_ptr == '\t' || *line_ptr == ':') @@ -1728,7 +1737,7 @@ static void *loadSetupFileData(char *filename, boolean use_hash) } } -#if 1 +#if ALLOW_TOKEN_VALUE_SEPARATOR_BEING_WHITESPACE /* fallback: if no token/value separator found, also allow whitespaces */ if (!token_value_separator_found) { @@ -1745,19 +1754,19 @@ static void *loadSetupFileData(char *filename, boolean use_hash) } } -#if 1 +#if CHECK_TOKEN_VALUE_SEPARATOR__WARN_IF_MISSING if (token_value_separator_found) { if (!token_value_separator_warning) { - Error(ERR_RETURN_LINE, "-"); - Error(ERR_WARN, "no valid token/value separator in config file:"); - Error(ERR_RETURN, "- config file: '%s'", filename); + Error(ERR_INFO_LINE, "-"); + Error(ERR_WARN, "missing token/value separator(s) in config file:"); + Error(ERR_INFO, "- config file: '%s'", filename); token_value_separator_warning = TRUE; } - Error(ERR_RETURN, "- no separator in line: '%s'", line); + Error(ERR_INFO, "- line %d: '%s'", line_nr, line_raw); } #endif } @@ -1780,40 +1789,53 @@ static void *loadSetupFileData(char *filename, boolean use_hash) if (*token) { - if (use_hash) - setHashEntry((SetupFileHash *)setup_file_data, token, value); + if (strEqual(token, "include")) + { + if (getHashEntry(include_filename_hash, value) == NULL) + { + char *basepath = getBasePath(filename); + char *basename = getBaseName(value); + char *filename_include = getPath2(basepath, basename); + +#if 0 + Error(ERR_INFO, "[including file '%s']", filename_include); +#endif + + loadSetupFileData(setup_file_data, filename_include, FALSE, is_hash); + + free(basepath); + free(basename); + free(filename_include); + } + else + { + Error(ERR_WARN, "ignoring already processed file '%s'", value); + } + } else - insert_ptr = addListEntry((SetupFileList *)insert_ptr, token, value); + { + if (is_hash) + setHashEntry((SetupFileHash *)setup_file_data, token, value); + else + insert_ptr = addListEntry((SetupFileList *)insert_ptr, token, value); + + token_count++; + } } } fclose(file); -#if 1 +#if CHECK_TOKEN_VALUE_SEPARATOR__WARN_IF_MISSING if (token_value_separator_warning) - Error(ERR_RETURN_LINE, "-"); + Error(ERR_INFO_LINE, "-"); #endif - if (use_hash) - { - if (hashtable_count((SetupFileHash *)setup_file_data) == 0) - Error(ERR_WARN, "configuration file '%s' is empty", filename); - } - else - { - SetupFileList *setup_file_list = (SetupFileList *)setup_file_data; - SetupFileList *first_valid_list_entry = setup_file_list->next; - - /* free empty list header */ - setup_file_list->next = NULL; - freeSetupFileList(setup_file_list); - setup_file_data = first_valid_list_entry; + if (token_count == 0) + Error(ERR_WARN, "configuration file '%s' is empty", filename); - if (first_valid_list_entry == NULL) - Error(ERR_WARN, "configuration file '%s' is empty", filename); - } - - return setup_file_data; + if (top_recursion_level) + freeSetupFileHash(include_filename_hash); } void saveSetupFileHash(SetupFileHash *hash, char *filename) @@ -1839,12 +1861,27 @@ void saveSetupFileHash(SetupFileHash *hash, char *filename) SetupFileList *loadSetupFileList(char *filename) { - return (SetupFileList *)loadSetupFileData(filename, FALSE); + SetupFileList *setup_file_list = newSetupFileList("", ""); + SetupFileList *first_valid_list_entry; + + loadSetupFileData(setup_file_list, filename, TRUE, FALSE); + + first_valid_list_entry = setup_file_list->next; + + /* free empty list header */ + setup_file_list->next = NULL; + freeSetupFileList(setup_file_list); + + return first_valid_list_entry; } SetupFileHash *loadSetupFileHash(char *filename) { - return (SetupFileHash *)loadSetupFileData(filename, TRUE); + SetupFileHash *setup_file_hash = newSetupFileHash(); + + loadSetupFileData(setup_file_hash, filename, TRUE, TRUE); + + return setup_file_hash; } void checkSetupFileHashIdentifier(SetupFileHash *setup_file_hash, @@ -2400,6 +2437,7 @@ static TreeInfo *getArtworkInfoCacheEntry(LevelDirTree *level_node, int type) cached = FALSE; } } + *artwork_info = ldi; }