Merge pull request #3 from lucic71/dev_args

Dev args
This commit is contained in:
Lucian 2021-03-19 18:10:05 +02:00 committed by GitHub
commit 8c97f3bb8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 402 additions and 0 deletions

67
char_dyn_arr.c Normal file
View File

@ -0,0 +1,67 @@
// SPDX-License-Identifier: BSD-2
#include "char_dyn_arr.h"
#include <errno.h>
#include <stdlib.h>
struct char_dyn_arr *init_char_dyn_arr(int size)
{
struct char_dyn_arr *a;
a = NULL;
a = calloc(1, sizeof(struct char_dyn_arr));
if (!a)
goto free_and_exit;
a->data = calloc(size, sizeof(char *));
if (!(a->data))
goto free_and_exit;
a->used = 0;
a->size = size;
return a;
free_and_exit:
free(a);
free(a->data);
return NULL;
}
int insert_char_dyn_arr(struct char_dyn_arr *a, char *e)
{
if (a->used == a->size) {
a->size *= 2;
a->data = realloc(a->data, a->size * sizeof(char *));
if (!(a->data))
goto free_and_exit;
}
a->data[a->used++] = e;
return CHAR_DYN_ARR_OK;
free_and_exit:
free(a);
free(a->data);
return CHAR_DYN_ARR_FAILED;
}
extern void free_char_dyn_arr(struct char_dyn_arr *a)
{
int i;
if (!a)
return;
if (a->data) {
for (i = 0; i < a->used; i++)
free(a->data[i]);
}
free(a->data);
free(a);
}

20
include/char_dyn_arr.h Normal file
View File

@ -0,0 +1,20 @@
/* SPDX-License-Identifier: BSD-2 */
#ifndef _char_dyn_arr
#define _char_dyn_arr
#define CHAR_DYN_ARR_OK 0
#define CHAR_DYN_ARR_FAILED -1
struct char_dyn_arr {
char **data;
int used;
int size;
};
extern struct char_dyn_arr *init_char_dyn_arr(int size);
extern int insert_char_dyn_arr(struct char_dyn_arr *a, char *e);
extern void free_char_dyn_arr(struct char_dyn_arr *a);
#endif

18
include/pp_args.h Normal file
View File

@ -0,0 +1,18 @@
/* SPDX-License-Identifier: BSD-2 */
#ifndef _pp_args
#define _pp_args
#include "pp.h"
#include "char_dyn_arr.h"
struct args {
struct char_dyn_arr *inc_dirs;
char *in_file;
char *out_file;
};
extern void pp_free_args(struct args *args);
extern struct args *pp_parse_args(int argc, char **argv, string_map_t define_map);
#endif

View File

@ -1,3 +1,5 @@
/* SPDX-License-Identifier: BSD-2 */
#ifndef _pp_defines_h
#define _pp_defines_h
@ -7,6 +9,7 @@
#define PP_FAILED -3
#define PP_OMEM -4
#define PP_BAD_FILE_OP -5
#define PP_BAD_ARGS -6
extern int pp_errno;

3
pp.c
View File

@ -264,6 +264,9 @@ int pp_create_file_without_defines(FILE *in, FILE *out)
line = NULL;
len = 0;
is_inside_multiline_define = 0;
prev_is_inside_multiline_define = 0;
while ((read = getline(&line, &len, in)) != -1) {
stripped_line = strdup(line);

291
pp_args.c Normal file
View File

@ -0,0 +1,291 @@
// SPDX-License-Identifier: BSD-2
#include "pp_args.h"
#include "pp_defines.h"
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#define DEFINE_FLAG "-D"
#define DEFINE_FLAG_SZ (sizeof(DEFINE_FLAG) - 1)
#define INCLUDE_FLAG "-I"
#define INCLUDE_FLAG_SZ (sizeof(INCLUDE_FLAG) - 1)
#define OUTPUT_FLAG "-o"
#define OUTPUT_FLAG_SZ (sizeof(OUTPUT_FLAG) - 1)
int _is_split_define_flag(char *flag)
{
return !strncmp(flag, DEFINE_FLAG, DEFINE_FLAG_SZ)
&& strlen(flag) == DEFINE_FLAG_SZ;
}
int _is_tied_define_flag(char *flag)
{
return !strncmp(flag, DEFINE_FLAG, DEFINE_FLAG_SZ)
&& strlen(flag) != DEFINE_FLAG_SZ;
}
int _is_include_flag(char *flag)
{
return !strncmp(flag, INCLUDE_FLAG, INCLUDE_FLAG_SZ);
}
int _is_output_flag(char *flag)
{
return !strncmp(flag, OUTPUT_FLAG, OUTPUT_FLAG_SZ);
}
int _is_in_out_file_arg(char *prev_flag)
{
return !_is_split_define_flag(prev_flag) && !_is_include_flag(prev_flag)
&& !_is_output_flag(prev_flag);
}
int _is_unrecognized_flag(char *flag)
{
return flag[0] == '-' && !_is_split_define_flag(flag)
&& !_is_include_flag(flag) && !_is_output_flag(flag);
}
int _calloc_and_check(char **p, int sz)
{
*p = calloc(sz, sizeof(char));
if (!(*p)) {
pp_errno = PP_OMEM;
return PP_FAILED;
}
return PP_OK;
}
int _add_sym_mapp_to_map(string_map_t define_map, char *sym_mapp)
{
char *sym;
char *mapp;
char *eq_pos;
int sym_len;
int mapp_len;
int ret;
int res;
if (!strstr(sym_mapp, "=")) {
res = hashmap_put(define_map, sym_mapp, "");
if (res != MAP_OK)
return PP_FAILED;
else
return PP_OK;
}
sym = NULL;
mapp = NULL;
eq_pos = strstr(sym_mapp, "=");
sym_len = eq_pos - sym_mapp;
ret = _calloc_and_check(&sym, sym_len + 1);
if (ret == PP_FAILED)
goto free_and_exit;
strncpy(sym, sym_mapp, sym_len);
eq_pos++;
mapp_len = strlen(eq_pos);
ret = _calloc_and_check(&mapp, mapp_len + 1);
if (ret == PP_FAILED)
goto free_and_exit;
strncpy(mapp, eq_pos, mapp_len);
ret = hashmap_put(define_map, sym, mapp);
if (ret == MAP_OK)
return PP_OK;
else
return PP_FAILED;
free_and_exit:
free(sym);
free(mapp);
return ret;
}
struct args *_create_struct_args(void)
{
struct args *ret;
ret = NULL;
ret = calloc(1, sizeof(struct args));
if (!ret)
goto free_and_exit;
ret->inc_dirs = init_char_dyn_arr(2);
if (!(ret->inc_dirs))
goto free_and_exit;
return ret;
free_and_exit:
free_char_dyn_arr(ret->inc_dirs);
free(ret);
return NULL;
}
int _collect_inc_dirs(struct args *args, char *inc_dir)
{
int res;
res = insert_char_dyn_arr(args->inc_dirs, inc_dir);
if (res == CHAR_DYN_ARR_OK)
return PP_OK;
else
return PP_FAILED;
}
int _add_in_file_to_args(struct args *args, char *in_file)
{
char *alloc_in_file;
int in_file_len;
int res;
in_file_len = strlen(in_file);
res = _calloc_and_check(&alloc_in_file, in_file_len + 1);
if (res == PP_FAILED)
return PP_FAILED;
strncpy(alloc_in_file, in_file, in_file_len);
args->in_file = alloc_in_file;
return PP_OK;
}
int _add_out_file_to_args(struct args *args, char *out_file)
{
char *alloc_out_file;
int out_file_len;
int res;
out_file_len = strlen(out_file);
res = _calloc_and_check(&alloc_out_file, out_file_len + 1);
if (res == PP_FAILED)
return PP_FAILED;
strncpy(alloc_out_file, out_file, out_file_len);
args->out_file = alloc_out_file;
return PP_OK;
}
struct args *pp_parse_args(int argc, char **argv, string_map_t define_map)
{
struct args *args;
char *sym_mapp;
int i;
int in_file_found;
int out_file_found;
int is_flag;
int res;
args = _create_struct_args();
if (!args)
return NULL;
in_file_found = 0;
out_file_found = 0;
for (i = 0; i < argc; i++) {
is_flag = 0;
if (_is_unrecognized_flag(argv[i])) {
pp_errno = PP_BAD_ARGS;
goto free_and_exit;
}
if (_is_split_define_flag(argv[i])) {
if (i + 1 < argc) {
res = _add_sym_mapp_to_map(define_map, argv[i + 1]);
if (res == PP_FAILED)
goto free_and_exit;
is_flag = 1;
} else {
goto free_and_exit;
}
}
if (_is_tied_define_flag(argv[i])) {
sym_mapp = argv[i] + DEFINE_FLAG_SZ;
res = _add_sym_mapp_to_map(define_map, sym_mapp);
if (res == PP_FAILED)
goto free_and_exit;
is_flag = 1;
}
if (_is_include_flag(argv[i])) {
if (i + 1 < argc) {
res = _collect_inc_dirs(args, argv[i + 1]);
if (res == PP_FAILED)
goto free_and_exit;
is_flag = 1;
} else {
goto free_and_exit;
}
}
if (_is_output_flag(argv[i])) {
if (i + 1 < argc) {
res = _add_out_file_to_args(args, argv[i]);
if (res == PP_FAILED)
goto free_and_exit;
is_flag = 1;
} else {
goto free_and_exit;
}
}
if (!is_flag && !in_file_found && i - 1 >= 0 && _is_in_out_file_arg(argv[i - 1])) {
res = _add_in_file_to_args(args, argv[i]);
if (res == PP_FAILED)
goto free_and_exit;
in_file_found = 1;
} else if (!is_flag && in_file_found && i - 1 >= 0 && _is_in_out_file_arg(argv[i - 1])) {
if (out_file_found) {
pp_errno = PP_BAD_ARGS;
goto free_and_exit;
}
res = _add_out_file_to_args(args, argv[i]);
if (res == PP_FAILED)
goto free_and_exit;
out_file_found = 1;
}
}
return args;
free_and_exit:
pp_free_args(args);
return NULL;
}
void pp_free_args(struct args *args)
{
if (!args)
return;
free_char_dyn_arr(args->inc_dirs);
free(args->in_file);
free(args->out_file);
free(args);
}