tiny-shell 0.2
A mini shell project aiming to gain knowledge about Win32 and Linux API
Loading...
Searching...
No Matches
args.c File Reference
#include "args.h"
#include "../core/io_wrap.h"
#include "config.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
Include dependency graph for args.c:

Go to the source code of this file.

Macros

#define QUOTATION_MARK_STR   "\""
 

Enumerations

enum  { MAGIC_TOKEN = '!' , QUOTATION_MARK = '\"' }
 

Functions

os_char * transform_quotes (const os_char *str)
 Transform whitespaces inside quotes into MAGIC_TOKEN
 
void split_by_whitespaces (const os_char *str, struct args *buffer)
 
void verify_background (struct args *args)
 
void re_transform_arg (os_char *arg)
 Transform MAGIC_TOKEN inside arg into space.
 
bool args_init_from_str (struct args *obj, const os_char *input)
 Build args from an input string.
 
void args_destroy (struct args *obj)
 
struct argsargs_deep_copy (const struct args *obj)
 Deep copy the object, including arguments string.
 
void args_deep_copy_init (struct args *obj, const struct args *source)
 Initialize the object by deep copying source
 
bool is_whitespace (os_char c)
 !
 

Macro Definition Documentation

◆ QUOTATION_MARK_STR

#define QUOTATION_MARK_STR   "\""

Definition at line 13 of file args.c.

Referenced by transform_quotes().

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
MAGIC_TOKEN 
QUOTATION_MARK 

Definition at line 9 of file args.c.

9 {
10 MAGIC_TOKEN = '!',
11 QUOTATION_MARK = '\"',
12};
@ MAGIC_TOKEN
Definition args.c:10
@ QUOTATION_MARK
Definition args.c:11

Function Documentation

◆ args_deep_copy()

struct args * args_deep_copy ( const struct args * obj)

Deep copy the object, including arguments string.

Definition at line 145 of file args.c.

145 {
146 if(!obj) {
147 return NULL;
148 }
149 struct args *res = malloc(sizeof(struct args));
150 res->argc = obj->argc;
151 res->background = obj->background;
152 res->argv = (os_char **)malloc((obj->argc + 1) * sizeof(os_char *));
153 for(int i = 0; i < obj->argc; ++i) {
154 const unsigned int len = strlen(obj->argv[i]);
155 res->argv[i] = malloc((len + 1) * sizeof(os_char));
156 memcpy(res->argv[i], obj->argv[i], len * sizeof(os_char));
157 res->argv[i][len] = '\0';
158 }
159 res->argv[obj->argc] = NULL;
160 return res;
161}
Result after parsing an arbitrary string.
Definition args.h:10
os_char ** argv
Definition args.h:11
unsigned int argc
Definition args.h:12
bool background
Definition args.h:13

References args::argc, args::argv, and args::background.

◆ args_deep_copy_init()

void args_deep_copy_init ( struct args * obj,
const struct args * source )

Initialize the object by deep copying source

Definition at line 163 of file args.c.

163 {
164 assert(source != NULL && "Cannot deep copy null");
165 obj->argc = source->argc;
166 obj->background = source->background;
167 obj->argv = (os_char **)malloc((source->argc + 1) * sizeof(os_char *));
168 for(int i = 0; i < source->argc; ++i) {
169 const unsigned int len = strlen(source->argv[i]);
170 obj->argv[i] = malloc((len + 1) * sizeof(os_char));
171 memcpy(obj->argv[i], source->argv[i], len * sizeof(os_char));
172 obj->argv[i][len] = '\0';
173 }
174 obj->argv[obj->argc] = NULL;
175}

References args::argc, args::argv, and args::background.

Referenced by cmd_init_from_str().

Here is the caller graph for this function:

◆ args_destroy()

void args_destroy ( struct args * obj)

Definition at line 135 of file args.c.

135 {
136 if(!obj) {
137 return;
138 }
139 for(int i = 0; i < obj->argc; ++i) {
140 free(obj->argv[i]);
141 }
142 free((void *)obj->argv);
143}

References args::argc, and args::argv.

Referenced by cmd_destroy(), and cmd_init_from_str().

Here is the caller graph for this function:

◆ args_init_from_str()

bool args_init_from_str ( struct args * obj,
const os_char * input )

Build args from an input string.

Returns
true if initialization succeeded, false otherwise

Definition at line 117 of file args.c.

117 {
118 assert(obj && "NULL input");
119 obj->argc = 0;
120 obj->argv = NULL;
121 obj->background = false;
122 os_char *quote_transformed = transform_quotes(input);
123 if(!quote_transformed) {
124 return false;
125 }
126 split_by_whitespaces(quote_transformed, obj);
127 free(quote_transformed);
128 for(int i = 0; i < obj->argc; ++i) {
129 re_transform_arg(obj->argv[i]);
130 }
132 return true;
133}
void verify_background(struct args *args)
Definition args.c:87
void split_by_whitespaces(const os_char *str, struct args *buffer)
Definition args.c:52
os_char * transform_quotes(const os_char *str)
Transform whitespaces inside quotes into MAGIC_TOKEN
Definition args.c:16
void re_transform_arg(os_char *arg)
Transform MAGIC_TOKEN inside arg into space.
Definition args.c:108

References args::argc, args::argv, args::background, re_transform_arg(), split_by_whitespaces(), transform_quotes(), and verify_background().

Referenced by cmd_init_from_str().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_whitespace()

bool is_whitespace ( os_char c)

!

Helper function

Definition at line 177 of file args.c.

177 {
178 return c == ' ' || c == '\t' || c == '\n';
179}

Referenced by split_by_whitespaces(), and transform_quotes().

Here is the caller graph for this function:

◆ re_transform_arg()

void re_transform_arg ( os_char * arg)

Transform MAGIC_TOKEN inside arg into space.

Definition at line 108 of file args.c.

108 {
109 const unsigned int len = strlen(arg);
110 for(int i = 0; i < len; ++i) {
111 if(arg[i] == MAGIC_TOKEN) {
112 arg[i] = ' ';
113 }
114 }
115}

References MAGIC_TOKEN.

Referenced by args_init_from_str().

Here is the caller graph for this function:

◆ split_by_whitespaces()

void split_by_whitespaces ( const os_char * str,
struct args * buffer )

Definition at line 52 of file args.c.

52 {
53 os_char **argv = (os_char **)malloc(MAX_ARGC * sizeof(os_char *));
54 unsigned int argc = 0;
55
56 bool is_space = true;
57 bool was_space = true;
58 int start = 0;
59
60 for(int i = 0; true; ++i) {
61 is_space = is_whitespace(str[i]) || str[i] == '\0';
62 if(is_space && !was_space) {
63 if(argc >= MAX_ARGC) {
64 format_error("Too many arguments, max number is %u\n", MAX_ARGC);
65 break;
66 }
67 const unsigned int len = (i - 1) - start + 1;
68 argv[argc] = malloc(len + 1);
69 memcpy(argv[argc], str + start, len);
70 argv[argc][len] = '\0';
71 argc++;
72 }
73 if(!is_space && was_space) {
74 start = i;
75 }
76 was_space = is_space;
77 if(str[i] == '\0') {
78 break;
79 }
80 }
81
82 argv[argc] = NULL;
83 buffer->argc = argc;
84 buffer->argv = argv;
85}
bool is_whitespace(os_char c)
!
Definition args.c:177
#define MAX_ARGC
Definition config.h:9
void format_error(char *fmt,...)
Used format_xxx instead of printf and such for uniform output.
Definition io_wrap.c:89

References args::argc, args::argv, format_error(), is_whitespace(), and MAX_ARGC.

Referenced by args_init_from_str().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ transform_quotes()

os_char * transform_quotes ( const os_char * str)

Transform whitespaces inside quotes into MAGIC_TOKEN

Definition at line 16 of file args.c.

16 {
17 unsigned int length = 0;
18 os_char *res = malloc(strlen(str) + 1);
19 bool quote_opened = false;
20 for(int i = 0; str[i] != '\0'; ++i) {
21 if(str[i] == QUOTATION_MARK) {
22 quote_opened = !quote_opened;
23 } else if(quote_opened) {
24 if(is_whitespace(str[i]))
25 res[length] = MAGIC_TOKEN;
26 else
27 res[length] = str[i];
28 length++;
29 } else {
30 res[length] = str[i];
31 length++;
32 }
33 }
34
35 if(quote_opened) {
36 format_error("Number of " QUOTATION_MARK_STR " character is odd\n");
37 free(res);
38 return NULL;
39 }
40
41 res[length] = '\0';
42 os_char *tmp = realloc(res, length + 1);
43 if(!tmp) {
44 format_error("Cannot allocate memory for input args\n");
45 free(res);
46 return NULL;
47 } else {
48 return tmp;
49 }
50}
#define QUOTATION_MARK_STR
Definition args.c:13

References format_error(), is_whitespace(), MAGIC_TOKEN, QUOTATION_MARK, and QUOTATION_MARK_STR.

Referenced by args_init_from_str().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ verify_background()

void verify_background ( struct args * args)

Definition at line 87 of file args.c.

87 {
88 int first_oc = -1;
89 for(int i = 0; i < args->argc; ++i) {
90 if(strcmp(args->argv[i], "&") == 0) {
91 first_oc = i;
92 break;
93 }
94 }
95 if(first_oc < 0) {
96 args->background = false;
97 return;
98 }
99 free(args->argv[first_oc]);
100 for(int i = first_oc + 1; i < args->argc; ++i) {
101 args->argv[i - 1] = args->argv[i];
102 }
103 args->argc--;
104 args->background = true;
105}

References args::argc, args::argv, and args::background.

Referenced by args_init_from_str().

Here is the caller graph for this function: