root/04/release-0.4e/sgfparserC.cc

Revision 21, 2.9 kB (checked in by ug, 5 years ago)

Import release 0.4d

Line 
1 #include <Python.h>
2
3 typedef PyObject* PYOptr;
4
5 static PyObject* parseC(PyObject* self, PyObject* args) {
6
7   char *sgf;
8   int sgfLength;
9
10   PyObject *parseExc;
11
12   if (!PyArg_ParseTuple(args, "s#O", &sgf, &sgfLength, &parseExc))
13     return NULL;
14   PYOptr current = PyList_New(0);
15
16   int p = -1;
17   PYOptr c[500];
18   int cIndex = 0;
19   char last = ')';
20   bool inbrackets = false;
21
22   int i = 0;
23
24   // skip everything before first (; :
25
26   int gameStart = -1;
27   while (i < sgfLength && gameStart == -1) {
28     while (i < sgfLength && sgf[i] != '(') i++;
29     gameStart = i;
30     i++;
31     while (i < sgfLength && (sgf[i] == ' ' || sgf[i] == '\t' || sgf[i] == '\r' || sgf[i] == '\n')) i++;
32     if (i < sgfLength && sgf[i] != ';') gameStart = -1;
33   }
34  
35   if (i >= sgfLength) {
36     PyErr_SetString(parseExc, "SGF parse error: game start not found");
37     return NULL;
38   }
39
40   i = gameStart;
41        
42   while (i < sgfLength) {
43     if (inbrackets) {
44       if (sgf[i]==']') {
45         int numberBackslashes = 0;
46         int j = i-1;
47         while (sgf[j] == '\\') {
48           numberBackslashes++;
49           j--;
50         }
51         if (!(numberBackslashes % 2)) inbrackets = false;
52       }
53       i++;
54       continue;
55     }
56
57     if (sgf[i] == '[') inbrackets = true;
58        
59     if (sgf[i] == '(') {
60       if (last != ')') {
61         if (p != -1) {
62           PyObject *temp = PyString_FromStringAndSize(sgf+p, i-p);
63           if (PyList_Append(current, temp))
64             return NULL;   // PyList_Append returns 0 on success
65           Py_DECREF(temp);
66         }
67         PYOptr newlist = PyList_New(0);
68         PyList_Append(current, newlist);
69         Py_XDECREF(current);
70         current = newlist;
71       }
72                
73       PYOptr newlist = PyList_New(0);
74       PyList_Append(current, newlist);
75       c[cIndex++] = current;
76       current = newlist;
77                
78       p = -1;
79       last = '(';
80     }
81
82     if (sgf[i] == ')') {
83       if (last != ')' && p != -1) {
84         PyObject *temp = PyString_FromStringAndSize(sgf+p, i-p);
85         if (PyList_Append(current, temp))
86           return NULL;   // PyList_Append returns 0 on success
87         Py_DECREF(temp);
88       }
89      
90       if (!cIndex) {
91         PyErr_SetString(parseExc, "SGF parse error: mismatched parentheses");
92         return NULL;
93       }
94       Py_XDECREF(current);
95       current = c[--cIndex];
96       last = ')';
97     }
98
99     if (sgf[i] == ';') {
100       if (p != -1) {
101         PyObject *temp = PyString_FromStringAndSize(sgf+p, i-p);
102         if (PyList_Append(current, temp))
103             return NULL;   // PyList_Append returns 0 on success
104         Py_DECREF(temp);
105       }
106       p = i;
107     }
108     i++;
109   }
110    
111   if (inbrackets) {
112     PyErr_SetString(parseExc, "SGF parse error: unexpected end of data");
113     return NULL;
114   }
115
116   if (cIndex) {
117     while (cIndex) {
118       cIndex--;
119       Py_DECREF(c[cIndex]);
120     }
121     PyErr_SetString(parseExc, "SGF parse error: mismatched parentheses");
122     return NULL;
123   }
124
125   return current;
126 }
127
128
129 static PyMethodDef sgfparserMethods[] = {
130   {"parseC",  parseC, METH_VARARGS},
131   {NULL,      NULL}        /* Sentinel */
132 };
133
134
135 extern "C" {
136   void initsgfparserC() {
137     (void) Py_InitModule("sgfparserC", sgfparserMethods);
138   }
139 }
Note: See TracBrowser for help on using the browser.