*/
#include "../common/rexit.h" /* exit_err() */
#include "../common/try_malloc.h" /* try_malloc() */
-#include "cleanup.h" /* set_cleanup_flag() */
-#include "map_object_actions.h" /* init_map_object_actions() */
-#include "map_objects.h" /* free_map_objects(), add_map_objects(),
- * init_map_object_defs()
- */
+#include "cleanup.h" /* set_cleanup_flag(), CLEANUP_MAP_OBJ_DEFS,
+ * CLEANUP_MAP_OBJ_ACTS
+ */
+#include "io.h" /* read_config_file(), struct EntrySkeleton */
#include "map.h" /* init_map() */
+#include "map_object_actions.h" /* struct MapObjAct, read_map_object_action() */
+#include "map_objects.h" /* struct MapObjDef, free_map_objects(),
+ * add_map_objects(), read_map_object_def()
+ */
#include "rrand.h" /* rrand() */
#include "run.h" /* obey_msg(), io_loop() */
#include "world.h" /* global world */
char * err_moa = "No map object actions file.";
exit_err(access(world.path_map_obj_defs, F_OK), err_mod);
exit_err(access(world.path_map_obj_acts, F_OK), err_moa);
- init_map_object_defs();
- init_map_object_actions();
+ read_config_file(world.path_map_obj_defs, CLEANUP_MAP_OBJECT_DEFS,
+ sizeof(struct MapObjDef),
+ (struct EntrySkeleton **) &world.map_obj_defs,
+ read_map_object_def);
+ read_config_file(world.path_map_obj_acts, CLEANUP_MAP_OBJECT_ACTS,
+ sizeof(struct MapObjAct),
+ (struct EntrySkeleton **) &world.map_obj_acts,
+ read_map_object_action);
}
#include <limits.h> /* PIPE_BUF */
#include <stddef.h> /* size_t, NULL */
#include <stdint.h> /* uint8_t, uint32_t */
-#include <stdio.h> /* defines EOF, FILE, sprintf() */
-#include <stdlib.h> /* free() */
+#include <stdio.h> /* defines EOF, FILE, sprintf(), ungetc() */
+#include <stdlib.h> /* free(), atoi() */
#include <string.h> /* strlen(), memcpy() */
#include <sys/types.h> /* time_t */
#include <time.h> /* time() */
+#include "../common/err_try_fgets.h" /* err_try_fgets(), err_line(),
+ * reset_err_try_fgets_counter()
+ */
#include "../common/readwrite.h" /* try_fopen(), try_fclose_unlink_rename(),
- * try_fwrite(), try_fputc(), try_fgetc()
+ * try_fwrite(), try_fputc(), try_fgetc(),
+ * try_fclose()
*/
+#include "../common/rexit.h" /* exit_trouble() */
#include "../common/try_malloc.h" /* try_malloc() */
-#include "cleanup.h" /* set_cleanup_flag() */
+#include "cleanup.h" /* set_cleanup_flag(), enum cleanup_flag */
#include "map_objects.h" /* structs MapObj, MapObjDef, get_map_obj_def() */
#include "world.h" /* global world */
+extern void read_config_file(char * path, enum cleanup_flag cleanup,
+ size_t size, struct EntrySkeleton ** entry_start,
+ void (* read) (char *, uint32_t, char *,
+ struct EntrySkeleton *, FILE *))
+{
+ char * f_name = "init_map_object_defs()";
+ char * context_prefix = "Failed reading config file: ";
+ char context[strlen(context_prefix) + strlen(path) + 1];
+ sprintf(context, "%s%s", context_prefix, path);
+ char * err_uniq = "Declaration of ID already used.";
+ FILE * file = try_fopen(path, "r", f_name);
+ uint32_t linemax = textfile_width(file);
+ char line[linemax + 1];
+ reset_err_try_fgets_counter();
+ struct EntrySkeleton ** entry_ptr_ptr = entry_start;
+ while (1)
+ {
+ int test_for_end = try_fgetc(file, f_name);
+ if (EOF == test_for_end || '\n' == test_for_end)
+ {
+ break;
+ }
+ exit_trouble(EOF == ungetc(test_for_end, file), f_name, "ungetc()");
+ err_try_fgets(line, linemax, file, context, "nfi8");
+ struct EntrySkeleton * entry = try_malloc(size, f_name);
+ entry->id = atoi(line);
+ struct EntrySkeleton * entry_test = * entry_start;
+ for (; NULL != entry_test; entry_test = entry_test->next)
+ {
+ err_line(entry->id == entry_test->id, line, context, err_uniq);
+ }
+ read(line, linemax, context, entry, file);
+ entry->next = NULL;
+ * entry_ptr_ptr = entry;
+ entry_ptr_ptr = &entry->next;
+ err_try_fgets(line, linemax, file, context, "d");
+ }
+ try_fclose(file, f_name);
+ set_cleanup_flag(cleanup);
+}
+
+
+
extern char * io_round()
{
char * f_name = "io_round()";
#ifndef IO_H
#define IO_H
+#include <stddef.h> /* size_t */
+#include <stdint.h> /* uint8_t, uint32_t */
+#include <stdio.h> /* FILE */
+#include "cleanup.h" /* enum cleanup_flag */
+
+/* Wrapper to reading in config files from "path" for DB entries of "size
+ * starting at "entry_start", to be unset by "cleanup" and reading in individual
+ * entry data line by line via "read"(). Assumes all entries start with the
+ * items collected in the EntrySkeleton struct.
+ */
+struct EntrySkeleton
+{
+ uint8_t id;
+ struct EntrySkeleton * next;
+};
+extern void read_config_file(char * path, enum cleanup_flag cleanup,
+ size_t size, struct EntrySkeleton ** entry_start,
+ void (* read) (char *, uint32_t, char *,
+ struct EntrySkeleton *, FILE *));
+
/* Return single \0-terminated string read from input queue (world.queue); or,
* if queue is empty and world.turn is unequal world.last_update_turn, update
* world state file at world.path_worldstate (and update world.last_update_turn
#include <stdio.h> /* sprintf(), ungetc() */
#include <stdlib.h> /* free(), atoi() */
#include <string.h> /* strlen(), strcmp(), memcpy(), strncmp() */
-#include "../common/err_try_fgets.h" /* err_try_fgets(), err_line(),
- * reset_err_try_fgets_counter()
- */
-#include "../common/readwrite.h" /* textfile_width(), try_fopen(), try_fclose(),
- * try_fgetc()
- */
-#include "../common/rexit.h" /* exit_err(), exit_trouble() */
+#include "../common/err_try_fgets.h" /* err_try_fgets() */
+#include "../common/rexit.h" /* exit_err() */
#include "../common/try_malloc.h" /* try_malloc() */
#include "../common/yx_uint8.h" /* struct yx_uint8 */
-#include "cleanup.h" /* set_cleanup_flag() */
+#include "io.h" /* struct EntrySkeleton */
#include "map_objects.h" /* structs MapObj, MapObjDef, get_player(),
* set_object_position(), own_map_object(),
* get_map_object_def()
-extern void init_map_object_actions()
+extern void read_map_object_action(char * line, uint32_t linemax,char * context,
+ struct EntrySkeleton * entry, FILE * file)
{
char * f_name = "init_map_object_actions()";
- FILE * file = try_fopen(world.path_map_obj_acts, "r", f_name);
- uint32_t linemax = textfile_width(file);
- char line[linemax + 1];
- struct MapObjAct ** moa_ptr_ptr = &world.map_obj_acts;
- char * context = "Failed reading map object actions config file. ";
- char * err_uniq = "Declaration of ID already used.";
- reset_err_try_fgets_counter();
- while (1)
+ struct MapObjAct * moa = (struct MapObjAct *) entry;
+ err_try_fgets(line, linemax, file, context, "0nfi8");
+ moa->effort = atoi(line);
+ err_try_fgets(line, linemax, file, context, "0nf");
+ line[strlen(line) - 1] = '\0';
+ uint8_t len_name = strlen(line) + 1;
+ moa->name = try_malloc(len_name, f_name);
+ memcpy(moa->name, line, len_name);
+ if (!( try_func_name(moa, "move", actor_move)
+ || try_func_name(moa, "pick_up", actor_pick)
+ || try_func_name(moa, "drop", actor_drop)
+ || try_func_name(moa, "use", actor_use)))
{
- int test_for_end = try_fgetc(file, f_name);
- if (EOF == test_for_end || '\n' == test_for_end)
- {
- break;
- }
- exit_trouble(EOF == ungetc(test_for_end, file), f_name, "ungetc()");
- struct MapObjAct * moa = try_malloc(sizeof(struct MapObjAct), f_name);
- err_try_fgets(line, linemax, file, context, "nfi8");
- moa->id = atoi(line);
- struct MapObjAct * moa_test = world.map_obj_acts;
- for (; NULL != moa_test; moa_test = moa_test->next)
- {
- err_line(moa->id == moa_test->id, line, context, err_uniq);
- }
- err_try_fgets(line, linemax, file, context, "0nfi8");
- moa->effort = atoi(line);
- err_try_fgets(line, linemax, file, context, "0nf");
- line[strlen(line) - 1] = '\0';
- uint8_t len_name = strlen(line) + 1;
- moa->name = try_malloc(len_name, f_name);
- memcpy(moa->name, line, len_name);
- if (!( try_func_name(moa, "move", actor_move)
- || try_func_name(moa, "pick_up", actor_pick)
- || try_func_name(moa, "drop", actor_drop)
- || try_func_name(moa, "use", actor_use)))
- {
- moa->func = actor_wait;
- }
- moa->next = NULL;
- * moa_ptr_ptr = moa;
- moa_ptr_ptr = &moa->next;
- err_try_fgets(line, linemax, file, context, "d");
+ moa->func = actor_wait;
}
- try_fclose(file, f_name);
- set_cleanup_flag(CLEANUP_MAP_OBJECT_ACTS);
}
#ifndef MAP_OBJECT_ACTIONS_H
#define MAP_OBJECT_ACTIONS_H
-#include <stdint.h> /* uint8_t */
+#include <stdint.h> /* uint8_t, uint23_t */
+#include <stdio.h> /* FILE */
struct MapObj;
+struct EntrySkeleton;
struct MapObjAct
{
+ uint8_t id; /* unique id of map object action; must be >0 */
struct MapObjAct * next;
void (* func) (struct MapObj *); /* function called after .effort turns */
char * name; /* human-readable identifier */
- uint8_t id; /* unique id of map object action; must be >0 */
uint8_t effort; /* how many turns the action takes */
};
-/* Init MapObjAct chain at world.map_obj_acts. */
-extern void init_map_object_actions();
+/* Read-in to "entry" multi-line entry from MapObjAct config "file", using
+ * pre-allocated "line", "linemax" and "context" as input for err_try_fgets().
+ */
+extern void read_map_object_action(char * line, uint32_t linemax,char * context,
+ struct EntrySkeleton * entry, FILE * file);
/* Free MapObjAct * chain starting at "moa". */
extern void free_map_object_actions(struct MapObjAct * moa);
#include <stdint.h> /* uint8_t, uint16_t */
#include <stdlib.h> /* free(), atoi() */
#include <string.h> /* strlen(), memcpy(), memset() */
-#include "../common/err_try_fgets.h" /* err_try_fgets(), err_line(),
- * reset_err_try_fgets_counter()
- */
-#include "../common/readwrite.h" /* try_fopen(), try_fclose(), try_fgetc(),
- * textfile_width()
- */
-#include "../common/rexit.h" /* exit_err(), exit_trouble() */
+#include "../common/err_try_fgets.h" /* err_try_fgets() */
+#include "../common/rexit.h" /* exit_err() */
#include "../common/try_malloc.h" /* try_malloc() */
#include "../common/yx_uint8.h" /* yx_uint8 struct */
-#include "cleanup.h" /* set_cleanup_flag() */
#include "map.h" /* is_passable() */
#include "rrand.h" /* rrand() */
#include "world.h" /* global world */
#include "yx_uint8.h" /* yx_uint8_cmp() */
-
+#include "io.h" /* struct EntrySkeleton */
/* Return pointer to map object of "id" in chain starting at "ptr". */
static struct MapObj * get_map_object(struct MapObj * ptr, uint8_t id);
-extern void init_map_object_defs()
+extern void read_map_object_def(char * line, uint32_t linemax, char * context,
+ struct EntrySkeleton * entry, FILE * file)
{
char * f_name = "init_map_object_defs()";
- char * context = "Failed reading map object definitions file. ";
- char * err_uniq = "Declaration of ID already used.";
- FILE * file = try_fopen(world.path_map_obj_defs, "r", f_name);
- uint32_t linemax = textfile_width(file);
- struct MapObjDef ** last_mod_ptr_ptr = &world.map_obj_defs;
- char line[linemax + 1];
- reset_err_try_fgets_counter();
- while (1)
- {
- int test_for_end = try_fgetc(file, f_name);
- if (EOF == test_for_end || '\n' == test_for_end)
- {
- break;
- }
- exit_trouble(EOF == ungetc(test_for_end, file), f_name, "ungetc()");
- struct MapObjDef * mod = try_malloc(sizeof(struct MapObjDef), f_name);
- mod->next = NULL;
- err_try_fgets(line, linemax, file, context, "nfi8");
- mod->id = atoi(line);
- struct MapObjDef * mod_test = world.map_obj_defs;
- for (; NULL != mod_test; mod_test = mod_test->next)
- {
- err_line(mod->id == mod_test->id, line, context, err_uniq);
- }
- err_try_fgets(line, linemax, file, context, "0nfi8");
- mod->corpse_id = atoi(line);
- err_try_fgets(line, linemax, file, context, "0nfs");
- mod->char_on_map = line[0];
- err_try_fgets(line, linemax, file, context, "0nfi8");
- mod->lifepoints = atoi(line);
- err_try_fgets(line, linemax, file, context, "0nf");
- line[strlen(line) - 1] = '\0';
- mod->name = try_malloc(strlen(line) + 1, f_name);
- memcpy(mod->name, line, strlen(line) + 1);
- err_try_fgets(line, linemax, file, context, "0nfi8");
- mod->consumable = atoi(line);
- * last_mod_ptr_ptr = mod;
- last_mod_ptr_ptr = &mod->next;
- err_try_fgets(line, linemax, file, context, "d");
- }
- try_fclose(file, f_name);
- set_cleanup_flag(CLEANUP_MAP_OBJECT_DEFS);
+ struct MapObjDef * mod = (struct MapObjDef *) entry;
+ err_try_fgets(line, linemax, file, context, "0nfi8");
+ mod->corpse_id = atoi(line);
+ err_try_fgets(line, linemax, file, context, "0nfs");
+ mod->char_on_map = line[0];
+ err_try_fgets(line, linemax, file, context, "0nfi8");
+ mod->lifepoints = atoi(line);
+ err_try_fgets(line, linemax, file, context, "0nf");
+ line[strlen(line) - 1] = '\0';
+ mod->name = try_malloc(strlen(line) + 1, f_name);
+ memcpy(mod->name, line, strlen(line) + 1);
+ err_try_fgets(line, linemax, file, context, "0nfi8");
+ mod->consumable = atoi(line);
}
#ifndef MAP_OBJECTS_H
#define MAP_OBJECTS_H
-#include <stdint.h> /* uint8_t */
+#include <stdint.h> /* uint8_t, uint32_t */
+#include <stdio.h> /* FILE */
#include "../common/yx_uint8.h" /* yx_uint8 structs */
+struct EntrySkeleton;
struct MapObjDef
{
+ uint8_t id; /* map object definition identifier / sets .type */
struct MapObjDef * next;
char char_on_map; /* map object symbol to appear on map */
char * name; /* string to describe object in game log */
- uint8_t id; /* map object definition identifier / sets .type */
uint8_t corpse_id; /* type to change map object into upon destruction */
uint8_t lifepoints; /* default start value for map object's .lifepoints */
uint8_t consumable; /* can be eaten if !0, for so much hitpoint win */
-/* Initialize map object definitions chain. */
-extern void init_map_object_defs();
+/* Read-in to "entry" multi-line entry from MapObjDef config "file", using
+ * pre-allocated "line", "linemax" and "context" as input for err_try_fgets().
+ */
+extern void read_map_object_def(char * line, uint32_t linemax, char * context,
+ struct EntrySkeleton * entry, FILE * file);
/* Free map object definitions chain starting at "mod_start". */
extern void free_map_object_defs(struct MapObjDef * mod_start);