From 85c2e213b5b19030e23cd1b51a4f99bcaee42bec Mon Sep 17 00:00:00 2001 From: Gabe Venberg Date: Tue, 12 Sep 2023 09:03:54 -0500 Subject: [PATCH] made follow workplace style guide broke out into functions, implemented the (stupid) single return rule, (seriously, see how many nested if's it generates.), and added timestamps to logfile. --- file_tee/src/file_tee.c | 154 +++++++++++++++++++++++++++++----------- 1 file changed, 113 insertions(+), 41 deletions(-) diff --git a/file_tee/src/file_tee.c b/file_tee/src/file_tee.c index 6f97be5..a338ae5 100644 --- a/file_tee/src/file_tee.c +++ b/file_tee/src/file_tee.c @@ -1,71 +1,143 @@ +#include +#include #include #include +#include -static const char doc[] = -"Reads a file and outputs to a file while also printing contents.\n" -"If OUTPUT_FILE is not given, will only output to stdout"; -static const char args_doc[] = "INPUT_FILE [OUTPUT_FILE]"; +static const char doc[] = "Reads a file and outputs to a file while also printing contents.\n" + "If LOG_FILE is not given, will only output to stdout"; +static const char args_doc[] = "INPUT_FILE [LOG_FILE]"; -struct arguments { +struct Arguments { char* inFile; - char* outFile; + char* logFile; }; -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? adding fflushes fixes it, but I shouldnt need to add that. - - struct arguments arguments = {NULL, NULL}; - +static bool parseArgs(int argc, char* argv[], struct Arguments* arguments) { + bool succsess = true; switch (argc) { case 3: - arguments.outFile = argv[2]; + arguments->logFile = argv[2]; // fallthrough case 2: - arguments.inFile = argv[1]; + arguments->inFile = argv[1]; break; default: printf("%s\n%s\n", args_doc, doc); - return EXIT_FAILURE; + succsess = false; break; } + return succsess; +} - FILE* inFile = fopen(arguments.inFile, "r"); +// puts the current time into buff in the form of YYYY-MM-DD HH:MM:SS. +// buff MUST BE at least 20 chars long. +static bool getTimeString(char* buff) { + bool succsess = true; + time_t posixTime = time(NULL); + if (posixTime != (time_t)(-1)) { + struct tm utcTime = *gmtime(&posixTime); + // strftime returns 0 if the buffer was not big enough. + if (strftime(buff, 20, "%F %T", &utcTime) == 0) { + succsess = false; + } + } else { + succsess = false; + } + + return succsess; +} + +static bool sendToLog(FILE* logFile, char* lineBuff) { + bool succsess = true; + char currentTime[20] = ""; + if (getTimeString(currentTime)) { + if (fprintf(logFile, "%s ", currentTime) >= 0) { + if (fputs(lineBuff, logFile) >= 0) { + fflush(logFile); + } else { + succsess = false; + } + } else { + succsess = false; + } + } else { + succsess = false; + } + + return succsess; +} + +static bool initInputFile(FILE** inFile, char* fileName) { + bool succsess = true; + *inFile = fopen(fileName, "r"); if (!inFile) { - printf("error opening file %s\n", arguments.inFile); - return EXIT_FAILURE; + printf("error opening file %s\n", fileName); + succsess = false; } - FILE* outFile; - if (arguments.outFile != NULL) { - outFile = fopen(arguments.outFile, "w"); - if (!outFile) { - printf("error opening file %s\n", arguments.outFile); - return EXIT_FAILURE; + return succsess; +} + +static bool initLogFile(FILE** logFile, char* fileName) { + bool succsess = true; + if (fileName != NULL) { + *logFile = fopen(fileName, "w"); + if (logFile != NULL) { + if (fputs("start of log\n", *logFile) < 0) { + printf("could not write to %s\n", fileName); + succsess = false; + } + } else { + printf("error opening file %s\n", fileName); + succsess = false; } - if (fputs("start of log\n", outFile) < 0) { - printf("could not write to %s\n", arguments.outFile); - return EXIT_FAILURE; - } - fflush(outFile); + fflush(*logFile); } + return succsess; +} + +static void processLines(FILE* inFile, FILE* logFile) { char* lineBuff = NULL; size_t lineBuffSize = 0; - ssize_t line_size; + ssize_t lineSize; do { - line_size = getline(&lineBuff, &lineBuffSize, inFile); + lineSize = getline(&lineBuff, &lineBuffSize, inFile); printf("%s", lineBuff); - if (arguments.outFile != NULL) { - fputs(lineBuff, outFile); - fflush(outFile); + if (logFile != NULL) { + sendToLog(logFile, lineBuff); } - } while (line_size >= 0); + } while (lineSize >= 0); - // these things should be done by the OS when we exit. - // free(lineBuff); - // fclose(inFile); - // fclose(outFile); - - return EXIT_SUCCESS; + free(lineBuff); +} + +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? adding fflushes fixes it, but I shouldnt + // need to add that. + + int ret = EXIT_SUCCESS; + struct Arguments arguments = {NULL, NULL}; + if (parseArgs(argc, argv, &arguments)) { + FILE* inFile = NULL; + if (initInputFile(&inFile, arguments.inFile)) { + FILE* outFile = NULL; + if (initLogFile(&outFile, arguments.logFile)) { + processLines(inFile, outFile); + + // these things should be done by the OS when we exit. + // fclose(inFile); + // fclose(outFile); + } else { + ret = EXIT_FAILURE; + } + } else { + ret = EXIT_FAILURE; + } + } else { + ret = EXIT_FAILURE; + } + return ret; }