root/05/release-0.5i/sgfpars.cc

Revision 41, 21.1 kB (checked in by ug, 5 years ago)

Updated copyright notice

Line 
1 // File: sgfpars.cc
2
3 //   Copyright (C) 2001-4 Ulrich Goertz (u@g0ertz.de)
4
5 //   This is part of Kombilo, a go database program.
6
7 //   This program is free software; you can redistribute it and/or modify
8 //   it under the terms of the GNU General Public License as published by
9 //   the Free Software Foundation; either version 2 of the License, or
10 //   (at your option) any later version.
11
12 //   This program is distributed in the hope that it will be useful,
13 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //   GNU General Public License for more details.
16
17 //   You should have received a copy of the GNU General Public License
18 //   along with this program (see doc/license.txt); if not, write to the Free Software
19 //   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 //   The GNU GPL is also currently available at
21 //   http://www.gnu.org/copyleft/gpl.html
22
23
24 #include <cstring>
25 #include "sgfpars.h"
26
27
28 intN::intN(int i, intN* p) {
29   data = i;
30   prev = p;
31 }
32
33 IntStack::IntStack() {
34   root = 0;
35 }
36
37 void IntStack::push(int i) {
38   intN* n = new intN(i, root);
39   root = n;
40 }
41
42 void IntStack::pop() {
43   intN* d = root;
44   root = d->prev;
45   delete d;
46 }
47
48 int IntStack::top() {
49   if (root) return root->data;
50   else return -1;
51 }
52
53 bool IntStack::nonempty() {
54   if (root) return 1;
55   else return 0;
56 }
57
58
59 nodeN::nodeN(Node* i, nodeN* p) {
60   data = i;
61   prev = p;
62 }
63
64 NodeStack::NodeStack() {
65   root = 0;
66 }
67
68 void NodeStack::push(Node* i) {
69   nodeN* n = new nodeN(i, root);
70   root = n;
71 }
72
73 void NodeStack::pop() {
74   nodeN* d = root;
75   root = d->prev;
76   delete d;
77 }
78
79 Node* NodeStack::top() {
80   if (root) return root->data;
81   else return 0;
82 }
83
84 bool NodeStack::nonempty() {
85   if (root) return 1;
86   else return 0;
87 }
88
89
90
91
92 SGFError::SGFError() {}
93
94 char* SGFescape(char* s) {
95   char* t = new char[2*strlen(s)+1];
96   int j = 0;
97   for(int i = 0; i<strlen(s); i++) {
98     if (s[i] == '\\' || s[i] == ']') t[j++]='\\';
99     t[j++] = s[i];
100   }
101                                    
102   t[j++] = 0;
103
104   char* result = new char[j];
105   strcpy(result, t);
106   delete t;
107   return result;
108 }
109
110 Node::Node(Node* prev, char* SGFst, int lvl=0) throw(SGFError) {
111   next = NULL;
112   previous = prev;
113   up = NULL;
114   down = NULL;
115
116   numChildren = 0;
117   level = lvl;
118        
119   parsed = 0;
120
121   if (SGFst) {
122     SGFstring = new char[strlen(SGFst)+1];
123     strcpy(SGFstring, SGFst);
124     if (!(data=PyDict_New())) throw SGFError();
125     parseNode();
126   }
127   else {
128     SGFstring = new char[1];
129     SGFstring[0] = 0;
130     if (!(data = PyDict_New())) throw SGFError();
131   }
132    
133   posyD = 0;
134 }
135        
136 Node::~Node() {
137   delete [] SGFstring;
138   Py_DECREF(data);
139 }
140
141
142 PyObject* Node::getData() {
143   if (!parsed) parseNode();
144   Py_INCREF(data);
145   return data;
146 }
147
148 PyObject* Node::pathToNode() {
149   PyObject* l = PyList_New(0);
150   Node* n = this;
151
152   while (n->previous) {
153     PyList_Append(l, PyInt_FromLong(n->level));
154     n = n->previous;
155   }       
156   PyList_Reverse(l);
157   return l;
158 }
159
160
161 void Node::parseNode() throw(SGFError) {
162   // printf("Parse node, %s\n", SGFstring);
163
164   if (!parsed) {
165
166     char* s = SGFstring;
167     int lSGFstring = strlen(s);
168     int i = 0;
169    
170     while (i < lSGFstring && s[i] != ';' && (s[i]==' ' || s[i]=='\n' || s[i]=='\r' || s[i]=='\t'))
171       i++;
172    
173     if (i>=lSGFstring) {
174       throw SGFError();
175     }
176     if (s[i] != ';') {
177       throw SGFError();
178     }
179     i++;
180    
181     while (i < lSGFstring) {
182       while (i < lSGFstring && (s[i]==' ' || s[i]=='\n' || s[i]=='\r' || s[i]=='\t'))
183         i++;
184      
185       if (i >= lSGFstring) break;
186      
187       char ID[20];
188       int IDindex = 0;
189      
190       while (i < lSGFstring && s[i] != '[') {
191         if (65 <= s[i] && s[i] <= 90)
192           ID[IDindex++] = s[i];
193         else if (!(97 <= s[i] && s[i] <= 122) && !(s[i]==' ' || s[i]=='\n' || s[i]=='\r' || s[i]=='\t')) {
194           throw SGFError();
195         }
196        
197         i++;
198       }
199      
200       i++;
201      
202       if (i >= lSGFstring) {
203         throw SGFError();
204       }
205      
206       if (!IDindex) {
207         throw SGFError();
208       }
209       ID[IDindex] = 0;
210      
211       if (PyDict_GetItemString(data, ID)) {
212         if (!Node::sloppy) {
213           throw SGFError();
214         }
215       }
216       else {
217         PyObject* nl = PyList_New(0);
218         if (!nl) {
219           throw SGFError();
220         }
221         if (PyDict_SetItemString(data, ID, nl)==-1) {
222           throw SGFError();
223         }
224         Py_DECREF(nl);
225       }
226      
227       PyObject* propertyValueList = PyDict_GetItemString(data, ID);
228       if (!propertyValueList) {
229         throw SGFError();
230       }
231      
232       while (i < lSGFstring) {
233         char* propValue = new char[lSGFstring+1];
234         int propValueIndex = 0;
235        
236         while (s[i] != ']') {
237          
238           //printf("i, s[i]: %d, %c\n", i, s[i]);
239           if (s[i] == '\t') {
240             propValue[propValueIndex++] = ' ';
241             i++;
242             continue;
243           }
244           if (s[i] == '\\') {
245             i++;
246            
247             if ((s[i]=='\n' && s[i+1]=='\r') || (s[i]=='\r' && s[i+1]=='\n')) {
248               i += 2;
249               continue;
250             }
251             else if (s[i]=='\n' || s[i]=='\r') {
252               i++;
253               continue;
254             }
255           }
256           propValue[propValueIndex++] = s[i];
257           i++;
258          
259           if (i >= lSGFstring) {
260             throw SGFError();
261           }
262         }
263        
264         propValue[propValueIndex] = 0;
265         PyObject* hlp = PyString_FromString(propValue);
266         PyList_Append(propertyValueList, hlp);
267         delete [] propValue;
268         Py_DECREF(hlp);
269        
270         i++;
271        
272         while (i < lSGFstring && (s[i]==' ' || s[i]=='\n' || s[i]=='\r' || s[i]=='\t'))
273           i++;
274        
275         if (i >= lSGFstring || s[i] != '[') break;
276         else i++;
277       }
278      
279       if (!strcmp(ID, "B") || !strcmp(ID, "W") || !strcmp(ID, "AW") || !strcmp(ID, "AB")) {
280         for(int N=0; N < PyList_Size(propertyValueList); N++) {
281           char* en = PyString_AsString(PyList_GetItem(propertyValueList, N));
282           char* en1 = new char[strlen(en)+1];
283           int jj = 0;
284          
285           for (int ii=0; ii<strlen(en); ii++) {
286             if (!Node::sloppy || !(en[ii]=='\n' || en[ii]=='\r'))
287               en1[jj++] = en[ii];
288           }
289           en1[jj] = 0;
290          
291           if (!(strlen(en1) == 2 || (strlen(en) == 0 && (!strcmp(ID,"B") || !strcmp(ID,"W"))))) {
292             throw SGFError();
293           }
294          
295           PyList_SetItem(propertyValueList, N, PyString_FromString(en1));
296           delete en1;
297         }
298       }                                       
299      
300     }
301     parsed = 1;
302   }
303 }   
304    
305
306 int Node::sloppy = 1;
307
308 Cursor::Cursor(char* sgf, int sloppy) throw(SGFError) {
309   Node::sloppy = sloppy;
310
311   height = 0;
312   width = 0;
313   posx = 0;
314   posy = 0;
315
316   root = new Node(NULL, NULL, 0);
317   parse(sgf);
318
319   currentN = root->next;
320   setFlags();       
321 }
322
323
324
325 Cursor::~Cursor() {
326   deltree(root);
327 }
328
329 void Cursor::setFlags() {
330   if (currentN->next) atEnd = 0;
331   else atEnd = 1;
332   if (currentN->previous) atStart = 0;
333   else atStart = 1;
334 }
335  
336 int Cursor::noChildren() {
337   return currentN->numChildren;
338 }
339
340 PyObject* Cursor::currentNode() {
341   if (!currentN->parsed)
342     currentN->parseNode();
343
344   Py_INCREF(currentN->data);
345   return currentN->data;
346 }
347
348 void Cursor::parse(char* s) throw(SGFError) {
349
350   Node* curr = root;       
351   int p = -1;           // start of the currently parsed node
352   NodeStack c;       // stack of nodes from which variations started
353   IntStack c_width;
354   IntStack c_height;
355
356   int height_previous = 0;
357   int width_currentVar = 0;
358
359   char last = ')';      // type of last parsed bracked ('(' or ')')
360   bool inbrackets = false;   // are the currently parsed characters in []'s?
361
362   int i = 0;  // current parser position
363   int lSGFstring = strlen(s);
364
365   int found_par = 0;
366   while (i < lSGFstring) {
367     if (s[i]=='(') {
368       found_par = i+1;
369       i++;
370       continue;
371     }
372     if (found_par && s[i]==';') break;
373    
374     if (found_par && !(s[i]==' ' || s[i]=='\n' || s[i]=='\r' || s[i]=='\t'))
375       found_par = 0;
376     i++;
377   }
378
379   if (i >= lSGFstring) throw SGFError();
380
381   i = found_par-1; // found beginning of SGF file
382         
383   while (i < lSGFstring) {
384     while (i < lSGFstring && !(s[i]=='(' || s[i]==')' || s[i]=='[' || s[i]==']' || s[i]==';')) i++;
385     if (i >= lSGFstring) break;
386
387     if (inbrackets) {
388       if (s[i]==']') {
389         int numberBackslashes = 0;
390         int j = i-1;
391         while (s[j] == '\\') {
392           numberBackslashes++;
393           j--;
394         }
395         if (!(numberBackslashes % 2))
396           inbrackets = 0;
397       }
398       i++;
399       continue;
400     }
401          
402     if (s[i] == '[') inbrackets = 1;
403        
404     if (s[i] == '(') {
405       if (last != ')' && p != -1) {
406         delete[] curr->SGFstring;
407         curr->SGFstring = new char[i-p+1];
408         curr->SGFstring = strncpy(curr->SGFstring, s+p, i-p);       
409         curr->SGFstring[i-p] = 0;
410         // curr->parseNode();
411       }
412
413       Node* nn = new Node(0,0,0);
414       nn->previous = curr;
415
416       if (++width_currentVar > width) width = width_currentVar;
417       if (curr->next) {
418         Node* last = curr->next;
419         while (last->down) last = last->down;
420         nn->up = last;                                 
421         last->down = nn;
422         nn->level = last->level + 1;
423         height++;
424         nn->posyD = height - height_previous;
425       }
426       else {
427         curr->next = nn;
428         nn->posyD = 0;
429         height_previous = height;
430       }
431
432       curr->numChildren++;
433      
434       c.push(curr);
435       c_width.push(width_currentVar-1);
436       c_height.push(height);
437          
438       curr = nn;
439                
440       p = -1;
441       last = '(';
442     }
443
444     if (s[i] == ')') {
445       if (last != ')' && p != -1) {
446         delete[] curr->SGFstring;
447         curr->SGFstring = new char[i-p+1];
448         curr->SGFstring = strncpy(curr->SGFstring, s+p, i-p);       
449         curr->SGFstring[i-p] = 0;
450         // curr->parseNode();
451       }
452       if (c.nonempty()) {
453         curr = c.top();
454         c.pop();
455         width_currentVar = c_width.top();
456         c_width.pop();
457         height_previous = c_height.top();
458         c_height.pop();
459       }
460       else {
461         throw SGFError();
462       }
463       last = ')';
464     }
465    
466     if (s[i] == ';') {
467       if (p != -1) {
468         delete[] curr->SGFstring;
469         curr->SGFstring = new char[i-p+1];
470         curr->SGFstring = strncpy(curr->SGFstring, s+p, i-p);       
471         curr->SGFstring[i-p] = 0;
472         // curr->parseNode();
473
474         Node* nn = new Node(0,0,0);
475         nn->previous = curr;
476
477         if (++width_currentVar > width) width = width_currentVar;
478         nn->posyD = 0;
479         curr->numChildren = 1;
480         curr->next = nn;
481         curr = nn;
482       }
483       p = i;
484     }
485
486     i++;
487   }
488
489   if (inbrackets || c.nonempty()) throw SGFError();
490  
491   Node* n = curr->next;
492   n->previous = NULL;
493   n->up = NULL;
494
495   while (n->down) {
496     n = n->down;
497     n->previous = NULL;
498   }
499 }
500
501 void Cursor::game(int n) throw(SGFError) {
502   if (n < root->numChildren) {
503     posx = 0;
504     posy = 0;
505     currentN = root->next;
506     for(int i=0; i<n; i++) currentN = currentN->down;
507     setFlags();
508   }
509   else throw SGFError();
510 }
511
512
513
514
515 void Cursor::deltree(Node* node) {
516   Node* n;
517
518   if (node->next) {
519     n = node->next;
520
521     while (n->down) {
522       n = n->down;
523       deltree(n->up);
524     }
525
526     deltree(n);
527   }
528
529   delete node;
530 }
531
532
533
534
535 void Cursor::delVariation(Node* c) {
536
537   if (c->previous) {
538     delVar(c);
539   }
540   else {
541     if (c->next) {
542       Node* node = c->next;
543       while (node->down) {
544         node = node->down;
545         delVar(node->up);
546       } 
547       delVar(node);
548     }
549     c->next = 0;
550   }
551
552   setFlags();
553 }
554
555 void Cursor::delVar(Node* node) {
556
557   if (node->up) node->up->down = node->down;
558   else {
559     node->previous->next = node->down;
560   }
561   if (node->down) {
562     node->down->up = node->up;
563     node->down->posyD = node->posyD;
564     Node* n = node->down;
565     while (n) {
566       n->level--;
567       n = n->down;
568     }
569   }
570
571   int h = 0;
572   Node* n = node;
573   while (n->next) {
574     n = n->next;
575     while (n->down) {
576       n = n->down;
577       h += n->posyD;
578     }
579   }
580
581   if (node->up || node->down) h++;
582
583   Node* p = node->previous;
584   p->numChildren--;
585
586   while (p) {
587     if (p->down) p->down->posyD -= h;
588     p = p->previous;
589   }
590
591   height -= h;
592
593   // p = node->down;
594   deltree(node);
595   // node = 0;
596 }
597
598
599 void Cursor::add(char* st) {
600
601   Node* node = new Node(currentN,st,0);
602
603   node->down = 0;
604   node->next = 0;
605   node->numChildren = 0;
606
607   if (!currentN->next) {
608     // printf("new %s at %s\n", node->SGFstring, currentN->SGFstring);
609     node->level = 0;
610     node->posyD = 0;
611     node->up = 0;
612
613     currentN->next = node;
614     currentN->numChildren = 1;
615   }
616   else {
617     // printf("adding %s at %s\n", node->SGFstring, currentN->SGFstring);
618     Node* n = currentN->next;
619     while (n->down) {
620       n = n->down;
621       posy+=n->posyD;
622     }
623    
624     n->down = node;
625     node->up = n;
626     node->level = n->level + 1;
627     node->next= 0;
628     currentN->numChildren++;
629
630     node->posyD = 1;
631     while (n->next) {
632       n = n->next;
633       while (n->down) {
634         n = n->down;
635         node->posyD += n->posyD;
636       }
637     }
638     posy += node->posyD;
639
640     height++;
641
642     n = node;
643     while (n->previous) {
644       n = n->previous;
645       if (n->down) n->down->posyD++;
646     }
647
648   }
649
650   currentN = node;
651
652   posx++;
653   setFlags();
654
655   if (posx > width) width++;
656
657 }
658
659
660 PyObject* Cursor::next(int n) throw(SGFError) {
661
662   if (n >= noChildren()) {
663     throw SGFError();
664   }
665   posx++;
666   currentN = currentN->next;
667   for (int i=0; i<n; i++) {
668     currentN = currentN->down;
669     posy += currentN->posyD;
670   }
671   setFlags();
672
673   return currentNode();
674 }
675    
676 PyObject* Cursor::previous() throw(SGFError) {
677   if (currentN->previous) {
678     while (currentN->up) {
679       posy -= currentN->posyD;
680       currentN = currentN->up;
681     }
682     currentN = currentN->previous;
683     posx--;
684   }
685   else throw SGFError();
686   setFlags();
687   return currentNode();
688 }
689
690 PyObject* Cursor::getRootNode(int n) throw(SGFError) {
691   if (!root) {
692     Py_INCREF(Py_None);
693     return Py_None;
694   }
695
696   if (n >= root->numChildren) throw SGFError();
697   Node* nn = root->next;
698   for(int i=0; i<n; i++) nn = nn->down; 
699  
700   if (!nn->parsed) nn->parseNode();
701   Py_INCREF(nn->data);
702   return nn->data;
703 }
704
705
706 void Cursor::updateCurrentNode() throw(SGFError) {
707   delete[] currentN->SGFstring;
708   currentN->SGFstring = nodeToString(currentN->data);
709   if (!currentN->parsed) {
710     currentN->parsed = 1;
711   }
712
713   // Py_DECREF(currentN->data);
714   // if (!(currentN->data=PyDict_New())) throw SGFError();
715   // currentN->parseNode();
716 }
717
718 void Cursor::updateRootNode(PyObject* data, int n) throw(SGFError) {
719   if (n >= root->numChildren) throw SGFError();
720   Node* nn = root->next;
721   for(int i=0; i<n; i++) nn = nn->down;
722   delete[] nn->SGFstring;
723   nn->SGFstring = rootNodeToString(data);
724   Py_DECREF(nn->data);
725   if (!(nn->data=PyDict_New())) throw SGFError();
726   nn->parsed = 0;
727   nn->parseNode();
728 }
729
730
731 char* Cursor::rootNodeToString(PyObject* data) {
732   char result[10000];
733   result[0] = 0;
734   strcat(result, ";");
735  
736   PyObject* item;
737   if ((item=PyDict_GetItem(data, PyString_FromString("GM")))) {
738     strcat(result, "GM[");
739     char* t = SGFescape(PyString_AsString(PyList_GetItem(item, 0)));
740     strcat(result, t);
741     delete[] t;
742     strcat(result, "]\n");
743   }
744   if ((item=PyDict_GetItem(data, PyString_FromString("FF")))) {
745     strcat(result, "FF[");
746     char* t = SGFescape(PyString_AsString(PyList_GetItem(item, 0)));
747     strcat(result, t);
748     delete[] t;
749     strcat(result, "]\n");
750   }
751   if ((item=PyDict_GetItem(data, PyString_FromString("SZ")))) {
752     strcat(result, "SZ[");
753     char* t = SGFescape(PyString_AsString(PyList_GetItem(item, 0)));
754     strcat(result, t);
755     delete[] t;
756     strcat(result, "]\n");
757   }
758   if ((item=PyDict_GetItem(data, PyString_FromString("PW")))) {
759     strcat(result, "PW[");
760     char* t = SGFescape(PyString_AsString(PyList_GetItem(item, 0)));
761     strcat(result, t);
762     delete[] t;
763     strcat(result, "]\n");
764   }
765   if ((item=PyDict_GetItem(data, PyString_FromString("WR")))) {
766     strcat(result, "WR[");
767     char* t = SGFescape(PyString_AsString(PyList_GetItem(item, 0)));
768     strcat(result, t);
769     delete[] t;
770     strcat(result, "]\n");
771   }
772   if ((item=PyDict_GetItem(data, PyString_FromString("PB")))) {
773     strcat(result, "PB[");
774     char* t = SGFescape(PyString_AsString(PyList_GetItem(item, 0)));
775     strcat(result, t);
776     delete[] t;
777     strcat(result, "]\n");
778   }
779   if ((item=PyDict_GetItem(data, PyString_FromString("BR")))) {
780     strcat(result, "BR[");
781     char* t = SGFescape(PyString_AsString(PyList_GetItem(item, 0)));
782     strcat(result, t);
783     delete[] t;
784     strcat(result, "]\n");
785   }
786   if ((item=PyDict_GetItem(data, PyString_FromString("EV")))) {
787     strcat(result, "EV[");
788     char* t = SGFescape(PyString_AsString(PyList_GetItem(item, 0)));
789     strcat(result, t);
790     delete[] t;
791     strcat(result, "]\n");
792   }
793   if ((item=PyDict_GetItem(data, PyString_FromString("RO")))) {
794     strcat(result, "RO[");
795     char* t = SGFescape(PyString_AsString(PyList_GetItem(item, 0)));
796     strcat(result, t);
797     delete[] t;
798     strcat(result, "]\n");
799   }
800   if ((item=PyDict_GetItem(data, PyString_FromString("DT")))) {
801     strcat(result, "DT[");
802     char* t = SGFescape(PyString_AsString(PyList_GetItem(item, 0)));
803     strcat(result, t);
804     delete[] t;
805     strcat(result, "]\n");
806   }
807   if ((item=PyDict_GetItem(data, PyString_FromString("PC")))) {
808     strcat(result, "PC[");
809     char* t = SGFescape(PyString_AsString(PyList_GetItem(item, 0)));
810     strcat(result, t);
811     delete[] t;
812     strcat(result, "]\n");
813   }
814   if ((item=PyDict_GetItem(data, PyString_FromString("KM")))) {
815     strcat(result, "KM[");
816     char* t = SGFescape(PyString_AsString(PyList_GetItem(item, 0)));
817     strcat(result, t);
818     delete[] t;
819     strcat(result, "]\n");
820   }
821   if ((item=PyDict_GetItem(data, PyString_FromString("RE")))) {
822     strcat(result, "RE[");
823     char* t = SGFescape(PyString_AsString(PyList_GetItem(item, 0)));
824     strcat(result, t);
825     delete[] t;
826     strcat(result, "]\n");
827   }
828   if ((item=PyDict_GetItem(data, PyString_FromString("US")))) {
829     strcat(result, "US[");
830     char* t = SGFescape(PyString_AsString(PyList_GetItem(item, 0)));
831     strcat(result, t);
832     delete[] t;
833     strcat(result, "]\n");
834   }
835   if ((item=PyDict_GetItem(data, PyString_FromString("GC")))) {
836     strcat(result, "GC[");
837     char* t = SGFescape(PyString_AsString(PyList_GetItem(item, 0)));
838     strcat(result, t);
839     delete[] t;
840     strcat(result, "]\n");
841   }
842
843   int l = 0;
844
845   PyObject *key, *value;
846   int pos = 0;
847
848   while (PyDict_Next(data, &pos, &key, &value)) {
849     char* s = PyString_AsString(key);
850     if (strcmp(s, "GM") && strcmp(s, "FF") && strcmp(s, "SZ") && strcmp(s, "PW") && strcmp(s, "WR") &&
851         strcmp(s, "PB") && strcmp(s, "BR") && strcmp(s, "EV") && strcmp(s, "RO") && strcmp(s, "DT") &&
852         strcmp(s, "PC") && strcmp(s, "KM") && strcmp(s, "RE") && strcmp(s, "US") && strcmp(s, "GC")) {
853      
854       strcat(result, s);
855
856       for(int k = 0; k < PyList_Size(value); k++) {
857         PyObject* item = PyList_GetItem(value, k);
858         char* t = SGFescape(PyString_AsString(item));
859         strcat(result, "[");
860         strcat(result, t);
861         strcat(result, "]");
862         l += strlen(t) + 2;
863         delete[] t;
864         if (l>72) {
865           strcat(result, "\n");
866           l = 0;
867         }
868       }
869     }
870   }
871   strcat(result, "\n");
872   char* t = new char[strlen(result)+1];
873   strcpy(t, result);
874   return t;
875 }
876
877 char* Cursor::nodeToString(PyObject* data) throw(SGFError) {
878
879   char result[50000];
880   result[0] = 0;
881   strcat(result, ";");
882
883   int l = 0;
884
885   PyObject *key, *value;
886   int pos = 0;
887
888   while (PyDict_Next(data, &pos, &key, &value)) {
889     char* s = PyString_AsString(key);
890    
891     if (!PyList_Check(value)) {
892       throw SGFError();
893     }
894
895     if (PyList_Size(value) == 0) continue;
896  
897     strcat(result, s);
898
899     for(int k = 0; k < PyList_Size(value); k++) {
900       PyObject* item = PyList_GetItem(value, k);
901       if (!PyString_Check(item)) {
902         throw SGFError();
903       }
904
905       char* t = SGFescape(PyString_AsString(item));
906       strcat(result, "[");
907       strcat(result, t);
908       strcat(result, "]");
909       l += strlen(t) + 2;
910       delete[] t;
911       if (l>72) {
912         strcat(result, "\n");
913         l = 0;
914       }
915    
916     }
917   }
918  
919   strcat(result, "\n");
920   // printf("strlen(result) == %d\n", strlen(result));
921   char* t = new char[strlen(result)+1];
922   strcpy(t, result);
923   return t;
924 }
925
926
927 char* Cursor::outputVar(Node* node) {
928   int s = 1000;
929   char* result = new char[s];
930   result[0] = 0;
931
932   if (strlen(node->SGFstring) + strlen(result) >= s-5) {
933     s += 1000 + strlen(node->SGFstring);
934     char* res = new char[s];
935     strcpy(res, result);
936     delete [] result;
937     result = res;
938   }
939
940   strcat(result, node->SGFstring);
941   // printf("%s\n", node->SGFstring);
942
943   while (node->next) {
944     node = node->next;
945     if (node->down) {
946       strcat(result, "(");
947
948       char* r = outputVar(node);
949
950       if (strlen(r) + strlen(result) >= s-5) {
951         s += 1000 + strlen(r);
952         char* res = new char[s];
953         strcpy(res, result);
954         delete [] result;
955         result = res;
956       }
957
958       strcat(result, r);
959       delete [] r;
960
961       while(node->down) {
962         node = node->down;
963         strcat(result, ")(");
964        
965         char* r = outputVar(node);
966
967         if (strlen(r) + strlen(result) >= s-5) {
968           s += 1000 + strlen(r);
969           char* res = new char[s];
970           strcpy(res, result);
971           delete [] result;
972           result = res;
973         }
974        
975         strcat(result, r);
976         delete [] r;
977       }
978       strcat(result, ")");
979       break;
980     }
981     else {
982       if (strlen(node->SGFstring) + strlen(result) >= s) {
983         s += 1000 + strlen(node->SGFstring);
984         char* res = new char[s];
985         strcpy(res, result);
986         delete [] result;
987         result = res;
988       }
989       strcat(result, node->SGFstring);
990       // printf("%s\n", node->SGFstring);
991     }
992   }
993
994   // printf("r: %d \n", strlen(result));
995
996   char* t = new char[strlen(result)+1];
997   strcpy(t, result);
998
999   delete result;
1000   return t;
1001 }
1002
1003
1004 char* Cursor::output() {
1005
1006   int s = 2000;
1007   char* result = new char[s];
1008   result[0] = 0;
1009
1010   Node* n = root->next;
1011
1012   while (n) {
1013     char* t = outputVar(n);
1014
1015     if (strlen(t) + strlen(result) >= s-5) {
1016       s += 2000 + strlen(t);
1017       char* res = new char[s];
1018       strcpy(res, result);
1019       delete [] result;
1020       result = res;
1021     }
1022
1023     strcat(result, "(");
1024     strcat(result, t);
1025     strcat(result, ")\n");
1026     delete [] t;   
1027     n = n->down;
1028   } 
1029
1030   char* t = new char[strlen(result)+1];
1031   strcpy(t, result);
1032   delete [] result;
1033   return t;
1034 }
1035
1036
1037
Note: See TracBrowser for help on using the browser.