cleanup
This commit is contained in:
@@ -1,52 +0,0 @@
|
||||
# Makefile
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -Wextra -O2
|
||||
PICFLAGS = -fPIC
|
||||
|
||||
.PHONY: all dynamic static test-dynamic test-static clean
|
||||
|
||||
all: dynamic static
|
||||
|
||||
# --- Dynamic (shared) build ---
|
||||
dynamic: libtext.so main_d
|
||||
|
||||
libtext.so: lib_d.o
|
||||
$(CC) -shared -o $@ $^
|
||||
|
||||
main_d: main_d.o
|
||||
$(CC) -o $@ $^ -ldl
|
||||
|
||||
lib_d.o: lib_d.c
|
||||
$(CC) $(CFLAGS) $(PICFLAGS) -c $< -o $@
|
||||
|
||||
# --- Static build ---
|
||||
static: libtext.a main_s
|
||||
|
||||
libtext.a: lib_s.o
|
||||
ar rcs $@ $^
|
||||
|
||||
main_s: main_s.o libtext.a
|
||||
$(CC) -o $@ main_s.o libtext.a
|
||||
|
||||
# Generic rule for other .o files
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
# --- Test targets ---
|
||||
# Creates a small `test_input.txt`, runs the program, and shows `out.txt`
|
||||
test-dynamic: dynamic
|
||||
printf "Hello123456789\nLine2abc\n" > test_input.txt
|
||||
./main_d test_input.txt out.txt 100 ./libtext.so
|
||||
@echo "---- out.txt ----"
|
||||
cat out.txt
|
||||
|
||||
test-static: static
|
||||
printf "Hello123456789\nLine2abc\n" > test_input.txt
|
||||
./main_s test_input.txt out.txt 100
|
||||
@echo "---- out.txt ----"
|
||||
cat out.txt
|
||||
|
||||
# --- Cleanup ---
|
||||
clean:
|
||||
rm -f *.o *.so *.a main_d main_s test_input.txt out.txt
|
||||
@@ -1,18 +0,0 @@
|
||||
#include <string.h>
|
||||
|
||||
int replace_char_line(char *buf, int key, int *replacements_left) {
|
||||
(void)key;
|
||||
int replaced = 0;
|
||||
int count = 0;
|
||||
|
||||
for (size_t i = 0; buf[i] != '\0'; i++) {
|
||||
if (buf[i] == '\n') continue;
|
||||
count++;
|
||||
if (count % 3 == 0 && *replacements_left > 0) {
|
||||
buf[i] = ' ';
|
||||
replaced++;
|
||||
(*replacements_left)--;
|
||||
}
|
||||
}
|
||||
return replaced;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
#include <stddef.h>
|
||||
|
||||
int replace_char_line(char *buf, int key, int *replacements_left) {
|
||||
(void)key;
|
||||
int replaced = 0;
|
||||
int count = 0;
|
||||
|
||||
for (size_t i = 0; buf[i] != '\0'; i++) {
|
||||
if (buf[i] == '\n') continue;
|
||||
count++;
|
||||
if (count % 3 == 0 && *replacements_left > 0) {
|
||||
buf[i] = ' ';
|
||||
replaced++;
|
||||
(*replacements_left)--;
|
||||
if (*replacements_left == 0) break;
|
||||
}
|
||||
}
|
||||
return replaced;
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#define MAX_LINE 4096
|
||||
|
||||
typedef int (*replace_func_t)(char*, int, int*);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc != 5) {
|
||||
fprintf(stderr, "Usage: %s <in> <out> <cap> <path_to_so>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
FILE *fin = fopen(argv[1], "r");
|
||||
if (!fin) { perror("fopen input"); return 1; }
|
||||
FILE *fout = fopen(argv[2], "w");
|
||||
if (!fout) { perror("fopen output"); fclose(fin); return 1; }
|
||||
|
||||
int cap = atoi(argv[3]);
|
||||
if (cap < 0) {
|
||||
fprintf(stderr, "invalid cap\n");
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void *lib = dlopen(argv[4], RTLD_LAZY);
|
||||
if (!lib) {
|
||||
fprintf(stderr, "dlopen error: %s\n", dlerror());
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
replace_func_t replace = (replace_func_t)dlsym(lib, "replace_char_line");
|
||||
if (!replace) {
|
||||
fprintf(stderr, "dlsym error: %s\n", dlerror());
|
||||
dlclose(lib);
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int total = 0;
|
||||
char line[MAX_LINE];
|
||||
|
||||
while (fgets(line, sizeof(line), fin)) {
|
||||
if (cap > 0) {
|
||||
int key = (unsigned char)line[0];
|
||||
int repl_line = replace(line, key, &cap);
|
||||
total += repl_line;
|
||||
}
|
||||
fputs(line, fout);
|
||||
}
|
||||
|
||||
dlclose(lib);
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
printf("total_replacements: %d\n", total);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAX_LINE 4096
|
||||
|
||||
int replace_char_line(char *buf, int key, int *replacements_left);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc != 4) {
|
||||
fprintf(stderr, "Usage: %s <in> <out> <cap>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
FILE *fin = fopen(argv[1], "r");
|
||||
if (!fin) { perror("fopen input"); return 1; }
|
||||
FILE *fout = fopen(argv[2], "w");
|
||||
if (!fout) { perror("fopen output"); fclose(fin); return 1; }
|
||||
|
||||
int cap = atoi(argv[3]);
|
||||
if (cap < 0) {
|
||||
fprintf(stderr, "invalid cap\n");
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int total = 0;
|
||||
char line[MAX_LINE];
|
||||
|
||||
while (fgets(line, sizeof(line), fin)) {
|
||||
if (cap > 0) {
|
||||
// key is unused, but pass the first byte for symmetry
|
||||
int key = (unsigned char)line[0];
|
||||
int repl_line = replace_char_line(line, key, &cap);
|
||||
total += repl_line;
|
||||
}
|
||||
fputs(line, fout);
|
||||
}
|
||||
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
printf("total_replacements: %d\n", total);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
# Makefile
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -Wextra -std=c99
|
||||
LDFLAGS = -ldl
|
||||
|
||||
# Цель по умолчанию
|
||||
all: task12 libtextlib.so
|
||||
|
||||
# Основная программа
|
||||
task12: task12.c
|
||||
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
|
||||
|
||||
# Динамическая библиотека
|
||||
libtextlib.so: textlib.c
|
||||
$(CC) $(CFLAGS) -fPIC -shared -o $@ $<
|
||||
|
||||
# Очистка
|
||||
clean:
|
||||
rm -f task12 libtextlib.so input.txt output.txt
|
||||
|
||||
# Тест
|
||||
test: all
|
||||
echo -e "Hello world\ntest line\nanother" > input.txt
|
||||
./task12 input.txt output.txt 5 ./libtextlib.so
|
||||
cat output.txt
|
||||
|
||||
.PHONY: all clean test
|
||||
@@ -1,96 +0,0 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#define RBUFSZ 4096
|
||||
#define WBUFSZ 4096
|
||||
|
||||
static void die_perror(const char *what, const char *path, int exit_code) {
|
||||
int saved = errno;
|
||||
char msg[512];
|
||||
if (path) {
|
||||
snprintf(msg, sizeof(msg), "%s: %s: %s\n", what, path, strerror(saved));
|
||||
} else {
|
||||
snprintf(msg, sizeof(msg), "%s: %s\n", what, strerror(saved));
|
||||
}
|
||||
(void) write(STDERR_FILENO, msg, strlen(msg));
|
||||
_exit(exit_code);
|
||||
}
|
||||
|
||||
static long long parse_ll(const char *s) {
|
||||
char *end = NULL;
|
||||
errno = 0;
|
||||
long long v = strtoll(s, &end, 10);
|
||||
if (errno != 0 || end == s || *end != '\0' || v < 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc != 5) {
|
||||
const char *usage =
|
||||
"Usage: lab2_var12 <input.txt> <output.txt> <max_replacements> <library.so>\n"
|
||||
"Variant 12: Load text processing library dynamically and process file.\n"
|
||||
"Library should provide 'process_text' function.\n";
|
||||
(void) write(STDERR_FILENO, usage, strlen(usage));
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *in_path = argv[1];
|
||||
const char *out_path = argv[2];
|
||||
long long cap = parse_ll(argv[3]);
|
||||
const char *lib_path = argv[4];
|
||||
|
||||
if (cap < 0) {
|
||||
die_perror("invalid max_replacements", argv[3], -1);
|
||||
}
|
||||
|
||||
// Динамически загружаем библиотеку
|
||||
void *lib_handle = dlopen(lib_path, RTLD_LAZY);
|
||||
if (!lib_handle) {
|
||||
const char *error_msg = dlerror();
|
||||
char msg[512];
|
||||
snprintf(msg, sizeof(msg), "dlopen failed: %s\n", error_msg ? error_msg : "unknown error");
|
||||
(void) write(STDERR_FILENO, msg, strlen(msg));
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Получаем указатель на функцию обработки текста
|
||||
long long (*process_text)(const char*, const char*, long long) =
|
||||
(long long (*)(const char*, const char*, long long)) dlsym(lib_handle, "process_text");
|
||||
|
||||
if (!process_text) {
|
||||
const char *error_msg = dlerror();
|
||||
char msg[512];
|
||||
snprintf(msg, sizeof(msg), "dlsym failed: %s\n", error_msg ? error_msg : "unknown error");
|
||||
(void) write(STDERR_FILENO, msg, strlen(msg));
|
||||
dlclose(lib_handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Вызываем функцию из библиотеки
|
||||
long long result = process_text(in_path, out_path, cap);
|
||||
|
||||
if (result < 0) {
|
||||
die_perror("process_text failed", NULL, -1);
|
||||
}
|
||||
|
||||
// Закрываем библиотеку
|
||||
dlclose(lib_handle);
|
||||
|
||||
// Выводим результат
|
||||
char res[64];
|
||||
int m = snprintf(res, sizeof(res), "%lld\n", result);
|
||||
if (m > 0) {
|
||||
(void) write(STDOUT_FILENO, res, (size_t) m);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define RBUFSZ 4096
|
||||
#define WBUFSZ 4096
|
||||
|
||||
// Функция обработки текста
|
||||
long long process_text(const char *in_path, const char *out_path, long long cap) {
|
||||
int in_fd = open(in_path, O_RDONLY);
|
||||
if (in_fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
mode_t filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
|
||||
int out_fd = open(out_path, O_CREAT | O_WRONLY | O_TRUNC, filePerms);
|
||||
if (out_fd < 0) {
|
||||
close(in_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char rbuf[RBUFSZ];
|
||||
char wbuf[WBUFSZ];
|
||||
size_t wlen = 0;
|
||||
|
||||
long long total_replacements = 0;
|
||||
int at_line_start = 1;
|
||||
unsigned char line_key = 0;
|
||||
int replacing_enabled = 1;
|
||||
|
||||
for (;;) {
|
||||
ssize_t n = read(in_fd, rbuf, sizeof(rbuf));
|
||||
if (n > 0) {
|
||||
for (ssize_t i = 0; i < n; i++) {
|
||||
unsigned char c = (unsigned char) rbuf[i];
|
||||
|
||||
if (at_line_start) {
|
||||
line_key = c;
|
||||
at_line_start = 0;
|
||||
}
|
||||
|
||||
unsigned char outc = c;
|
||||
if (c == '\n') {
|
||||
at_line_start = 1;
|
||||
} else if (replacing_enabled && c == line_key) {
|
||||
if (total_replacements < cap) {
|
||||
outc = ' ';
|
||||
total_replacements++;
|
||||
if (total_replacements == cap) {
|
||||
replacing_enabled = 0;
|
||||
}
|
||||
} else {
|
||||
replacing_enabled = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (wlen == sizeof(wbuf)) {
|
||||
ssize_t wrote = write(out_fd, wbuf, wlen);
|
||||
if (wrote < 0 || (size_t) wrote != wlen) {
|
||||
close(in_fd);
|
||||
close(out_fd);
|
||||
return -1;
|
||||
}
|
||||
wlen = 0;
|
||||
}
|
||||
wbuf[wlen++] = (char) outc;
|
||||
}
|
||||
} else if (n == 0) {
|
||||
if (wlen > 0) {
|
||||
ssize_t wrote = write(out_fd, wbuf, wlen);
|
||||
if (wrote < 0 || (size_t) wrote != wlen) {
|
||||
close(in_fd);
|
||||
close(out_fd);
|
||||
return -1;
|
||||
}
|
||||
wlen = 0;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
close(in_fd);
|
||||
close(out_fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
close(in_fd);
|
||||
close(out_fd);
|
||||
|
||||
return total_replacements;
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
# Makefile
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -Wextra -O2
|
||||
PICFLAGS = -fPIC
|
||||
|
||||
.PHONY: all dynamic static test-dynamic test-static clean
|
||||
|
||||
all: dynamic static
|
||||
|
||||
# --- Dynamic (shared) build ---
|
||||
dynamic: libtext.so main_d
|
||||
|
||||
libtext.so: lib_d.o
|
||||
$(CC) -shared -o $@ $^
|
||||
|
||||
main_d: main_d.o
|
||||
$(CC) -o $@ $^ -ldl
|
||||
|
||||
lib_d.o: lib_d.c
|
||||
$(CC) $(CFLAGS) $(PICFLAGS) -c $< -o $@
|
||||
|
||||
# --- Static build ---
|
||||
static: libtext.a main_s
|
||||
|
||||
libtext.a: lib_s.o
|
||||
ar rcs $@ $^
|
||||
|
||||
main_s: main_s.o libtext.a
|
||||
$(CC) -o $@ main_s.o libtext.a
|
||||
|
||||
# Generic rule for other .o files
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
# --- Test targets ---
|
||||
# Creates a small `test_input.txt`, runs the program, and shows `out.txt`
|
||||
test-dynamic: dynamic
|
||||
printf "Hello123456789\n!!@@2211122\n" > test_input.txt
|
||||
./main_d test_input.txt out.txt 100 ./libtext.so
|
||||
@echo "---- out.txt ----"
|
||||
cat out.txt
|
||||
|
||||
test-static: static
|
||||
printf "Hello123456789\n!!@@2211122\n" > test_input.txt
|
||||
./main_s test_input.txt out.txt 100
|
||||
@echo "---- out.txt ----"
|
||||
cat out.txt
|
||||
|
||||
# --- Cleanup ---
|
||||
clean:
|
||||
rm -f *.o *.so *.a main_d main_s test_input.txt out.txt
|
||||
@@ -1,35 +0,0 @@
|
||||
#include <stddef.h>
|
||||
|
||||
int replace_char(char *buf, int key, int *replacements_left) {
|
||||
(void)key;
|
||||
int replaced = 0;
|
||||
size_t i = 0;
|
||||
|
||||
while (buf[i] != '\0') {
|
||||
if (buf[i] == '\n') {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Detect start of a symbol run
|
||||
char symbol = buf[i];
|
||||
size_t run_start = i;
|
||||
size_t run_len = 1;
|
||||
|
||||
// Count length of run
|
||||
while (buf[i + run_len] == symbol && buf[i + run_len] != '\n' && buf[i + run_len] != '\0') {
|
||||
run_len++;
|
||||
}
|
||||
|
||||
// For pairs and longer runs: replace every 2nd, 4th, ...
|
||||
for (size_t j = 1; j < run_len && *replacements_left > 0; j += 2) {
|
||||
buf[run_start + j] = ' ';
|
||||
replaced++;
|
||||
(*replacements_left)--;
|
||||
if (*replacements_left == 0) break;
|
||||
}
|
||||
|
||||
i += run_len;
|
||||
}
|
||||
return replaced;
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
#include <stddef.h>
|
||||
|
||||
int replace_char(char *buf, int key, int *replacements_left) {
|
||||
(void)key;
|
||||
int replaced = 0;
|
||||
size_t i = 0;
|
||||
|
||||
while (buf[i] != '\0') {
|
||||
if (buf[i] == '\n') {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Detect start of a symbol run
|
||||
char symbol = buf[i];
|
||||
size_t run_start = i;
|
||||
size_t run_len = 1;
|
||||
|
||||
// Count length of run
|
||||
while (buf[i + run_len] == symbol && buf[i + run_len] != '\n' && buf[i + run_len] != '\0') {
|
||||
run_len++;
|
||||
}
|
||||
|
||||
// For pairs and longer runs: replace every 2nd, 4th, ...
|
||||
for (size_t j = 1; j < run_len && *replacements_left > 0; j += 2) {
|
||||
buf[run_start + j] = ' ';
|
||||
replaced++;
|
||||
(*replacements_left)--;
|
||||
if (*replacements_left == 0) break;
|
||||
}
|
||||
|
||||
i += run_len;
|
||||
}
|
||||
return replaced;
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#define MAX_LINE 4096
|
||||
|
||||
typedef int (*replace_func_t)(char*, int, int*);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc != 5) {
|
||||
fprintf(stderr, "Usage: %s <in> <out> <cap> <path_to_so>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
FILE *fin = fopen(argv[1], "r");
|
||||
if (!fin) { perror("fopen input"); return 1; }
|
||||
FILE *fout = fopen(argv[2], "w");
|
||||
if (!fout) { perror("fopen output"); fclose(fin); return 1; }
|
||||
|
||||
int cap = atoi(argv[3]);
|
||||
if (cap < 0) {
|
||||
fprintf(stderr, "invalid cap\n");
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void *lib = dlopen(argv[4], RTLD_LAZY);
|
||||
if (!lib) {
|
||||
fprintf(stderr, "dlopen error: %s\n", dlerror());
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
replace_func_t replace = (replace_func_t)dlsym(lib, "replace_char");
|
||||
if (!replace) {
|
||||
fprintf(stderr, "dlsym error: %s\n", dlerror());
|
||||
dlclose(lib);
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int total = 0;
|
||||
char line[MAX_LINE];
|
||||
|
||||
while (fgets(line, sizeof(line), fin)) {
|
||||
if (cap > 0) {
|
||||
int key = (unsigned char)line[0];
|
||||
int repl_line = replace(line, key, &cap);
|
||||
total += repl_line;
|
||||
}
|
||||
fputs(line, fout);
|
||||
}
|
||||
|
||||
dlclose(lib);
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
printf("total_replacements: %d\n", total);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAX_LINE 4096
|
||||
|
||||
int replace_char(char *buf, int key, int *replacements_left);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc != 4) {
|
||||
fprintf(stderr, "Usage: %s <in> <out> <cap>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
FILE *fin = fopen(argv[1], "r");
|
||||
if (!fin) { perror("fopen input"); return 1; }
|
||||
FILE *fout = fopen(argv[2], "w");
|
||||
if (!fout) { perror("fopen output"); fclose(fin); return 1; }
|
||||
|
||||
int cap = atoi(argv[3]);
|
||||
if (cap < 0) {
|
||||
fprintf(stderr, "invalid cap\n");
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int total = 0;
|
||||
char line[MAX_LINE];
|
||||
|
||||
while (fgets(line, sizeof(line), fin)) {
|
||||
if (cap > 0) {
|
||||
// key is unused, but pass the first byte for symmetry
|
||||
int key = (unsigned char)line[0];
|
||||
int repl_line = replace_char(line, key, &cap);
|
||||
total += repl_line;
|
||||
}
|
||||
fputs(line, fout);
|
||||
}
|
||||
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
printf("total_replacements: %d\n", total);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user