-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutil.c
More file actions
187 lines (158 loc) · 5.09 KB
/
util.c
File metadata and controls
187 lines (158 loc) · 5.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/* util.c - this file contains implementations of different
helper functions used within the program */
#include "include/util.h"
#include <ctype.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <unistd.h>
/* prompt
Shows the input promt.
Consists of the user, the hostname,
the working directory and a dollar sign.
*/
void prompt(void)
{
/* Get current user. */
char* user = getenv("USER");
/* Get hostname. */
char* hostname = getenv("HOSTNAME");
/* Get current working directory. */
char* working_directory = get_working_directory();
/* Show error if no memory for the current working directory
could be allocated. Then, display an error message and
only a dollar sign. */
if (working_directory == NULL) {
printf("$ ");
return;
}
/* Prompt for user input. If username or hostname were not set
trough environment variables, omit hostname or both user
and hostname. */
if (user == NULL) {
/* Print current working directory. */
printf("%s$ ", working_directory);
} else if ((user != NULL) && (hostname == NULL)) {
/* Print current working directory with username. */
printf("%s:%s$ ", user, working_directory);
} else {
/* Print current working directory with user and hostname. */
printf("%s@%s:%s$ ", user, hostname, working_directory);
}
/* Free allocated memory. */
free(working_directory);
working_directory = NULL;
}
/* get_working_directory
Returns the current working directory as string.
In case the current directory can not be fetched,
the error message is printed and a null pointer is
returned instead.
*/
char* get_working_directory(void) {
char* result = getcwd(NULL, 0);
if (result == NULL) {
perror("Could not get current working directory");
}
return result;
}
/* read_input
Reads input from the command line until either enter was pressed
or the maximum input length has been reached.
Not necessary spaces and tabs are skipped.
Returns a null pointer if no memory could be allocated
for reading the input string.
*/
char* read_input(void)
{
char* input = (char*) malloc(INITIAL_INPUT_LENGTH);
int position = 0;
int input_buffer_length = INITIAL_INPUT_LENGTH;
char current_char;
bool last_input_was_letter = false;
/* Return null pointer if the memory allocation failed. */
if (input == NULL) {
perror("Could not read input");
return NULL;
}
do {
/* Get last pressed key. */
current_char = getwc(stdin);
/* Terminate the string if enter was pressed. */
if (current_char == '\n') {
input[position] = '\0';
/* Add a space or tab only to the input string
if a letter was entered before. */
} else if (isblank(current_char)) {
if (last_input_was_letter) {
input[position] = current_char;
position++;
last_input_was_letter = false;
}
} else {
/* Otherwise, add the character. */
input[position] = current_char;
position++;
last_input_was_letter = true;
}
/* Increase input buffer if necessary. */
if (position == input_buffer_length) {
input_buffer_length *= 2;
input = realloc(input, input_buffer_length);
/* Return null pointer if reallocation failed. */
if (input == NULL) {
perror("Could not read input");
return NULL;
}
}
} while (current_char != '\n');
return input;
}
/* get_nr_of_spaces
Counts the space characters in a given string and returns them
*/
int get_nr_of_spaces(char* input) {
int result = 0;
int i = 0;
do {
if (input[i] == ' ') {
result++;
}
i++;
} while(i <= strlen(input));
return result;
}
/* get_arguments_from_input
Splits the input string into an array of strings.
The space symbol is used as delimiter here, so the string is cut
whereever a space is found.
This function is used for splitting the user input into an array.
The first element contains the program name.
The following elements contain the arguments handed over to the program.
If no arguments are handed over, the array contains only one element.
A null pointer is returned in case not enough memory for the
array can be allocated.
*/
char** get_arguments_from_input(char* input)
{
const char delimiter[] = " ";
char** result = (char**) malloc((get_nr_of_spaces(input) + 2) * sizeof(char**));
int i = 0;
char* part = strtok(input, delimiter);
/* Return null pointer if the memory allocation failed. */
if (result == NULL) {
perror("Can not get input");
return NULL;
}
/* Populate the array with the program and the comman-line options */
do {
result[i] = part;
i++;
part = strtok(NULL, delimiter);
} while (part != NULL);
result[i] = NULL;
return result;
}