diff --git a/README b/README index b14caf7..f986228 100644 --- a/README +++ b/README @@ -16,9 +16,9 @@ $ make RUN === -$ +$ -tileset -level Example: -$ build/sle assets/tileset.png sample.kble +$ build/sle -tileset assets/tileset.png -level sample.kble USAGE ===== diff --git a/include/editing_area/main.h b/include/editing_area/main.h index baa33f8..af7661e 100644 --- a/include/editing_area/main.h +++ b/include/editing_area/main.h @@ -4,5 +4,5 @@ #include "shared_data.h" -int editing_area_main(int argc, char **argv, +int editing_area_main(char *level_path, char *tileset_path, struct SharedData *shared_data); diff --git a/include/tile_picker/main.h b/include/tile_picker/main.h index ed484b6..c6190c6 100644 --- a/include/tile_picker/main.h +++ b/include/tile_picker/main.h @@ -4,5 +4,5 @@ #include "shared_data.h" -int tile_picker_main(int argc, char **argv, +int tile_picker_main(char *tileset_path, struct SharedData *shared_data); diff --git a/src/editing_area/main.c b/src/editing_area/main.c index 7ffd328..d27cbe0 100644 --- a/src/editing_area/main.c +++ b/src/editing_area/main.c @@ -16,7 +16,7 @@ static void init_mouse(void); static void update_mouse(int *mouse_x, int *mouse_y, struct Level level, struct SharedData *shared_data); -int editing_area_main(int argc, char **argv, +int editing_area_main(char *level_path, char *tileset_path, struct SharedData *shared_data) { int mouse_x; @@ -32,7 +32,7 @@ int editing_area_main(int argc, char **argv, SetTargetFPS(editor_target_fps); init_mouse(); /* load textures */ - tileset = LoadTexture(argv[1]); + tileset = LoadTexture(tileset_path); /* only proceed if tileset is large enough */ if (tileset.width < TILESET_MIN_WIDTH_PX || @@ -46,7 +46,7 @@ int editing_area_main(int argc, char **argv, } /* load level */ - if (level_read(&level, argv[2])) + if (level_read(&level, level_path)) goto panic; while (!WindowShouldClose()) { @@ -64,7 +64,7 @@ int editing_area_main(int argc, char **argv, } /* save level */ - level_write(level, argv[2]); + level_write(level, level_path); panic: diff --git a/src/main.c b/src/main.c index 34767ce..fec26cf 100644 --- a/src/main.c +++ b/src/main.c @@ -4,37 +4,43 @@ #include "editing_area/main.h" #include "shared_data.h" #include "tile_picker/main.h" +#include #include #include #include #include +#include #include #include #include +static const int buffer_size = 256; + static void *create_shared_memory(size_t size); +static void overflow_prevention(void); /* work on optarg */ +static void process_arguments(int argc, char **argv, + char tileset_path[buffer_size], + char level_path[buffer_size]); /* The editor fork to create two windows. One will be the level editor * and the other the tile selection. This is done to allow the user to * organize these panels in the way they want to. */ int main(int argc, char **argv) { + pid_t child_process; + char level_path[buffer_size] = ""; + char tileset_path[buffer_size] = ""; struct SharedData *shared_data = (struct SharedData *)create_shared_memory( sizeof(struct SharedData)); shared_data->end_child = false; shared_data->selected_tile = 69; - pid_t child_process; /* set log level */ SetTraceLogLevel(LOG_ERROR); - /* check for argument count */ - if (argc != 3) { - fprintf(stderr, "ERROR: expected 2 arguments, got %d\n", - argc - 1); - return EXIT_FAILURE; - }; + /* process arguments */ + process_arguments(argc, argv, tileset_path, level_path); /* forking here */ child_process = fork(); @@ -43,10 +49,11 @@ int main(int argc, char **argv) return EXIT_FAILURE; } else if (child_process == 0) { /* child process, start the tile picker */ - return tile_picker_main(argc, argv, shared_data); + return tile_picker_main(tileset_path, shared_data); } else { /* main process, start the editing area */ - editing_area_main(argc, argv, shared_data); + editing_area_main(level_path, tileset_path, + shared_data); return EXIT_SUCCESS; } } @@ -60,3 +67,75 @@ static void *create_shared_memory(size_t size) int visibility = MAP_SHARED | MAP_ANONYMOUS; return mmap(NULL, size, protection, visibility, -1, 0); } + +static void overflow_prevention(void) +{ + /* make sure arguments won't overflow */ + if (strlen(optarg) > buffer_size) { + fprintf(stderr, + "ERROR: option size %lu is " + "bigger than maximum %d\n", + strlen(optarg), buffer_size); + exit(EXIT_FAILURE); + } +} + +static void process_arguments(int argc, char **argv, + char tileset_path[buffer_size], + char level_path[buffer_size]) +{ + int opt; + while (1) { + static struct option long_options[] = { + {"level", required_argument, 0, 'l'}, + {"tileset", required_argument, 0, 't'}, + {0, 0, 0, 0}, + }; + /* getopt_long stores the option index here */ + int option_index = 0; + + opt = getopt_long_only(argc, argv, "", long_options, + &option_index); + /* detect the end of the options */ + if (opt == -1) + break; + + switch (opt) { + case 'l': + overflow_prevention(); + strcpy(level_path, optarg); + break; + case 't': + overflow_prevention(); + strcpy(tileset_path, optarg); + break; + case '?': + /* getopt_long already printed an error message + */ + exit(EXIT_FAILURE); + default: + fprintf(stderr, + "ERROR: option -%c non handled " + "(open an issue!)\n", + opt); + exit(EXIT_FAILURE); + } + } + /* missing arguments? */ + { + int error = 0; + if (level_path[0] == '\0') { + fprintf(stderr, "ERROR: no level path " + "specified (-level )\n"); + error = 1; + } + if (tileset_path[0] == '\0') { + fprintf(stderr, + "ERROR: no tileset path specified " + "(-tileset )\n"); + error = 1; + } + if (error) + exit(EXIT_FAILURE); + } +} diff --git a/src/tile_picker/main.c b/src/tile_picker/main.c index a2de3fd..d75c333 100644 --- a/src/tile_picker/main.c +++ b/src/tile_picker/main.c @@ -14,8 +14,7 @@ static void init_mouse(void); static void update_mouse(int *mouse_x, int *mouse_y, struct SharedData *shared_data); -int tile_picker_main(int argc, char **argv, - struct SharedData *shared_data) +int tile_picker_main(char *tileset_path, struct SharedData *shared_data) { int mouse_x; int mouse_y; @@ -27,7 +26,7 @@ int tile_picker_main(int argc, char **argv, SetTargetFPS(picker_target_fps); init_mouse(); /* load textures */ - tileset = LoadTexture(argv[1]); + tileset = LoadTexture(tileset_path); /* only proceed if tileset is well loaded */ if (tileset.width > 0) {