lib.[ch], dvd-sector-copy.c: Publish the `buf' machinery as inline functions.
authorMark Wooding <mdw@distorted.org.uk>
Fri, 8 Apr 2022 14:31:24 +0000 (15:31 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Fri, 8 Apr 2022 14:34:58 +0000 (15:34 +0100)
Translate the macros into inline functions, and export them from
`lib.h', with some minor tweaking.

  * I've added `buf_putz', and fixed `buf_putc' to advance the output
    pointer as one would expect.

  * I've pulled the actual buffer extension into an out-of-line
    function.

dvd-sector-copy.c
lib.c
lib.h

index f1f6d4e..e699741 100644 (file)
@@ -805,26 +805,6 @@ static void emit(secaddr start, secaddr end)
 #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;
@@ -832,11 +812,9 @@ static int read_line(FILE *fp, struct buf *b)
   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);
 }
 
@@ -1002,7 +980,7 @@ int main(int argc, char *argv[])
          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;
@@ -1028,7 +1006,7 @@ int main(int argc, char *argv[])
          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;
diff --git a/lib.c b/lib.c
index 25cc829..320f04d 100644 (file)
--- a/lib.c
+++ b/lib.c
@@ -98,7 +98,14 @@ long parse_int(const char **p_inout, unsigned f,
   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)
 {
diff --git a/lib.h b/lib.h
index 2b127e3..2b8eb6b 100644 (file)
--- a/lib.h
+++ b/lib.h
@@ -143,6 +143,42 @@ extern PRINTF_LIKE(2, 3) NORETURN
         * 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)                                           \