mirror of
https://github.com/Orc/discount.git
synced 2026-09-25 04:10:00 +03:00
1. Add the new amalloc module, which (if enabled with
--enable-amalloc) replaced malloc and its ilk with
versions that attempt to maintain a linked list of
allocated blocks that can be printed to stderr with
the `adump()` function.
2. Clean up a couple more places where I leak memory
during the first level parse.
3. tweak cstring.h to try to chase down places where
the C compiler might optimize EXPAND() into producing
broken code.
This commit is contained in:
+1
-1
@@ -11,7 +11,7 @@ PGMS=markdown
|
||||
SAMPLE_PGMS=mkd2html
|
||||
@THEME@SAMPLE_PGMS+= theme
|
||||
MKDLIB=libmarkdown.a
|
||||
OBJS=mkdio.o markdown.o dumptree.o generate.o docheader.o version.o
|
||||
OBJS=mkdio.o markdown.o dumptree.o generate.o docheader.o version.o @AMALLOC@
|
||||
|
||||
all: $(PGMS) $(SAMPLE_PGMS)
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* debugging malloc()/realloc()/calloc()/free() that attempts
|
||||
* to keep track of just what's been allocated today.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAGIC 0x1f2e3d4c
|
||||
|
||||
struct alist { int magic, size; struct alist *next, *last; };
|
||||
|
||||
static struct alist list = { 0, 0, 0, 0 };
|
||||
|
||||
void *
|
||||
acalloc(int size, int count)
|
||||
{
|
||||
struct alist *ret = calloc(size + sizeof(struct alist), count);
|
||||
|
||||
if ( ret ) {
|
||||
ret->magic = MAGIC;
|
||||
ret->size = size * count;
|
||||
if ( list.next ) {
|
||||
ret->next = list.next;
|
||||
ret->last = &list;
|
||||
ret->next->last = ret;
|
||||
list.next = ret;
|
||||
}
|
||||
else {
|
||||
ret->last = ret->next = &list;
|
||||
list.next = list.last = ret;
|
||||
}
|
||||
return ret+1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void*
|
||||
amalloc(int size)
|
||||
{
|
||||
return acalloc(size,1);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
afree(void *ptr)
|
||||
{
|
||||
struct alist *p2 = ((struct alist*)ptr)-1;
|
||||
|
||||
if ( p2->magic == MAGIC ) {
|
||||
p2->last->next = p2->next;
|
||||
p2->next->last = p2->last;
|
||||
free(p2);
|
||||
}
|
||||
else
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
arealloc(void *ptr, int size)
|
||||
{
|
||||
struct alist *p2 = ((struct alist*)ptr)-1;
|
||||
struct alist save;
|
||||
|
||||
if ( p2->magic == MAGIC ) {
|
||||
save.next = p2->next;
|
||||
save.last = p2->last;
|
||||
p2 = realloc(p2, sizeof(p2) + size);
|
||||
|
||||
if ( p2 ) {
|
||||
p2->size = size;
|
||||
p2->next->last = p2;
|
||||
p2->last->next = p2;
|
||||
return p2+1;
|
||||
}
|
||||
else {
|
||||
save.next->last = save.last;
|
||||
save.last->next = save.next;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
adump()
|
||||
{
|
||||
struct alist *p;
|
||||
|
||||
|
||||
for ( p = list.next; p && (p != &list); p = p->next ) {
|
||||
fprintf(stderr, "allocated: %d byte%s\n", p->size, (p->size==1) ? "" : "s");
|
||||
fprintf(stderr, " [%.*s]\n", p->size, p+1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* debugging malloc()/realloc()/calloc()/free() that attempts
|
||||
* to keep track of just what's been allocated today.
|
||||
*/
|
||||
#ifndef AMALLOC_D
|
||||
#define AMALLOC_D
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef USE_AMALLOC
|
||||
|
||||
extern void *amalloc(int);
|
||||
extern void *acalloc(int,int);
|
||||
extern void *arealloc(void*,int);
|
||||
extern void afree(void*);
|
||||
extern void adump();
|
||||
|
||||
#define malloc amalloc
|
||||
#define calloc acalloc
|
||||
#define realloc arealloc
|
||||
#define free afree
|
||||
|
||||
#else
|
||||
|
||||
#define adump() (void)1
|
||||
|
||||
#endif
|
||||
|
||||
#endif/*AMALLOC_D*/
|
||||
+10
-1
@@ -9,7 +9,8 @@
|
||||
#
|
||||
ac_help='--enable-dl-tag Use the DL tag extension
|
||||
--enable-pandoc-header Use pandoc-style header blocks
|
||||
--with-tabstops=N Set tabstops to N characters (default is 4)'
|
||||
--with-tabstops=N Set tabstops to N characters (default is 4)
|
||||
--enable-amalloc Enable memory allocation debugging'
|
||||
|
||||
LOCAL_AC_OPTIONS='
|
||||
set=`locals $*`;
|
||||
@@ -99,6 +100,14 @@ fi
|
||||
AC_DEFINE 'TABSTOP' $TABSTOP
|
||||
AC_SUB 'TABSTOP' $TABSTOP
|
||||
|
||||
|
||||
if [ "$WITH_AMALLOC" ]; then
|
||||
AC_DEFINE 'USE_AMALLOC' 1
|
||||
AC_SUB 'AMALLOC' 'amalloc.o'
|
||||
else
|
||||
AC_SUB 'AMALLOC' ''
|
||||
fi
|
||||
|
||||
[ "$OS_FREEBSD" -o "$OS_DRAGONFLY" ] || AC_CHECK_HEADERS malloc.h
|
||||
|
||||
[ "$WITH_DL_TAG" ] && AC_DEFINE 'DL_TAG_EXTENSION' '1'
|
||||
|
||||
@@ -10,16 +10,17 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "amalloc.h"
|
||||
|
||||
/* expandable Pascal-style string.
|
||||
*/
|
||||
#define STRING(type) struct { type *text; int size, alloc; }
|
||||
|
||||
#define RESERVE(x,c) (x).text = malloc(sizeof T(x)[0] * (((x).size=0),((x).alloc=(c))) )
|
||||
#define CREATE(x) RESERVE(x,100)
|
||||
#define EXPAND(x) (x).text[((x).size < (x).alloc \
|
||||
? 0 \
|
||||
: !((x).text = realloc((x).text, sizeof T(x)[0] * ((x).alloc += 100)))), \
|
||||
(x).size++]
|
||||
#define EXPAND(x) ((x).size++)[((x).size < (x).alloc) \
|
||||
? (x).text \
|
||||
: (x).text = realloc((x).text, sizeof T(x)[0] * ((x).alloc += 100))]
|
||||
|
||||
#define DELETE(x) (x).alloc ? (free(T(x)), S(x) = (x).alloc = 0) \
|
||||
: ( S(x) = 0 )
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "cstring.h"
|
||||
#include "markdown.h"
|
||||
#include "amalloc.h"
|
||||
|
||||
#define afterdle(t) (T((t)->text) + (t)->dle)
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <stdio.h>
|
||||
#include "markdown.h"
|
||||
#include "cstring.h"
|
||||
#include "amalloc.h"
|
||||
|
||||
struct frame {
|
||||
int indent;
|
||||
|
||||
+1
-1
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "cstring.h"
|
||||
#include "markdown.h"
|
||||
#include "amalloc.h"
|
||||
|
||||
/* prefixes for <automatic links>
|
||||
*/
|
||||
@@ -1196,4 +1197,3 @@ mkd_style(Document *d, FILE *f)
|
||||
return stylesheets(d->code, f);
|
||||
return EOF;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "amalloc.h"
|
||||
|
||||
#if HAVE_LIBGEN_H
|
||||
#include <libgen.h>
|
||||
@@ -137,5 +138,6 @@ main(int argc, char **argv)
|
||||
rc = mkd_dump(doc, stdout, 0, argc ? basename(argv[0]) : "stdin");
|
||||
else
|
||||
rc = markdown(doc, stdout, flags);
|
||||
adump();
|
||||
exit( (rc == 0) ? 0 : errno );
|
||||
}
|
||||
|
||||
+18
-6
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "cstring.h"
|
||||
#include "markdown.h"
|
||||
#include "amalloc.h"
|
||||
|
||||
/* block-level tags for passing html blocks through the blender
|
||||
*/
|
||||
@@ -669,7 +670,12 @@ listblock(Paragraph *top, int trim, MMIOT *f)
|
||||
if ( !(q = skipempty(text)) || (islist(q,&trim) != top->typ) )
|
||||
break;
|
||||
|
||||
para = (q != text);
|
||||
if ( para = (q != text) ) {
|
||||
Line anchor;
|
||||
|
||||
anchor.next = text;
|
||||
freeLineRange(&anchor, q);
|
||||
}
|
||||
|
||||
if ( para && (top->typ != DL) ) p->down->align = PARA;
|
||||
}
|
||||
@@ -699,7 +705,7 @@ addfootnote(Line *p, MMIOT* f)
|
||||
{
|
||||
int j, i;
|
||||
int c;
|
||||
Line *p2 = p->next;
|
||||
Line *np = p->next;
|
||||
|
||||
Footnote *foot = &EXPAND(f->footnotes);
|
||||
|
||||
@@ -729,9 +735,11 @@ addfootnote(Line *p, MMIOT* f)
|
||||
}
|
||||
|
||||
|
||||
if ( (j >= S(p->text)) && p2 && p2->dle && tgood(T(p2->text)[p2->dle]) ) {
|
||||
j = p2->dle;
|
||||
p = p2;
|
||||
if ( (j >= S(p->text)) && np && np->dle && tgood(T(np->text)[np->dle]) ) {
|
||||
freeLine(p);
|
||||
p = np;
|
||||
np = p->next;
|
||||
j = p->dle;
|
||||
}
|
||||
|
||||
if ( (c = tgood(T(p->text)[j])) ) {
|
||||
@@ -751,7 +759,8 @@ addfootnote(Line *p, MMIOT* f)
|
||||
EXPAND(foot->title) = 0;
|
||||
}
|
||||
|
||||
return p->next;
|
||||
freeLine(p);
|
||||
return np;
|
||||
}
|
||||
|
||||
|
||||
@@ -798,6 +807,7 @@ compile(Line *ptr, int toplevel, MMIOT *f)
|
||||
ParagraphRoot d = { 0, 0 };
|
||||
Paragraph *p = 0;
|
||||
char *key;
|
||||
Line *r;
|
||||
int para = toplevel;
|
||||
int hdr_type, list_type, indent;
|
||||
|
||||
@@ -817,7 +827,9 @@ compile(Line *ptr, int toplevel, MMIOT *f)
|
||||
}
|
||||
else if ( ishr(ptr) ) {
|
||||
p = Pp(&d, 0, HR);
|
||||
r = ptr;
|
||||
ptr = ptr->next;
|
||||
freeLine(r);
|
||||
}
|
||||
else if (( list_type = islist(ptr, &indent) )) {
|
||||
p = Pp(&d, ptr, list_type);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define _MARKDOWN_D
|
||||
|
||||
#include "cstring.h"
|
||||
#include "amalloc.h"
|
||||
|
||||
/* reference-style links (and images) are stored in an array
|
||||
* of footnotes.
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
#include "mkdio.h"
|
||||
#include "cstring.h"
|
||||
#include "amalloc.h"
|
||||
|
||||
char *pgm = "mkd2html";
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "cstring.h"
|
||||
#include "markdown.h"
|
||||
#include "amalloc.h"
|
||||
|
||||
typedef ANCHOR(Line) LineAnchor;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define _MKDIO_D
|
||||
|
||||
#include <stdio.h>
|
||||
#include "amalloc.h"
|
||||
|
||||
typedef void MMIOT;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user