// Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License. // See LICENSE.md for license information. // SPDX-License-Identifier: MIT // // gateText.c - message text for the gate tools (gateText.h). #define _DEFAULT_SOURCE #include #include #include #include #include #include "gateText.h" #include "toolFile.h" void gateTextAdd(ToolBufT *buf, const char *fmt, ...) { va_list args; va_start(args, fmt); gateTextAddV(buf, fmt, args); va_end(args); } void gateTextAddV(ToolBufT *buf, const char *fmt, va_list args) { va_list again; char *text; int len; va_copy(again, args); len = vsnprintf(NULL, 0, fmt, args); if (len < 0) { toolFail("bad message format"); } text = (char *)malloc((size_t)len + 1u); if (text == NULL) { toolFail("out of memory"); } vsnprintf(text, (size_t)len + 1u, fmt, again); va_end(again); toolBufAdd(buf, text, (size_t)len); free(text); } size_t gateTextFind(const uint8_t *hay, size_t hayLen, size_t from, const void *needle, size_t needleLen) { const uint8_t *first; const uint8_t *at; const uint8_t *last; if (from > hayLen || hayLen - from < needleLen) { return GATE_TEXT_NOT_FOUND; } if (needleLen == 0u) { return from; } first = (const uint8_t *)needle; last = hay + hayLen - needleLen; at = hay + from; while (at <= last) { at = (const uint8_t *)memchr(at, first[0], (size_t)(last - at) + 1u); if (at == NULL) { return GATE_TEXT_NOT_FOUND; } if (memcmp(at, needle, needleLen) == 0) { return (size_t)(at - hay); } at++; } return GATE_TEXT_NOT_FOUND; } bool gateTextReadFile(const char *path, uint8_t **data, size_t *len, ToolBufT *problem) { struct stat info; // A directory opens, then reads as nonsense: say what it is. if (stat(path, &info) == 0 && S_ISDIR(info.st_mode)) { gateTextAdd(problem, "cannot read %s: %s", path, strerror(EISDIR)); return false; } errno = 0; if (!toolReadFile(path, data, len)) { gateTextAdd(problem, "cannot read %s: %s", path, strerror(errno != 0 ? errno : EIO)); return false; } return true; } const char *gateTextString(ToolBufT *buf) { toolBufByte(buf, 0u); buf->len--; return (const char *)buf->data; }