cmd #1: use dynamic memory for managing args

This commit is contained in:
tylen 2024-09-23 22:01:29 +00:00 committed by Vasily Davydov
parent 9d40f081ac
commit 92f9c03128
5 changed files with 87 additions and 37 deletions

View File

@ -3,7 +3,7 @@
set -xe
CC="gcc"
FLAGS="-Wall -Wpedantic"
FLAGS="-Wall -Wpedantic -ggdb"
SRCS="$(find ./src -type f -name "*.c")"
CURRENT_DIR="$(git rev-parse --show-toplevel)"
BUILD_DIR="${CURRENT_DIR}/build"

View File

@ -2,8 +2,12 @@
#include "cmd.h"
int main (int argc, char *argv[]) {
static void __attribute__((constructor)) init_cdo(void) {
atexit(exit_cmd);
init_cmd();
}
int main (int argc, char *argv[]) {
struct CommandLineArg* args = parse_args(argc, argv);
return 0;
}

View File

@ -5,43 +5,79 @@
#include <stdlib.h>
#include <string.h>
const struct CommandLineArg supported_args [] = {
{
"PROJECT",
"Path to the project to be used for looking up TODO's",
"Current Working directory",
STRING
},
{}
static struct ArgList* supported_args;
static const char* PREDEFINED_ARG_NAMES [] = {
"project"
};
static const char* PREDEFINED_ARG_DESC [] = {
"Path to the project to be used for looking up TODO's"
};
static const char* PREDEFINED_ARG_VALUES [] = {
NULL
};
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);
for (int i = 0; i < ARG_COUNT; i++) {
buffer_append(usage_lines, supported_args->args[i].name);
buffer_append(usage_lines, " - ");
buffer_append(usage_lines, supported_args[i].description);
buffer_append(usage_lines, supported_args->args[i].description);
if (supported_args->args[i].value) {
buffer_append(usage_lines, " [DEFAULT = ");
buffer_append(usage_lines, supported_args[i].value);
buffer_append(usage_lines, supported_args->args[i].value);
buffer_append(usage_lines, "]");
}
buffer_append(usage_lines, "\n]");
}
buffer_append(usage_lines, "\n");
buffer_flush(usage_lines);
}
void init_cmd(void) {
return
static struct CommandLineArg* renderArg(ArgName name) {
struct CommandLineArg* e = malloc(sizeof(struct CommandLineArg));
e->name = NULL;
e->description = NULL;
e->value = NULL;
if (PREDEFINED_ARG_NAMES[name]) {
e->name = malloc(strlen(PREDEFINED_ARG_NAMES[name]) + 1);
strcpy(e->name, PREDEFINED_ARG_NAMES[name]);
}
if (PREDEFINED_ARG_DESC[name]) {
e->description = malloc(strlen(PREDEFINED_ARG_DESC[name]) + 1);
strcpy(e->description, PREDEFINED_ARG_DESC[name]);
}
if (PREDEFINED_ARG_VALUES[name]) {
e->value = malloc(strlen(PREDEFINED_ARG_VALUES[name]) + 1);
strcpy(e->value, PREDEFINED_ARG_VALUES[name]);
}
return e;
}
void create_arg_list(struct ArgList* list, size_t capacity) {
void init_cmd(void) {
supported_args = create_arg_list(ARG_COUNT);
for (int i = 0; i < ARG_COUNT; i++) {
append_arg(supported_args, renderArg(i));
}
}
void exit_cmd(void) {
free_arg_list(supported_args);
}
struct ArgList* create_arg_list(size_t capacity) {
struct ArgList* list = NULL;
list = (struct ArgList*) malloc(sizeof(struct ArgList));
list->args = (struct CommandLineArg*) malloc(capacity * sizeof(struct CommandLineArg));
list->size = 0;
list->capacity = capacity;
return list;
}
void append_arg(struct ArgList* list, struct CommandLineArg arg) {
void append_arg(struct ArgList* list, struct CommandLineArg* arg) {
if (list->size + 1 >= list->capacity) {
list->capacity *= 2;
list->args =
@ -51,11 +87,20 @@ void append_arg(struct ArgList* list, struct CommandLineArg arg) {
list->capacity * sizeof(struct CommandLineArg)
);
}
memcpy(
list->args + (list->size * sizeof(struct CommandLineArg)),
&arg,
sizeof(struct CommandLineArg)
);
memcpy(list->args + list->size, arg, sizeof(struct CommandLineArg));
free(arg);
list->size += 1;
}
void free_arg_list(struct ArgList* list) {
for (size_t i = 0; i < ARG_COUNT; i++) {
free(list->args[i].name);
free(list->args[i].description);
free(list->args[i].value);
}
free(list->args);
free(list);
}
struct CommandLineArg* parse_args(const int argc, char* argv[]) {

View File

@ -1,21 +1,22 @@
#ifndef __CMD_H__
#define __CMD_H__
#include <stdlib.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;
ARG_PROJECT,
ARG_COUNT
} ArgName;
struct CommandLineArg {
char name[MAX_CMD_LINE_ARG_NAME_LEN];
char description[MAX_CMD_LINE_ARG_DESC_LEN];
char* name;
char* description;
char* value;
CmdType type;
};
struct ArgList {
@ -24,12 +25,12 @@ struct ArgList {
size_t size;
};
struct ArgList* supported_arg_list;
struct CommandLineArg* parse_args(const int argc, char* argv[]);
void init_cmd(void);
void create_arg_list(struct ArgList* list, size_t capacity);
void append_arg(struct ArgList* list, struct CommandLineArg arg);
void exit_cmd(void);
struct ArgList* create_arg_list(size_t capacity);
void append_arg(struct ArgList* list, struct CommandLineArg* arg);
void free_arg_list(struct ArgList* list);
void usage(void);
#endif /*__CMD_H__*/

View File

@ -1,8 +1,8 @@
#include <stdlib.h>
#ifndef __BUFFER_H__
#define __BUFFER_H__
#include <stdlib.h>
typedef struct {
char* data;
size_t size;