/* 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; }