File: cnexus.c

package info (click to toggle)
python-biopython 1.68%2Bdfsg-3~bpo8%2B1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-backports
  • size: 46,856 kB
  • sloc: python: 160,306; xml: 93,216; ansic: 9,118; sql: 1,208; makefile: 155; sh: 63
file content (137 lines) | stat: -rw-r--r-- 3,756 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/* Copyright 2005 by Frank Kauff.  All rights reserved.
 * This code is part of the Biopython distribution and governed by its
 * license. Please see the LICENSE file that should have been included
 * as part of this package.
 *
 * cnexus.c
 *
 * Parse input strings, cut out (nested) comments, deal with quoted text.
 * Input lines terminated with ; are separated by ASCII code 7 (something
 * that naturally doesn't occur in plain NEXUS files).
 *
 * Used by Nexus.py
 */

#include <Python.h>
#include <string.h>

static PyObject * cnexus_scanfile(PyObject *self, PyObject *args)
{
    PyObject *cleaninput;
    const char *input;
    char *scanned, *scanned_start;
    char t, quotelevel;
    int speciallevel, commlevel;

    quotelevel=0;
    speciallevel=0;
    commlevel=0;

    if (!PyArg_ParseTuple(args, "s", &input))
        return NULL;
    if (!(scanned=malloc(strlen(input)+1)))
        PyErr_NoMemory();
    scanned_start=scanned;
    for(t=*input;(t=*input);input++)
    {
        /* end of standard quote */
        if (!(commlevel || speciallevel) && t==quotelevel)
            quotelevel=0;
        /* start of standard quote */
        else if (!quotelevel && !(commlevel || speciallevel) && (t=='\'' || t=='"'))
            quotelevel=t;
        /* start of comment outside quote */
        else if (!quotelevel  && t=='[')
        {
            /* check for special comments */
            /*if ((*(input+1)=='!' || *(input+1)=='&' || *(input+1)=='%' ||
                    *(input+1)=='/' || *(input+1)=='\\' || *(input+1)=='@')
                    && !(commlevel || speciallevel))
                speciallevel=1;
            */
            if ((*(input+1)=='&') && !(commlevel || speciallevel))
                speciallevel=1;
            else /* standard comment */
                commlevel++;
        }
        else if (!quotelevel && t==']')
        {
            /* does it end a special comment? */
            if (speciallevel)
                speciallevel=0;
            else
            {
                commlevel--;
                if (commlevel<0) /* error: unmatched ] */
                {
                    free(scanned_start);
                    return Py_BuildValue("s","]");
                }
                continue;
            }
        }
        if (!commlevel)
        {
            /* we replace the ; at the end of command lines with special
             * character to make subsequent parsing of blocks easier */
            if (t==';' && !(quotelevel || speciallevel))
                /* need an ascii code thats not part of a nexus file, used as
                 * separator */
                *(scanned++)=7;
            else
                *(scanned++)=t;
        }
        /* printf("t %c, commlevel %d, speciallevel %d, quotelevel '%c', scanned %d\n",
         * t,commlevel,speciallevel,quotelevel,scanned);
         */
    }

    if (commlevel>0)
    {
        /* error: unmatched [ */
        free(scanned_start);
        return Py_BuildValue("s","[");
    }
    else
    {
        *scanned=0; /* end of string */
        cleaninput= Py_BuildValue("s",scanned_start);
        free(scanned_start);
        return cleaninput;
    }
}

static PyMethodDef cNexusMethods[]=
{
    {"scanfile",cnexus_scanfile,METH_VARARGS,"Scan file and deal with comments and quotes."},
    {NULL,NULL,0,NULL}
};

#if PY_MAJOR_VERSION >= 3

static struct PyModuleDef moduledef = {
        PyModuleDef_HEAD_INIT,
        "cnexus",
        NULL,
        -1,
        cNexusMethods,
        NULL,
        NULL,
        NULL,
        NULL
};

PyObject *
PyInit_cnexus(void)
{
    return PyModule_Create(&moduledef);
}


#else

PyMODINIT_FUNC initcnexus(void)
{
    (void) Py_InitModule("cnexus",cNexusMethods);
}
#endif