root/04/bugfix/sgfparserC.cc

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

Import release 0.4d

Line 
1#include <Python.h>
2
3typedef PyObject* PYOptr;
4
5static 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
129static PyMethodDef sgfparserMethods[] = {
130  {"parseC",  parseC, METH_VARARGS},
131  {NULL,      NULL}        /* Sentinel */
132};
133
134
135extern "C" {
136  void initsgfparserC() {
137    (void) Py_InitModule("sgfparserC", sgfparserMethods);
138  }
139}
Note: See TracBrowser for help on using the browser.