diff --git a/src/cdo.c b/src/cdo.c index faf0653..4218eef 100644 --- a/src/cdo.c +++ b/src/cdo.c @@ -1,6 +1,8 @@ #include +#include "cmd.h" + int main (int argc, char *argv[]) { - printf("Welcome to %s!", argv[0]); + struct CommandLineArg* args = parse_args(argc, argv); return 0; } diff --git a/src/cmd.c b/src/cmd.c new file mode 100644 index 0000000..325799a --- /dev/null +++ b/src/cmd.c @@ -0,0 +1,39 @@ +#include "cmd.h" +#include "tools/log.h" +#include "tools/buffer.h" + +#include + +const struct CommandLineArg supported_args [] = { + { + "PROJECT", + "Path to the project to be used for looking up TODO's", + "Current Working directory", + STRING + }, + {} +}; + +void usage(void) { + Buffer * usage_lines = buffer_create(DEFAULT_USAGE_LINE_LEN); + buffer_append(usage_lines, "Usage: cdo [PROJECT] [OPTION]\n"); + buffer_append(usage_lines, "Parse TODO's of the PROJECT.\n\n"); + for (int i = 0; supported_args[i].type != EMPTY; i++) { + buffer_append(usage_lines, supported_args[i].name); + buffer_append(usage_lines, " - "); + buffer_append(usage_lines, supported_args[i].description); + buffer_append(usage_lines, " [DEFAULT = "); + buffer_append(usage_lines, supported_args[i].value); + } + buffer_append(usage_lines, "\n]"); + buffer_flush(usage_lines); +} + +struct CommandLineArg* parse_args(const int argc, char* argv[]) { + if (argc < 2) { + LOG_ERROR_USER("At least 1 argument required."); + usage(); + exit(1); + } + return NULL; +} \ No newline at end of file diff --git a/src/cmd.h b/src/cmd.h new file mode 100644 index 0000000..0b70ee5 --- /dev/null +++ b/src/cmd.h @@ -0,0 +1,24 @@ +#ifndef __CMD_H__ +#define __CMD_H__ + +#define MAX_CMD_LINE_ARG_NAME_LEN 256 +#define MAX_CMD_LINE_ARG_DESC_LEN 1024 +#define DEFAULT_USAGE_LINE_LEN 256 +#define SUPPORTED_ARGS_AMOUNT 2 + +typedef enum { + EMPTY, + STRING +} CmdType; + +struct CommandLineArg { + char name[MAX_CMD_LINE_ARG_NAME_LEN]; + char description[MAX_CMD_LINE_ARG_DESC_LEN]; + char* value; + CmdType type; +}; + +struct CommandLineArg* parse_args(const int argc, char* argv[]); +void usage(void); + +#endif /*__CMD_H__*/ \ No newline at end of file diff --git a/src/tools/buffer.c b/src/tools/buffer.c new file mode 100644 index 0000000..8099c86 --- /dev/null +++ b/src/tools/buffer.c @@ -0,0 +1,40 @@ +#include "buffer.h" +#include "log.h" + +#include +#include + +Buffer* buffer_create(size_t capacity) { + Buffer* buffer = (Buffer*)malloc(sizeof(Buffer)); + buffer->data = (char*)malloc(capacity); + buffer->size = 0; + buffer->capacity = capacity; + return buffer; +} + +void buffer_append(Buffer* buffer, const char* str) { + size_t len = strlen(str); + if (buffer->size + len >= buffer->capacity) { + buffer->capacity *= 2; + buffer->data = (char*)realloc(buffer->data, buffer->capacity); + } + strcpy(buffer->data + buffer->size, str); + buffer->size += len; +} + +void buffer_flush(Buffer* buffer) { + printf("%s", buffer->data); + buffer_free(buffer); +} + +void buffer_free(Buffer* buffer) { + if (!buffer->data || !buffer) { + LOG_WARNING("Trying to free NULL pointer"); + } + free(buffer->data); + buffer->data = NULL; + free(buffer); + buffer = NULL; +} + + diff --git a/src/tools/buffer.h b/src/tools/buffer.h new file mode 100644 index 0000000..8787b66 --- /dev/null +++ b/src/tools/buffer.h @@ -0,0 +1,17 @@ +#include + +#ifndef __BUFFER_H__ +#define __BUFFER_H__ + +typedef struct { + char* data; + size_t size; + size_t capacity; +} Buffer; + +Buffer* buffer_create(size_t capacity); +void buffer_append(Buffer* buffer, const char* str); +void buffer_flush(Buffer* buffer); +void buffer_free(Buffer* buffer); + +#endif /*__BUFFER_H__*/ diff --git a/src/tools/log.h b/src/tools/log.h new file mode 100644 index 0000000..ae36ff6 --- /dev/null +++ b/src/tools/log.h @@ -0,0 +1,104 @@ +#ifndef __THREAD_COMMON_LOG_H_ +#define __THREAD_COMMON_LOG_H_ + +#include +#include +#include + + +/* ================= Settings ================== */ +#define LOG_COLORED_OUTPUT +#define HIGH_PRIORITY_DEBUG +#define LOG_DEBUG_MESSAGES 0 +/* ================= Settings ================== */ + +// internal debug defines +#ifdef HIGH_PRIORITY_DEBUG +#include +#define INT_ASSERT(statement) assert(statement) +#else +#define INT_ASSERT(statement) +#endif + +#ifdef LOG_COLORED_OUTPUT +#define C_INFO "\x1b[34mINFO\x1b[0m" +#define C_DEBUG "\x1b[35mDEBUG\x1b[0m" +#define C_DEBUG_ISR "\x1b[36mDEBUG_ISR\x1b[0m" +#define C_WARN "\x1b[33mWARNING\x1b[0m" +#define C_ERROR "\x1b[31mERROR\x1b[0m" +#else +#define C_INFO "INFO" +#define C_DEBUG "DEBUG" +#define C_DEBUG_ISR "DEBUG_ISR" +#define C_WARN "WARNING" +#define C_ERROR "ERROR" +#endif +#define LOG_BUFFER_MAX_CAP 256 +#define LOG_MESSAGE_MAX_CAP 150 + +#define _LOG_STREAMOUT(message, message_length) \ + INT_ASSERT(message_length > 0); \ + printf("%.*s", message_length, message) + +static void create_log_line(const char * _status, + const char * _location, + const char * _func, + const size_t _line, + const char * _fmt, ...) +{ + va_list args; + va_start(args, _fmt); + char message [LOG_BUFFER_MAX_CAP] = {0}; + int message_len = vsnprintf(message, LOG_BUFFER_MAX_CAP, _fmt, args); + va_end(args); + char buffer [LOG_BUFFER_MAX_CAP] = {0}; + int buffer_len = snprintf(buffer, LOG_BUFFER_MAX_CAP, + "[%s] In [File: %s] [Func: %s] [Line: %zu] %.*s\n", + _status, + _location, + _func, + _line, + message_len, + message); + _LOG_STREAMOUT(buffer, buffer_len); + +} + +static void create_log_line_simple(const char * _status, + const char * _fmt, ...) +{ + va_list args; + va_start(args, _fmt); + char message [LOG_BUFFER_MAX_CAP] = {0}; + int message_len = vsnprintf(message, LOG_BUFFER_MAX_CAP, _fmt, args); + va_end(args); + char buffer [LOG_BUFFER_MAX_CAP] = {0}; + int buffer_len = snprintf(buffer, LOG_BUFFER_MAX_CAP, + "[%s] %.*s\n", + _status, + message_len, + message); + _LOG_STREAMOUT(buffer, buffer_len); + +} + +#define LOG_INFO( fmt, ...) \ + create_log_line(C_INFO, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__); + +#define LOG_WARNING(fmt, ...) \ + create_log_line(C_WARN, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__); + +#define LOG_ERROR(fmt, ...) \ + create_log_line(C_ERROR, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__); \ + exit(1); + +#define LOG_ERROR_USER(fmt, ...) \ + create_log_line_simple(C_ERROR, fmt, ##__VA_ARGS__); + +#if LOG_DEBUG_MESSAGES +#define LOG_DEBUG(fmt, ...) \ + create_log_line(C_DEBUG, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__); +#endif + + +#endif /* __THREAD_COMMON_LOG_H_ */