[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xterm: Changes to 'upstream-unstable'



 MANIFEST                 |    2 
 NEWS                     |  161 +-------
 charproc.c               |  185 ++++++++-
 ctlseqs.ms               |   50 ++
 ctlseqs.txt              |   40 +-
 fontutils.c              |  169 ++++++---
 fontutils.h              |    9 
 graphics.c               |   18 
 graphics_regis.c         |  870 +++++++++++++++++++++++++++++++----------------
 main.c                   |    2 
 misc.c                   |    4 
 package/debian/changelog |   12 
 package/freebsd/Makefile |    2 
 package/xterm.spec       |    4 
 print.c                  |    4 
 ptydata.c                |    6 
 trace.c                  |    4 
 util.c                   |   32 -
 version.h                |    6 
 wcwidth.c                |  628 ++++++++++++++++++++++++++-------
 wcwidth.h                |   33 +
 xstrings.c               |   20 -
 xterm.log.html           |  148 +++++++
 xterm.man                |    7 
 24 files changed, 1696 insertions(+), 720 deletions(-)

New commits:
commit 44287d929208662c177f7b123b7af447669252f9
Author: Sven Joachim <svenjoac@gmx.de>
Date:   Thu Jun 22 19:11:05 2017 +0200

    Imported Upstream version 330

diff --git a/MANIFEST b/MANIFEST
index e3ef41e..d4d4430 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,4 +1,4 @@
-MANIFEST for xterm-329, version xterm-329
+MANIFEST for xterm-330, version xterm-330
 --------------------------------------------------------------------------------
 MANIFEST                        this file
 256colres.h                     resource-definitions for 256-color mode
diff --git a/NEWS b/NEWS
index 6bdc013..7022694 100644
--- a/NEWS
+++ b/NEWS
@@ -1,44 +1,38 @@
 The NEWS file was generated from xterm.log.html, which serves as the changelog
 for xterm.
 --------------------------------------------------------------------------------
-                            Patch #329 - 2017/06/12
+                            Patch #330 - 2017/06/20
 
-     * add  control  sequences  for  reading  the Sixel and ReGIS graphics
-       sizes (suggested by Ben Wong).
-     * add  a  workaround  for  wcwidth  returning -1 for characters which
-       should have been printable (FreeBSD #219800).
-     * fix a bug in font initialization from patch #328 (FreeBSD #219800).
-     * fix  a special case in HideCursor which assigned a bold font to the
-       slot  used  for  normal  font  in changes for italics in patch #307
-       (Debian #858304).
      * updates for ReGIS (Ross Combs):
-          + Strings  specified  with  no  command  are used as "comments".
-            Print these in the log when tracing.
-          + Catch  attempts  to use "alternate display" mode (AKA "blink")
-            from the GIGI, but do not implement it.
-          + The  T(M)  command  should only multiply the height by 10, not
-            20.
-          + Make  the  S(E)  command reset more state than just the screen
-            contents.
-          + Remove two rotation variables which were only being printed.
-          + Numerous minor fixes and comment updates in the R command.
-          + Unknown R command option names trigger an empty response.
-          + Fix  the  output  position after printing rotated text (it was
-            missing the the sign before).
-          + Fix  the  position  change  with pixelvectors and rotated text
-            (the rotation transform was not being applied).
-          + Update  the TODO list and remove a verification FIXME (slanted
-            text positioning is correct as is).
-          + Emulate  the  approximately  1.4x  enlargement  for text which
-            isn't rotated at right angles.
-          + Only  update the color planes specified in the plane mask (the
-            W command's F option).
-     * fix  a  bug  introduced by the changes to font information in patch
-       #328.   When  processing  the  "checkfont"  option  of  the  locale
-       resource,  the  program  referred  to the request data, to an array
-       which  was  only  allocated  in  the new/result widget (report by H
-       Merijn Brand).
-     * fix  a  missing assignment initialization to make the utf8 resource
-       control  whether  escape sequences to enable/disable UTF-8 mode are
-       allowed.
+          + remove redundant text command error check which broke T(B) and
+            T(E).
+          + retain  the  loading  alphabet  number across multiple “L”
+            commands.
+          + add S(T) delay handler.
+          + fix some color handling error messages.
+          + add stubbed-out macrograph handling.
+          + use  fragment_remaining()  and  fragment_consumed() instead of
+            manually checking position / length in various places.
+          + rename  some  local  variables  in  string  /  extent / option
+            parsing
+          + wrap some long lines.
+          + move macrograph command handling out of the top-level.
+     * add a summary of the italic fonts loaded to -report-fonts option.
+     * modify the font-lookup for italics to allow for “-i-” if no match
+       is found with slant “-o-” (prompted by patch by Ben Wong).
+     * change  default values for mkSamplePass and mkSampleSize to reflect
+       generally-improved  locale  support  in  various  operating systems
+       (FreeBSD #219800).
+     * modify  wcwidth.c to return -1 for non-Unicode values, and adjust a
+       couple  of blocks to better match assumptions about ambiguous-width
+       characters  in  other  implementations.  Also  modify  wcwidth.c to
+       support  configurable soft-hyphen, so there is no drawback to using
+       this version rather than a system wcwidth.
+     * amend  change  made  in  patch #328 for cursor-visibility to handle
+       case  where  an  application  is  updating  the reverse-video state
+       (FreeBSD #219800).
+     * update  tables  of  combining  and  ambiguous-width  characters  in
+       wcwidth.c based on Unicode 10.0.0.
+     * build-fix         for        --enable-sixel-graphics        without
+       --enable-regis-graphics (reports by Sven Joachim, FreeBSD #219945).
 
diff --git a/charproc.c b/charproc.c
index 8cf2285..31cd8bc 100644
--- a/charproc.c
+++ b/charproc.c
@@ -1,4 +1,4 @@
-/* $XTermId: charproc.c,v 1.1487 2017/06/12 01:01:20 tom Exp $ */
+/* $XTermId: charproc.c,v 1.1492 2017/06/19 08:34:54 tom Exp $ */
 
 /*
  * Copyright 1999-2016,2017 by Thomas E. Dickey
@@ -746,8 +746,8 @@ static XtResource xterm_resources[] =
     Bres(XtNvt100Graphics, XtCVT100Graphics, screen.vt100_graphics, True),
     Bres(XtNwideChars, XtCWideChars, screen.wide_chars, False),
     Ires(XtNcombiningChars, XtCCombiningChars, screen.max_combining, 2),
-    Ires(XtNmkSamplePass, XtCMkSamplePass, misc.mk_samplepass, 256),
-    Ires(XtNmkSampleSize, XtCMkSampleSize, misc.mk_samplesize, 1024),
+    Ires(XtNmkSamplePass, XtCMkSamplePass, misc.mk_samplepass, 655),
+    Ires(XtNmkSampleSize, XtCMkSampleSize, misc.mk_samplesize, 65536),
     Sres(XtNutf8, XtCUtf8, screen.utf8_mode_s, "default"),
     Sres(XtNutf8Fonts, XtCUtf8Fonts, screen.utf8_fonts_s, "default"),
     Sres(XtNwideBoldFont, XtCWideBoldFont, misc.default_font.f_wb, DEFWIDEBOLDFONT),
@@ -2874,6 +2874,7 @@ doparsing(XtermWidget xw, unsigned c, struct ParseState *sp)
 			if_OPT_ISO_COLORS(screen, {
 			    break;
 			});
+			/* FALLTHRU */
 		    default:
 			TRACE(("...unexpected subparameter in SGR\n"));
 			op = 9999;
@@ -3696,6 +3697,7 @@ doparsing(XtermWidget xw, unsigned c, struct ParseState *sp)
 			    break;
 			}
 			break;
+# if OPT_REGIS_GRAPHICS
 		    case 3:	/* ReGIS geometry */
 			switch (GetParam(1)) {
 			case 1:	/* read */
@@ -3717,6 +3719,7 @@ doparsing(XtermWidget xw, unsigned c, struct ParseState *sp)
 			    break;
 			}
 			break;
+#endif
 		    default:
 			TRACE(("DATA_ERROR: CASE_GRAPHICS_ATTRIBUTES request with unknown item parameter: %d\n",
 			       GetParam(0)));
@@ -8559,6 +8562,7 @@ VTInitialize(Widget wrequest,
 	TRACE(("setting utf8_mode to 0\n"));
 	screen->utf8_mode = uFalse;
     }
+    mk_wcwidth_init(screen->utf8_mode);
     TRACE(("initialized UTF-8 mode to %d\n", screen->utf8_mode));
 
 #if OPT_MINI_LUIT
@@ -10352,10 +10356,16 @@ ShowCursor(void)
 		}
 	    }
 	}
-	if (T_COLOR(screen, TEXT_CURSOR) == bg_pix ||
-	    T_COLOR(screen, TEXT_CURSOR) == (reversed
-					     ? xw->dft_background
-					     : xw->dft_foreground)) {
+
+#define CUR_XX T_COLOR(screen, TEXT_CURSOR)
+#define CGS_FG getCgsFore(xw, currentWin, getCgsGC(xw, currentWin, currentCgs))
+#define CGS_BG getCgsBack(xw, currentWin, getCgsGC(xw, currentWin, currentCgs))
+
+#define FIX_311 (CUR_XX == (reversed ? xw->dft_background : xw->dft_foreground))
+#define FIX_328 (CUR_XX == bg_pix)
+#define FIX_330 (FIX_328 && reversed && in_selection)
+
+	if (FIX_330 || FIX_311) {
 	    setCgsBack(xw, currentWin, currentCgs, fg_pix);
 	}
 	setCgsFore(xw, currentWin, currentCgs, bg_pix);
@@ -10432,10 +10442,7 @@ ShowCursor(void)
 	     * Set up a new request.
 	     */
 	    if (filled) {
-		if (T_COLOR(screen, TEXT_CURSOR) == bg_pix ||
-		    T_COLOR(screen, TEXT_CURSOR) == (reversed
-						     ? xw->dft_background
-						     : xw->dft_foreground)) {
+		if (FIX_330 || FIX_311) {
 		    setCgsBack(xw, currentWin, currentCgs, fg_pix);
 		}
 		setCgsFore(xw, currentWin, currentCgs, bg_pix);
@@ -10571,7 +10578,7 @@ HideCursor(void)
     int cursor_col;
     CLineData *ld = 0;
 #if OPT_WIDE_ATTRS
-    CgsEnum which_Cgs = gcMAX;
+    int which_Cgs = gcMAX;
     unsigned attr_flags;
     int which_font = fNorm;
 #endif
@@ -10663,7 +10670,7 @@ HideCursor(void)
 	which_Cgs = reverseCgs(xw, attr_flags, in_selection, which_font);
 	if (which_Cgs != gcMAX) {
 	    setCgsFont(xw, WhichVWin(screen),
-		       which_Cgs,
+		       (CgsEnum) which_Cgs,
 		       (((attr_flags & ATR_ITALIC) && UseItalicFont(screen))
 			? getItalicFont(screen, which_font)
 			: getNormalFont(screen, which_font)));
@@ -10707,7 +10714,7 @@ HideCursor(void)
 #if OPT_WIDE_ATTRS
     if (which_Cgs != gcMAX) {
 	setCgsFont(xw, WhichVWin(screen),
-		   which_Cgs,
+		   (CgsEnum) which_Cgs,
 		   (((xw->flags & ATR_ITALIC) && UseItalicFont(screen))
 		    ? getItalicFont(screen, which_font)
 		    : getNormalFont(screen, which_font)));
diff --git a/fontutils.c b/fontutils.c
index 6f80c84..6db575e 100644
--- a/fontutils.c
+++ b/fontutils.c
@@ -1,4 +1,4 @@
-/* $XTermId: fontutils.c,v 1.528 2017/06/08 23:53:31 tom Exp $ */
+/* $XTermId: fontutils.c,v 1.531 2017/06/20 09:10:19 tom Exp $ */
 
 /*
  * Copyright 1998-2016,2017 by Thomas E. Dickey
@@ -460,11 +460,58 @@ bold_font_name(FontNameProperties *props, int use_average_width)
 
 #if OPT_WIDE_ATTRS
 static char *
-italic_font_name(FontNameProperties *props, int use_average_width)
+italic_font_name(FontNameProperties *props, const char *slant)
 {
     FontNameProperties myprops = *props;
-    myprops.slant = "o";
-    return derive_font_name(&myprops, props->weight, use_average_width, props->end);
+    myprops.slant = slant;
+    return derive_font_name(&myprops, props->weight, myprops.average_width, props->end);
+}
+
+static Boolean
+open_italic_font(XtermWidget xw, int n, FontNameProperties *fp, XTermFonts * data)
+{
+    static const char *slant[] =
+    {
+	"o",
+	"i"
+    };
+    char *name;
+    Cardinal pass;
+    Boolean result = False;
+
+    for (pass = 0; pass < XtNumber(slant); ++pass) {
+	if ((name = italic_font_name(fp, slant[pass])) != 0) {
+	    TRACE(("open_italic_font %s %s\n",
+		   whichFontEnum((VTFontEnum) n), name));
+	    if (xtermOpenFont(xw, name, data, False)) {
+		result = (data->fs != 0);
+#if OPT_REPORT_FONTS
+		if (resource.reportFonts) {
+		    printf("opened italic version of %s:\n\t%s\n",
+			   whichFontEnum(n),
+			   name);
+		}
+#endif
+	    }
+	    free(name);
+	    if (result)
+		break;
+	}
+    }
+#if OPT_TRACE
+    if (result) {
+	XFontStruct *fs = data->fs;
+	if (fs != 0) {
+	    TRACE(("...actual size %dx%d (ascent %d, descent %d)\n",
+		   fs->ascent +
+		   fs->descent,
+		   fs->max_bounds.width,
+		   fs->ascent,
+		   fs->descent));
+	}
+    }
+#endif
+    return result;
 }
 #endif
 
@@ -1062,7 +1109,7 @@ reportVTFontInfo(XtermWidget xw, int fontnum)
 }
 #endif
 
-typedef XTermFonts *(*MyGetFont) (TScreen *, VTFontEnum);
+typedef XTermFonts *(*MyGetFont) (TScreen *, int);
 
 void
 xtermUpdateFontGCs(XtermWidget xw, Bool italic)
@@ -1645,45 +1692,44 @@ xtermLoadItalics(XtermWidget xw)
 
     if (!screen->ifnts_ok) {
 	int n;
+	FontNameProperties *fp;
+	XTermFonts *data;
 
 	screen->ifnts_ok = True;
 	for (n = 0; n < fMAX; ++n) {
-	    FontNameProperties *fp;
-	    XTermFonts *data = getItalicFont(screen, n);
+	    switch (n) {
+	    case fNorm:
+		/* FALLTHRU */
+	    case fBold:
+		/* FALLTHRU */
+#if OPT_WIDE_CHARS
+	    case fWide:
+		/* FALLTHRU */
+	    case fWBold:
+#endif
+		/* FALLTHRU */
+		data = getItalicFont(screen, n);
 
-	    /*
-	     * FIXME - need to handle font-leaks
-	     */
-	    data->fs = 0;
-	    if (getNormalFont(screen, n)->fs != 0 &&
-		(fp = get_font_name_props(screen->display,
-					  getNormalFont(screen, n)->fs,
-					  0)) != 0) {
-		char *name;
-
-		if ((name = italic_font_name(fp, fp->average_width)) != 0) {
-		    TRACE(("xtermLoadItalics %s %s\n", whichFontEnum(n), name));
-		    if (xtermOpenFont(xw, name, data, False)) {
-#if OPT_TRACE
-			XFontStruct *fs = data->fs;
-			if (fs != 0) {
-			    TRACE(("...actual size %dx%d (ascent %d, descent %d)\n",
-				   fs->ascent +
-				   fs->descent,
-				   fs->max_bounds.width,
-				   fs->ascent,
-				   fs->descent));
+		/*
+		 * FIXME - need to handle font-leaks
+		 */
+		data->fs = 0;
+		if (getNormalFont(screen, n)->fs != 0 &&
+		    (fp = get_font_name_props(screen->display,
+					      getNormalFont(screen, n)->fs,
+					      0)) != 0) {
+		    if (!open_italic_font(xw, n, fp, data)) {
+			if (n > 0) {
+			    xtermCopyFontInfo(data,
+					      getItalicFont(screen, n - 1));
+			} else {
+			    xtermOpenFont(xw,
+					  getNormalFont(screen, n)->fn,
+					  data, False);
 			}
-#endif
-		    } else if (n > 0) {
-			xtermCopyFontInfo(data, getItalicFont(screen, n - 1));
-		    } else {
-			xtermOpenFont(xw,
-				      getNormalFont(screen, n)->fn,
-				      data, False);
 		    }
-		    free(name);
 		}
+		break;
 	    }
 	}
     }
@@ -2148,6 +2194,7 @@ xtermSetCursorBox(TScreen *screen)
 
 #if OPT_RENDERFONT
 
+#if OPT_REPORT_FONTS
 static FcChar32
 xtermXftFirstChar(XftFont *xft)
 {
@@ -2192,8 +2239,9 @@ xtermXftLastChar(XftFont *xft)
 	    break;
 	}
     }
-    return (long) last;
+    return (FcChar32) last;
 }
+#endif /* OPT_REPORT_FONTS */
 
 #if OPT_TRACE > 1
 static void
@@ -2264,6 +2312,7 @@ checkXft(XtermWidget xw, XTermXftFonts *data, XftFont *xft)
     data->map.mixed = (data->map.max_width >= (data->map.min_width + 1));
 }
 
+#if OPT_REPORT_FONTS
 static void
 reportXftFonts(XtermWidget xw,
 	       XftFont *fp,
@@ -2300,6 +2349,9 @@ reportXftFonts(XtermWidget xw,
 	}
     }
 }
+#else
+#define reportXftFonts(xw, result, name, tag, match)	/* empty */
+#endif /* OPT_REPORT_FONTS */
 
 static XftFont *
 xtermOpenXft(XtermWidget xw, const char *name, XftPattern *pat, const char *tag)
@@ -3695,8 +3747,8 @@ HandleSetFont(Widget w GCC_UNUSED,
 		/* FALLTHRU */
 	    case 4:
 		fonts.f_w = x_strdup(params[3]);
-		/* FALLTHRU */
 #endif
+		/* FALLTHRU */
 	    case 3:
 		fonts.f_b = x_strdup(params[2]);
 		/* FALLTHRU */
@@ -4072,7 +4124,7 @@ initFontList(XtermWidget xw,
 
     TRACE(("initFontList(%s)\n", name));
     for (which = 0; which < fMAX; ++which) {
-	save2FontList(xw, name, target, which, "", ttf);
+	save2FontList(xw, name, target, (VTFontEnum) which, "", ttf);
     }
 }
 
@@ -4188,10 +4240,10 @@ freeFontLists(VTFontList * lists)
  * XXX make this allocate the font on demand.
  */
 XTermFonts *
-getNormalFont(TScreen *screen, VTFontEnum which)
+getNormalFont(TScreen *screen, int which)
 {
     XTermFonts *result = 0;
-    if ((int) which >= 0 && which < fMAX)
+    if (which >= 0 && which < fMAX)
 	result = &(screen->fnts[which]);
     return result;
 }
@@ -4209,11 +4261,11 @@ getDoubleFont(TScreen *screen, int which)
 
 #if OPT_WIDE_ATTRS || OPT_RENDERWIDE
 XTermFonts *
-getItalicFont(TScreen *screen, VTFontEnum which)
+getItalicFont(TScreen *screen, int which)
 {
     XTermFonts *result = 0;
 #if OPT_WIDE_ATTRS
-    if ((int) which >= 0 && which < fMAX)
+    if (which >= 0 && which < fMAX)
 	result = &(screen->ifnts[which]);
 #else
     (void) screen;
@@ -4229,12 +4281,12 @@ getItalicFont(TScreen *screen, VTFontEnum which)
  * XXX make this allocate the font on demand.
  */
 XTermXftFonts *
-getMyXftFont(XtermWidget xw, VTFontEnum which, int fontnum)
+getMyXftFont(XtermWidget xw, int which, int fontnum)
 {
     TScreen *screen = TScreenOf(xw);
     XTermXftFonts *result = 0;
     if (fontnum >= 0 && fontnum < NMENUFONTS) {
-	switch (which) {
+	switch ((VTFontEnum) which) {
 	case fNorm:
 	    result = &(screen->renderFontNorm[fontnum]);
 	    break;
diff --git a/fontutils.h b/fontutils.h
index fac6759..188cca5 100644
--- a/fontutils.h
+++ b/fontutils.h
@@ -1,4 +1,4 @@
-/* $XTermId: fontutils.h,v 1.118 2017/06/08 23:52:08 tom Exp $ */
+/* $XTermId: fontutils.h,v 1.119 2017/06/19 08:31:10 tom Exp $ */
 
 /*
  * Copyright 1998-2016,2017 by Thomas E. Dickey
@@ -39,8 +39,8 @@
 extern Bool xtermLoadDefaultFonts (XtermWidget /* xw */);
 extern Bool xtermOpenFont (XtermWidget /* xw */, const char */* name */, XTermFonts * /* result */, Bool /* force */);
 extern XTermFonts * getDoubleFont (TScreen * /* screen */, int /* which */);
-extern XTermFonts * getItalicFont (TScreen * /* screen */, VTFontEnum /* which */);
-extern XTermFonts * getNormalFont (TScreen * /* screen */, VTFontEnum /* which */);
+extern XTermFonts * getItalicFont (TScreen * /* screen */, int /* which */);
+extern XTermFonts * getNormalFont (TScreen * /* screen */, int /* which */);
 extern const VTFontNames * defaultVTFontNames(XtermWidget /* xw */);
 extern const VTFontNames * xtermFontName (const char */* normal */);
 extern const char * whichFontEnum (VTFontEnum /* value */);
@@ -136,7 +136,7 @@ extern void xtermSaveVTFonts (XtermWidget /* xw */);
 
 #if OPT_RENDERFONT
 extern Bool xtermXftMissing (XtermWidget /* xw */, XftFont * /* font */, unsigned /* wc */);
-extern XTermXftFonts *getMyXftFont (XtermWidget /* xw */, VTFontEnum /* which */, int /* fontnum */);
+extern XTermXftFonts *getMyXftFont (XtermWidget /* xw */, int /* which */, int /* fontnum */);
 extern XftFont *getXftFont (XtermWidget /* xw */, VTFontEnum /* which */, int /* fontnum */);
 extern void xtermCloseXft (TScreen * /* screen */, XTermXftFonts * /* pub */);
 #endif
diff --git a/graphics.c b/graphics.c
index 9c5ec90..4bd50b4 100644
--- a/graphics.c
+++ b/graphics.c
@@ -1,7 +1,7 @@
-/* $XTermId: graphics.c,v 1.72 2017/06/07 00:19:36 Ross.Combs Exp $ */
+/* $XTermId: graphics.c,v 1.73 2017/06/18 18:20:22 tom Exp $ */
 
 /*
- * Copyright 2013-2015,2016 by Ross Combs
+ * Copyright 2013-2016,2017 by Ross Combs
  *
  *                         All Rights Reserved
  *
diff --git a/graphics_regis.c b/graphics_regis.c
index 4ab3fca..ce52b49 100644
--- a/graphics_regis.c
+++ b/graphics_regis.c
@@ -1,4 +1,4 @@
-/* $XTermId: graphics_regis.c,v 1.92 2017/06/11 21:47:52 tom Exp $ */
+/* $XTermId: graphics_regis.c,v 1.96 2017/06/21 01:15:19 tom Exp $ */
 
 /*
  * Copyright 2014-2016,2017 by Ross Combs
@@ -224,6 +224,7 @@ typedef struct RegisParseState {
 #define TEXT_TILT_STATE_GOT_DSD  3U
 
 typedef struct RegisGraphicsContext {
+    XtermWidget current_widget;
     Graphic *destination_graphic;
     Graphic *display_graphic;
     int terminal_id;
@@ -306,6 +307,28 @@ static void get_bitmap_of_character(RegisGraphicsContext const *context,
 				    unsigned *w, unsigned *h,
 				    unsigned max_pixels);
 
+static void
+init_regis_load_state(RegisParseState *state)
+{
+    state->load_index = MAX_REGIS_ALPHABETS;
+    state->load_w = 8U;
+    state->load_h = 10U;
+    state->load_alphabet = 1U;	/* FIXME: is this the correct default */
+    state->load_name[0] = '\0';
+    state->load_glyph = (unsigned) (unsigned char) '\0';
+    state->load_row = 0U;
+}
+
+static void
+init_regis_parse_state(RegisParseState *state)
+{
+    state->command = '_';
+    state->option = '_';
+    state->stack_next = 0U;
+    state->load_index = MAX_REGIS_ALPHABETS;
+    init_regis_load_state(state);
+}
+
 static int
 ifloor(double d)
 {
@@ -2118,9 +2141,12 @@ get_bitmap_of_character(RegisGraphicsContext const *context, int ch,
     unsigned bestmatch;
     char const *fontname = NULL;
 
-    if (context->current_text_controls->alphabet_num == 0) {
+    assert(context);
+    assert(w);
+    assert(h);
+
+    if (context->current_text_controls->alphabet_num == 0)
 	fontname = context->builtin_font;
-    }
 
     *w = 0U;
     *h = 0U;
@@ -2710,14 +2736,26 @@ get_fragment(RegisDataFragment const *fragment, unsigned pos)
     return '\0';
 }
 
-static size_t
-fragment_len(RegisDataFragment const *fragment)
+#define fragment_length(f) (f)->len
+
+static unsigned
+fragment_remaining(RegisDataFragment const *fragment)
 {
     assert(fragment);
 
+    if (fragment->pos > fragment->len)
+	return 0U;
     return fragment->len - fragment->pos;
 }
 
+static int
+fragment_consumed(RegisDataFragment const *fragment)
+{
+    assert(fragment);
+
+    return fragment->pos >= fragment->len;
+}
+
 static void
 fragment_to_string(RegisDataFragment const *fragment, char *out,
 		   unsigned outlen)
@@ -2759,8 +2797,8 @@ skip_regis_whitespace(RegisDataFragment *input)
 
     assert(input);
 
-    for (; input->pos < input->len; input->pos++) {
-	char ch = input->start[input->pos];
+    while (!fragment_consumed(input)) {
+	char ch = peek_fragment(input);
 	if (ch != ',' && !IsSpace(ch)) {
 	    break;
 	}
@@ -2768,6 +2806,7 @@ skip_regis_whitespace(RegisDataFragment *input)
 	    TRACE(("end of input line\n\n"));
 	}
 	skipped = 1;
+	pop_fragment(input);
     }
 
     if (skipped)
@@ -2920,33 +2959,36 @@ extract_regis_command(RegisDataFragment *input, char *command)
 static int
 extract_regis_string(RegisDataFragment *input, char *out, unsigned maxlen)
 {
-    char first_ch;
+    char open_quote_ch;
     char ch;
-    unsigned outlen = 0U;
+    unsigned outlen;
 
     assert(input);
     assert(out);
+    assert(maxlen > 0U);
 
     if (input->pos >= input->len)
 	return 0;
 
-    ch = input->start[input->pos];
+    ch = peek_fragment(input);
     if (ch != '\'' && ch != '"')
 	return 0;
-    first_ch = ch;
-    input->pos++;
+    open_quote_ch = ch;
+    outlen = 0U;
+    pop_fragment(input);
 
     ch = '\0';
-    for (; input->pos < input->len; input->pos++) {
+    while (!fragment_consumed(input)) {
 	char prev_ch = ch;
-	ch = input->start[input->pos];
-	/* ';' (resync) is not recognized in strings */
-	if (prev_ch == first_ch) {
-	    if (ch == first_ch) {
+	ch = peek_fragment(input);
+	/* ';' (resync) and '@' (macrograph) are not recognized in strings */
+	if (prev_ch == open_quote_ch) {
+	    if (ch == open_quote_ch) {
 		if (outlen < maxlen) {
 		    out[outlen] = ch;
 		}
 		outlen++;
+		pop_fragment(input);
 		ch = '\0';
 		continue;
 	    }
@@ -2958,14 +3000,15 @@ extract_regis_string(RegisDataFragment *input, char *out, unsigned maxlen)
 	}
 	if (ch == '\0')
 	    break;
-	if (ch != first_ch) {
-	    if (outlen < maxlen) {
+	if (ch != open_quote_ch) {
+	    if (outlen < maxlen)
 		out[outlen] = ch;
-	    }
 	    outlen++;
 	}
+	pop_fragment(input);
     }
-    if (ch == first_ch) {
+    if (ch == open_quote_ch) {
+	pop_fragment(input);
 	if (outlen < maxlen)
 	    out[outlen] = '\0';
 	else
@@ -2983,7 +3026,7 @@ extract_regis_parenthesized_data(RegisDataFragment *input,
 				 RegisDataFragment *output)
 {
     char ch;
-    char first_ch;
+    char open_quote_ch;
     int nesting;
 
     assert(input);
@@ -3002,25 +3045,25 @@ extract_regis_parenthesized_data(RegisDataFragment *input,
     input->pos++;
     output->start++;
     nesting = 1;
-    first_ch = '\0';
+    open_quote_ch = '\0';
 
     ch = '\0';
     for (; input->pos < input->len; input->pos++, output->len++) {
 	char prev_ch = ch;
 	ch = input->start[input->pos];
 	if (ch == '\'' || ch == '"') {
-	    if (first_ch == '\0') {
-		first_ch = ch;
+	    if (open_quote_ch == '\0') {
+		open_quote_ch = ch;
 	    } else {
-		if (ch == prev_ch && prev_ch == first_ch) {
+		if (ch == prev_ch && prev_ch == open_quote_ch) {
 		    ch = '\0';
-		} else if (ch == first_ch) {
-		    first_ch = '\0';
+		} else if (ch == open_quote_ch) {
+		    open_quote_ch = '\0';
 		}
 	    }
 	    continue;
 	}
-	if (first_ch != '\0')
+	if (open_quote_ch != '\0')
 	    continue;
 
 	if (ch == ';') {
@@ -3051,7 +3094,7 @@ extract_regis_option(RegisDataFragment *input,
 {
     char ch;
     int paren_level, bracket_level;
-    char first_ch;
+    char open_quote_ch;
 
     assert(input);
     assert(option);
@@ -3086,21 +3129,21 @@ extract_regis_option(RegisDataFragment *input,
     paren_level = 0;
     bracket_level = 0;
 
-    first_ch = '\0';
+    open_quote_ch = '\0';
     for (; input->pos < input->len; input->pos++, output->len++) {
 	ch = input->start[input->pos];
 	TRACE(("looking at char '%c' in option '%c'\n", ch, *option));
 	/* FIXME: any special rules for commas? */
 	/* FIXME: handle escaped quotes */
 	if (ch == '\'' || ch == '"') {
-	    if (first_ch == ch) {
-		first_ch = '\0';
+	    if (open_quote_ch == ch) {
+		open_quote_ch = '\0';
 	    } else {
-		first_ch = ch;
+		open_quote_ch = ch;
 	    }
 	    continue;
 	}
-	if (first_ch != '\0')
+	if (open_quote_ch != '\0')
 	    continue;
 	if (ch == '(') {
 	    paren_level++;
@@ -3165,6 +3208,9 @@ regis_num_to_int(RegisDataFragment const *input, int *out)
 {
     char ch;
 
+    assert(input);
+    assert(out);
+
     /* FIXME: handle exponential notation and rounding */
     /* FIXME: check for junk after the number */
     ch = peek_fragment(input);
@@ -3198,15 +3244,21 @@ load_regis_colorspec(RegisGraphicsContext const *context,
     short l = -1;
     int simple;
 
+    assert(context);
+    assert(input);
+    assert(r_out);
+    assert(g_out);
+    assert(b_out);
+
     copy_fragment(&colorspec, input);
     TRACE(("colorspec option: \"%s\"\n", fragment_to_tempstr(&colorspec)));
 
     skip_regis_whitespace(&colorspec);
     simple = 0;
-    if (fragment_len(&colorspec) == 1) {
+    if (fragment_remaining(&colorspec) == 1U) {
 	simple = 1;
-    } else if (fragment_len(&colorspec) > 1) {
-	char after = get_fragment(&colorspec, 1);
+    } else if (fragment_remaining(&colorspec) > 1U) {
+	char after = get_fragment(&colorspec, 1U);
 	if (IsSpace(after))
 	    simple = 1;
     }
@@ -3273,7 +3325,7 @@ load_regis_colorspec(RegisGraphicsContext const *context,
 	    l = 100;
 	    break;
 	default:
-	    TRACE(("unknown RGB color name: \"%c\"\n", ch));
+	    TRACE(("DATA_ERROR: unknown RGB color name: \"%c\"\n", ch));
 	    return 0;
 	}
     } else {
@@ -3283,7 +3335,7 @@ load_regis_colorspec(RegisGraphicsContext const *context,
 	short h = -1;
 	short s = -1;
 
-	while (colorspec.pos < colorspec.len) {
+	while (!fragment_consumed(&colorspec)) {
 	    if (skip_regis_whitespace(&colorspec))
 		continue;
 
@@ -3325,13 +3377,15 @@ load_regis_colorspec(RegisGraphicsContext const *context,
 		break;
 #endif
 	    default:
-		TRACE(("unrecognized character in colorspec: \"%c\"\n", comp));
+		TRACE(("DATA_ERROR: unrecognized component in colorspec: '%c'\n",
+		       comp));
 		return 0;
 	    }
 
 	    skip_regis_whitespace(&colorspec);
 	    if (!extract_regis_num(&colorspec, &num)) {
-		TRACE(("unrecognized character in colorspec: \"%c\"\n", comp));
+		TRACE(("DATA_ERROR: expected int after '%c' component in colorspec: \"%s\"\n",
+		       comp, fragment_to_tempstr(&colorspec)));
 		return 0;
 	    }
 	    if (!regis_num_to_int(&num, &val)) {
@@ -3382,7 +3436,7 @@ load_regis_colorspec(RegisGraphicsContext const *context,
 	    hls2rgb(0, l, 0, &r, &g, &b);
 	    TRACE(("converted to RGB: %hd,%hd,%hd\n", r, g, b));
 	} else {
-	    TRACE(("unrecognized colorspec format\n"));
+	    TRACE(("DATA_ERROR: unrecognized colorspec format\n"));
 	    return 0;
 	}
     }
@@ -3400,7 +3454,7 @@ load_regis_colorspec(RegisGraphicsContext const *context,
     *b_out = b;
 
     skip_regis_whitespace(&colorspec);
-    if (colorspec.pos < colorspec.len) {
+    if (!fragment_consumed(&colorspec)) {
 	char skip;
 
 	skip = pop_fragment(&colorspec);
@@ -3450,7 +3504,7 @@ load_regis_regnum_or_colorspec(RegisGraphicsContext const *context,
 	*out = (RegisterNum) val;
 
 	skip_regis_whitespace(&colorspec);
-	if (colorspec.pos < colorspec.len) {
+	if (!fragment_consumed(&colorspec)) {
 	    char skip;
 
 	    skip = pop_fragment(&colorspec);
@@ -3757,10 +3811,12 @@ load_regis_coord_pixelvector(RegisGraphicsContext const *context,
 			     int origx, int origy,
 			     int *xloc, int *yloc)
 {
-    const int mul = (int) (context->temporary_write_controls.pv_multiplier * COORD_SCALE);
+    const int mul = (int) (context->temporary_write_controls.pv_multiplier
+			   * COORD_SCALE);
     int found = 0;
     int ux = 0, uy = 0;
     unsigned offset = 0U;
+
     while (load_regis_raw_pixelvector_digit(pixelvector, &offset,
 					    &ux, &uy,
 					    mul))
@@ -3793,7 +3849,8 @@ load_regis_coord_pixelvector_step(RegisGraphicsContext const *context,
 				  int origx, int origy,
 				  int *xloc, int *yloc)
 {
-    const int mul = (int) (context->temporary_write_controls.pv_multiplier * COORD_SCALE);
+    const int mul = (int) (context->temporary_write_controls.pv_multiplier
+			   * COORD_SCALE);
     int found = 0;
     int ux = 0, uy = 0;
     if (load_regis_raw_pixelvector_digit(pixelvector, offset, &ux, &uy, mul))
@@ -3944,7 +4001,7 @@ load_regis_write_control(RegisParseState *state,
 	    RegisDataFragment item;
 	    char suboption;
 
-	    while (arg->pos < arg->len) {
+	    while (!fragment_consumed(arg)) {
 		if (skip_regis_whitespace(arg))
 		    continue;
 
@@ -3953,7 +4010,7 @@ load_regis_write_control(RegisParseState *state,
 		if (extract_regis_parenthesized_data(arg, &suboptionset)) {
 		    TRACE(("got write pattern suboptionset: \"%s\"\n",
 			   fragment_to_tempstr(&suboptionset)));
-		    while (suboptionset.pos < suboptionset.len) {
+		    while (!fragment_consumed(&suboptionset)) {
 			skip_regis_whitespace(&suboptionset);
 			if (extract_regis_option(&suboptionset, &suboption,
 						 &suboptionarg)) {
@@ -3984,7 +4041,7 @@ load_regis_write_control(RegisParseState *state,
 					skip_regis_whitespace(&suboptionarg);
 				    }
 
-				    if (fragment_len(&suboptionarg)) {
+				    if (!fragment_consumed(&suboptionarg)) {
 					TRACE(("DATA_ERROR: unknown content after pattern multiplier \"%s\"\n",
 					       fragment_to_tempstr(&suboptionarg)));
 					return 0;
@@ -4133,7 +4190,7 @@ load_regis_write_control(RegisParseState *state,
 	    int ref_x = cur_x, ref_y = cur_y;
 	    int shading_enabled = 0;
 
-	    while (arg->pos < arg->len) {
+	    while (!fragment_consumed(arg)) {
 		if (skip_regis_whitespace(arg))
 		    continue;
 
@@ -4155,7 +4212,7 @@ load_regis_write_control(RegisParseState *state,
 		    skip_regis_whitespace(&suboptionset);
 		    TRACE(("got shading control suboptionset: \"%s\"\n",
 			   fragment_to_tempstr(&suboptionset)));
-		    while (suboptionset.pos < suboptionset.len) {
+		    while (!fragment_consumed(&suboptionset)) {
 			if (skip_regis_whitespace(&suboptionset))
 			    continue;
 			if (extract_regis_option(&suboptionset, &suboption,
@@ -4168,7 +4225,7 @@ load_regis_write_control(RegisParseState *state,
 			    case 'x':
 				TRACE(("found horizontal shading suboption \"%s\"\n",
 				       fragment_to_tempstr(&suboptionarg)));
-				if (fragment_len(&suboptionarg)) {
+				if (!fragment_consumed(&suboptionarg)) {
 				    TRACE(("DATA_ERROR: unexpected value to horizontal shading suboption FIXME\n"));
 				    return 0;
 				}
@@ -4278,14 +4335,14 @@ load_regis_write_control_set(RegisParseState *state,
     RegisDataFragment arg;
     char option;
 
-    while (controls->pos < controls->len) {
+    while (!fragment_consumed(controls)) {
 	if (skip_regis_whitespace(controls))
 	    continue;
 
 	if (extract_regis_parenthesized_data(controls, &optionset)) {
 	    TRACE(("got write control optionset: \"%s\"\n",
 		   fragment_to_tempstr(&optionset)));
-	    while (optionset.pos < optionset.len) {
+	    while (!fragment_consumed(&optionset)) {
 		skip_regis_whitespace(&optionset);
 		if (extract_regis_option(&optionset, &option, &arg)) {
 		    skip_regis_whitespace(&arg);
@@ -4361,21 +4418,23 @@ map_regis_graphics_pages(XtermWidget xw, RegisGraphicsContext *context)
 	old_display_id = context->display_graphic->id;
     }
 
-    context->destination_graphic = get_new_or_matching_graphic(xw,
-							       charrow, charcol,
-							       context->width,
-							       context->height,
-							       context->destination_page);
+    context->destination_graphic =
+	get_new_or_matching_graphic(xw,
+				    charrow, charcol,
+				    context->width,
+				    context->height,
+				    context->destination_page);


Reply to: