about summary refs log tree commit diff stats
path: root/WWW/Library/Implementation/SGML.c
diff options
context:
space:
mode:
authorThomas E. Dickey <dickey@invisible-island.net>2021-07-23 23:38:38 +0000
committerThomas E. Dickey <dickey@invisible-island.net>2021-07-23 23:38:38 +0000
commitfd6abf252cbc486b59eb5e9187bc87f4b05f6cd0 (patch)
tree770d4e9a4887c79d620360482c3f4290a7a4cbe7 /WWW/Library/Implementation/SGML.c
parentcc4054129b8ce4043e8ab2a701e795827bdb2e0a (diff)
downloadlynx-snapshots-fd6abf252cbc486b59eb5e9187bc87f4b05f6cd0.tar.gz
snapshot of project "lynx", label v2-9-0dev_6n
Diffstat (limited to 'WWW/Library/Implementation/SGML.c')
-rw-r--r--WWW/Library/Implementation/SGML.c60
1 files changed, 54 insertions, 6 deletions
diff --git a/WWW/Library/Implementation/SGML.c b/WWW/Library/Implementation/SGML.c
index 97a25eee..7e04a6cc 100644
--- a/WWW/Library/Implementation/SGML.c
+++ b/WWW/Library/Implementation/SGML.c
@@ -1,5 +1,5 @@
 /*
- * $LynxId: SGML.c,v 1.176 2021/07/02 00:08:26 tom Exp $
+ * $LynxId: SGML.c,v 1.177 2021/07/23 20:36:47 tom Exp $
  *
  *			General SGML Parser code		SGML.c
  *			========================
@@ -981,6 +981,8 @@ static void handle_sgmlatt(HTStream *me)
 #define ALT_TAGP(t) ALT_TAGP_OF_TAGNUM(TAGNUM_OF_TAGP(t))
 #define NORMAL_TAGP(t) NORMAL_TAGP_OF_TAGNUM(TAGNUM_OF_TAGP(t))
 
+#define IsTagAlias(a,b) (((a) == (b)) || ((a) - (a)->alias == (b) - (b)->alias))
+
 static BOOL element_valid_within(HTTag * new_tag, HTTag * stacked_tag, int direct)
 {
     BOOL result = YES;
@@ -989,7 +991,7 @@ static BOOL element_valid_within(HTTag * new_tag, HTTag * stacked_tag, int direc
     if (stacked_tag && new_tag) {
 	usecontains = (direct ? stacked_tag->contains : stacked_tag->icontains);
 	usecontained = (direct ? new_tag->contained : new_tag->icontained);
-	if (new_tag == stacked_tag) {
+	if (IsTagAlias(new_tag, stacked_tag)) {
 	    result = (BOOL) ((Tgc_same & usecontains) &&
 			     (Tgc_same & usecontained));
 	} else {
@@ -1000,6 +1002,26 @@ static BOOL element_valid_within(HTTag * new_tag, HTTag * stacked_tag, int direc
     return result;
 }
 
+static BOOL element_really_within(HTTag * new_tag, HTTag * stacked_tag, int direct)
+{
+    BOOL result = YES;
+    TagClass usecontains, usecontained;
+
+    if (stacked_tag && new_tag) {
+	usecontains = (direct ? stacked_tag->contains : stacked_tag->icontains);
+	usecontained = (direct ? new_tag->contained : new_tag->icontained);
+	if (IsTagAlias(new_tag, stacked_tag)) {
+	    result = (BOOL) ((Tgc_same & usecontains) &&
+			     (Tgc_same & usecontained));
+	} else {
+	    result = (BOOL) ((new_tag->tagclass & usecontains) ==
+			     new_tag->tagclass &&
+			     (stacked_tag->tagclass & usecontained) == stacked_tag->tagclass);
+	}
+    }
+    return result;
+}
+
 typedef enum {
     close_NO = 0,
     close_error = 1,
@@ -1014,7 +1036,7 @@ static canclose_t can_close(HTTag * new_tag, HTTag * stacked_tag)
 	result = close_NO;
     } else if (stacked_tag->flags & Tgf_endO) {
 	result = close_valid;
-    } else if (new_tag == stacked_tag) {
+    } else if (IsTagAlias(new_tag, stacked_tag)) {
 	result = ((Tgc_same & new_tag->canclose)
 		  ? close_error
 		  : close_NO);
@@ -1057,7 +1079,7 @@ static int is_on_stack(HTStream *me, HTTag * old_tag)
     int i = 1;
 
     for (; stacked; stacked = stacked->next, i++) {
-	if (stacked->tag == old_tag ||
+	if (IsTagAlias(stacked->tag, old_tag) ||
 	    stacked->tag == ALT_TAGP(old_tag))
 	    return i;
     }
@@ -1072,8 +1094,21 @@ static void end_element(HTStream *me, HTTag * old_tag)
     BOOL extra_action_taken = NO;
     canclose_t canclose_check = close_valid;
     int stackpos = is_on_stack(me, old_tag);
+    BOOL direct_container = YES;
 
     if (!Old_DTD) {
+	if (old_tag->aliases) {
+	    if (me->element_stack) {
+		if (!element_really_within(old_tag,
+					   me->element_stack->tag,
+					   direct_container) &&
+		    element_really_within(old_tag + 1,
+					  me->element_stack->tag,
+					  direct_container)) {
+		    ++old_tag;
+		}
+	    }
+	}
 	while (canclose_check != close_NO &&
 	       me->element_stack &&
 	       (stackpos > 1 || (!extra_action_taken && stackpos == 0))) {
@@ -1195,7 +1230,7 @@ static void end_element(HTStream *me, HTTag * old_tag)
 		    ? (me->element_stack->tag->flags & Tgf_nolyspcl)
 		    : NO);
 #ifdef WIND_DOWN_STACK
-	if (old_tag == t)
+	if (IsTagAlias(old_tag, t))
 	    return;		/* Correct sequence */
 #else
 	return;
@@ -1223,10 +1258,22 @@ static void start_element(HTStream *me)
     canclose_t canclose_check = close_valid;
 
     if (!Old_DTD) {
+	if (new_tag->aliases) {
+	    if (me->element_stack) {
+		if (!element_really_within(new_tag,
+					   me->element_stack->tag,
+					   direct_container) &&
+		    element_really_within(new_tag + 1,
+					  me->element_stack->tag,
+					  direct_container)) {
+		    ++new_tag;
+		}
+	    }
+	}
 	while (me->element_stack &&
 	       (canclose_check == close_valid ||
 		(canclose_check == close_error &&
-		 new_tag == me->element_stack->tag)) &&
+		 IsTagAlias(new_tag, me->element_stack->tag))) &&
 	       !(valid = element_valid_within(new_tag,
 					      me->element_stack->tag,
 					      direct_container))) {
@@ -1417,6 +1464,7 @@ HTTag *SGMLFindTag(const SGML_dtd * dtd,
 	/* my_casecomp() - optimized by the first character, NOT_ASCII ok */
 	diff = my_casecomp(dtd->tags[i].name, s);	/* Case insensitive */
 	if (diff == 0) {	/* success: found it */
+	    i -= dtd->tags[i].alias;
 	    *res = &dtd->tags[i];
 	    return *res;
 	}