From fbbe9044acc239cb48630e2947b0098b05cedee5 Mon Sep 17 00:00:00 2001
From: Mike Curtis <Michael.C.Curtis@gmail.com>
Date: Tue, 9 Apr 2013 14:11:49 -0500
Subject: [PATCH] DevNull speedup options for TextBuffer class and sc_game pgn
 -format

---
 src/game.cpp        |    2 ++
 src/game.h          |    4 +++-
 src/textbuf.cpp     |   47 ++++++++++++++++++++++++++++++++++++-----------
 src/textbuf.h       |    6 +++++-
 src/tkscid.cpp      |    4 +++-
 tcl/windows/pgn.tcl |   11 +++--------
 6 files changed, 52 insertions(+), 22 deletions(-)

diff --git a/src/game.cpp b/src/game.cpp
index dc9051b..ea6eeb3 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -731,6 +731,8 @@ Game::PgnFormatFromString (const char * str, gameFormatT * fmt)
         *fmt = PGN_FORMAT_LaTeX;
     } else if (strIsCasePrefix (str, "Color")) {
         *fmt = PGN_FORMAT_Color;
+    } else if (strIsCasePrefix (str, "DevNull")) {
+        *fmt = PGN_FORMAT_DevNull;
     } else {
         return false;
     }
diff --git a/src/game.h b/src/game.h
index 8a4e6ae..10951e6 100644
--- a/src/game.h
+++ b/src/game.h
@@ -209,7 +209,8 @@ enum gameFormatT {
     PGN_FORMAT_Plain = 0,   // Plain regular PGN output
     PGN_FORMAT_HTML = 1,    // HTML format
     PGN_FORMAT_LaTeX = 2,   // LaTeX (with chess12 package) format
-    PGN_FORMAT_Color = 3    // PGN, with color tags <red> etc
+    PGN_FORMAT_Color = 3,   // PGN, with color tags <red> etc
+    PGN_FORMAT_DevNull = 4  // No output, but set key variables such as PgnNextMovePos PgnLastMovePos 
 };
 
 #define PGN_STYLE_TAGS             1
@@ -545,6 +546,7 @@ public:
     bool      IsHtmlFormat  () { return (PgnFormat == PGN_FORMAT_HTML); }
     bool      IsLatexFormat () { return (PgnFormat == PGN_FORMAT_LaTeX); }
     bool      IsColorFormat () { return (PgnFormat == PGN_FORMAT_Color); }
+    bool      IsDevNullFormat () { return (PgnFormat == PGN_FORMAT_DevNull); }
 
     void      SetHtmlStyle (uint style) { HtmlStyle = style; }
     uint      GetHtmlStyle () { return HtmlStyle; }
diff --git a/src/textbuf.cpp b/src/textbuf.cpp
index 1b59ad9..0129e99 100644
--- a/src/textbuf.cpp
+++ b/src/textbuf.cpp
@@ -30,6 +30,7 @@ TextBuffer::Init (void)
     ConvertNewlines = true;
     HasTranslations = false;
     PausedTranslations = false;
+    DevNull = false;
 }
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -68,6 +69,7 @@ TextBuffer::Empty (void)
 void
 TextBuffer::AddTranslation (char ch, const char * str)
 {
+  if (!IsDevNull()) {
     if (! HasTranslations) {
         HasTranslations = true;
         for (uint i=0; i < 256; i++) {
@@ -75,6 +77,7 @@ TextBuffer::AddTranslation (char ch, const char * str)
         }
     }
     Translation [(byte) ch] = str;
+  }
 }
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -100,6 +103,7 @@ TextBuffer::SetBufferSize (uint length)
 errorT
 TextBuffer::NewLine ()
 {
+  if (!IsDevNull()) {
     ASSERT (Current != NULL);
     if (ByteCount >= BufferSize) { return ERROR_BufferFull; }
     *Current++ = '\n'; 
@@ -110,7 +114,8 @@ TextBuffer::NewLine ()
         *Current++ = ' '; Column++; ByteCount++;
     }
     *Current = 0;
-    return OK;
+  }
+  return OK;
 }
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -118,6 +123,7 @@ TextBuffer::NewLine ()
 errorT
 TextBuffer::Indent ()
 {
+  if (!IsDevNull()) {
     ASSERT (Current != NULL);
     if (!LineIsEmpty) {
         return NewLine();
@@ -128,7 +134,8 @@ TextBuffer::Indent ()
         }
         *Current = 0;
     }
-    return OK;
+  }
+  return OK;
 }
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -137,6 +144,7 @@ TextBuffer::Indent ()
 errorT
 TextBuffer::PrintLine (const char * str)
 {
+  if (!IsDevNull()) {
     ASSERT(Current != NULL);
     while (*str != 0) {
         if (ByteCount > BufferSize) { return ERROR_BufferFull; }
@@ -144,6 +152,8 @@ TextBuffer::PrintLine (const char * str)
         str++;
     }
     return NewLine();
+  }
+  else return OK;
 }
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -153,6 +163,7 @@ TextBuffer::PrintLine (const char * str)
 errorT
 TextBuffer::PrintWord (const char * str)
 {
+  if (!IsDevNull()) {
     ASSERT(Current != NULL);
     uint length = strLength (str);
     if (Column + length >= WrapColumn)    { NewLine(); }
@@ -175,7 +186,8 @@ TextBuffer::PrintWord (const char * str)
     }
     *Current = 0;  // add trailing end-of-string to buffer
     LineIsEmpty = 0;
-    return OK;
+  }
+  return OK;
 }
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -184,13 +196,15 @@ TextBuffer::PrintWord (const char * str)
 errorT
 TextBuffer::PrintSpace (void)
 {
+  if (!IsDevNull()) {
     if (ByteCount + 1 >= BufferSize)  { return ERROR_BufferFull; }
     if (Column + 1 >= WrapColumn) {
         NewLine();
     } else {
         *Current = ' '; Current++; ByteCount++; Column++; LineIsEmpty = 0;
     }
-    return OK;
+  }
+  return OK;
 }
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -199,11 +213,13 @@ TextBuffer::PrintSpace (void)
 errorT
 TextBuffer::PrintChar (char b)
 {
+  if (!IsDevNull()) {
     if (Column + 1 >= WrapColumn)  { NewLine(); }
     if (ByteCount + 1 >= BufferSize)  { return ERROR_BufferFull; }
     AddChar (b);
     Column++; LineIsEmpty = 0;
-    return OK;
+  }
+  return OK;
 }
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -212,6 +228,7 @@ TextBuffer::PrintChar (char b)
 errorT
 TextBuffer::PrintString (const char * str)
 {
+  if (!IsDevNull()) {
     errorT err;
     char currentWord[1024];  // should be long enough for a word
     while (*str != 0) {
@@ -234,7 +251,8 @@ TextBuffer::PrintString (const char * str)
         if (err != OK) { return err; }
         str++;
     }
-    return OK;
+  }
+  return OK;
 }
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -244,15 +262,19 @@ TextBuffer::PrintString (const char * str)
 errorT
 TextBuffer::PrintInt (uint i, const char * str)
 {
+  if (!IsDevNull()) {
     char temp[255];
-    sprintf(temp, "%d%s", i, str);
+    sprintf(temp, "%d%s", i, str);    
     return PrintWord(temp);
+  }
+  else return OK;
 }
 
 #ifdef WINCE
 errorT
 TextBuffer::DumpToFile (/*FILE * */Tcl_Channel fp)
 {
+  if (!IsDevNull()) {
     ASSERT (fp != NULL);
     //uint count = 0;
     char * b = Buffer;
@@ -262,7 +284,8 @@ TextBuffer::DumpToFile (/*FILE * */Tcl_Channel fp)
         count++; b++;
     }*/
     my_Tcl_Write(fp, b, ByteCount);
-    return OK;
+  }
+  return OK;
 }
 
 #else
@@ -272,14 +295,16 @@ TextBuffer::DumpToFile (/*FILE * */Tcl_Channel fp)
 errorT
 TextBuffer::DumpToFile (FILE * fp)
 {
+  if (!IsDevNull()) {
     ASSERT (fp != NULL);
     uint count = 0;
     char * b = Buffer;
     while (count < ByteCount) {
-        putc (*b, fp);
-        count++; b++;
+      putc (*b, fp);
+      count++; b++;
     }
-    return OK;
+  }
+  return OK;
 }
 #endif
 ///////////////////////////////////////////////////////////////////////////
diff --git a/src/textbuf.h b/src/textbuf.h
index 38df582..9f84875 100644
--- a/src/textbuf.h
+++ b/src/textbuf.h
@@ -34,6 +34,7 @@ private:
     uint   ByteCount;
     uint   BufferSize;
     bool   ConvertNewlines;  // If true, convert newlines to spaces.
+    bool   DevNull;
     char * Buffer;
     char * Current;
 
@@ -83,7 +84,8 @@ public:
     void     SetIndent (uint column) { IndentColumn = column; }
     char *   GetBuffer ()        { return Buffer; }
     void     NewlinesToSpaces (bool b) { ConvertNewlines = b; }
-
+    void     SetDevNull (bool b) { DevNull = b; }
+    bool     IsDevNull ()        { return DevNull; }
     void     AddTranslation (char ch, const char * str);
     // void     ClearTranslation (char ch) { Translation[ch] = NULL; }
     // Changed ch to int, to avoid compiler warnings. 
@@ -113,6 +115,7 @@ public:
 inline void
 TextBuffer::AddChar (char ch)
 {
+  if (!IsDevNull ()) {
     if (HasTranslations  &&  !PausedTranslations) {
         byte b = (byte) ch;
         const char * str = Translation[b];
@@ -128,6 +131,7 @@ TextBuffer::AddChar (char ch)
     *Current = ch;
     Current++;
     ByteCount++;
+  }
 }
 
 #endif  // SCID_TEXTBUF_H
diff --git a/src/tkscid.cpp b/src/tkscid.cpp
index ae63f5c..1f9e9f6 100644
--- a/src/tkscid.cpp
+++ b/src/tkscid.cpp
@@ -7966,7 +7966,7 @@ sc_game_pgn (ClientData cd, Tcl_Interp * ti, int argc, const char ** argv)
         OPT_COLUMN, OPT_COMMENTS, OPT_BASE, OPT_GAME_NUMBER, OPT_FORMAT,
         OPT_SHORT_HDR, OPT_INDENT_COMMENTS, OPT_INDENT_VARS,
         OPT_SYMBOLS, OPT_TAGS, OPT_VARS, OPT_WIDTH, OPT_SPACE,
-        OPT_NOMARKS, OPT_UNICODE,
+        OPT_NOMARKS, OPT_UNICODE
     };
 
     scidBaseT * base = db;
@@ -8082,8 +8082,10 @@ sc_game_pgn (ClientData cd, Tcl_Interp * ti, int argc, const char ** argv)
 
     base->tbuf->Empty();
     base->tbuf->SetWrapColumn (lineWidth);
+    if (g->IsDevNullFormat()) base->tbuf->SetDevNull(true);
     g->WriteToPGN (base->tbuf);
     Tcl_AppendResult (ti, base->tbuf->GetBuffer(), NULL);
+    base->tbuf->SetDevNull(false);
     return TCL_OK;
 }
 
diff --git a/tcl/windows/pgn.tcl b/tcl/windows/pgn.tcl
index e3ca1c1..c99cf5a 100644
--- a/tcl/windows/pgn.tcl
+++ b/tcl/windows/pgn.tcl
@@ -340,7 +340,7 @@ namespace eval pgn {
   #
   ################################################################################
   proc HideBoard {} {
-    wm withdraw .pgnPopup
+      if {[winfo exists .pgnPopup]} {wm withdraw .pgnPopup}
   }
   
   ################################################################################
@@ -402,13 +402,8 @@ namespace eval pgn {
     }
     
     if {$::pgn::showColor} {
-      #TODO: This code is slow.
-      #      Write a faster function to update PgnNextMovePos & PgnLastMovePos
-      sc_game pgn -symbols $::pgn::symbolicNags \
-        -indentVar $::pgn::indentVars -indentCom $::pgn::indentComments \
-        -space $::pgn::moveNumberSpaces -format color -column $::pgn::columnFormat \
-        -short $::pgn::shortHeader -markCodes $::pgn::stripMarks
-      #########################################
+      #  faster function call for updating PgnNextMovePos & PgnLastMovePos
+      sc_game pgn -format DevNull
 
       if { $::pgn::boldMainLine } {
         .pgnWin.text configure -font font_Bold
-- 
1.7.9.5

