Kestrel Interface
Loading...
Searching...
No Matches
kest_eff_parser.c
Go to the documentation of this file.
1#include <stdlib.h>
2#include <stdarg.h>
3#include <string.h>
4#include <stdio.h>
5
6#include "kest_int.h"
7
8#ifndef PRINTLINES_ALLOWED
9#define PRINTLINES_ALLOWED 1
10#endif
11
12static const char *FNAME = "kest_eff_parser.c";
13
14const char *ver_str = "v1.0";
15
18
20
31
41
47
48void *kest_parser_alloc(size_t size)
49{
51}
52
53char *kest_parser_strndup(const char *str, int n)
54{
55 size_t len = strnlen(str, n);
56
57 char *new_str = kest_parser_alloc(len + 1);
58
59 if (!new_str) return NULL;
60 memcpy(new_str, str, len);
61 new_str[len] = '\0';
62
63 return new_str;
64}
65
67{
68 if (!ps)
69 return ERR_NULL_PTR;
70
71 kest_token_ll *tokens = ps->tokens;
72 kest_ast_node **root_ptr = &ps->ast;
73
75
76 if (!root)
77 return ERR_ALLOC_FAIL;
78
79 *root_ptr = root;
80
82 root->data = NULL;
83 root->child = NULL;
84 root->next = NULL;
85
86 // Let's do a first pass to find the sections
87
88 kest_ast_node *current_section = NULL;
89 kest_ast_node *next_section = NULL;
92 kest_token_ll *current_token = tokens;
93 kest_token_ll *prev_tokens[4] = {NULL, NULL, NULL, NULL};
94
95 kest_token_ll *current_sec_start = NULL;
96
97 int section_start_score = 0;
98 int next_section_start_score;
99
100 int token_n = 0;
101 int line = 1;
102
103 while (current_token)
104 {
105 token_n++;
106
107 if (current_token->data)
108 {
109 if (token_is_newline(current_token->data))
110 {
111 line++;
112 token_n = 1;
113 }
114
115 next_section_start_score = get_section_start_score(current_token->data, section_start_score);
116
117 if (section_start_score == 2)
118 {
119 if (next_section_start_score == 3)
120 {
121 next_section = kest_parser_alloc(sizeof(kest_ast_node));
122
123 if (!next_section)
124 return ERR_ALLOC_FAIL;
125
126 next_section->type = KEST_AST_NODE_SECTION;
127 next_section->data = NULL;
128 next_section->next = NULL;
129 next_section->child = NULL;
130
132
133 if (!ns)
134 {
135 return ERR_ALLOC_FAIL;
136 }
137
138 ns->name = kest_parser_strndup(current_token->data, 16);
139
140 if (!ns->name)
141 {
142 return ERR_ALLOC_FAIL;
143 }
144
145 ns->dict = NULL;
146
147 next_section->data = (void*)ns;
148
149 if (current_section && cs)
150 {
151 cs->tokens = kest_token_span_to_ll(current_sec_start->next, prev_tokens[3]);
152 current_section->next = next_section;
153 }
154 else
155 {
156 root->child = next_section;
157 }
158
159 current_section = next_section;
160 current_sec_start = current_token;
161 cs = ns;
162 }
163 else
164 {
165 kest_parser_error_at(ps, current_token, "Invalid section name \"%s\"", current_token->data);
166 return ERR_BAD_ARGS;
167 }
168
169 section_start_score = 0;
170 }
171 else
172 {
173 section_start_score = next_section_start_score;
174 }
175 }
176
177 prev_tokens[0] = current_token;
178 prev_tokens[1] = prev_tokens[0];
179 prev_tokens[2] = prev_tokens[1];
180 prev_tokens[3] = prev_tokens[2];
181
182 current_token = current_token->next;
183 }
184
185 if (current_section)
186 {
187 cs->tokens = kest_token_span_to_ll(current_sec_start->next, NULL);
188 }
189
190 // Now let's actually parse those sections
191
192 current_section = root->child;
193
194 // We need to do the code section last
195 kest_ast_node *info_section = NULL;
196 kest_ast_node *code_section = NULL;
197 kest_ast_node *resources_section = NULL;
198 kest_ast_node *parameters_section = NULL;
199 kest_ast_node *settings_section = NULL;
200 kest_ast_node *defs_section = NULL;
201
203
204 int ret_val;
205 while (current_section)
206 {
207 sect = (kest_eff_desc_file_section*)current_section->data;
208
209 if (!sect)
210 {
211 current_section = current_section->next;
212 continue;
213 }
214
215 if (strcmp(sect->name, "INFO") == 0)
216 {
217 if ((ret_val = kest_parse_dictionary_section(ps, current_section)) != NO_ERROR)
218 {
219 return ret_val;
220 }
221 info_section = current_section;
222 }
223 else if (strcmp(sect->name, "RESOURCES") == 0)
224 {
225 if ((ret_val = kest_parse_dictionary_section(ps, current_section)) != NO_ERROR)
226 {
227 return ret_val;
228 }
229 resources_section = current_section;
230 }
231 else if (strcmp(sect->name, "PARAMETERS") == 0)
232 {
233 if ((ret_val = kest_parse_dictionary_section(ps, current_section)) != NO_ERROR)
234 {
235 return ret_val;
236 }
237 parameters_section = current_section;
238 }
239 else if (strcmp(sect->name, "SETTINGS") == 0)
240 {
241 if ((ret_val = kest_parse_dictionary_section(ps, current_section)) != NO_ERROR)
242 {
243 return ret_val;
244 }
245 settings_section = current_section;
246 }
247 else if (strcmp(sect->name, "DEFS") == 0)
248 {
249 if ((ret_val = kest_parse_dictionary_section(ps, current_section)) != NO_ERROR)
250 {
251 return ret_val;
252 }
253 defs_section = current_section;
254 }
255 else if (strcmp(sect->name, "CODE") == 0)
256 {
257 code_section = current_section;
258 ret_val = NO_ERROR;
259 }
260 else
261 {
262 kest_parser_error(ps, "Invalid section name \"%s\"", sect->name);
263 return ERR_BAD_ARGS;
264 }
265
266 if (ret_val != NO_ERROR)
267 return ret_val;
268 current_section = current_section->next;
269 }
270
271 if (info_section)
272 {
273 if ((ret_val = kest_dictionary_section_lookup_str(info_section, "name", &ps->name)) != NO_ERROR)
274 {
275 kest_parser_error(ps, "Effect name missing");
276 return ret_val;
277 }
278 else
279 {
280 KEST_PRINTF("Found name: \"%s\"\n", ps->name ? ps->name : "(NULL)");
281 }
282 if ((ret_val = kest_dictionary_section_lookup_str(info_section, "cname", &ps->cname)) != NO_ERROR)
283 {
284 kest_parser_error(ps, "Effect cname missing");
285 return ret_val;
286 }
287 else
288 {
289 KEST_PRINTF("Found cname: \"%s\"\n", ps->cname ? ps->cname : "(NULL)");
290 }
291 }
292 else
293 {
294 kest_parser_error(ps, "INFO section missing");
295 return ERR_BAD_ARGS;
296 }
297
300
301 if (!ps->scope)
302 return ERR_ALLOC_FAIL;
303
304 if (resources_section)
305 {
306 if ((ret_val = kest_resources_section_extract(ps, &ps->resources, resources_section)) != NO_ERROR)
307 {
308 return ret_val;
309 }
310
312 }
313
314 if (parameters_section)
315 {
316 if ((ret_val = kest_parameters_section_extract(ps, &ps->parameters, parameters_section)) != NO_ERROR)
317 {
318 return ret_val;
319 }
320
323 }
324
325 if (settings_section)
326 {
327 if ((ret_val = kest_settings_section_extract(ps, &ps->settings, settings_section)) != NO_ERROR)
328 {
329 return ret_val;
330 }
331
333 KEST_PRINTF("Adding settings to scope...\n");
335 }
336
337 if (defs_section)
338 {
339 KEST_PRINTF("Adding defs to scope...\n");
340 if ((ret_val = kest_defs_section_extract(ps, ps->scope, defs_section)) != NO_ERROR)
341 {
342 return ret_val;
343 }
344 }
345
346 if (code_section)
347 {
348 if ((ret_val = kest_parse_code_section(ps, code_section)) != NO_ERROR)
349 {
350 return ret_val;
351 }
352 }
353
354 return NO_ERROR;
355}
356
358{
359 if (!ps) return ERR_NULL_PTR;
360
361 ps->tokens = NULL;
362 ps->current_token = NULL;
363
364 ps->parameters = NULL;
365 ps->resources = NULL;
366 ps->settings = NULL;
367 ps->blocks = NULL;
368 ps->cname = NULL;
369 ps->name = NULL;
370
371 ps->asm_lines = NULL;
372 ps->def_exprs = NULL;
373
374 ps->errors = 0;
375 ps->scope = NULL;
376 ps->lines = NULL;
377 ps->n_lines = 0;
378
379 return NO_ERROR;
380}
381
383{
384 if (!ps)
385 return ERR_NULL_PTR;
386
387 if (!ps->content)
388 return ERR_BAD_ARGS;
389
390 if (!ps->n_lines)
391 return NO_ERROR;
392
393 int line = 1;
394 ps->lines = kest_parser_alloc(sizeof(char*) * ps->n_lines);
395
396 if (!ps->lines)
397 return ERR_ALLOC_FAIL;
398
399 for (int i = 0; i < ps->n_lines; i++)
400 ps->lines[i] = NULL;
401
402 ps->lines[0] = ps->content;
403
404 int line_start = 0;
405
406 for (int i = 0; i < ps->file_size && line < ps->n_lines; i++)
407 {
408 if (line_start)
409 ps->lines[line++] = &ps->content[i];
410
411 line_start = 0;
412
413 if (ps->content[i] == '\n')
414 {
415 ps->content[i] = 0;
416 line_start = 1;
417 }
418 }
419
420 // It may be the case that, if the final line is just "\n", the loop will end one
421 // line early. Then, there is a risk of segfault if one tries to deref ps->lines[n_lines-1]
422 // therefore, decrement ps->n_lines to prevent this.
423 ps->n_lines = line;
424
425 return NO_ERROR;
426}
427
429{
430 if (!ps)
431 return ERR_NULL_PTR;
432
434
435 kest_dsp_resource_pll *res = ps->resources;
436 kest_filter *filter;
437
438 while (res)
439 {
440 if (res->data && res->data->type == KEST_DSP_RESOURCE_FILTER)
441 {
442 filter = (kest_filter*)res->data->data;
443
444 if (!filter)
445 break;
446
448 }
449
450 res = res->next;
451 }
452
453 return NO_ERROR;
454}
455
457{
458 if (!fname)
459 return NULL;
460
461 printf("kest_read_eff_desc_from_file\n");
462
463 kest_effect_desc *result = NULL;
465
466 int ret_val;
467
469 {
470 if ((ret_val = kest_eff_parser_init_mempool()) != NO_ERROR)
471 {
472 KEST_PRINTF("Error initialising parser mempool: %s\n", kest_error_code_to_string(ret_val));
473 return NULL;
474 }
475 }
476
478
479 FILE *src = fopen(fname, "r");
480
481 if (!src)
482 {
483 KEST_PRINTF("Failed to open file \"%s\"!\n", fname);
484 return NULL;
485 }
486
487 fseek(src, 0, SEEK_END);
488 ps.file_size = ftell(src);
489 fseek(src, SEEK_SET, 0);
490
491 ps.content = kest_parser_alloc(ps.file_size * sizeof(char) + 1);
492
493 if (!ps.content)
494 {
495 kest_parser_error(&ps, "File \"%s\" size %d too large\n", fname, ps.file_size);
496 fclose(src);
497 return NULL;
498 }
499
500 fread(ps.content, 1, ps.file_size, src);
501
502 ps.content[ps.file_size] = 0;
503
504 fclose(src);
505 src = NULL;
506
507 ps.fname = kest_parser_strndup(fname, 128);
508
510
511 int j = 0;
512
513 if (ps.errors != 0)
514 {
515 KEST_PRINTF("File \"%s\" ignored due to errors.\n", fname);
516 return NULL;
517 }
518
520
521 ret_val = kest_parse_tokens(&ps);
522
523 if (ps.errors != 0)
524 {
525 KEST_PRINTF("File \"%s\" ignored due to errors.\n", fname);
526 if (ps.parameters)
527 {
528 kest_parameter_pll_free(ps.parameters);
529 }
530 if (ps.resources)
531 {
532 kest_dsp_resource_pll_free(ps.resources);
533 }
534 if (ps.blocks)
535 {
536 kest_block_pll_free(ps.blocks);
537 }
538 return NULL;
539 }
540
541 if (ret_val == NO_ERROR)
542 {
543 KEST_PRINTF("File \"%s\" parsed sucessfully\n", fname);
544 }
545 else
546 {
547 KEST_PRINTF("File \"%s\" parsing failed. Error code: %s\n", fname, kest_error_code_to_string(ret_val));
548 }
549
550 ret_val = kest_process_asm_lines(&ps);
551
552 if (ret_val != NO_ERROR)
553 {
554 return NULL;
555 }
556
558
559 result = kest_alloc(sizeof(kest_effect_desc));
560
561 if (result)
562 {
563 kest_init_effect_desc(result);
564
565 result->parameters = ps.parameters;
566 result->resources = ps.resources;
567 result->settings = ps.settings;
568 result->blocks = ps.blocks;
569
570 result->cname = kest_strndup(ps.cname, 128);
571 result->name = kest_strndup(ps.name, 128);
572
573 result->def_exprs = ps.def_exprs;
574
576 }
577
578 return result;
579}
580
581#define KEST_PARSER_PRINT_BUFLEN 1024
582#define KEST_PARSER_PRINT_LOC_BUFLEN 128
583
584const char *err_colour = "\e[01;31m";
585const char *info_colour = "\e[01;36m";
586const char *warn_colour = "\e[01;32m";
587const char *reset_colour = "\e[0m";
588
589#define PR_LINE_INDENT 4
590
591int kest_parser_format_offending_section(char *line, int index, int length, char *buf, int buf_len, char *colour)
592{
593 if (!line || !buf)
594 return ERR_NULL_PTR;
595
596 int i, j, buf_pos;
597
598 buf_pos = 0;
599
600 for (i = 0; i < PR_LINE_INDENT; i++)
601 buf[buf_pos++] = ' ';
602
603 for (i = 0; i < index && buf_pos + 1 < buf_len && line[i] != 0; i++)
604 buf[buf_pos++] = line[i];
605
606 if (colour)
607 {
608 for (j = 0; err_colour[j] != 0 && buf_pos + 1 < buf_len; j++)
609 buf[buf_pos++] = colour[j];
610 }
611
612 for (j = 0; j < length && buf_pos < buf_len; j++)
613 buf[buf_pos++] = line[i++];
614
615 if (colour)
616 {
617 for (j = 0; reset_colour[j] != 0 && buf_pos + 1 < buf_len; j++)
618 buf[buf_pos++] = reset_colour[j];
619 }
620
621 for (j = 0; line[i] != 0 && buf_pos + 1 < buf_len; j++)
622 buf[buf_pos++] = line[i++];
623
624 if (buf_pos + index + length / 2 + 1 + PR_LINE_INDENT >= buf_len)
625 {
626 buf[buf_pos < buf_len ? buf_pos : buf_len - 1] = 0;
627 return NO_ERROR;
628 }
629 else
630 {
631 buf[buf_pos++] = '\n';
632 }
633
634 for (int i = 0; i <= index + length / 2 + PR_LINE_INDENT - 1 && buf_pos + 1 < KEST_PARSER_PRINT_BUFLEN; i++)
635 buf[buf_pos++] = '~';
636
637 buf[buf_pos++] = '^';
638 buf[buf_pos++] = 0;
639
640 return NO_ERROR;
641}
642
644{
645 char buf[KEST_PARSER_PRINT_BUFLEN];
646 va_list args;
647 va_start(args, msg);
648 vsnprintf(buf, sizeof(buf), msg, args);
649 va_end(args);
650
651 char loc_string[KEST_PARSER_PRINT_LOC_BUFLEN];
652 if (ps->fname && token)
653 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s:%d)", ps->fname, token->line);
654 else if (ps->fname)
655 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s)", ps->fname);
656 else
657 loc_string[0] = 0;
658
659 KEST_PRINTF_("%sINFO%s%s: %s\n", info_colour, loc_string, reset_colour, buf);
660
661 int ret_val;
662 if (token && token->line < ps->n_lines && ps->lines && ps->lines[token->line])
663 {
664 ret_val = kest_parser_format_offending_section(ps->lines[token->line - 1], token->index, strlen(token->data), buf, KEST_PARSER_PRINT_BUFLEN, info_colour);
665
666 if (ret_val == NO_ERROR)
667 KEST_PRINTF_("%s\n", buf);
668 }
669}
670
671void kest_parser_warn_at(kest_eff_parsing_state *ps, kest_token_ll *token, const char *msg, ...)
672{
673 char buf[KEST_PARSER_PRINT_BUFLEN];
674 va_list args;
675 va_start(args, msg);
676 vsnprintf(buf, sizeof(buf), msg, args);
677 va_end(args);
678
679 char loc_string[KEST_PARSER_PRINT_LOC_BUFLEN];
680 if (ps->fname && token)
681 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s:%d)", ps->fname, token->line);
682 else if (ps->fname)
683 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s)", ps->fname);
684 else
685 loc_string[0] = 0;
686
687 KEST_PRINTF_("\e[01;32mWARNING%s\e[0m: %s\n", loc_string, buf);
688
689 int ret_val;
690 if (token && token->line < ps->n_lines && ps->lines && ps->lines[token->line])
691 {
692 ret_val = kest_parser_format_offending_section(ps->lines[token->line - 1], token->index, strlen(token->data), buf, KEST_PARSER_PRINT_BUFLEN, warn_colour);
693
694 if (ret_val == NO_ERROR)
695 KEST_PRINTF_("%s\n", buf);
696 }
697}
698
699void kest_parser_error_at(kest_eff_parsing_state *ps, kest_token_ll *token, const char *msg, ...)
700{
701 char buf[KEST_PARSER_PRINT_BUFLEN];
702 int tok_len;
703 int buf_pos;
704 int i;
705 int j;
706 int k;
707 va_list args;
708 va_start(args, msg);
709 vsnprintf(buf, sizeof(buf), msg, args);
710 va_end(args);
711
712 char loc_string[KEST_PARSER_PRINT_LOC_BUFLEN];
713 if (ps->fname && token)
714 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s:%d)", ps->fname, token->line);
715 else if (ps->fname)
716 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s)", ps->fname);
717 else
718 loc_string[0] = 0;
719
720 ps->errors++;
721 KEST_PRINTF_("%sERROR%s%s: %s\n", err_colour, loc_string, reset_colour, buf);
722
723 int ret_val;
724 if (token && token->line < ps->n_lines && ps->lines && ps->lines[token->line])
725 {
726 ret_val = kest_parser_format_offending_section(ps->lines[token->line - 1], token->index, strlen(token->data), buf, KEST_PARSER_PRINT_BUFLEN, err_colour);
727
728 if (ret_val == NO_ERROR)
729 KEST_PRINTF_("%s\n", buf);
730 }
731}
732
733void kest_parser_print_info_at_line(kest_eff_parsing_state *ps, int line, const char *msg, ...)
734{
735 char buf[KEST_PARSER_PRINT_BUFLEN];
736 va_list args;
737 va_start(args, msg);
738 vsnprintf(buf, sizeof(buf), msg, args);
739 va_end(args);
740
741 char loc_string[KEST_PARSER_PRINT_LOC_BUFLEN];
742 if (ps->fname)
743 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s:%d)", ps->fname, line);
744 else if (ps->fname)
745 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s)", ps->fname);
746 else
747 loc_string[0] = 0;
748
749 KEST_PRINTF_("\e[01;36mINFO%s\e[0m: %s\n", loc_string, buf);
750}
751
752void kest_parser_warn_at_line(kest_eff_parsing_state *ps, int line, const char *msg, ...)
753{
754 char buf[KEST_PARSER_PRINT_BUFLEN];
755 va_list args;
756 va_start(args, msg);
757 vsnprintf(buf, sizeof(buf), msg, args);
758 va_end(args);
759
760 char loc_string[KEST_PARSER_PRINT_LOC_BUFLEN];
761 if (ps->fname)
762 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s:%d)", ps->fname, line);
763 else if (ps->fname)
764 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s)", ps->fname);
765 else
766 loc_string[0] = 0;
767
768 KEST_PRINTF_("\e[01;32mWARNING%s\e[0m: %s\n", loc_string, buf);
769}
770
771void kest_parser_error_at_line(kest_eff_parsing_state *ps, int line, const char *msg, ...)
772{
773 char buf[KEST_PARSER_PRINT_BUFLEN];
774 va_list args;
775 va_start(args, msg);
776 vsnprintf(buf, sizeof(buf), msg, args);
777 va_end(args);
778
779 char loc_string[KEST_PARSER_PRINT_LOC_BUFLEN];
780 if (ps->fname)
781 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s:%d)", ps->fname, line);
782 else if (ps->fname)
783 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s)", ps->fname);
784 else
785 loc_string[0] = 0;
786
787 ps->errors++;
788 KEST_PRINTF_("\e[01;31mERROR%s\e[0m: %s\n", loc_string, buf);
789}
790
792{
793 char buf[KEST_PARSER_PRINT_BUFLEN];
794 va_list args;
795 va_start(args, msg);
796 vsnprintf(buf, sizeof(buf), msg, args);
797 va_end(args);
798
799 char loc_string[KEST_PARSER_PRINT_LOC_BUFLEN];
800 if (ps->fname && node)
801 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s:%d)", ps->fname, node->line);
802 else if (ps->fname)
803 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s)", ps->fname);
804 else
805 loc_string[0] = 0;
806
807 KEST_PRINTF_("\e[01;36mINFO%s\e[0m: %s\n", loc_string, buf);
808}
809
811{
812 char buf[KEST_PARSER_PRINT_BUFLEN];
813 va_list args;
814 va_start(args, msg);
815 vsnprintf(buf, sizeof(buf), msg, args);
816 va_end(args);
817
818 char loc_string[KEST_PARSER_PRINT_LOC_BUFLEN];
819 if (ps->fname && node)
820 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s:%d)", ps->fname, node->line);
821 else if (ps->fname)
822 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s)", ps->fname);
823 else
824 loc_string[0] = 0;
825
826 KEST_PRINTF_("\e[01;32mWARNING%s\e[0m: %s\n", loc_string, buf);
827}
828
830{
831 char buf[KEST_PARSER_PRINT_BUFLEN];
832 va_list args;
833 va_start(args, msg);
834 vsnprintf(buf, sizeof(buf), msg, args);
835 va_end(args);
836
837 char loc_string[KEST_PARSER_PRINT_LOC_BUFLEN];
838 if (ps->fname && node)
839 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s:%d)", ps->fname, node->line);
840 else if (ps->fname)
841 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s)", ps->fname);
842 else
843 loc_string[0] = 0;
844
845 ps->errors++;
846 KEST_PRINTF_("\e[01;31mERROR%s\e[0m: %s\n", loc_string, buf);
847}
848
849void kest_parser_print_info(kest_eff_parsing_state *ps, const char *msg, ...)
850{
851 char buf[KEST_PARSER_PRINT_BUFLEN];
852 va_list args;
853 va_start(args, msg);
854 vsnprintf(buf, sizeof(buf), msg, args);
855 va_end(args);
856
857 char loc_string[KEST_PARSER_PRINT_LOC_BUFLEN];
858 if (ps->fname && ps->current_token)
859 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s:%d)", ps->fname, ps->current_token->line);
860 else if (ps->fname)
861 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s)", ps->fname);
862 else
863 loc_string[0] = 0;
864
865 KEST_PRINTF_("\e[01;36INFO%s\e[0m: %s\n", loc_string, buf);
866}
867
868void kest_parser_warn(kest_eff_parsing_state *ps, const char *msg, ...)
869{
870 char buf[KEST_PARSER_PRINT_BUFLEN];
871 va_list args;
872 va_start(args, msg);
873 vsnprintf(buf, sizeof(buf), msg, args);
874 va_end(args);
875
876 char loc_string[KEST_PARSER_PRINT_LOC_BUFLEN];
877 if (ps->fname && ps->current_token)
878 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s:%d)", ps->fname, ps->current_token->line);
879 else if (ps->fname)
880 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s)", ps->fname);
881 else
882 loc_string[0] = 0;
883
884 KEST_PRINTF_("\e[01;32mWARNING%s\e[0m: %s\n", loc_string, buf);
885}
886
887void kest_parser_error(kest_eff_parsing_state *ps, const char *msg, ...)
888{
889 char buf[KEST_PARSER_PRINT_BUFLEN];
890 va_list args;
891 va_start(args, msg);
892 vsnprintf(buf, sizeof(buf), msg, args);
893 va_end(args);
894
895 char loc_string[KEST_PARSER_PRINT_LOC_BUFLEN];
896 if (ps->fname && ps->current_token)
897 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s:%d)", ps->fname, ps->current_token->line);
898 else if (ps->fname)
899 snprintf(loc_string, KEST_PARSER_PRINT_LOC_BUFLEN, " (%s)", ps->fname);
900 else
901 loc_string[0] = 0;
902
903 ps->errors++;
904
905 KEST_PRINTF_("\e[01;31mERROR%s\e[0m: %s\n", loc_string, buf);
906}
void * kest_alloc(size_t size)
Definition kest_alloc.c:11
char * kest_strndup(const char *str, size_t n)
Definition kest_alloc.c:73
int kest_process_asm_lines(kest_eff_parsing_state *ps)
int kest_bump_arena_reset(kest_bump_arena *arena)
int kest_bump_arena_init(kest_bump_arena *arena, size_t capacity)
void * kest_bump_arena_alloc(kest_bump_arena *arena, size_t size)
int kest_bump_arena_destroy(kest_bump_arena *arena)
int kest_init_effect_desc(kest_effect_desc *eff)
int kest_effect_desc_generate_res_rpt(kest_effect_desc *eff)
char * kest_parser_strndup(const char *str, int n)
int kest_parser_lineize_content(kest_eff_parsing_state *ps)
void kest_parser_print_info_at_node(kest_eff_parsing_state *ps, kest_ast_node *node, const char *msg,...)
const char * err_colour
int init_parsing_state(kest_eff_parsing_state *ps)
int kest_parser_mempool_initialised
void kest_parser_warn_at_line(kest_eff_parsing_state *ps, int line, const char *msg,...)
void kest_parser_warn_at_node(kest_eff_parsing_state *ps, kest_ast_node *node, const char *msg,...)
#define KEST_PARSER_PRINT_BUFLEN
const char * reset_colour
kest_allocator * kest_parser_allocator
int kest_eff_parser_reset_mempool()
int kest_parse_tokens(kest_eff_parsing_state *ps)
int kest_parser_compute_formats(kest_eff_parsing_state *ps)
const char * info_colour
void kest_parser_warn_at(kest_eff_parsing_state *ps, kest_token_ll *token, const char *msg,...)
void kest_parser_print_info_at_line(kest_eff_parsing_state *ps, int line, const char *msg,...)
int kest_eff_parser_init_mempool()
void kest_parser_print_info(kest_eff_parsing_state *ps, const char *msg,...)
int kest_parser_format_offending_section(char *line, int index, int length, char *buf, int buf_len, char *colour)
void kest_parser_error_at_node(kest_eff_parsing_state *ps, kest_ast_node *node, const char *msg,...)
#define PR_LINE_INDENT
#define KEST_PARSER_PRINT_LOC_BUFLEN
void kest_parser_error(kest_eff_parsing_state *ps, const char *msg,...)
kest_bump_arena kest_eff_parser_mempool
const char * warn_colour
void * kest_parser_alloc(size_t size)
void kest_parser_print_info_at(kest_eff_parsing_state *ps, kest_token_ll *token, const char *msg,...)
kest_effect_desc * kest_read_eff_desc_from_file(char *fname)
int kest_eff_parser_deinit_mempool()
void kest_parser_error_at_line(kest_eff_parsing_state *ps, int line, const char *msg,...)
void kest_parser_error_at(kest_eff_parsing_state *ps, kest_token_ll *token, const char *msg,...)
const char * ver_str
void kest_parser_warn(kest_eff_parsing_state *ps, const char *msg,...)
#define KEST_AST_NODE_SECTION
#define KEST_EFF_PARSER_MEM_POOL_SIZE_KB
#define KEST_AST_NODE_ROOT
int kest_parse_dictionary_section(kest_eff_parsing_state *ps, kest_ast_node *section)
int kest_resources_section_extract(kest_eff_parsing_state *ps, kest_dsp_resource_pll **list, kest_ast_node *sect)
int kest_parameters_section_extract(kest_eff_parsing_state *ps, kest_parameter_pll **list, kest_ast_node *sect)
int kest_dictionary_section_lookup_str(kest_ast_node *section, const char *name, const char **result)
int kest_parse_code_section(kest_eff_parsing_state *ps, kest_ast_node *section)
int kest_settings_section_extract(kest_eff_parsing_state *ps, kest_setting_pll **list, kest_ast_node *sect)
int kest_defs_section_extract(kest_eff_parsing_state *ps, kest_expr_scope *scope, struct kest_ast_node *sect)
int get_section_start_score(char *str, int current_score)
const char * kest_error_code_to_string(int error_code)
#define ERR_ALLOC_FAIL
#define ERR_BAD_ARGS
#define NO_ERROR
#define ERR_NULL_PTR
int kest_expr_scope_add_settings(kest_expr_scope *scope, kest_setting_pll *settings)
int kest_expr_scope_init(kest_expr_scope *scope)
int kest_expr_scope_add_params(kest_expr_scope *scope, kest_parameter_pll *params)
int kest_filter_compute_format(kest_filter *filter, kest_expr_scope *scope)
int kest_settings_assign_ids(kest_setting_pll *list)
int kest_parameters_assign_ids(kest_parameter_pll *list)
#define KEST_PRINTF_(...)
Definition kest_printf.h:11
#define KEST_PRINTF(...)
Definition kest_printf.h:10
int kest_compute_register_formats(kest_block_pll *blocks, kest_expr_scope *scope)
int kest_resources_assign_handles(kest_dsp_resource_pll *list)
#define KEST_DSP_RESOURCE_FILTER
int token_is_newline(char *str)
int kest_tokenize_content(kest_eff_parsing_state *ps)
kest_token_ll * kest_token_span_to_ll(kest_token_ll *start, kest_token_ll *end)
struct kest_ast_node * child
struct kest_ast_node * next
struct kest_dictionary * dict
kest_expr_scope * scope
kest_token_ll * current_token
kest_named_expression_pll * def_exprs
kest_dsp_resource_pll * resources
kest_block_pll * blocks
kest_parameter_pll * parameters
kest_setting_pll * settings
struct kest_asm_line_pll * asm_lines
kest_parameter_pll * parameters
kest_block_pll * blocks
kest_setting_pll * settings
const char * cname
kest_dsp_resource_pll * resources
const char * name
kest_named_expression_pll * def_exprs
struct kest_token_ll * next