]> git.huck.website - gol.git/commitdiff
v0.2.2
authorHuck Boles <huck@huck.website>
Mon, 6 Feb 2023 18:17:45 +0000 (12:17 -0600)
committerHuck Boles <huck@huck.website>
Mon, 6 Feb 2023 18:17:45 +0000 (12:17 -0600)
Makefile
README
src/function.c
src/gol.c
src/gol.h
src/map.c
src/struct.c

index 7d9852e840707c8c918e7e0678b38b14ee070e7c..19dd8bb4538ba14b12a91deb9fbb6a74d2f50ed9 100644 (file)
--- 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 8665e8ec73d8baa40bd273e7d41baa84e20ad4b3..757f5b2575eee527bb54e5f9adb98e4791815616 100644 (file)
--- 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.
 
index 363f253acf12d766c1f946c2bad0e0b9764fabe0..daa2bf26249002344fae493ff2413f87d70f5ca0 100644 (file)
@@ -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);
 }
index 5a010b8014f16cd63757543762cc907e214af0f4..a17e869780796d84a5375da736606e27757d9470 100644 (file)
--- 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);
index f81ba77fef1c0926b6ec3a6f41ec7c62c2d25aaa..ed307d547aa01e7011f2ad0c9c153a70d110a719 100644 (file)
--- a/src/gol.h
+++ b/src/gol.h
@@ -8,44 +8,54 @@
 #include <wchar.h>
 
 #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);
index 95c3e206a2a306bed623df6082aa853851bfdee2..ff15519a63f92a165d457b319772e227f03775ed 100644 (file)
--- 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;
 }
index 213b4bf3be817398fac9fbcbca5eca912595d948..8dc7176a23f0f5a920501a08e1143ad0d0e53acc 100644 (file)
@@ -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);