16static void trim(
const char **s,
size_t *len)
20 while (n && p[n - 1] ==
' ')
24 while (n && *p ==
' ')
34static bool field_is(
const HaasMdcResp *r,
size_t idx,
const char *lit)
36 if (idx >= r->n_fields)
40 const char *f = r->field[idx];
41 size_t fl = r->field_len[idx];
45 if (lit[i] ==
'\0' || f[i] != lit[i])
50 return lit[i] ==
'\0';
54static bool parse_u32(
const char *s,
size_t len, uint32_t *out)
62 for (
size_t i = 0; i < len; i++)
64 if (s[i] <
'0' || s[i] >
'9')
68 v = v * 10 + (uint32_t)(s[i] -
'0');
79size_t pc_haas_mdc_build_q(
char *buf,
size_t cap, uint16_t qnum)
85 pc_sb sb_q = {buf, cap, 0,
true};
92size_t pc_haas_mdc_build_var(
char *buf,
size_t cap, uint32_t var)
98 pc_sb sb_var = {buf, cap, 0,
true};
105bool pc_haas_mdc_parse(
const char *buf,
size_t len, HaasMdcResp *out)
115 bool have_stx =
false;
116 for (
size_t i = 0; i < len; i++)
118 if (buf[i] == PC_HAAS_MDC_STX)
130 bool have_etb =
false;
131 for (
size_t i = stx + 1; i < len; i++)
133 if (buf[i] == PC_HAAS_MDC_ETB)
145 const char *p = buf + stx + 1;
146 size_t plen = etb - stx - 1;
150 for (
size_t i = 0; i <= plen; i++)
152 if (i == plen || p[i] ==
',')
154 const char *f = p + start;
155 size_t fl = i - start;
157 if (out->n_fields < PC_HAAS_MDC_MAX_FIELDS)
159 out->field[out->n_fields] = f;
160 out->field_len[out->n_fields] = fl;
166 return out->n_fields > 0;
169bool pc_haas_mdc_field(
const HaasMdcResp *r,
size_t idx,
const char **p,
size_t *l)
171 if (!r || idx >= r->n_fields)
181 *l = r->field_len[idx];
186bool pc_haas_mdc_value(
const HaasMdcResp *r,
const char **p,
size_t *l)
188 return pc_haas_mdc_field(r, 1, p, l);
191bool pc_haas_mdc_is_error(
const HaasMdcResp *r)
193 return r && field_is(r, 0,
"UNKNOWN");
196bool pc_haas_mdc_parse_status(
const HaasMdcResp *r, HaasMdcStatus *out)
203 out->program =
nullptr;
204 out->program_len = 0;
205 out->status =
nullptr;
208 out->parts_valid =
false;
210 if (field_is(r, 0,
"STATUS"))
214 if (r->n_fields >= 2)
216 out->status = r->field[1];
217 out->status_len = r->field_len[1];
221 if (field_is(r, 0,
"PROGRAM") && r->n_fields >= 3)
224 out->program = r->field[1];
225 out->program_len = r->field_len[1];
226 out->status = r->field[2];
227 out->status_len = r->field_len[2];
228 if (r->n_fields >= 5)
231 if (parse_u32(r->field[4], r->field_len[4], &n))
234 out->parts_valid =
true;
242bool pc_haas_mdc_parse_macro(
const HaasMdcResp *r, uint32_t *var,
const char **value,
size_t *value_len)
244 if (!r || r->n_fields < 3 || !field_is(r, 0,
"MACRO"))
249 if (!parse_u32(r->field[1], r->field_len[1], &v))
259 *value = r->field[2];
263 *value_len = r->field_len[2];
268bool pc_haas_mdc_dprnt_line(
const char *buf,
size_t len,
const char **text,
size_t *text_len)
270 if (!buf || len == 0)
275 for (
size_t i = 0; i < len; i++)
277 if (buf[i] == PC_HAAS_MDC_STX)
286 while (n && (*p == (
char)PC_HAAS_MDC_PROMPT || *p ==
'\r' || *p ==
'\n' || *p == 0x12))
292 while (n && (p[n - 1] ==
'\r' || p[n - 1] ==
'\n' || p[n - 1] == 0x14))
Haas Machine Data Collection (MDC) Q-command codec (PC_ENABLE_HAAS_MDC) - a zero-heap codec for the d...
Bounded no-heap string builder that fails closed on overflow (one shared copy).
size_t pc_sb_finish(pc_sb *b)
NUL-terminate and return the built length, or 0 if the build overflowed.
void pc_sb_ch(pc_sb *b, char c)
Append a single character.
void pc_sb_lit(pc_sb *b, const char(&s)[N])
Append a string literal. The array parameter deduces N, so the length is a constant.
void pc_sb_u32(pc_sb *b, uint32_t v)
Append v as decimal (no leading zeros; "0" for zero).
Bump-append target; ok latches false once an append would overflow cap.