From 97fb8de5da7623b9b2df4bc3bf8533aea0c0a6d5 Mon Sep 17 00:00:00 2001 From: Gabe Venberg Date: Wed, 6 Sep 2023 15:07:08 -0500 Subject: [PATCH] Did a few exersises, most of the way through serial_logger. --- combinations/src/combinations.c | 35 +++++++------ file_tee/Makefile | 65 +++++++++++++++++++++++ file_tee/src/file_tee.c | 69 +++++++++++++++++++++++++ function_pointer/Makefile | 65 +++++++++++++++++++++++ function_pointer/src/function_pointer.c | 26 ++++++++++ hello_world/src/helloworld.c | 7 +-- retrieve_count/Makefile | 65 +++++++++++++++++++++++ retrieve_count/src/retrieve_count.c | 19 +++++++ 8 files changed, 331 insertions(+), 20 deletions(-) create mode 100644 file_tee/Makefile create mode 100644 file_tee/src/file_tee.c create mode 100644 function_pointer/Makefile create mode 100644 function_pointer/src/function_pointer.c create mode 100644 retrieve_count/Makefile create mode 100644 retrieve_count/src/retrieve_count.c diff --git a/combinations/src/combinations.c b/combinations/src/combinations.c index 90b3455..416b847 100644 --- a/combinations/src/combinations.c +++ b/combinations/src/combinations.c @@ -1,30 +1,31 @@ -/* calculates all subsets of the string comb by assigning eatch letter a position in a binary number and counting up. */ +/* calculates all subsets of the string comb by assigning eatch letter a + * position in a binary number and counting up. */ #include #include // #define DEBUG int main() { - char* comb = "ABCD"; - int count = strlen(comb); - // that bitshifting is the same is squaring count - int permutations = (1 << count); + char *comb = "ABCD"; + int count = strlen(comb); + // that bitshifting is the same is squaring count + int permutations = (1 << count); - printf("string is %s\nthere are %d permutations", comb, permutations); + printf("string is %s\nthere are %d permutations", comb, permutations); - for (unsigned char i = 0; i < permutations; i++) { - for (unsigned char j = 0; j < 4; j++) { - // when j=0, will result in 0b0001, when j=1, 0b0010, j=2 0b0100. - unsigned char mask = 1 << j; + for (unsigned char i = 0; i < permutations; i++) { + for (unsigned char j = 0; j < 4; j++) { + // when j=0, will result in 0b0001, when j=1, 0b0010, j=2 0b0100. + unsigned char mask = 1 << j; #ifdef DEBUG - printf(" j=%x mask=%x, postmask=%x, i=%x", j, mask, (i & mask), i); + printf(" j=%x mask=%x, postmask=%x, i=%x", j, mask, (i & mask), i); #endif /* ifdef DEBUG */ - if ((i & mask) != 0) { - printf(" %c", comb[j]); - } + if ((i & mask) != 0) { + printf(" %c", comb[j]); + } + } + printf("\n"); } - printf("\n"); - } - return 0; + return 0; } diff --git a/file_tee/Makefile b/file_tee/Makefile new file mode 100644 index 0000000..82811a6 --- /dev/null +++ b/file_tee/Makefile @@ -0,0 +1,65 @@ +CC := gcc +CXX := g++ +OPTIMIZATION := -O3 +CFLAGS = ${OPTIMIZATION} -Wextra -Wall -Wpedantic +# all: helloworld +# +# #automatically built from implicit rules. +# helloworld: helloworld.c +# +# clean: +# rm -f helloworld +# +TARGET_EXEC := filetee + +BUILD_DIR := ./build +SRC_DIRS := ./src + +# Find all the C and C++ files we want to compile +# Note the single quotes around the * expressions. The shell will incorrectly expand these otherwise, but we want to send the * directly to the find command. +SRCS := $(shell find $(SRC_DIRS) -name '*.cpp' -or -name '*.c' -or -name '*.s') + +# Prepends BUILD_DIR and appends .o to every src file +# As an example, ./your_dir/hello.cpp turns into ./build/./your_dir/hello.cpp.o +OBJS := $(SRCS:%=$(BUILD_DIR)/%.o) + +# String substitution (suffix version without %). +# As an example, ./build/hello.cpp.o turns into ./build/hello.cpp.d +DEPS := $(OBJS:.o=.d) + +# Every folder in ./src will need to be passed to GCC so that it can find header files +INC_DIRS := $(shell find $(SRC_DIRS) -type d) +# Add a prefix to INC_DIRS. So moduleA would become -ImoduleA. GCC understands this -I flag +INC_FLAGS := $(addprefix -I,$(INC_DIRS)) + +# The -MMD and -MP flags together generate Makefiles for us! +# These files will have .d instead of .o as the output. +DEPFLAGS := $(INC_FLAGS) -MMD -MP + +# The final build step. +$(BUILD_DIR)/$(TARGET_EXEC): $(OBJS) + $(CXX) $(OBJS) -o $@ $(LDFLAGS) + +# Build step for C source +$(BUILD_DIR)/%.c.o: %.c + mkdir -p $(dir $@) + $(CC) $(DEPFLAGS) $(CFLAGS) -c $< -o $@ + +# Build step for C++ source +$(BUILD_DIR)/%.cpp.o: %.cpp + mkdir -p $(dir $@) + $(CXX) $(DEPFLAGS) $(CXXFLAGS) -c $< -o $@ + + +.PHONY: clean +clean: + rm -r $(BUILD_DIR) + +.PHONY: run +run: $(BUILD_DIR)/$(TARGET_EXEC) + $(BUILD_DIR)/$(TARGET_EXEC) + +# Include the .d makefiles. The - at the front suppresses the errors of missing +# Makefiles. Initially, all the .d files will be missing, and we don't want those +# errors to show up. +-include $(DEPS) diff --git a/file_tee/src/file_tee.c b/file_tee/src/file_tee.c new file mode 100644 index 0000000..c24f673 --- /dev/null +++ b/file_tee/src/file_tee.c @@ -0,0 +1,69 @@ +#include +#include + +static const char Help[] = "Reads a file and outputs to a file while also printing contents."; +static const char Usage[] = "INPUT_FILE [OUTPUT_FILE]"; + +struct arguments { + char* inFile; + char* outFile; +}; + +int main(int argc, char* argv[]) { + // for some reason, when doing this with a serial port, log.log never gets written to. I think this is becasue the + // program is terminated with ctrl-c, so the file descriptors dont close?. + + struct arguments arguments = {NULL, NULL}; + + switch (argc) { + case 3: + arguments.outFile = argv[2]; + // fallthrough + case 2: + arguments.inFile = argv[1]; + break; + default: + printf("%s\n%s\n", Usage, Help); + return EXIT_FAILURE; + break; + } + + FILE* inFile = fopen(arguments.inFile, "r"); + if (!inFile) { + printf("error opening file %s\n", arguments.inFile); + return EXIT_FAILURE; + } + FILE* outFile; + if (arguments.outFile != NULL) { + outFile = fopen(arguments.outFile, "w"); + if (!outFile) { + printf("error opening file %s\n", arguments.outFile); + return EXIT_FAILURE; + } + if (fputs("start of log\n", outFile) < 0) { + printf("could not write to %s\n", arguments.outFile); + return EXIT_FAILURE; + } + fflush(outFile); + } + + char* lineBuff = NULL; + size_t lineBuffSize = 0; + ssize_t line_size; + + do { + line_size = getline(&lineBuff, &lineBuffSize, inFile); + printf("%s", lineBuff); + if (arguments.outFile != NULL) { + fputs(lineBuff, outFile); + fflush(outFile); + } + } while (line_size >= 0); + + // these things should be done by the OS when we exit. + // free(lineBuff); + // fclose(inFile); + // fclose(outFile); + + return EXIT_SUCCESS; +} diff --git a/function_pointer/Makefile b/function_pointer/Makefile new file mode 100644 index 0000000..040f25c --- /dev/null +++ b/function_pointer/Makefile @@ -0,0 +1,65 @@ +CC := gcc +CXX := g++ +OPTIMIZATION := -O3 +CFLAGS = ${OPTIMIZATION} -Werror -Wextra -Wall -Wpedantic +# all: helloworld +# +# #automatically built from implicit rules. +# helloworld: helloworld.c +# +# clean: +# rm -f helloworld +# +TARGET_EXEC := functionpointer + +BUILD_DIR := ./build +SRC_DIRS := ./src + +# Find all the C and C++ files we want to compile +# Note the single quotes around the * expressions. The shell will incorrectly expand these otherwise, but we want to send the * directly to the find command. +SRCS := $(shell find $(SRC_DIRS) -name '*.cpp' -or -name '*.c' -or -name '*.s') + +# Prepends BUILD_DIR and appends .o to every src file +# As an example, ./your_dir/hello.cpp turns into ./build/./your_dir/hello.cpp.o +OBJS := $(SRCS:%=$(BUILD_DIR)/%.o) + +# String substitution (suffix version without %). +# As an example, ./build/hello.cpp.o turns into ./build/hello.cpp.d +DEPS := $(OBJS:.o=.d) + +# Every folder in ./src will need to be passed to GCC so that it can find header files +INC_DIRS := $(shell find $(SRC_DIRS) -type d) +# Add a prefix to INC_DIRS. So moduleA would become -ImoduleA. GCC understands this -I flag +INC_FLAGS := $(addprefix -I,$(INC_DIRS)) + +# The -MMD and -MP flags together generate Makefiles for us! +# These files will have .d instead of .o as the output. +DEPFLAGS := $(INC_FLAGS) -MMD -MP + +# The final build step. +$(BUILD_DIR)/$(TARGET_EXEC): $(OBJS) + $(CXX) $(OBJS) -o $@ $(LDFLAGS) + +# Build step for C source +$(BUILD_DIR)/%.c.o: %.c + mkdir -p $(dir $@) + $(CC) $(DEPFLAGS) $(CFLAGS) -c $< -o $@ + +# Build step for C++ source +$(BUILD_DIR)/%.cpp.o: %.cpp + mkdir -p $(dir $@) + $(CXX) $(DEPFLAGS) $(CXXFLAGS) -c $< -o $@ + + +.PHONY: clean +clean: + rm -r $(BUILD_DIR) + +.PHONY: run +run: $(BUILD_DIR)/$(TARGET_EXEC) + $(BUILD_DIR)/$(TARGET_EXEC) + +# Include the .d makefiles. The - at the front suppresses the errors of missing +# Makefiles. Initially, all the .d files will be missing, and we don't want those +# errors to show up. +-include $(DEPS) diff --git a/function_pointer/src/function_pointer.c b/function_pointer/src/function_pointer.c new file mode 100644 index 0000000..fd9a2f2 --- /dev/null +++ b/function_pointer/src/function_pointer.c @@ -0,0 +1,26 @@ +#include +#include + +void function0(void) { printf("function 0\n"); } +void function1(void) { printf("function 1\n"); } +void function2(void) { printf("function 2\n"); } +typedef void (*VoidToVoid)(void); + +int main(int argc, char *argv[]) { + VoidToVoid functions[3] = {function0, function1, function2}; + if (argc != 2) { + printf("one argument only\n"); + return EXIT_FAILURE; + } + + unsigned char index = strtol(argv[1], NULL, 10); + + if (index > 2) { + printf("argument must be between 0 and 2\n"); + return EXIT_FAILURE; + } + + functions[index](); + + return EXIT_SUCCESS; +} diff --git a/hello_world/src/helloworld.c b/hello_world/src/helloworld.c index f25a259..eba1b77 100644 --- a/hello_world/src/helloworld.c +++ b/hello_world/src/helloworld.c @@ -1,8 +1,9 @@ #include #include -int main() -{ - printf("Hello World\n"); +int main() { + if (printf("Hello World\n") < 0) { + return EXIT_FAILURE; + } return EXIT_SUCCESS; } diff --git a/retrieve_count/Makefile b/retrieve_count/Makefile new file mode 100644 index 0000000..5b824bb --- /dev/null +++ b/retrieve_count/Makefile @@ -0,0 +1,65 @@ +CC := gcc +CXX := g++ +OPTIMIZATION := -O3 +CFLAGS = ${OPTIMIZATION} -Werror -Wextra -Wall -Wpedantic +# all: helloworld +# +# #automatically built from implicit rules. +# helloworld: helloworld.c +# +# clean: +# rm -f helloworld +# +TARGET_EXEC := retrievecount + +BUILD_DIR := ./build +SRC_DIRS := ./src + +# Find all the C and C++ files we want to compile +# Note the single quotes around the * expressions. The shell will incorrectly expand these otherwise, but we want to send the * directly to the find command. +SRCS := $(shell find $(SRC_DIRS) -name '*.cpp' -or -name '*.c' -or -name '*.s') + +# Prepends BUILD_DIR and appends .o to every src file +# As an example, ./your_dir/hello.cpp turns into ./build/./your_dir/hello.cpp.o +OBJS := $(SRCS:%=$(BUILD_DIR)/%.o) + +# String substitution (suffix version without %). +# As an example, ./build/hello.cpp.o turns into ./build/hello.cpp.d +DEPS := $(OBJS:.o=.d) + +# Every folder in ./src will need to be passed to GCC so that it can find header files +INC_DIRS := $(shell find $(SRC_DIRS) -type d) +# Add a prefix to INC_DIRS. So moduleA would become -ImoduleA. GCC understands this -I flag +INC_FLAGS := $(addprefix -I,$(INC_DIRS)) + +# The -MMD and -MP flags together generate Makefiles for us! +# These files will have .d instead of .o as the output. +DEPFLAGS := $(INC_FLAGS) -MMD -MP + +# The final build step. +$(BUILD_DIR)/$(TARGET_EXEC): $(OBJS) + $(CXX) $(OBJS) -o $@ $(LDFLAGS) + +# Build step for C source +$(BUILD_DIR)/%.c.o: %.c + mkdir -p $(dir $@) + $(CC) $(DEPFLAGS) $(CFLAGS) -c $< -o $@ + +# Build step for C++ source +$(BUILD_DIR)/%.cpp.o: %.cpp + mkdir -p $(dir $@) + $(CXX) $(DEPFLAGS) $(CXXFLAGS) -c $< -o $@ + + +.PHONY: clean +clean: + rm -r $(BUILD_DIR) + +.PHONY: run +run: $(BUILD_DIR)/$(TARGET_EXEC) + $(BUILD_DIR)/$(TARGET_EXEC) + +# Include the .d makefiles. The - at the front suppresses the errors of missing +# Makefiles. Initially, all the .d files will be missing, and we don't want those +# errors to show up. +-include $(DEPS) diff --git a/retrieve_count/src/retrieve_count.c b/retrieve_count/src/retrieve_count.c new file mode 100644 index 0000000..2457119 --- /dev/null +++ b/retrieve_count/src/retrieve_count.c @@ -0,0 +1,19 @@ +#include + +static unsigned int counter = 0; + +void increment(void) { + // static unsigned int counter = 0; + counter++; + // printf("%d ", counter); +} + +int retrieve(void) { return counter; } + +int main(void) { + for (int i = 0; i < 5; i++) { + increment(); + printf("%d ", retrieve()); + } + return 0; +}