From d37cb21e2d9730db4beda6900513fe31d4c06629 Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Mon, 6 Feb 2023 12:17:45 -0600 Subject: [PATCH] v0.2.2 --- Makefile | 98 +++++++++++++++++++++++++++++++++++++------------- README | 12 +++++-- src/function.c | 17 +++------ src/gol.c | 17 ++++----- src/gol.h | 46 ++++++++++++++---------- src/map.c | 96 +++++++++++++++++++------------------------------ src/struct.c | 3 +- 7 files changed, 160 insertions(+), 129 deletions(-) diff --git a/Makefile b/Makefile index 7d9852e..19dd8bb 100644 --- a/Makefile +++ b/Makefile @@ -4,13 +4,17 @@ VER ?= 0.2.2 SHELL = /bin/bash DESTDIR ?= - ETCDIR ?= $(DESTDIR)/etc/$(NAME) USRDIR ?= $(DESTDIR)/usr -BINDIR ?= $(USRDIR)/bin -LIBDIR ?= $(USRDIR)/lib -MANDIR ?= $(USRDIR)/share/man/man1 -DOCDIR ?= $(USRDIR)/share/doc/$(NAME) + +PREFIX ?= $(USRDIR) +BINDIR ?= $(PREFIX)/bin +LIBDIR ?= $(PREFIX)/lib +SHAREDIR ?= $(PREFIX)/share +INCLUDE ?= $(PREFIX)/include +MANDIR ?= $(SHAREDIR)/man +MAN1DIR ?= $(MANDIR)/man1 +DOCDIR ?= $(PREFIX)/doc/$(NAME) SRCDIR ?= ./src OBJDIR ?= ./obj @@ -20,6 +24,10 @@ BIN ?= $(BUILD)/$(NAME) SRC ?= $(wildcard $(SRCDIR)/*.c) HDR ?= $(wildcard $(SRCDIR)/*.h) OBJ ?= $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(SRC)) +LIBNAME ?= lib$(NAME) +LIB ?= $(BUILD)/$(LIBNAME).so +STATIC ?= $(BUILD)/$(LIBNAME).a + TAR ?= $(BUILD)/$(NAME)-$(VER).tar.gz @@ -27,19 +35,32 @@ MAN ?= $(SRCDIR)/$(NAME).1 MANPAGE ?= $(patsubst $(SRCDIR)/%.1,$(BUILD)/%.1.gz,$(MAN)) DOC ?= README LICENSE -CC ?= gcc -ZIP ?= gzip +CC = gcc +AR = ar +LD = ld +ZIP = gzip +RM = rm -f + CFLAGS += -O2 -pipe -WARNINGS ?= -Wall -Wextra -Wpedantic -CPPFLAGS += -I $(SRCDIR) -LDFLAGS += -L $(SRCDIR) +CPPFLAGS += -I$(SRCDIR) -I$(BUILD) +LDFLAGS += -L$(SRCDIR) -L$(BUILD) LDLIBS += -FLAGS ?= $(CPPFLAGS) $(CFLAGS) $(WARNINGS) $(LDFLAGS) $(LDLIBS) +WARNINGS ?= -Wall -Wextra -Wpedantic + +FLAGS += $(CPPFLAGS) $(CFLAGS) $(WARNINGS) $(LDFLAGS) $(LDLIBS) +DEBUGFLAGS += $(WARNINGS) $(CPPFLAGS) $(LDFLAGS) $(LDLIBS) -ggdb -Og -pipe +RELEASEFLAGS = $(CPPFLAGS) $(LDFLAGS) $(LDLIBS) -O3 -pipe -DNDEBUG -DDONT_USE_VOL all: $(BIN) -release: CFLAGS = -O3 -pipe -DNDEBUG -DDONT_USE_VOL -release: $(BIN) +lib: $(LIB) + +static: $(STATIC) + +release: | $(BUILD) + $(MAKE) clean + $(CC) $(SRC) $(RELEASEFLAGS) -o $(BIN)-$(VER) + $(MAKE) tar install: $(BIN) $(MANPAGE) $(DOC) -mkdir -p $(BINDIR) @@ -51,28 +72,57 @@ install: $(BIN) $(MANPAGE) $(DOC) -mkdir -p $(DOCDIR) install -CDm 644 -t $(DOCDIR) $(DOC) -uninstall: - -rm -rf $(BINDIR)/$(BIN) $(MANDIR)/$(MANPAGE) $(DOCDIR) +install_lib: + -mkdir -p $(LIBDIR) + cp $(LIB) $(LIBDIR) + chmod 755 $(LIBDIR)/$(patsubst $(BUILD)/%,%,$(LIB)) + -mkdir -p $(INCLUDE) + cp $(HDR) $(INCLUDE) + chmod 644 $(INCLUDE)/$(patsubst $(SRCDIR)/%,%,$(HDR)) + +install_static: + -mkdir -p $(LIBDIR) + cp $(STATIC) $(LIBDIR) + chmod 755 $(LIBDIR)/$(patsubst $(BUILD)/%,%,$(STATIC)) + -mkdir -p $(INCLUDE) + cp $(HDR) $(INCLUDE) + chmod 644 $(INCLUDE)/$(patsubst $(SRCDIR)/%,%,$(HDR)) -tar: $(SRC) $(HDR) $(MAN) $(DOC) +uninstall: + $(RM) -r $(BINDIR)/$(patsubst $(BUILD)/%,%,$(BIN)) + $(RM) -r $(MANDIR)/$(patsubst $(BUILD)/%,%,$(MANPAGE)) + $(RM) -r $(INCLUDE)/$(patsubst $(SRC)/%,%,$(HDR)) + $(RM) -r $(LIBDIR)/$(patsubst $(BUILD)/%,%,$(LIB)) + $(RM) -r $(LIBDIR)/$(patsubst $(BUILD)/%,%,$(STATIC)) + $(RM) -r $(DOCDIR) + +tar: $(SRC) $(HDR) $(MAN) $(DOC) | $(BUILD) tar -I $(ZIP) -cvf $(TAR) $(SRC) $(HDR) $(MAN) $(DOC) -$(BIN): $(OBJ) +$(BIN): $(OBJ) | $(BUILD) $(CC) $(OBJ) $(FLAGS) -o $(BIN) -$(OBJDIR)/%.o: $(SRCDIR)/%.c $(HDR) +$(LIB): $(SRC) $(HDR) | $(BUILD) + $(CC) $(SRC) $(FLAGS) -fPIC -shared -lc -o $(LIB) + +$(STATIC): $(OBJ) | $(BUILD) + $(AR) rcs $(STATIC) $(OBJ) + +$(OBJDIR)/%.o: $(SRCDIR)/%.c $(HDR) | $(OBJDIR) $(CC) -c $(FLAGS) $< -o $@ clean: - -rm -f $(BUILD)/* $(OBJDIR)/* + $(RM) $(BUILD)/* $(OBJDIR)/* -debug: $(SRC) - $(CC) $(SRC) $(FLAGS) -ggdb3 -Og -pipe -o $(BIN)-debug +debug: | $(BUILD) + $(MAKE) clean + $(CC) $(SRC) $(DEBUGFLAGS) -o $(BIN)-debug -$(MANPAGE): $(MAN) +$(MANPAGE): $(MAN) | $(BUILD) $(ZIP) -c $(MAN) > $(MANPAGE) -$(SRCDIR) $(OBJDIR) $(BUILDIR): +$(SRCDIR) $(OBJDIR) $(BUILD): mkdir $@ -.PHONY: all release clean install tar uninstall debug test +.PHONY: all release lib install_lib static install_static tar clean install uninstall debug + diff --git a/README b/README index 8665e8e..757f5b2 100644 --- a/README +++ b/README @@ -13,8 +13,8 @@ Installation: Download and extract source: $ curl "https://download.huck.website/gol-[VERSION].tar.gz > gol.tar.gz - $ tar -xzvf gol.tar.gz - $ cd gol.tar.gz + $ tar -xzvf gol.tar.gz > + $ cd gol Build and install: $ make && sudo make install @@ -30,5 +30,11 @@ Usage: $ gol -a Change initial distribution weight: $ gol -w [INT] -E + Change time interval between steps: + $ gol -t [ms] + Use a file as input: + $gol -f [file] + +When using a file as input, gol uses any non-whitespace character as a live cell. If the given +file is larger than the map, gol will simply fit what it can on the map. diff --git a/src/function.c b/src/function.c index 363f253..daa2bf2 100644 --- a/src/function.c +++ b/src/function.c @@ -1,6 +1,5 @@ #include "gol.h" - extern int row,col,step,ascii,color,weight,file; extern char *filename; @@ -44,22 +43,16 @@ void parseopts(int n, char **args){ return; } -void errorcheck(int err){ +void errorcheck(ERROR err){ if (errno != 0) { fprintf(stderr,"\nERROR: %s\n",strerror(errno)); - exit(EXIT_FAILURE); + err |= SYS_ERR; } if (err == NO_ERR) { return; } - - if ((err & FLAG_ERR) != 0) { - fprintf(stderr,"ERROR: Unknown Flag\n"); - printf("Use -h for help"); - } - - if ((err & STATE_ERR) != 0) { fprintf(stderr,"ERROR: Could not determine cell state\n"); } - - if ((err & FILE_ERR) != 0) { fprintf(stderr,"ERROR: Could not open file\n"); } + if ((err & FLAG_ERR) != 0) fprintf(stderr,"ERROR: Unknown Flag\n"); + if ((err & STATE_ERR) != 0) fprintf(stderr,"ERROR: Could not determine cell state\n"); + if ((err & FILE_ERR) != 0) fprintf(stderr,"ERROR: Could not open file\n"); exit(err); } diff --git a/src/gol.c b/src/gol.c index 5a010b8..a17e869 100644 --- a/src/gol.c +++ b/src/gol.c @@ -6,17 +6,14 @@ char *filename; int main(int argc, char *argv[]){ srand(time(NULL)); - int stop = 1; row = 30; col = 90; step = 75000; - ascii = 0; weight = 5; - file = 0; filename = malloc(sizeof(char) * MAXLINE); parseopts(argc,argv); - struct map map = newmap(); + MAP map = newmap(); if (file) { mapfile(map,filename); @@ -24,8 +21,8 @@ int main(int argc, char *argv[]){ genmap(map); } - while (stop > 0){ - stop = updatemap(map); + while (1){ + updatemap(map); printdisplay(map); usleep(step); } @@ -36,14 +33,14 @@ int main(int argc, char *argv[]){ } -void printdisplay(struct map map){ +void printdisplay(MAP map){ printf("%s",CLEAR); for (int r = 0; r < row; r++){ for (int c = 0; c < col; c++){ - if (ascii == 0){ - printf("%4s",map.line[r].cell[c].pixel); - } else { + if (ascii){ printf("%c",map.line[r].cell[c].cellchar); + } else { + printf("%4s",map.line[r].cell[c].pixel); } } putc('\n',stdout); diff --git a/src/gol.h b/src/gol.h index f81ba77..ed307d5 100644 --- a/src/gol.h +++ b/src/gol.h @@ -8,44 +8,54 @@ #include #define MAXLINE 10000 -#define VERSION "0.2.1" +#define VERSION "0.2.2" #define CLEAR "\e[1;1H\e[2J" -enum {DIE = -1, DEAD = 0, ALIVE = 1, SPAWN = 1 << 1}; +enum { + DIE = -1, + DEAD = 0, + ALIVE = 1, + SPAWN = 1 << 1 +}; /* error codes */ -enum {NO_ERR = 0, FLAG_ERR = 1, STATE_ERR = 1 << 1, COLOR_ERR = 1 << 2, FILE_ERR = 1 << 3}; +enum { + NO_ERR = 0, + SYS_ERR = 1, + FLAG_ERR = 1 << 1, + STATE_ERR = 1 << 2, + COLOR_ERR = 1 << 3, + FILE_ERR = 1 << 4 +}; + +typedef int ERROR; +typedef struct map MAP; +struct map { struct line *line; }; +struct line { struct cell *cell; }; struct cell { char pixel[4]; char cellchar; int state; }; -struct line { - struct cell *cell; -}; - -struct map { - struct line *line; -}; /* main.c */ -void errorcheck(int); +void errorcheck(ERROR); void parseopts(int,char **); void help(void); -void printdisplay(struct map); +void printdisplay(MAP); /* map.c */ -void genmap(struct map); -void mapfile(struct map, char *); -int updatemap(struct map); -int numneighbor(struct map,int,int); -int checkstate(struct map,int,int); +void genmap(MAP); +void mapfile(MAP, char *); +void updatemap(MAP); +int numneighbor(MAP,int,int); +int checkstate(MAP,int,int); char statechar(int); char *statecell(int); /* struct.c */ struct map newmap(void); -void freemap(struct map); +void freemap(MAP); diff --git a/src/map.c b/src/map.c index 95c3e20..ff15519 100644 --- a/src/map.c +++ b/src/map.c @@ -2,7 +2,7 @@ extern int row,col,weight; -void genmap(struct map map){ +void genmap(MAP map){ int rnd = 0; for (int r = 0; r < row; r++){ for (int c = 0; c < col; c++){ @@ -17,7 +17,7 @@ void genmap(struct map map){ return; } -void mapfile(struct map map, char *file){ +void mapfile(MAP map, char *file){ FILE *fp = fopen(file, "r"); if (!fp) errorcheck(FILE_ERR); @@ -49,9 +49,8 @@ void mapfile(struct map map, char *file){ return; } -int updatemap(struct map map){ - int n = 0; - struct map tmp = newmap(); +void updatemap(MAP map){ + MAP tmp = newmap(); /* non edges */ for (int r = 0; r < row-1; r++){ @@ -60,26 +59,23 @@ int updatemap(struct map map){ tmp.line[r].cell[c].state = state; tmp.line[r].cell[c].cellchar = statechar(state); strncpy(tmp.line[r].cell[c].pixel,statecell(state),4); - if (state > DEAD){ n++; } } } /* left/right side */ - for (int r = 0; r < row -1; r++){ + for (int r = 0; r < row - 1; r++){ int state = checkstate(map,r,0); tmp.line[r].cell[col-1].state = state; tmp.line[r].cell[col-1].cellchar = statechar(state); strncpy(tmp.line[r].cell[col-1].pixel,statecell(state),4); - if (state > DEAD){ n++; } } - /* top/bottom */ - for (int c = 0; c < col -1; c++){ + /* top/bottom row */ + for (int c = 0; c < col - 1; c++){ int state = checkstate(map,0,c); tmp.line[row-1].cell[c].state = state; tmp.line[row-1].cell[c].cellchar = statechar(state); strncpy(tmp.line[row-1].cell[c].pixel,statecell(state),4); - if (state > DEAD){ n++; } } /* copy to map */ @@ -89,10 +85,10 @@ int updatemap(struct map map){ } } - return n; + return; } -int checkstate(struct map map,int r, int c){ +int checkstate(MAP map,int r, int c){ int state = 0; int n = numneighbor(map, r, c); @@ -138,58 +134,38 @@ char *statecell(int state){ } -int numneighbor(struct map map, int r, int c){ +int numneighbor(MAP map, int r, int c){ int n = 0; /* non-edges */ if (r > 0 && r < row - 1 && c > 0 && c < col - 1){ - if (map.line[r+1].cell[c+1].state > DEAD) n ++; - if (map.line[r].cell[c+1].state > DEAD) n ++; - if (map.line[r-1].cell[c+1].state > DEAD) n ++; - if (map.line[r+1].cell[c].state > DEAD) n ++; - if (map.line[r-1].cell[c].state > DEAD) n ++; - if (map.line[r+1].cell[c-1].state > DEAD) n ++; - if (map.line[r].cell[c-1].state > DEAD) n ++; - if (map.line[r-1].cell[c-1].state > DEAD) n ++; - /* top row */ + if (map.line[r+1].cell[c+1].state > DEAD) n++; + if (map.line[r].cell[c+1].state > DEAD) n++; + if (map.line[r-1].cell[c+1].state > DEAD) n++; + if (map.line[r+1].cell[c].state > DEAD) n++; + if (map.line[r-1].cell[c].state > DEAD) n++; + if (map.line[r+1].cell[c-1].state > DEAD) n++; + if (map.line[r].cell[c-1].state > DEAD) n++; + if (map.line[r-1].cell[c-1].state > DEAD) n++; + /* top/bottom row */ } else if (r == 0 && c > 0 && c < col){ - if (map.line[r+1].cell[c+1].state > DEAD) n ++; - if (map.line[r].cell[c+1].state > DEAD) n ++; - if (map.line[row-1].cell[c+1].state > DEAD) n ++; - if (map.line[r+1].cell[c].state > DEAD) n ++; - if (map.line[row-1].cell[c].state > DEAD) n ++; - if (map.line[r+1].cell[c-1].state > DEAD) n ++; - if (map.line[r].cell[c-1].state > DEAD) n ++; - if (map.line[row-1].cell[c-1].state > DEAD) n ++; - /* bottom row */ - } else if (r == row - 1 && c > 0 && c < col){ - if (map.line[0].cell[c+1].state > DEAD) n ++; - if (map.line[r].cell[c+1].state > DEAD) n ++; - if (map.line[r-1].cell[c+1].state > DEAD) n ++; - if (map.line[0].cell[c].state > DEAD) n ++; - if (map.line[r-1].cell[c].state > DEAD) n ++; - if (map.line[0].cell[c-1].state > DEAD) n ++; - if (map.line[r].cell[c-1].state > DEAD) n ++; - if (map.line[r-1].cell[c-1].state > DEAD) n ++; - /* left side */ + if (map.line[r+1].cell[c+1].state > DEAD) n++; + if (map.line[r].cell[c+1].state > DEAD) n++; + if (map.line[row-2].cell[c+1].state > DEAD) n++; + if (map.line[r+1].cell[c].state > DEAD) n++; + if (map.line[row-2].cell[c].state > DEAD) n++; + if (map.line[r+1].cell[c-1].state > DEAD) n++; + if (map.line[r].cell[c-1].state > DEAD) n++; + if (map.line[row-2].cell[c-1].state > DEAD) n++; + /* left/right side */ } else if (r > 0 && r < row && c == 0){ - if (map.line[r+1].cell[c+1].state > DEAD) n ++; - if (map.line[r].cell[c+1].state > DEAD) n ++; - if (map.line[r-1].cell[c+1].state > DEAD) n ++; - if (map.line[r+1].cell[c].state > DEAD) n ++; - if (map.line[r-1].cell[c].state > DEAD) n ++; - if (map.line[r+1].cell[col-1].state > DEAD) n ++; - if (map.line[r].cell[col-1].state > DEAD) n ++; - if (map.line[r-1].cell[col-1].state > DEAD) n ++; - /* right side */ - } else if (r > 0 && r < row && c == col - 1){ - if (map.line[r+1].cell[0].state > DEAD) n ++; - if (map.line[r].cell[0].state > DEAD) n ++; - if (map.line[r-1].cell[0].state > DEAD) n ++; - if (map.line[r+1].cell[c].state > DEAD) n ++; - if (map.line[r-1].cell[c].state > DEAD) n ++; - if (map.line[r+1].cell[c-1].state > DEAD) n ++; - if (map.line[r].cell[c-1].state > DEAD) n ++; - if (map.line[r-1].cell[c-1].state > DEAD) n ++; + if (map.line[r+1].cell[c+1].state > DEAD) n++; + if (map.line[r].cell[c+1].state > DEAD) n++; + if (map.line[r-1].cell[c+1].state > DEAD) n++; + if (map.line[r+1].cell[c].state > DEAD) n++; + if (map.line[r-1].cell[c].state > DEAD) n++; + if (map.line[r+1].cell[col-2].state > DEAD) n++; + if (map.line[r].cell[col-2].state > DEAD) n++; + if (map.line[r-1].cell[col-2].state > DEAD) n++; } return n; } diff --git a/src/struct.c b/src/struct.c index 213b4bf..8dc7176 100644 --- a/src/struct.c +++ b/src/struct.c @@ -11,8 +11,7 @@ struct map newmap(void){ return tmp; } - -void freemap(struct map map){ +void freemap(MAP map){ for (int r = 0; r < row; r++){ for (int c = 0; c < col; c++){ free(map.line[r].cell); -- 2.45.2