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.
This commit is contained in:
Gabe Venberg 2023-09-12 09:03:54 -05:00
parent 187bb3f761
commit 85c2e213b5

View file

@ -1,71 +1,143 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
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;
}
if (fputs("start of log\n", outFile) < 0) {
printf("could not write to %s\n", arguments.outFile);
return EXIT_FAILURE;
} else {
printf("error opening file %s\n", fileName);
succsess = false;
}
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);
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.
// free(lineBuff);
// fclose(inFile);
// fclose(outFile);
return EXIT_SUCCESS;
} else {
ret = EXIT_FAILURE;
}
} else {
ret = EXIT_FAILURE;
}
} else {
ret = EXIT_FAILURE;
}
return ret;
}