SayoriOS  0.3.3
eBatRuntime.c
1 #include "kernel.h"
2 #include "eBat.h"
3 #include "eBatRuntime.h"
4 
5 BAT_GoTo_T* bat_runtime_find_goto(BAT_T* bat, char* key){
6  bat_debug("[Find GoTo] Size: %d\n", bat->Size_GT);
7  for (int i = 0; i < bat->Size_GT; i++){
8  BAT_GoTo_T* gt = (BAT_GoTo_T*) bat->GoTo[i];
9  bat_debug(" |--- '%s' == '%s'\n", gt->Identifier, key);
10  if (strcmp(gt->Identifier, key) == 0){
11  bat_debug(" |--- TRUE\n");
12  return gt;
13  }
14  }
15  bat_debug(" |--- NULL RETURN\n");
16  return NULL;
17 }
18 
19 void bat_runtime_echo(BAT_T* bat,BAT_GROUP_T* group){
20  if (bat->Echo == 1 && group->Size > 0){
21  printf("%s ", EBAT_CONFIG_HELLO_LINE);
22  for (int i = 0; i < group->Size; i++){
23  BAT_TOKEN_T *Line = (BAT_TOKEN_T *) group->Tokens[i];
24  if (Line->type == BAT_TOKEN_TYPE_VARIABLE) {
25  printf("%c%s%c ", '%', Line->value,'%');
26  } else if (Line->type == BAT_TOKEN_TYPE_STRING) {
27  printf("\"%s\" ", Line->value);
28  } else {
29  printf("%s ", Line->value);
30  }
31 
32  }
33  printf("\n");
34  }
35  #ifdef DEBUG
36  if (bat->Debug == 1){
37  for (int y = 0; y < group->Size; y++){
38  BAT_TOKEN_T* xtok = (BAT_TOKEN_T*) group->Tokens[y];
39  bat_debug(" |--- [%d | %d] Tok: [%d] %s | Val: %s \n", y+1, group->Size, xtok->type, bat_debug_type(xtok->type), xtok->value);
40  }
41  }
42  #endif
43 }
44 
45 int bat_runtime_equal_var_and_string(int Line, BAT_TOKEN_T* Data1, BAT_TOKEN_T* Eq, BAT_TOKEN_T* Data2) {
46  if (Data1->type != BAT_TOKEN_TYPE_VARIABLE){
47  bat_fatalerror(Line, "The first value must be a variable.");
48  return 0;
49  }
50  if (Data2->type != BAT_TOKEN_TYPE_STRING){
51  bat_fatalerror(Line, "The second value must be a string.");
52  return 0;
53  }
54  eBatCheckModule(Line, EBAT_CONFIG_SYSTEM_SET, "System.Set");
55  eBatCheckVariable(Line, Data1->value, D1);
56 
57  qemu_ok("D1: '%s' && D3 '%s'", D1, Data2->value);
58 
59  int ret = 0;
60  if (Eq->type == BAT_TOKEN_TYPE_EQUAL){
61  ret = (strcmp(D1, Data2->value) == 0?1:0);
62  } else {
63  ret = (strcmp(D1, Data2->value) != 0?1:0);
64  }
65 
66 
67  free(D1);
68  return ret;
69 }
70 
71 int bat_runtime_equal(int Line, BAT_TOKEN_T* Data1, BAT_TOKEN_T* Eq, BAT_TOKEN_T* Data2) {
72  if (Data1->type != Data2->type || (Data1->type != BAT_TOKEN_TYPE_VARIABLE && Data1->type != BAT_TOKEN_TYPE_NUMBER)) {
73  bat_fatalerror(Line, "You cannot compare different types of data. Only NUMBERS and VARIABLES are allowed to be compared.");
74  return 0;
75  }
76  if (Data1->type == BAT_TOKEN_TYPE_VARIABLE) {
77  eBatCheckModule(Line, EBAT_CONFIG_SYSTEM_SET, "System.Set");
78  eBatCheckVariable(Line, Data1->value, D1);
79  eBatCheckVariable(Line, Data2->value, D2);
80  if (D1 == NULL || D2 == NULL){
81  if (D1 != NULL) free((void*) D1);
82  if (D2 != NULL) free((void*) D2);
83  return 0;
84  }
85 
86  int ret = (strcmp(D1, D2) == 0?1:0);
87 
88  free(D1);
89  free(D2);
90  return ret;
91  } else if (Data1->type == BAT_TOKEN_TYPE_NUMBER){
92  int a = bat_strtol(Data1->value);
93  int b = bat_strtol(Data2->value);
94  switch (Eq->type) {
95  case BAT_TOKEN_TYPE_EQUAL:{
96  return (a == b?1:0);
97  }
98  case BAT_TOKEN_TYPE_NOT_EQUAL:{
99  return (a != b?1:0);
100  }
101  case BAT_TOKEN_TYPE_GREATER:{
102  return (a > b?1:0);
103  }
104  case BAT_TOKEN_TYPE_LESS:{
105  return (a < b?1:0);
106  }
107  case BAT_TOKEN_TYPE_LESS_EQUAL:{
108  return (a <= b?1:0);
109  }
110  case BAT_TOKEN_TYPE_GREATER_EQUAL:{
111  return (a >= b?1:0);
112  }
113  default:
114  return 0;
115  }
116  }
117  return 0;
118 }
119 
120 int bat_runtime_eval(BAT_T* bat,BAT_GROUP_T* group, int line, int offset) {
121  if (group->Size <= 0) {
122  bat_debug("Group Size is 0\n");
123  return 0;
124  }
125 
126  BAT_TOKEN_T *MainTok = (BAT_TOKEN_T *) group->Tokens[offset + 0];
127 
128 
129  bat_debug("[%d] MainTok == %s\n", offset, bat_debug_type(MainTok->type));
130 
131  if (MainTok->type == BAT_TOKEN_TYPE_PAUSE){
132  bat_runtime_system_pause();
133  return 0;
134  } else if (MainTok->type == BAT_TOKEN_TYPE_GOTO){
135  EBAT_INVALIDARGC(line, group->Size - offset, 2);
136  BAT_TOKEN_T *Data1 = (BAT_TOKEN_T *) group->Tokens[offset + 1];
137  qemu_warn("Start goto '%s'\n", Data1->value);
138  BAT_GoTo_T* gt = NULL;
139  if (Data1->type == BAT_TOKEN_TYPE_VARIABLE){
140  eBatCheckVariable(line, Data1->value, D1);
141  gt = bat_runtime_find_goto(bat, D1);
142  free(D1);
143  } else {
144  gt = bat_runtime_find_goto(bat, Data1->value);
145  }
146  eBatCheckGoTo(line, gt);
147 
148  int ret = 0;
149  for (int x = 0; x < gt->Size; x++){
150  BAT_GROUP_T* group = (BAT_GROUP_T*) gt->Groups[x];
151 
152  bat_runtime_echo(bat, group);
153 
154  ret = bat_runtime_eval(bat, group, line, 0);
155  bat_debug("sysline: %d | line: %d | ret: %d\n",gt->Line, line, ret);
156  if (EBAT_CONFIG_CRITICAL_STOP == 1 && ret > 0) {
157  bat_debug("CRITICAL OUT\n");
158  bat->ErrorCode = ret;
159  return ret;
160  break;
161  }
162  }
163  bat_runtime_eval(bat, (BAT_GROUP_T*) gt->Groups, line, 0);
164  return ret;
165  }
166 
167  if (MainTok->type == BAT_TOKEN_TYPE_EXIT) {
168  EBAT_INVALIDARGC(line, group->Size - offset, 2);
169  BAT_TOKEN_T *Data1 = (BAT_TOKEN_T *) group->Tokens[offset + 1];
170  return (-1 * bat_strtol(Data1->value));
171  }
172 
173  if (MainTok->type == BAT_TOKEN_TYPE_SET) {
174  eBatCheckModule(line, EBAT_CONFIG_SYSTEM_SET, "System.Set");
175  EBAT_INVALIDARGC(line, group->Size - offset, 4);
176  BAT_TOKEN_T *VAR = (BAT_TOKEN_T *) group->Tokens[offset + 1];
177  BAT_TOKEN_T *EQ = (BAT_TOKEN_T *) group->Tokens[offset + 2];
178  BAT_TOKEN_T *SET = (BAT_TOKEN_T *) group->Tokens[offset + 3];
179  eBatCheckMixingData(line, EQ->type, BAT_TOKEN_TYPE_SET);
180  if (SET->type == BAT_TOKEN_TYPE_NOT){
181  bat_runtime_system_set(VAR->value, NULL);
182  } else {
183  eBatCheckMixingData(line, SET->type, BAT_TOKEN_TYPE_STRING);
184  bat_runtime_system_set(VAR->value, SET->value);
185  }
186  }
187  if (MainTok->type == BAT_TOKEN_TYPE_ECHO) {
188  EBAT_INVALIDMINARGC(line, group->Size - offset, 2);
189  BAT_TOKEN_T *TextTok = (BAT_TOKEN_T *) group->Tokens[offset + 1];
190  //printf("TextTok is %s => '%s'\n", bat_debug_type(TextTok->type), TextTok->value);
191  if (TextTok->type == BAT_TOKEN_TYPE_DEBUG){
192  bat->Debug = !(bat->Debug);
193  return 0;
194  } else if (TextTok->type == BAT_TOKEN_TYPE_TRUE){
195  bat->Echo = 1;
196  return 0;
197  } else if (TextTok->type == BAT_TOKEN_TYPE_FALSE){
198  bat->Echo = 0;
199  return 0;
200  }
201 
202  for (int ec = 1; ec < group->Size - offset; ec++){
203  int isStart = (ec == 1?1:0);
204  int isEnd = (group->Size - offset - 1 == ec?1:0);
205  BAT_TOKEN_T *Echo = (BAT_TOKEN_T *) group->Tokens[offset + ec];
206  //printf("\n |----- [%d | %d] '%s'\n",ec, group->Size - offset - 1, Echo->value);
207  if (Echo->type == BAT_TOKEN_TYPE_VARIABLE){
208  eBatCheckModule(line, EBAT_CONFIG_SYSTEM_SET, "System.Set");
209  eBatCheckVariable(line, Echo->value, Text);
210  bat_runtime_system_echo(Text, isStart, isEnd);
211  free(Text);
212  } else {
213  bat_runtime_system_echo(Echo->value, isStart, isEnd);
214  }
215  }
216  return 0;
217  }
218 
219  if (MainTok->type == BAT_TOKEN_TYPE_IF) {
220 
221  EBAT_INVALIDMINARGC(line, group->Size - offset, 3);
222 
223  int isNOT = 0;
224 
225  BAT_TOKEN_T *DataNOT = (BAT_TOKEN_T *) group->Tokens[offset + 1];
226  if (DataNOT->type == BAT_TOKEN_TYPE_NOT){
227  isNOT = 1;
228  }
229 
230 
231  BAT_TOKEN_T *Data1 = (BAT_TOKEN_T *) group->Tokens[offset + isNOT + 1];
232  BAT_TOKEN_T *Data2 = (BAT_TOKEN_T *) group->Tokens[offset + isNOT + 2];
233  BAT_TOKEN_T *Data3 = (BAT_TOKEN_T *) group->Tokens[offset + isNOT + 3];
234 
235  if (Data1->type == BAT_TOKEN_TYPE_EXIST) {
236  qemu_note("D1 == BAT_TOKEN_TYPE_EXIST");
237  eBatCheckModule(line, EBAT_CONFIG_FILEIO_EXIST, "FileIO.Exits");
238  if (Data2->type == BAT_TOKEN_TYPE_STRING){
239  int breq = bat_runtime_fileio_exist(Data2->value);
240  bat_debug("IF EXIST STRING: %d | %d\n", breq, (breq == 1 && isNOT == 0) ||
241  (breq != 1 && isNOT == 1));
242  if ((breq == 1 && isNOT == 0) ||
243  (breq != 1 && isNOT == 1)){
244  bat_debug("Start eval %d\n", offset + isNOT + 3);
245  bat_runtime_eval(bat, group, line, offset + isNOT + 3);
246  }
247  } else {
248  eBatCheckMixingData(line, Data2->type, BAT_TOKEN_TYPE_VARIABLE);
249  eBatCheckModule(line, EBAT_CONFIG_SYSTEM_SET, "System.Set");
250  eBatCheckVariable(line, Data2->value, Path);
251 
252  int breq = bat_runtime_fileio_exist(Path);
253  bat_debug("IF EXIST VARIABLE: %d\n", breq);
254  if ((breq == 1 && isNOT == 0) ||
255  (breq != 1 && isNOT == 1)){
256  bat_runtime_eval(bat, group, line, offset + isNOT + 3);
257  }
258 
259  free(Path);
260  }
261 
262  } else if (Data1->type == BAT_TOKEN_TYPE_NUMBER) {
263  qemu_note("D1 == BAT_TOKEN_TYPE_NUMBER");
264  EBAT_INVALIDMINARGC(line, group->Size - offset, offset + 4);
265 
266  int breq = bat_runtime_equal(line, Data1, Data2, Data3);
267  if ((breq == 1 && isNOT == 0) ||
268  (breq != 1 && isNOT == 1)){
269  bat_runtime_eval(bat, group, line, offset + isNOT + 3);
270  }
271  bat_debug("breq: %d | xret\n", breq);
272 
273  } else if (Data1->type == BAT_TOKEN_TYPE_VARIABLE && Data3->type == BAT_TOKEN_TYPE_VARIABLE) {
274  EBAT_INVALIDMINARGC(line, group->Size - offset, offset + 4);
275 
276  int breq = bat_runtime_equal(line, Data1, Data2, Data3);
277  if ((breq == 1 && isNOT == 0) ||
278  (breq != 1 && isNOT == 1)){
279  bat_runtime_eval(bat, group, line, offset + isNOT + 3);
280  }
281  } else if (Data1->type == BAT_TOKEN_TYPE_VARIABLE && Data3->type == BAT_TOKEN_TYPE_STRING) {
282  qemu_ok("D1 == VAR && D3 == STR");
283  EBAT_INVALIDMINARGC(line, group->Size - offset, offset + 4);
284 
285  int breq = bat_runtime_equal_var_and_string(line, Data1, Data2, Data3);
286  if ((breq == 1 && isNOT == 0) ||
287  (breq != 1 && isNOT == 1)) {
288  qemu_ok("[PASS] Line: %d | Off: %d", line, offset + isNOT + 4);
289  bat_runtime_eval(bat, group, line, offset + isNOT + 4);
290  }
291  }
292  }
293  if (MainTok->type == BAT_TOKEN_TYPE_RUN || MainTok->type == BAT_TOKEN_TYPE_STRING) {
294  int argc = group->Size - offset;
295  char **argv = malloc((argc + 1) * sizeof(char*));
296 
297  if (argv == NULL) {
298  return 1;
299  }
300  for (int i = 0; i < argc; i++){
301  BAT_TOKEN_T *DataX = (BAT_TOKEN_T *) group->Tokens[offset + i];
302  if (DataX->type == BAT_TOKEN_TYPE_VARIABLE){
303  eBatCheckModule(line, EBAT_CONFIG_SYSTEM_SET, "System.Set");
304  eBatCheckVariable(line, DataX->value, Text);
305  size_t slen = strlen(Text);
306  argv[i] = malloc((slen + 1) * sizeof(char));
307  if (argv[i] == NULL) {
308  return 1;
309  }
310  memset(argv[i], 0, slen + 1);
311  memcpy(argv[i], Text, slen);
312  free(Text);
313  } else {
314  size_t slen = strlen(DataX->value);
315  argv[i] = malloc((slen + 1) * sizeof(char));
316  if (argv[i] == NULL) {
317  return 1;
318  }
319  memset(argv[i], 0, slen + 1);
320  memcpy(argv[i], DataX->value, slen);
321  }
322  printf("[%d] val: '%s'\n", i, DataX->value);
323  }
324  int ret = bar_runtime_system_exec(argc, argv);
325  return ret;
326  }
327 
328  return 0;
329 }
330 
331 int bat_runtime_exec(BAT_T* bat){
332  bat_debug("========================\n");
333  bat_debug("Runtime EXEC\n");
334  bat_debug("========================\n");
335  int ret = 0;
336  for (int x = 0; x < bat->Size; x++){
337  BAT_GROUP_T* group = (BAT_GROUP_T*) bat->Group[x];
338 
339  bat_runtime_echo(bat, group);
340 
341  ret = bat_runtime_eval(bat, group, x + 1, 0);
342  bat_debug("line: %d | ret: %d\n", x +1, ret);
343  if (EBAT_CONFIG_CRITICAL_STOP == 1 && ret > 0) {
344  bat_debug("CRITICAL OUT\n");
345  //bat->ErrorCode = ret;
346  break;
347  }
348 
349  }
350  bat->ErrorCode = ret;
351  bat_debug("========================\n");
352  return ret;
353 }
size_t strlen(const char *str)
Возращает длину строки
Definition: string.c:88
int strcmp(const char *s1, const char *s2)
Сравнение строк
Definition: string.c:253
void * memset(void *ptr, char value, size_t num)
Заполнение массива указанными символами
Definition: string.c:203
void * memcpy(void *restrict destination, const void *restrict source, size_t n)
Копирование непересекающихся массивов используя SSE.
Definition: string.c:173
Definition: eBat.h:77
Definition: eBat.h:72
Definition: eBat.h:91
Definition: eBat.h:83