-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathterminal.c
197 lines (153 loc) · 5.14 KB
/
terminal.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
#include "project-defs.h"
static command_t command;
// reads int only not floats and increments the char_count to the index of after the number
bool read_int(char *line, uint8_t* char_count, int16_t* int_value_ptr) {
char *ptr = line + *char_count; // the variable that will extract the next digit from
unsigned char c; // the variable that will hold each digit
c = *ptr++; // extracting the next digit!
// catching negative values :)
bool isnegative = false;
if (c == '-') {
isnegative = true;
c = *ptr++;
// incrementing pointer anyway if +ve sign is there
} else if (c == '+') {
c = *ptr++;
}
// Algorithm to convert char digits to int
uint32_t intval = 0;
uint8_t ndigit = 0; // current digit read index
int8_t exp = 0; // NOT uint8_t as this must hold +ve and -ve numbers
while (1) {
c -= '0';
if (c <= 9) {
ndigit++;
if (ndigit <= MAX_INT_DIGITS) {
intval = (((intval << 2) + intval) << 1) + c; // intval*10 + c
//
} else {
exp++; // Drop overflow digits
}
} else {
// encountered a non integer character
break;
}
c = *ptr++;
}
// Return if no digits have been read.
if (!ndigit) { return(false); };
long int lival;
lival = (long int)intval;
if (exp > 0) {
do {
lival *= 10.0;
} while (--exp > 0);
}
// Assign floating point value with correct sign.
if (isnegative) {
*int_value_ptr = -lival;
} else {
*int_value_ptr = lival;
}
*char_count = ptr - line - 1; // Set char_counter to next statement
return (true);
}
LINE_STATUS terminal_execute_line(char* line) {
uint8_t char_count = 0;
char letter;
uint16_t int_value = 0; // temporary int value that gets read from the terminal then assigned to another variable of any other c component
// Resetting the command
memset(&command, 0, sizeof(command_t));
while (line[char_count] != 0) {
/* [ Step 1: Capture read character and type check] */
// Reading letter argument, aka which function to execute
letter = line[char_count];
// incrementing char_count for next iteration
char_count++;
// IMP: capital letters are command letters
// small letters are argument letters
// Checking letter is a letter
// checking if it's before A or after z or any character in between Z and a in the ascii table
if ( letter < 'A' || letter > 'z' || (letter > 'Z' && letter < 'a')) {
printf("\rExpected a letter!\n");
return LINE_FAILED;
}
// small letter case is not a command, it's parameter
if (!(letter >= 'a' && letter < 'z') && \
(command.command_type != COMMAND_NOT_SET)) {
printf("Can't have >1 command letter in one command!\n");
return LINE_FAILED;
}
/* [ Step 2: Identify and Initiate command_t variable] */
switch(letter) {
case 'A':
// testing reading int argument
if (!read_int(line, &char_count, &int_value)) {
printf("Bad integer Number Format\n");
return LINE_FAILED;
}
command.command_type = COMMAND_TEST_INT_READING;
break;
case 'N':
command.command_type = COMMAND_GET_NRF24_REGISTERS;
break;
case 'T':
command.command_type = COMMAND_GET_CURRENT_TIME;
break;
case 'i':
// reading int argument for a multi-argument command
if (!read_int(line, &char_count, &int_value)) {
printf("Bad int Number Format\n");
return LINE_FAILED;
}
command.i = int_value;
break;
case 'j':
// reading int argument for a multi-argument command
if (!read_int(line, &char_count, &int_value)) {
printf("Bad int Number Format\n");
return LINE_FAILED;
}
command.j = int_value;
break;
default:
printf("Command Letter '%c' Not Implemented\n", letter);
return LINE_FAILED;
}
}
/* [ Step 3: Error checking ] */
switch(command.command_type) {
case COMMAND_TEST_INT_READING:
case COMMAND_GET_CURRENT_TIME:
case COMMAND_GET_NRF24_REGISTERS:
break;
default:
// if the command_type is not set (COMMAND_NOT_SET).
// then a correct command wasn't passed in Step2.
// which means that the default: of Step2 should run
// so WTF?!??!
printf("SHOULD NEVER REACH HERE IN ERROR CHECKING.\n");
return LINE_FAILED;
}
/* [ Step 4: Execute! ] */
switch(command.command_type) {
case COMMAND_TEST_INT_READING:
printf("Read INT value: %d\n", int_value);
break;
case COMMAND_GET_NRF24_REGISTERS:
nrf24_print_internal_register_values();
break;
case COMMAND_GET_CURRENT_TIME:
/* report("Time: %lu\n", get_current_time()); */
report("From STC\n"); //TODO: JUST FOR SHOWING
break;
default:
// if the command_type is not set (COMMAND_NOT_SET).
// then a correct command wasn't passed in Step2.
// which means that the default: of Step2 should run
// so WTF?!??!
printf("SHOULD NEVER REACH HERE.");
return LINE_FAILED;
}
return LINE_PASSED;
}