/* SPDX-License-Identifier: LGPL-2.1-only */ /* Copyright (C) 2020 Gediminas Jakutis */ #include #include #include #include #include #include "io.h" #include "defs.h" static char randfile[] = "/dev/urandom"; static struct settings settings = {0}; static struct stream file_in = {.prev_idx = -1, .fd = -1}; static struct stream file_out = {.prev_idx = -1, .fd = -1, .out = 1}; static int parseargs(int argc, char **argv, struct settings * settings); void printhelp(const char * const name); int main(int argc, char **argv) { int ret = 0; try_s((ret = parseargs(argc, argv, &settings)), out); if (settings.opmode == mode_generate) { file_in.name = randfile; file_in.out = -1; file_in.n = settings.to; file_out.n = settings.to; } else { file_in.name = settings.filein; } file_out.name = settings.fileout ? settings.fileout : settings.filein; try_s(( ret = stream_open(&file_in, &settings)) || (ret = stream_open(&file_out, &settings)), out); out: stream_close(&file_in); stream_close(&file_out); return ret; } static int parseargs(int argc, char **argv, struct settings * settings) { struct settings s = {0}; ssize_t i; int ret = 0; if (argc < 2) { goto err; } for (i = 1; i < argc - 1; ++i) { if (!(strcmp(argv[i], "--sort"))) { s.opmode = mode_normal; } else if (!(strcmp(argv[i], "--fetch"))) { s.opmode = mode_fetch; } else if (!(strcmp(argv[i], "--generate"))) { s.opmode = mode_generate; } else if (!(strcmp(argv[i], "--array"))) { s.format = array; } else if (!(strcmp(argv[i], "--list"))) { s.format = list; } else if (!(strcmp(argv[i], "--cache"))) { s.access = cached; } else if (!(strcmp(argv[i], "--no-cache"))) { s.access = direct; } else if (!(strncmp(argv[i], "--position=", 11))) { if (strlen(argv[i]) > 11) { s.ss = strtoul(argv[i] + 11, NULL, 10); } else { goto err; } } else if (!(strncmp(argv[i], "--num=", 6))) { if (strlen(argv[i]) > 6) { s.to = strtoul(argv[i] + 11, NULL, 10); } else { goto err; } } else if (!(strncmp(argv[i], "--out=", 6))) { if (strlen(argv[i]) > 6) { s.fileout = argv[i] + 6; } else { goto err; } } else { goto err; } } if (!strncmp(argv[i], "--", 2)) { goto err; } else { s.filein = argv[i]; } if (!s.fileout) { s.fileout = s.filein; } if (s.opmode == mode_generate) { /* we always generate in-memory for PERFORMANCE */ s.access = cached; if (s.format == list) { /* we need to generate the empty header, too */ ++s.to; } } else if (s.opmode == mode_fetch) { s.to = s.ss + s.to; } s.stride = s.format == list ? sizeof(struct entry_l) : sizeof(struct entry); *settings = s; while (0) { err: ret = EINVAL; printhelp(*argv); } return ret; } void printhelp(const char * const name) { printf( "This is a mergesort program and such\n" "\n" "usage:\t%s [options]\n FILE" "\n" "Options:\n" " --sort sort mode (default)\n" " --fetch do not sort, fetch element(s) instead\n" " --generate generate an input dataset\n" " --array use an array data format (default)\n" " --list use a linked list data format\n" " --[no]-cache cache data in memory (default) or process data in-place\n" " --position= fetch element from position \n" " --num= of elements to fetch/generate\n" " --out= write output to file\n" "\n" "In case more than one same option is provided, the last one take precedence\n" "\n", name); return; }