gnugo-devel
[Top][All Lists]
Advanced

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

Re: [gnugo-devel] another regression patch


From: Gunnar Farneback
Subject: Re: [gnugo-devel] another regression patch
Date: Sat, 21 Sep 2002 22:50:17 +0200
User-agent: EMH/1.14.1 SEMI/1.14.3 (Ushinoya) FLIM/1.14.2 (Yagi-Nishiguchi) APEL/10.3 Emacs/20.7 (sparc-sun-solaris2.7) (with unibyte mode)

Arend wrote:
> Most of the .sgf files you added (at least those I tried) are broken in
> CVS.  E.g. all blunder files except blunder17.sgf. Somewhere in the tool
> chain there seems to be a problem with lines longer than 990 characters.

As usual this turned out to be a mailer problem. (That it also
propagated into CVS was due to unfortunate circumstances.) The files
have been fixed for a while already.

However, I don't think --printsgf should write such long lines in the
first place. The appended patch makes GNU Go write nicer-looking sgf
files in general. This involves a major revision of all code to write
sgf files in sgfnode.c. 

Another change is that --printsgf creates a cleaner file and adjusts
komi to compensate for captured stones.

I modified the sgf reading code to use the EOF macro rather than -1. I
also changed an incorrect '\0' (a bizarre way to write 0, btw) to EOF.
This causes the code to fail reading certain truncated files (such as
some of those turning up broken in cvs) rather than hang in an eternal
loop.

- sgffile_loadandprint() renamed to sgffile_printsgf() and revised
- use EOF rather than -1 the code to read sgf files in sgfnode.c
- major revision of code to write an sgf tree to file in sgfnode.c

I hope I didn't break anything. The things I've tested look okay but
more extensive testing would be welcome.

/Gunnar

Index: engine/gnugo.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/gnugo.h,v
retrieving revision 1.68
diff -u -r1.68 gnugo.h
--- engine/gnugo.h      16 Sep 2002 07:27:48 -0000      1.68
+++ engine/gnugo.h      21 Sep 2002 20:37:48 -0000
@@ -477,7 +477,7 @@
 void sgffile_add_debuginfo(SGFNode *node, int value);
 void sgffile_output(SGFTree *tree);
 
-void sgffile_loadandprint(SGFTree *tree, int next);
+void sgffile_printsgf(int color_to_play, const char *filename);
 void sgffile_printboard(SGFTree *tree);
 void sgffile_recordboard(SGFNode *node);
 
Index: engine/sgffile.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/sgffile.c,v
retrieving revision 1.22
diff -u -r1.22 sgffile.c
--- engine/sgffile.c    16 Sep 2002 08:37:08 -0000      1.22
+++ engine/sgffile.c    21 Sep 2002 20:37:48 -0000
@@ -142,29 +142,45 @@
 
 
 /*
- * sgffile_loadandprint adds the current board position as well as
- * information about who is to play and illegal moves to the tree.
+ * sgffile_printsgf creates an sgf of the current board position
+ * (without any move history). It also adds information about who is
+ * to play and marks illegal moves with the private sgf property IL.
  */
 
 void
-sgffile_loadandprint(SGFTree *tree, int next)
+sgffile_printsgf(int color_to_play, const char *filename)
 {
+  SGFTree sgftree;
   int m, n;
   char pos[3];
+  char str[128];
+  float relative_komi;
+
+  relative_komi = komi + black_captured - white_captured;
+  
+  sgftree_clear(&sgftree);
+  sgftreeCreateHeaderNode(&sgftree, board_size, relative_komi);
+  sgf_write_header(sgftree.root, 1, random_seed, relative_komi,
+                  level, chinese_rules);
+  gg_snprintf(str, 128, "GNU Go %s load and print", gg_version());
+  sgfOverwriteProperty(sgftree.root, "GN", str);
   
-  sgffile_printboard(tree);
+  sgffile_printboard(&sgftree);
   
-  if (next == EMPTY)
+  if (color_to_play == EMPTY)
     return;
 
-  sgfAddProperty(tree->lastnode, "PL", (next == WHITE ? "W" : "B"));
+  sgfAddProperty(sgftree.lastnode, "PL", (color_to_play == WHITE ? "W" : "B"));
 
   for (m = 0; m < board_size; ++m)
     for (n = 0; n < board_size; ++n)
-      if (BOARD(m, n) == EMPTY && !is_legal(POS(m, n), next)) {
-       gg_snprintf(pos, 3, "%c%c", 'a' + n, 'a' + m);
-       sgfAddProperty(tree->lastnode, "IL", pos);
+      if (BOARD(m, n) == EMPTY && !is_legal(POS(m, n), color_to_play)) {
+       gg_snprintf(pos, 3, "%c%c", 'a' + n, 'a' + m);
+       sgfAddProperty(sgftree.lastnode, "IL", pos);
       }
+
+
+  writesgf(sgftree.root, filename);
 }
 
 
Index: interface/main.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/interface/main.c,v
retrieving revision 1.52
diff -u -r1.52 main.c
--- interface/main.c    16 Sep 2002 08:37:08 -0000      1.52
+++ interface/main.c    21 Sep 2002 20:37:51 -0000
@@ -933,11 +933,7 @@
       if (mandated_color != EMPTY)
         gameinfo.to_move = mandated_color;
 
-      sgftree.root->child = NULL;
-      sgftreeSetLastNode(&sgftree, sgftree.root);
-      sgffile_loadandprint(&sgftree, gameinfo.to_move);
-
-      writesgf(sgftree.root, printsgffile);
+      sgffile_printsgf(gameinfo.to_move, printsgffile);
     }
     break;
     
Index: sgf/sgfnode.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/sgf/sgfnode.c,v
retrieving revision 1.17
diff -u -r1.17 sgfnode.c
--- sgf/sgfnode.c       16 Sep 2002 08:37:08 -0000      1.17
+++ sgf/sgfnode.c       21 Sep 2002 20:37:55 -0000
@@ -68,7 +68,7 @@
   void *pt = malloc(size);
 
   if (!pt) {
-    fprintf(stderr, "%s: Out of memory!\n", "xalloc");
+    fprintf(stderr, "xalloc: Out of memory!\n");
     exit(2);
   }
 
@@ -82,7 +82,7 @@
   void *ptnew = realloc(pt, size);
 
   if (!ptnew) {
-    fprintf(stderr, "%s: Out of memory!\n", "xrealloc");
+    fprintf(stderr, "xrealloc: Out of memory!\n");
     exit(2);
   }
   return ptnew;
@@ -233,6 +233,24 @@
 
 
 /*
+ * Is there a property of this type in the node?
+ */
+
+static int
+sgfHasProperty(SGFNode *node, const char *name)
+{
+  SGFProperty *prop;
+  short nam = name[0] | name[1] << 8;
+
+  for (prop = node->props; prop; prop = prop->next)
+    if (prop->name == nam)
+      return 1;
+
+  return 0;
+}
+
+
+/*
  * Overwrite a property from an SGF node with text or create a new
  * one if it does not exist.
  */
@@ -694,6 +712,76 @@
 }
 
 
+/*
+ * Write result of the game to the game tree.
+ */
+
+void
+sgfWriteResult(SGFNode *node, float score, int overwrite)
+{
+  char text[8];
+  char winner;
+  float s;
+  int dummy;
+
+  /* If not writing to the SGF file, skip everything and return now. */
+  if (!node)
+    return;
+
+  /* If not overwriting and there already is a result property, return. */
+  if (!overwrite)
+    if (sgfGetIntProperty(node, "RE", &dummy))
+      return;
+
+  if (score > 0.0) {
+    winner = 'W';
+    s = score;
+  }
+  else if (score < 0.0) {
+    winner = 'B';
+    s = -score;
+  }
+  else {
+    winner = '0';
+    s = 0;
+  }
+
+  if (winner == '0')
+    gg_snprintf(text, 8, "0");
+  else if (score < 1000.0 && score > -1000.0)
+    gg_snprintf(text, 8, "%c+%3.1f", winner, s);
+  else
+    gg_snprintf(text, 8, "%c+%c", winner, 'R');
+  sgfOverwriteProperty(node, "RE", text);
+}
+
+
+void
+sgf_write_header(SGFNode *root, int overwrite, int seed, float komi,
+                int level, int rules)
+{
+  time_t curtime = time(NULL);
+  struct tm *loctime = localtime(&curtime);
+  char str[128];
+  int dummy;
+
+  gg_snprintf(str, 128, "GNU Go %s Random Seed %d level %d", 
+             VERSION, seed, level);
+  if (overwrite || !sgfGetIntProperty(root, "GN", &dummy))
+    sgfOverwriteProperty(root, "GN", str);
+  gg_snprintf(str, 128, "%4.4i-%2.2i-%2.2i",
+             loctime->tm_year+1900, loctime->tm_mon+1, loctime->tm_mday);
+  if (overwrite || !sgfGetIntProperty(root, "DT", &dummy))
+    sgfOverwriteProperty(root, "DT", str);
+  if (overwrite || !sgfGetIntProperty(root, "AP", &dummy))
+    sgfOverwriteProperty(root, "AP", "GNU Go "VERSION);
+  if (overwrite || !sgfGetIntProperty(root, "RU", &dummy))
+    sgfOverwriteProperty(root, "RU", rules ? "Chinese" : "Japanese");
+  sgfOverwriteProperty(root, "FF", "4");
+  sgfOverwritePropertyFloat(root, "KM", komi);
+}
+
+
 /* ================================================================ */
 /*                          Read SGF tree                           */
 /* ================================================================ */
@@ -788,10 +876,10 @@
 static void
 propident(char *buffer, int size)
 {
-  if (lookahead == -1 || !isupper(lookahead)) 
+  if (lookahead == EOF || !isupper(lookahead)) 
     parse_error("Expected an upper case letter.", 0);
   
-  while (lookahead != -1 && isalpha(lookahead)) {
+  while (lookahead != EOF && isalpha(lookahead)) {
     if (isupper(lookahead) && size > 1) {
       *buffer++ = lookahead;
       size--;
@@ -808,7 +896,7 @@
   char *p = buffer;
 
   match('[');
-  while (lookahead != ']' && lookahead != '\0') {
+  while (lookahead != ']' && lookahead != EOF) {
     if (lookahead == '\\') {
       lookahead = sgf_getch();
       /* Follow the FF4 definition of backslash */
@@ -859,7 +947,7 @@
 {
   SGFProperty *last = NULL;
   match(';');
-  while (lookahead != -1 && isupper(lookahead))
+  while (lookahead != EOF && isupper(lookahead))
     last = property(n, last);
 }
 
@@ -886,7 +974,7 @@
     match('(');
   else
     for (;;) {
-      if (lookahead == -1) {
+      if (lookahead == EOF) {
        parse_error("Empty file?", 0);
        break;
       }
@@ -932,7 +1020,7 @@
     match('(');
   else
     for (;;) {
-      if (lookahead == -1) {
+      if (lookahead == EOF) {
        parse_error("Empty file?", 0);
        break;
       }
@@ -1083,296 +1171,208 @@
 
 #define OPTION_STRICT_FF4 0
 
+static int sgf_column = 0;
 
-/*
- * p->child is the next move.
- * p->next  is the next variation
- */
-
-
-#if 0
-void
-sgf_putch(char c)
+static void
+sgf_putc(int c, FILE *file)
 {
-  fputc(c, ttsgfout);
-}
+  if (c == '\n' && sgf_column == 0)
+    return;
 
+  fputc(c, file);
 
-void
-sgf_puts(const char *s)
-{
-  fputs(s, ttsgfout);
-}
-
+  if (c == '\n')
+    sgf_column = 0;
+  else
+    sgf_column++;
 
-void
-sgf_putint(int i)
-{
-  char buf[10];
-  char *p = buf;
-  
-  if (i < 0) {
-    sgf_putch('-');
-    i = -i;
+  if (c == ']' && sgf_column > 60) {
+    fputc('\n', file);
+    sgf_column = 0;
   }
-  do {
-    *p++ = i % 10;
-    i /= 10;
-  } while (i > 9);
-  while (p > buf)
-    sgf_putch((char) (*--p + '0'));
-  /* MS-C complains even of this conversion, if not cast... */
 }
 
-
 static void
-unparse_prop(SGFProperty *p)
+sgf_puts(const char *s, FILE *file)
 {
-  char name[3], *cp;
-
-  name[2] = 0;
-  while (p != NULL) {
-    name[0] = p->name & 255;
-    name[1] = p->name >> 8;
-    if (name[1] == ' ')
-      name[1] = 0;
-    sgf_puts(name);
-    sgf_putch('[');
-    for (cp = p->value; *cp; cp++) {
-      if (*cp == '[' || *cp == ']' || *cp == '\\')
-       sgf_putch('\\');
-      sgf_putch(*cp);
+  for (; *s; s++) {
+    if (*s == '[' || *s == ']' || *s == '\\') {
+      fputc('\\', file);
+      sgf_column++;
     }
-    sgf_putch(']');
-    p = p->next;
+    fputc((int) *s, file);
+    sgf_column++;
   }
 }
-#endif
 
-
-/*
- * Print all unprinted property values at node N to file.
+/* Print all properties with the given name in a node to file and mark
+ * them as printed.
+ *
+ * If is_comment is 1, multiple properties are concatenated with a
+ * newline. I.e. we write
+ *
+ * C[comment1
+ * comment2]
+ *
+ * instead of
+ *
+ * C[comment1][comment2]
+ *
+ * Most other property types should be written in the latter style.
  */
 
 static void
-sgfPrintAllProperties(FILE *file, SGFNode *node)
+sgf_print_name(FILE *file, short name)
 {
-  SGFProperty *prop;
-  SGFProperty *last;
-  
-  prop = node->props;
-  if (!prop)
-    return;
-
-  do {
-    if (!(prop->name & 0x20)) {
-      last = prop;
-          
-      fprintf(file, "%c%c[%s]", prop->name&0xff, (prop->name>>8) & 0xff, 
-             prop->value);
-      prop = prop->next;
-      while (prop) {
-       if (last->name == prop->name) {
-         fprintf(file, "[%s]", prop->value);
-         prop->name |= 0x20;  /* indicate already printed */
-       }
-       prop = prop->next;
-      }
-      prop = last;
-      prop->name |= 0x20;  /* indicate already printed */
-    }
-    prop = prop->next;
-  } while (prop);
+  sgf_putc(name & 0xff, file);
+  if (name >> 8 != ' ')
+    sgf_putc(name >> 8, file);
 }
 
-
-/*
- * Print the property values of NAME at node N and mark it as printed. 
- */
-
-int
-sgfPrintCharProperty(FILE *file, SGFNode *node, const char *name)
+static void
+sgf_print_property(FILE *file, SGFNode *node, short name, int is_comment)
 {
-  int first = 1;
+  int n = 0;
   SGFProperty *prop;
-  short nam = name[0] | name[1] << 8;
 
   for (prop = node->props; prop; prop = prop->next) {
-    if (prop->name == nam) {
-      prop->name |= 0x20;  /* indicate already printed */
-      if (first) {
-       if (name[1] == ' ')
-         fprintf(file, "%c", name[0]);
-       else
-         fprintf(file, "%s", name);
-       first = 0;
+    if (prop->name == name) {
+      prop->name |= 0x20;  /* Indicate already printed. */
+      if (n == 0) {
+       sgf_print_name(file, name);
+       sgf_putc('[', file);
+      }
+      else if (is_comment)
+       sgf_putc('\n', file);
+      else {
+       sgf_putc(']', file);
+       sgf_putc('[', file);
       }
-      fprintf(file, "[%s]", prop->value);
+      
+      sgf_puts(prop->value, file);
+      n++;
     }
   }
 
-  return !first;
-}
+  if (n > 0)
+    sgf_putc(']', file);
 
+  /* Add a newline after certain properties. */
+  if (name == SGFAB || name == SGFAW || name == SGFAE || (is_comment && n > 1))
+    sgf_putc('\n', file);
+}
 
 /*
- * Print comments from Node node.
- *
- * NOTE: cgoban does not print "C[comment1][comment2]" and I don't know
- *       what the sgfspec says.
+ * Print all remaining unprinted property values at node N to file.
  */
 
-int
-sgfPrintCommentProperty(FILE *file, SGFNode *node, const char *name)
+static void
+sgfPrintRemainingProperties(FILE *file, SGFNode *node)
 {
-  int first = 1;
   SGFProperty *prop;
-  short nam = name[0] | name[1] << 8;
-
-  for (prop = node->props; prop; prop = prop->next) {
-    if (prop->name == nam) {
-      prop->name |= 0x20;  /*indicate already printed*/
-      if (first) {
-       if (name[1] == ' ')
-         fprintf(file, "%c[%s", name[0], prop->value);
-       else
-         fprintf(file, "%s[%s", name, prop->value);
-       first = 0;
-      }
-      else
-       fprintf(file, "\n%s", prop->value);
-    }
-  }
 
-  if (!first) {
-    fprintf(file, "]");
-    return 1;
-  }
-  else
-    return 0;
+  for (prop = node->props; prop; prop = prop->next)
+    if (!(prop->name & 0x20))
+      sgf_print_property(file, node, prop->name, 0);
 }
 
 
 /*
- * Write result of the game to the game tree.
+ * Print the property values of NAME at node N and mark it as printed. 
  */
 
-void
-sgfWriteResult(SGFNode *node, float score, int overwrite)
-{
-  char text[8];
-  char winner;
-  float s;
-  int dummy;
-
-  /* If not writing to the SGF file, skip everything and return now. */
-  if (!node)
-    return;
-
-  /* If not overwriting and there already is a result property, return. */
-  if (!overwrite)
-    if (sgfGetIntProperty(node, "RE", &dummy))
-      return;
-
-  if (score > 0.0) {
-    winner = 'W';
-    s = score;
-  }
-  else if (score < 0.0) {
-    winner = 'B';
-    s = -score;
-  }
-  else {
-    winner = '0';
-    s = 0;
-  }
-
-  if (winner == '0')
-    gg_snprintf(text, 8, "0");
-  else if (score < 1000.0 && score > -1000.0)
-    gg_snprintf(text, 8, "%c+%3.1f", winner, s);
-  else
-    gg_snprintf(text, 8, "%c+%c", winner, 'R');
-  sgfOverwriteProperty(node, "RE", text);
-}
-
-
 static void
-restore_property(SGFProperty *prop)
+sgfPrintCharProperty(FILE *file, SGFNode *node, const char *name)
 {
-  if(prop) {
-    restore_property(prop->next);
-    prop->name&=~0x20;
-  }
+  short nam = name[0] | name[1] << 8;
+  
+  sgf_print_property(file, node, nam, 0);
 }
 
 
+/*
+ * Print comments from Node node.
+ *
+ * NOTE: cgoban does not print "C[comment1][comment2]" and I don't know
+ *       what the sgfspec says.
+ */
+
 static void
-restore_node(SGFNode *node)
+sgfPrintCommentProperty(FILE *file, SGFNode *node, const char *name)
 {
-  if (node) {
-    restore_property(node->props);
-    restore_node(node->child);
-    restore_node(node->next);
-  }
+  short nam = name[0] | name[1] << 8;
+  
+  sgf_print_property(file, node, nam, 1);
 }
 
 
 static void
 unparse_node(FILE *file, SGFNode *node)
 {
-  fputs("\n ;", file);
+  sgf_putc(';', file);
   sgfPrintCharProperty(file, node, "B ");
   sgfPrintCharProperty(file, node, "W ");
   sgfPrintCommentProperty(file, node, "N ");
   sgfPrintCommentProperty(file, node, "C ");
-  if (sgfPrintCommentProperty(file, node, "PB")
-      || sgfPrintCommentProperty(file, node, "BR"))
-    fputs("\n", file);
-  if (sgfPrintCommentProperty(file, node, "PW")
-      || sgfPrintCommentProperty(file, node, "WR"))
-    fputs("\n", file);
-  sgfPrintAllProperties(file, node);
+  sgfPrintRemainingProperties(file, node);
 }
 
 
 static void
-unparse_root(FILE *file, SGFNode *node, int root)
+unparse_root(FILE *file, SGFNode *node)
 {
-  fputs(";", file);
+  sgf_putc(';', file);
+  
+  if (sgfHasProperty(node, "GM"))
+    sgfPrintCharProperty(file, node, "GM");
+  else {
+    fputs("GM[1]", file);
+    sgf_column += 5;
+  }
+  
   sgfPrintCharProperty(file, node, "FF");
-  if (sgfPrintCharProperty(file, node, "GM"))
-    fputs("\n", file);
-  else if (root)
-    fputs("GM[1]\n", file);
-
-  if (sgfPrintCharProperty(file, node, "SZ"))
-    fputs("\n", file);
-  if (sgfPrintCharProperty(file, node, "GN"))
-    fputs("\n", file);
-  if (sgfPrintCharProperty(file, node, "DT"))
-    fputs("\n", file);
-  if (sgfPrintCommentProperty(file, node, "PB")
-      || sgfPrintCommentProperty(file, node, "BR"))
-    fputs("\n", file);
-  if (sgfPrintCommentProperty(file, node, "PW")
-      || sgfPrintCommentProperty(file, node, "WR"))
-    fputs("\n", file);
-  sgfPrintCharProperty(file, node, "B ");
-  sgfPrintCharProperty(file, node, "W ");
+  sgf_putc('\n', file);
+
+  sgfPrintCharProperty(file, node, "SZ");
+  sgf_putc('\n', file);
+  
+  sgfPrintCharProperty(file, node, "GN");
+  sgf_putc('\n', file);
+  
+  sgfPrintCharProperty(file, node, "DT");
+  sgf_putc('\n', file);
+  
+  sgfPrintCommentProperty(file, node, "PB");
+  sgfPrintCommentProperty(file, node, "BR");
+  sgf_putc('\n', file);
+  
+  sgfPrintCommentProperty(file, node, "PW");
+  sgfPrintCommentProperty(file, node, "WR");
+  sgf_putc('\n', file);
+  
   sgfPrintCommentProperty(file, node, "N ");
   sgfPrintCommentProperty(file, node, "C ");
-  sgfPrintAllProperties(file, node);
+  sgfPrintRemainingProperties(file, node);
+
+  sgf_putc('\n', file);
 }
 
 
+/*
+ * p->child is the next move.
+ * p->next  is the next variation
+ */
+
 static void
 unparse_game(FILE *file, SGFNode *node, int root)
 {
   if (!root)
-    fputc('\n', file);
-  fputc('(', file);
-  unparse_root(file, node, root);
+    sgf_putc('\n', file);
+  sgf_putc('(', file);
+  if (root)
+    unparse_root(file, node);
+  else
+    unparse_node(file, node);
 
   node = node->child;
   while (node != NULL && node->next == NULL) {
@@ -1384,34 +1384,39 @@
     unparse_game(file, node, 0);
     node = node->next;
   }
-  fputs(")", file);
+  sgf_putc(')', file);
+  if (root)
+    sgf_putc('\n', file);
 }
 
-void
-sgf_write_header(SGFNode *root, int overwrite, int seed, float komi,
-                int level, int rules)
+/* Printed properties are marked by adding the 0x20 bit to the
+ * property name (changing an upper case letter to lower case). This
+ * function removes this mark so that we can print the property next
+ * time too. It recurses to all properties in the linked list.
+ */
+static void
+restore_property(SGFProperty *prop)
 {
-  time_t curtime = time(NULL);
-  struct tm *loctime = localtime(&curtime);
-  char str[128];
-  int dummy;
+  if (prop) {
+    restore_property(prop->next);
+    prop->name &= ~0x20;
+  }
+}
 
-  gg_snprintf(str, 128, "GNU Go %s Random Seed %d level %d", 
-             VERSION, seed, level);
-  if (overwrite || !sgfGetIntProperty(root, "GN", &dummy))
-    sgfOverwriteProperty(root, "GN", str);
-  gg_snprintf(str, 128, "%4.4i-%2.2i-%2.2i",
-             loctime->tm_year+1900, loctime->tm_mon+1, loctime->tm_mday);
-  if (overwrite || !sgfGetIntProperty(root, "DT", &dummy))
-    sgfOverwriteProperty(root, "DT", str);
-  if (overwrite || !sgfGetIntProperty(root, "AP", &dummy))
-    sgfOverwriteProperty(root, "AP", PACKAGE":"VERSION);
-  if (overwrite || !sgfGetIntProperty(root, "RU", &dummy))
-    sgfOverwriteProperty(root, "RU", rules ? "Chinese" : "Japanese");
-  sgfOverwriteProperty(root, "FF", "4");
-  sgfOverwritePropertyFloat(root, "KM", komi);
+/* When called with the tree root, recurses to all properties in the
+ * tree and removes all print marks.
+ */
+static void
+restore_node(SGFNode *node)
+{
+  if (node) {
+    restore_property(node->props);
+    restore_node(node->child);
+    restore_node(node->next);
+  }
 }
 
+
 /*
  * Opens filename and writes the game stored in the sgf structure.
  */
@@ -1431,6 +1436,7 @@
     return 0;
   }
 
+  sgf_column = 0;
   unparse_game(outfile, root, 1);
   fclose(outfile);
   
Index: sgf/sgftree.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/sgf/sgftree.h,v
retrieving revision 1.13
diff -u -r1.13 sgftree.h
--- sgf/sgftree.h       16 Sep 2002 08:37:08 -0000      1.13
+++ sgf/sgftree.h       21 Sep 2002 20:37:55 -0000
@@ -80,7 +80,7 @@
 void sgfOverwriteProperty(SGFNode *node, const char *name, const char *text);
 void sgfOverwritePropertyFloat(SGFNode *node, const char *name, float val);
 void sgfOverwritePropertyInt(SGFNode *node, const char *name, int val);
-void * xrealloc(void *pt, unsigned int size);
+void *xrealloc(void *pt, unsigned int size);
 SGFProperty *sgfMkProperty(const char *name, const  char *value,
                           SGFNode *node, SGFProperty *last);
 void sgfFreeProperty(SGFProperty *prop);
@@ -89,9 +89,9 @@
 SGFNode *sgfAddPlay(SGFNode *node, int who, int movex, int movey);
 SGFNode *sgfAddPlayLast(SGFNode *node, int who, int movex, int movey);
 
-int sgfPrintCharProperty(FILE *file, SGFNode *node, const char *name);
-int sgfPrintCommentProperty(FILE *file, SGFNode *node, const char *name);
 void sgfWriteResult(SGFNode *node, float score, int overwrite);
+void sgf_write_header(SGFNode *root, int overwrite, int seed, float komi,
+                     int level, int rules);
 
 SGFNode *sgfLabel(SGFNode *node, const char *label, int i, int j);
 SGFNode *sgfLabelInt(SGFNode *node, int num, int i, int j);
@@ -115,8 +115,6 @@
 SGFNode *readsgffilefuseki(const char *filename, int moves_per_game);
 
 /* Write SGF tree to a file. */
-void sgf_write_header(SGFNode *root, int overwrite, int seed, float komi,
-                     int level, int rules);
 int writesgf(SGFNode *root, const char *filename);
 
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]