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