diff --git a/lab_2/Makefile b/lab_2/Makefile index d2e096a..294e6b9 100644 --- a/lab_2/Makefile +++ b/lab_2/Makefile @@ -1,27 +1,37 @@ -# Makefile CC = gcc CFLAGS = -Wall -Wextra -std=c99 -LDFLAGS = -ldl +LDFLAGS = -# Цель по умолчанию -all: task12 libtextlib.so +# Static build +static: main_static -# Основная программа -task12: task12.c - $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) +main_static: main_static.o textlib_static.o + $(CC) $(CFLAGS) -o $@ main_static.o textlib_static.o -# Динамическая библиотека -libtextlib.so: textlib.c - $(CC) $(CFLAGS) -fPIC -shared -o $@ $< +main_static.o: main_static.c textlib_static.h + $(CC) $(CFLAGS) -c -o $@ main_static.c -# Очистка +textlib_static.o: textlib_static.c textlib_static.h + $(CC) $(CFLAGS) -c -o $@ textlib_static.c + +# Dynamic build +dynamic: main_dynamic libtextlib.so + +main_dynamic: main_dynamic.o + $(CC) $(CFLAGS) -o $@ main_dynamic.o -ldl + +main_dynamic.o: main_dynamic.c + $(CC) $(CFLAGS) -c -o $@ main_dynamic.c + +libtextlib.so: textlib_dynamic.c + $(CC) $(CFLAGS) -fPIC -shared -o $@ textlib_dynamic.c + +# Build both +all: static dynamic + +# Clean clean: - rm -f task12 libtextlib.so input.txt output.txt + rm -f *.o main_static main_dynamic libtextlib.so out.txt + @echo "Cleaned build artifacts." -# Тест -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 +.PHONY: all static dynamic clean \ No newline at end of file diff --git a/lab_2/in.txt b/lab_2/in.txt new file mode 100644 index 0000000..2d15f49 --- /dev/null +++ b/lab_2/in.txt @@ -0,0 +1,5 @@ +abbaabbaabbaabbaabbaabbaabbaabba +xyzx + .. +.. ./. +---- diff --git a/lab_2/main_dynamic.c b/lab_2/main_dynamic.c new file mode 100644 index 0000000..cc2d435 --- /dev/null +++ b/lab_2/main_dynamic.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include + +#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 \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()); fclose(fin); fclose(fout); dlclose(lib); return 1; } + + int total = 0; + char line[MAX_LINE]; + while (fgets(line, sizeof(line), fin) && cap > 0) { + if (line[0] == '\0' || line[0] == '\n') { + fputs(line, fout); + continue; + } + int key = (unsigned char)line[0]; + int repl_line = replace(line + 1, key, &cap); + total += repl_line; + fputc(line[0], fout); + fputs(line + 1, fout); + } + while (fgets(line, sizeof(line), fin)) { + fputs(line, fout); + } + fclose(fin); fclose(fout); + dlclose(lib); + printf("total_replacements: %d\n", total); + return 0; +} \ No newline at end of file diff --git a/lab_2/main_static.c b/lab_2/main_static.c new file mode 100644 index 0000000..c2b645c --- /dev/null +++ b/lab_2/main_static.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include "textlib_static.h" + +#define MAX_LINE 4096 + +int main(int argc, char *argv[]) { + if (argc != 4) { + fprintf(stderr, "Usage: %s \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) && cap > 0) { + if (line[0] == '\0' || line[0] == '\n') { + fputs(line, fout); + continue; + } + int key = (unsigned char)line[0]; + int repl_line = replace_char_line(line + 1, key, &cap); + total += repl_line; + fputc(line[0], fout); + fputs(line + 1, fout); + } + while (fgets(line, sizeof(line), fin)) { + fputs(line, fout); + } + fclose(fin); fclose(fout); + printf("total_replacements: %d\n", total); + return 0; +} \ No newline at end of file diff --git a/lab_2/old/Makefile b/lab_2/old/Makefile new file mode 100644 index 0000000..d2e096a --- /dev/null +++ b/lab_2/old/Makefile @@ -0,0 +1,27 @@ +# 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 diff --git a/lab_2/task12.c b/lab_2/old/task12.c similarity index 100% rename from lab_2/task12.c rename to lab_2/old/task12.c diff --git a/lab_2/textlib.c b/lab_2/old/textlib.c similarity index 100% rename from lab_2/textlib.c rename to lab_2/old/textlib.c diff --git a/lab_2/textlib_dynamic.c b/lab_2/textlib_dynamic.c new file mode 100644 index 0000000..950efc9 --- /dev/null +++ b/lab_2/textlib_dynamic.c @@ -0,0 +1,15 @@ +#include + +int replace_char_line(char *buf, int key, int *replacements_left) { + int replaced = 0; + for (size_t i = 0; buf[i] != '\0'; i++) { + if ((unsigned char)buf[i] == (unsigned char)key && + *replacements_left > 0 && + buf[i] != '\n') { + buf[i] = ' '; + replaced++; + (*replacements_left)--; + } + } + return replaced; +} diff --git a/lab_2/textlib_static.c b/lab_2/textlib_static.c new file mode 100644 index 0000000..c3bba60 --- /dev/null +++ b/lab_2/textlib_static.c @@ -0,0 +1,16 @@ +#include "textlib_static.h" +#include + +int replace_char_line(char *buf, int key, int *replacements_left) { + int replaced = 0; + for (size_t i = 0; buf[i] != '\0'; i++) { + if ((unsigned char)buf[i] == (unsigned char)key && + *replacements_left > 0 && + buf[i] != '\n') { + buf[i] = ' '; + replaced++; + (*replacements_left)--; + } + } + return replaced; +} diff --git a/lab_2/textlib_static.h b/lab_2/textlib_static.h new file mode 100644 index 0000000..239b283 --- /dev/null +++ b/lab_2/textlib_static.h @@ -0,0 +1,6 @@ +#ifndef TEXTLIB_STATIC_H +#define TEXTLIB_STATIC_H + +int replace_char_line(char *buf, int key, int *replacements_left); + +#endif // TEXTLIB_STATIC_H