--- Begin Message ---
Package: xserver-xorg-input-evtouch
Version: 0.8.7-3
Severity: wishlist
Tags: patch
This patch improves the debugging support in evtouch.
Major changes:
* Reimplementation of debug macros are less likely to cause unintended
side effects (e.g. merging with adjacent statements, mismatched else's).
* debug_level controls all debugging.
* Globally changable reporting levels for features.
* More features instrumented.
* Live reporting mode for location information.
Quortech open source packages can be found at:
ftp://ftp.quortech.com/eclipse/deb-packages/
This patch is included in xf86-input-evtouch_0.8.7-3quortech3.dsc.
-- System Information:
Debian Release: 4.0
APT prefers stable
APT policy: (500, 'stable')
Architecture: i386 (i686)
Shell: /bin/sh linked to /bin/bash
Kernel: Linux 2.6.22-14-generic
Locale: LANG=en_CA.UTF-8, LC_CTYPE=en_CA.UTF-8 (charmap=UTF-8)
# Description: This patch improves the debugging support in evtouch.
#
# Changes
# o Statements_M : Utility macro to make debugging macros simpler and
# more robust.
# o debug_level : Combine to single global provided by libtouch.c.
# o DBG : Move to libtouch.h to be shared with evtouch.c. Make more
# robust. Allow entire blocks of debugging statements to be skipped.
# o DBGOUT : Move to evtouch.c, the only place it's currently used.
# o DBGOUT : Local control through DebugLevel option of output.
# Avoids uncontrolled output size in /var/log/Xorg.0.log with noisy
# touch screen. Encapsulate debugging statements that weren't using.
# o DBGOUT : Make robust to surrounding statements.
# o DBGXF86, DBGLOC : Globally changable reporting levels for features.
# o DBGXF86 : Instrument tracing of xf86 calls.
# o dbg_loc : Report location information as received and transmitted.
# o DBGLOC_INLINE : Overwrites location information in place on ASCII
# terminal. Useful for live testing of accuracy of touch screen.
# o EVTouchDumpPacketToLog : Reduce single usage to DBGOUT call.
#
# Feel free to send comments, critics, suggestions to w...@acm.org
# To apply simply change into the toplevel directory of the source to be
modified and enter:
# patch -p1 < <PATH_TO_PATCH>
#
# All patches are available under the GNU GPL, I hope they might be useful for
you (-:
# - Brett Wuth
#
Index: xf86-input-evtouch-0.8.7/evtouch.c
===================================================================
--- xf86-input-evtouch-0.8.7.orig/evtouch.c 2009-01-15 14:55:33.000000000
-0700
+++ xf86-input-evtouch-0.8.7/evtouch.c 2009-01-15 15:38:41.000000000 -0700
@@ -92,6 +92,14 @@
#include "libtouch.h"
#include "evtouch.h"
+/* The verbosity levels at which to output various */
+#define DBGXF86 (9) /* XF86 calls */
+#define DBGLOC (1) /* location information */
+
+#define DBGLOC_INLINE (1) /* whether to display location information
+ * on one line continously updated (1), or
+ * on multiple lines (0) */
+
/*****************************************************************************
* Variables without includable headers
****************************************************************************/
@@ -106,7 +114,17 @@
static void
EVTouchPtrCtrl(DeviceIntPtr device, PtrCtrl *ctrl);
-static int debug_level = 0;
+#ifdef EVDBG
+ /* Only output the debug statement if it meets *our* debug_level.
+ */
+#define DBGOUT(lvl, ...) DBG( (lvl), xf86ErrorFVerb( (lvl), __VA_ARGS__ ); )
+#else
+ /* Do nothing, but require the user to include trailing ";"
+ * so that syntax rules of normal statements are maintained.
+ * Compiler will optimize this statement away.
+ */
+#define DBGOUT(lvl, ...) Statements_M()
+#endif
InputDriverRec EVTOUCH = {
1,
@@ -150,9 +168,12 @@
int *errmaj,
int *errmin )
{
- xf86AddModuleInfo(&EVTouchInfo, module);
- xf86AddInputDriver(&EVTOUCH, module, 0);
- return module;
+ DBGOUT( DBGXF86, "EVTouch: xf86AddModuleInfo(&EVTouchInfo, module)\n" );
+ xf86AddModuleInfo(&EVTouchInfo, module);
+
+ DBGOUT( DBGXF86, "EVTouch: xf86AddInputDriver(&EVTOUCH, module, 0)\n" );
+ xf86AddInputDriver(&EVTOUCH, module, 0);
+ return module;
}
@@ -201,6 +222,39 @@
****************************************************************************/
+/* Report the current location information as received and as sent on to X */
+static void
+dbg_loc( int *in_x, /* the received X location, NULL if no change */
+ int *in_y, /* the received Y location, NULL if no change */
+ int *out_x, /* the sent X location, NULL if no change */
+ int *out_y /* the sent Y location, NULL if no change */
+ )
+{
+ static int last_in_x, last_in_y, last_out_x, last_out_y;
+
+ if (in_x) last_in_x = *in_x;
+ if (in_y) last_in_y = *in_y;
+ if (out_x) last_out_x = *out_x;
+ if (out_y) last_out_y = *out_y;
+
+ /* Print the current location as received and sent.
+ * Fields that have been updated are marked with a leading '*'.
+ */
+ DBGOUT( DBGLOC,
+ "EVTouch in = (%c%5d, %c%5d), out = (%c%5d, %c%5d)%c",
+ in_x ? '*' : ' ',
+ last_in_x,
+ in_y ? '*' : ' ',
+ last_in_y,
+ out_x ? '*' : ' ',
+ last_out_x,
+ out_y ? '*' : ' ',
+ last_out_y,
+ DBGLOC_INLINE ? '\r' : '\n'
+ );
+}
+
+
static CARD32
emulate3Timer(OsTimerPtr timer, CARD32 now, pointer _local)
{
@@ -212,7 +266,9 @@
EVTouchPrivatePtr priv = (EVTouchPrivatePtr) local->private;
+ DBGOUT( DBGXF86, "EVTouch: xf86BlockSIGIO()\n" );
sigstate = xf86BlockSIGIO();
+ DBGOUT( DBGXF86, "EVTouch: returned sigstate = %d\n", sigstate );
PostMotionEvent(local);
@@ -240,6 +296,8 @@
}
priv->emulate3_timer_expired = TRUE;
+
+ DBGOUT( DBGXF86, "EVTouch: xf86UnblockSIGIO(sigstate=%d)\n", sigstate );
xf86UnblockSIGIO(sigstate);
return 0;
@@ -291,6 +349,8 @@
ev = &priv->ev;
if ( (ev->code == ABS_X) || (ev->code == ABS_Z) ) {
+ dbg_loc( &ev->value, NULL, NULL, NULL );
+
if ((priv->cur_x - ev->value < priv->move_limit)
&& (priv->cur_x - ev->value > -priv->move_limit))
return;
@@ -299,6 +359,8 @@
}
if ( (ev->code == ABS_Y) || (ev->code == ABS_RX) ) {
+ dbg_loc( NULL, &ev->value, NULL, NULL );
+
if ((priv->cur_y - ev->value < priv->move_limit)
&& (priv->cur_y - ev->value > -priv->move_limit))
return;
@@ -469,7 +531,9 @@
LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private);
+ DBGOUT( DBGXF86, "EVTouch: xf86OpenSerial(local->options)\n" );
local->fd = xf86OpenSerial(local->options);
+ DBGOUT( DBGXF86, "EVTouch: returned local->fd = %d\n", local->fd );
DBGOUT(2, "EVTouch: %s\n", __FUNCTION__ );
@@ -486,9 +550,10 @@
if (!priv->buffer)
{
- xf86CloseSerial(local->fd);
- local->fd = -1;
- return (!Success);
+ DBGOUT( DBGXF86, "EVTouch: xf86CloseSerial(local->fd=%d)\n",
local->fd );
+ xf86CloseSerial(local->fd);
+ local->fd = -1;
+ return (!Success);
}
if (QueryHardware(local) != Success)
@@ -497,6 +562,7 @@
return (!Success);
}
+ DBGOUT( DBGXF86, "EVTouch: xf86FlushInput(local->fd=%d)\n", local->fd );
xf86FlushInput(local->fd);
if (ioctl(local->fd, EVIOCGRAB, (void *)1))
@@ -504,6 +570,7 @@
#ifndef XFREE86_V4
+ DBGOUT( DBGXF86, "EVTouch: xf86AddEnabledDevice(local)\n" );
xf86AddEnabledDevice(local);
#else
AddEnabledDevice(local->fd);
@@ -528,12 +595,14 @@
if (local->fd != -1)
{
ioctl(local->fd, EVIOCGRAB, (void *)0);
- xf86RemoveEnabledDevice (local);
+ DBGOUT( DBGXF86, "EVTouch: xf86RemoveEnabledDevice(local)\n" );
+ xf86RemoveEnabledDevice(local);
if (priv->buffer)
{
XisbFree(priv->buffer);
priv->buffer = NULL;
}
+ DBGOUT( DBGXF86, "EVTouch: xf86CloseSerial(local->fd=%d)\n",
local->fd );
xf86CloseSerial(local->fd);
local->fd = -1;
}
@@ -605,6 +674,8 @@
DBGOUT(2, "EVTouch: %s btn_count=%d\n", __FUNCTION__,
priv->btn_count);
priv->btn_actions = xcalloc(priv->btn_count, sizeof(BtnAction));
+
+ DBGOUT( DBGXF86, "EVTouch: xf86memset(...)\n" );
xf86memset(priv->btn_actions, 0,
priv->btn_count * sizeof(BtnAction));
@@ -627,26 +698,40 @@
return !Success;
}
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 2
+ DBGOUT( DBGXF86, "EVTouch: xf86InitValuatorAxisStruct(...)\n" );
xf86InitValuatorAxisStruct(dev, 0, 0, priv->screen_width,
1024,
EV_AXIS_MIN_RES /* min_res */ ,
EV_AXIS_MAX_RES /* max_res */ );
+
+ DBGOUT( DBGXF86, "EVTouch: xf86InitValuatorDefaults(dev,0)\n" );
xf86InitValuatorDefaults(dev, 0);
+
+ DBGOUT( DBGXF86, "EVTouch: xf86InitValuatorAxisStruct(...)\n" );
xf86InitValuatorAxisStruct(dev, 1, 0, priv->screen_height,
1024,
EV_AXIS_MIN_RES /* min_res */ ,
EV_AXIS_MAX_RES /* max_res */ );
+
+ DBGOUT( DBGXF86, "EVTouch: xf86InitValuatorDefaults(dev,1)\n" );
xf86InitValuatorDefaults(dev, 1);
#else
+ DBGOUT( DBGXF86, "EVTouch: xf86InitValuatorAxisStruct(...)\n" );
xf86InitValuatorAxisStruct(dev, 0, priv->min_x, priv->max_x,
1024,
EV_AXIS_MIN_RES /* min_res */ ,
EV_AXIS_MAX_RES /* max_res */ );
+
+ DBGOUT( DBGXF86, "EVTouch: xf86InitValuatorDefaults(dev,0)\n" );
xf86InitValuatorDefaults(dev, 0);
+
+ DBGOUT( DBGXF86, "EVTouch: xf86InitValuatorAxisStruct(...)\n" );
xf86InitValuatorAxisStruct(dev, 1, priv->min_y, priv->max_y,
1024,
EV_AXIS_MIN_RES /* min_res */ ,
EV_AXIS_MAX_RES /* max_res */ );
+
+ DBGOUT( DBGXF86, "EVTouch: xf86InitValuatorDefaults(dev,1)\n" );
xf86InitValuatorDefaults(dev, 1);
#endif
/* Initial position of pointer on screen: Centered */
@@ -670,7 +755,8 @@
/*
* Allocate the motion events buffer.
*/
- xf86MotionHistoryAllocate (local);
+ DBGOUT( DBGXF86, "EVTouch: xf86MotionHistoryAllocate(local)\n" );
+ xf86MotionHistoryAllocate(local);
return (Success);
}
@@ -708,9 +794,10 @@
static void
EVTouchNewPacket (EVTouchPrivatePtr priv)
{
- xf86memset(&priv->ev, 0, sizeof(struct input_event));
- priv->packeti = 0;
- priv->binary_pkt = FALSE;
+ DBGOUT( DBGXF86, "EVTouch: xf86memset(...)\n" );
+ xf86memset(&priv->ev, 0, sizeof(struct input_event));
+ priv->packeti = 0;
+ priv->binary_pkt = FALSE;
}
@@ -736,7 +823,11 @@
if (sizeof(priv->ev) == count) {
count = 0;
- EVTouchDumpPacketToLog(priv);
+#ifdef LOG_RAW_PACKET
+ DBGOUT( 2,
+ "EVTOUCHPCKT type=0x%02x code=0x%02x
value=0x%02x\n",
+ priv->ev.type, priv->ev.code, priv->ev.value );
+#endif
return Success;
}
@@ -876,9 +967,6 @@
int xc = 0, yc = 0;
int screen_width = 0;
int screen_height = 0;
-#ifdef EVDBG
- int i = 0;
-#endif
EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private);
ScrnInfoPtr pScrn = xf86Screens[priv->screen_num];
@@ -1003,14 +1091,20 @@
#ifdef EVDBG
- for (i=0; i<3; i++)
- xf86ErrorFVerb(2, "cx[%d]=%f cy[%d]=%f\n", i, cx[i]
- ,i, cy[i]);
-
- DBGOUT(2, "EVTouch: ViewPort_X0=%d ViewPort_Y0=%d\n",
- *(priv->pViewPort_X0),
- *(priv->pViewPort_Y0));
- DBGOUT(2, "EVTouch: dx=%f dy=%f\n", dx, dy);
+ DBG( 2,
+ {
+ int i = 0;
+ for (i=0; i<3; i++)
+ DBGOUT( 2,
+ "cx[%d]=%f cy[%d]=%f\n",
+ i, cx[i], i, cy[i] );
+
+ DBGOUT( 2,
+ "EVTouch: ViewPort_X0=%d ViewPort_Y0=%d\n",
+ *(priv->pViewPort_X0),
+ *(priv->pViewPort_Y0) );
+ DBGOUT( 2, "EVTouch: dx=%f dy=%f\n", dx, dy );
+ } );
#endif
xc = ( ((float)xc / max_x) * screen_width ) + dx;
@@ -1100,7 +1194,9 @@
if (!priv)
return NULL;
+ DBGOUT( DBGXF86, "EVTouch: xf86AllocateInput(drv, 0)\n" );
local = xf86AllocateInput(drv, 0);
+ DBGOUT( DBGXF86, "EVTouch: returned local=%p\n", local );
if (!local) {
xfree(priv);
return NULL;
@@ -1123,15 +1219,18 @@
local->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
local->conf_idev = dev;
+
+ DBGOUT( DBGXF86, "EVTouch: xf86CollectInputOptions(local,
default_options, NULL)\n" );
xf86CollectInputOptions(local, default_options, NULL);
+ DBGOUT( DBGXF86, "EVTouch: xf86OptionListReport(local->options)\n" );
xf86OptionListReport(local->options);
priv->libtouch = xcalloc(1, sizeof(LibTouchRec));
libtouchInit(priv->libtouch, local,PostButtonEvent);
- priv->screen_num = xf86SetIntOption(local->options, "ScreenNumber",
0 );
+ priv->screen_num = xf86SetIntOption(local->options, "ScreenNumber", 0
);
priv->calibrate = xf86SetIntOption(local->options, "Calibrate", 0);
@@ -1207,6 +1306,7 @@
}
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
+ DBGOUT( DBGXF86, "EVTouch: xf86AlwaysCore(local, TRUE)\n" );
xf86AlwaysCore(local, TRUE);
#endif
priv->touch_flags = 0;
@@ -1222,14 +1322,17 @@
if (priv->calibrate) {
priv->fifo = open("/tmp/ev_calibrate", O_RDWR, 0);
if (priv->fifo < 0)
- xf86ErrorFVerb(2, "open FIFO FAILED\n");
+ DBGOUT( 2, "open FIFO FAILED\n" );
}
/* this results in an xstrdup that must be freed later */
local->name = xf86SetStrOption( local->options, "DeviceName", "EVTouch
TouchScreen" );
+
+ DBGOUT( DBGXF86, "EVTouch: xf86ProcessCommonOptions(local,
local->options)\n" );
xf86ProcessCommonOptions(local, local->options);
local->flags |= XI86_CONFIGURED;
+ DBGOUT( DBGXF86, "EVTouch: xf86CloseSerial(local->fd = %d)\n",
local->fd );
xf86CloseSerial(local->fd);
local->fd = -1;
@@ -1248,52 +1351,64 @@
static void
PostMotionEvent(LocalDevicePtr local) {
-int cur_x, cur_y;
-EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private);
+ int cur_x, cur_y;
+ EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private);
- cur_x = priv->cur_x;
- cur_y = priv->cur_y;
+ cur_x = priv->cur_x;
+ cur_y = priv->cur_y;
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 2
- ConvertProc(local,0,2,priv->cur_x,priv->cur_y,0,0,0,0,&cur_x,&cur_y);
+ ConvertProc(local,0,2,priv->cur_x,priv->cur_y,0,0,0,0,&cur_x,&cur_y);
#endif
-xf86PostMotionEvent (local->dev, TRUE, 0, 2, cur_x, cur_y);
+ dbg_loc( NULL, NULL, &cur_x, &cur_y );
+
+ DBGOUT( DBGXF86, "EVTouch: xf86PostMotionEvent (local->dev, TRUE, 0, 2,
cur_x=%d, cur_y=%d)\n", cur_x, cur_y );
+ xf86PostMotionEvent (local->dev, TRUE, 0, 2, cur_x, cur_y);
}
static void
PostProximityEvent(LocalDevicePtr local, int is_in) {
-int cur_x, cur_y;
-EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private);
+ int cur_x, cur_y;
+ EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private);
- cur_x = priv->cur_x;
- cur_y = priv->cur_y;
+ cur_x = priv->cur_x;
+ cur_y = priv->cur_y;
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 2
- ConvertProc(local,0,2,priv->cur_x,priv->cur_y,0,0,0,0,&cur_x,&cur_y);
+ ConvertProc(local,0,2,priv->cur_x,priv->cur_y,0,0,0,0,&cur_x,&cur_y);
#endif
-xf86PostProximityEvent(local->dev, is_in, 0, 2, cur_x,cur_y);
+ dbg_loc( NULL, NULL, &cur_x, &cur_y );
+
+ DBGOUT( DBGXF86, "EVTouch: xf86PostProximityEvent(local->dev, is_in=%d, 0,
2, cur_x=%d,cur_y=%d)\n", is_in, cur_x, cur_y );
+ xf86PostProximityEvent(local->dev, is_in, 0, 2, cur_x,cur_y);
}
static void
PostButtonEvent(LocalDevicePtr local, int button, int is_down,int x, int y) {
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 2
- ConvertProc(local,0,2,x,y,0,0,0,0,&x,&y);
+ ConvertProc(local,0,2,x,y,0,0,0,0,&x,&y);
#endif
-xf86PostButtonEvent (local->dev, TRUE, button, is_down, 0, 2, x, y);
+ dbg_loc( NULL, NULL, &x, &y );
+
+ DBGOUT( DBGXF86, "EVTouch: xf86PostButtonEvent( local->dev, TRUE, button =
%d, is_down = %d, 0, 2, x = %d, y = %d )\n", button, is_down, x, y );
+ xf86PostButtonEvent( local->dev, TRUE, button, is_down, 0, 2, x, y );
}
static void InputSetScreen(LocalDevicePtr local) {
-int cur_x, cur_y;
-EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private);
+ int cur_x, cur_y;
+ EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private);
- cur_x = priv->cur_x;
- cur_y = priv->cur_y;
+ cur_x = priv->cur_x;
+ cur_y = priv->cur_y;
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 2
- ConvertProc(local,0,2,priv->cur_x,priv->cur_y,0,0,0,0,&cur_x,&cur_y);
+ ConvertProc(local,0,2,priv->cur_x,priv->cur_y,0,0,0,0,&cur_x,&cur_y);
#endif
-xf86XInputSetScreen(local,priv->screen_num,cur_x,cur_y);
+ dbg_loc( NULL, NULL, &cur_x, &cur_y );
+
+ DBGOUT( DBGXF86, "EVTouch:
xf86XInputSetScreen(local,priv->screen_num=%d,cur_x=%d,cur_y=%d)\n",
priv->screen_num, cur_x, cur_y );
+ xf86XInputSetScreen(local,priv->screen_num,cur_x,cur_y);
}
Index: xf86-input-evtouch-0.8.7/evtouch.h
===================================================================
--- xf86-input-evtouch-0.8.7.orig/evtouch.h 2009-01-15 14:55:33.000000000
-0700
+++ xf86-input-evtouch-0.8.7/evtouch.h 2009-01-15 15:37:31.000000000 -0700
@@ -29,12 +29,6 @@
#define _evtouch_H_
-#ifdef EVDBG
-#define DBGOUT(lvl, ...) (xf86ErrorFVerb(lvl, __VA_ARGS__))
-#else
-#define DBGOUT(lvl, ...)
-#endif
-
/******************************************************************************
* Definitions
* structs, typedefs, #defines, enums
@@ -148,12 +142,6 @@
* Declarations
*****************************************************************************/
-#ifdef LOG_RAW_PACKET
-#define EVTouchDumpPacketToLog(priv) ( xf86ErrorFVerb(2, "EVTOUCHPCKT
type=0x%02x code=0x%02x value=0x%02x\n",
priv->ev.type, priv->ev.code, priv->ev.value ) )
-#else
-#define EVTouchDumpPacketToLog(priv)
-#endif
-
void trigger_sm(EVTouchPrivatePtr priv);
/*
Index: xf86-input-evtouch-0.8.7/libtouch.c
===================================================================
--- xf86-input-evtouch-0.8.7.orig/libtouch.c 2009-01-15 14:55:33.000000000
-0700
+++ xf86-input-evtouch-0.8.7/libtouch.c 2009-01-15 15:23:07.000000000 -0700
@@ -40,12 +40,8 @@
#include "libtouch.h"
-#ifdef DBG
-#undef DBG
-#endif
-
-static int debug_level = 0;
-#define DBG(lvl, f) {if ((lvl) <= debug_level) f;}
+/* Maximum level of debug information to be displayed */
+extern int debug_level = 0;
typedef struct state {
void (*enter_state)(LibTouchRecPtr priv);
Index: xf86-input-evtouch-0.8.7/libtouch.h
===================================================================
--- xf86-input-evtouch-0.8.7.orig/libtouch.h 2009-01-15 14:55:33.000000000
-0700
+++ xf86-input-evtouch-0.8.7/libtouch.h 2009-01-15 15:23:07.000000000 -0700
@@ -3,6 +3,103 @@
#include <xf86_ansic.h>
#include <os.h>
+/* Macro to allow arbitrary statements to be executed as a single
+ * statement. This is a helper macro creating other macros. This
+ * macro must be followed by a ";" (like any other statement) and will
+ * accept only a ";" as the next character. Embedded Stmts must each
+ * be properly terminated. E.g.:
+ *
+ * Statements_M();
+ * Statements_M( foo(); bar(); );
+ * Statements_M( if (foo) bar(); );
+ * Statements_M( {
+ * int foo;
+ * bar( &foo );
+ * } );
+ * Statements_M( if (foo)
+ * break;
+ * if (bar)
+ * continue;
+ * );
+ *
+ *
+ * Warnings:
+ *
+ * Because the implementation use an if/else construct, if the caller
+ * uses something like:
+ *
+ * if (foo) Statements_M( ... );
+ *
+ * some compilers will "helpfully" produce a warning like:
+ *
+ * warning: suggest explicit braces to avoid ambiguous 'else'
+ *
+ * For this macro, the warning is inappropriate and can be ignored.
+ * To avoid the warning, rewrite the code as:
+ *
+ * if (foo) { Statements_M( ... ); }
+ *
+ * FIXME: Investigate compiler-specific pragmas/markup to turn off
+ * just for this macro.
+ *
+ *
+ * Implementation:
+ *
+ * Squiggly brackets "{ ... }" handle arbitrary statements.
+ *
+ * "do ... while (0)" is optimized away but syntactically can only be
+ * followed by a ";". Other solutions could accidentally merge
+ * following statements if the ";" was forgotten by the caller.
+ *
+ * "if (1) ... else ..." composes the whole thing as a single
+ * statement. A following "else" won't match our "if", because it's
+ * already been matched. Embedded break and continue statements are
+ * allowed. The compiler will optimize the if statement away.
+ */
+#define Statements_M( Stmts ) \
+ if (1) { Stmts } else do ; while (0)
+
+
+/* Maximum level of debug information to be displayed */
+extern int debug_level;
+
+/* Only execute the debug statement(s) if it meets our debug_level.
+ *
+ * The ";" after the statement is optional, as has been the convention
+ * in earlier implementations of this macro. E.g.:
+ *
+ * DBG( 1, bar() );
+ *
+ * More complex statements are also possible. E.g.:
+ *
+ * DBG( 1, bar(); );
+ * DBG( 1, bar(); baz(); );
+ * DBG( 1, while (foo) baz(); );
+ * DBG( 1, {
+ * int i;
+ * for (i = 0; i < foo; i++)
+ * bar();
+ * } );
+ *
+ *
+ * Implementation:
+ *
+ * The ";" after the "f" makes including a ";" optional.
+ *
+ * "{ ... }" avoids: "warning: suggest explicit braces to avoid
+ * ambiguous 'else'"
+ */
+#ifdef DBG
+#undef DBG
+#endif
+#define DBG( lvl, f ) \
+ Statements_M( if ((lvl) <= debug_level) \
+ { \
+ Statements_M( f; ); \
+ } \
+ )
+
+
#define TOUCHED 0x01
#define X_COORD 0x02
#define Y_COORD 0x04
--- End Message ---