1#include <myaw.h>
2
3
4uint16_t PwTypeId_MwStatus = 0;
5
6uint16_t MW_END_OF_BLOCK = 0;
7uint16_t MW_PARSE_ERROR = 0;
8
9_PwValue _mw_parser_error(MwParser* parser, char* source_file_name, unsigned source_line_number,
10 unsigned line_number, unsigned char_pos, char* description, ...)
11{
12 _PwValue status = PW_NULL;
13 if (!pw_create(PwTypeId_MwStatus, &status)) {
14 // this never happens because init always returns true
15 return PwStatus(PW_ERROR);
16 }
17 // status is PW_SUCCESS by default
18 if (status.status_code != PW_SUCCESS) {
19 // this should never happen
20 return status;
21 }
22
23 // mandatory fields must be initialized first
24 _pw_set_status_location(&status, source_file_name, source_line_number);
25
26 // the base Status constructor does not allocate struct_data for PW_SUCCESS
27 // do this by setting status code and description
28
29 status.status_code = MW_PARSE_ERROR;
30 _pw_set_status_desc(&status, "");
31 if (status.struct_data == nullptr) {
32 return PwStatus(PW_ERROR_OOM);
33 }
34
35 MwStatusData* status_data = _mw_status_data_ptr(&status);
36 status_data->line_number = line_number;
37 status_data->position = char_pos;
38
39 va_list ap;
40 va_start(ap);
41 _pw_set_status_desc_ap(&status, description, ap);
42 va_end(ap);
43 return status;
44}
45
46static bool mw_status_hash(PwMethod_Basic_hash* mthis, PwValuePtr self, PwHashContext* ctx, _PwCompoundChain* tail)
47{
48 if (!pw_super(mthis, self, ctx, tail)) {
49 return false;
50 }
51 MwStatusData* data = pw_this_data(self);
52 _pw_hash_uint64(ctx, data->line_number);
53 _pw_hash_uint64(ctx, data->position);
54 return true;
55}
56
57static bool mw_status_dump(PwMethod_Basic_dump* mthis, PwValuePtr self, FILE* fp, int indent, _PwCompoundChain* tail)
58{
59 if (!pw_super(mthis, self, fp, indent, tail)) {
60 return false;
61 }
62 _pw_print_indent(fp, indent);
63 MwStatusData* data = pw_this_data(self);
64 fprintf(fp, "Line %u, position %u\n", data->line_number, data->position);
65 return true;
66}
67
68static bool mw_status_to_string(PwMethod_Basic_to_string* mthis, PwValuePtr self, PwValuePtr result, _PwCompoundChain* tail)
69{
70 if (!pw_super(mthis, self, result, tail)) {
71 return false;
72 }
73 MwStatusData* data = _mw_status_data_ptr(self);
74
75 char location[48];
76 snprintf(location, sizeof(location), " Line %u, position %u: ",
77 data->line_number, data->position);
78
79 return pw_string_append(result, location, nullptr);
80}
81
82static PwInterface_Basic mw_status_basic_interface = {
83 .hash = { .func = mw_status_hash },
84 .dump = { .func = mw_status_dump },
85 .to_string = { .func = mw_status_to_string }
86};
87
88[[ gnu::constructor ]]
89static void init_mw_status()
90{
91 _pw_init_types();
92
93 if (PwTypeId_MwStatus) {
94 return;
95 }
96
97 PwTypeId_MwStatus = pw_add_type2("MwStatus", MwStatusData,
98 PW_PARENTS,
99 PwTypeId_Status,
100 PW_INTERFACES,
101 PwInterfaceId_Basic, &mw_status_basic_interface);
102 // init status codes
103 MW_END_OF_BLOCK = pw_define_status("END_OF_BLOCK");
104 MW_PARSE_ERROR = pw_define_status("PARSE_ERROR");
105}