Spaces:
No application file
No application file
| /* Copyright 2005 by Frank Kauff. All rights reserved. | |
| * | |
| * This file is part of the Biopython distribution and governed by your | |
| * choice of the "Biopython License Agreement" or the "BSD 3-Clause 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 | |
| */ | |
| 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=PyMem_RawMalloc(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 ] */ | |
| { | |
| PyMem_RawFree(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 that's 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 [ */ | |
| PyMem_RawFree(scanned_start); | |
| return Py_BuildValue("s","["); | |
| } | |
| else | |
| { | |
| *scanned=0; /* end of string */ | |
| cleaninput= Py_BuildValue("s",scanned_start); | |
| PyMem_RawFree(scanned_start); | |
| return cleaninput; | |
| } | |
| } | |
| static PyMethodDef cNexusMethods[]= | |
| { | |
| {"scanfile",cnexus_scanfile,METH_VARARGS,"Scan file and deal with comments and quotes."}, | |
| {NULL,NULL,0,NULL} | |
| }; | |
| static struct PyModuleDef moduledef = { | |
| PyModuleDef_HEAD_INIT, | |
| "cnexus", | |
| NULL, | |
| -1, | |
| cNexusMethods, | |
| NULL, | |
| NULL, | |
| NULL, | |
| NULL | |
| }; | |
| PyObject * | |
| PyInit_cnexus(void) | |
| { | |
| return PyModule_Create(&moduledef); | |
| } | |