#undef BUFSECTORS
}
-struct buf {
- char *p;
- size_t n, sz;
-};
-#define BUF_INIT { 0, 0, 0 }
-#define BUF_REWIND(b) do { (b)->n = 0; } while (0)
-#define BUF_FREE(b) do { \
- buf *_b = (b); \
- free(_b->p); _b->p = 0; _b->n = _b->sz = 0; \
-} while (0)
-#define BUF_PUTC(b, ch) do { \
- struct buf *_b = (b); \
- if (_b->n >= _b->sz) { \
- _b->sz = _b->sz ? 2*_b->sz : 32; \
- _b->p = realloc(_b->p, _b->sz); \
- if (!_b->p) bail("out of memory allocating %zu bytes", _b->sz); \
- } \
- _b->p[_b->n] = (ch); \
-} while (0)
-
static int read_line(FILE *fp, struct buf *b)
{
int ch;
ch = getc(fp);
if (ch == EOF)
return (-1);
- else if (ch != '\n') do {
- BUF_PUTC(b, ch); b->n++;
- ch = getc(fp);
- } while (ch != EOF && ch != '\n');
- BUF_PUTC(b, 0);
+ else if (ch != '\n')
+ do { buf_putc(b, ch); ch = getc(fp); } while (ch != EOF && ch != '\n');
+ buf_putz(b);
return (0);
}
bail_syserr(errno, "failed to open ranges file `%s'", optarg);
i = 0; last = -1;
for (;;) {
- BUF_REWIND(&buf); if (read_line(fp, &buf)) break;
+ buf_rewind(&buf); if (read_line(fp, &buf)) break;
p = buf.p; i++;
while (ISSPACE(*p)) p++;
if (!*p || *p == '#') continue;
bail_syserr(errno, "failed to open bad-blocks file `%s'", optarg);
i = 0; last = -1;
for (;;) {
- BUF_REWIND(&buf); if (read_line(fp, &buf)) break;
+ buf_rewind(&buf); if (read_line(fp, &buf)) break;
p = buf.p; i++;
while (ISSPACE(*p)) p++;
if (!*p || *p == '#') continue;
return (x);
}
-/*----- Resizing arrays ---------------------------------------------------*/
+/*----- Resizing buffers and arrays ---------------------------------------*/
+
+void buf__grow(struct buf *b)
+{
+ b->sz = b->sz ? 2*b->sz : 32;
+ b->p = realloc(b->p, b->sz);
+ if (!b->p) bail("out of memory allocating %zu bytes", b->sz);
+}
void *vec__grow(void *p, size_t esz, size_t *sz_inout)
{
* exit with status code 2.
*/
+/*----- Resizing buffers --------------------------------------------------*/
+
+struct buf {
+ /* A buffer for a string which can grow automatically. */
+
+ char *p; /* pointer to the buffer */
+ size_t n, sz; /* string length, buffer size */
+};
+#define BUF_INIT { 0, 0, 0 }
+
+static inline void buf_rewind(struct buf *b) { b->n = 0; }
+ /* Throw away the current contents of B so that new stuff gets added
+ * to the beginning.
+ */
+
+static inline void buf_free(struct buf *b)
+ { free(b->p); b->p = 0; b->n = b->sz = 0; }
+ /* Release the memory allocated for B. The buffer can be reused
+ * immediately and/or freed again safely.
+ */
+
+extern void buf__grow(struct buf *b);
+ /* Make B's buffer larger, so that (at least) one extra byte can be
+ * written to it. (Internal to `buf_putc'.)
+ */
+
+static inline void buf_putc(struct buf *b, int ch)
+ { if (b->n >= b->sz) buf__grow(b); b->p[b->n++] = ch; }
+ /* Append the character CH to the buffer B. */
+
+static inline void buf_putz(struct buf *b)
+ { if (b->n >= b->sz) buf__grow(b); b->p[b->n] = 0; }
+ /* Append a zero byte to B without increasing the string length, so
+ * that a future `buf_putc' will overwrite it.
+ */
+
/*----- Resizing vectors --------------------------------------------------*/
#define DEFVEC(vtype, etype) \