about summary refs log tree commit diff stats
path: root/WWW/Library/Implementation/dtd_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'WWW/Library/Implementation/dtd_util.c')
-rw-r--r--WWW/Library/Implementation/dtd_util.c1405
1 files changed, 0 insertions, 1405 deletions
diff --git a/WWW/Library/Implementation/dtd_util.c b/WWW/Library/Implementation/dtd_util.c
deleted file mode 100644
index 4e18fdf7..00000000
--- a/WWW/Library/Implementation/dtd_util.c
+++ /dev/null
@@ -1,1405 +0,0 @@
-/*
- * $LynxId: dtd_util.c,v 1.76 2010/09/25 00:30:23 tom Exp $
- *
- * Given a SGML_dtd structure, write a corresponding flat file, or "C" source.
- * Given the flat-file, write the "C" source.
- *
- * TODO: use symbols for HTMLA_NORMAL, etc.
- */
-
-#include <HTUtils.h>
-#include <HTMLDTD.h>
-#include <string.h>
-
-/*
- * Tweaks to build standalone.
- */
-#undef exit
-
-BOOLEAN WWW_TraceFlag = FALSE;
-FILE *TraceFP(void)
-{
-    return stderr;
-}
-
-/*
- * Begin the actual utility.
- */
-#define GETOPT "chl:o:ts"
-
-#define NOTE(message) fprintf(output, message "\n");
-/* *INDENT-OFF* */
-#ifdef USE_PRETTYSRC
-# define N HTMLA_NORMAL
-# define i HTMLA_ANAME
-# define h HTMLA_HREF
-# define c HTMLA_CLASS
-# define x HTMLA_AUXCLASS
-# define T(t) , t
-#else
-# define T(t)			/*nothing */
-#endif
-
-#define ATTR_TYPE(name) { #name, name##_attr_list }
-
-static const attr core_attr_list[] = {
-	{ "CLASS"         T(c) },
-	{ "ID"            T(i) },
-	{ "STYLE"         T(N) },
-	{ "TITLE"         T(N) },
-	{ 0               T(N) }	/* Terminate list */
-};
-
-static const attr i18n_attr_list[] = {
-	{ "DIR"           T(N) },
-	{ "LANG"          T(N) },
-	{ 0               T(N) }	/* Terminate list */
-};
-
-static const attr events_attr_list[] = {
-	{ "ONCLICK"       T(N) },
-	{ "ONDBLCLICK"    T(N) },
-	{ "ONKEYDOWN"     T(N) },
-	{ "ONKEYPRESS"    T(N) },
-	{ "ONKEYUP"       T(N) },
-	{ "ONMOUSEDOWN"   T(N) },
-	{ "ONMOUSEMOVE"   T(N) },
-	{ "ONMOUSEOUT"    T(N) },
-	{ "ONMOUSEOVER"   T(N) },
-	{ "ONMOUSEUP"     T(N) },
-	{ 0               T(N) }	/* Terminate list */
-};
-
-static const attr align_attr_list[] = {
-	{ "ALIGN"         T(N) },
-	{ 0               T(N) }	/* Terminate list */
-};
-
-static const attr cellalign_attr_list[] = {
-	{ "ALIGN"         T(N) },
-	{ "CHAR"          T(N) },
-	{ "CHAROFF"       T(N) },
-	{ "VALIGN"        T(N) },
-	{ 0               T(N) }	/* Terminate list */
-};
-
-static const attr bgcolor_attr_list[] = {
-	{ "BGCOLOR"       T(N) },
-	{ 0               T(N) }	/* Terminate list */
-};
-
-#undef T
-/* *INDENT-ON* */
-
-static void failed(const char *s)
-{
-    perror(s);
-    exit(EXIT_FAILURE);
-}
-
-static void usage(void)
-{
-    static const char *tbl[] =
-    {
-	"Usage: dtd_util [options]",
-	"",
-	"Options:",
-	"  -c           generate C-source"
-	"  -h           generate C-header"
-	"  -l           load",
-	"  -o filename  specify output (default: stdout)",
-	"  -s           strict (HTML DTD 0)",
-	"  -t           tagsoup (HTML DTD 1)",
-    };
-    unsigned n;
-
-    for (n = 0; n < TABLESIZE(tbl); ++n) {
-	fprintf(stderr, "%s\n", tbl[n]);
-    }
-    exit(EXIT_FAILURE);
-}
-
-static const char *SGMLContent2s(SGMLContent contents)
-{
-    char *value = "?";
-
-    switch (contents) {
-    case SGML_EMPTY:
-	value = "SGML_EMPTY";
-	break;
-    case SGML_LITTERAL:
-	value = "SGML_LITTERAL";
-	break;
-    case SGML_CDATA:
-	value = "SGML_CDATA";
-	break;
-    case SGML_SCRIPT:
-	value = "SGML_SCRIPT";
-	break;
-    case SGML_RCDATA:
-	value = "SGML_RCDATA";
-	break;
-    case SGML_MIXED:
-	value = "SGML_MIXED";
-	break;
-    case SGML_ELEMENT:
-	value = "SGML_ELEMENT";
-	break;
-    case SGML_PCDATA:
-	value = "SGML_PCDATA";
-	break;
-    }
-    return value;
-}
-
-static SGMLContent s2SGMLContent(const char *value)
-{
-    static SGMLContent table[] =
-    {
-	SGML_EMPTY,
-	SGML_LITTERAL,
-	SGML_CDATA,
-	SGML_SCRIPT,
-	SGML_RCDATA,
-	SGML_MIXED,
-	SGML_ELEMENT,
-	SGML_PCDATA
-    };
-    unsigned n;
-    SGMLContent result = SGML_EMPTY;
-
-    for (n = 0; n < TABLESIZE(table); ++n) {
-	if (!strcmp(SGMLContent2s(table[n]), value)) {
-	    result = table[n];
-	    break;
-	}
-    }
-    return result;
-}
-
-static void PrintF(FILE *, int, const char *,...) GCC_PRINTFLIKE(3, 4);
-
-static void PrintF(FILE *output, int width, const char *fmt,...)
-{
-    char buffer[BUFSIZ];
-    va_list ap;
-
-    va_start(ap, fmt);
-    vsprintf(buffer, fmt, ap);
-    va_end(ap);
-
-    fprintf(output, "%-*s", width, buffer);
-}
-
-static int same_AttrList(AttrList a, AttrList b)
-{
-    int result = 1;
-
-    if (a && b) {
-	while (a->name && b->name) {
-	    if (strcmp(a->name, b->name)) {
-		result = 0;
-		break;
-	    }
-	    ++a, ++b;
-	}
-	if (a->name || b->name)
-	    result = 0;
-    } else {
-	result = 0;
-    }
-    return result;
-}
-
-static int first_attrs(const SGML_dtd * dtd, int which)
-{
-    int check;
-    int result = TRUE;
-
-    for (check = 0; check < which; ++check) {
-	if (dtd->tags[check].attributes == dtd->tags[which].attributes) {
-	    result = FALSE;
-	    break;
-	} else if (same_AttrList(dtd->tags[check].attributes,
-				 dtd->tags[which].attributes)) {
-	    result = FALSE;
-	    dtd->tags[which].attributes = dtd->tags[check].attributes;
-	    break;
-	}
-    }
-    return result;
-}
-
-static char *no_dashes(char *target, const char *source)
-{
-    int j;
-
-    for (j = 0; (target[j] = source[j]) != '\0'; ++j) {
-	if (!isalnum(target[j]))
-	    target[j] = '_';
-    }
-    return target;
-}
-
-/* the second "OBJECT" is treated specially */
-static int first_object(const SGML_dtd * dtd, int which)
-{
-    int check;
-
-    for (check = 0; check <= which; ++check) {
-	if (!strcmp(dtd->tags[check].name, "OBJECT"))
-	    break;
-    }
-    return (check == which);
-}
-
-static const char *NameOfAttrs(const SGML_dtd * dtd, int which)
-{
-    int check;
-    const char *result = dtd->tags[which].name;
-
-    for (check = 0; check < which; ++check) {
-	if (dtd->tags[check].attributes == dtd->tags[which].attributes) {
-	    result = dtd->tags[check].name;
-	    break;
-	}
-    }
-    /* special cases to match existing headers */
-    if (!strcmp(result, "ABBR"))
-	result = "GEN";
-    else if (!strcmp(result, "BLOCKQUOTE"))
-	result = "BQ";
-    else if (!strcmp(result, "BASEFONT"))
-	result = "FONT";
-    else if (!strcmp(result, "CENTER"))
-	result = "DIV";
-    else if (!strcmp(result, "DIR"))
-	result = "UL";
-    else if (!strcmp(result, "H1"))
-	result = "H";
-    else if (!strcmp(result, "TBODY"))
-	result = "TR";
-    return result;
-}
-
-static const char *DEF_name(const SGML_dtd * dtd, int which)
-{
-    const char *result = dtd->tags[which].name;
-
-    if (!strcmp(result, "OBJECT") && !first_object(dtd, which))
-	result = "OBJECT_PCDATA";
-    return result;
-}
-
-typedef struct {
-    const char *name;
-    const attr *attrs;
-    int count;
-    int which;
-} AttrInfo;
-
-static int compare_attr_types(const void *a, const void *b)
-{
-    const AttrType *p = (const AttrType *) a;
-    const AttrType *q = (const AttrType *) b;
-    int result = 0;
-
-    /* keep lowercase AttrType lists before uppercase, since latter are derived */
-    if (isupper(p->name[0]) ^ isupper(q->name[0])) {
-	if (isupper(p->name[0])) {
-	    result = 1;
-	} else {
-	    result = -1;
-	}
-    } else {
-	result = strcmp(p->name, q->name);
-    }
-    return result;
-}
-
-static int len_AttrTypes(const AttrType * data)
-{
-    int result = 0;
-
-    for (result = 0; data[result].name != 0; ++result) {
-	;
-    }
-    return result;
-}
-
-static AttrType *sorted_AttrTypes(const AttrType * source)
-{
-    AttrType *result = 0;
-    unsigned number = len_AttrTypes(source);
-
-    if (number != 0) {
-	result = typecallocn(AttrType, number + 1);
-	if (result != 0) {
-	    MemCpy(result, source, number * sizeof(*result));
-	    qsort(result, number, sizeof(*result), compare_attr_types);
-	}
-    }
-
-    return result;
-}
-
-static int compare_attr(const void *a, const void *b)
-{
-    const AttrInfo *p = (const AttrInfo *) a;
-    const AttrInfo *q = (const AttrInfo *) b;
-
-    return strcmp(p->name, q->name);
-}
-
-static int len_AttrList(AttrList data)
-{
-    int result = 0;
-
-    for (result = 0; data[result].name != 0; ++result) {
-	;
-    }
-    return result;
-}
-
-static void sort_uniq_AttrList(attr * data)
-{
-    unsigned have = len_AttrList(data);
-    unsigned j, k;
-
-    qsort(data, have, sizeof(*data), compare_attr);
-    /*
-     * Eliminate duplicates
-     */
-    for (j = 0; j < have; ++j) {
-	for (k = j; data[k].name; ++k) {
-	    if (data[k + 1].name == 0)
-		break;
-	    if (strcmp(data[j].name, data[k + 1].name)) {
-		break;
-	    }
-	}
-	data[j] = data[k];
-    }
-    memset(data + j, 0, sizeof(data[0]));
-}
-
-static attr *copy_AttrList(AttrList data)
-{
-    unsigned need = len_AttrList(data);
-    unsigned n;
-
-    attr *result = (attr *) calloc(need + 1, sizeof(attr));
-
-    for (n = 0; n < need; ++n)
-	result[n] = data[n];
-    sort_uniq_AttrList(result);
-    return result;
-}
-
-static attr *merge_AttrLists(const AttrType * data)
-{
-    const AttrType *at;
-    attr *result = 0;
-    unsigned need = 1;
-    unsigned have = 0;
-    unsigned j;
-
-    for (at = data; at->name; ++at) {
-	need += len_AttrList(at->list);
-    }
-    result = (attr *) calloc(need + 1, sizeof(attr));
-    for (at = data; at->name; ++at) {
-	if (!strcmp(at->name, "events")) {
-	    ;			/* lynx does not use events */
-	} else {
-	    for (j = 0; at->list[j].name; ++j) {
-		result[have++] = at->list[j];
-	    }
-	}
-    }
-    sort_uniq_AttrList(result);
-    return result;
-}
-
-static int clean_AttrList(attr * target, AttrList source)
-{
-    int result = 0;
-    int j, k;
-
-    for (j = 0; target[j].name != 0; ++j) {
-	for (k = 0; source[k].name != 0; ++k) {
-	    if (!strcmp(target[j].name, source[k].name)) {
-		k = j--;
-		for (;;) {
-		    target[k] = target[k + 1];
-		    if (target[k++].name == 0)
-			break;
-		}
-		++result;
-		break;
-	    }
-	}
-    }
-    return result;
-}
-
-/*
- * Actually COUNT the number of attributes, to make it possible to edit a
- * attribute-table in src0_HTMLDTD.h and have all of the files updated by
- * just doing a "make sources".
- */
-static int AttrCount(HTTag * tag)
-{
-    return len_AttrList(tag->attributes);
-}
-
-static AttrInfo *sorted_attrs(const SGML_dtd * dtd, unsigned *countp)
-{
-    int j;
-
-    AttrInfo *data = (AttrInfo *) calloc(dtd->number_of_tags, sizeof(AttrInfo));
-    unsigned count = 0;
-
-    /* get the attribute-data */
-    for (j = 0; j < dtd->number_of_tags; ++j) {
-	if (first_attrs(dtd, j)) {
-	    data[count].name = NameOfAttrs(dtd, j);
-	    data[count].attrs = dtd->tags[j].attributes;
-	    data[count].count = AttrCount(&(dtd->tags[j]));
-	    data[count].which = j;
-	    ++count;
-	}
-    }
-    /* sort the data by the name of their associated tag */
-    qsort(data, count, sizeof(*data), compare_attr);
-    *countp = count;
-    return data;
-}
-
-static void dump_src_HTTag_Defines(FILE *output, const SGML_dtd * dtd, int which)
-{
-    HTTag *tag = &(dtd->tags[which]);
-
-#define myFMT "0x%05X"
-    fprintf(output,
-	    "#define T_%-13s "
-	    myFMT "," myFMT "," myFMT "," myFMT "," myFMT "," myFMT
-	    "," myFMT "\n",
-	    DEF_name(dtd, which),
-	    tag->tagclass,
-	    tag->contains,
-	    tag->icontains,
-	    tag->contained,
-	    tag->icontained,
-	    tag->canclose,
-	    tag->flags);
-}
-
-static void dump_AttrItem(FILE *output, const attr * data)
-{
-    char buffer[BUFSIZ];
-    char pretty = 'N';
-
-    sprintf(buffer, "\"%s\"", data->name);
-#ifdef USE_PRETTYSRC
-    switch (data->type) {
-    case HTMLA_NORMAL:
-	pretty = 'N';
-	break;
-    case HTMLA_ANAME:
-	pretty = 'i';
-	break;
-    case HTMLA_HREF:
-	pretty = 'h';
-	break;
-    case HTMLA_CLASS:
-	pretty = 'c';
-	break;
-    case HTMLA_AUXCLASS:
-	pretty = 'x';
-	break;
-    }
-#endif
-    fprintf(output, "\t{ %-15s T(%c) },\n", buffer, pretty);
-}
-
-static void dump_AttrItem0(FILE *output)
-{
-    fprintf(output, "\t{ 0               T(N) }\t/* Terminate list */\n");
-}
-
-static void dump_src_AttrType(FILE *output, const char *name, AttrList data, const char **from)
-{
-    int n;
-
-    fprintf(output, "static const attr %s_attr_list[] = {\n", name);
-    if (data != 0) {
-	for (n = 0; data[n].name != 0; ++n) {
-	    dump_AttrItem(output, data + n);
-	}
-    }
-    fprintf(output, "\t{ 0               T(N) }	/* Terminate list */\n");
-    fprintf(output, "};\n");
-    NOTE("");
-    fprintf(output, "static const AttrType %s_attr_type[] = {\n", name);
-    if (from != 0) {
-	while (*from != 0) {
-	    fprintf(output, "\t{ ATTR_TYPE(%s) },\n", *from);
-	    ++from;
-	}
-    } else {
-	fprintf(output, "\t{ ATTR_TYPE(%s) },\n", name);
-    }
-    fprintf(output, "\t{ 0, 0 },\n");
-    fprintf(output, "};\n");
-    NOTE("");
-}
-
-static void dump_src_HTTag_Attrs(FILE *output, const SGML_dtd * dtd, int which)
-{
-    HTTag *tag = &(dtd->tags[which]);
-    attr *list = merge_AttrLists(tag->attr_types);
-    char buffer[BUFSIZ];
-    int n;
-    int limit = len_AttrList(list);
-
-    sprintf(buffer, "static const attr %s_attr[] = {", NameOfAttrs(dtd, which));
-    fprintf(output,
-	    "%-40s/* %s attributes */\n", buffer, tag->name);
-    for (n = 0; n < limit; ++n) {
-	dump_AttrItem(output, list + n);
-    }
-    dump_AttrItem0(output);
-    fprintf(output, "};\n");
-    NOTE("");
-    free(list);
-}
-
-static void dump_src_HTTag(FILE *output, const SGML_dtd * dtd, int which)
-{
-    HTTag *tag = &(dtd->tags[which]);
-    char *P_macro = "P";
-
-#ifdef USE_JUSTIFY_ELTS
-    if (!tag->can_justify)
-	P_macro = "P0";
-#endif
-    PrintF(output, 19, " { %s(%s),", P_macro, tag->name);
-    PrintF(output, 24, "ATTR_DATA(%s), ", NameOfAttrs(dtd, which));
-    PrintF(output, 14, "%s,", SGMLContent2s(tag->contents));
-    fprintf(output, "T_%s", DEF_name(dtd, which));
-    fprintf(output, "},\n");
-}
-
-static void dump_source(FILE *output, const SGML_dtd * dtd, int dtd_version)
-{
-    static AttrType generic_types[] =
-    {
-	ATTR_TYPE(core),
-	ATTR_TYPE(i18n),
-	ATTR_TYPE(events),
-	ATTR_TYPE(align),
-	ATTR_TYPE(cellalign),
-	ATTR_TYPE(bgcolor),
-	{0, 0}
-    };
-    AttrType *gt;
-
-    const char *marker = "src_HTMLDTD_H";
-    int j;
-
-    unsigned count = 0;
-    AttrInfo *data = sorted_attrs(dtd, &count);
-
-    fprintf(output, "/* %cLynxId%c */\n", '$', '$');
-    fprintf(output, "#ifndef %s%d\n", marker, dtd_version);
-    fprintf(output, "#define %s%d 1\n\n", marker, dtd_version);
-
-    /*
-     * If we ifdef this for once, and make the table names distinct, we can
-     * #include the strict- and tagsoup-output directly in HTMLDTD.c
-     */
-    NOTE("#ifndef once_HTMLDTD");
-    NOTE("#define once_HTMLDTD 1");
-    NOTE("");
-
-    /* construct TagClass-define's */
-    for (j = 0; j <= dtd->number_of_tags; ++j) {
-	dump_src_HTTag_Defines(output, dtd, j);
-    }
-    NOTE("#define T__UNREC_	0x00000,0x00000,0x00000,0x00000,0x00000,0x00000,0x00000");
-
-    /* construct attribute-tables */
-    NOTE("#ifdef USE_PRETTYSRC");
-    NOTE("# define N HTMLA_NORMAL");
-    NOTE("# define i HTMLA_ANAME");
-    NOTE("# define h HTMLA_HREF");
-    NOTE("# define c HTMLA_CLASS");
-    NOTE("# define x HTMLA_AUXCLASS");
-    NOTE("# define T(t) , t");
-    NOTE("#else");
-    NOTE("# define T(t)			/*nothing */");
-    NOTE("#endif");
-    NOTE("/* *INDENT-OFF* */");
-    NOTE("");
-    NOTE("#define ATTR_TYPE(name) #name, name##_attr_list");
-    NOTE("");
-    NOTE("/* generic attributes, used in different tags */");
-    for (gt = generic_types; gt->name != 0; ++gt) {
-	dump_src_AttrType(output, gt->name, gt->list, 0);
-    }
-    NOTE("");
-    NOTE("/* tables defining attributes per-tag in terms of generic attributes (editable) */");
-    for (j = 0; j < (int) count; ++j) {
-	int which = data[j].which;
-
-	if (first_attrs(dtd, which)) {
-	    HTTag *tag = &(dtd->tags[which]);
-	    const AttrType *types = tag->attr_types;
-	    const char *name = NameOfAttrs(dtd, which);
-	    attr *list = 0;
-	    const char *from_attr[10];
-	    int from_size = 0;
-
-	    while (types->name != 0) {
-		from_attr[from_size++] = types->name;
-		if (!strcmp(types->name, name)) {
-		    list = copy_AttrList(types->list);
-		    for (gt = generic_types; gt->name != 0; ++gt) {
-			if (clean_AttrList(list, gt->list)) {
-			    int k;
-			    int found = 0;
-
-			    for (k = 0; k < from_size; ++k) {
-				if (!strcmp(from_attr[k], gt->name)) {
-				    found = 1;
-				    break;
-				}
-			    }
-			    if (!found)
-				from_attr[from_size++] = gt->name;
-			    break;
-			}
-		    }
-		}
-		++types;
-	    }
-	    from_attr[from_size] = 0;
-
-	    if (list != 0) {
-		dump_src_AttrType(output, name, list, from_attr);
-		free(list);
-	    }
-	}
-    }
-    NOTE("");
-    NOTE("/* attribute lists for the runtime (generated by dtd_util) */");
-    for (j = 0; j < (int) count; ++j) {
-	dump_src_HTTag_Attrs(output, dtd, data[j].which);
-    }
-    NOTE("/* *INDENT-ON* */");
-    NOTE("");
-    NOTE("/* justification-flags */");
-    NOTE("#undef N");
-    NOTE("#undef i");
-    NOTE("#undef h");
-    NOTE("#undef c");
-    NOTE("#undef x");
-    NOTE("");
-    NOTE("#undef T");
-    NOTE("");
-    NOTE("/* tag-names */");
-    for (j = 0; j <= dtd->number_of_tags; ++j) {
-	fprintf(output, "#undef %s\n", DEF_name(dtd, j));
-    }
-    NOTE("");
-    NOTE("/* these definitions are used in the tags-tables */");
-    NOTE("#undef P");
-    NOTE("#undef P_");
-    NOTE("#ifdef USE_COLOR_STYLE");
-    NOTE("#define P_(x) #x, (sizeof #x) -1");
-    NOTE("#define NULL_HTTag_ NULL, 0");
-    NOTE("#else");
-    NOTE("#define P_(x) #x");
-    NOTE("#define NULL_HTTag_ NULL");
-    NOTE("#endif");
-    NOTE("");
-    NOTE("#ifdef USE_JUSTIFY_ELTS");
-    NOTE("#define P(x) P_(x), 1");
-    NOTE("#define P0(x) P_(x), 0");
-    NOTE("#define NULL_HTTag NULL_HTTag_,0");
-    NOTE("#else");
-    NOTE("#define P(x) P_(x)");
-    NOTE("#define P0(x) P_(x)");
-    NOTE("#define NULL_HTTag NULL_HTTag_");
-    NOTE("#endif");
-    NOTE("");
-    NOTE("#define ATTR_DATA(name) name##_attr, HTML_##name##_ATTRIBUTES, name##_attr_type");
-    NOTE("");
-    NOTE("#endif /* once_HTMLDTD */");
-    NOTE("/* *INDENT-OFF* */");
-
-    /* construct the tags table */
-    fprintf(output,
-	    "static const HTTag tags_table%d[HTML_ALL_ELEMENTS] = {\n",
-	    dtd_version);
-    for (j = 0; j <= dtd->number_of_tags; ++j) {
-	if (j == dtd->number_of_tags) {
-	    NOTE("/* additional (alternative variants), not counted in HTML_ELEMENTS: */");
-	    NOTE("/* This one will be used as a temporary substitute within the parser when");
-	    NOTE("   it has been signalled to parse OBJECT content as MIXED. - kw */");
-	}
-	dump_src_HTTag(output, dtd, j);
-    }
-    fprintf(output, "};\n");
-
-    NOTE("/* *INDENT-ON* */");
-    NOTE("");
-    fprintf(output, "#endif /* %s%d */\n", marker, dtd_version);
-
-    free(data);
-}
-
-static void dump_hdr_attr(FILE *output, AttrInfo * data)
-{
-    int j;
-    char buffer[BUFSIZ];
-
-    for (j = 0; j < data->count; ++j) {
-	PrintF(output, 33, "#define HTML_%s_%s",
-	       data->name,
-	       no_dashes(buffer, data->attrs[j].name));
-	fprintf(output, "%2d\n", j);
-    }
-    PrintF(output, 33, "#define HTML_%s_ATTRIBUTES", data->name);
-    fprintf(output, "%2d\n", data->count);
-    fprintf(output, "\n");
-}
-
-static void dump_header(FILE *output, const SGML_dtd * dtd)
-{
-    const char *marker = "hdr_HTMLDTD_H";
-    int j;
-
-    unsigned count = 0;
-    AttrInfo *data = sorted_attrs(dtd, &count);
-
-    fprintf(output, "/* %cLynxId%c */\n", '$', '$');
-    fprintf(output, "#ifndef %s\n", marker);
-    fprintf(output, "#define %s 1\n\n", marker);
-
-    NOTE("#ifdef __cplusplus");
-    NOTE("extern \"C\" {");
-    NOTE("#endif");
-
-    NOTE("/*");
-    NOTE("");
-    NOTE("   Element Numbers");
-    NOTE("");
-    NOTE("   Must Match all tables by element!");
-    NOTE("   These include tables in HTMLDTD.c");
-    NOTE("   and code in HTML.c.");
-    NOTE("");
-    NOTE(" */");
-
-    fprintf(output, "    typedef enum {\n");
-    for (j = 0; j < dtd->number_of_tags; ++j) {
-	fprintf(output, "\tHTML_%s,\n", dtd->tags[j].name);
-    }
-    NOTE("\tHTML_ALT_OBJECT");
-    NOTE("    } HTMLElement;\n");
-    NOTE("/* Notes: HTML.c uses a different extension of the");
-    NOTE("          HTML_ELEMENTS space privately, see");
-    NOTE("          HTNestedList.h.");
-    NOTE("");
-    NOTE("   Do NOT replace HTML_ELEMENTS with");
-    NOTE("   TABLESIZE(mumble_dtd.tags).");
-    NOTE("");
-    NOTE("   Keep the following defines in synch with");
-    NOTE("   the above enum!");
-    NOTE(" */");
-    NOTE("");
-    NOTE("/* # of elements generally visible to Lynx code */");
-    fprintf(output, "#define HTML_ELEMENTS %d\n", dtd->number_of_tags);
-    NOTE("");
-    NOTE("/* # of elements visible to SGML parser */");
-    fprintf(output, "#define HTML_ALL_ELEMENTS %d\n", dtd->number_of_tags + 1);
-    NOTE("");
-    NOTE("/*");
-    NOTE("");
-    NOTE("   Attribute numbers");
-    NOTE("");
-    NOTE("   Identifier is HTML_<element>_<attribute>.");
-    NOTE("   These must match the tables in HTML.c!");
-    NOTE("");
-    NOTE(" */");
-
-    /* output the sorted list */
-    for (j = 0; j < (int) count; ++j) {
-	dump_hdr_attr(output, data + j);
-    }
-    free(data);
-
-    NOTE("#ifdef __cplusplus");
-    NOTE("}");
-    NOTE("#endif");
-
-    fprintf(output, "#endif\t\t\t\t/* %s */\n", marker);
-}
-
-#define FMT_NUM_ATTRS "%d attributes:\n"
-#define FMT_ONE_ATTR  "%d:%d:%s\n"
-#define NUM_ONE_ATTR  3
-
-static void dump_flat_attrs(FILE *output,
-			    const attr * attributes,
-			    int number_of_attributes)
-{
-    int n;
-
-    fprintf(output, "\t\t" FMT_NUM_ATTRS, number_of_attributes);
-    for (n = 0; n < number_of_attributes; ++n) {
-	fprintf(output, "\t\t\t" FMT_ONE_ATTR, n,
-#ifdef USE_PRETTYSRC
-		attributes[n].type,
-#else
-		0,		/* need placeholder for source-compat */
-#endif
-		attributes[n].name
-	    );
-    }
-}
-
-static void dump_flat_attr_types(FILE *output, const AttrType * attr_types)
-{
-    const AttrType *p = sorted_AttrTypes(attr_types);
-    int number = len_AttrTypes(attr_types);
-
-    fprintf(output, "\t\t%d attr_types\n", number);
-
-    if (p != 0) {
-	while (p->name != 0) {
-	    fprintf(output, "\t\t\t%s\n", p->name);
-	    ++p;
-	}
-    }
-}
-
-static void dump_flat_SGMLContent(FILE *output, const char *name, SGMLContent contents)
-{
-    fprintf(output, "\t\t%s: %s\n", name, SGMLContent2s(contents));
-}
-
-#define DUMP(name) \
-	if (theClass & Tgc_##name) {\
-	    fprintf(output, " " #name); \
-	    theClass &= ~(Tgc_##name); \
-	}
-
-static void dump_flat_TagClass(FILE *output, const char *name, TagClass theClass)
-{
-    fprintf(output, "\t\t%s:", name);
-    DUMP(FONTlike);
-    DUMP(EMlike);
-    DUMP(MATHlike);
-    DUMP(Alike);
-    DUMP(formula);
-    DUMP(TRlike);
-    DUMP(SELECTlike);
-    DUMP(FORMlike);
-    DUMP(Plike);
-    DUMP(DIVlike);
-    DUMP(LIlike);
-    DUMP(ULlike);
-    DUMP(BRlike);
-    DUMP(APPLETlike);
-    DUMP(HRlike);
-    DUMP(MAPlike);
-    DUMP(outer);
-    DUMP(BODYlike);
-    DUMP(HEADstuff);
-    DUMP(same);
-    if (theClass)
-	fprintf(output, " OOPS:%#x", theClass);
-    fprintf(output, "\n");
-}
-
-#undef DUMP
-
-#define DUMP(name) \
-	if (theFlags & Tgf_##name) {\
-	    fprintf(output, " " #name); \
-	    theFlags &= ~(Tgf_##name); \
-	}
-
-static void dump_flat_TagFlags(FILE *output, const char *name, TagFlags theFlags)
-{
-    fprintf(output, "\t\t%s:", name);
-    DUMP(endO);
-    DUMP(startO);
-    DUMP(mafse);
-    DUMP(strict);
-    DUMP(nreie);
-    DUMP(frecyc);
-    DUMP(nolyspcl);
-    if (theFlags)
-	fprintf(output, " OOPS:%#x", theFlags);
-    fprintf(output, "\n");
-}
-
-#undef DUMP
-
-static void dump_flat_HTTag(FILE *output, unsigned n, HTTag * tag)
-{
-    fprintf(output, "\t%u:%s\n", n, tag->name);
-#ifdef USE_JUSTIFY_ELTS
-    fprintf(output, "\t\t%s\n", tag->can_justify ? "justify" : "nojustify");
-#endif
-    dump_flat_attrs(output, tag->attributes, AttrCount(tag));
-    dump_flat_attr_types(output, tag->attr_types);
-    dump_flat_SGMLContent(output, "contents", tag->contents);
-    dump_flat_TagClass(output, "tagclass", tag->tagclass);
-    dump_flat_TagClass(output, "contains", tag->contains);
-    dump_flat_TagClass(output, "icontains", tag->icontains);
-    dump_flat_TagClass(output, "contained", tag->contained);
-    dump_flat_TagClass(output, "icontained", tag->icontained);
-    dump_flat_TagClass(output, "canclose", tag->canclose);
-    dump_flat_TagFlags(output, "flags", tag->flags);
-}
-
-static int count_attr_types(AttrType * attr_types, HTTag * tag)
-{
-    int count = 0;
-    const AttrType *p;
-    AttrType *q;
-
-    if ((p = tag->attr_types) != 0) {
-	while (p->name != 0) {
-	    if ((q = attr_types) != 0) {
-		while (q->name != 0) {
-		    if (!strcmp(q->name, p->name)) {
-			--count;
-			break;
-		    }
-		    ++q;
-		}
-		*q = *p;
-	    }
-	    ++count;
-	    ++p;
-	}
-    }
-    return count;
-}
-
-static void dump_flatfile(FILE *output, const SGML_dtd * dtd)
-{
-    AttrType *attr_types = 0;
-    int pass;
-    unsigned count = 0;
-    unsigned n;
-
-    /* merge all of the attr_types data */
-    for (pass = 0; pass < 2; ++pass) {
-	for (n = 0; (int) n < dtd->number_of_tags; ++n) {
-	    count += count_attr_types(attr_types, &(dtd->tags[n]));
-	}
-	if (pass == 0) {
-	    attr_types = typecallocn(AttrType, count + 1);
-	    count = 0;
-	} else {
-	    count = len_AttrTypes(attr_types);
-	    qsort(attr_types, count, sizeof(*attr_types), compare_attr_types);
-	    fprintf(output, "%d attr_types\n", count);
-	    for (n = 0; n < count; ++n) {
-		fprintf(output, "\t%d:%s\n", n, attr_types[n].name);
-		dump_flat_attrs(output, attr_types[n].list,
-				len_AttrList(attr_types[n].list));
-	    }
-	}
-    }
-
-    fprintf(output, "%d tags\n", dtd->number_of_tags);
-    for (n = 0; (int) n < dtd->number_of_tags; ++n) {
-	dump_flat_HTTag(output, n, &(dtd->tags[n]));
-    }
-#if 0
-    fprintf(output, "%d entities\n", dtd->number_of_entities);
-    for (n = 0; n < dtd->number_of_entities; ++n) {
-    }
-#endif
-}
-
-static char *get_line(FILE *input)
-{
-    char temp[1024];
-    char *result = 0;
-
-    if (fgets(temp, (int) sizeof(temp), input) != 0) {
-	result = strdup(temp);
-    }
-    return result;
-}
-
-#define LOAD(name) \
-	if (!strcmp(data, #name)) {\
-	    *theClass |= Tgc_##name; \
-	    continue; \
-	}
-
-static int load_flat_TagClass(FILE *input, const char *name, TagClass * theClass)
-{
-    char prefix[80];
-    char *next = get_line(input);
-    char *data;
-    int result = 0;
-
-    *theClass = 0;
-    if (next != 0) {
-	sprintf(prefix, "\t\t%s:", name);
-	data = strtok(next, "\n ");
-
-	if (data != 0 && !strcmp(data, prefix)) {
-	    result = 1;
-
-	    while ((data = strtok(NULL, "\n ")) != 0) {
-
-		LOAD(FONTlike);
-		LOAD(EMlike);
-		LOAD(MATHlike);
-		LOAD(Alike);
-		LOAD(formula);
-		LOAD(TRlike);
-		LOAD(SELECTlike);
-		LOAD(FORMlike);
-		LOAD(Plike);
-		LOAD(DIVlike);
-		LOAD(LIlike);
-		LOAD(ULlike);
-		LOAD(BRlike);
-		LOAD(APPLETlike);
-		LOAD(HRlike);
-		LOAD(MAPlike);
-		LOAD(outer);
-		LOAD(BODYlike);
-		LOAD(HEADstuff);
-		LOAD(same);
-
-		fprintf(stderr, "Unexpected TagClass '%s'\n", data);
-		result = 0;
-		break;
-	    }
-	} else if (data) {
-	    fprintf(stderr, "load_flat_TagClass: '%s' vs '%s'\n", data, prefix);
-	}
-	free(next);
-    } else {
-	fprintf(stderr, "Did not find contents\n");
-    }
-    return result;
-}
-
-#undef LOAD
-
-#define LOAD(name) \
-	if (!strcmp(data, #name)) {\
-	    *flags |= Tgf_##name; \
-	    continue; \
-	}
-
-static int load_flat_TagFlags(FILE *input, const char *name, TagFlags * flags)
-{
-    char prefix[80];
-    char *next = get_line(input);
-    char *data;
-    int result = 0;
-
-    *flags = 0;
-    if (next != 0) {
-	sprintf(prefix, "\t\t%s:", name);
-	data = strtok(next, "\n ");
-
-	if (data != 0 && !strcmp(data, prefix)) {
-	    result = 1;
-
-	    while ((data = strtok(NULL, "\n ")) != 0) {
-
-		LOAD(endO);
-		LOAD(startO);
-		LOAD(mafse);
-		LOAD(strict);
-		LOAD(nreie);
-		LOAD(frecyc);
-		LOAD(nolyspcl);
-
-		fprintf(stderr, "Unexpected TagFlag '%s'\n", data);
-		result = 0;
-		break;
-	    }
-	} else if (data) {
-	    fprintf(stderr, "load_flat_TagFlags: '%s' vs '%s'\n", data, prefix);
-	}
-	free(next);
-    }
-    return result;
-}
-
-#undef LOAD
-
-static int load_flat_AttrList(FILE *input, AttrList * attrs, int *length)
-{
-    attr *attributes;
-    int j, jcmp, code;
-    int result = 1;
-    char name[1024];
-
-#ifdef USE_PRETTYSRC
-    int atype;
-#endif
-
-    if (fscanf(input, FMT_NUM_ATTRS, length) == 1
-	&& *length > 0
-	&& (attributes = typecallocn(attr, (size_t) (*length + 1))) != 0) {
-	*attrs = attributes;
-	for (j = 0; j < *length; ++j) {
-	    code = fscanf(input, FMT_ONE_ATTR,
-			  &jcmp,
-			  &atype,
-			  name
-		);
-	    if (code == NUM_ONE_ATTR && (j == jcmp)) {
-		attributes[j].name = strdup(name);
-#ifdef USE_PRETTYSRC
-		attributes[j].type = atype;
-#endif
-	    } else {
-		fprintf(stderr, "Did not find attributes\n");
-		result = 0;
-		break;
-	    }
-	}
-	if (*length > 1)
-	    qsort(attributes, *length, sizeof(attributes[0]), compare_attr);
-    }
-    return result;
-}
-
-static int load_flat_HTTag(FILE *input, unsigned nref, HTTag * tag, AttrType * allTypes)
-{
-    int result = 0;
-    unsigned ncmp = 0;
-    char name[1024];
-    int code;
-    int j;
-
-    code = fscanf(input, "%d:%s\n", &ncmp, name);
-    if (code == 2 && (nref == ncmp)) {
-	result = 1;
-	tag->name = strdup(name);
-#ifdef USE_COLOR_STYLE
-	tag->name_len = strlen(tag->name);
-#endif
-#ifdef USE_JUSTIFY_ELTS
-	if (fscanf(input, "%s\n", name) == 1) {
-	    tag->can_justify = !strcmp(name, "justify");
-	} else {
-	    fprintf(stderr, "Did not find can_justify\n");
-	    result = 0;
-	}
-#endif
-	if (result) {
-	    result = load_flat_AttrList(input, &(tag->attributes), &(tag->number_of_attributes));
-	}
-	if (result) {
-	    AttrType *myTypes;
-	    int k, count;
-	    char *next = get_line(input);
-
-	    if (next != 0
-		&& sscanf(next, "%d attr_types\n", &count)
-		&& (myTypes = typecallocn(AttrType, (size_t) (count + 1)))
-		!= 0) {
-		tag->attr_types = myTypes;
-		for (k = 0; k < count; ++k) {
-		    next = get_line(input);
-		    if (next != 0
-			&& sscanf(next, "%s\n", name)) {
-			for (j = 0; allTypes[j].name != 0; ++j) {
-			    if (!strcmp(allTypes[j].name, name)) {
-				myTypes[k].name = strdup(name);
-				myTypes[k].list = allTypes[j].list;
-				break;
-			    }
-			}
-		    } else {
-			result = 0;
-			break;
-		    }
-		}
-		if (result && count > 1)
-		    qsort(myTypes, count, sizeof(myTypes[0]), compare_attr_types);
-	    }
-	}
-	if (result) {
-	    char *next = get_line(input);
-
-	    if (next != 0
-		&& sscanf(next, "\t\tcontents: %s\n", name)) {
-		tag->contents = s2SGMLContent(name);
-		free(next);
-	    } else {
-		fprintf(stderr, "Did not find contents\n");
-		result = 0;
-	    }
-	}
-	if (result) {
-	    result = load_flat_TagClass(input, "tagclass", &(tag->tagclass));
-	}
-	if (result) {
-	    result = load_flat_TagClass(input, "contains", &(tag->contains));
-	}
-	if (result) {
-	    result = load_flat_TagClass(input, "icontains", &(tag->icontains));
-	}
-	if (result) {
-	    result = load_flat_TagClass(input, "contained", &(tag->contained));
-	}
-	if (result) {
-	    result = load_flat_TagClass(input, "icontained", &(tag->icontained));
-	}
-	if (result) {
-	    result = load_flat_TagClass(input, "canclose", &(tag->canclose));
-	}
-	if (result) {
-	    result = load_flat_TagFlags(input, "flags", &(tag->flags));
-	}
-    } else {
-	fprintf(stderr, "load_flat_HTTag error\n");
-    }
-    return result;
-}
-
-static int load_flat_AttrType(FILE *input, AttrType * types, size_t ncmp)
-{
-    int result = 0;
-    int ntst;
-    char name[1024];
-
-    if (fscanf(input, "%d:%s\n", &ntst, name) == 2
-	&& (ntst == (int) ncmp)) {
-	result = 1;
-	types->name = strdup(name);
-	if (!load_flat_AttrList(input, &(types->list), &ntst))
-	    result = 0;
-    }
-    return result;
-}
-
-static SGML_dtd *load_flatfile(FILE *input)
-{
-    AttrType *attr_types = 0;
-    SGML_dtd *result = 0;
-    size_t n;
-    size_t number_of_attrs = 0;
-    size_t number_of_tags = 0;
-    HTTag *tag;
-    int code;
-
-    code = fscanf(input, "%d attr_types\n", &number_of_attrs);
-    if (code
-	&& number_of_attrs
-	&& (attr_types = typecallocn(AttrType, number_of_attrs + 1)) != 0) {
-	for (n = 0; n < number_of_attrs; ++n) {
-	    if (!load_flat_AttrType(input, attr_types + n, n)) {
-		break;
-	    }
-	}
-    }
-
-    code = fscanf(input, "%d tags\n", &number_of_tags);
-    if (code == 1) {
-	if ((result = typecalloc(SGML_dtd)) != 0
-	    && (result->tags = typecallocn(HTTag, (number_of_tags + 2))) != 0) {
-	    for (n = 0; n < number_of_tags; ++n) {
-		if (load_flat_HTTag(input, n, &(result->tags[n]), attr_types)) {
-		    result->number_of_tags = (n + 1);
-		} else {
-		    break;
-		}
-	    }
-	    tag = 0;
-	    for (n = 0; n < number_of_tags; ++n) {
-		if (result->tags[n].name != 0
-		    && !strcmp(result->tags[n].name, "OBJECT")) {
-		    tag = result->tags + number_of_tags;
-		    *tag = result->tags[n];
-		    tag->contents = SGML_MIXED;
-		    tag->flags = Tgf_strict;
-		    break;
-		}
-	    }
-	    if (tag == 0) {
-		fprintf(stderr, "Did not find OBJECT tag\n");
-		result = 0;
-	    }
-	}
-    }
-    return result;
-}
-
-int main(int argc, char *argv[])
-{
-    const SGML_dtd *the_dtd = &HTML_dtd;
-    int ch;
-    int dtd_version = 0;
-    int c_option = FALSE;
-    int h_option = FALSE;
-    int l_option = FALSE;
-    FILE *input = stdin;
-    FILE *output = stdout;
-
-    while ((ch = getopt(argc, argv, GETOPT)) != -1) {
-	switch (ch) {
-	case 'c':
-	    c_option = TRUE;
-	    break;
-	case 'h':
-	    h_option = TRUE;
-	    break;
-	case 'l':
-	    l_option = TRUE;
-	    input = fopen(optarg, "r");
-	    if (input == 0)
-		failed(optarg);
-	    break;
-	case 'o':
-	    output = fopen(optarg, "w");
-	    if (output == 0)
-		failed(optarg);
-	    break;
-	case 't':
-	    dtd_version = 1;
-	    break;
-	case 's':
-	    dtd_version = 0;
-	    break;
-	default:
-	    usage();
-	}
-    }
-
-    HTSwitchDTD(dtd_version);
-    if (l_option)
-	the_dtd = load_flatfile(input);
-
-    if (the_dtd != 0) {
-	if (c_option)
-	    dump_source(output, the_dtd, dtd_version);
-	if (h_option)
-	    dump_header(output, the_dtd);
-	if (!c_option && !h_option)
-	    dump_flatfile(output, the_dtd);
-    }
-
-    return EXIT_SUCCESS;
-}