Optimize the html block tag list handler; standard html tags now live in a static array

and html5 (or other) tags are added to an extratags array that is only searched
if the tag can't be found in the standard one.
This commit is contained in:
david parsons
2011-07-22 00:21:10 -07:00
parent 5dd053c0de
commit 07c10928ba
6 changed files with 148 additions and 77 deletions
+5
View File
@@ -65,6 +65,11 @@ $(DESTDIR)/$(LIBDIR):
version.o: version.c VERSION
$(CC) -DVERSION=\"`cat VERSION`\" -c version.c
tags.o: tags.c blocktags
blocktags: mktags
./mktags > blocktags
# example programs
@THEME@theme: theme.o $(MKDLIB) mkdio.h
@THEME@ $(CC) -o theme theme.o -lmarkdown @LIBS@
+1 -1
View File
@@ -1 +1 @@
2.1.1.1
2.1.1.2
-2
View File
@@ -10,8 +10,6 @@ mkd_with_html5_tags()
if ( populated ) return;
populated = 1;
mkd_prepare_tags();
mkd_define_tag("ASIDE", 0);
mkd_define_tag("FOOTER", 0);
mkd_define_tag("HEADER", 0);
+108
View File
@@ -0,0 +1,108 @@
/* block-level tags for passing html blocks through the blender
*/
#include <stdio.h>
#define __WITHOUT_AMALLOC 1
#include "cstring.h"
#include "tags.h"
STRING(struct kw) blocktags;
/* define a html block tag
*/
void
mkd_define_tag(char *id, int selfclose)
{
struct kw *p = &EXPAND(blocktags);
p->id = id;
p->size = strlen(id);
p->selfclose = selfclose;
}
/* case insensitive string sort (for qsort() and bsearch() of block tags)
*/
static int
casort(struct kw *a, struct kw *b)
{
if ( a->size != b->size )
return a->size - b->size;
return strncasecmp(a->id, b->id, b->size);
}
/* stupid cast to make gcc shut up about the function types being
* passed into qsort() and bsearch()
*/
typedef int (*stfu)(const void*,const void*);
/* sort the list of html block tags for later searching
*/
void
mkd_sort_tags()
{
qsort(T(blocktags), S(blocktags), sizeof(struct kw), (stfu)casort);
}
/* load in the standard collection of html tags that markdown supports
*/
static void
pile_of_tags()
{
#define KW(x) mkd_define_tag(x, 0)
#define SC(x) mkd_define_tag(x, 1)
KW("STYLE");
KW("SCRIPT");
KW("ADDRESS");
KW("BDO");
KW("BLOCKQUOTE");
KW("CENTER");
KW("DFN");
KW("DIV");
KW("OBJECT");
KW("H1");
KW("H2");
KW("H3");
KW("H4");
KW("H5");
KW("H6");
KW("LISTING");
KW("NOBR");
KW("UL");
KW("P");
KW("OL");
KW("DL");
KW("PLAINTEXT");
KW("PRE");
KW("TABLE");
KW("WBR");
KW("XMP");
SC("HR");
SC("BR");
KW("IFRAME");
KW("MAP");
mkd_sort_tags();
} /* pile_of_tags */
main()
{
int i;
pile_of_tags();
printf("struct kw blocktags[] = {\n");
for (i=0; i < S(blocktags); i++)
printf(" { \"%s\", %d, %d },\n", T(blocktags)[i].id, T(blocktags)[i].size, T(blocktags)[i].selfclose );
printf("};\n\n");
printf("#define NR_blocktags %d\n", S(blocktags));
exit(0);
}
+1 -9
View File
@@ -18,7 +18,6 @@
#include "amalloc.h"
#include "tags.h"
static int need_to_setup = 1;
static int need_to_initrng = 1;
void
@@ -29,19 +28,12 @@ mkd_initialize()
need_to_initrng = 0;
INITRNG(time(0));
}
if ( need_to_setup ) {
need_to_setup = 0;
mkd_prepare_tags();
}
}
void
mkd_shlib_destructor()
{
if ( !need_to_setup ) {
need_to_setup = 1;
mkd_deallocate_tags();
}
mkd_deallocate_tags();
}
+33 -65
View File
@@ -4,19 +4,33 @@
#include "cstring.h"
#include "tags.h"
STRING(struct kw) blocktags;
STRING(struct kw) extratags;
/* the standard collection of tags are built and sorted when
* discount is configured, so all we need to do is pull them
* in and use them.
*
* Additional tags still need to be allocated, sorted, and deallocated.
*/
#include "blocktags"
/* define a html block tag
/* define an additional html block tag
*/
void
mkd_define_tag(char *id, int selfclose)
{
struct kw *p = &EXPAND(blocktags);
struct kw *p;
p->id = id;
p->size = strlen(id);
p->selfclose = selfclose;
/* only add the new tag if it doesn't exist in
* either the standard or extra tag tables.
*/
if ( !(p = mkd_search_tags(id, strlen(id))) ) {
p = &EXPAND(extratags);
p->id = id;
p->size = strlen(id);
p->selfclose = selfclose;
}
}
@@ -37,87 +51,41 @@ casort(struct kw *a, struct kw *b)
typedef int (*stfu)(const void*,const void*);
/* sort the list of html block tags for later searching
/* sort the list of extra html block tags for later searching
*/
void
mkd_sort_tags()
{
qsort(T(blocktags), S(blocktags), sizeof(struct kw), (stfu)casort);
qsort(T(extratags), S(extratags), sizeof(struct kw), (stfu)casort);
}
/* look for a token in the html block tag list
*/
struct kw*
mkd_search_tags(char *pat, int len)
{
struct kw key;
struct kw *ret;
key.id = pat;
key.size = len;
return bsearch(&key, T(blocktags), S(blocktags), sizeof key, (stfu)casort);
if ( (ret=bsearch(&key,blocktags,NR_blocktags,sizeof key,(stfu)casort)) )
return ret;
if ( S(extratags) )
return bsearch(&key,T(extratags),S(extratags),sizeof key,(stfu)casort);
return 0;
}
static int populated = 0;
/* load in the standard collection of html tags that markdown supports
*/
void
mkd_prepare_tags()
{
#define KW(x) mkd_define_tag(x, 0)
#define SC(x) mkd_define_tag(x, 1)
if ( populated ) return;
populated = 1;
KW("STYLE");
KW("SCRIPT");
KW("ADDRESS");
KW("BDO");
KW("BLOCKQUOTE");
KW("CENTER");
KW("DFN");
KW("DIV");
KW("OBJECT");
KW("H1");
KW("H2");
KW("H3");
KW("H4");
KW("H5");
KW("H6");
KW("LISTING");
KW("NOBR");
KW("UL");
KW("P");
KW("OL");
KW("DL");
KW("PLAINTEXT");
KW("PRE");
KW("TABLE");
KW("WBR");
KW("XMP");
SC("HR");
SC("BR");
KW("IFRAME");
KW("MAP");
mkd_sort_tags();
} /* mkd_prepare_tags */
/* destroy the blocktags list (for shared libraries)
/* destroy the extratags list (for shared libraries)
*/
void
mkd_deallocate_tags()
{
if ( S(blocktags) > 0 ) {
populated = 0;
DELETE(blocktags);
}
if ( S(extratags) > 0 )
DELETE(extratags);
} /* mkd_deallocate_tags */