From:  Kari Hurtta <hurtta@kasvihuone.keh.iki.fi.invalid>
Date:  03 Jan 2024 19:53:51 Hong Kong Time
Newsgroup:  news.alt119.net/comp.mail.elm
Subject:  

Patch: Elm ME+ 2.5 PLalpha62 -> Elm ME+ 2.5 PLalpha63 [7/7]

NNTP-Posting-Host:  null

Archive-name: elmME+2.5/PLalpha63.7

Before applying this patch catenate parts 1 - 7 first.
Also it should be possible to apply parts 1 - 7
individually.

Part 0 does not include patch.

This patch is agaist Elm ME+ 2.5 PLalpha62

====================================== ( part 7/7 ) =========
Index: elmME+.2.5.alpha63-cvs/src/menu_common/message_limit.c
*** elmME+.2.5.alpha62/src/menu_common/message_limit.c	Wed Jun 16 20:17:54 2021
--- elmME+.2.5.alpha63-cvs/src/menu_common/message_limit.c	Wed Dec 13 18:55:32 2023
***************
*** 1,7 ****
! static char rcsid[] = "@(#)$Id: message_limit.c,v 2.7 2021/05/24 16:26:44 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.7 $   $State: Exp $
   *
   *  Author: Kari Hurtta  (was hurtta+elm@posti.FMI.FI)
   *      or  Kari Hurtta 
--- 1,7 ----
! static char rcsid[] = "@(#)$Id: message_limit.c,v 2.8 2023/12/13 16:55:32 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.8 $   $State: Exp $
   *
   *  Author: Kari Hurtta  (was hurtta+elm@posti.FMI.FI)
   *      or  Kari Hurtta 
***************
*** 279,285 ****
      
      vector = safe_calloc(n, sizeof(vector[0]));
  
!     if (string_matches_ascii(str, s2us("thread"),0)) {
  	int current = get_current(mbxview);
  	struct header_rec * hdr;
  	
--- 279,285 ----
      
      vector = safe_calloc(n, sizeof(vector[0]));
  
!     if (string_matches_ascii(str, s2us("thread"),0,SMA_op_normal)) {
  	int current = get_current(mbxview);
  	struct header_rec * hdr;
  	
***************
*** 300,306 ****
  	ret = limit_by_string_subject(temp,vector,mbxview);
  	free_string(&temp);
  
!     } else if (string_matches_ascii(str, s2us("dsn"),0)) {
  
  	ret = limit_to_dsn(vector,mbxview);
  
--- 300,306 ----
  	ret = limit_by_string_subject(temp,vector,mbxview);
  	free_string(&temp);
  
!     } else if (string_matches_ascii(str, s2us("dsn"),0,SMA_op_normal)) {
  
  	ret = limit_to_dsn(vector,mbxview);
  
***************
*** 329,356 ****
  
  	    ret = limit_by_header(first, rest, vector,  mbxview, page);
  
! 	} else if (string_matches_ascii(first,s2us("subject"),0)) {
  
  	    rest = clip_from_string(str,&pos,L);
  
  	    ret = limit_selection(SUBJECT, rest, vector, mbxview);
  
! 	} else if (string_matches_ascii(first, s2us("to"),0)) {
  	    rest = clip_from_string(str,&pos,L);
  
  	    ret = limit_selection(TO, rest, vector, mbxview);
  
! 	} else if (string_matches_ascii(first, s2us("cc"),0)) {
  	    rest = clip_from_string(str,&pos,L);
  		    
  	    ret = limit_selection(CC, rest, vector, mbxview);
  	    
! 	} else if (string_matches_ascii(first, s2us("from"),0)) {
  	    rest = clip_from_string(str,&pos,L);
  
  	    ret = limit_selection(FROM, rest, vector, mbxview);
  
! 	} else if (string_matches_ascii(first, s2us("header"),0)) {
  	    struct string *header  = NULL;
  	    uint16 delim;
  
--- 329,356 ----
  
  	    ret = limit_by_header(first, rest, vector,  mbxview, page);
  
! 	} else if (string_matches_ascii(first,s2us("subject"),0,SMA_op_normal)) {
  
  	    rest = clip_from_string(str,&pos,L);
  
  	    ret = limit_selection(SUBJECT, rest, vector, mbxview);
  
! 	} else if (string_matches_ascii(first, s2us("to"),0,SMA_op_normal)) {
  	    rest = clip_from_string(str,&pos,L);
  
  	    ret = limit_selection(TO, rest, vector, mbxview);
  
! 	} else if (string_matches_ascii(first, s2us("cc"),0,SMA_op_normal)) {
  	    rest = clip_from_string(str,&pos,L);
  		    
  	    ret = limit_selection(CC, rest, vector, mbxview);
  	    
! 	} else if (string_matches_ascii(first, s2us("from"),0,SMA_op_normal)) {
  	    rest = clip_from_string(str,&pos,L);
  
  	    ret = limit_selection(FROM, rest, vector, mbxview);
  
! 	} else if (string_matches_ascii(first, s2us("header"),0,SMA_op_normal)) {
  	    struct string *header  = NULL;
  	    uint16 delim;
  
Index: elmME+.2.5.alpha63-cvs/src/metapager.c
*** elmME+.2.5.alpha62/src/metapager.c	Sat Aug 28 14:11:45 2021
--- elmME+.2.5.alpha63-cvs/src/metapager.c	Wed Dec 13 18:55:32 2023
***************
*** 1,7 ****
! static char rcsid[] = "@(#)$Id: metapager.c,v 2.37 2021/07/07 16:28:00 hurtta Exp $";
  
! /*****************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.37 $   $State: Exp $
   *
   *  Modified by: Kari Hurtta 
   *                       (was hurtta+elm@posti.FMI.FI, 
--- 1,7 ----
! static char rcsid[] = "@(#)$Id: metapager.c,v 2.38 2023/12/13 16:55:32 hurtta Exp $";
  
! /*******************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.38 $   $State: Exp $
   *
   *  Modified by: Kari Hurtta 
   *                       (was hurtta+elm@posti.FMI.FI, 
***************
*** 9,15 ****
   *           or  Kari Hurtta 
   *
   *  Initially written by: Michael Elkins , 1995
!  ****************************************************************************/
  
  #include "def_elm.h"
  #include "s_elm.h"
--- 9,15 ----
   *           or  Kari Hurtta 
   *
   *  Initially written by: Michael Elkins , 1995
!  ******************************************************************/
  
  #include "def_elm.h"
  #include "s_elm.h"
Index: elmME+.2.5.alpha63-cvs/src/opt_generic.c
*** elmME+.2.5.alpha62/src/opt_generic.c	Sat Aug 28 14:11:45 2021
--- elmME+.2.5.alpha63-cvs/src/opt_generic.c	Wed Dec 13 18:55:32 2023
***************
*** 1,7 ****
! static char rcsid[] = "@(#)$Id: opt_generic.c,v 2.18 2021/07/07 16:28:00 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.18 $   $State: Exp $
   *
   *  Most of code moved from src/options.c
   *
--- 1,7 ----
! static char rcsid[] = "@(#)$Id: opt_generic.c,v 2.19 2023/12/13 16:55:32 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.19 $   $State: Exp $
   *
   *  Most of code moved from src/options.c
   *
***************
*** 623,629 ****
  	    return 0;
  	}
  
! 	if (!s || !string_matches_ascii(buffer,s2us(s),0)) {
  	    
  	    if (save_info[x].dt_type->parse_line(& save_info[x],
  						 1 /* local */ ,buffer,
--- 623,629 ----
  	    return 0;
  	}
  
! 	if (!s || !string_matches_ascii(buffer,s2us(s),0,SMA_op_normal)) {
  	    
  	    if (save_info[x].dt_type->parse_line(& save_info[x],
  						 1 /* local */ ,buffer,
Index: elmME+.2.5.alpha63-cvs/src/pager/helper.c
*** elmME+.2.5.alpha62/src/pager/helper.c	Wed Sep 28 21:29:37 2016
--- elmME+.2.5.alpha63-cvs/src/pager/helper.c	Wed Dec 13 18:55:32 2023
***************
*** 1,7 ****
! static char rcsid[] = "@(#)$Id: helper.c,v 1.5 2016/09/28 18:29:37 hurtta Exp $";
  
  /************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.5 $   $State: Exp $
   *
   *  Author: Kari Hurtta 
   *      or  Kari Hurtta 
--- 1,7 ----
! static char rcsid[] = "@(#)$Id: helper.c,v 1.6 2023/12/13 16:55:32 hurtta Exp $";
  
  /************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.6 $   $State: Exp $
   *
   *  Author: Kari Hurtta 
   *      or  Kari Hurtta 
***************
*** 32,38 ****
  						   pager_buffer,helper_data_sp,
  						   wrap_info,current_line,
  						   current_pager_range,
! 						   helper_data_pg)
       struct menu_context      * ctx;
       helper_get_line_f        * get_line;
       union pager_help_param     pager_buffer;
--- 32,39 ----
  						   pager_buffer,helper_data_sp,
  						   wrap_info,current_line,
  						   current_pager_range,
! 						   helper_data_pg,current_alt_data,
! 						   get_range_param)
       struct menu_context      * ctx;
       helper_get_line_f        * get_line;
       union pager_help_param     pager_buffer;
***************
*** 41,56 ****
       struct string           ** current_line;
       struct pager_range      ** current_pager_range;
       struct pager_helper_data * helper_data_pg;
  {
      enum pager_helper_status ret = phelper_failure;
! 
!     enum span_result span_line_result;
      int was_start_of_line;
      int buffer_len = 0;
  
!     struct string           * L_buffer      = *current_line;  
      struct pager_range      * L_pager_range = *current_pager_range;
  
      if (SPAN_HELPER_DATA_magic != helper_data_sp->magic)
  	panic("PAGER PANIC",__FILE__,__LINE__,
  	      "pager_helper_process_line",
--- 42,64 ----
       struct string           ** current_line;
       struct pager_range      ** current_pager_range;
       struct pager_helper_data * helper_data_pg;
+      struct string_alt       ** current_alt_data;   /* NULL if not supported */
+      helper_get_param_f       * get_range_param;
  {
      enum pager_helper_status ret = phelper_failure;
!     enum span_result span_line_result = span_failure;
!     
      int was_start_of_line;
      int buffer_len = 0;
  
!     struct string           * L_buffer      = *current_line;
!     struct string_alt       * L_alt_data    = NULL;
      struct pager_range      * L_pager_range = *current_pager_range;
+     enum pager_range_opcode opcode = pr_opcode_none;
  
+     if (current_alt_data)
+ 	L_alt_data = * current_alt_data;
+     
      if (SPAN_HELPER_DATA_magic != helper_data_sp->magic)
  	panic("PAGER PANIC",__FILE__,__LINE__,
  	      "pager_helper_process_line",
***************
*** 67,80 ****
  		    helper_data_sp->virtual_line,
  		    helper_data_sp->buffer_x,
  		    helper_data_sp->start_of_line));
  
      if (PAGER_HELPER_DATA_magic != helper_data_pg->magic)
  	panic("PAGER PANIC",__FILE__,__LINE__,
  	      "pager_helper_process_line",
  	      "Bad magic number (pager_helper_data)",0);
      
!     if (!L_buffer || 
! 	helper_data_sp->buffer_x >= (buffer_len = string_len(L_buffer))) {
  
  	enum range_changed range_changed = rc_same_range;
  	/* caller of get_line_from_stringbuffer is expected to 
--- 75,91 ----
  		    helper_data_sp->virtual_line,
  		    helper_data_sp->buffer_x,
  		    helper_data_sp->start_of_line));
+     DPRINT(Debug,10,(&Debug, 
+ 		     "pager_helper_process_line: cur_line=%d, cur_col=%d\n",
+ 		     helper_data_sp->cur_line,helper_data_sp->cur_col));
  
      if (PAGER_HELPER_DATA_magic != helper_data_pg->magic)
  	panic("PAGER PANIC",__FILE__,__LINE__,
  	      "pager_helper_process_line",
  	      "Bad magic number (pager_helper_data)",0);
      
!     if ((!L_buffer && !L_alt_data) || 
! 	(L_buffer && helper_data_sp->buffer_x >= (buffer_len = string_len(L_buffer)))) {
  
  	enum range_changed range_changed = rc_same_range;
  	/* caller of get_line_from_stringbuffer is expected to 
***************
*** 92,98 ****
--- 103,112 ----
  
  	    }
  	    free_string (&L_buffer);
+ 	    if (L_alt_data)
+ 		free_string_alt(& L_alt_data);
  	}
+ 		
  	helper_data_sp->buffer_x = 0;
  
  	/* There is no pending data to output, so we need to grab 
***************
*** 100,115 ****
  	 */
  
  	if (helper_data_sp->lineext) {
- 	    L_buffer = get_lineext_and_walk(&(helper_data_sp->lineext),
- 					    &(helper_data_pg->pg_flags),
- 					    &range_changed,
- 					    &L_pager_range);   
- 	    
- 	    buffer_len = string_len(L_buffer);
  
! 	    DPRINT(Debug,9,(&Debug, "pager_helper_process_line: new line extension on line %d -- len = %d\n",
! 			    helper_data_sp->idx,
! 			    buffer_len));
  	} else {
  
  	    L_buffer = get_line(pager_buffer,
--- 114,174 ----
  	 */
  
  	if (helper_data_sp->lineext) {
  
! 	    if (current_alt_data) {
! 		L_alt_data = get_lineext_alt_and_walk(&(helper_data_sp->lineext),
! 						      &(helper_data_pg->pg_flags),
! 						      &range_changed,
! 						      &L_pager_range);
! 
! 		buffer_len = -1;
! 
! 		if (L_alt_data) {
! 		    enum string_alt_type alt_data_type = string_alt_none;
! 		    const union string_alt_value alt_data_value
! 			= get_string_alt_value(L_alt_data,&alt_data_type);
! 
! 		    switch (alt_data_type) {
! 		    case string_alt_none:
! 			DPRINT(Debug,9,(&Debug, "pager_helper_process_line: new line extension on line %d (alt data) -- no data\n"));
! 
! 			break;
! 		    case string_alt_text:
! 			L_buffer = dup_string(alt_data_value.text);
! 			buffer_len = string_len(L_buffer);
! 
! 			DPRINT(Debug,9,(&Debug,
! 					"pager_helper_process_line: new line extension on line %d (alt data) -- len = %d\n",
! 					helper_data_sp->idx,
! 					buffer_len));
! 						
! 			break;
! 		    case string_alt_entity:
! 			DPRINT(Debug,9,(&Debug,
! 					"pager_helper_process_line: new line extension on line %d (alt data) -- entity\n"));
! 
! 			break;
! 		    }
! 
! 
! 		} else {
! 		    ret = phelper_EOD;  /* End of data */
! 		    goto out;
! 		}
! 		
! 	    } else {
! 		L_buffer = get_lineext_and_walk(&(helper_data_sp->lineext),
! 						&(helper_data_pg->pg_flags),
! 						&range_changed,
! 						&L_pager_range);   
! 		
! 		buffer_len = string_len(L_buffer);
! 		
! 		DPRINT(Debug,9,(&Debug,
! 				"pager_helper_process_line: new line extension on line %d -- len = %d\n",
! 				helper_data_sp->idx,
! 				buffer_len));		
! 	    }
  	} else {
  
  	    L_buffer = get_line(pager_buffer,
***************
*** 133,138 ****
--- 192,225 ----
  			    buffer_len));
  	}	
  
+ 	if (L_buffer) {
+ 	    DEBUG_PRINT_STRING(Debug,12,
+ 			       "pager_helper_process_line: buffer = ",
+ 			       "                         : buffer > ",
+ 			       L_buffer);
+ 	}
+ 
+ 	if (helper_data_sp->lineext) {
+ 	    DPRINT(Debug,12,(&Debug, 
+ 			     "pager_helper_process_line: have line extension\n"));
+ 	}
+ 	
+ 	if (range_changed != rc_same_range || helper_data_sp->start_of_line) {
+ 	    DPRINT(Debug,9,(&Debug, 
+ 			    "pager_helper_process_line: range_changed=%d",
+ 			    range_changed));
+ 	    switch (range_changed) {
+ 	    case rc_same_range: DPRINT(Debug,9,(&Debug, " rc_same_range")); break;
+ 	    case rc_newline:    DPRINT(Debug,9,(&Debug, " rc_newline"));   break;
+ 	    case rc_same_line:  DPRINT(Debug,9,(&Debug, " rc_same_line")); break;
+ 	    }
+ 
+ 	    if (helper_data_sp->start_of_line) {
+ 		DPRINT(Debug,9,(&Debug, ", already on start of line"));
+ 	    }
+ 	    DPRINT(Debug,9,(&Debug, "\n"));		
+ 	}
+ 	
  	if (!(helper_data_sp->start_of_line)) {
  	    switch (range_changed) {
  	    case rc_same_range: break;
***************
*** 153,169 ****
  	    }
  	}
      }
      
!     if (helper_data_pg->search_matches >= 0 &&
! 	helper_data_pg->search_matches == helper_data_sp->idx)
! 	helper_data_sp->this_flags = pg_STANDOUT;
!     else
! 	helper_data_sp->this_flags = helper_data_pg->pg_flags;
!   
!     span_line_result = span_helper(ctx,L_pager_range,wrap_info,L_buffer,
! 				   helper_data_sp);
  
      switch (span_line_result) {
      case span_failure:
  	
  	if (!was_start_of_line) {
--- 240,377 ----
  	    }
  	}
      }
+ 
+     if (L_pager_range) {
+ 	opcode = get_pager_range_opcode(L_pager_range);
+ 	
+ 	DPRINT(Debug,9,(&Debug, 
+ 			"pager_helper_process_line: opcode=%d",
+ 			opcode));
+ 	switch (opcode) {
+ 	case pr_opcode_none:           DPRINT(Debug,9,(&Debug," pr_opcode_none"));          break;
+ 	case pr_opcode_pager_replace:  DPRINT(Debug,9,(&Debug," pr_opcode_pager_replace")); break;
+ 	}
+ 	DPRINT(Debug,9,(&Debug, "\n"));
+     }
      
!     switch (opcode) {
!     case pr_opcode_pager_replace:
! 
! 	if (0 == helper_data_sp->buffer_x) {
! 	    
! 	    if (L_pager_range) {
! 		int next_param_pos = 0;
! 		int found_param_pos = -1;
! 		struct pager_param_value * builtin_param =
! 		    get_range_param(pager_buffer,L_pager_range,
! 				    pp_opcode_builtin,
! 				    &next_param_pos,
! 				    &found_param_pos);
! 		
! 		if (builtin_param) {
! 		    int replaced_text = 0;
! 		    
! 		    enum pager_param_type param_type = pp_type_none;
! 		    const union pager_param_uvalue uvalue =
! 			get_pager_param_uvalue(builtin_param,
! 					       ¶m_type);
! 		    
! 		    switch (param_type) {
! 		    case pp_type_none:     break;
! 			
! 		    case pp_type_text:
! 			if (L_buffer)
! 			    free_string(& L_buffer);
! 
! 			L_buffer = dup_string(uvalue.text);
! 			buffer_len = string_len(L_buffer);
! 			replaced_text = 1;
! 
! 			break;
! 		    }
! 		    		    
! 		    free_pager_param_value(&builtin_param);
! 		    if (replaced_text) {
! 			DPRINT(Debug,9,(&Debug, 
! 					"pager_helper_process_line: Changed text\n"));
! 			
! 			goto proceed_text;
! 
! 		    }
! 		}
! 	    }
! 	    
! 	    helper_data_sp->buffer_x = buffer_len;
! 	    ret = phelper_done;
! 	    	    
! 	    /* Now hiding */
! 	
! 	    DPRINT(Debug,9,(&Debug, 
! 			    "pager_helper_process_line: Hiding line\n"));
! 	    
! 	    goto out;
! 	}
! 
! 	
! 	
! 	/* FALLTHRU */
! 
!     proceed_text:
!     case pr_opcode_none:
!     
! 	if (helper_data_pg->search_matches >= 0 &&
! 	    helper_data_pg->search_matches == helper_data_sp->idx)
! 	    helper_data_sp->this_flags = pg_STANDOUT;
! 	else
! 	    helper_data_sp->this_flags = helper_data_pg->pg_flags;
! 
! 
! 	if (L_buffer) { 	
! 	    span_line_result = span_helper(ctx,L_pager_range,wrap_info,L_buffer,
! 					   helper_data_sp);
! 	} else if (L_alt_data) {
! 
! 	    span_line_result = span_alt_data_helper(ctx,L_pager_range,wrap_info,
! 						    L_alt_data,
! 						    &L_buffer,
! 						    &(helper_data_pg->pg_flags),
! 						    helper_data_sp);
! 
! 	    if (L_buffer)
! 		buffer_len = string_len(L_buffer);	    
! 	}
  
+ 	break;    
+     }
+ 
+     DPRINT(Debug,9,(&Debug, 
+ 		    "pager_helper_process_line: span_line_result=%d ",
+ 		    span_line_result));
+     
      switch (span_line_result) {
+     case span_clear_alt_data:
+ 
+ 	if (L_alt_data) {
+ 	    DPRINT(Debug,9,(&Debug, "clearing alt data\n"));
+ 	    
+ 	    free_string_alt(& L_alt_data);
+ 
+ 	    if (!L_buffer &&  !helper_data_sp->lineext) {
+ 		DPRINT(Debug,9,(&Debug, 
+ 				"pager_helper_process_line: end of line %d\n",
+ 				helper_data_sp->idx));
+ 
+ 		helper_data_sp->idx++;
+ 		helper_data_sp->buffer_x = 0;
+ 	    }
+ 	    
+ 	    break;
+ 	}
+ 	DPRINT(Debug,9,(&Debug, 
+ 			"no alt data (clearing alt data) - "));
+ 
+ 	/* PASSTHRU */
+ 	
      case span_failure:
  	
  	if (!was_start_of_line) {
***************
*** 256,261 ****
--- 464,475 ----
      *current_line        = L_buffer;
      *current_pager_range = L_pager_range;
  
+     if ( current_alt_data)
+ 	* current_alt_data = L_alt_data;
+     else if (L_alt_data)
+ 	free_string_alt(& L_alt_data);
+     
+ 
      DPRINT(Debug,10,(&Debug, 
  		     "pager_helper_process_line=%d",ret));
      switch(ret) {
Index: elmME+.2.5.alpha63-cvs/src/pager/span_range.c
*** elmME+.2.5.alpha62/src/pager/span_range.c	Sat Oct 26 12:43:18 2019
--- elmME+.2.5.alpha63-cvs/src/pager/span_range.c	Wed Dec 13 18:55:32 2023
***************
*** 1,7 ****
! static char rcsid[] = "@(#)$Id: span_range.c,v 1.10 2019/10/26 09:43:18 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.10 $   $State: Exp $
   *
   *  Author: Kari Hurtta 
   *      or  Kari Hurtta 
--- 1,7 ----
! static char rcsid[] = "@(#)$Id: span_range.c,v 1.11 2023/12/13 16:55:32 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 1.11 $   $State: Exp $
   *
   *  Author: Kari Hurtta 
   *      or  Kari Hurtta 
***************
*** 57,63 ****
  		     "span_range_prefix: range_flags = %d, quote_level = %d, indent = %d\n",
  		     range_flags,quote_level,indent));
  
!     if (0 != (range_flags & PR_REPLY_QUOTE))                     /* Should not happen */
  	quote_level++;
  
      if (quote_level && quote_prefix) {
--- 57,63 ----
  		     "span_range_prefix: range_flags = %d, quote_level = %d, indent = %d\n",
  		     range_flags,quote_level,indent));
  
!     if (ison(range_flags,PR_REPLY_QUOTE))                     /* Should not happen */
  	quote_level++;
  
      if (quote_level && quote_prefix) {
***************
*** 84,90 ****
  	if (len > 0)
  	    first_char = give_unicode_from_string(quote_prefix,0);
  
! 	if (0 != (range_flags & PR_QUOTE_L)) {                  /* Should not happen */
  	    int need_quote = 0x005B /* [ */ == first_char;
  	    
  	    DPRINT(Debug,12,(&Debug,
--- 84,90 ----
  	if (len > 0)
  	    first_char = give_unicode_from_string(quote_prefix,0);
  
! 	if (ison(range_flags,PR_QUOTE_L)) {                  /* Should not happen */
  	    int need_quote = 0x005B /* [ */ == first_char;
  	    
  	    DPRINT(Debug,12,(&Debug,
***************
*** 152,158 ****
      failure:
  	;
  
!     } else if (0 != (range_flags & PR_QUOTE_L)) {            /* Should not happen */
  	int need_quote = 0x005B /* [ */ == first_char;
  	
  	DPRINT(Debug,12,(&Debug,
--- 152,158 ----
      failure:
  	;
  
!     } else if (ison(range_flags,PR_QUOTE_L)) {            /* Should not happen */
  	int need_quote = 0x005B /* [ */ == first_char;
  	
  	DPRINT(Debug,12,(&Debug,
***************
*** 225,231 ****
  		     "span_range_middle: range_flags = %d, quote_level = %d, indent = %d\n",
  		     range_flags,quote_level,indent));
  
!         while (CUR_col < COLUMNS - COLUMNS/3 && 
  	   CUR_col < indent) {	
  	menu_WriteUnicode(ctx,0x0020 /* SPACE */ );
  	CUR_col++;       
--- 225,231 ----
  		     "span_range_middle: range_flags = %d, quote_level = %d, indent = %d\n",
  		     range_flags,quote_level,indent));
  
!     while (CUR_col < COLUMNS - COLUMNS/3 && 
  	   CUR_col < indent) {	
  	menu_WriteUnicode(ctx,0x0020 /* SPACE */ );
  	CUR_col++;       
***************
*** 248,313 ****
      0,0,0,NULL,0,0,0,0,0,0,0,0,0,0,0
  };
  
! enum span_result span_helper (ctx,pager_range,info,buffer,data)
       struct menu_context * ctx;
!      struct pager_range  * pager_range;
!      struct pg_wrap_info * info;
!      struct string       * buffer;
       struct span_helper_data * data;
  {
-     enum span_result span_line_result;
- 
      int L_mayclear      = 0;
- 
-     int buffer_len      = string_len(buffer);
-     int LINES, COLUMNS;
      int WP;
  
      if (SPAN_HELPER_DATA_magic != data->magic)
  	panic("PAGER PANIC",__FILE__,__LINE__,
! 	      "span_helper",
  	      "Bad magic number",0);
  
      L_mayclear          = data->mayclear;
      WP  =  /* pager_indicate_wrapping */ data->wrap_indicator;
! 
!     menu_get_sizes(ctx, &LINES, &COLUMNS);
! 
      if (pager_range) {
  	data->range_flags = get_pager_range_flags(pager_range);
  	
  	DPRINT(Debug,9,(&Debug, 
! 			"span_helper: pager range: quote_level=%d range_flags=%d\n",
  			get_pager_range_quote_level(pager_range),
  			data->range_flags));
      }
  
      if (data->start_of_line) {
  	DPRINT(Debug,10,(&Debug, 
! 			 "span_helper: virtual_line=%d, start of line\n",
  			 data->virtual_line));
  	
  	record_pg_wrap_info(info,&(data->virtual_line),data->idx,
  			    data->buffer_x,data->lineext);
      }
  
      if (data->start_of_line && pager_range) {
- 	uint16 ch = 0;   /* First character may be needed */
  	
! 	if (buffer_len > 0)
! 	    ch = give_unicode_from_string(buffer,0);
  	
! 	span_line_result = span_range_prefix(ctx,
! 					     data->cur_line,&(data->cur_col),
! 					     ch,pager_range,
! 					     &(data->this_flags),
! 					     &L_mayclear,
! 					     WP
! 					     );
  	
  	DPRINT(Debug,9,(&Debug, 
! 			"span_helper: span_range_prefix result = %d, ",
! 			span_line_result));
  	
  	data->start_of_line = 0;
  	data->p_start_COL   = data->cur_col;
--- 248,321 ----
      0,0,0,NULL,0,0,0,0,0,0,0,0,0,0,0
  };
  
! static enum spanh_prefix_res {
!     spanh_exit = 0,
!     spanh_main,
! } span_helper_prefix P_(( struct menu_context * ctx,
! 			  struct pager_range      * pager_range,
! 			  struct pg_wrap_info     * info,
! 			  struct span_helper_data * data,
! 			  uint16                    ch,
! 			  enum span_result        * span_line_result_p
! 			  ));
! 
! enum spanh_prefix_res span_helper_prefix(ctx,pager_range,info,data,ch,
! 					 span_line_result_p)
       struct menu_context * ctx;
!      struct pager_range      * pager_range;
!      struct pg_wrap_info     * info;
       struct span_helper_data * data;
+      uint16                    ch;
+      enum span_result        * span_line_result_p;
  {
      int L_mayclear      = 0;
      int WP;
  
+     enum spanh_prefix_res res = spanh_exit;
+ 
      if (SPAN_HELPER_DATA_magic != data->magic)
  	panic("PAGER PANIC",__FILE__,__LINE__,
! 	      "span_helper_prefix",
  	      "Bad magic number",0);
  
      L_mayclear          = data->mayclear;
      WP  =  /* pager_indicate_wrapping */ data->wrap_indicator;
!     
      if (pager_range) {
  	data->range_flags = get_pager_range_flags(pager_range);
  	
  	DPRINT(Debug,9,(&Debug, 
! 			"span_helper_prefix: pager range: quote_level=%d range_flags=%d\n",
  			get_pager_range_quote_level(pager_range),
  			data->range_flags));
      }
  
      if (data->start_of_line) {
  	DPRINT(Debug,10,(&Debug, 
! 			 "span_helper_prefix: virtual_line=%d, start of line\n",
  			 data->virtual_line));
  	
  	record_pg_wrap_info(info,&(data->virtual_line),data->idx,
  			    data->buffer_x,data->lineext);
      }
  
+     
      if (data->start_of_line && pager_range) {
  	
! 	/* 1) Writes quote prefix */
  	
! 	* span_line_result_p =
! 	    span_range_prefix(ctx,
! 			      data->cur_line,&(data->cur_col),
! 			      ch,pager_range,
! 			      &(data->this_flags),
! 			      &L_mayclear,
! 			      WP
! 			      );
  	
  	DPRINT(Debug,9,(&Debug, 
! 			"span_helper_prefix: span_range_prefix result = %d, ",
! 			* span_line_result_p));
  	
  	data->start_of_line = 0;
  	data->p_start_COL   = data->cur_col;
***************
*** 317,356 ****
  	    data->start_of_range = 0;
  	}
  
! 	if (data->buffer_x >= buffer_len) {
! 	    DPRINT(Debug,9,(&Debug, 
! 			    "no buffer left (buffer_x=%d buffer_len=%d), ",
! 			    data->buffer_x,buffer_len));
! 	    goto buffer_handled;
! 	}
  	
      } else if (data->start_of_range && pager_range) {
  
! 	uint16 ch = 0;   /* First character may be needed */
  	
! 	if (buffer_len > 0)
! 	    ch = give_unicode_from_string(buffer,0);
! 
! 	span_line_result = span_range_middle(ctx,
! 					     data->cur_line,&(data->cur_col),
! 					     ch,pager_range,
! 					     &(data->this_flags),
! 					     &L_mayclear);
  	
  	DPRINT(Debug,9,(&Debug, 
! 			"span_helper: span_range_middle result = %d, ",
! 			span_line_result));
  
  	data->start_of_range = 0;
  	
  	if (data->buffer_x >= buffer_len) {
  	    DPRINT(Debug,9,(&Debug, 
  			    "no buffer left (buffer_x=%d buffer_len=%d), ",
  			    data->buffer_x,buffer_len));
  	    goto buffer_handled;
  	}
  
!     } else {
  	if (data->start_of_line) {
  	    DPRINT(Debug,10,(&Debug, 
  			     "span_helper: No pager range on beginning of line\n"));
--- 325,659 ----
  	    data->start_of_range = 0;
  	}
  
! 	res = spanh_exit;
  	
      } else if (data->start_of_range && pager_range) {
  
! 	/* 2) Writes indentation */
  	
! 	* span_line_result_p =
! 	    span_range_middle(ctx,
! 			      data->cur_line,&(data->cur_col),
! 			      ch,pager_range,
! 			      &(data->this_flags),
! 			      &L_mayclear);
  	
  	DPRINT(Debug,9,(&Debug, 
! 			"span_helper_prefix: span_range_middle result = %d, ",
! 			* span_line_result_p));
  
  	data->start_of_range = 0;
+ 
+ 	res = spanh_exit;
+ 	
+     } else {
+ 	
+ 	res = spanh_main;
  	
+ 	DPRINT(Debug,9,(&Debug, 
+ 			"span_helper_prefix: "));
+     }
+ 
+     data->mayclear      = L_mayclear ? 1 : 0;
+ 
+     DPRINT(Debug,9,(&Debug, "return %d",res));
+     switch (res) {
+     case spanh_exit: DPRINT(Debug,9,(&Debug, " spanh_exit")); break;
+     case spanh_main: DPRINT(Debug,9,(&Debug, " spanh_main")); break;
+     }
+     DPRINT(Debug,9,(&Debug, "\n"));
+ 
+     return res;
+ }
+ 
+ enum span_result span_alt_data_helper (ctx,pager_range,info,
+ 				       alt_buffer,
+ 				       res_buffer,
+ 				       res_pg_flags,
+ 				       data)
+      struct menu_context * ctx;
+      struct pager_range  * pager_range;
+      struct pg_wrap_info * info;
+      struct string_alt   * alt_buffer;
+      struct string      ** res_buffer;
+      int                 * res_pg_flags;
+      struct span_helper_data * data;
+ {
+     enum span_result ret = span_clear_alt_data;
+     uint16 ch = 0;   /* First character may be needed */
+ 
+     enum string_alt_type alt_data_type = string_alt_none;
+     const union string_alt_value alt_data_value =
+ 	get_string_alt_value(alt_buffer,&alt_data_type);
+ 
+     int LINES, COLUMNS;
+     
+ 
+     int character_ok = 0; 
+     
+     	
+     if (SPAN_HELPER_DATA_magic != data->magic)
+ 	panic("PAGER PANIC",__FILE__,__LINE__,
+ 	      "span_alt_data_helper",
+ 	      "Bad magic number",0);
+ 
+     menu_get_sizes(ctx, &LINES, &COLUMNS);
+     
+     switch (alt_data_type) {
+     case string_alt_none:
+ 	
+ 	DPRINT(Debug,10,(&Debug, "span_alt_data_helper: empty alt data\n"));
+        	
+ 	goto out;
+ 	    
+     case string_alt_text:
+ 	    
+ 	if (*res_buffer)
+ 	    free_string(res_buffer);
+ 	*res_buffer = dup_string(alt_data_value.text);
+ 	data->buffer_x = 0;
+ 	
+ 	DPRINT(Debug,10,(&Debug,
+ 			 "span_alt_data_helper: Set string\n"));
+ 	DEBUG_PRINT_STRING(Debug,12,
+ 			   "span_alt_data_helper: buffer = ",
+ 			   "                    : buffer > ",
+ 			   *res_buffer);
+ 
+ 	goto out;
+ 	    
+     case string_alt_entity: {
+ 	int                    ref_key_pg_flags = 0;
+ 	const struct string  * ref_key =
+ 	    out_entity_reference_key(alt_data_value.entity,
+ 				     & ref_key_pg_flags);
+ 	const struct string  * text_value = 
+ 	    out_entity_text_value(alt_data_value.entity);
+ 	
+ 	struct string  * res1 = NULL;
+ 
+ 	DPRINT(Debug,11,(&Debug,
+ 			 "span_alt_data_helper: entity %S\n",
+ 			 ref_key));
+ 	
+ 	if (text_value && (res1 = curses_available_string(text_value))) {
+ 	    if (*res_buffer)
+ 		free_string(res_buffer);
+ 	    *res_buffer = res1;
+ 	    res1 = NULL;
+ 	    data->buffer_x = 0;
+ 	    
+ 	    DPRINT(Debug,10,(&Debug,
+ 			     "span_alt_data_helper: Set string\n"));
+ 
+ 	    DEBUG_PRINT_STRING(Debug,12,
+ 			       "span_alt_data_helper: buffer = ",
+ 			       "                    : buffer > ",
+ 			       *res_buffer);
+ 	    
+ 	    goto out;
+ 	    
+ 	}
+ 	
+ 	ch = out_entity_unicode_value(alt_data_value.entity);
+ 
+ 	switch (ch) {
+ 	case UNICODE_BAD_CHAR:
+ 	    character_ok = 0;
+ 	    break;
+ 	case UNICODE_SOFT_HYPHEN:   /* What to do ? */
+ 	    character_ok = 1;
+ 	    break;
+ 	    
+ 	default: {
+ 	    charset_t utf8 = MIME_name_to_charset("UTF-8",0);
+ 
+ 	    enum charset_unicode_stat x;
+ 
+ 	    DPRINT(Debug,11,(&Debug, "span_alt_data_helper: entity unicode value x%04x\n",
+ 			     ch));
+ 	    
+ 	    if (utf8 &&
+ 		(0 != (charset_properties(utf8) & CS_printable)) &
+ 		curses_available_charset(utf8)) {
+ 		x = string_type_have_unicode(utf8,ch);
+ 	    } else {
+ 		x = string_type_have_unicode(display_charset,ch);
+ 	    }
+ 
+ 	    switch (x) {
+ 	    case charset_unicode_bad:
+ 	    case charset_unicode_unknown:
+ 	    case charset_missing_unicode:
+ 		character_ok = 0;
+ 		break;
+ 	    case charset_have_unicode:
+ 		character_ok = 1;
+ 	    }
+ 	}
+ 	    break;
+ 	}
+ 
+ 	if (! character_ok) {
+ 	    int len         = string_len(ref_key);
+ 	    
+ 	    /* This should be  0x0026 '&' */
+ 	    if (len > 0)
+ 		ch = give_unicode_from_string(ref_key,0);
+ 
+ 	}
+ 		    
+     }
+ 	    break;
+     }
+ 
+     switch(span_helper_prefix(ctx,pager_range,info,data,ch,&ret)) {
+     case spanh_exit:
+ 	
+ 	break;
+ 
+     case spanh_main: {
+ 		
+ 	if (data->start_of_line) {
+ 	    DPRINT(Debug,10,(&Debug, 
+ 			     "span_alt_data_helper: No pager range on beginning of line\n"));
+ 	    
+ 	    data->start_of_line = 0;
+ 	    data->p_start_COL   = 0;
+ 	}
+ 
+ 	if (data->start_of_range) {
+ 	    DPRINT(Debug,10,(&Debug, 
+ 			     "span_alt_data_helper: start of range (range changed) without range\n"));
+ 	    
+ 	    data->start_of_range = 0;
+ 	}
+ 
+ 
+ 	if (data->joined_line) {
+ 	    DPRINT(Debug,10,(&Debug, 
+ 			     "span_alt_data_helper: this is joined line\n"));
+ 	}
+ 
+ 	
+ 	 switch (alt_data_type) {
+ 	 case string_alt_none:
+ 	 case string_alt_text:
+ 	     goto out;
+ 
+ 	 case string_alt_entity: {
+ 
+ 	     /* Not very good ---- */
+ 	     
+ 	     if ( character_ok) {
+ 		 charset_t utf8 = MIME_name_to_charset("UTF-8",0);
+ 		 		 
+ 		 if (*res_buffer)
+ 		     free_string(res_buffer);
+ 		 *res_buffer = new_string(utf8 ? utf8 : display_charset);
+ 
+ 		 /* This can fail silently */
+ 		 add_unicode_to_string(*res_buffer,1,&ch);
+ 
+ 		 DPRINT(Debug,10,(&Debug,
+ 				  "span_alt_data_helper: Set string\n"));
+ 
+ 		 DEBUG_PRINT_STRING(Debug,12,
+ 				    "span_alt_data_helper: buffer = ",
+ 				    "                    : buffer > ",
+ 				    *res_buffer);
+ 
+ 		 
+ 		 
+ 	     } else {
+ 
+ 		 int                    ref_key_pg_flags = 0;
+ 		 const struct string  * ref_key =
+ 		     out_entity_reference_key(alt_data_value.entity,
+ 					      & ref_key_pg_flags);
+ 
+ 		 if (*res_buffer)
+ 		     free_string(res_buffer);
+ 		 *res_buffer    = dup_string(ref_key);
+ 		 *res_pg_flags |= ref_key_pg_flags;
+ 
+ 		 data->buffer_x = 0;
+ 		 
+ 		 DPRINT(Debug,10,(&Debug,
+ 				  "span_alt_data_helper: Set string\n"));
+ 		 
+ 		 DEBUG_PRINT_STRING(Debug,12,
+ 				    "span_alt_data_helper: buffer = ",
+ 				    "                    : buffer > ",
+ 				    *res_buffer);		 
+ 	     }
+ 
+ 	 }
+ 	     break;
+ 	 }
+     }
+ 	break;
+     }
+ 	
+ out:
+ 
+     DPRINT(Debug,9,(&Debug,"span_alt_data_helper = %d\n",
+ 		    ret));
+     
+     return ret;
+ }
+ 
+ enum span_result span_helper (ctx,pager_range,info,buffer,data)
+      struct menu_context * ctx;
+      struct pager_range  * pager_range;
+      struct pg_wrap_info * info;
+      struct string       * buffer;
+      struct span_helper_data * data;
+ {
+     enum span_result span_line_result = span_failure;
+ 
+     int buffer_len      = string_len(buffer);
+     int LINES, COLUMNS;
+     uint16 ch = 0;   /* First character may be needed */
+     int L_mayclear;
+     
+     if (SPAN_HELPER_DATA_magic != data->magic)
+ 	panic("PAGER PANIC",__FILE__,__LINE__,
+ 	      "span_helper",
+ 	      "Bad magic number",0);
+     
+     L_mayclear          = data->mayclear;
+ 
+     menu_get_sizes(ctx, &LINES, &COLUMNS);
+ 
+     if (buffer_len > 0)
+ 	ch = give_unicode_from_string(buffer,0);
+ 
+ 
+     switch(span_helper_prefix(ctx,pager_range,info,data,ch,&span_line_result)) {
+     case spanh_exit:
+ 
+ 	DPRINT(Debug,9,(&Debug,"span_helper: "));
+ 
  	if (data->buffer_x >= buffer_len) {
  	    DPRINT(Debug,9,(&Debug, 
  			    "no buffer left (buffer_x=%d buffer_len=%d), ",
  			    data->buffer_x,buffer_len));
  	    goto buffer_handled;
  	}
+ 	
+ 	break;
  
!     case spanh_main: {
! 	int center_cur_col  = data->cur_col;
! 	int center_buffer_x = data->buffer_x;
! 	
! 	int WP  =  /* pager_indicate_wrapping */ data->wrap_indicator;
! 	
! 	int  max_width = COLUMNS;
! 
! 	/* 3) Writes actual text */
! 	
  	if (data->start_of_line) {
  	    DPRINT(Debug,10,(&Debug, 
  			     "span_helper: No pager range on beginning of line\n"));
***************
*** 371,412 ****
  	    DPRINT(Debug,10,(&Debug, 
  			     "span_helper: this is joined line\n"));
  	}
- 
- 	if (0 != (data->range_flags & PR_CENTER_THIS) &&
- 	    COLUMNS > buffer_len &&
- 	    data->p_start_COL  == data->cur_col) {
- 
- 	    /* Does not work correctly with double with characters 
- 	       also does not work with control characters
- 	     */
- 
- 	    int pos = (COLUMNS - buffer_len) / 2;
- 	  
- 	    if (pos > data->cur_col) {
- 		DPRINT(Debug,10,(&Debug, 
- 				 "span_helper: centering this line, col=%d => %d\n",
- 				 data->cur_col,pos));
- 
- 
- 		/* Make sure that garbage from previous
- 		   output is not left */
- 		if (L_mayclear) {
- 		    menu_MoveCursor(ctx,data->cur_line,data->cur_col);
- 
- 		    menu_CleartoEOLN(ctx);
- 		    L_mayclear = 0;
- 		}
- 		
- 		menu_MoveCursor(ctx,data->cur_line,pos);
- 		data->cur_col     = pos;
- 		data->p_start_COL = pos;
- 	    }	    	   
- 	}
- 
  	
! 	if (0 != (data->range_flags & PR_WORD_WRAP) 
  	    || 
! 	    (data->force_word_wrap && 0 == (data->range_flags & PR_PREFORMAT))
  	    ) {
  	    
  	    span_line_result = span_words(ctx,
--- 674,683 ----
  	    DPRINT(Debug,10,(&Debug, 
  			     "span_helper: this is joined line\n"));
  	}
  	
! 	if (ison(data->range_flags,PR_WORD_WRAP) 
  	    || 
! 	    (data->force_word_wrap && isoff(data->range_flags,PR_PREFORMAT))
  	    ) {
  	    
  	    span_line_result = span_words(ctx,
***************
*** 414,424 ****
  					  buffer,&(data->buffer_x),
  					  &L_mayclear,
  					  data->this_flags,
! 					  COLUMNS    /* max_width*/,
  					  buffer_len /* max_len */,
  					  data->joined_line,
  					  data->p_start_COL,
! 					  0 == (data->range_flags & 
  						PR_MAX_WIDTH) ? 
  					  data->p_width : 0,
  					  WP);
--- 685,695 ----
  					  buffer,&(data->buffer_x),
  					  &L_mayclear,
  					  data->this_flags,
! 					  max_width  /* max_width*/,
  					  buffer_len /* max_len */,
  					  data->joined_line,
  					  data->p_start_COL,
! 					  isoff(data->range_flags, 
  						PR_MAX_WIDTH) ? 
  					  data->p_width : 0,
  					  WP);
***************
*** 439,445 ****
  					 buffer,&(data->buffer_x),
  					 &L_mayclear,
  					 data->this_flags,
! 					 COLUMNS    /* max_width*/,
  					 buffer_len /* max_len */,
  					 WP);
  	    DPRINT(Debug,9,(&Debug, 
--- 710,716 ----
  					 buffer,&(data->buffer_x),
  					 &L_mayclear,
  					 data->this_flags,
! 					 max_width  /* max_width*/,
  					 buffer_len /* max_len */,
  					 WP);
  	    DPRINT(Debug,9,(&Debug, 
***************
*** 447,473 ****
  			    span_line_result));
  	    
  	}
  	
!     buffer_handled:
  	if (data->lineext) {
  	    DPRINT(Debug,9,(&Debug," line extension (joining), "));
  	    
  	    data->joined_line = 1;
! 	} else if (0 == (data->range_flags & PR_JOIN_LINES)) {
  	    DPRINT(Debug,9,(&Debug," line wrapping, "));
  	    data->start_of_line = 1;  /* Need new line */
  	} else {
  	    DPRINT(Debug,9,(&Debug," joining lines, "));
  	    data->joined_line = 1;
  	}
-     }
-     
-     data->mayclear      = L_mayclear ? 1 : 0;
- 
-     DPRINT(Debug,9,(&Debug," span_helper=%d | ",span_line_result));
- 
-     /* pager_helper_process_line() on src/pager/helper.c prints rest of debug line */
  
      return span_line_result;
  }
  
--- 718,861 ----
  			    span_line_result));
  	    
  	}
+ 
+ 	/* Redraw on centered */
  	
! 	if (! data->joined_line &&
! 	    ! data->lineext &&
! 	    ison(data->range_flags,PR_CENTER_THIS) &&
! 	    span_line_result >= span_ok &&
! 	    data->buffer_x > center_buffer_x &&
! 	    data->cur_col  > center_cur_col &&
! 	    center_cur_col < max_width) {
! 
! 	    
! 	    int end_col = data->cur_col;
! 
! 	    int used_len = end_col - center_cur_col;
! 	    int avail_space = max_width - center_cur_col;
! 
! 	    if (avail_space > used_len) {
! 
! 		int new_start_col = data->p_start_COL;
! 		
! 		int new_start_pos =
! 		    center_cur_col +
! 		    (avail_space - used_len) /2;
! 
! 		if (isoff(data->range_flags, PR_MAX_WIDTH) &&
! 		    data->p_width > 0 && data->p_width < max_width) {
! 
! 		    /* This does not depend printed line length 
! 		       -- also move reference length for wrapping
! 
! 		     */
! 		    
! 		    new_start_col
! 			+= ( max_width - data->p_width) / 2;
! 
! 		    if (new_start_col > new_start_pos)
! 			new_start_col = new_start_pos;			
! 		}
! 		
! 		if (new_start_pos > center_cur_col) {
! 		    DPRINT(Debug,10,(&Debug, 
! 				     "span_helper: centering this line (redraw), start col = %d => %d -- p_start_COL = %d => %d\n",
! 				     center_cur_col,new_start_pos,
! 				     data->p_start_COL,new_start_col
! 				     ));
! 		    
! 		    /* Need reddraw line */
! 		    
! 		    menu_MoveCursor(ctx,data->cur_line,center_cur_col);
! 		    menu_CleartoEOLN(ctx);
! 		    
! 		    data->cur_col  = new_start_pos;
! 		    data->buffer_x = center_buffer_x;
! 		    
! 		    menu_MoveCursor(ctx,data->cur_line,data->cur_col);
! 
! 		    if (ison(data->range_flags,PR_WORD_WRAP) 
! 			|| 
! 			(data->force_word_wrap && isoff(data->range_flags,PR_PREFORMAT))
! 			) {
! 			
! 			span_line_result = span_words(ctx,
! 						      data->cur_line,&(data->cur_col),
! 						      buffer,&(data->buffer_x),
! 						      &L_mayclear,
! 						      data->this_flags,
! 						      max_width  /* max_width*/,
! 						      buffer_len /* max_len */,
! 						      data->joined_line,
! 						      new_start_col /* p_start_COL */,
! 						      isoff(data->range_flags, 
! 							    PR_MAX_WIDTH) ? 
! 						      data->p_width : 0,
! 						      WP);
! 			
! 			DPRINT(Debug,9,(&Debug, 
! 					"span_helper: span_words redraw result = %d, ",
! 					span_line_result));
! 			
! 		    } else {
! 			
! 			/* This is the part of the code that actually displays on 
! 			 * the screen 
! 			 */
! 			
! 			span_line_result = span_line(ctx,
! 						     data->cur_line,&(data->cur_col),
! 						     buffer,&(data->buffer_x),
! 						     &L_mayclear,
! 						     data->this_flags,
! 						     max_width  /* max_width*/,
! 						     buffer_len /* max_len */,
! 						     WP);
! 			DPRINT(Debug,9,(&Debug, 
! 					"span_helper: span_line redaw result = %d, ",
! 					span_line_result));
! 	    
! 		    }		    		    		    
! 		}
! 	    }	    	   
! 	}
!        	
! 	buffer_handled:
  	if (data->lineext) {
  	    DPRINT(Debug,9,(&Debug," line extension (joining), "));
  	    
  	    data->joined_line = 1;
! 	} else if (isoff(data->range_flags,PR_JOIN_LINES)) {
  	    DPRINT(Debug,9,(&Debug," line wrapping, "));
  	    data->start_of_line = 1;  /* Need new line */
+ 	} else if (ison(data->range_flags,PR_ADD_SPACE)) {
+ 
+ 	    if (data->p_start_COL >= data->cur_col) {
+ 		DPRINT(Debug,9,(&Debug," joining lines (no space on start),"));
+ 	    } else if (COLUMNS > data->cur_col+1) {
+ 		menu_MoveCursor(ctx,data->cur_line,data->cur_col);
+ 		menu_CleartoEOLN(ctx);
+ 		menu_Writechar(ctx,' ');
+ 		data->cur_col++;
+ 		
+ 		DPRINT(Debug,9,(&Debug," joining lines with space, "));
+ 	    } else {
+ 		DPRINT(Debug,9,(&Debug," joining lines (no space),"));
+ 	    }
+ 	    data->joined_line = 1;
  	} else {
  	    DPRINT(Debug,9,(&Debug," joining lines, "));
  	    data->joined_line = 1;
  	}
  
+ 	data->mayclear      = L_mayclear ? 1 : 0;
+     }
+ 	break;
+     }
+ 	   
+     DPRINT(Debug,9,(&Debug," span_helper=%d \n",span_line_result));
+         
      return span_line_result;
  }
  
Index: elmME+.2.5.alpha63-cvs/src/pattern.c
*** elmME+.2.5.alpha62/src/pattern.c	Mon Jul 14 18:07:30 2014
--- elmME+.2.5.alpha63-cvs/src/pattern.c	Wed Dec 13 18:55:32 2023
***************
*** 1,7 ****
! static char rcsid[] = "@(#)$Id: pattern.c,v 2.6 2014/07/14 15:07:30 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.6 $   $State: Exp $
   *
   *  Modified by: Kari Hurtta 
   *                       (was hurtta+elm@posti.FMI.FI, hurtta+elm@ozone.FMI.FI)
--- 1,7 ----
! static char rcsid[] = "@(#)$Id: pattern.c,v 2.7 2023/12/13 16:55:32 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.7 $   $State: Exp $
   *
   *  Modified by: Kari Hurtta 
   *                       (was hurtta+elm@posti.FMI.FI, hurtta+elm@ozone.FMI.FI)
***************
*** 223,239 ****
      }
      
      if (function == DELETED && 
! 	string_matches_ascii(meta_pattern, s2us("tagged"),0)) {
  
  	if (meta_pattern)
  	    free_string( & (meta_pattern));
  	
  	return(DeleteTagged(menu, page, LOC->header_page));
  
!     } else if (string_matches_ascii(meta_pattern, s2us("flagged"),0)) 
  	count = DoFlagged(function, menu, LOC);
  
!     else if (string_matches_ascii(meta_pattern, s2us("all"),0))
  	count = DoAll(function, menu, LOC);
  
      else {
--- 223,239 ----
      }
      
      if (function == DELETED && 
! 	string_matches_ascii(meta_pattern, s2us("tagged"),0,SMA_op_normal)) {
  
  	if (meta_pattern)
  	    free_string( & (meta_pattern));
  	
  	return(DeleteTagged(menu, page, LOC->header_page));
  
!     } else if (string_matches_ascii(meta_pattern, s2us("flagged"),0,SMA_op_normal)) 
  	count = DoFlagged(function, menu, LOC);
  
!     else if (string_matches_ascii(meta_pattern, s2us("all"),0,SMA_op_normal))
  	count = DoAll(function, menu, LOC);
  
      else {
Index: elmME+.2.5.alpha63-cvs/src/quotadisp.c
*** elmME+.2.5.alpha62/src/quotadisp.c	Fri Sep  2 20:38:19 2022
--- elmME+.2.5.alpha63-cvs/src/quotadisp.c	Wed Dec 13 18:55:32 2023
***************
*** 1,7 ****
! static char rcsid[] = "@(#)$Id: quotadisp.c,v 2.3 2022/08/19 16:13:05 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.3 $   $State: Exp $
   *
   *  Author: Kari Hurtta 
   *      or  Kari Hurtta 
   *      or  Kari Hurtta 
   *                       (was hurtta+elm@posti.FMI.FI, hurtta+elm@ozone.FMI.FI)
--- 1,7 ----
! static char rcsid[] = "@(#)$Id: save_opts.c,v 2.8 2023/12/13 16:55:32 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.8 $   $State: Exp $
   *
   *  Modified by: Kari Hurtta 
   *                       (was hurtta+elm@posti.FMI.FI, hurtta+elm@ozone.FMI.FI)
***************
*** 102,108 ****
  			      "Backup %s => %s failed: %s"),
  		      user_rc_file,bck,strerror(err));
  
! 
  	    return;
  	}
  
--- 102,108 ----
  			      "Backup %s => %s failed: %s"),
  		      user_rc_file,bck,strerror(err));
  
! 	    free(bck);
  	    return;
  	}
  
Index: elmME+.2.5.alpha63-cvs/src/screen/curses.c
*** elmME+.2.5.alpha62/src/screen/curses.c	Tue Apr 20 20:32:06 2021
--- elmME+.2.5.alpha63-cvs/src/screen/curses.c	Wed Dec 13 18:55:32 2023
***************
*** 1,20 ****
! static char rcsid[] = "@(#)$Id: curses.c,v 2.22 2021/04/20 16:54:07 hurtta Exp $";
  
! /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.22 $   $State: Exp $
   *
   *  Modified by: Kari Hurtta 
   *                       (was hurtta+elm@posti.FMI.FI, 
   *                            hurtta+elm@ozone.FMI.FI)
   *           or  Kari Hurtta 
!  *****************************************************************************
   *
   * Some code copied from Elm 2.4 src/curses.c. It have following copyright:
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
   *
!  *****************************************************************************/
  
  #include "def_screen.h"
  #include "s_me.h"
--- 1,20 ----
! static char rcsid[] = "@(#)$Id: curses.c,v 2.23 2023/12/13 16:55:32 hurtta Exp $";
  
! /************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.23 $   $State: Exp $
   *
   *  Modified by: Kari Hurtta 
   *                       (was hurtta+elm@posti.FMI.FI, 
   *                            hurtta+elm@ozone.FMI.FI)
   *           or  Kari Hurtta 
!  ************************************************************************
   *
   * Some code copied from Elm 2.4 src/curses.c. It have following copyright:
   *
   * 			Copyright (c) 1988-1992 USENET Community Trust
   * 			Copyright (c) 1986,1987 Dave Taylor
   *
!  ************************************************************************/
  
  #include "def_screen.h"
  #include "s_me.h"
***************
*** 66,75 ****
  
      { pg_REVERSE, NULL, NULL,
        "mr"     /* Start reverse mode  */ ,
!       NULL     /* End reverse mode */ }
  
  };
  
  static char *CUR_end_modes = NULL;
  /*     me   End all mode like so, us, mb, md and mr  */
  
--- 66,96 ----
  
      { pg_REVERSE, NULL, NULL,
        "mr"     /* Start reverse mode  */ ,
!       NULL     /* End reverse mode */ },
  
+     { pg_ITALIC, NULL, NULL,
+       "ZH"    /* Enter italic mode */,
+       "ZR"    /* End italic mode */ },
+ 
+     { pg_DIM, NULL, NULL,
+       "mh"    /* Start half-bright mode */,
+       NULL    /* End half-bright mode */ },
+ 
+     { pg_bit_SUBSCRIPT , NULL, NULL,
+       "ZN"   /* Enter subscript mode */,
+       "ZV"   /* End subscript mode */ },
+ 
+     { pg_bit_SUPERSCRIPT, NULL, NULL,
+       "ZO"   /* Enter superscript mode */,
+       "ZW"   /* End superscript mode   */ }
+     
+        
  };
  
+ static const struct ansi_sgr_attribute * ansi_attr[NUM_pg_attr_bits+5];
+ static size_t                            ansi_attr_len = 0;
+ static int                               ansi_attr_pg_flags = 0;
+ 
  static char *CUR_end_modes = NULL;
  /*     me   End all mode like so, us, mb, md and mr  */
  
***************
*** 250,275 ****
  		}
  		break;
  	    }
- 
  	}
! 	
! 	CUR_end_modes        =  tgetstr("me", &ptr);     /* End all mode like so, us, mb, md and mr */
  
  	CUR_cleartoeoln       = tgetstr("ce", &ptr);     /* Clear to end of line */
  	CUR_cleartoeos        = tgetstr("cd", &ptr);     /* Clear to end of screen */
  	CUR_lines	      	   = tgetnum("li");           /* Number of lines */
  	CUR_columns	   = tgetnum("co");           /* Number of columns */
! 	cur_tabspacing	   = ((cur_tabspacing=tgetnum("it"))<= 0 ? 8 : cur_tabspacing);
! 	                                              /* Difference between tab positions */
! 	CUR_automargin	   = tgetflag("am");          /* Automatic margins which means automatic 
! 							 line wrap */
  	CUR_eatnewlineglitch   = tgetflag("xn");         /* Newline/wraparound glitch */
  	CUR_transmit_on	   = tgetstr("ks", &ptr);     /* Turn keypad on  */
  	CUR_transmit_off      = tgetstr("ke", &ptr);     /* turn keypad off */
  	CUR_set_memlock	   = tgetstr("ml", &ptr);     /* ... not listed ... */
  	CUR_clear_memlock	   = tgetstr("mu", &ptr);     /* ... not listed ... */
! 	CUR_start_termcap	   = tgetstr("ti", &ptr);     /* Begin program that uses cursor motion */
! 	CUR_end_termcap	   = tgetstr("te", &ptr);     /* End program that uses cursor motion */
  
  
  	get_terminal_keys(&ptr);
--- 271,302 ----
  		}
  		break;
  	    }
  	}
! 		
! 	CUR_end_modes        =  tgetstr("me", &ptr);     /* End all mode like so, 
! 							    us, mb, md and mr */
  
  	CUR_cleartoeoln       = tgetstr("ce", &ptr);     /* Clear to end of line */
  	CUR_cleartoeos        = tgetstr("cd", &ptr);     /* Clear to end of screen */
  	CUR_lines	      	   = tgetnum("li");           /* Number of lines */
  	CUR_columns	   = tgetnum("co");           /* Number of columns */
! 	cur_tabspacing	   =
! 	    ((cur_tabspacing=tgetnum("it"))<= 0 ? 8 : cur_tabspacing);
! 	     /* Difference between tab positions */
! 	
! 	CUR_automargin	   = tgetflag("am");    /* Automatic margins which means 
! 						   automatic line wrap */
  	CUR_eatnewlineglitch   = tgetflag("xn");         /* Newline/wraparound glitch */
  	CUR_transmit_on	   = tgetstr("ks", &ptr);     /* Turn keypad on  */
  	CUR_transmit_off      = tgetstr("ke", &ptr);     /* turn keypad off */
+ 	
  	CUR_set_memlock	   = tgetstr("ml", &ptr);     /* ... not listed ... */
  	CUR_clear_memlock	   = tgetstr("mu", &ptr);     /* ... not listed ... */
! 	
! 	CUR_start_termcap	   = tgetstr("ti", &ptr);   /* Begin program that uses 
! 							       cursor motion */
! 	CUR_end_termcap	   = tgetstr("te", &ptr);     /* End program that uses cursor 
! 							 motion */
  
  
  	get_terminal_keys(&ptr);
***************
*** 322,327 ****
--- 349,380 ----
  	return 0;
  }
  
+ /* Called after config is read */
+ void curses_check_terminal()
+ {
+     if (terminal_type[0]) {
+ 	ansi_attr_pg_flags
+ 	    = ansi_sgr_attributes(terminal_type,
+ 				  ansi_attr,
+ 				  (sizeof ansi_attr) /
+ 				  sizeof (ansi_attr[0]),
+ 				  &ansi_attr_len);
+ 	DPRINT(Debug,4, (&Debug,
+ 			 "curses_check_terminal: ansi_attr_pg_flags=%x (%s), terminal=%s\n",
+ 			 ansi_attr_pg_flags,
+ 			 give_pg_flags(ansi_attr_pg_flags),
+ 			 terminal_type));
+ 
+ 	
+     } else {
+ 	DPRINT(Debug,4, (&Debug,
+ 			 "curses_check_terminal: cur_InitScreen not called?\n"));
+ 
+     }
+ }
+ 
+ 
+ 
  /* DO NOT return lines-1 (as ScreenSize() did) */
  
  void cur_ScreenSize(lines, columns)
***************
*** 666,671 ****
--- 719,755 ----
      FlushBuffer();	
  }
  
+ static void write_ansi_sgr_attr P_((short ANSI_sgr_settings[],
+ 				    int setcount));
+ static void write_ansi_sgr_attr(ANSI_sgr_settings,setcount)
+      short ANSI_sgr_settings[];
+      int setcount;
+ {
+     int i;
+     
+     if (setcount < 1)
+ 	return;
+ 
+     /* Write CSI as ESC [ */
+     outchar(0x1B  /* ESC (escape)  */);
+     outchar('[');
+ 
+     for (i = 0; i < setcount; i++) {
+         char buffer[8];
+ 	int n,j; 
+ 	
+ 	if (i > 0)
+ 	    outchar(';');
+ 	
+ 	n = elm_sfprintf(buffer,sizeof buffer,FRM("%d"),
+ 			 ANSI_sgr_settings[i]);
+ 	for (j = 0; j < n; j++)
+ 	    outchar(buffer[j]);
+     }
+     
+     outchar('m');
+ }
+ 
  void cur_changemode(mode,set,reset)
       int *mode; 
       int set; 
***************
*** 673,678 ****
--- 757,764 ----
  {
      int i;
      int found = 0;
+     int f;
+     int unsupported = 0;
  
      /* To allow switching modes from 'reset' to 'set', run reset first */
  
***************
*** 689,710 ****
  
  	return;
      }
! 
      DPRINT(Debug,7, (&Debug, 
! 		     "cur_changemode: for %x set and %x reset: mode = %x\n",
! 		     set,reset,*mode));
  
  
      for (i =0 ; i < (sizeof set_modes) / sizeof (set_modes[0]); i++) {
! 	if ((reset & set_modes[i].mode)   && set_modes[i].off) {
  	    tputs(set_modes[i].off, 1, OUTCHAR);
! 	    *mode &= ~(set_modes[i].mode);
! 
! 	    found |= set_modes[i].mode;
  
  	    DPRINT(Debug,7, (&Debug, 
! 			     "cur_changemode: reset %x => mode = %x\n",
! 			     reset, *mode));
  	   
  	}
      }
--- 775,871 ----
  
  	return;
      }
!     
      DPRINT(Debug,7, (&Debug, 
! 		     "cur_changemode: for %x (%s) set and ",
! 		     set, give_pg_flags(set)));
! 
!     DPRINT(Debug,7, (&Debug, "%x (%s) reset: ",
! 		     reset, give_pg_flags(reset)));
! 
!     DPRINT(Debug,7, (&Debug, "mode = %x (%s)\n",
! 		     *mode,give_pg_flags(*mode)));
! 
!     f = pg_set_or_disable_flags(NULL,set);
!     if (ison(*mode,f)) {
! 	int d = f & *mode ;
! 
! 	if (d) {
! 	    DPRINT(Debug,7, (&Debug, 
! 			     "cur_changemode: disable set %x => reset incompatible %x (%s)\n",
! 			     f,d, give_pg_flags(d)));
! 
! 	    setit(reset,d);
! 
! 	}
!     }
! 
!     /* pg_STANDOUT is probably  pg_BOLD and pg_REVERSE 
!        or
!        pg_STANDOUT is same than pg_REVERSE   
! 
!        Probable should re-enable other if cleared
!     */
  
+     
+     if (ison(reset,ansi_attr_pg_flags)) {
+ 
+ 	short ANSI_sgr_settings [ NUM_pg_attr_bits ];
+ 	int setcount = 0;
+ 	size_t j;
+ 	
+ 	DPRINT(Debug,7, (&Debug, 
+ 			 "cur_changemode: ansi_attr_len=%zu, ansi_attr_pg_flags %zu (%s)\n",
+ 			 ansi_attr_len,
+ 			 ansi_attr_pg_flags,
+ 			 give_pg_flags(ansi_attr_pg_flags)));
+ 
+ 
+ 	/* Do disables if possoble */
+ 
+ 	for (j = 0;
+ 	     j < ansi_attr_len &&
+ 		 setcount < (sizeof ANSI_sgr_settings) /
+ 		 sizeof (ANSI_sgr_settings[0]);
+ 	     j++) {
+ 	    if (ansi_attr[j]) {		
+ 		if (ison(reset,ansi_attr[j]->pg_flag)) {
+ 		    
+ 		    ANSI_sgr_settings[setcount++] =
+ 			ansi_attr[j]->end_value;
+ 		    
+ 		    clearit(*mode,ansi_attr[j]->pg_flag);
+ 		    setit(found,ansi_attr[j]->pg_flag);
+ 
+ 		     DPRINT(Debug,7, (&Debug, 
+ 				      "cur_changemode: %s %x reset %x => mode = %x (%s)\n",
+ 				      ansi_attr[j]->name ?
+ 				      ansi_attr[j]->name : "",
+ 				      ansi_attr[j]->pg_flag,
+ 				      reset, *mode,
+ 				      give_pg_flags(*mode)));
+ 		}		
+ 	    }
+ 	}
+ 
+ 	write_ansi_sgr_attr(ANSI_sgr_settings,setcount);	
+     }
  
+     
      for (i =0 ; i < (sizeof set_modes) / sizeof (set_modes[0]); i++) {
! 	if (ison(reset,set_modes[i].mode)   && set_modes[i].off) {
  	    tputs(set_modes[i].off, 1, OUTCHAR);
! 	    
! 	    clearit(*mode,set_modes[i].mode);
! 	    setit(found,set_modes[i].mode);
  
  	    DPRINT(Debug,7, (&Debug, 
! 			     "cur_changemode: %s %x reset %x => mode = %x (%s)\n",
! 			     set_modes[i].set_off ?
! 			     set_modes[i].set_off : "",
! 			     set_modes[i].mode,
! 			     reset, *mode,
! 			     give_pg_flags(*mode)));
  	   
  	}
      }
***************
*** 715,743 ****
  	tputs(CUR_end_modes, 1, OUTCHAR); 
  	
  	DPRINT(Debug,7, (&Debug, 
! 			 "cur_changemode: all reset (for mode %x reset), need set %x\n",
! 			 reset,needmode));
  	
  	*mode = 0;
  	
! 	set  |=  needmode;
      }
  
  
      for (i =0 ; i < (sizeof set_modes) / sizeof (set_modes[0]); i++) {
  
! 	if ((set & set_modes[i].mode)   && set_modes[i].on) {
  	    tputs(set_modes[i].on, 1, OUTCHAR);
! 	    *mode |= set_modes[i].mode;
  
  	    DPRINT(Debug,7, (&Debug, 
! 			     "cur_changemode: set %x => mode = %x\n",
! 			     set, *mode));
  
  	}
  
      }
  
  }
  
  /*  ----------------------------------------------------------- */
--- 876,965 ----
  	tputs(CUR_end_modes, 1, OUTCHAR); 
  	
  	DPRINT(Debug,7, (&Debug, 
! 			 "cur_changemode: all reset (for mode %x reset), need set %x (%s)\n",
! 			 reset,needmode,
! 			 give_pg_flags(needmode)));
  	
  	*mode = 0;
  	
! 	setit(set,needmode);
      }
  
  
      for (i =0 ; i < (sizeof set_modes) / sizeof (set_modes[0]); i++) {
  
! 	if (ison(set,set_modes[i].mode)   && set_modes[i].on) {
! 	    
  	    tputs(set_modes[i].on, 1, OUTCHAR);
! 	    setit(*mode,set_modes[i].mode);
  
  	    DPRINT(Debug,7, (&Debug, 
! 			     "cur_changemode: %s %x set %x => mode = %x (%s)\n",
! 			     set_modes[i].set_on ?
! 			     set_modes[i].set_on : "",
! 			     set_modes[i].mode,
! 			     set, *mode,
! 			     give_pg_flags(*mode)));
  
  	}
  
      }
  
+     if (ison(set,ansi_attr_pg_flags)) {
+ 	short ANSI_sgr_settings [ NUM_pg_attr_bits ];
+ 	int setcount = 0;
+ 	size_t j;
+ 	
+ 	DPRINT(Debug,7, (&Debug, 
+ 			 "cur_changemode: ansi_attr_len=%zu, ansi_attr_pg_flags %zu (%s)\n",
+ 			 ansi_attr_len,
+ 			 ansi_attr_pg_flags,
+ 			 give_pg_flags(ansi_attr_pg_flags)));
+ 
+ 	/* Do enables if possible */
+ 
+ 	for (j = 0;
+ 	     j < ansi_attr_len &&
+ 		 setcount < (sizeof ANSI_sgr_settings) /
+ 		 sizeof (ANSI_sgr_settings[0]);
+ 	     j++) {
+ 	    if (ansi_attr[j]) {
+ 
+ 		if (ison(set,ansi_attr[j]->pg_flag)) {
+ 
+ 		    ANSI_sgr_settings[setcount++] =
+ 			ansi_attr[j]->start_value;
+ 
+ 		    setit(*mode,ansi_attr[j]->pg_flag);
+ 
+ 		    DPRINT(Debug,7, (&Debug, 
+ 				     "cur_changemode: %s %x set %x => mode = %x (%s)\n",
+ 				     ansi_attr[j]->name ?
+ 				     ansi_attr[j]->name : "",
+ 				     ansi_attr[j]->pg_flag,
+ 				     set, *mode,
+ 				     give_pg_flags(*mode)));
+ 
+ 		}
+ 	    }
+ 	}
+ 
+ 	write_ansi_sgr_attr(ANSI_sgr_settings,setcount);	
+ 	
+     }
+ 
+ 
+     unsupported = set;
+     clearit(unsupported,*mode);
+     if (unsupported) {
+ 	DPRINT(Debug,7, (&Debug, 
+ 			 "cur_changemode: unsupported %x (%s)",
+ 			 unsupported,give_pg_flags(unsupported)));
+ 	
+ 	DPRINT(Debug,7, (&Debug, " -> result %x (%s)\n",
+ 			 *mode,give_pg_flags(*mode)));
+     }
+         
  }
  
  /*  ----------------------------------------------------------- */
***************
*** 1218,1223 ****
--- 1440,1533 ----
      }    
  }
  
+ 
+ int curses_available_charset(cs)
+      charset_t cs;
+ {
+ 
+     if (cs == display_charset)
+ 	return 1;
+     if (cs == system_charset)
+ 	return 1;
+ 
+     if (!allow_charset_switching)
+ 	return 0;
+     
+     return terminal_can_switch_to(terminal_type,cs,1 /* silent */, 0);
+ 
+ }
+ 
+ /* mallocs result -- result need to be valid characters and usable 
+    may return NULL
+ */
+ struct string * curses_available_string(S)
+      const struct string *S;
+ {
+ #define NUM_charsets 255
+     
+     charset_t  charset_vector[NUM_charsets];
+     int candinate [NUM_charsets];
+     int cs_count;
+     
+     int len = string_len(S);
+     int i,j;
+     
+     charset_t * csv = give_display_charsets(charset_vector,
+ 					    NUM_charsets,
+ 					    0 /* not signal */
+ 					    );
+ 
+     struct string * S1 = NULL;
+     
+     
+     for (cs_count = 0; csv[cs_count]; cs_count++)
+ 	candinate[cs_count] = 1;
+ 
+     for (i = 0; i < len; i++) {
+ 	uint16 c = give_unicode_from_string(S,i);
+ 	
+ 	if (UNICODE_BAD_CHAR == c) {
+ 
+ 
+ 	    return NULL;
+ 	}
+ 
+ 	for (j = 0; j < cs_count; j++) {
+ 
+ 	    enum charset_unicode_stat x;
+ 
+ 	    x = string_type_have_unicode(csv[j],c);
+ 
+ 	    switch (x) {
+ 	    case charset_unicode_bad:
+ 	    case charset_unicode_unknown:
+ 	    case charset_missing_unicode:
+ 		candinate[j] = 0;
+ 		break;
+ 	    case charset_have_unicode:
+ 		break;                  
+ 	    }               
+ 	}
+     }
+ 
+     for (j = 0; j < cs_count; j++) {
+ 	if (candinate[j]) {
+ 	    int failcount = 0;
+ 	    
+ 	    S1 =  convert_string2(csv[j],
+ 				  S,&failcount);
+ 	    
+ 	    if (S1 && 0 == failcount)
+ 		break;
+ 	    
+ 	    if (S1)
+ 		free_string(&S1);
+ 	}
+     }
+     
+     return S1;
+ }
+ 
  struct string *curses_printable_clip(S,pos,len,visible_len,max_visible)
       const struct string *S;
       int *pos;
Index: elmME+.2.5.alpha63-cvs/src/screen/screen.c
*** elmME+.2.5.alpha62/src/screen/screen.c	Thu Jul 28 18:49:52 2022
--- elmME+.2.5.alpha63-cvs/src/screen/screen.c	Wed Dec 13 18:55:32 2023
***************
*** 1,7 ****
! static char rcsid[] = "@(#)$Id: screen.c,v 2.11 2022/07/14 14:16:01 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.11 $   $State: Exp $
   *
   *  Author: Kari Hurtta  
   *                  (was hurtta+elm@posti.FMI.FI, hurtta+elm@ozone.FMI.FI)
--- 1,7 ----
! static char rcsid[] = "@(#)$Id: screen.c,v 2.12 2023/12/13 16:55:32 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.12 $   $State: Exp $
   *
   *  Author: Kari Hurtta  
   *                  (was hurtta+elm@posti.FMI.FI, hurtta+elm@ozone.FMI.FI)
***************
*** 926,937 ****
  
  void StartBold()
  {
      DPRINT(Debug,49, (&Debug, "StartBold()\n"));
  
      enter_terminal_hook();
  
      SYNC(default_context);
!     cur_changemode(&CUR_modes, pg_BOLD,0);
  }
  
  void EndBold()
--- 926,940 ----
  
  void StartBold()
  {
+     int add = pg_BOLD;
+     int disable = pg_set_or_disable_flags(NULL,add);
+ 	
      DPRINT(Debug,49, (&Debug, "StartBold()\n"));
  
      enter_terminal_hook();
  
      SYNC(default_context);
!     cur_changemode(&CUR_modes, add,disable);
  }
  
  void EndBold()
***************
*** 947,958 ****
  
  void StartStandout() 
  {
      DPRINT(Debug,49, (&Debug, "StartStandout()\n"));
  
      enter_terminal_hook();
  
      SYNC(default_context);
!     cur_changemode(&CUR_modes, pg_STANDOUT,0);
  }
  
  void EndStandout() 
--- 950,964 ----
  
  void StartStandout() 
  {
+     int add = pg_STANDOUT;
+     int disable = pg_set_or_disable_flags(NULL,add);
+     
      DPRINT(Debug,49, (&Debug, "StartStandout()\n"));
  
      enter_terminal_hook();
  
      SYNC(default_context);
!     cur_changemode(&CUR_modes, add,disable);
  }
  
  void EndStandout() 
***************
*** 968,979 ****
  
  void StartUnderline() 
  {
      DPRINT(Debug,49, (&Debug, "StartUnderline()\n"));
  
      enter_terminal_hook();
  
      SYNC(default_context);
!     cur_changemode(&CUR_modes, pg_UNDERLINE,0);
  }
  
  void EndUnderline() 
--- 974,988 ----
  
  void StartUnderline() 
  {
+     int add = pg_UNDERLINE;
+     int disable = pg_set_or_disable_flags(NULL,add);
+ 
      DPRINT(Debug,49, (&Debug, "StartUnderline()\n"));
  
      enter_terminal_hook();
  
      SYNC(default_context);
!     cur_changemode(&CUR_modes, add,disable);
  }
  
  void EndUnderline() 
***************
*** 990,995 ****
--- 999,1006 ----
       struct menu_context *ctx; 
       int f;
  {
+     int disable = pg_set_or_disable_flags(NULL,f);
+ 
      if (MENU_CONTEXT_magic != ctx->magic)
  	panic("SCREEN PANIC",__FILE__,__LINE__,"menu_StartXX",
  	      "Bad type magic number",0);
***************
*** 1001,1007 ****
      enter_terminal_hook();
  
      SYNC(ctx);
!     ctx->routine->wra_changemode(ctx, f, 0);
  }
  
  void menu_EndXX(ctx,f)
--- 1012,1018 ----
      enter_terminal_hook();
  
      SYNC(ctx);
!     ctx->routine->wra_changemode(ctx, f, disable);
  }
  
  void menu_EndXX(ctx,f)
Index: elmME+.2.5.alpha63-cvs/utils/Makefile.SH
*** elmME+.2.5.alpha62/utils/Makefile.SH	Fri Sep  4 10:57:00 2020
--- elmME+.2.5.alpha63-cvs/utils/Makefile.SH	Wed Dec 13 18:55:32 2023
***************
*** 35,48 ****
     XX=
  fi
  
! libx="../libs/libelmme-base.a ../libs/libelmme-mailer.a ../libs/libelmme-mbox.a ../libs/libelmme-addr.a ../libs/libelmme-misc.a"
! libxs="../shlib/libelmme-base.so ../shlib/libelmme-mailer.so ../shlib/libelmme-mbox.so ../shlib/libelmme-addr.so ../shlib/libelmme-misc.so"
  headers="elm_defs.h defs_major.h"
  
  echo "Extracting utils/Makefile (with variable substitutions)"
  cat >Makefile <Makefile < 
   *       or Kari Hurtta 
--- 1,7 ----
! static char rcsid[] = "@(#)$Id: elmconfwriter.c,v 2.11 2023/12/13 16:55:32 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.11 $   $State: Exp $
   *
   *  Author: Kari Hurtta  
   *       or Kari Hurtta 
***************
*** 19,25 ****
  #include "addrlib.h"
  #include "aliaslib.h"
  #include "mboxlib.h"
! 
  #include "reghelper.h"
  
  DEBUG_VAR(Debug,__FILE__,"util");
--- 19,25 ----
  #include "addrlib.h"
  #include "aliaslib.h"
  #include "mboxlib.h"
! #include "melib.h"
  #include "reghelper.h"
  
  DEBUG_VAR(Debug,__FILE__,"util");
***************
*** 63,68 ****
--- 63,69 ----
  	conf_aliases_map,
  	conf_mlist_map,
  	conf_hash_marks,
+ 	conf_tagfilter_entities,
  	conf_LAST
      } config_file;
  
***************
*** 185,190 ****
--- 186,192 ----
      init_addrlib(read_flags);
      init_aliaslib(read_flags);
      init_mboxlib(read_flags);
+     init_melib(read_flags);   
      init_defaults(read_flags);
  
      elm_sfprintf(version_buff, sizeof version_buff,
***************
*** 237,242 ****
--- 239,248 ----
  		break;
  	    case conf_hash_marks: targetfile = system_hash_marks;
  		break;
+ 
+ 	    case conf_tagfilter_entities:
+ 		targetfile = system_tagfilter_entfile;
+ 		break;
  		
  	    case conf_LAST:
  		break;
***************
*** 291,303 ****
  		    struct stat target_stat;
  		    int mode = 0644;
  		    
! 		    int r1 = access(targetfile,WRITE_ACCESS);
! 		    int r2;
! 		    int r4;
  		    
  		    switch (r1) {
  			
! 		    case -1: {			
  			int errcode = errno;
  			
  			if (ENOENT == errcode) {
--- 297,309 ----
  		    struct stat target_stat;
  		    int mode = 0644;
  		    
! 		    enum syscall_status r1 = access(targetfile,WRITE_ACCESS);
! 		    enum syscall_status r2;
! 		    enum syscall_status r4;
  		    
  		    switch (r1) {
  			
! 		    case syscall_error /* -1 */: {			
  			int errcode = errno;
  			
  			if (ENOENT == errcode) {
***************
*** 321,327 ****
  		    }
  			break;
  
! 		    case 0:			
  			if (list_files) {
  			    if (backup_file[config_file]) {
  				FILE * orig_file_F   = NULL;
--- 327,333 ----
  		    }
  			break;
  
! 		    case syscall_success /* 0 */:
  			if (list_files) {
  			    if (backup_file[config_file]) {
  				FILE * orig_file_F   = NULL;
***************
*** 333,339 ****
  				r2 = stat(targetfile,&target_stat);
  				
  				switch (r2) {
! 				case -1: {
  				    int errcode = errno;
  				    
  				    printf ("%s (error: %s)\n",
--- 339,345 ----
  				r2 = stat(targetfile,&target_stat);
  				
  				switch (r2) {
! 				case syscall_error /* -1 */: {
  				    int errcode = errno;
  				    
  				    printf ("%s (error: %s)\n",
***************
*** 345,351 ****
  				}
  				    break;
  				    
! 				case 0:
  				    mode = target_stat.st_mode & 07777;
  				    				
  				    orig_file_F   = fopen(targetfile,"r");
--- 351,357 ----
  				}
  				    break;
  				    
! 				case syscall_success /* 0 */:
  				    mode = target_stat.st_mode & 07777;
  				    				
  				    orig_file_F   = fopen(targetfile,"r");
***************
*** 462,468 ****
  		    r2 = stat(targetfile,&target_stat);
  
  		    switch (r2) {
! 		    case -1: {
  			int errcode = errno;
  			
  			lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNoStat,
--- 468,474 ----
  		    r2 = stat(targetfile,&target_stat);
  
  		    switch (r2) {
! 		    case syscall_error /* -1 */: {
  			int errcode = errno;
  			
  			lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNoStat,
***************
*** 473,479 ****
  		    }
  			break;
  
! 		    case 0:
  			mode = target_stat.st_mode & 07777;
  		    
  			if (0 != (mode & 00002)) {
--- 479,485 ----
  		    }
  			break;
  
! 		    case syscall_success /* 0 */:
  			mode = target_stat.st_mode & 07777;
  		    
  			if (0 != (mode & 00002)) {
***************
*** 505,511 ****
  #endif
  		    case conf_aliases_map: 
  		    case conf_mlist_map:
! 		    case conf_hash_marks: 
  			
  			tmp = elm_message(FRM("%s.N"),targetfile);
  			f = open_or_create(tmp);
--- 511,518 ----
  #endif
  		    case conf_aliases_map: 
  		    case conf_mlist_map:
! 		    case conf_hash_marks:
! 		    case conf_tagfilter_entities: 
  			
  			tmp = elm_message(FRM("%s.N"),targetfile);
  			f = open_or_create(tmp);
***************
*** 568,573 ****
--- 575,582 ----
  						 "ELMCONFWRITER",version_buff,
  						 system_mail_services_cs,
  						 system_mail_services_pl);
+ 
+ 			/* XXX error message ? */
  			break;
  #endif
  			
***************
*** 602,615 ****
  						   system_hash_marks_cs,
  						   system_hash_marks_pl,
  						   SYSTEM_RC);
! 			break;
  			
  		    case conf_LAST:
  			break;
  		    }
  		
  		    switch (config_file) {
! 			int r3;
  			
  		    case conf_charset_map:
  		    case conf_mime_types_map:
--- 611,643 ----
  						   system_hash_marks_cs,
  						   system_hash_marks_pl,
  						   SYSTEM_RC);
! 
! 			/* XXX error message ? */
  			
+ 			break;
+ 
+ 		    case conf_tagfilter_entities:
+ 			r = dump_tagfilter_entities(f,system_tagfilter_entities_conf,NULL,
+ 						    "ELMCONFWRITER",version_buff,
+ 						    system_tagfilter_entities_cs,
+ 						    system_tagfilter_entities_pl,
+ 						    SYSTEM_RC,&errcode);
+ 
+ 			if (!r && errcode) {
+ 			    lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotWriteable,
+ 					      "File %.50s is not writeable: %s"),
+ 				      tmp, strerror(errcode));
+ 			    
+ 			    err=1;
+ 			}
+ 
+ 			break;
  		    case conf_LAST:
  			break;
  		    }
  		
  		    switch (config_file) {
! 			enum syscall_status r3;
  			
  		    case conf_charset_map:
  		    case conf_mime_types_map:
***************
*** 620,626 ****
  #endif
  		    case conf_aliases_map: 
  		    case conf_mlist_map:
! 		    case conf_hash_marks: 
  			
  			if (EOF == fclose(f)) {
  			    int errcode = errno;
--- 648,655 ----
  #endif
  		    case conf_aliases_map: 
  		    case conf_mlist_map:
! 		    case conf_hash_marks:
! 		    case conf_tagfilter_entities:
  			
  			if (EOF == fclose(f)) {
  			    int errcode = errno;
***************
*** 635,645 ****
  			}
  
  			if (backup_file[config_file]) {
! 			    int r5 = link(targetfile,backup_file[config_file]);
  			    
  			    switch (r5) {
  				int errcode;
! 			    case -1:
  				errcode = errno;
  				lib_error(CATGETS(elm_msg_cat, MeSet, MeBackupFailed,
  						  "Backup %s => %s failed: %s"),
--- 664,674 ----
  			}
  
  			if (backup_file[config_file]) {
! 			    enum syscall_status r5 = link(targetfile,backup_file[config_file]);
  			    
  			    switch (r5) {
  				int errcode;
! 			    case syscall_error /* -1 */:
  				errcode = errno;
  				lib_error(CATGETS(elm_msg_cat, MeSet, MeBackupFailed,
  						  "Backup %s => %s failed: %s"),
***************
*** 648,654 ****
  				unlink(tmp);   /* Ignore error */
  				free(tmp);
  				continue;
! 			    case 0:  /* List backup */
  				printf ("%s -> %s\n",
  					targetfile,backup_file[config_file]);
  				break;
--- 677,683 ----
  				unlink(tmp);   /* Ignore error */
  				free(tmp);
  				continue;
! 			    case syscall_success /* 0 */:  /* List backup */
  				printf ("%s -> %s\n",
  					targetfile,backup_file[config_file]);
  				break;
***************
*** 658,664 ****
  			r3 = rename(tmp,targetfile);
  
  			switch (r3) {
! 			case -1: {
  			    int errcode = errno;
  			    lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotRenamed,
  					      "Failed to rename temporary file to %.50s: %.30s"),
--- 687,693 ----
  			r3 = rename(tmp,targetfile);
  
  			switch (r3) {
! 			case syscall_error /* -1 */: {
  			    int errcode = errno;
  			    lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotRenamed,
  					      "Failed to rename temporary file to %.50s: %.30s"),
***************
*** 670,676 ****
  			    continue;
  			}
  			    break;
! 			case 0:
  			    break;
  			}
  			
--- 699,705 ----
  			    continue;
  			}
  			    break;
! 			case syscall_success /* 0 */:
  			    break;
  			}
  			
***************
*** 691,697 ****
  		    r4 = chmod(targetfile,mode);
  		    switch (r4) {
  			
! 		    case -1: {
  			int errcode = errno;
  			lib_error(CATGETS(elm_msg_cat, MeSet, MeFileModeNotChanged,
  					  "Failed to change file %s mode (new mode %05o):  %s"),
--- 720,726 ----
  		    r4 = chmod(targetfile,mode);
  		    switch (r4) {
  			
! 		    case syscall_error /* -1 */: {
  			int errcode = errno;
  			lib_error(CATGETS(elm_msg_cat, MeSet, MeFileModeNotChanged,
  					  "Failed to change file %s mode (new mode %05o):  %s"),
***************
*** 700,706 ****
  		    }
  			break;
  
! 		    case 0:		    
  			log_config(targetfile);
  			break;
  		    }
--- 729,735 ----
  		    }
  			break;
  
! 		    case syscall_success /* 0 */:		    
  			log_config(targetfile);
  			break;
  		    }
Index: elmME+.2.5.alpha63-cvs/utils/elmmailinglists.c
*** elmME+.2.5.alpha62/utils/elmmailinglists.c	Fri Dec 21 13:21:43 2018
--- elmME+.2.5.alpha63-cvs/utils/elmmailinglists.c	Wed Dec 13 18:55:32 2023
***************
*** 1,7 ****
! static char rcsid[] = "@(#)$Id: elmmailinglists.c,v 2.12 2018/12/21 11:21:43 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.12 $   $State: Exp $
   *
   *  Author: Kari Hurtta  (was hurtta+elm@posti.FMI.FI)
   *      or  Kari Hurtta 
--- 1,7 ----
! static char rcsid[] = "@(#)$Id: elmmailinglists.c,v 2.13 2023/12/13 16:55:32 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.13 $   $State: Exp $
   *
   *  Author: Kari Hurtta  (was hurtta+elm@posti.FMI.FI)
   *      or  Kari Hurtta 
***************
*** 49,55 ****
      init_debugfile("ELMMAILINGLISTS");
  #endif
      
! while ((c = ELM_GETOPT(argc, argv, OPTION_LETTERS)) != EOF) {
  	switch(c) {
  	case 'G':
  	    global++;
--- 49,55 ----
      init_debugfile("ELMMAILINGLISTS");
  #endif
      
!     while ((c = ELM_GETOPT(argc, argv, OPTION_LETTERS)) != EOF) {
  	switch(c) {
  	case 'G':
  	    global++;
Index: elmME+.2.5.alpha63-cvs/utils/elmregister.c
*** elmME+.2.5.alpha62/utils/elmregister.c	Thu Jul 28 18:49:52 2022
--- elmME+.2.5.alpha63-cvs/utils/elmregister.c	Wed Dec 13 18:55:32 2023
***************
*** 1,7 ****
! static char rcsid[] = "@(#)$Id: elmregister.c,v 2.34 2022/06/25 08:06:31 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.34 $   $State: Exp $
   *
   *  Author: Kari Hurtta  
   *                  (was hurtta+elm@posti.FMI.FI, hurtta+elm@ozone.FMI.FI)
--- 1,7 ----
! static char rcsid[] = "@(#)$Id: elmregister.c,v 2.35 2023/12/13 16:55:32 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.35 $   
   *
   *  Author: Kari Hurtta  
   *                  (was hurtta+elm@posti.FMI.FI, hurtta+elm@ozone.FMI.FI)
***************
*** 87,97 ****
  extern int errno;
  #endif
  
! #if defined(BSD_TYPE) && !defined(WEXITSTATUS)
! typedef union wait S__;
! #else
! typedef int        S__;
! #endif
  
  static char  * filelist  = SYSTEM_DEFAULT_FILELIST;
  static const char  * stage_dir = STAGE_DIR;
--- 87,93 ----
  extern int errno;
  #endif
  
! #include "convert_status.h"
  
  static char  * filelist  = SYSTEM_DEFAULT_FILELIST;
  static const char  * stage_dir = STAGE_DIR;
***************
*** 1501,1507 ****
      
      int w;
      S__ status;
! 
      FILE *fd = NULL;
      struct log_entries * last = NULL;
  
--- 1497,1503 ----
      
      int w;
      S__ status;
!     
      FILE *fd = NULL;
      struct log_entries * last = NULL;
  
***************
*** 1714,1724 ****
  	if (w == -1 && errno != EINTR)
  	    break;
  
!     if (w != PID || status != 0) {
  	fprintf(stderr,
! 		"%s: Failed to run %s\n",
  		program_name,argv[x]);
! 	return 1;   /* FAILURE */	
      }
      
      /* NOTE: LI leaked ... */
--- 1710,1738 ----
  	if (w == -1 && errno != EINTR)
  	    break;
  
!     if (w != PID) {
  	fprintf(stderr,
! 		"%s: Failed to run %s -- wait failed\n",
  		program_name,argv[x]);
! 	return 1;   /* FAILURE */
!     } else {
! 	int status_sig;
! 	int status_exit_code = 0;
! 
! 	status_sig = convert_status(status,&status_exit_code);
! 	if (0 != status_sig) {
! 	    fprintf(stderr,
! 		    "%s: Failed to run %s -- signal %d\n",
! 		    program_name,argv[x],status_sig);
! 	    return 1;   /* FAILURE */
! 	} 
! 	
! 	if (0 != status_exit_code) {
! 	    fprintf(stderr,
! 		    "%s: Failed to run %s -- exit status %d\n",
! 		    program_name,argv[x],status_exit_code);
! 	    return 1;   /* FAILURE */	
! 	}
      }
      
      /* NOTE: LI leaked ... */
***************
*** 2337,2347 ****
  	if (w == -1 && errno != EINTR)
  		break;
  
!     if (w != pid || status != 0) {
  	fprintf(stderr,
! 		"%s: Failed to copy %s to %s (with using %s)\n",
  		program_name,src,trg,ELMREGISTER_CP);
! 	exit(1);   /* FAILURE */	
      }
  }
  
--- 2351,2380 ----
  	if (w == -1 && errno != EINTR)
  		break;
  
!     if (w != pid) {
  	fprintf(stderr,
! 		"%s: Failed to copy %s to %s (with using %s) -- wait failed\n",
  		program_name,src,trg,ELMREGISTER_CP);
! 	exit(1);   /* FAILURE */
!     } else {
! 	int status_sig;
! 	int status_exit_code = 0;
! 	
! 	status_sig = convert_status(status,&status_exit_code);
! 	
! 	if (0 != status_sig) {
! 	    fprintf(stderr,
! 		    "%s: Failed to copy %s to %s (with using %s) -- signal %d\n",
! 		    program_name,src,trg,ELMREGISTER_CP, status_sig);
! 	    exit(1);   /* FAILURE */
! 	}
! 	
! 	if (0 != status_exit_code) {
! 	    fprintf(stderr,
! 		    "%s: Failed to copy %s to %s (with using %s) -- exit status %d\n",
! 		    program_name,src,trg,ELMREGISTER_CP,status_exit_code);
! 	    exit(1);   /* FAILURE */	
! 	}
      }
  }
  
***************
*** 4824,4830 ****
  		int w;
  		S__ status;
  
- 
  		for (i = 0; ptr->arg_ptrs[i] && i < MAX_ARGS; i++) {
  
  		    int z;
--- 4857,4862 ----
***************
*** 4974,4985 ****
  			) != pid)
  		    if (w == -1 && errno != EINTR)
  			break;
! 		
! 		if (w != pid || status != 0) {
  		    fprintf(stderr,
! 			    "%s: Failed to run %s\n",
  			    program_name,translated[0]);
! 		    Exit_status = 1;   /* FAILURE */	
  		}
  
  	    fail:
--- 5006,5037 ----
  			) != pid)
  		    if (w == -1 && errno != EINTR)
  			break;
! 
! 		if (w != pid) {
  		    fprintf(stderr,
! 			    "%s: Failed to run %s -- wait failed\n",
  			    program_name,translated[0]);
! 		    Exit_status = 1;   /* FAILURE */		    
! 		} else {
! 		    int status_sig;
! 		    int status_exit_code = 0;
! 
! 		    status_sig = convert_status(status,&status_exit_code);
! 
! 		    if (0 != status_sig) {
! 			fprintf(stderr,
! 				"%s: Failed to run %s -- signal %d\n",
! 				program_name,translated[0],status_sig);
! 			Exit_status = 1;   /* FAILURE */	
! 
! 		    }
! 
! 		    if (0 != status_exit_code) {
! 			fprintf(stderr,
! 				"%s: Failed to run %s -- exit status %d\n",
! 				program_name,translated[0],status_exit_code);
! 			Exit_status = 1;   /* FAILURE */	
! 		    }
  		}
  
  	    fail:
Index: elmME+.2.5.alpha63-cvs/utils/elmtagfilterents.c
*** /tmp/2707-very-long-file-name/NULL-2707-comes-in-here--XXXXXXXXX	Mon Jan  1 21:13:30 2024
--- elmME+.2.5.alpha63-cvs/utils/elmtagfilterents.c	Wed Dec 13 18:55:32 2023
***************
*** 0 ****
--- 1,383 ----
+ static char rcsid[] = "@(#)$Id: elmtagfilterents.c,v 2.1 2023/12/13 16:55:32 hurtta Exp $";
+ 
+ /******************************************************************************
+  *  The Elm (ME+) Mail System  -  $Revision: 2.1 $   $State: Exp $
+  *
+  *  Author: Kari Hurtta 
+  *      or  Kari Hurtta 
+  *****************************************************************************/
+ 
+ #include "def_utils.h"
+ #include "misclib.h"
+ #include "reghelper.h"
+ #include "s_me.h"
+ #include "s_elm.h"
+ #include "mboxlib.h"
+ #include "addrlib.h"
+ #include "melib.h"
+ #include "rc_imp.h"
+ 
+ extern char *optarg;		
+ extern int   optind;		
+ 
+ DEBUG_VAR(Debug,__FILE__,"util");
+ 
+ const char * program_name = "elmtagfilterents";
+ int    register_fd  = -1;
+ char * register_module = NULL;
+ 
+ static char version_buff[NLEN];
+ 
+ static const char OPTION_LETTERS[] = "Gd:cC:r:w:"; 
+ 
+ int main P_((int argc, char *argv[]));
+ int main(argc, argv)
+      int argc;
+      char *argv[];
+ {
+     int err = 0;
+     int global = 0;
+ 
+     char *targetfile = NULL;
+     FILE * commentfile = NULL;
+     int config_merge = 0;
+ 
+     int read_flags = 0;
+     int c;
+ 
+     struct tagfilter_entities_conf * MAP = NULL;
+     charset_t                        cs = NULL;
+     struct editor_propline         * pl = NULL;
+ 
+ #if DEBUG
+     init_debugfile("ELMTAGFILTERENTS");
+ #endif
+ 
+         while ((c = ELM_GETOPT(argc, argv, OPTION_LETTERS)) != EOF) {
+ 	switch(c) {
+ 	case 'G':
+ 	    global++;
+ 	    break;
+ 	case 'd':
+ #if DEBUG
+ 	    set_debugging(optarg);
+ #endif
+ 	    /* Error is printed later */
+ 	    break;
+ 	}
+     }
+     optind = 1;     /* Reset scanning */
+ 
+     locale_init();
+ 
+     REGHELPER_INIT(argv[0]);
+ 
+     read_flags = global ? READ_FLAG_GLOBAL_ONLY : 0;
+     
+     user_init();
+     init_addrlib(read_flags);
+     init_mboxlib(read_flags);
+     init_melib(read_flags);
+     init_defaults(read_flags);
+ 
+     while ((c = ELM_GETOPT(argc, argv, OPTION_LETTERS)) != EOF) {
+ 	switch(c) {
+ 	case 'G':
+ 	    global++;
+ 	    break;
+ 	case 'c':
+ 	    config_merge++;
+ 	    break;
+ 
+ 	case 'C':
+ 	    if (0 != access(optarg,READ_ACCESS)) {
+ 		int errcode = errno;
+ 		lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotReadable,
+ 				  "File %.50s is not readable: %s"),
+ 			  optarg, strerror(errcode));
+ 		err++;
+ 		goto fail;
+ 	    }
+ 
+ 	    commentfile = fopen(optarg,"r");
+ 	    if (!commentfile) {
+ 		int errcode = errno;
+ 		lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotReadable,
+ 				  "File %.50s is not readable: %s"),
+ 			  optarg, strerror(errcode));
+ 		err++;
+ 		goto fail;
+ 		
+ 	    }
+ 	    break;
+ 
+ 	    	case 'd' : 
+ #if DEBUG
+ 	    set_debugging(optarg);	 
+ #else
+ 	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmArgsIngoringDebug,
+ 			      "Warning: system created without debugging enabled - request ignored\n"));
+ #endif
+ 	    break;
+ 
+ 	case 'r':
+ 	    set_user_rc_location(optarg); 
+ 	    break;
+ 
+ 	case 'w' : 
+ 	    targetfile = optarg;
+ 	    if (0 != access(targetfile,WRITE_ACCESS)) {
+ 		int errcode = errno;
+ 		
+ 		if (errcode != ENOENT) {
+ 		    lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotWriteable,
+ 				      "File %.50s is not writeable: %s"),
+ 			      targetfile, strerror(errcode));
+ 		    err++;
+ 		    goto fail;
+ 		}
+ 	    }
+ 	    break;
+ 	case '?':
+ 	    err = 1;
+ 	    goto fail;
+ 	}
+     }
+ 
+     elm_sfprintf(version_buff, sizeof version_buff,
+ 		 FRM("%s PL%s"), VERSION, PATCHLEVEL);
+ 
+ #ifdef DEBUG
+     { 
+ 	int d UNUSED_VAROK = panic_dprint("\n\
+ ======================================================\n\
+ Debug output of the ELMTAGFILTERENTS program (version %s).\n",
+ 			     version_buff);
+ 
+ #if 0	
+ 	if (d >= 50) {
+ 	    panic_dprint("WARNING: Edit manually out sensitive information from that file!\n");
+     
+ 	    lower_prompt("WARNING: Debug file may include passwords -- edit it!");
+ 	    sleep(5+sleepmsg);	    
+ 	}
+ #endif
+     }
+ #endif
+ 
+     if (!global)
+ 	read_rc_file(read_flags);
+     else
+ 	post_init_check(read_flags);
+ 
+     if (optind < argc) {
+ 	int errcount = 0;
+ 	int need_rewrite = 0;
+ 
+ 	MAP = parse_tagfilter_entities(argv[optind],&errcount,&cs,&pl,
+ 				       global ? SYSTEM_RC : LOCAL_RC,
+ 				       & need_rewrite);
+ 
+ 	if (!MAP || errcount) {
+ 	    err = 1;
+ 	    goto fail;
+ 	}
+     }
+     
+     if (config_merge) {
+ 	int errcount = 0;
+ 
+ 	if (!MAP) {
+ 	    lib_error(CATGETS(elm_msg_cat, MeSet, MeConfigMergeMap,
+ 			      "Config merge (-c) requires map as argument"));
+ 	    err++;
+ 	    goto fail;
+ 	}
+ 
+ 	if (targetfile) {
+ 	    lib_error(CATGETS(elm_msg_cat, MeSet, MeConfigMergeNoW,
+ 			      "Config merge (-c) Can not used with -w"));
+ 	    err++;
+ 	    goto fail;
+ 	}
+ 
+ 	if (pl)
+ 	    free_editor_propline(&pl);
+ 
+ 
+ 	if (global) {
+ 	    if (!change_tagfilter_entities(& system_tagfilter_entities_conf,
+ 					   MAP,SYSTEM_RC,
+ 					   system_tagfilter_entfile,&errcount)) {
+ 		err++;
+ 	    }
+ 		
+ 	    free_tagfilter_entities_conf(&MAP);
+ 
+ 	    MAP        =  system_tagfilter_entities_conf;
+ 	    targetfile =  system_tagfilter_entfile;
+ 	    cs         =  system_tagfilter_entities_cs;
+ 	    pl         =  system_tagfilter_entities_pl;
+ 
+ 	} else {
+ 	    if (!change_tagfilter_entities(&  user_tagfilter_entities_conf,
+ 					   MAP, LOCAL_RC,
+ 					   user_tagfilter_entfile,&errcount
+ 					   )) {
+ 		err++;
+ 	    }
+ 	    
+ 	    free_tagfilter_entities_conf(&MAP);
+ 
+ 	    MAP        = user_tagfilter_entities_conf;
+ 	    targetfile = user_tagfilter_entfile;
+ 	    cs         = user_tagfilter_entities_cs;
+ 	    pl         = user_tagfilter_entities_pl;	    
+ 	}
+ 
+ 	if (errcount) {
+ 	    err = 1;
+ 	}
+ 
+ 	if (0 != access(targetfile,WRITE_ACCESS)) {
+ 	    int errcode = errno;
+ 	    
+ 	    if (errcode != ENOENT) {
+ 		lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotWriteable,
+ 				  "File %.50s is not writeable: %s"),
+ 			  targetfile, strerror(errcode));
+ 		err++;
+ 		goto fail;
+ 	    }
+ 	}
+     }
+ 
+ 
+     if (!MAP) {
+ 	if (global) {
+ 	    MAP = system_tagfilter_entities_conf;
+ 	    cs  = system_tagfilter_entities_cs;
+ 	    pl  = system_tagfilter_entities_pl;
+ 	} else {
+ 	    MAP = user_tagfilter_entities_conf;
+ 	    cs  = user_tagfilter_entities_cs;
+ 	    pl  = user_tagfilter_entities_pl;
+ 	}
+     }
+ 
+   
+     if (targetfile) {
+ 	char * tmp = elm_message(FRM("%s.N"),targetfile);
+ 	int errcode = can_open(tmp,"w");
+ 	FILE *f;
+ 	
+ 	if (errcode) {
+ 	    lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotWriteable,
+ 			      "File %.50s is not writeable: %s"),
+ 		      tmp, strerror(errcode));
+ 	    
+ 	    err++;
+ 	    goto fail_dump;
+ 	}
+ 	
+ 	f = fopen(tmp,"w");
+ 	if (!f) {
+ 	    errcode = errno;
+ 	    lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotWriteable,
+ 			      "File %.50s is not writeable: %s"),
+ 		      tmp, strerror(errcode));
+ 	    
+ 	    err++;
+ 	    goto fail_dump;
+ 	}
+ 
+ 	if (! dump_tagfilter_entities(f,MAP,commentfile,
+ 				      "ELMTAGFILTERENTS",version_buff,
+ 				      cs,pl,
+ 				      global ? SYSTEM_RC : LOCAL_RC,
+ 				      &errcode)) {
+ 	    if (errcode)
+ 		lib_error(CATGETS(elm_msg_cat, MeSet, MeConfFileWriteFailedC,
+ 				  "Failed to write config file %.50s: %s"),
+ 			  tmp,strerror(errcode));
+ 	    else
+ 		lib_error(CATGETS(elm_msg_cat, MeSet, MeConfFileWriteFailed,
+ 				  "Failed to write config file %.50s"),
+ 			  tmp);
+ 	    fclose(f);
+ 	    
+ 	    err++;
+ 	    goto fail_dump;
+ 	}
+ 				      
+ 	if (EOF == fclose(f)) {
+ 	    errcode = errno;
+ 	    lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotWriteable,
+ 			      "File %.50s is not writeable: %s"),
+ 		      tmp, strerror(errcode));
+ 	    
+ 	    err++;
+ 	    goto fail_dump;
+ 	}
+ 	if (0 != rename(tmp,targetfile)) {
+ 	    errcode = errno;
+ 	    lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotRenamed,
+ 			      "Failed to rename temporary file to %.50s: %.30s"),
+ 		      targetfile, strerror(errcode));
+ 	    
+ 	    err++;
+ 	    goto fail_dump;
+ 	}
+ 	log_config(targetfile);
+ 
+     fail_dump:
+ 	
+ 	free(tmp);
+ 
+     } else {
+ 	int errcode = 0;
+ 	
+ 	if (! dump_tagfilter_entities(stdout,MAP,commentfile,
+ 				      "ELMTAGFILTERENTS",version_buff,
+ 				      cs,pl,
+ 				      global ? SYSTEM_RC : LOCAL_RC,
+ 				      &errcode)) {
+ 
+ 	    if (errcode)
+ 		lib_error(CATGETS(elm_msg_cat, MeSet, MeConfPrintFailedC,
+ 				  "Failed to print config: %s"),
+ 			  strerror(errcode));
+ 	    else
+ 		lib_error(CATGETS(elm_msg_cat, MeSet, MeConfPrintFailed,
+ 				  "Failed to print config"));
+ 
+ 	    err++;
+ 	    goto fail;
+ 	}			  	    
+     }
+     
+  fail:
+     if (commentfile)
+ 	fclose(commentfile);
+ 
+     if (MAP &&
+ 	MAP != system_tagfilter_entities_conf &&
+ 	MAP != user_tagfilter_entities_conf)
+ 	free_tagfilter_entities_conf(&MAP);	
+ 
+     if (err)
+       lib_error(CATGETS(elm_msg_cat, MeSet, MeProgFailed,
+ 			"%s failed; exit code=%d"),
+ 		argv[0],err);
+     
+     return err;
+ }
+ 
+ /*
+  * Local Variables:
+  *  mode:c
+  *  c-basic-offset:4
+  *  buffer-file-coding-system: iso-8859-1
+  * End:
+  */
+ 
Index: elmME+.2.5.alpha63-cvs/utils/elmterminal.c
*** elmME+.2.5.alpha62/utils/elmterminal.c	Fri Dec 21 13:21:43 2018
--- elmME+.2.5.alpha63-cvs/utils/elmterminal.c	Wed Dec 13 18:55:32 2023
***************
*** 1,7 ****
! static char rcsid[] = "@(#)$Id: elmterminal.c,v 2.9 2018/12/21 11:21:43 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.9 $   $State: Exp $
   *
   *  Author: Kari Hurtta  
   *                  (was hurtta+elm@posti.FMI.FI, hurtta+elm@ozone.FMI.FI)
--- 1,7 ----
! static char rcsid[] = "@(#)$Id: elmterminal.c,v 2.10 2023/12/13 16:55:32 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.10 $   $State: Exp $
   *
   *  Author: Kari Hurtta  
   *                  (was hurtta+elm@posti.FMI.FI, hurtta+elm@ozone.FMI.FI)
***************
*** 153,171 ****
      }
  #endif
  
!   if (!global)
!       read_rc_file(read_flags);
!   else
!       post_init_check(read_flags);
! 
!   if (optind < argc) {
!       int errcount = 0;
!       MAP = load_terminal_map(argv[optind],&errcount);
!       if (!MAP || errcount) {
! 	err = 1;
! 	goto fail;
!       }
!   }
  
      if (config_merge) {
  
--- 153,171 ----
      }
  #endif
  
!     if (!global)
! 	read_rc_file(read_flags);
!     else
! 	post_init_check(read_flags);
!     
!     if (optind < argc) {
! 	int errcount = 0;
! 	MAP = load_terminal_map(argv[optind],&errcount);
! 	if (!MAP || errcount) {
! 	    err = 1;
! 	    goto fail;
! 	}
!     }
  
      if (config_merge) {
  
***************
*** 211,287 ****
  	}
      }
  	  
!   if (!MAP) {
!       if (global)
! 	  MAP = system_terminal_map;
!       else
! 	  MAP = user_terminal_map;
!   }
! 
!   if (targetfile) {
!       char * tmp = elm_message(FRM("%s.N"),targetfile);
!       int errcode = can_open(tmp,"w");
!       FILE *f;
!       
!       if (errcode) {
! 	  lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotWriteable,
! 			    "File %.50s is not writeable: %s"),
! 		    tmp, strerror(errcode));
! 	  
! 	  err++;
! 	  free(tmp);
! 	  goto fail;
!       }
!       f = fopen(tmp,"w");
!       if (!f) {
! 	  int errcode = errno;
! 	  lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotWriteable,
! 			    "File %.50s is not writeable: %s"),
! 		    tmp, strerror(errcode));
! 	  
! 	  err++;
! 	  free(tmp);
! 	  goto fail;
!       }
! 
!       dump_terminal_map(f,MAP,commentfile,"ELMTERMINAL",version_buff);
! 
!       if (EOF == fclose(f)) {
! 	  int errcode = errno;
! 	  lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotWriteable,
! 			    "File %.50s is not writeable: %s"),
! 		    tmp, strerror(errcode));
! 	  
! 	  err++;
! 	  free(tmp);
! 	  goto fail;
!       }
!       if (0 != rename(tmp,targetfile)) {
! 	  int errcode = errno;
! 	  lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotRenamed,
! 			    "Failed to rename temporary file to %.50s: %.30s"),
! 		    targetfile, strerror(errcode));
! 	  
! 	  err++;
! 	  free(tmp);
! 	  goto fail;
!       }
!       log_config(targetfile);
!       free(tmp);
  
!   } else
!       dump_terminal_map(stdout,MAP,commentfile,"ELMTERMINAL",version_buff);
      
   fail:
!   if (commentfile)
!       fclose(commentfile);
! 
!   if (MAP &&
!       MAP != system_terminal_map &&
!       MAP != user_terminal_map)
!       free_terminal_map(&MAP);
! 
!   if (err)
  	lib_error(CATGETS(elm_msg_cat, MeSet, MeProgFailed,
  			  "%s failed; exit code=%d"),
  		  argv[0],err);
--- 211,287 ----
  	}
      }
  	  
!     if (!MAP) {
! 	if (global)
! 	    MAP = system_terminal_map;
! 	else
! 	    MAP = user_terminal_map;
!     }
  
!     if (targetfile) {
! 	char * tmp = elm_message(FRM("%s.N"),targetfile);
! 	int errcode = can_open(tmp,"w");
! 	FILE *f;
! 	
! 	if (errcode) {
! 	    lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotWriteable,
! 			      "File %.50s is not writeable: %s"),
! 		      tmp, strerror(errcode));
! 	    
! 	    err++;
! 	    free(tmp);
! 	    goto fail;
! 	}
! 	f = fopen(tmp,"w");
! 	if (!f) {
! 	    int errcode = errno;
! 	    lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotWriteable,
! 			      "File %.50s is not writeable: %s"),
! 		      tmp, strerror(errcode));
! 	    
! 	    err++;
! 	    free(tmp);
! 	    goto fail;
! 	}
! 	
! 	dump_terminal_map(f,MAP,commentfile,"ELMTERMINAL",version_buff);
! 	
! 	if (EOF == fclose(f)) {
! 	    int errcode = errno;
! 	    lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotWriteable,
! 			      "File %.50s is not writeable: %s"),
! 		      tmp, strerror(errcode));
! 	    
! 	    err++;
! 	    free(tmp);
! 	    goto fail;
! 	}
! 	if (0 != rename(tmp,targetfile)) {
! 	    int errcode = errno;
! 	    lib_error(CATGETS(elm_msg_cat, MeSet, MeFileNotRenamed,
! 			      "Failed to rename temporary file to %.50s: %.30s"),
! 		      targetfile, strerror(errcode));
! 	    
! 	    err++;
! 	    free(tmp);
! 	    goto fail;
! 	}
! 	log_config(targetfile);
! 	free(tmp);
! 	
!     } else
! 	dump_terminal_map(stdout,MAP,commentfile,"ELMTERMINAL",version_buff);
      
   fail:
!     if (commentfile)
! 	fclose(commentfile);
!     
!     if (MAP &&
! 	MAP != system_terminal_map &&
! 	MAP != user_terminal_map)
! 	free_terminal_map(&MAP);
!     
!     if (err)
  	lib_error(CATGETS(elm_msg_cat, MeSet, MeProgFailed,
  			  "%s failed; exit code=%d"),
  		  argv[0],err);
Index: elmME+.2.5.alpha63-cvs/utils/readmsg/readmsg.c
*** elmME+.2.5.alpha62/utils/readmsg/readmsg.c	Sun Dec  4 10:38:37 2022
--- elmME+.2.5.alpha63-cvs/utils/readmsg/readmsg.c	Wed Dec 13 18:55:33 2023
***************
*** 1,7 ****
! static char rcsid[] = "@(#)$Id: readmsg.c,v 2.21 2022/11/02 16:26:29 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.21 $   $State: Exp $
   *
   *  Modified by: Kari Hurtta  
   *                       (was hurtta+elm@posti.FMI.FI, 
--- 1,7 ----
! static char rcsid[] = "@(#)$Id: readmsg.c,v 2.22 2023/12/13 16:55:33 hurtta Exp $";
  
  /******************************************************************************
!  *  The Elm (ME+) Mail System  -  $Revision: 2.22 $   $State: Exp $
   *
   *  Modified by: Kari Hurtta  
   *                       (was hurtta+elm@posti.FMI.FI, 
***************
*** 776,781 ****
--- 776,782 ----
      user_init();
      init_addrlib(read_flags);
      init_mboxlib(read_flags);
+     init_melib(read_flags);
      init_defaults(read_flags);
  
      signal(SIGPIPE, pipe_signal);		

-- 
/ Kari Hurtta