This repository has been archived by the owner on Sep 19, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinput.c
276 lines (228 loc) · 4.94 KB
/
input.c
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
/*
*
* task.c
*
* Baltasar Dinis 89416
* IAED project
*
* defines input functions, to parse commands
*/
#include "input.h"
/* a string will be a command => max len < 15 */
#define CMD_BUFFER 15
/* initial alloc size for list of ulongs */
#define INIT_ULONG_LIST 32
/* max size of an ulong */
#if ULONG_WIDTH == 32
#define ULONG_BUFFER 10
#else
#define ULONG_BUFFER 20
#endif
/* max len for quoted string */
#define QUOTED_MAX 8000
/*-------------------------------*/
/* prototypes */
/*-------------------------------*/
/*-------------------------------*/
/*-------------------------------*/
/*-------------------------------*/
/*
* function: get_ulong
*
* gets an unsigned long from the stdinput
* u: pointer to an unsigned long, to be filled
*
* return: false on incorrect input
*
* the ulong has to start with a space
* either ends with a space or a newline, putting either back
* on the stream
*/
bool get_ulong(unsigned long *u)
{
char ch;
size_t i = 0;
unsigned long old= 0;
*u = 0;
if ((ch = getc(stdin)) != ' ')
return false;
while (isdigit(ch = getc(stdin)) && i < ULONG_BUFFER) {
*u *= 10;
*u += (ch - '0');
/* check for overflow */
if (*u < old)
return false;
i++;
}
if (ch == ' ' || ch == '\n') {
ungetc(ch, stdin);
return *u > 0;
}
return false;
}
/*
* function: get_ulong_list
*
* gets an unsigned long from the first token in str
* list: pointer to array of unsigned long's, to be filled
* n_elems: pointer to an size_t, number of elements in the list
*
* return: false on incorrect input
*/
bool get_ulong_list(unsigned long **list, size_t *n_elems)
{
bool flag = true;
unsigned long u = 0;
unsigned long *ull = NULL;
size_t allocd = INIT_ULONG_LIST;
size_t size = 0;
*list = NULL;
*n_elems = 0;
if (end_of_line())
return true;
ull = (unsigned long *) malloc(allocd * sizeof(unsigned long));
while (!end_of_line() &&(flag == get_ulong(&u))) {
if (size == allocd) {
allocd *= 2;
ull = (unsigned long *) realloc(ull, allocd * sizeof(unsigned long));
}
ull[size++] = u;
}
if (!flag) {
free(ull);
*list = NULL;
return false;
}
/* free unnecessary space */
*list = (unsigned long *) realloc(ull, size * sizeof(unsigned long));
*n_elems = size;
return true;
}
/*
* function: get_quoted_str
*
* gets a string with the "<substr>" format
* str: pointer to string where the token is extracted to
*
* return: false on incorrect input or buffer exceededs QUOTED_MAX
*
* stream must begin with a single space
*/
bool get_quoted_str(char **str)
{
/* allocated in stack: cheap */
char buffer[QUOTED_MAX + 1];
char ch;
size_t str_size;
if (!((ch = getc(stdin)) == ' ' && (ch = getc(stdin)) == '\"'))
return false;
str_size = 0;
buffer[str_size++] = ch;
while ((ch = getc(stdin)) != '\"' && ch != '\n' && str_size < QUOTED_MAX)
buffer[str_size++] = ch;
if (ch != '\"')
return false;
buffer[str_size++] = '\"';
buffer[str_size] = '\0';
*str = (char *) malloc((str_size + 1) * sizeof(char));
strcpy(*str, buffer);
return true;
}
/*
* function: end_of_line
*
* checks if stdin reached EOL
*
* doesn't alter the position of the stream
*
* return: bool
*/
bool end_of_line()
{
char ch = getc(stdin);
if (ch == '\n' || ch == EOF) {
ungetc(ch, stdin);
return true;
}
ungetc(ch, stdin);
return false;
}
/*
* function: end_of_file
*
* checks if stdin reached EOF
*
* return: bool
*/
bool end_of_file()
{
char ch = getc(stdin);
if (ch == EOF) {
ungetc(ch, stdin);
return true;
}
ungetc(ch, stdin);
return false;
}
/*
* function: flush_line
*
* flushes line, getting the stream to either the char after '\n'
* or leaving it at EOF
*/
void flush_line()
{
char ch;
while ((ch = getc(stdin)) != '\n' && ch != EOF);
}
/*
* function: get_cmd
*
* get a command (different commands specified in cmd.h)
*
* cmd strings are:
* * "add"
* * "duration"
* * "depend"
* * "remove"
* * "path"
* * "exit"
*
* return: cmd corresponding to a code for the commands listed
* or an INVALID command
*/
cmd get_cmd()
{
/* allocd in stack: quick and cheap */
char buffer[CMD_BUFFER];
size_t i;
char ch;
i = 0;
while (isalpha((ch = getc(stdin))) && i < CMD_BUFFER) {
buffer[i++] = ch;
}
if (ch == ' ' || ch == '\n' || ch == EOF) {
ungetc(ch, stdin);
}
else {
return INVALID;
}
buffer[i] = '\0';
if (strcmp(buffer, "add") == 0)
return ADD;
else if (strcmp(buffer, "duration") == 0)
return DUR;
else if (strcmp(buffer, "depend") == 0)
return DEP;
else if (strcmp(buffer, "remove") == 0)
return RM;
else if (strcmp(buffer, "path") == 0)
return PATH;
else if (strcmp(buffer, "first") == 0)
return FIRST;
else if (strcmp(buffer, "second") == 0)
return SECOND;
else if (strcmp(buffer, "exit") == 0)
return EXIT;
return INVALID;
}