/* non-recursive high-level commands
The contract here is:
The commands may alter any of the tag-specific variables
errors may be indicated if encountered in childReturnCode and the error* variables
*/
case MATCH_SWORDSTART:
case MATCH_SWORDEND:
case MATCH_SFINDWORD:
/* these items basically follow the low-level contract, with the
only exception being that MATCH_SFINDWORD will change childStart
*/
{
int wordstart, wordend;
int returnCode;
DPRINTF("\nsWordStart/End/sFindWord :\n"
" in string = '%.40s'\n",text+childPosition);
childStart = childPosition;
returnCode = TE_SEARCHAPI(
match,
text,
childStart,
sliceright,
&wordstart,
&wordend
);
if (returnCode < 0) {
childReturnCode = ERROR_CODE;
errorType = PyExc_SystemError;
errorMessage = PyString_FromFormat(
"Search-object search returned value < 0 (%i): probable bug in text processing engine",
returnCode
);
} else if (returnCode == 0) {
/* not matched */
DPRINTF(" (no success)\n");
childReturnCode = FAILURE_CODE;
} else {
/* matched, adjust childPosition according to the word start/end/find requirements */
if (command == MATCH_SWORDSTART) {
childPosition = wordstart;
} else {
childPosition = wordend;
}
if (command == MATCH_SFINDWORD) {
/* XXX logic problem with lookahead
should it reset to real childStart or
the fake one created here? */
childStart = wordstart;
}
DPRINTF(" [%i:%i] (matched and remembered this slice)\n",
childStart,childPosition);
}
break;
}
case MATCH_LOOP:
/* No clue what this is supposed to do, real surprising if it works...
*/
DPRINTF("\nLoop: pre loop counter = %i\n",loopcount);
if (loopcount > 0) {
/* we are inside a loop */
loopcount--;
} else if (loopcount < 0) {
/* starting a new loop */
if (PyInt_Check(match)) {
loopcount = PyInt_AS_LONG(match);
loopstart = childPosition;
} else {
childReturnCode = ERROR_CODE;
errorType = PyExc_TypeError;
errorMessage = PyString_FromFormat(
"Tag Table entry %i: expected an integer (command=Loop) got a %.50s",
index,
match->ob_type->tp_name
);
}
}
if (childReturnCode == NULL_CODE ) {
if (loopcount == 0) {
/* finished loop */
loopcount = -1;
}
if (loopstart == childPosition) {
/* not matched */
childReturnCode = FAILURE_CODE;
} else {
childReturnCode = SUCCESS_CODE;
/* on success, add match from start of the whole loop to end of current iteration?
Would be really good if I had a clue what this is supposed to do :) .
*/
childStart = loopstart;
}
DPRINTF("\nloop: post loop counter = %i\n",loopcount);
}
break;
case MATCH_LOOPCONTROL:
DPRINTF("\nLoopControl: loop counter = %i, "
"setting it to = %li\n",
loopcount,PyInt_AS_LONG(match));
loopcount = PyInt_AS_LONG(match);
break;
case MATCH_CALL:
case MATCH_CALLARG:
/* call and callarg actually follow the low-level contract */
{
PyObject *fct = NULL;
int argc = -1;
if (!PyTuple_Check(match)) {
argc = 0;
fct = match;
} else {
argc = PyTuple_GET_SIZE(match) - 1;
if (argc < 0) {
/* how is this even possible? */
childReturnCode = ERROR_CODE;
errorType = PyExc_TypeError;
errorMessage = PyString_FromFormat(
"Tag Table entry %i: "
"expected a tuple (fct,arg0,arg1,...)"
"(command=CallArg)",
index
);
} else {
fct = PyTuple_GET_ITEM(match,0);
}
}
if (childReturnCode == NULL_CODE && PyCallable_Check(fct)) {
PyObject *args;
register PyObject *w;
register int argIndex;
DPRINTF("\nCall[Arg] :\n");
childStart = childPosition;
/* Build args = (textobj,childStart,sliceright[,arg0,arg1,...]) */
args = PyTuple_New(3 + argc);
if (!args) {
childReturnCode = ERROR_CODE;
errorType = PyExc_SystemError;
errorMessage = PyString_FromFormat(
"Unable to create argument tuple for CallArgs command at index %i",
index
);
} else {
Py_INCREF(textobj);
PyTuple_SET_ITEM(args,0,textobj);
w = PyInt_FromLong(childStart);
if (!w){
childReturnCode = ERROR_CODE;
errorType = PyExc_SystemError;
errorMessage = PyString_FromFormat(
"Unable to convert an integer %i to a Python Integer",
childStart
);
} else {
PyTuple_SET_ITEM(args,1,w);
w = PyInt_FromLong(sliceright);
if (!w) {
childReturnCode = ERROR_CODE;
errorType = PyExc_SystemError;
errorMessage = PyString_FromFormat(
"Unable to convert an integer %i to a Python Integer",
sliceright
);
} else {
PyTuple_SET_ITEM(args,2,w);
for (argIndex = 0; argIndex < argc; argIndex++) {
w = PyTuple_GET_ITEM(match,argIndex + 1);
Py_INCREF(w);
PyTuple_SET_ITEM(args,3 + argIndex,w);
}
/* now actually call the object */
w = PyEval_CallObject(fct,args);
Py_DECREF(args);
if (w == NULL) {
childReturnCode = ERROR_CODE;
/* child's error should be allowed to propagate */
} else if (!PyInt_Check(w)) {
childReturnCode = ERROR_CODE;
errorType = PyExc_TypeError;
errorMessage = PyString_FromFormat(
"Tag Table entry %i: matching function has to return an integer, returned a %.50s",
index,
w->ob_type->tp_name
);
} else {
childPosition = PyInt_AS_LONG(w);
Py_DECREF(w);
if (childStart == childPosition) {
/* not matched */
DPRINTF(" (no success)\n");
childReturnCode = FAILURE_CODE;
}
}
}
}
}
} else {
childReturnCode = ERROR_CODE;
errorType = PyExc_TypeError;
errorMessage = PyString_FromFormat(
"Tag Table entry %i: "
"expected a callable object, got a %.50s"
"(command=Call[Arg])",
index,
fct->ob_type->tp_name
);
}
break;
}
syntax highlighted by Code2HTML, v. 0.9.1