run_user_validation(char *ofile) { int i, status; /* should also check status everywhere */ char *errors, *warnings; PyObject *results, *orders, *nextorder=NULL; Py_Initialize(); PyRun_SimpleString("import sys; sys.path.append('..')"); PP_Run_Function("inventory", "load_orders", "O", &orders, "(s)", ofile); PP_Run_Function("inventory", "print_files", "", NULL, "()"); for (i=0; i < PyObject_Length(orders); i++) { /* len(x) */ Py_XDECREF(nextorder); nextorder = PyObject_GetItem(orders, PyInt_FromLong(i)); /* x[i] */ printf("\n%d ", i); PyObject_Print(nextorder, stdout, 0); printf("\n"); status = PP_Run_Function( /* validate2.validate(p,q,b) */ "validate2", "validate", "O", &results, "O", nextorder); if (status == -1) { printf("Python error during validation.\n"); PyErr_Print(); /* show traceback */ continue; } PyArg_Parse(results, "(ss)", &warnings, &errors); printf("errors: %s\n", strlen(errors)? errors : "none"); printf("warnings: %s\n", strlen(warnings)? warnings : "none"); Py_DECREF(results); /* ok to free strings */ PP_Run_Function("inventory", "print_files", "", NULL, "()"); } }
PyObject * PP_Debug_Bytecode(PyObject *codeobject, PyObject *moddict) { int res; PyObject *presult; fixPdbRetval(moddict); res = PP_Run_Function( /* "pdb.runeval(codeobj, gdict, ldict)" */ "pdb", "runeval", /* accepts string|code, code=stmt|expr */ "O", &presult, "(OOO)", codeobject, moddict, moddict); return (res != 0) ? NULL : presult; /* null if error in run_function */ }
PyObject * PP_Debug_Codestr(PPStringModes mode, const char *codestring, PyObject *moddict) { int res; PyObject *presult; const char *pdbname = (mode == PP_EXPRESSION ? "runeval" : "run"); fixPdbRetval(moddict); /* pass code to a pbd.py function */ res = PP_Run_Function( /* "pdb.run(stmt, gdict, ldict)" */ "pdb", pdbname, /* "pdb.runeval(expr, gdict, ldict)" */ "O", &presult, "(sOO)", codestring, moddict, moddict); return (res != 0) ? NULL : presult; /* return null or increfd object */ }
PyObject * PP_Debug_Function(PyObject *func, PyObject *args) { int oops, res, i; PyObject *presult; /* expand tuple for func */ oops = _PyTuple_Resize(&args, (1 + PyTuple_Size(args))); /* NO 3RD ARG */ if (oops) return NULL; /* "args = (funcobj,) + (arg,..)" */ /* move orig args right */ for (i=PyTuple_Size(args)-1; i > 1; i--) PyTuple_SetItem(args, i, PyTuple_GetItem(args, i-1)); PyTuple_SetItem(args, 0, func); res = PP_Run_Function( /* "pdb.runcall(funcobj, arg,..)" */ "pdb", "runcall", /* recursive run_function */ "O", &presult, "O", args); /* args already is a tuple */ return (res != 0) ? NULL : presult; /* errors in run_function? */ } /* presult not yet decref'd */
PyObject * PP_Debug_Function(PyObject *func, PyObject *args) { int oops, res; PyObject *presult; /* expand tuple at front */ // it seems that some versions of python want just 2 arguments; in that // case, remove trailing 1 #if (PY_MAJOR_VERSION==2)&&(PY_MINOR_VERSION>=2) oops = _PyTuple_Resize(&args, (1 + PyTuple_Size(args))); #else oops = _PyTuple_Resize(&args, (1 + PyTuple_Size(args)),1); #endif oops |= PyTuple_SetItem(args, 0, func); if (oops) return NULL; /* "args = (funcobj,) + (arg,..)" */ res = PP_Run_Function( /* "pdb.runcall(funcobj, arg,..)" */ "pdb", "runcall", /* recursive run_function */ "O", &presult, "O", args); /* args already is a tuple */ return (res != 0) ? NULL : presult; /* errors in run_function? */ } /* presult not yet decref'd */
run_user_validation() { /* python is initialized automatically */ int i, status, nbytes; /* caveat: should check status everywhere */ char script[4096]; /* caveat: should malloc a big-enough block */ char *errors, *warnings; FILE *file; file = fopen("validate1.py", "r"); /* customizable validations */ nbytes = fread(script, 1, 4096, file); /* load python file text */ script[nbytes] = '\0'; status = PP_Make_Dummy_Module("orders"); /* application's own namespace */ for (i=0; i < numorders; i++) { /* like making a new dictionary */ printf("\n%d (%d, %d, '%s')\n", i, orders[i].product, orders[i].quantity, orders[i].buyer); PP_Set_Global("orders", "PRODUCT", "i", orders[i].product); /* int */ PP_Set_Global("orders", "QUANTITY", "i", orders[i].quantity); /* int */ PP_Set_Global("orders", "BUYER", "s", orders[i].buyer); /* str */ status = PP_Run_Codestr(PP_STATEMENT, script, "orders", "", NULL); if (status == -1) { printf("Python error during validation.\n"); PyErr_Print(); /* show traceback */ continue; } PP_Get_Global("orders", "ERRORS", "s", &errors); /* can split */ PP_Get_Global("orders", "WARNINGS", "s", &warnings); /* on blanks */ printf("errors: %s\n", strlen(errors)? errors : "none"); printf("warnings: %s\n", strlen(warnings)? warnings : "none"); free(errors); free(warnings); PP_Run_Function("inventory", "print_files", "", NULL, "()"); } }
void PP_Fetch_Error_Text() { // called without exception happened! //assert(PyErr_Occurred()); char *tempstr; PyObject *errobj, *errdata, *errtraceback, *pystring; /* get latest python exception information */ /* this also clears the current exception */ PyErr_Fetch(&errobj, &errdata, &errtraceback); /* all 3 incref'd */ /* convert type and data to strings */ /* calls str() on both to stringify */ pystring = NULL; if (errobj != NULL && (pystring = PyObject_Str(errobj)) != NULL && /* str(errobj) */ (PyString_Check(pystring)) ) /* str() increfs */ { strncpy(PP_last_error_type, PyString_AsString(pystring), MAX); /*Py->C*/ PP_last_error_type[MAX-1] = '\0'; } else strcpy(PP_last_error_type, "<unknown exception type>"); Py_XDECREF(pystring); pystring = NULL; if (errdata != NULL && (pystring = PyObject_Str(errdata)) != NULL && /* str(): increfs */ (PyString_Check(pystring)) ) { strncpy(PP_last_error_info, PyString_AsString(pystring), MAX); /*Py->C*/ PP_last_error_info[MAX-1] = '\0'; } else strcpy(PP_last_error_info, "<unknown exception data>"); Py_XDECREF(pystring); /* convert traceback to string */ /* print text to a StringIO.StringIO() internal file object, then */ /* fetch by calling object's .getvalue() method (see lib manual); */ pystring = NULL; if (errtraceback != NULL && (PP_Run_Function("StringIO", "StringIO", "O", &pystring, "()") == 0) && (PyTraceBack_Print(errtraceback, pystring) == 0) && (PP_Run_Method(pystring, "getvalue", "s", &tempstr, "()") == 0) ) { strncpy(PP_last_error_trace, tempstr, MAX); PP_last_error_trace[MAX-1] = '\0'; free(tempstr); /* it's a strdup */ } else strcpy(PP_last_error_trace, "<unknown exception traceback>"); Py_XDECREF(pystring); Py_XDECREF(errobj); Py_XDECREF(errdata); /* this function owns all 3 objects */ Py_XDECREF(PP_last_traceback); /* they've been NULL'd out in Python */ PP_last_traceback = errtraceback; /* save/export raw traceback object */ }