commit be39097f63ae186a3dc08fc4de7c1116585a2c0d Author: hasslesstech Date: Sat Sep 21 16:39:10 2024 +0300 initial commit diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..44270b2 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +CFLAGS = -I lib/ -O3 -Wall -Werror -Wextra -Wpedantic + +build: src/main.c + mkdir -p bin/ + gcc $(CFLAGS) -o bin/main \ + src/terminal_colors.c \ + src/main.c \ + -lm diff --git a/lib/terminal_colors.h b/lib/terminal_colors.h new file mode 100644 index 0000000..0a9b655 --- /dev/null +++ b/lib/terminal_colors.h @@ -0,0 +1,5 @@ +#define COLOR_RED 1 + +void clear_color(void); + +void set_color(int color_id); diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..5a6fefe --- /dev/null +++ b/src/main.c @@ -0,0 +1,180 @@ +#include +#include +#include + +#include "terminal_colors.h" + +static int +retrieve_double_from_string(double* p_target, + char* p_source) +{ + return sscanf(p_source, "%lf", p_target); +} + +static int +retrieve_inputs_from_argv(char** argv, + double* px, + double* py) +{ + /* + * In binary form, shows which values have + * failed to be read. If specific bit is set, + * the corresponding value has not been read + * correctly. + * + * return code: 00 + * ^^ + * || + * |`- bit 0 represents value of "x" + * | + * `- bit 1 represents value of "y" + */ + int return_code = 0; + + if (1 != retrieve_double_from_string(px, argv[1])) + return_code |= 0x1; + + if (1 != retrieve_double_from_string(py, argv[2])) + return_code |= 0x2; + + return return_code; +} + + +static void +retrieve_double_from_stdin(double* p_target, + char* p_label) +{ + char retrieved_string[128]; + + for (int attempts = 0; attempts < 10000; ++attempts) + { + printf("Enter %s: ", p_label); + + fgets(retrieved_string, 127, stdin); + + int received_args = sscanf(retrieved_string, "%lf", p_target); + + if (1 == received_args) + break; + + puts("Please, try again."); + } +} + +static void +retrieve_inputs_from_stdin(double* px, + double* py) +{ + retrieve_double_from_stdin(px, "x"); + retrieve_double_from_stdin(py, "y"); +} + +static void +calculate_result(double* z1, + double* z2, + double* x, + double* y) +{ + double temp1; + + *z1 = cos(*x); + *z1 = *z1 * *z1 + * *z1 * *z1; + *z1 += sin(2**y); + temp1 = sin(*x/2); + *z1 += temp1 * temp1 + / 4 - 1; + + *z2 = sin(*x + *y); + *z2 += sin(*x - *y); +} + +static void +print_padding(int padding_length) +{ + for (int i = 0; i < padding_length; i++) + { + fputs(" ", stdout); + } +} + +static void +print_argument_error(char** argv, + int argc, + int wrong_argument_index) +{ + fputs("[Error] ", stdout); + + int padding_length = 0; + + for (int i = 0; i < argc; ++i) + { + if (i < wrong_argument_index) + padding_length += strlen(argv[i]) + 1; + } + + for (int i = 0; i < argc; ++i) + { + if (i == wrong_argument_index) + set_color(COLOR_RED); + + fputs(argv[i], stdout); + + if (i == wrong_argument_index) + clear_color(); + + fputs(" ", stdout); + } + + fputs("\n[Error]", stdout); + print_padding(padding_length); + puts(" ^ not a valid (double) value."); +} + +static void +print_error_message(char** argv, + int argc, + int error_code) +{ + puts("[Error] Incorrect CLI argument input."); + + if (error_code & 0x1) + print_argument_error(argv, argc, 1); + + if (error_code & 0x2) + print_argument_error(argv, argc, 2); +} + +int +main(int argc, + char** argv) +{ + double x, + y, + z1, + z2; + + if (3 == argc) + { + int read_errors = retrieve_inputs_from_argv(argv, &x, &y); + + if (read_errors) + { + print_error_message(argv, argc, read_errors); + return 1; + } + } + else + { + retrieve_inputs_from_stdin(&x, &y); + } + + calculate_result(&z1, &z2, &x, &y); + + printf("Results:\nz1 = %.10lf\nz2 = %.10lf\n", z1, z2); + + return 0; +} + + diff --git a/src/terminal_colors.c b/src/terminal_colors.c new file mode 100644 index 0000000..4a1d40b --- /dev/null +++ b/src/terminal_colors.c @@ -0,0 +1,23 @@ +#include + +void +clear_color() +{ + fputs("\033[0m", stdout); +} + +/* + * Color codes: + * 1 - red + */ +void set_color(int color_code) +{ + switch (color_code) + { + case 1: + fputs("\033[31;1m", stdout); + break; + default: + break; + } +}