
#define CHECK(p1,p2)            \
if (42 != p1)                   \
  {                             \
  if (!wBadVariable)            \
    {                           \
    wBadValue = p1;             \
    p1 = 42;                    \
    wBadVariable = p2;          \
    }                           \
  }

void AssertTrashedDS ( WORD wAssertValue )
{
  static WORD wQueueValue;   // The next open spot in the queue
  static WORD wQueue[10];    // The actual queue

         WORD wBadVariable;
         WORD wBadValue;

  //
  // These three lines add the passed in AssertionValue into the queue,
  // and zero out the next spot (which will be displayed as an asterisk)
  //

  wQueue[wQueueValue] = wAssertValue;
  wQueueValue = (wQueueValue+1)%10;
  wQueue[wQueueValue] = 0;

  //
  // The CHECK macro above will only set the wBadValue and wBadVariable
  // values if no asserion violation has occured.  Since it is possible
  // that multiple assertion variables could have been trashed at the
  // same time, we will continue this loop as long as *any* of the
  // assertion variables are trashed.  Note that the CHECK macro restores
  // the trashed assertion varaible once it has detected it.  This
  // prevents inifinite loops.
  //

  do
    {
    // Resetting this varaible makes the assumption that no trashing was done

    wBadVariable = 0;

    //
    // Check all of the variables.  Remember that once one trashing has been
    // found, the remaining trashed varaibles will remain trashed.  The next
    // iteration of the do-loop will find the next trashed variable, and
    // so on until all trashed variables have been reported.
    //

    CHECK(asv1,1);
    CHECK(asv2,2);
    CHECK(asv3,3);
    CHECK(asv4,4);
    CHECK(asv5,5);
    CHECK(asv6,6);
    CHECK(asv7,7);
    CHECK(asv8,8);
    CHECK(asv9,9);
    CHECK(asv10,10);
    CHECK(asv11,11);

    //
    // If we actually found a trashing, report it
    //

    if (wBadVariable)
      {
      int i;
      char szMsg[255];
      char szMsg1[255];
      char szMsg2[128];
      char szNum[10];

      //
      // Generate a string of the queue values, using a "*" for the zero
      // value to indicate the end of the queue
      //

      *szMsg1 = 0;
      for ( i = 0; i < 10; i++ )
        {
        if (wQueue[i])
          wsprintf ( szNum, "%d", wQueue[i]);
        else
          lstrcpy ( szNum, "*" );
        if (i != 9)
          lstrcat ( szNum, "," );
        lstrcat ( szMsg1, szNum );
        }

      //
      // Create a cute string showing the programmer/unlucky enduser the list
      //

      wsprintf ( szMsg, "%s (%s)",
                 (LPSTR)"Assertion Failure",
                 (LPSTR)szMsg1
               );

      //
      // Create a caption saying which varaible was trashed, and it's value
      //

      wsprintf ( szMsg2, "Assertion Variable asv%d=%d", wBadVariable, wBadValue );

      //
      // Alert the programmer/unlucky enduser
      //

      MessageBox ( NULL, szMsg, szMsg2, MB_SYSTEMMODAL );

      }  // end if bad value
    }
  while (wBadVariable); // Keep doing this until assertion varaibles are clean

} // end function

