Add an error check for correct formatting in Deflate uncompressed
[sgt/halibut] / misc.c
diff --git a/misc.c b/misc.c
index 647d642..3f2483c 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -18,7 +18,7 @@ struct stackTag {
 stack stk_new(void) {
     stack s;
 
-    s = mknew(struct stackTag);
+    s = snew(struct stackTag);
     s->sp = 0;
     s->size = 0;
     s->data = NULL;
@@ -34,7 +34,7 @@ void stk_free(stack s) {
 void stk_push(stack s, void *item) {
     if (s->size <= s->sp) {
        s->size = s->sp + 32;
-       s->data = resize(s->data, s->size);
+       s->data = sresize(s->data, s->size, void *);
     }
     s->data[s->sp++] = item;
 }
@@ -62,7 +62,7 @@ const rdstringc empty_rdstringc = {0, 0, NULL};
 void rdadd(rdstring *rs, wchar_t c) {
     if (rs->pos >= rs->size-1) {
        rs->size = rs->pos + 128;
-       rs->text = resize(rs->text, rs->size);
+       rs->text = sresize(rs->text, rs->size, wchar_t);
     }
     rs->text[rs->pos++] = c;
     rs->text[rs->pos] = 0;
@@ -71,35 +71,38 @@ void rdadds(rdstring *rs, wchar_t const *p) {
     int len = ustrlen(p);
     if (rs->pos >= rs->size - len) {
        rs->size = rs->pos + len + 128;
-       rs->text = resize(rs->text, rs->size);
+       rs->text = sresize(rs->text, rs->size, wchar_t);
     }
     ustrcpy(rs->text + rs->pos, p);
     rs->pos += len;
 }
 wchar_t *rdtrim(rdstring *rs) {
-    rs->text = resize(rs->text, rs->pos + 1);
+    rs->text = sresize(rs->text, rs->pos + 1, wchar_t);
     return rs->text;
 }
 
 void rdaddc(rdstringc *rs, char c) {
     if (rs->pos >= rs->size-1) {
        rs->size = rs->pos + 128;
-       rs->text = resize(rs->text, rs->size);
+       rs->text = sresize(rs->text, rs->size, char);
     }
     rs->text[rs->pos++] = c;
     rs->text[rs->pos] = 0;
 }
 void rdaddsc(rdstringc *rs, char const *p) {
-    int len = strlen(p);
+    rdaddsn(rs, p, strlen(p));
+}
+void rdaddsn(rdstringc *rs, char const *p, int len) {
     if (rs->pos >= rs->size - len) {
        rs->size = rs->pos + len + 128;
-       rs->text = resize(rs->text, rs->size);
+       rs->text = sresize(rs->text, rs->size, char);
     }
-    strcpy(rs->text + rs->pos, p);
+    memcpy(rs->text + rs->pos, p, len);
     rs->pos += len;
+    rs->text[rs->pos] = 0;
 }
 char *rdtrimc(rdstringc *rs) {
-    rs->text = resize(rs->text, rs->pos + 1);
+    rs->text = sresize(rs->text, rs->pos + 1, char);
     return rs->text;
 }
 
@@ -126,7 +129,7 @@ static int compare_wordlists_literally(word *a, word *b) {
        } else {
            wchar_t *ap = a->text, *bp = b->text;
            while (*ap && *bp) {
-               wchar_t ac = utolower(*ap), bc = utolower(*bp);
+               wchar_t ac = *ap, bc = *bp;
                if (ac != bc)
                    return (ac < bc ? -1 : +1);
                if (!*++ap && a->next && a->next->type == t && !a->next->alt)
@@ -194,10 +197,25 @@ int compare_wordlists(word *a, word *b) {
            }
        }
 
+#ifdef HAS_WCSCOLL
+       {
+           wchar_t a[2], b[2];
+           int ret;
+
+           a[0] = pos[0].c;
+           b[0] = pos[1].c;
+           a[1] = b[1] = L'\0';
+
+           ret = wcscoll(a, b);
+           if (ret)
+               return ret;
+       }
+#else
        if (pos[0].c < pos[1].c)
            return -1;
        else if (pos[0].c > pos[1].c)
            return +1;
+#endif
 
        if (!pos[0].c)
            break;                     /* they're equal */
@@ -213,23 +231,37 @@ int compare_wordlists(word *a, word *b) {
     return compare_wordlists_literally(a, b);
 }
 
-void mark_attr_ends(paragraph *sourceform) {
-    paragraph *p;
+void mark_attr_ends(word *words)
+{
     word *w, *wp;
-    for (p = sourceform; p; p = p->next) {
-       wp = NULL;
-       for (w = p->words; w; w = w->next) {
-           if (isattr(w->type)) {
-               int before = (wp && isattr(wp->type) &&
-                             sameattr(wp->type, w->type));
-               int after = (w->next && isattr(w->next->type) &&
-                            sameattr(w->next->type, w->type));
-               w->aux |= (before ?
-                          (after ? attr_Always : attr_Last) :
-                          (after ? attr_First : attr_Only));
-           }
-           wp = w;
+
+    wp = NULL;
+    for (w = words; w; w = w->next) {
+       int both;
+       if (!isvis(w->type))
+           /* Invisible elements should not affect this calculation */
+           continue;
+       both = (isattr(w->type) &&
+               wp && isattr(wp->type) &&
+               sameattr(wp->type, w->type));
+       w->aux |= both ? attr_Always : attr_First;
+       if (wp && !both) {
+           /* If previous considered word turns out to have been
+            * the end of a run, tidy it up. */
+           int wp_attr = attraux(wp->aux);
+           wp->aux = (wp->aux & ~attr_mask) |
+               ((wp_attr == attr_Always) ? attr_Last
+                        /* attr_First */ : attr_Only);
        }
+       wp = w;
+    }
+
+    /* Tidy up last word touched */
+    if (wp) {
+       int wp_attr = attraux(wp->aux);
+       wp->aux = (wp->aux & ~attr_mask) |
+           ((wp_attr == attr_Always) ? attr_Last
+                    /* attr_First */ : attr_Only);
     }
 }
 
@@ -448,7 +480,7 @@ wrappedline *wrap_para(word *text, int width, int subsequentwidth,
      */
     i = 0;
     while (i < nwords) {
-       wrappedline *w = mknew(wrappedline);
+       wrappedline *w = snew(wrappedline);
        *ptr = w;
        ptr = &w->next;
        w->next = NULL;
@@ -501,13 +533,13 @@ void cmdline_cfg_add(paragraph *cfg, char *string)
 
     upos = ulen;
     ulen += 2 + ustrlen(ustring);
-    cfg->keyword = resize(cfg->keyword, ulen);
+    cfg->keyword = sresize(cfg->keyword, ulen, wchar_t);
     ustrcpy(cfg->keyword+upos, ustring);
     cfg->keyword[ulen-1] = L'\0';
 
     pos = len;
     len += 2 + strlen(string);
-    cfg->origkeyword = resize(cfg->origkeyword, len);
+    cfg->origkeyword = sresize(cfg->origkeyword, len, char);
     strcpy(cfg->origkeyword+pos, string);
     cfg->origkeyword[len-1] = '\0';
 
@@ -518,7 +550,7 @@ paragraph *cmdline_cfg_new(void)
 {
     paragraph *p;
 
-    p = mknew(paragraph);
+    p = snew(paragraph);
     memset(p, 0, sizeof(*p));
     p->type = para_Config;
     p->next = NULL;