chiark / gitweb /
url: Allow `;' to separate key/value pairs in URL-encoded strings.
[mLib] / lbuf.c
diff --git a/lbuf.c b/lbuf.c
index 9c0ec229d96c8b20afff38a6ae185ca498e219ea..7b28ddab5719db49303d5f1087899827f58903bc 100644 (file)
--- a/lbuf.c
+++ b/lbuf.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
 /* -*-c-*-
  *
- * $Id: lbuf.c,v 1.4 2000/06/17 10:38:14 mdw Exp $
+ * $Id: lbuf.c,v 1.7 2004/04/08 01:36:13 mdw Exp $
  *
  * Block-to-line buffering
  *
  *
  * Block-to-line buffering
  *
  * MA 02111-1307, USA.
  */
 
  * MA 02111-1307, USA.
  */
 
-/*----- Revision history --------------------------------------------------* 
- *
- * $Log: lbuf.c,v $
- * Revision 1.4  2000/06/17 10:38:14  mdw
- * Add support for variable buffer sizes.
- *
- * Revision 1.3  1999/05/22 13:38:50  mdw
- * Fix bug which discarded initial portions of incomplete lines.
- *
- * Revision 1.2  1999/05/17 20:36:08  mdw
- * Make the magical constants for the buffer flags uppercase.
- *
- * Revision 1.1  1999/05/14 21:01:14  mdw
- * Integrated `select' handling bits from the background resolver project.
- *
- */
-
 /*----- Header files ------------------------------------------------------*/
 
 #include <assert.h>
 /*----- Header files ------------------------------------------------------*/
 
 #include <assert.h>
@@ -87,6 +70,11 @@ void lbuf_flush(lbuf *b, char *p, size_t len)
   char *base;                          /* Base address of current line */
   int cr;                              /* Carriage return state */
 
   char *base;                          /* Base address of current line */
   int cr;                              /* Carriage return state */
 
+  if (b->f & LBUF_CLOSE) {
+    b->func(0, 0, b->p);
+    return;
+  }
+
   /* --- Initialize variables as necessary --- */
 
   if (!p) {
   /* --- Initialize variables as necessary --- */
 
   if (!p) {
@@ -111,39 +99,36 @@ void lbuf_flush(lbuf *b, char *p, size_t len)
 
     /* --- Quickly discard uninteresting characters --- */
 
 
     /* --- Quickly discard uninteresting characters --- */
 
-    if (*q != '\r' && *q != '\n') {
-      cr = 0;
-      continue;
-    }
-    if (*q == '\r') {
-      cr = 1;
-      continue;
+    switch (b->delim) {
+      case LBUF_CRLF:
+      case LBUF_STRICTCRLF:
+       if (*q != '\r' && *q != '\n') {
+         cr = 0;
+         continue;
+       }
+       if (*q == '\r') {
+         cr = 1;
+         continue;
+       }
+       if (!cr && b->delim == LBUF_STRICTCRLF)
+         continue;
+       break;
+      default:
+       if (*q != b->delim)
+         continue;
     }
 
     }
 
-    /* --- Two choices here --- *
-     *
-     * I can either be strict about CRLF line ends, or I can be shoddy
-     * and allow bare LFs.  I'll do the latter, although I oughtn't,
-     * because it makes testing interactively and with Unix text files
-     * easier.
-     */
-
-#ifdef STRICT_CRLF
-    if (!cr)
-      continue;
-#endif 
-
-    /* --- I have a positive ID on a linefeed --- *
+    /* --- I have a positive ID on a delimiter --- *
      *
      * If I'm interested in this string, report it to my owner.
      */
 
     if (base) {
      *
      * If I'm interested in this string, report it to my owner.
      */
 
     if (base) {
+      len = q - base;
       if (cr)
       if (cr)
-       q[-1] = 0;                      /* Exercise: why is this safe? */
-      else
-       *q = 0;
-      b->func(base, b->p);
+       len--;                          /* Exercise: why is this safe? */
+      base[len] = 0;
+      b->func(base, len, b->p);
       if (!(b->f & LBUF_ENABLE)) {
        base = q + 1;
        break;
       if (!(b->f & LBUF_ENABLE)) {
        base = q + 1;
        break;
@@ -156,10 +141,10 @@ void lbuf_flush(lbuf *b, char *p, size_t len)
   /* --- Sift through the aftermath --- */
 
   if (base) {
   /* --- Sift through the aftermath --- */
 
   if (base) {
-    size_t len = l - base;
+    len = l - base;
     if (len == b->sz) {
       b->buf[len - 1] = 0;
     if (len == b->sz) {
       b->buf[len - 1] = 0;
-      b->func(base, b->p);
+      b->func(base, len - 1, b->p);
     } else if (base != b->buf)
       memmove(b->buf, base, len);
     b->len = len;
     } else if (base != b->buf)
       memmove(b->buf, base, len);
     b->len = len;
@@ -186,14 +171,15 @@ void lbuf_close(lbuf *b)
 {
   if (b->len && b->len != b->sz) {
     b->buf[b->len] = 0;
 {
   if (b->len && b->len != b->sz) {
     b->buf[b->len] = 0;
-    b->func(b->buf, b->p);
+    b->func(b->buf, b->len, b->p);
   }
   if (b->buf) {
     x_free(b->a, b->buf);
     b->buf = 0;
   }
   }
   if (b->buf) {
     x_free(b->a, b->buf);
     b->buf = 0;
   }
+  b->f |= LBUF_CLOSE;
   if (b->f & LBUF_ENABLE)
   if (b->f & LBUF_ENABLE)
-    b->func(0, b->p);
+    b->func(0, 0, b->p);
 }
 
 /* --- @lbuf_free@ --- *
 }
 
 /* --- @lbuf_free@ --- *
@@ -288,7 +274,7 @@ void lbuf_setsize(lbuf *b, size_t sz)
 /* --- @lbuf_init@ --- *
  *
  * Arguments:  @lbuf *b@ = pointer to buffer block
 /* --- @lbuf_init@ --- *
  *
  * Arguments:  @lbuf *b@ = pointer to buffer block
- *             @void (*func)(char *s, void *p)@ = handler function
+ *             @lbuf_func *func@ = handler function
  *             @void *p@ = argument pointer for @func@
  *
  * Returns:    ---
  *             @void *p@ = argument pointer for @func@
  *
  * Returns:    ---
@@ -299,14 +285,13 @@ void lbuf_setsize(lbuf *b, size_t sz)
  *             for the first time.
  */
 
  *             for the first time.
  */
 
-void lbuf_init(lbuf *b,
-              void (*func)(char */*s*/, void */*p*/),
-              void *p)
+void lbuf_init(lbuf *b, lbuf_func *func, void *p)
 {
   b->func = func;
   b->p = p;
   b->len = 0;
   b->f = LBUF_ENABLE;
 {
   b->func = func;
   b->p = p;
   b->len = 0;
   b->f = LBUF_ENABLE;
+  b->delim = LBUF_CRLF;
   b->buf = 0;
   b->a = arena_global;
   lbuf_setsize(b, 256);
   b->buf = 0;
   b->a = arena_global;
   lbuf_setsize(b, 256);