vlad-refactor

This commit is contained in:
2025-12-10 16:47:58 +07:00
parent 47cfeaddb4
commit cb9d0ac607
26 changed files with 2709 additions and 0 deletions

52
vlad/lab_2/Makefile Normal file
View File

@@ -0,0 +1,52 @@
# 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

35
vlad/lab_2/lib_d.c Normal file
View File

@@ -0,0 +1,35 @@
#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;
}

35
vlad/lab_2/lib_s.c Normal file
View File

@@ -0,0 +1,35 @@
#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;
}

62
vlad/lab_2/main_d.c Normal file
View File

@@ -0,0 +1,62 @@
#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;
}

44
vlad/lab_2/main_s.c Normal file
View File

@@ -0,0 +1,44 @@
#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;
}