I wrote an app to recreate the matrix digital rain of the movie. It works ok if I set N_DROPS
to low number (5). If I set it to (10), the characters start to flicker and if I set it to 15, I get a segfault. I tried to you valgrind but it seems that I could not install it properly on my MacOS 11.6.1. What is the origin of the problem, I could I diagnose it with print statements and how can I solve it?
Here is the code:
/*matrix_digital_rain.c*/
#include <curses.h>
#include <unistd.h>
#include <locale.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include "set_characters.h"
#include "hyperparameters.h"
#include "functions.h"
int main() {
srand((unsigned) time(NULL)); // Initialization, should only be called once.
setlocale(LC_ALL, "");
int max_y = 0, max_x = 0;
Drop_init_vals drop_init_vals_array[N_DROPS] ;
for (int drop_num = 0; drop_num < N_DROPS; drop_num++){
drop_init_vals_array[drop_num] = drop_init_vals_array_to_zero(drop_init_vals_array[drop_num]);
drop_init_vals_array[drop_num].rand_iter_start = rand() % ITER_START_RANGE;
}
int iter = 0;
initscr();
noecho();
curs_set(FALSE);
start_color();
init_color(CUSTOM_GREEN1, 90, 280, 90);
init_color(CUSTOM_GREEN2, 100, 500, 100);
init_color(CUSTOM_GREEN3, 100, 900, 100);
init_color(COLOR_BLACK, 0, 0, 0);
char char_set[DIM_1_ARRAY_STRING][BYTES_PER_CHAR] = {SET_CHAR};
char str_display[DIM_0_ARRAY_STRING][DIM_1_ARRAY_STRING][BYTES_PER_CHAR];
for (int i = 0; i<DIM_0_ARRAY_STRING; i++){
for (int j = 0; j<DIM_1_ARRAY_STRING; j++){
strcpy(str_display[i][j], char_set[rand() % N_COMMAS]);
}
}
while(1)
{
getmaxyx(stdscr, max_y, max_x);
clear();
for (int drop_num = 0; drop_num<N_DROPS; drop_num++){
if (iter % ITER_REFRESH == drop_init_vals_array[drop_num].rand_iter_start){
drop_init_vals_array[drop_num].n_dim_str = drop_num;
drop_init_vals_array[drop_num].x1 = rand() % X1_RANGE;
drop_init_vals_array[drop_num].n_string = 20 + rand() % N_STRING_RANGE;
drop_init_vals_array[drop_num].iter_init = iter;
drop_init_vals_array[drop_num].rand_iter_start_bool = 1;
}
if(drop_init_vals_array[drop_num].rand_iter_start_bool == 1){
print_n_string_from_string_array_struct(
drop_init_vals_array[drop_num],
str_display,
iter
);
if (iter == drop_init_vals_array[drop_num].iter_init + ITER_REFRESH){
drop_init_vals_array[drop_num].rand_iter_start_bool = 0;
}
}
}
iter++;
refresh();
usleep(DELAY);
}
attron(COLOR_PAIR(1));
attron(COLOR_PAIR(2));
attron(COLOR_PAIR(3));
endwin();
refresh();
use_default_colors();
}
/*functions.h*/
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
typedef struct {
int x1, y1, n_string, n_dim_str, iter_init, rand_iter_start, rand_iter_start_bool;
} Drop_init_vals ;
void print_n_string_from_string_array_struct(Drop_init_vals drop_init_vals, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR], int iter);
Drop_init_vals random_drop_init_vals(Drop_init_vals drop_init_vals);
Drop_init_vals drop_init_vals_to_zero(void);
void print_GREEN1(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR]);
void print_GREEN2(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR]);
void print_GREEN3(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR]);
Drop_init_vals drop_init_vals_array_to_zero(Drop_init_vals drop_init_vals);
#endif
/*functions.c*/
#include "hyperparameters.h"
#include "functions.h"
#include <curses.h>
#include <time.h>
#include <stdlib.h>
void print_GREEN1(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR])
{
init_pair(1, CUSTOM_GREEN1, COLOR_BLACK);
attron(COLOR_PAIR(1));
mvprintw(y1+i-n_string, x1, str_display[n_dim_str][i]);
}
void print_GREEN2(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR])
{
init_pair(2, CUSTOM_GREEN2, COLOR_BLACK);
attron(COLOR_PAIR(2));
mvprintw(y1+i-n_string, x1, str_display[n_dim_str][i]);
}
void print_GREEN3(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR])
{
init_pair(3, CUSTOM_GREEN3, COLOR_BLACK);
attron(COLOR_PAIR(3));
mvprintw(y1+i-n_string, x1, str_display[n_dim_str][i]);
}
Drop_init_vals drop_init_vals_to_zero(void)
{
Drop_init_vals drop_init_vals;
drop_init_vals.y1 = 0;
drop_init_vals.x1 = 0;
drop_init_vals.n_string = 0;
drop_init_vals.iter_init = 0;
drop_init_vals.n_dim_str = 0;
return drop_init_vals;
}
Drop_init_vals random_drop_init_vals(Drop_init_vals drop_init_vals)
{
drop_init_vals.x1 = rand() % X1_RANGE;
drop_init_vals.n_string = 20 + rand() % N_STRING_RANGE;
return drop_init_vals;
}
void print_n_string_from_string_array_struct(Drop_init_vals drop_init_vals, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR], int iter)
{
int y1 = drop_init_vals.y1;
int x1 = drop_init_vals.x1;
int n_string = drop_init_vals.n_string;
int n_dim_str = drop_init_vals.n_dim_str;
int y_start = iter - drop_init_vals.iter_init;
int count = 0;
for (int i=y_start; i<y_start+n_string; i++)
{
if (count == 0 || count == 1){
print_GREEN1(y1, x1, i, n_string, n_dim_str, &str_display[n_dim_str]);
}
else if (count == 2 || count == 3 || count == 4){
print_GREEN2(y1, x1, i, n_string, n_dim_str, &str_display[n_dim_str]);
}
else{
print_GREEN3(y1, x1, i, n_string, n_dim_str, &str_display[n_dim_str]);
}
count++;
}
}
Drop_init_vals drop_init_vals_array_to_zero(Drop_init_vals drop_init_vals)
{
for (int drop_num = 0; drop_num < N_DROPS; drop_num++){
drop_init_vals.y1 = 0;
drop_init_vals.x1 = 0;
drop_init_vals.n_string = 0;
drop_init_vals.iter_init = 0;
drop_init_vals.n_dim_str = 0;
}
return drop_init_vals;
}
/*set_characters.h*/
#ifndef SET_CHARACTERS_H
#define SET_CHARACTERS_H
#define N_COMMAS 56
#define SET_CHAR "ㇰ", "ㇱ", "ㇲ","ㇳ","ㇴ","ㇵ","ㇶ","ㇷ","ㇸ","ㇹ","ㇺ","ㇻ","ㇼ","ㇽ","ㇾ", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "<", "=", ">", "T", "H","E", "M", "A", "T", "R", "I", "X", "Z", ":", "・", ".", "=", "*", "+", "-", "<", ">", "¦", "|", "#", "_"
#endif
/*hyperparameters.h*/
#ifndef HYPERPARAMETERS_H
#define HYPERPARAMETERS_H
#define DELAY 60000 //480000
#define CUSTOM_GREEN1 8
#define CUSTOM_GREEN2 9
#define CUSTOM_GREEN3 10
#define COLOR_BLACK 0
#define DIM_0_ARRAY_STRING 20
#define DIM_1_ARRAY_STRING 100
#define BYTES_PER_CHAR 5
#define LEN_STRING_DISPLAY 100
#define MAX_Y 100
#define MAX_X 100
#define N_STRING_MAX 20
#define N_DROPS 5
#define Y1_RANGE 20
#define X1_RANGE 30
#define N_STRING_RANGE 5
#define Y_START_RANGE 15
#define ITER_REFRESH 80
#define ITER_START_RANGE 80
#endif
#makefile
CC = gcc
CFLAGS = -O2 -Wextra -Wall -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wstrict-prototypes -Wstrict-overflow=5 -Wwrite-strings -Waggregate-return -Wcast-qual -Wswitch-default -Wswitch-enum -Wconversion -Wunreachable-code -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition
BINC=matrix_digital_rain
allc: $(BINC)
$(BINC): $(BINC).o functions.o
$(CC) $(CFLAGS) -ggdb3 $(BINC).o functions.o -o $@ -lncurses
$(BINC).o: $(BINC).c set_characters.h hyperparameters.h set_characters.h
$(CC) $(CFLAGS) -c $(BINC).c
functions.o: functions.c functions.h
$(CC) $(CFLAGS) -c functions.c
clean:
$(RM) -rf $(BINC) *.dSYM *.o
runc: allc
./$(BINC)
EDIT
So as mentioned in a comment, I added -fsanitize=address,undefined
to the compilation and got the following output:
make runc
gcc -O2 -Wextra -Wall -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wstrict-prototypes -Wstrict-overflow=5 -Wwrite-strings -Waggregate-return -Wcast-qual -Wswitch-default -Wswitch-enum -Wconversion -Wunreachable-code -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -c functions.
ㇰ=en_US.UTF-8 2
S.UTF-8 ㇰ
-8 #
CURITYSESSIONID=186a6
YSESSIONID=186a6
IONID=186a6 /
=186a6 ㇺ
6
P_OPTIONS=--color=auto
IONS=--color=autoAddressSanitizer:DEADLYSIGNAL
=================================================================
==37477==ERROR: AddressSanitizer: stack-overflow on address 0x7ffeeac8d253 (pc 0x000104fe2d90 bp 0x7ffeeac882e0 sp 0x7ffeeac882e0 T0)
#0 0x104fe2d90 in __sanitizer::internal_strlen(char const*)+0x10 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x5dd90)
#1 0x104fa7f75 in printf_common(void*, char const*, __va_list_tag*)+0x25 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x22f75)
#2 0x104fa8a69 in wrap_vsnprintf+0x99 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x23a69)
#3 0x7fff40e9c161 in _nc_printf_string+0xba (libncurses.5.4.dylib:x86_64+0x1d161)
#4 0x7fff40e93952 in vwprintw+0x13 (libncurses.5.4.dylib:x86_64+0x14952)
#5 0x7fff40e93abb in mvprintw+0xa7 (libncurses.5.4.dylib:x86_64+0x14abb)
#6 0x104f76765 in print_n_string_from_string_array_struct+0x255 (matrix_digital_rain:x86_64+0x100003765)
#7 0x104f75e5b in main+0x74b (matrix_digital_rain:x86_64+0x100002e5b)
#8 0x7fff20506f3c in start+0x0 (libdyld.dylib:x86_64+0x15f3c)
SUMMARY: AddressSanitizer: stack-overflow (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x5dd90) in __sanitizer::internal_strlen(char const*)+0x10
==37477==ABORTING
make: *** [runc] Abort trap: 6
EDIT 2
I added the following to the compile -O0 -ggdb
and got the following output:
make runc
gcc -O2 -Wextra -Wall -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wstrict-prototypes -Wstrict-overflow=5 -Wwrite-strings -Waggregate-return -Wcast-qual -Wswitch-default -Wswitch-enum -Wconversion -Wunreachable-code -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -c functions.
2 f2
=>0x1fffdca62250: f2 f2 f2 f2 f2[f2]f2 f2 f2 f2 f2 f2 f2 f2 f2 f2
0x1fffdca62260: f2 f2 f2 f2 f2 f2 f2 f2 00 00 00 04 f3 f3 f3 f3
0x1fffdca62270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1fffdca62280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1fffdca62290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1fffdca622a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==41647==ABORTING
make: *** [runc] Abort trap: 6
%
[@matrix_digital_rain]$
[@matrix_digital_rain]$
EDIT
I tried to implement the change suggested by @n. m. namely:
- I checked if N_DROPS > DIM_0_ARRAY_STRING and made the program terminate if it is the case (lines 15-19 of script
matrix_digital_rain.c
)
if (N_DROPS > DIM_0_ARRAY_STRING)
{
printf("error N_DROPS should be equal or lower than DIM_0_ARRAY_STRING");
exit(EXIT_FAILURE);
}
- I did not increment twice str_display in
print_GREENX
andprint_n_string_from_string_array_struct
(in lines 64, 68 and 72 in scriptfunction.c
)
There is no segfault anymore (which is a MAJOR improvement, many thanks to @n. m.) however, there is still the flickering of the characters. Does it have to do with the many different mvprintw
statements?
Here is the full edited code:
/*matrix_digital_rain.c*/
#include <curses.h>
#include <unistd.h>
#include <locale.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include "set_characters.h"
#include "hyperparameters.h"
#include "functions.h"
int main() {
if (N_DROPS > DIM_0_ARRAY_STRING)
{
printf("error N_DROPS should be equal or lower than DIM_0_ARRAY_STRING");
exit(EXIT_FAILURE);
}
srand((unsigned) time(NULL)); // Initialization, should only be called once.
setlocale(LC_ALL, "");
int max_y = 0, max_x = 0;
Drop_init_vals drop_init_vals_array[N_DROPS] ;
for (int drop_num = 0; drop_num < N_DROPS; drop_num++){
drop_init_vals_array[drop_num] = drop_init_vals_array_to_zero(drop_init_vals_array[drop_num]);
drop_init_vals_array[drop_num].rand_iter_start = rand() % ITER_START_RANGE;
}
int iter = 0;
initscr();
noecho();
curs_set(FALSE);
start_color();
init_color(CUSTOM_GREEN1, 90, 280, 90);
init_color(CUSTOM_GREEN2, 100, 500, 100);
init_color(CUSTOM_GREEN3, 100, 900, 100);
init_color(COLOR_BLACK, 0, 0, 0);
char char_set[DIM_1_ARRAY_STRING][BYTES_PER_CHAR] = {SET_CHAR};
char str_display[DIM_0_ARRAY_STRING][DIM_1_ARRAY_STRING][BYTES_PER_CHAR];
for (int i = 0; i<DIM_0_ARRAY_STRING; i++){
for (int j = 0; j<DIM_1_ARRAY_STRING; j++){
strcpy(str_display[i][j], char_set[rand() % N_COMMAS]);
}
}
while(1)
{
getmaxyx(stdscr, max_y, max_x);
clear();
for (int drop_num = 0; drop_num<N_DROPS; drop_num++){
if (iter % ITER_REFRESH == drop_init_vals_array[drop_num].rand_iter_start){
drop_init_vals_array[drop_num].n_dim_str = drop_num;
drop_init_vals_array[drop_num].x1 = rand() % X1_RANGE;
drop_init_vals_array[drop_num].n_string = 20 + rand() % N_STRING_RANGE;
drop_init_vals_array[drop_num].iter_init = iter;
drop_init_vals_array[drop_num].rand_iter_start_bool = 1;
}
if(drop_init_vals_array[drop_num].rand_iter_start_bool == 1){
print_n_string_from_string_array_struct(
drop_init_vals_array[drop_num],
str_display,
iter
);
if (iter == drop_init_vals_array[drop_num].iter_init + ITER_REFRESH){
drop_init_vals_array[drop_num].rand_iter_start_bool = 0;
}
}
}
iter++;
refresh();
usleep(DELAY);
}
attron(COLOR_PAIR(1));
attron(COLOR_PAIR(2));
attron(COLOR_PAIR(3));
endwin();
refresh();
use_default_colors();
}
/*functions.h*/
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
typedef struct {
int x1, y1, n_string, n_dim_str, iter_init, rand_iter_start, rand_iter_start_bool;
} Drop_init_vals ;
void print_n_string_from_string_array_struct(Drop_init_vals drop_init_vals, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR], int iter);
Drop_init_vals random_drop_init_vals(Drop_init_vals drop_init_vals);
Drop_init_vals drop_init_vals_to_zero(void);
void print_GREEN1(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR]);
void print_GREEN2(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR]);
void print_GREEN3(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR]);
Drop_init_vals drop_init_vals_array_to_zero(Drop_init_vals drop_init_vals);
#endif
/*functions.c*/
#include "hyperparameters.h"
#include "functions.h"
#include <curses.h>
#include <time.h>
#include <stdlib.h>
void print_GREEN1(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR])
{
init_pair(1, CUSTOM_GREEN1, COLOR_BLACK);
attron(COLOR_PAIR(1));
mvprintw(y1+i-n_string, x1, str_display[n_dim_str][i]);
}
void print_GREEN2(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR])
{
init_pair(2, CUSTOM_GREEN2, COLOR_BLACK);
attron(COLOR_PAIR(2));
mvprintw(y1+i-n_string, x1, str_display[n_dim_str][i]);
}
void print_GREEN3(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR])
{
init_pair(3, CUSTOM_GREEN3, COLOR_BLACK);
attron(COLOR_PAIR(3));
mvprintw(y1+i-n_string, x1, str_display[n_dim_str][i]);
}
Drop_init_vals drop_init_vals_to_zero(void)
{
Drop_init_vals drop_init_vals;
drop_init_vals.y1 = 0;
drop_init_vals.x1 = 0;
drop_init_vals.n_string = 0;
drop_init_vals.iter_init = 0;
drop_init_vals.n_dim_str = 0;
return drop_init_vals;
}
Drop_init_vals random_drop_init_vals(Drop_init_vals drop_init_vals)
{
drop_init_vals.x1 = rand() % X1_RANGE;
drop_init_vals.n_string = 20 + rand() % N_STRING_RANGE;
return drop_init_vals;
}
void print_n_string_from_string_array_struct(Drop_init_vals drop_init_vals, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR], int iter)
{
int y1 = drop_init_vals.y1;
int x1 = drop_init_vals.x1;
int n_string = drop_init_vals.n_string;
int n_dim_str = drop_init_vals.n_dim_str;
int y_start = iter - drop_init_vals.iter_init;
int count = 0;
for (int i=y_start; i<y_start+n_string; i++)
{
if (count == 0 || count == 1){
//print_GREEN1(y1, x1, i, n_string, n_dim_str, &str_display[n_dim_str]);
print_GREEN1(y1, x1, i, n_string, n_dim_str, str_display);
}
else if (count == 2 || count == 3 || count == 4){
//print_GREEN2(y1, x1, i, n_string, n_dim_str, &str_display[n_dim_str]);
print_GREEN2(y1, x1, i, n_string, n_dim_str, str_display);
}
else{
//print_GREEN3(y1, x1, i, n_string, n_dim_str, &str_display[n_dim_str]);
print_GREEN3(y1, x1, i, n_string, n_dim_str, str_display);
}
count++;
}
}
Drop_init_vals drop_init_vals_array_to_zero(Drop_init_vals drop_init_vals)
{
for (int drop_num = 0; drop_num < N_DROPS; drop_num++){
drop_init_vals.y1 = 0;
drop_init_vals.x1 = 0;
drop_init_vals.n_string = 0;
drop_init_vals.iter_init = 0;
drop_init_vals.n_dim_str = 0;
}
return drop_init_vals;
}
/*set_characters.h*/
#ifndef SET_CHARACTERS_H
#define SET_CHARACTERS_H
#define N_COMMAS 56
#define SET_CHAR "ㇰ", "ㇱ", "ㇲ","ㇳ","ㇴ","ㇵ","ㇶ","ㇷ","ㇸ","ㇹ","ㇺ","ㇻ","ㇼ","ㇽ","ㇾ", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "<", "=", ">", "T", "H","E", "M", "A", "T", "R", "I", "X", "Z", ":", "・", ".", "=", "*", "+", "-", "<", ">", "¦", "|", "#", "_"
#endif
/*hyperparameters.h*/
#ifndef HYPERPARAMETERS_H
#define HYPERPARAMETERS_H
#define DELAY 60000 //480000
#define CUSTOM_GREEN1 8
#define CUSTOM_GREEN2 9
#define CUSTOM_GREEN3 10
#define COLOR_BLACK 0
#define DIM_0_ARRAY_STRING 30
#define DIM_1_ARRAY_STRING 100
#define BYTES_PER_CHAR 5
#define LEN_STRING_DISPLAY 100
#define MAX_Y 100
#define MAX_X 100
#define N_STRING_MAX 20
#define N_DROPS 20
#define Y1_RANGE 20
#define X1_RANGE 50
#define N_STRING_RANGE 5
#define Y_START_RANGE 15
#define ITER_REFRESH 80
#define ITER_START_RANGE 80
#endif
#makefile
CC = gcc
CFLAGS = -O2 -Wextra -Wall -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wstrict-prototypes -Wstrict-overflow=5 -Wwrite-strings -Waggregate-return -Wcast-qual -Wswitch-default -Wswitch-enum -Wconversion -Wunreachable-code -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -fsanitize=address,undefined -O0 -ggdb
BINC=matrix_digital_rain
allc: $(BINC)
$(BINC): $(BINC).o functions.o
$(CC) $(CFLAGS) -ggdb3 $(BINC).o functions.o -o $@ -lncurses
$(BINC).o: $(BINC).c set_characters.h hyperparameters.h set_characters.h
$(CC) $(CFLAGS) -c $(BINC).c
functions.o: functions.c functions.h
$(CC) $(CFLAGS) -c functions.c
clean:
$(RM) -rf $(BINC) *.dSYM *.o
runc: allc
./$(BINC)
# ./$(BINC) >/dev/null