Use ncurses library
authorLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Sun, 15 Dec 2024 07:20:33 +0000 (08:20 +0100)
committerLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Sun, 15 Dec 2024 08:06:15 +0000 (09:06 +0100)
Every printing function had to be replaced.
Color is handled differently.
A function was commented out, because I did not want to think about how
to integrate it now.

Makefile
inc/FET_sim.h
src/c_addfet.c
src/c_addnode.c
src/colors.c
src/main.c
src/terminal.c
src/text.c

index 1e65f98d6dee65c8ac267daacd317560f4d950a3..9c9e94ab61128ba78b792d55b4cce42258f1f0d8 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 CC := gcc
 CFLAGS := -std=c99 -Wall -Wextra -Werror -Wpedantic
-LDFLAGS := -L Libft -lft
+LDFLAGS := -L Libft -lft -lncurses
 
 ifneq ("$(wildcard .debug)","")
        CFLAGS += -g
index eee311d7aca78f5e3368966ed08e469f170b1e70..6c4a310dde994921cf5d1e71c1dffae75529f513 100644 (file)
@@ -99,8 +99,8 @@ void  add_mosfet(t_vec *mosfets, t_type type);
 void   bind_fet_node(t_mosfet *mosfet, t_node *node, t_terminal terminal);
 
 void   free_node(void *node);
-int            process_input(t_vec *nodes, t_vec *mosfets, int fd);
-int            get_input(t_input *input, int fd);
+int            process_input(t_vec *nodes, t_vec *mosfets);
+int            get_input(t_input *input);
 
 const char     *state_color_escape(t_state state);
 void           draw_single(t_vec *mosfets, size_t i);
@@ -116,6 +116,10 @@ void       command_not_found(const char *input);
 void   print_help(t_command c);
 void   print_index_error(size_t index, size_t size);
 
+int            construct_input(t_input *input, char **split_inp);
+
+void   init_colors(void);
+
 t_state        simple_resolve_state(t_state s1, t_state s2);
 t_state        resolve_state(t_vec *connected_nodes);
 void   apply_state(t_state state, t_vec *connected_nodes);
index cbf77f37dfa40543059b57449def48b7b97226fa..8293552ee6255d82777c90ba359eb1c9cc61685f 100644 (file)
@@ -1,5 +1,6 @@
 #include "FET_sim.h"
 #include "libft.h"
+#include <ncurses.h>
 
 int    c_addfet(t_input input, t_vec *mosfets)
 {
@@ -8,20 +9,20 @@ int   c_addfet(t_input input, t_vec *mosfets)
        if (input.argc == 1 && input.argv[0].type == type)
        {
                add_mosfet(mosfets, input.argv[0].val.type);
-               ft_printf("Index of added FET:\n\t%u ", mosfets->size - 1);
+               printw("Index of added FET:\n\t%lu ", mosfets->size - 1);
        }
        else if (input.argc == 2 && input.argv[0].type == type && input.argv[1].type == num)
        {
                i = 0;
-               ft_printf("Indeces of added FETs:\n\t");
+               printw("Indeces of added FETs:\n\t");
                while (i < input.argv[1].val.num)
                {
-                       ft_printf("%u ", mosfets->size);
+                       printw("%lu ", mosfets->size);
                        add_mosfet(mosfets, input.argv[0].val.type);
                        ++i;
                }
        }
-       ft_printf("\n");
+       printw("\n");
        /*else
                print_wrong_usage(input);*/
        return (1);
index d98efc25ee3e1a1fc2510109ff00f9a87f8d8d6b..a1488490fcf3bb271f01c66360e08cebcf21c1e3 100644 (file)
@@ -1,19 +1,20 @@
 #include "FET_sim.h"
 #include "libft.h"
+#include <ncurses.h>
 
 static int add_nodes(t_vec *nodes, size_t num, t_state state)
 {
        size_t  i;
 
        i = 0;
-       ft_printf("Indexes of added nodes:\n\t");
+       printw("Indexes of added nodes:\n\t");
        while (i < num)
        {
-               ft_printf("%u ", nodes->size);
+               printw("%lu ", nodes->size);
                add_node(nodes, state);
                ++i;
        }
-       ft_printf("\n");
+       printw("\n");
        return (1);
 }
 
index 060031e242960924287bff1ab97fb243b2b57229..7bc7bd73b7e7ab0705017c611f17111c418c8148 100644 (file)
 #include "FET_sim.h"
 #include "libft.h"
+#include <ncurses.h>
 
-// ac stands for ANSI (escape code) color
-const char     g_default_ac[] = "\033[39m";
+typedef enum e_nc_color
+{
+       NC_DEFAULT,
+       NC_RED,
+       NC_GREEN,
+       NC_BLUE,
+}      t_nc_color;
 
-const char     g_red_ac[] = "\033[31m";
-const char     g_green_ac[] = "\033[32m";
-const char     g_blue_ac[] = "\033[34m";
-const char     g_white_ac[] = "\033[97m";
+void   init_colors(void)
+{
+       if (!has_colors())
+               return ;
+       start_color();
+       init_pair(NC_RED, COLOR_RED, COLOR_BLACK);
+       init_pair(NC_GREEN, COLOR_GREEN, COLOR_BLACK);
+       init_pair(NC_BLUE, COLOR_BLUE, COLOR_BLACK);
+       return ;
+}
 
-const char     *state_color_escape(t_state state)
+t_nc_color     get_state_color(t_state state)
 {
-       if (state == on)
-               return (g_green_ac);
-       if (state == off)
-               return (g_white_ac);
-       if (state == floating)
-               return (g_blue_ac);
-       return (g_red_ac);
+       if (state == on || state == pull_up)
+               return (NC_GREEN);
+       else if (state == off || state == pull_down)
+               return (NC_DEFAULT);
+       else if (state == floating)
+               return (NC_BLUE);
+       else
+               return (NC_RED);
 }
 
-void   draw_single(t_vec *mosfets, size_t i)
+static void    print_in_color(const char *str, t_nc_color color)
 {
-       t_mosfet        *mosfet;
+       attron(COLOR_PAIR(color));
+       while (*str)
+               addch(*(str++));
+       attroff(COLOR_PAIR(color));
+       return ;
+}
 
-       mosfet = ft_vec_access(mosfets, i);
+static void    draw_top(t_mosfet *mosfet)
+{
        if (mosfet->source)
        {
-               ft_printf("      %u\n", mosfet->source->id);
-               ft_printf("      %s|%s\n", state_color_escape(mosfet->source->state), g_default_ac);
+               printw("      %lu\n", mosfet->source->id);
+               print_in_color("      |\n", get_state_color(mosfet->source->state));
        }
        else
        {
-               ft_printf("      %sNULL%s\n", g_red_ac, g_default_ac);
-               ft_printf("      %s|%s\n", g_red_ac, g_default_ac);
+               print_in_color("     NULL\n", NC_RED);
+               print_in_color("      |\n", NC_RED);
        }
-       if (mosfet->gate)
+       return ;
+}
+
+static void    draw_switch(t_mosfet *mosfet)
+{
+       t_nc_color      color;
+
+       if (!mosfet->gate || !mosfet->is_opened)
        {
-               if (mosfet->is_opened && should_open(mosfet->type, mosfet->gate->state))
-                       ft_printf("%4u%s-%s%c%s|%s\n", mosfet->gate->id, state_color_escape(mosfet->gate->state), g_default_ac, mosfet->type, state_color_escape(mosfet->source->state), g_default_ac);
-               else if (should_open(mosfet->type, mosfet->gate->state))
-                       ft_printf("%4u%s-%s%c\\\n", mosfet->gate->id, state_color_escape(mosfet->gate->state), g_default_ac, mosfet->type);
-               else if (mosfet->is_opened)
-                       ft_printf("%4u%s-%s%c%s\\%s\n", mosfet->gate->id, state_color_escape(mosfet->gate->state), g_default_ac, mosfet->type, state_color_escape(mosfet->source->state), g_default_ac);
+               if (mosfet->gate && should_open(mosfet->type, mosfet->gate->state))
+                       addch('\\');
                else
-                       ft_printf("%4u%s-%s%c-\n", mosfet->gate->id, state_color_escape(mosfet->gate->state), g_default_ac, mosfet->type);
+                       addch('-');
        }
-       else
-               ft_printf("%sNULL--%s%c\n", g_red_ac, g_default_ac, mosfet->type);
-       if (mosfet->drain)
+       else if (mosfet->is_opened)
        {
-               ft_printf("      %s|%s\n", state_color_escape(mosfet->drain->state), g_default_ac);
-               ft_printf("      %u\n\n", mosfet->drain->id);
+               if (mosfet->source)
+                       color = get_state_color(mosfet->source->state);
+               else if (mosfet->drain)
+                       color = get_state_color(mosfet->drain->state);
+               else
+                       color = NC_RED;
+               if (should_open(mosfet->type, mosfet->gate->state))
+                       print_in_color("|", color);
+               else
+                       print_in_color("\\", color);
        }
-       else
+       return ;
+}
+
+static void    draw_middle(t_mosfet *mosfet)
+{
+       if (mosfet->gate)
        {
-               ft_printf("      %s|%s\n", g_red_ac, g_default_ac);
-               ft_printf("      %sNULL%s\n\n", g_red_ac, g_default_ac);
+               printw("%4lu", mosfet->gate->id);
+               print_in_color("-", get_state_color(mosfet->gate->state));
        }
-       ++i;
+       else
+               print_in_color("NULL-", NC_RED);
+       addch(mosfet->type);
+       draw_switch(mosfet);
+       addch('\n');
+       return ;
+}
+
+static void    draw_bottom(t_mosfet *mosfet)
+{
+       printw("      ");
+       if (mosfet->drain)
+               print_in_color("|\n", get_state_color(mosfet->drain->state));
+       else
+               print_in_color("|\n", NC_RED);
+       if (mosfet->drain)
+               printw("      %lu", mosfet->drain->id);
+       else
+               print_in_color("     NULL", NC_RED);
+       printw("\n\n");
+       return ;
+}
+
+void   draw_single(t_vec *mosfets, size_t i)
+{
+       t_mosfet        *mosfet;
+
+       mosfet = ft_vec_access(mosfets, i);
+       draw_top(mosfet);
+       draw_middle(mosfet);
+       draw_bottom(mosfet);
 }
index bfcdeb4ae94a6dd027b7086d6434edbfcf164f10..8cd78d801192cae7d413881f6b2ddfb3a752d134 100644 (file)
@@ -4,6 +4,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 
+/*
 void   build_graph(const char *filename, t_vec *nodes, t_vec *mosfets)
 {
        int     fd;
@@ -11,7 +12,7 @@ void  build_graph(const char *filename, t_vec *nodes, t_vec *mosfets)
        fd = open(filename, O_RDONLY);
        if (fd >= 0)
        {
-               while (process_input(nodes, mosfets, fd));
+               while (process_input(nodes, mosfets));
                close(fd);
        }
        else
@@ -20,6 +21,7 @@ void  build_graph(const char *filename, t_vec *nodes, t_vec *mosfets)
        }
        return ;
 }
+*/
 
 void   free_node(void *node)
 {
@@ -27,20 +29,6 @@ void free_node(void *node)
        return ;
 }
 
-void   free_split(char **sp)
-{
-       size_t  i;
-
-       i = 0;
-       while (sp[i])
-       {
-               free(sp[i]);
-               ++i;
-       }
-       free(sp);
-       return ;
-}
-
 size_t split_length(char **sp)
 {
        size_t  i;
@@ -197,6 +185,8 @@ int construct_input(t_input *input, char **split_inp)
        size_t  i;
        t_input tmp;
 
+       if (!split_inp || !split_inp[0])
+               return (1);
        tmp.argc = split_length(split_inp) - 1;
        if (!parse_command(split_inp[0], &tmp.command))
                return (0);
@@ -213,44 +203,12 @@ int       construct_input(t_input *input, char **split_inp)
        return (1);
 }
 
-int    get_input(t_input *input, int fd)
-{
-       int             res;
-       char    *str_inp;
-       char    **split_inp;
-
-       str_inp = get_next_line(fd);
-       if (!str_inp)
-       {
-               input->command = exitsim;
-               input->argc = 0;
-               return (1);
-       }
-       if (str_inp[0] == '\n')
-       {
-               free(str_inp);
-               return (1);
-       }
-       if (str_inp[0] && str_inp[ft_strlen(str_inp) - 1] == '\n')
-               str_inp[ft_strlen(str_inp) - 1] = '\0';
-       split_inp = ft_split(str_inp, " ");
-       res = construct_input(input, split_inp);
-       if (!res)
-       {
-               command_not_found(str_inp);
-       }
-       free(str_inp);
-       free_split(split_inp);
-       return (res);
-}
-
-int    process_input(t_vec *nodes, t_vec *mosfets, int fd)
+int    process_input(t_vec *nodes, t_vec *mosfets)
 {
        int                             res;
        static t_input  input = {.command = help, .argc = 0};
 
-       ft_printf("FET_sim> ");
-       if (!get_input(&input, fd))
+       if (!get_input(&input))
                return (1);
        res = 1;
        if (input.command == next)
@@ -277,23 +235,22 @@ void      cleanup(t_vec *nodes, t_vec *mosfets)
        update_nodes(NULL);
        ft_vec_free(nodes, free_node);
        ft_vec_free(mosfets, NULL);
-       get_next_line(-1);
        clean_terminal();
        return ;
 }
 
-int    main(int argc, char **argv)
+int    main(void)
 {
        t_vec   nodes;
        t_vec   mosfets;
 
-       setup_terminal();
-       print_start();
        ft_vec_init(&nodes, sizeof(t_node));
        ft_vec_init(&mosfets, sizeof(t_mosfet));
-       if (argc > 1)
-               build_graph(argv[1], &nodes, &mosfets);
-       while (process_input(&nodes, &mosfets, STDIN_FILENO));
+       setup_terminal();
+       print_start();
+       //if (argc > 1)
+       //      build_graph(argv[1], &nodes, &mosfets);
+       while (process_input(&nodes, &mosfets));
        cleanup(&nodes, &mosfets);
        return (0);
 }
index d1252a6c23feedbbcf17224dcead59ce47471201..3c7a2cc06b8b0080b356892d3dfccd23541de055 100644 (file)
@@ -1,18 +1,65 @@
 #include "FET_sim.h"
 #include "libft.h"
+#include <ncurses.h>
+#include <stdlib.h>
 
-static const char      alt_term_on[] = "\033[?1049h";
-static const char      alt_term_off[] = "\033[?1049l";
+#define INPUT_BUFFER_SIZE 100
 
 void   setup_terminal(void)
 {
-       ft_printf("%s", alt_term_on);
-       ft_printf("\033[H");
+       initscr();
+       init_colors();
+       keypad(stdscr, TRUE);
+       nonl();
+       cbreak();
+       echo();
+       scrollok(stdscr, TRUE);
+}
+
+void   free_split(char **sp)
+{
+       size_t  i;
+
+       i = 0;
+       while (sp[i])
+       {
+               free(sp[i]);
+               ++i;
+       }
+       free(sp);
        return ;
 }
 
+int    get_input(t_input *input)
+{
+       int             res;
+       char    str_inp[INPUT_BUFFER_SIZE + 1];
+       char    **split_inp;
+
+       addstr("FET_sim> ");
+       if (getnstr(str_inp, INPUT_BUFFER_SIZE) == ERR)
+       {
+               input->command = exitsim;
+               input->argc = 0;
+               return (1);
+       }
+       if (str_inp[0] == '\n')
+               return (1);
+       if (str_inp[0] && str_inp[ft_strlen(str_inp) - 1] == '\n')
+               str_inp[ft_strlen(str_inp) - 1] = '\0';
+       split_inp = ft_split(str_inp, " ");
+       res = construct_input(input, split_inp);
+       if (!res)
+       {
+               command_not_found(str_inp);
+       }
+       free_split(split_inp);
+       return (res);
+}
+
+
 void   clean_terminal(void)
 {
-       ft_printf("%s", alt_term_off);
+       endwin();
        return ;
 }
index b46ca15ba5aa94b6feabe85c1fd9306d143f7588..eeed0f2f9fabf138eff3128575404e7fc759f49b 100644 (file)
@@ -1,5 +1,6 @@
 #include "FET_sim.h"
 #include "libft.h"
+#include <ncurses.h>
 
 static const char      g_version_str[] = "0.0";
 
@@ -72,35 +73,35 @@ static const char   g_general_help_str[] = ""
 void   print_help(t_command c)
 {
        if (c == next)
-               ft_printf(g_next_help_str);
+               printw(g_next_help_str);
        else if (c == draw)
-               ft_printf(g_draw_help_str);
+               printw(g_draw_help_str);
        else if (c == setnode)
-               ft_printf(g_setnode_help_str);
+               printw(g_setnode_help_str);
        else if (c == addnode)
-               ft_printf(g_addnode_help_str);
+               printw(g_addnode_help_str);
        else if (c == addfet)
-               ft_printf(g_addfet_help_str);
+               printw(g_addfet_help_str);
        else if (c == bind)
-               ft_printf(g_bind_help_str);
+               printw(g_bind_help_str);
        else if (c == help)
-               ft_printf(g_help_help_str);
+               printw(g_help_help_str);
        else if (c == exitsim)
-               ft_printf(g_help_exit_str);
+               printw(g_help_exit_str);
        else
-               ft_printf(g_general_help_str, g_version_str);
+               printw(g_general_help_str, g_version_str);
        return ;
 }
 
 void   command_not_found(const char *input)
 {
-       ft_printf("The command \"%s\" is not a proper FET_sim command.\n", input);
+       printw("The command \"%s\" is not a proper FET_sim command.\n", input);
        return ;
 }
 
 void   print_start(void)
 {
-       ft_printf("FET_sim, version %s\n"
+       printw("FET_sim, version %s\n"
                        "FET_sim is a simulator of FET logic.\n"
                        "If you need some guidence, use the \"help\" command.\n",
                        g_version_str);
@@ -111,13 +112,13 @@ void      print_index_error(size_t index, size_t size)
 {
        if (size > 0)
        {
-               ft_printf("This action is invalid as given index %u "
-                       "is larger then the highest index present %u.\n",
+               printw("This action is invalid as given index %lu "
+                       "is larger then the highest index present %lu.\n",
                        index, size - 1);
        }
        else
        {
-               ft_printf("This action is invalid as there is no element yet.\n");
+               printw("This action is invalid as there is no element yet.\n");
        }
        return ;
 }