16size_t pc_gpib_command(
char *buf,
size_t cap,
const char *cmd)
18 if (!buf || cap == 0 || !cmd)
22 pc_sb sb_cmd = {buf, cap, 0,
true};
29size_t pc_gpib_addr(
char *buf,
size_t cap, uint8_t pad,
int sad)
31 if (!buf || cap == 0 || pad > 30)
35 pc_sb sb_addr = {buf, cap, 0,
true};
47size_t pc_gpib_read(
char *buf,
size_t cap, GpibRead mode, uint8_t ch)
53 pc_sb sb_read = {buf, cap, 0,
true};
56 case GpibRead::UNTIL_EOI:
59 case GpibRead::UNTIL_CHAR:
64 case GpibRead::UNTIL_TIMEOUT:
72size_t pc_gpib_spoll(
char *buf,
size_t cap,
int pad,
int sad)
78 pc_sb sb_spoll = {buf, cap, 0,
true};
94size_t pc_gpib_eos(
char *buf,
size_t cap, GpibEos eos)
100 pc_sb sb_eos = {buf, cap, 0,
true};
107size_t pc_gpib_build_data(uint8_t *buf,
size_t cap,
const uint8_t *src,
size_t len)
109 if (!buf || cap == 0 || (len && !src))
114 for (
size_t i = 0; i < len; i++)
117 bool esc = (c == 13 || c == 10 || c == 27 || c == 43);
118 size_t need = esc ? 2 : 1;
119 if (o + need + 1 > cap)
133bool pc_gpib_is_command(
const char *line,
size_t len)
135 return line && len >= 2 && line[0] ==
'+' && line[1] ==
'+';
139static void trim(
const char **s,
size_t *len)
143 while (n && (p[n - 1] ==
'\r' || p[n - 1] ==
'\n' || p[n - 1] ==
' '))
147 while (n && (*p ==
' '))
156bool pc_gpib_parse_decimal(
const char *s,
size_t len, uint32_t *out)
168 for (
size_t i = 0; i < len; i++)
170 if (s[i] <
'0' || s[i] >
'9')
174 v = v * 10 + (uint32_t)(s[i] -
'0');
183bool pc_gpib_parse_addr(
const char *s,
size_t len, uint8_t *pad,
int *sad)
198 while (i < len && s[i] >=
'0' && s[i] <=
'9')
200 p = p * 10 + (uint32_t)(s[i] -
'0');
210 while (i < len && s[i] ==
' ')
218 while (i < len && s[i] >=
'0' && s[i] <=
'9')
220 sa = sa * 10 + (uint32_t)(s[i] -
'0');
224 if (!sany || i != len || sa < 96 || sa > 126)
245bool pc_gpib_parse_version(
const char *s,
size_t len,
const char **ver,
size_t *ver_len)
251 static const char key[] =
"version ";
252 const size_t klen =
sizeof(key) - 1;
257 for (
size_t i = 0; i + klen <= len; i++)
259 if (memcmp(s + i, key, klen) == 0)
261 const char *v = s + i + klen;
262 size_t vlen = len - i - klen;
GPIB-over-LAN (Prologix-style) controller command codec (PC_ENABLE_GPIB) - a zero-heap codec for the ...
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_i64(pc_sb *b, int64_t v)
Append v as signed decimal (64-bit), with a leading '-' when negative.
void pc_sb_put(pc_sb *b, const char *s)
Append NUL-terminated s; leaves the buffer untouched and clears ok if it would not fit.
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.