• Patch: Elm ME+ 2.5 PLalpha62 -> Elm ME+ 2.5 PLalpha63 [4/7] (5/7)

    From Kari Hurtta@21:1/5 to All on Wed Jan 3 13:52:11 2024
    [continued from previous message]

    +
    + if (token->tag_lookahead) {
    + DEBUG_PRINT_STRING(Debug,20,
    + " tag_lookahead ",
    + " tag_lookahead > ",
    + token->tag_lookahead);
    + }
    + }
    +
    + if (token->tag_flags) {
    + DPRINT(Debug,20,(&Debug, " tag_flags %d",
    + token->tag_flags));
    +
    + if (ison(token->tag_flags,TFLAG_seen_nl)) {
    + DPRINT(Debug,20,(&Debug, " TFLAG_seen_nl"));
    + }
    + if (ison(token->tag_flags,TFLAG_seen_equals)) {
    + DPRINT(Debug,20,(&Debug, " TFLAG_seen_equals"));
    + }
    + if (ison(token->tag_flags,TFLAG_num_overflow)) {
    + DPRINT(Debug,20,(&Debug, " TFLAG_num_overflow"));
    + }
    + if (ison(token->tag_flags,TFLAG_unhandled_class)) {
    + DPRINT(Debug,20,(&Debug, " TFLAG_unhandled_class"));
    + }
    +
    + DPRINT(Debug,20,(&Debug, "\n"));
    + }
    +
    +
    + if (token->entity_state != ent_init ||
    + token->tag_state != ts_init ||
    + token->token_class == tf_body) {
    +
    + DPRINT(Debug,20,(&Debug, " entity_state %d",
    + token->entity_state));
    +
    + switch (token->entity_state) {
    + case ent_init: DPRINT(Debug,20,(&Debug, " ent_init")); break;
    + case ent_entity_start: DPRINT(Debug,20,(&Debug, " ent_entity_start")); break; /* Seen & on tag params or body */
    + case ent_decimal_ent: DPRINT(Debug,20,(&Debug, " ent_decimal_ent")); break; /* Seen &# on tag params or body */
    + case ent_hexdec_ent: DPRINT(Debug,20,(&Debug, " ent_hexdec_ent")); break; /* Seen &#x or &#X */
    + }
    +
    + DPRINT(Debug,20,(&Debug, "\n"));
    + }
    +
    + if (token->resubmit) {
    + DEBUG_PRINT_STRING(Debug,20,
    + " resubmit ",
    + " resubmit > ",
    + token->resubmit);
    + }
    +
    + if (token->sbuffer) {
    + DEBUG_PRINT_STRING(Debug,20,
    + " sbuffer ",
    + " sbuffer > ",
    + token->sbuffer);
    + }
    +
    + return ret;
    + }
    +
    + #define TAGFILTER_PARAMS_magic 0xFD12
    +
    + struct tagfilter_params {
    + unsigned short magic; /* TAGFILTER_PARAMS_magic */
    +
    + mime_t * body;
    + struct in_state * state_in;
    + struct out_state * state_out;
    + const struct decode_opts * decode_opt;
    + charset_t text_charset;
    + struct tagfilter_selection * tagfilter;
    +
    + struct tagfilter_token * current_token;
    + int error;
    +
    + struct tagfilter_stack_item **stack;
    + size_t stack_len;
    +
    + struct tagfilter_global * counter;
    + };
    +
    + static struct pager_range *tagfilter_inherited_pager_range
    + P_((struct tagfilter_params *params));
    + static struct pager_range *tagfilter_inherited_pager_range(params)
    + struct tagfilter_params *params;
    + {
    + struct pager_range *inherit = NULL;
    +
    + if (TAGFILTER_PARAMS_magic != params->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_inherited_pager_range",
    + "Bad magic number");
    +
    +
    + if (params->stack && params->stack_len > 0) {
    + size_t i = params->stack_len;
    +
    + while (i > 0) {
    + i--;
    +
    + if (params->stack[i]) {
    +
    + if (TAGFILTER_STACK_ITEM_magic != params->stack[i]->magic)
    + mime_panic(__FILE__,__LINE__,
    + "tagfilter_inherited_pager_range",
    + "Bad magic number (tagfilter_stack_item)");
    +
    + inherit = params->stack[i]->range;
    + if (inherit)
    + break;
    + }
    + }
    + }
    +
    + return inherit;
    + }
    +
    + static int tagfilter_inherited_pg_flags P_((struct tagfilter_params *params));
    + static int tagfilter_inherited_pg_flags(params)
    + struct tagfilter_params *params;
    + {
    + int inherit = 0;
    + int disable_pg_flags = 0;
    +
    + if (TAGFILTER_PARAMS_magic != params->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_inherited_pg_flags",
    + "Bad magic number");
    +
    + if (params->stack && params->stack_len > 0) {
    + size_t i = params->stack_len;
    +
    + while (i > 0) {
    + i--;
    +
    + if (params->stack[i]) {
    + int flags;
    + int d;
    +
    + if (TAGFILTER_STACK_ITEM_magic != params->stack[i]->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_inherited_pg_flags",
    + "Bad magic number ( tagfilter_stack_item)");
    +
    + flags = params->stack[i]->pg_flags;
    +
    + clearit(flags,disable_pg_flags);
    + setit(inherit,flags);
    +
    + /* No values before this */
    + if (params->stack[i]->reset_pg_flags)
    + break;
    +
    + d = pg_set_or_disable_flags(NULL,flags);
    + setit(disable_pg_flags,d);
    + }
    + }
    + }
    +
    + return inherit;
    + }
    +
    + static void tagfilter_dump_token P_((struct tagfilter_params *params,
    + int pg_flags));
    + static void tagfilter_dump_token(params,pg_flags)
    + struct tagfilter_params *params;
    + int pg_flags;
    + {
    + if (TAGFILTER_PARAMS_magic != params->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_dump_token",
    + "Bad magic number (tagfilter_params)");
    +
    + if (TAGFILTER_TOKEN_magic != params->current_token->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_dump_token",
    + "Bad magic number (tagfilter_token)");
    +
    + if (params->current_token->sbuffer)
    + state_putstring(params->current_token->sbuffer,
    + params->state_out);
    +
    + if (params->current_token->error)
    + params->error = 1;
    +
    + if (params->current_token->have_nl) {
    + struct pager_range *inherit
    + = tagfilter_inherited_pager_range(params);
    +
    + state_putc('\n',params->state_out);
    +
    + /* Re-set pg_flags */
    + set_out_state_line_mode(params->state_out,pg_flags,
    + inherit,0 );
    + }
    + }
    +
    + #define MAX_COLLECTED 1002
    +
    + enum collect_truncated {
    + collect_full_tag,
    + collect_truncated_tag,
    + collect_nl_tag,
    + collect_nl_truncated_tag,
    +
    + };
    +
    +
    + static void tagfilter_collect_token P_((struct tagfilter_params *params,
    + struct string ** collected_tag,
    + enum collect_truncated *truncated_tag));
    + static void tagfilter_collect_token(params,collected_tag,truncated_tag)
    + struct tagfilter_params *params;
    + struct string ** collected_tag;
    + enum collect_truncated *truncated_tag;
    + {
    + if (TAGFILTER_PARAMS_magic != params->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_collect_token",
    + "Bad magic number (tagfilter_params)");
    +
    + if (TAGFILTER_TOKEN_magic != params->current_token->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_collect_token",
    + "Bad magic number (tagfilter_token)");
    +
    + if (params->current_token->error)
    + params->error = 1;
    +
    + switch (*truncated_tag) {
    + case collect_truncated_tag:
    + case collect_nl_truncated_tag:
    + break;
    + case collect_nl_tag:
    + if (params->current_token->sbuffer)
    + *truncated_tag = collect_nl_truncated_tag;
    + break;
    +
    + case collect_full_tag:
    + if ((* collected_tag) &&
    + string_len(* collected_tag) >= MAX_COLLECTED) {
    + *truncated_tag = collect_truncated_tag;
    + } else {
    + if (params->current_token->sbuffer)
    + append_string(collected_tag,params->current_token->sbuffer,0); +
    + if (params->current_token->have_nl)
    + *truncated_tag = collect_nl_tag;
    + }
    + }
    + }
    +
    +
    + #if DEBUG
    + static char * token_class_string P_((enum tf_token_class cl));
    + static char * token_class_string(cl)
    + enum tf_token_class cl;
    + {
    + switch (cl) {
    + case tf_doctype_error: return "tf_doctype_error";
    + case tf_tag_atrvalue_error: return "tf_tag_atrvalue_error";
    + case tf_tag_param_error: return "tf_tag_param_error";
    + case tf_comment_error: return "tf_comment_error";
    + case tf_bcomment_error: return "tf_bcomment_error";
    + case tf_tag_error: return "tf_tag_error";
    + case tf_entity_error: return "tf_entity_error";
    + case tf_body: return "tf_body";
    + case tf_start_tag: return "tf_start_tag"; /* <tag */
    + case tf_whole_tag: return "tf_whole_tag"; /* <tag> */
    + case tf_selfclosed_tag: return "tf_selfclosed_tag"; /* <tag/> */
    + case tf_bcomment_start: return "tf_bcomment_start"; /* <? or <! or </ */
    + case tf_bcomment_chunk: return "tf_bcomment_chunk"; /* <? gogus comment chunk */
    + case tf_bcomment_end: return "tf_bcomment_end"; /* end bogus comment > */
    + case tf_start_endtag: return "tf_start_endtag"; /* </tag */
    + case tf_whole_endtag: return "tf_whole_endtag"; /* </tag> */
    + case tf_entity: return "tf_entity";
    + case tf_numeric_entity: return "tf_numeric_entity"; /* Numeric entity */
    + case tf_double_smaller: return "tf_double_smaller"; /* << as escaping */
    + case tf_span_nl: return "tf_span_nl"; /* span of newline (except first) */
    + case tf_comment_start: return "tf_comment_start"; /* <!-- */
    + case tf_whole_comment: return "tf_whole_comment"; /* <!----> */
    + case tf_comment_chunk: return "tf_comment_chunk"; /* <!-- comment chunk */
    + case tf_comment_end: return "tf_comment_end"; /* end comment --> */
    + case tf_tag_space: return "tf_tag_space"; /* space on attributes */
    + case tf_tag_atrname: return "tf_tag_atrname"; /* Got attribute name */
    + case tf_tag_selfclosed_end: return "tf_tag_selfclosed_end"; /* Got /> */
    + case tf_tag_end: return "tf_tag_end"; /* Got > */
    + case tf_tag_atrequal: return "tf_tag_atrequal"; /* Got = */
    + case tf_tag_atrvalue_start: return "tf_tag_atrvalue_start"; /* Start attribute value */
    + case tf_tag_atrvalue_segment: return "tf_tag_atrvalue_segment"; /* Part of attribute value */
    + case tf_tag_atrvalue_end: return "tf_tag_atrvalue_end"; /* Start attribute value */
    + case tf_doctype_start: return "tf_doctype_start"; /* <!DOCTYPE */
    + case tf_doctype_segment: return "tf_doctype_segment"; /* Part of DOCTYPE */
    + case tf_doctype_space: return "tf_doctype_space"; /* Space on doctype */
    + case tf_doctype_item: return "tf_doctype_item"; /* Collected doctype item */
    + case tf_doctype_end: return "tf_doctype_end"; /* DOCTYPE line ended */
    + }
    +
    + return "<unknown>";
    + }
    +
    + #endif
    +
    + /* Returns current_token_len -- */
    +
    + static int tagfilter_handle_doctype P_((struct tagfilter_params *params,
    + int current_token_len));
    +
    + static int tagfilter_handle_doctype(params,current_token_len)
    + struct tagfilter_params * params;
    + int current_token_len;
    + {
    + int doctype_ok = 0;
    + int idx = 0;
    + struct string * collected_tag = NULL;
    + enum collect_truncated truncated_tag = collect_full_tag;
    + int inherit_pg_flags;
    + struct pager_range *inherit;
    +
    + if (TAGFILTER_PARAMS_magic != params->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_handle_doctype",
    + "Bad magic number");
    +
    + if (TAGFILTER_SELECTION_magic != params->tagfilter->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_handle_doctype",
    + "Bad magic number (tagfilter_selection)");
    +
    + if (MIME_magic != params->body->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_handle_doctype",
    + "Bad magic number (mime_t)");
    +
    + if (TAGFILTER_TOKEN_magic != params->current_token->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_handle_doctype",
    + "Bad magic number (tagfilter_token)");
    +
    + DPRINT(Debug,20,(&Debug,
    + "tagfilter_handle_doctype: START current token len = %d, class = %d %s\n",
    + current_token_len,params->current_token->token_class,
    + token_class_string(params->current_token->token_class))); + if (params->current_token->sbuffer) {
    + DEBUG_PRINT_STRING(Debug,20,
    + "tagfilter_handle_doctype: current token = ",
    + "tagfilter_handle_doctype: current token > ",
    + params->current_token->sbuffer);
    + }
    +
    + inherit_pg_flags = tagfilter_inherited_pg_flags(params);
    + inherit = tagfilter_inherited_pager_range(params);
    +
    + while (current_token_len >= 0) {
    + if (params->current_token->error) {
    + struct pager_range *title_range =
    + state_add_simple_pager_range(params->state_out,inherit,PR_MAX_WIDTH,0,
    + 0);
    +
    + /* \n resets this */
    + set_out_state_line_mode(params->state_out,pg_BOLD,title_range,
    + 1 /* Newline */);
    + state_nlputs("[ ",params->state_out);
    +
    + state_printf(params->state_out,
    + CATGETS(elm_msg_cat, MeSet,
    + MeTagFErrorDoctypeDeclaration,
    + "Character error when parsing DOCTYPE declaration for %s/%s."),
    + get_major_type_name(params->body->TYPE),
    + get_subtype_name(params->body->TYPE));
    + state_nlputs(" ]\n",params->state_out);
    +
    + lib_error(CATGETS(elm_msg_cat, MeSet,
    + MeTagFErrorDoctypeDeclaration,
    + "Character error when parsing DOCTYPE declaration for %s/%s."),
    + get_major_type_name(params->body->TYPE),
    + get_subtype_name(params->body->TYPE));
    +
    + free_pager_range(&title_range);
    +
    + goto fail_doctype;
    + }
    +
    +
    + switch(params->current_token->token_class) {
    + case tf_doctype_error:
    + case tf_doctype_segment:
    + goto fail_doctype;
    +
    + case tf_doctype_start:
    + if (0 != idx)
    + goto fail_doctype;
    + break;
    + case tf_doctype_space:
    + idx++;
    + break;
    + case tf_doctype_item:
    +
    + if (1 == idx &&
    + params->tagfilter->doctype_name &&
    + params->current_token->doctype_item) {
    +
    + if (string_matches_ascii(params->current_token->doctype_item,
    + cs2us(params->tagfilter->doctype_name),
    + SMA_ignore_case,SMA_op_normal)) {
    + doctype_ok = 1;
    + } else {
    + struct pager_range *title_range =
    + state_add_simple_pager_range(params->state_out,inherit, + PR_MAX_WIDTH,0,
    + 0);
    +
    + /* \n resets this */
    + set_out_state_line_mode(params->state_out,pg_BOLD,title_range,
    + 1 /* Newline */);
    + state_nlputs("[ ",params->state_out);
    +
    + state_printf(params->state_out,
    + CATGETS(elm_msg_cat, MeSet,
    + MeTagFIdentifierDoctypeDeclaration,
    + "Got identifier %S when parsing DOCTYPE declaration for %s/%s."),
    + params->current_token->doctype_item,
    + get_major_type_name(params->body->TYPE),
    + get_subtype_name(params->body->TYPE));
    +
    + state_nlputs(" ]\n",params->state_out);
    +
    + lib_error(CATGETS(elm_msg_cat, MeSet,
    + MeTagFIdentifierDoctypeDeclaration,
    + "Got identifier %S when parsing DOCTYPE declaration for %s/%s."),
    + params->current_token->doctype_item,
    + get_major_type_name(params->body->TYPE),
    + get_subtype_name(params->body->TYPE));
    +
    + free_pager_range(&title_range);
    +
    + goto fail_doctype;
    + }
    + }
    + break;
    + case tf_doctype_end:
    +
    + tagfilter_collect_token(params,&collected_tag,&truncated_tag);
    +
    + current_token_len =
    + get_new_tagfilter_token(params->current_token,
    + params->tagfilter,
    + params->state_in);
    + goto check_doctype;
    + default:
    + goto check_doctype;
    + }
    +
    + tagfilter_collect_token(params,&collected_tag,&truncated_tag);
    +
    + current_token_len =
    + get_new_tagfilter_token(params->current_token,
    + params->tagfilter,
    + params->state_in);
    +
    + }
    +
    + check_doctype:
    +
    + if (!doctype_ok) {
    + int pg_flags;
    +
    + if (params->tagfilter->doctype_name) {
    +
    + struct pager_range *title_range =
    + state_add_simple_pager_range(params->state_out,inherit,
    + PR_MAX_WIDTH,0,
    + 0);
    +
    + /* \n resets this */
    + set_out_state_line_mode(params->state_out,pg_BOLD,title_range,
    + 1 /* Newline */);
    + state_nlputs("[ ",params->state_out);
    +
    + state_printf(params->state_out,
    + CATGETS(elm_msg_cat, MeSet,
    + MeTagFNoIdentDoctypeDeclaration,
    + "Identifier %s not found when parsing DOCTYPE declaration for %s/%s."),
    + params->tagfilter->doctype_name,
    + get_major_type_name(params->body->TYPE),
    + get_subtype_name(params->body->TYPE));
    +
    + state_nlputs(" ]\n",params->state_out);
    +
    + lib_error(CATGETS(elm_msg_cat, MeSet,
    + MeTagFNoIdentDoctypeDeclaration,
    + "Identifier %s not found when parsing DOCTYPE declaration for %s/%s."),
    + params->tagfilter->doctype_name,
    + get_major_type_name(params->body->TYPE),
    + get_subtype_name(params->body->TYPE));
    +
    + free_pager_range(&title_range);
    +
    + }
    +
    + fail_doctype:
    + DPRINT(Debug,20,(&Debug,
    + "tagfilter_handle_doctype: FAIL current token len = %d, class = %d %s\n",
    + current_token_len,params->current_token->token_class, + token_class_string(params->current_token->token_class)));
    + if (params->current_token->sbuffer) {
    + DEBUG_PRINT_STRING(Debug,20,
    + "tagfilter_handle_doctype: current token = ",
    + "tagfilter_handle_doctype: current token > ",
    + params->current_token->sbuffer);
    + }
    +
    + pg_flags = pg_UNDERLINE;
    +
    + set_out_state_line_mode(params->state_out,pg_flags,
    + inherit,0 );
    +
    + if (collected_tag)
    + state_putstring(collected_tag,params->state_out);
    +
    + switch (truncated_tag) {
    + case collect_nl_tag:
    + state_putc('\n',params->state_out);
    +
    + set_out_state_line_mode(params->state_out,pg_flags,
    + inherit,0 );
    + break;
    +
    + case collect_nl_truncated_tag:
    + state_putc('\n',params->state_out);
    +
    + /* FALLTRU */
    + case collect_truncated_tag:
    +
    + set_out_state_line_mode(params->state_out,pg_BOLD|pg_flags,
    + inherit,0 );
    + state_puts(" ... ",params->state_out);
    +
    +
    + /* Does not change if not EOLN */
    + set_out_state_line_pg_flags(params->state_out,pg_flags);
    + break;
    + case collect_full_tag:
    + break;
    + }
    +
    + while (current_token_len >= 0) {
    +
    + switch(params->current_token->token_class) {
    + int was_end;
    + case tf_doctype_error:
    + case tf_doctype_start:
    + case tf_doctype_segment:
    + case tf_doctype_space:
    + case tf_doctype_item:
    + case tf_doctype_end:
    +
    + was_end = tf_doctype_end ==
    + params->current_token->token_class;
    +
    + tagfilter_dump_token(params,pg_flags);
    +
    + current_token_len =
    + get_new_tagfilter_token(params->current_token,
    + params->tagfilter,
    + params->state_in);
    +
    + if (was_end)
    + goto exit_doctype;
    + break;
    + default:
    + goto exit_doctype;
    + }
    + }
    +
    + exit_doctype:
    +
    + /* Should not cause newline */
    + if (pg_flags || inherit || inherit_pg_flags) {
    +
    + set_out_state_line_mode(params->state_out,inherit_pg_flags,
    + inherit,0 );
    + }
    +
    + }
    +
    + if (collected_tag)
    + free_string(& collected_tag);
    +
    + DPRINT(Debug,20,(&Debug,
    + "tagfilter_handle_doctype: END current token len = %d, class = %d %s\n",
    + current_token_len,params->current_token->token_class, + token_class_string(params->current_token->token_class)));
    + if (params->current_token->sbuffer) {
    + DEBUG_PRINT_STRING(Debug,20,
    + "tagfilter_handle_doctype: current token = ",
    + "tagfilter_handle_doctype: current token > ",
    + params->current_token->sbuffer);
    + }
    +
    +
    + return current_token_len;
    + }
    +
    + /* Returns current_token_len -- */
    +
    + static int tagfilter_handle_error P_((struct tagfilter_params *params,
    + int current_token_len));
    +
    + static int tagfilter_handle_error(params,current_token_len)
    + struct tagfilter_params * params;
    + int current_token_len;
    + {
    + int pg_flags = pg_UNDERLINE;
    + struct pager_range *inherit;
    + int inherit_pg_flags ;
    +
    + if (TAGFILTER_PARAMS_magic != params->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_handle_error",
    + "Bad magic number (tagfilter_params)");
    +
    + if (TAGFILTER_SELECTION_magic != params->tagfilter->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_handle_error",
    + "Bad magic number (tagfilter_selection)");
    +
    + if (TAGFILTER_TOKEN_magic != params->current_token->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_handle_error",
    + "Bad magic number (tagfilter_token)");
    +
    + DPRINT(Debug,20,(&Debug,
    + "tagfilter_handle_error: START current token len = %d, class = %d %s\n",
    + current_token_len,params->current_token->token_class,
    + token_class_string(params->current_token->token_class))); + if (params->current_token->sbuffer) {
    + DEBUG_PRINT_STRING(Debug,20,
    + "tagfilter_handle_error: current token = ",
    + "tagfilter_handle_error: current token > ",
    + params->current_token->sbuffer);
    + }
    +
    + inherit_pg_flags = tagfilter_inherited_pg_flags(params);
    + inherit = tagfilter_inherited_pager_range(params);
    +
    + set_out_state_line_mode(params->state_out,pg_flags,
    + inherit,0 );
    +
    + while (current_token_len >= 0 &&
    + params->current_token->token_class < tf_body /* 0 */) {
    +
    + tagfilter_dump_token(params,pg_flags);
    +
    + current_token_len =
    + get_new_tagfilter_token(params->current_token,
    + params->tagfilter,
    + params->state_in);
    + }
    +
    + /* Should not cause newline */
    + if (pg_flags || inherit || inherit_pg_flags) {
    + set_out_state_line_mode(params->state_out,inherit_pg_flags,
    + inherit,0 );
    + }
    +
    + DPRINT(Debug,20,(&Debug,
    + "tagfilter_handle_error: END current token len = %d, class = %d %s\n",
    + current_token_len,params->current_token->token_class,
    + token_class_string(params->current_token->token_class))); + if (params->current_token->sbuffer) {
    + DEBUG_PRINT_STRING(Debug,20,
    + "tagfilter_handle_error: current token = ",
    + "tagfilter_handle_error: current token > ",
    + params->current_token->sbuffer);
    + }
    +
    +
    + return current_token_len;
    + }
    +
    + /* Returns current_token_len -- */
    +
    + static int tagfilter_handle_body P_((struct tagfilter_params *params,
    + int current_token_len));
    +
    + static int tagfilter_handle_body(params,current_token_len)
    + struct tagfilter_params * params;
    + int current_token_len;
    + {
    + struct pager_range *inherit;
    + int inherit_pg_flags ;
    +
    + int text_visible = 1;
    +
    + if (TAGFILTER_PARAMS_magic != params->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_handle_body",
    + "Bad magic number");
    +
    + if (TAGFILTER_SELECTION_magic != params->tagfilter->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_handle_body",
    + "Bad magic number (tagfilter_selection)");
    +
    + if (TAGFILTER_TOKEN_magic != params->current_token->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_handle_body",
    + "Bad magic number (tagfilter_token)");
    +
    + DPRINT(Debug,20,(&Debug,
    + "tagfilter_handle_body: START current token len = %d, class = %d %s\n",
    + current_token_len,params->current_token->token_class,
    + token_class_string(params->current_token->token_class))); + if (params->current_token->sbuffer) {
    + DEBUG_PRINT_STRING(Debug,20,
    + "tagfilter_handle_body: current token = ",
    + "tagfilter_handle_body: current token > ",
    + params->current_token->sbuffer);
    + }
    +
    + if (params->stack && params->stack_len > 0) {
    + size_t idx = params->stack_len-1;
    +
    + if (TAGFILTER_STACK_ITEM_magic != params->stack[idx]->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_handle_body",
    + "Bad magic number ( tagfilter_stack_item)");
    +
    + text_visible = params->stack[idx]->text_visible;
    + }
    +
    + /* body text with entities on body */
    +
    + inherit_pg_flags = tagfilter_inherited_pg_flags(params);
    + inherit = tagfilter_inherited_pager_range(params);
    +
    + DPRINT(Debug,20,(&Debug,
    + "tagfilter_handle_body: Body pg_flags %d %s\n",
    + inherit_pg_flags,
    + give_pg_flags(inherit_pg_flags)));
    +
    + set_out_state_line_mode(params->state_out,inherit_pg_flags,
    + inherit,0 );
    +
    + while (current_token_len >= 0) {
    +
    + if (tf_body == params->current_token->token_class) {
    +
    + if (params->current_token->sbuffer && text_visible)
    + state_putstring(params->current_token->sbuffer,
    + params->state_out);
    +
    + } else if (tf_double_smaller == params->current_token->token_class) {
    + /* text/enriched escaped < */
    +
    + /* Note that sbuffer includes all charaters
    + part of token -- not just token value
    + */
    +
    + if (text_visible)
    + state_putc('<',params->state_out);
    +
    + } else if ( ts_init == params->current_token->tag_state &&
    + tf_entity_error == params->current_token->token_class ) {
    +
    + if (text_visible) {
    +
    + set_out_state_line_mode(params->state_out,
    + pg_UNDERLINE,
    + inherit,0 );
    +
    + if (params->current_token->sbuffer)
    + state_putstring(params->current_token->sbuffer,
    + params->state_out);
    +
    + set_out_state_line_mode(params->state_out,
    + inherit_pg_flags,
    + inherit,0 );
    + }
    +
    + } else if ( ts_init == params->current_token->tag_state &&
    + tf_entity == params->current_token->token_class ) {
    +
    +
    + if (params->current_token->sbuffer &&
    + params->current_token->match_reference &&
    + text_visible) {
    + struct out_entity * oe =
    + out_entity_from_match(params->current_token->sbuffer,
    + params->current_token->
    + match_reference,
    + pg_REVERSE);
    +
    + state_putentity(oe,params->state_out);
    +
    + free_out_entity(&oe);
    + }
    +
    + } else if ( ts_init == params->current_token->tag_state &&
    + tf_numeric_entity == params->current_token->token_class) { +
    + if (params->current_token->sbuffer &&
    + text_visible) {
    + struct out_entity * oe =
    + new_out_entity(params->current_token->sbuffer,
    + NULL,
    + params->current_token->
    + numeric_reference,
    + pg_REVERSE);
    +
    + state_putentity(oe,params->state_out);
    +
    + free_out_entity(&oe);
    + }
    +
    + } else
    + break;
    +
    + if (params->current_token->error)
    + params->error = 1;
    +
    + if (params->current_token->have_nl && text_visible) {
    +
    + state_putc('\n',params->state_out);
    +
    + /* Re-set settings after newline */
    + set_out_state_line_mode(params->state_out,
    + inherit_pg_flags,
    + inherit,0 );
    +
    + }
    +
    +
    + current_token_len =
    + get_new_tagfilter_token(params->current_token,
    + params->tagfilter,
    + params->state_in);
    + }
    +
    + DPRINT(Debug,20,(&Debug,
    + "tagfilter_handle_body: END current token len = %d, class = %d %s\n",
    + current_token_len,params->current_token->token_class,
    + token_class_string(params->current_token->token_class))); + if (params->current_token->sbuffer) {
    + DEBUG_PRINT_STRING(Debug,20,
    + "tagfilter_handle_body: current token = ",
    + "tagfilter_handle_body: current token > ",
    + params->current_token->sbuffer);
    + }
    +
    +
    + return current_token_len;
    + }
    +
    + /* Returns current_token_len -- */
    +
    + static int tagfilter_handle_tag P_((struct tagfilter_params *params,
    + int current_token_len));
    + static int tagfilter_handle_tag(params,current_token_len)
    + struct tagfilter_params * params;
    + int current_token_len;
    + {
    + int tag_ok = 0;
    +
    + int tag_end_seen = 0;
    + int is_start_tag = 0;
    + int is_end_tag = 0;
    + int force_eoln = 0;
    +
    + struct string * collected_tag = NULL;
    + enum collect_truncated truncated_tag = collect_full_tag;
    +
    + struct pager_range * tag_range = NULL;
    + int tag_pg_flags = 0;
    +
    + struct string * tag_name = NULL;
    + struct tagfilter_tag_state * tag_state = NULL;
    + size_t stack_pos = 0;
    +
    + struct tagfilter_atr_state * attribute_state = NULL;
    +
    + if (TAGFILTER_PARAMS_magic != params->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_handle_tag",
    + "Bad magic number");
    +
    + stack_pos = params->stack_len; /* Not on stack */
    +
    + if (TAGFILTER_SELECTION_magic != params->tagfilter->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_handle_tag",
    + "Bad magic number (tagfilter_selection)");
    +
    + if (TAGFILTER_TOKEN_magic != params->current_token->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_handle_tag",
    + "Bad magic number (tagfilter_token)");
    +
    + DPRINT(Debug,20,(&Debug,
    + "tagfilter_handle_tag: START current token len = %d, class = %d %s\n",
    + current_token_len,params->current_token->token_class,
    + token_class_string(params->current_token->token_class))); + if (params->current_token->sbuffer) {
    + DEBUG_PRINT_STRING(Debug,20,
    + "tagfilter_handle_tag: current token = ",
    + "tagfilter_handle_tag: current token > ",
    + params->current_token->sbuffer);
    + }
    +
    + switch (params->current_token->token_class) {
    + case tf_start_tag:
    + is_start_tag = 1;
    +
    + if (0) {
    + case tf_whole_tag:
    + tag_end_seen = 1;
    + is_start_tag = 1;
    + }
    +
    + if (0) {
    + case tf_selfclosed_tag:
    + tag_end_seen = 1;
    + is_start_tag = 1;
    + is_end_tag = 1;
    + }
    +
    + if (0) {
    + case tf_start_endtag:
    + is_end_tag = 1;
    + }
    +
    + if (0) {
    + case tf_whole_endtag:
    + tag_end_seen = 1;
    + is_end_tag = 1;
    + }
    +
    + if (params->current_token->tag_name) {
    + tag_name = dup_string(params->current_token->tag_name);
    +
    +
    + if (! tag_end_seen) {
    + /* Printed on error */
    + tagfilter_collect_token(params,&collected_tag,&truncated_tag); +
    + current_token_len =
    + get_new_tagfilter_token(params->current_token,
    + params->tagfilter,
    + params->state_in);
    + }
    +
    + break;
    + }
    +
    + /* FALLTHRU */
    + default:
    + tag_pg_flags = tagfilter_inherited_pg_flags(params);
    + tag_range = tagfilter_inherited_pager_range(params);
    +
    + goto fail_tag;
    + }
    +
    + if (is_start_tag) {
    + struct tagfilter_stack_item * new_item = NULL;
    + struct tagfilter_tags * search_tags =
    + params->tagfilter->top_tags;
    + int reset_range = 0;
    +
    + if (params->stack && params->stack_len > 0) {
    + size_t idx = params->stack_len-1;
    +
    + while (idx > 0 && ! params->stack[idx])
    + idx--;
    +
    + if (params->stack[idx]) {
    +
    + if (TAGFILTER_STACK_ITEM_magic != params->stack[idx]->magic)
    + mime_panic(__FILE__,__LINE__,"tagfilter_handle_tag",
    + "Bad magic number ( tagfilter_stack_item)");
    +
    + search_tags = params->stack[idx]->nested_tags;
    + }
    + }
    +
    + stack_pos = params->stack_len;
    +
    + tag_state =
    + params->tagfilter->
    + give_stack_item(&new_item,search_tags,
    + tag_name,
    + params->stack,params->stack_len,
    + &stack_pos, /* should be params->stack_len */
    + params->body,
    + params->state_in,
    + params->state_out,
    + params->decode_opt,
    + params->text_charset,
    + params->tagfilter,
    + params->counter);
    +
    + if (tag_state) {
    +
    + /* Potentially this replaces stack_pos with
    + new tag
    + */
    +
    + if (stack_pos < params->stack_len) {
    + size_t i;
    +
    + /* Handle case where need close tags from stack */
    +
    + for (i = params->stack_len -1; i >= stack_pos; i--) {
    +
    + if (params->stack[i]) {
    +
    + if (params->tagfilter->
    + close_stack_item(tag_state,

    [continued in next message]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)