This commit is contained in:
Your Name 2025-05-04 12:52:17 +03:00
parent ec265a4c23
commit ad0d7d25ff
5 changed files with 171 additions and 109 deletions

16
libmu/file_open.c Normal file
View file

@ -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;
}

9
libmu/file_open.h Normal file
View file

@ -0,0 +1,9 @@
#ifndef _FILE_OPEN_H
#define _FILE_OPEN_H
#include <stdio.h>
#include <string.h>
#include <errno.h>
FILE *file_open(const char *prog, const char *path, const char *mode);
#endif

View file

@ -3,7 +3,8 @@
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
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;

View file

@ -1,89 +0,0 @@
/*#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#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;
}
*/

138
src/shuf.c Normal file
View file

@ -0,0 +1,138 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#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;
}