From ad0d7d25ff516eb01ba906f3e405d2c97350cbe3 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 4 May 2025 12:52:17 +0300 Subject: [PATCH] fixed --- libmu/file_open.c | 16 ++++++ libmu/file_open.h | 9 +++ src/cmp.c | 28 +++------- src/sh.c | 89 ------------------------------ src/shuf.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 171 insertions(+), 109 deletions(-) create mode 100644 libmu/file_open.c create mode 100644 libmu/file_open.h delete mode 100644 src/sh.c create mode 100644 src/shuf.c diff --git a/libmu/file_open.c b/libmu/file_open.c new file mode 100644 index 0000000..f0fb082 --- /dev/null +++ b/libmu/file_open.c @@ -0,0 +1,16 @@ +#include "file_open.h" + +FILE *file_open(const char *prog, const char *path, const char *mode) { + if (!strcmp(path, "-")) + return stdin; + + FILE *fp = fopen(path, mode); + if (fp == NULL) { + if (prog) + fprintf(stderr, "%s: %s\n", prog, strerror(errno)); + + return NULL; + } + + return fp; +} diff --git a/libmu/file_open.h b/libmu/file_open.h new file mode 100644 index 0000000..6832558 --- /dev/null +++ b/libmu/file_open.h @@ -0,0 +1,9 @@ +#ifndef _FILE_OPEN_H +#define _FILE_OPEN_H + +#include +#include +#include + +FILE *file_open(const char *prog, const char *path, const char *mode); +#endif diff --git a/src/cmp.c b/src/cmp.c index 0b7a26d..a23f909 100644 --- a/src/cmp.c +++ b/src/cmp.c @@ -3,7 +3,8 @@ #include #include #include -static char s_flag; +#include "file_open.h" +static char *s_flag = "cmp"; static int compare(FILE *fp1, FILE *fp2, const char *s1, const char *s2) { if (fp1 == fp2) @@ -29,7 +30,7 @@ static int compare(FILE *fp1, FILE *fp2, const char *s1, const char *s2) { } else if (ch1 != ch2) { - if (!s_flag) + if (s_flag) printf("files differ at byte %zu and line %zu\n", byte, lines); return 1; @@ -55,26 +56,13 @@ static long parse_int(const char *str) { return val; } -static FILE *file_open(const char *path) { - if (!strcmp(path, "-")) - return stdin; - - FILE *fp = fopen(path, "r"); - if (fp == NULL) { - fprintf(stderr, "cmp: %s\n", strerror(errno)); - return NULL; - } - - return fp; -} - int main(int argc, char **argv) { int opt; while ((opt = getopt(argc, argv, "s")) != -1) { switch (opt) { case 's': - s_flag = 1; + s_flag = NULL; break; default: @@ -106,7 +94,7 @@ int main(int argc, char **argv) { case 2: s2 = argv[1]; - fp2 = file_open(argv[1]); + fp2 = file_open(s_flag, argv[1], "r"); if (fp2 == NULL) exit(1); @@ -114,7 +102,7 @@ int main(int argc, char **argv) { case 1: s1 = argv[0]; - fp1 = file_open(argv[0]); + fp1 = file_open(s_flag, argv[0], "r"); if (fp1 == NULL) { fclose(fp2); exit(1); @@ -128,14 +116,14 @@ int main(int argc, char **argv) { } if (skip1 && fseek(fp1, skip1, SEEK_SET) < 0) { - if (!s_flag) + if (s_flag) fprintf(stderr, "cmp: %s\n", strerror(errno)); return 1; } if (skip2 && fseek(fp2, skip2, SEEK_SET) < 0) { - if (!s_flag) + if (s_flag) fprintf(stderr, "cmp: %s\n", strerror(errno)); return 1; diff --git a/src/sh.c b/src/sh.c deleted file mode 100644 index ae8ae14..0000000 --- a/src/sh.c +++ /dev/null @@ -1,89 +0,0 @@ -/*#include -#include -#include -#include -#include -#include "replace.h" - -enum { - NONE, - QUOTE -}; - -typedef { - char **argv; - size_t argc; - - int stdin; - int stdout; - int stderr; -}; - -char **parse(char **str, size_t *size) { - size_t count = 1; - char *p = *str; - - while (*p) { - if (*p == ' ') - count++; - - p++; - } - - char **tok = malloc((count + 1) * sizeof(char *)); - if (tok == NULL) { - fprintf(stderr, "sh: malloc: %s\n", strerror(errno)); - return NULL; - } - - *size = 0; - p = strtok(*str, " \t\n\r\a"); - while (p != NULL) { - tok[*size] = strdup(p); - (*size)++; - - p = strtok(NULL, " \t\n\r\a"); - } - - tok[*size] = NULL; - return tok; -} - -int main(int argc, char **argv) { - int opt; - while ((opt = getopt(argc, argv, "l")) != -1) { - switch (opt) { - case 'l': - break; - - default: - puts("sh [l]\n\t-l Login"); - break; - } - } - - int ret = 1; - - char *string = NULL; - size_t n = 0; - ssize_t bytes = 0; - - while ((bytes = getline(&string, &n, stdin)) > 0) { - size_t size = 0; - char **tok = parse(&string, &size); - - for (size_t i = 0; i < size; i++) - puts(tok[i]); - - clear_parser(tok); - } - - ret = 0; - -CLOSE: - if (string) - free(string); - - return ret; -} -*/ diff --git a/src/shuf.c b/src/shuf.c new file mode 100644 index 0000000..7170106 --- /dev/null +++ b/src/shuf.c @@ -0,0 +1,138 @@ +#include +#include +#include +#include +#include +#include +#include +#include "file_open.h" + +struct STRINGS { + size_t lines; + char **buf; +} str; +size_t n_flag; +FILE *o_flag; + +void free_strings(char print_flag) { + if (str.buf == NULL) + return; + + size_t num = 0; + for (size_t i = 0; i <= str.lines; i++) + if (str.buf[i] != NULL) { + if (print_flag) { + if (n_flag == 0) + fprintf(o_flag, "%s", str.buf[i]); + + else if (num < n_flag) { + size_t r = rand() % str.lines; + fprintf(o_flag, "%s", str.buf[r]); + num++; + } + } + + free(str.buf[i]); + } + + free(str.buf); +} + +static char read_file(FILE *fp) { + char *line = NULL; + ssize_t bytes = 0; + size_t n = 0; + + str.buf = malloc(sizeof(char *)); + if (str.buf == NULL) + goto RF_ERROR; + + while ((bytes = getline(&line, &n, fp)) != -1) { + char **tmp = realloc(str.buf, sizeof(char *) * (str.lines + 2)); + if (tmp == NULL) + goto RF_ERROR; + + str.buf = tmp; + + str.buf[str.lines] = strdup(line); + if (str.buf[str.lines] == NULL) + goto RF_ERROR; + + str.lines++; + + } + + if (line) + free(line); + + return 0; + +RF_ERROR: + fprintf(stderr, "shuf: read file: %s\n", strerror(errno)); + free_strings(0); + return 1; +} + +int main(int argc, char **argv) { + srand(time(NULL)); + o_flag = stdout; + + char *p; + int opt; + while ((opt = getopt(argc, argv, "o:n:")) != -1) { + switch (opt) { + case 'o': + o_flag = file_open("shuf", optarg, "w"); + if (o_flag == NULL) + return 1; + + break; + + case 'n': + n_flag = strtoul(optarg, &p, 10); + break; + + default: + printf("shuf -[on]\n\t-n NUM Output at most NUM lines\n\t-o STR Write to FILE\n"); + return 0; + } + } + + argv += optind; + argc -= optind; + + char *file = argv[0]; + if (argc == 0) + file = "-"; + + FILE *fp = file_open("shuf", file, "r"); + if (fp == NULL) + goto ERROR; + + if (read_file(fp) == 1) + goto ERROR; + + /* Shuf */ + if (n_flag == 0) { + for (size_t i = 0; i < str.lines; i++) { + char *tmp = str.buf[i]; + + size_t r = rand() % str.lines; + str.buf[i] = str.buf[r]; + str.buf[r] = tmp; + } + } + + /* Free and print */ + free_strings(1); + return 0; + +ERROR: + if (o_flag != stdout) + fclose(o_flag); + + if (fp != NULL) + fclose(fp); + + return 1; +}