Support for parser exceptions RCS*

git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@476 8cb11bc2-c004-0410-86c3-e597b4017df7
remotes/tags/1.0.0-rc1
lbruand 2002-02-11 20:13:50 +00:00
parent 8eec37e768
commit 87f43f02d5
6 changed files with 138 additions and 38 deletions

View File

@ -1,3 +1,14 @@
Modif ( 11-Feb-2002)
* Support for parser exceptions ( RCS* ):
tparse will try import those exceptions from the "common" module.
If it fails, tparse create those exceptions inside itself.
* Changed the INSTALL file to make installation clearer.
Modif ( 08-Feb-2002)
* Added Daniel Berlin's patch:
Use a buffer stdiobufstream to access a python File in C++.
Much faster.
Modif ( 30-Jan-2002)
* Fixed compilation problem of revision 1.2 of tparser.cpp
* Streamlined some part of the code. ( Added returns here and there...)

View File

@ -5,15 +5,19 @@
type as root:
$ python Setup.py install
in the /viewcvs/tparse directory will install tparse in
your python distribution.
In order to check if tparse has been correctly installed type:
$ python Setup.py build_ext
in the /viewcvs/tparse directory will compile tparse.
Normally, you can find a tparse.so dynamic library, in a directory called
build/lib.****/
where **** depends on OS.
cd into that directory.
Then check if tparse has been correctly installed:
$ python
Python 2.1.2 (#1, Jan 21 2002, 04:12:22)
[GCC 2.96 20000731 (Mandrake Linux 8.1 2.96-0.62mdk)] on linux2
Type "copyright", "credits" or "license" for more information.
>>> import tparse
>>>
This is ok.
now move the tparse.so into your lib/rcsparse directory

View File

@ -87,7 +87,7 @@ char * TokenParser::get() {
idx=0;
input->read(buf,CHUNK_SIZE);
if ( (buflength=input->gcount())==0 )
throw tparseException(" Unterminated string \"@\" missing!");
throw RCSIllegalCharacter(" Unterminated string \"@\" missing!");
}
//i=strchr(buf+idx,'@');
for(i=idx;i<buflength && (buf[i]!='@');i++) ;
@ -103,7 +103,7 @@ char * TokenParser::get() {
buf[0]='@';
input->read(buf+1,CHUNK_SIZE-1);
if ( (buflength=input->gcount())==0 )
throw tparseException("Unterminated string; @ missing");
throw RCSIllegalCharacter("Unterminated string; @ missing");
buflength++;
continue;
}
@ -122,7 +122,7 @@ char * TokenParser::get() {
void TokenParser::unget(char *token) {
if (backget) {
throw tparseException(" Error, ungetting a token while already having an ungetted token ");
throw RCSParseError(" Error, ungetting a token while already having an ungetted token ");
}
backget=token;

View File

@ -43,15 +43,40 @@
/* This class represents a exception that occured during the parsing of a file */
class tparseException {
class RCSParseError {
char *value;
public:
tparseException(char *myvalue) { value=myvalue; };
char *value;
RCSParseError() {};
RCSParseError(char *myvalue) { value=myvalue; };
char *getvalue() { return value; };
};
/* This class is used to stored a list of the branches of a revision */
class RCSIllegalCharacter :public RCSParseError {
public:
RCSIllegalCharacter(char *myvalue) { value=myvalue; };
};
class RCSExpected :public RCSParseError {
public:
char *got;
char *wanted;
RCSExpected( char *mygot, char *mywanted)
{
got=mygot;
wanted=mywanted;
}
char *getvalue() {
ostrstream *out= new ostrstream();
(*out)<<"RCSExcepted: "<<wanted<<" Got: "<< got<<endl;
out->put('\0');
return out->str();
};
};
/* This class is used to store a list of the branches of a revision */
class Branche {
public:
char *name;
@ -150,11 +175,11 @@ class TokenParser {
};
void matchsemicol() {
char *ptr=get();
if (ptr!=semicol) throw tparseException(" Incorrect syntax in the RCSFILE parsed!");
if (ptr!=semicol) throw RCSExpected(ptr,semicol);
};
void match(char *token) {
char *ptr;
if (strcmp(ptr=get(),token)!=0) throw tparseException(" Incorrect syntax in the RCSFILE parsed!");
if (strcmp(ptr=get(),token)!=0) throw RCSExpected(ptr,token);
delstr( ptr);
};
@ -164,7 +189,7 @@ class TokenParser {
idx=0;semicol=";";
input->read(buf,CHUNK_SIZE);
if ( (buflength=input->gcount())==0 )
throw tparseException("Non-existing file or empty file");
throw RCSParseError("Non-existing file or empty file");
};

View File

@ -42,12 +42,45 @@ static PyMethodDef tparseMethods[] = {
void inittparse()
{
PyObject *m, *d;
PyObject *m, *d, *common, *commondict;
m= Py_InitModule3("tparse", tparseMethods,__doc__);
common = PyImport_ImportModule("common");
if (!common) {
PyErr_Clear();
pyRCSStopParser = PyErr_NewException("tparse.RCSStopParser", NULL, NULL);
PyObject_SetAttrString(pyRCSStopParser,"__doc__",PyString_FromString(pyRCSStopParser__doc__));
pyRCSParseError = PyErr_NewException("tparse.RCSParseError", NULL, NULL);
PyObject_SetAttrString(pyRCSParseError,"__doc__",PyString_FromString(pyRCSParseError__doc__));
pyRCSIllegalCharacter = PyErr_NewException("tparse.RCSIllegalCharacter", NULL, NULL);
PyObject_SetAttrString(pyRCSIllegalCharacter,"__doc__",PyString_FromString(pyRCSIllegalCharacter__doc__));
pyRCSExpected = PyErr_NewException("tparse.RCSExpected", NULL, NULL);
PyObject_SetAttrString(pyRCSExpected,"__doc__",PyString_FromString(pyRCSExpected__doc__));
}
else {
commondict = PyModule_GetDict(common);
pyRCSStopParser = PyDict_GetItemString(commondict,"RCSStopParser");
Py_INCREF(pyRCSStopParser);
pyRCSParseError = PyDict_GetItemString(commondict,"RCSParseError");
Py_INCREF(pyRCSParseError);
pyRCSIllegalCharacter = PyDict_GetItemString(commondict,"RCSIllegalCharacter");
Py_INCREF(pyRCSIllegalCharacter);
pyRCSExpected = PyDict_GetItemString(commondict,"RCSExpected");
Py_INCREF(pyRCSExpected);
}
d = PyModule_GetDict(m);
StopParser = PyErr_NewException("tparse.stopparser", NULL, NULL);
PyObject_SetAttrString(StopParser,"__doc__",PyString_FromString(StopParser__doc__));
PyDict_SetItemString(d, "stopparser", StopParser);
PyDict_SetItemString(d, "RCSStopParser", pyRCSStopParser);
PyDict_SetItemString(d, "RCSParseError", pyRCSParseError);
PyDict_SetItemString(d, "RCSIllegalCharacter", pyRCSIllegalCharacter);
PyDict_SetItemString(d, "RCSExpected", pyRCSExpected);
PyDict_SetItemString(d, "__version__", PyString_FromString(__version__));
PyDict_SetItemString(d, "__date__", PyString_FromString(__date__));
PyDict_SetItemString(d, "__author__", PyString_FromString(__author__));
@ -67,7 +100,7 @@ class PythonSink : public Sink {
{
if (!PyObject_CallMethod(sink,"set_head_revision", "s", revision)) {
delstr(revision);
if (PyErr_ExceptionMatches(StopParser))
if (PyErr_ExceptionMatches(pyRCSStopParser))
return 1;
else
throw PythonException();
@ -79,7 +112,7 @@ class PythonSink : public Sink {
{
if (!PyObject_CallMethod(sink,"set_principal_branch", "s", branch_name)) {
delstr(branch_name);
if (PyErr_ExceptionMatches(StopParser))
if (PyErr_ExceptionMatches(pyRCSStopParser))
return 1;
else
throw PythonException();
@ -91,7 +124,7 @@ class PythonSink : public Sink {
{
if (!PyObject_CallMethod(sink,"define_tag", "ss", name,revision)) {
delstr(name);
if (PyErr_ExceptionMatches(StopParser))
if (PyErr_ExceptionMatches(pyRCSStopParser))
return 1;
else
throw PythonException();
@ -103,7 +136,7 @@ class PythonSink : public Sink {
{
if (!PyObject_CallMethod(sink,"set_comment", "s", comment)) {
delstr(comment);
if (PyErr_ExceptionMatches(StopParser))
if (PyErr_ExceptionMatches(pyRCSStopParser))
return 1;
else
throw PythonException();
@ -115,7 +148,7 @@ class PythonSink : public Sink {
{
if (!PyObject_CallMethod(sink,"set_description", "s", description)) {
delstr(description);
if (PyErr_ExceptionMatches(StopParser))
if (PyErr_ExceptionMatches(pyRCSStopParser))
return 1;
else
throw PythonException();
@ -140,7 +173,7 @@ class PythonSink : public Sink {
delstr(author);
delstr(state);
if (branches!=NULL) delete branches;delstr(next);
if (PyErr_ExceptionMatches(StopParser))
if (PyErr_ExceptionMatches(pyRCSStopParser))
return 1;
else
throw PythonException();
@ -159,7 +192,7 @@ class PythonSink : public Sink {
delstr(revision);
delstr(log);
delstr(text);
if (PyErr_ExceptionMatches(StopParser))
if (PyErr_ExceptionMatches(pyRCSStopParser))
return 1;
else
throw PythonException();
@ -173,7 +206,7 @@ class PythonSink : public Sink {
{
if (!PyObject_CallMethod(sink,"tree_completed", NULL))
{
if (PyErr_ExceptionMatches(StopParser))
if (PyErr_ExceptionMatches(pyRCSStopParser))
return 1;
else
throw PythonException();
@ -184,7 +217,7 @@ class PythonSink : public Sink {
{
if (!PyObject_CallMethod(sink,"parse_completed", NULL))
{
if (PyErr_ExceptionMatches(StopParser))
if (PyErr_ExceptionMatches(pyRCSStopParser))
return 1;
else
throw PythonException();
@ -217,9 +250,26 @@ static PyObject * tparse( PyObject *self, PyObject *args)
try {
tparseParser *tp=new tparseParser(input,new PythonSink(hsink) );
}
catch (tparseException e)
catch (RCSExpected e)
{
PyObject *exp= PyInstance_New(pyRCSExpected, Py_BuildValue("(ss)", e.got, e.wanted), NULL);
PyErr_SetObject(pyRCSExpected, exp);
Py_DECREF(hsink);
Py_XDECREF(file);
return NULL;
}
catch (RCSIllegalCharacter e)
{
PyObject *exp= PyInstance_New(pyRCSIllegalCharacter, Py_BuildValue("(s)", e.value), NULL);
PyErr_SetObject(pyRCSIllegalCharacter, exp);
Py_DECREF(hsink);
Py_XDECREF(file);
return NULL;
}
catch (RCSParseError e)
{
PyErr_SetString(PyExc_Exception,e.getvalue());
PyObject *exp= PyInstance_New(pyRCSParseError, Py_BuildValue("(s)", e.value), NULL);
PyErr_SetObject(pyRCSParseError, exp);
Py_DECREF(hsink);
Py_XDECREF(file);
return NULL;
@ -230,9 +280,9 @@ static PyObject * tparse( PyObject *self, PyObject *args)
Py_XDECREF(file);
return NULL;
}
Py_DECREF(hsink);
Py_XDECREF(file);
Py_INCREF(Py_None);
return Py_None;
Py_DECREF(hsink);
Py_XDECREF(file);
Py_INCREF(Py_None);
return Py_None;
}

View File

@ -29,11 +29,21 @@ tparse is a C++ library that offers an API to a performance-oriented RCSFILE par
It does little syntax checking.\n\
\n\
Version: $Id$\n";
static char *__version__ = "0.13";
static char *__date__ = "2002/01/27";
static char *__version__ = "0.14";
static char *__date__ = "2002/02/11";
static char *__author__ ="Lucas Bruand <lucas.bruand@ecl2002.ec-lyon.fr>";
static char *StopParser__doc__ ="Stop parser exception: to be raised from the sink to abort parsing.";
static PyObject *StopParser;
static char *pyRCSStopParser__doc__ ="Stop parser exception: to be raised from the sink to abort parsing.";
static PyObject *pyRCSStopParser;
static char *pyRCSParseError__doc__ ="Ancestor Exception";
static PyObject *pyRCSParseError;
static char *pyRCSIllegalCharacter__doc__ ="Parser has encountered an Illegal Character.";
static PyObject *pyRCSIllegalCharacter;
static char *pyRCSExpected__doc__ ="Parse has found something but the expected.";
static PyObject *pyRCSExpected;
static char *tparse__doc__=" Main function: parse a file and send the result to the sink \n\
Two ways of invoking this function from python:\n\