word pl_dde_poke(term_t handle, term_t item, term_t data, term_t timeout) { int hdl; char *datastr; HDDEDATA Hvalue; HSZ Hitem; long tmo; if ( !get_conv_handle(handle, &hdl) || !get_hsz(item, &Hitem) ) fail; if ( !PL_get_chars(data, &datastr, CVT_ALL) ) return PL_error(NULL, 0, NULL, ERR_TYPE, ATOM_text, data); if ( !PL_get_long(timeout, &tmo) ) return PL_error(NULL, 0, NULL, ERR_TYPE, ATOM_integer, timeout); if ( tmo <= 0 ) tmo = TIMEOUT_VERY_LONG; Hvalue = DdeClientTransaction(datastr, strlen(datastr)+1, conv_handle[hdl], Hitem, CF_TEXT, XTYP_POKE, (DWORD)tmo, NULL); if ( !Hvalue ) return dde_warning("poke"); succeed; }
word pl_dde_request(term_t handle, term_t item, term_t value, term_t timeout) { int hdl; int rval; int ddeErr; HSZ Hitem; DWORD result, valuelen; HDDEDATA Hvalue; long tmo; if ( !get_conv_handle(handle, &hdl) || !get_hsz(item, &Hitem) ) fail; if ( !PL_get_long(timeout, &tmo) ) return PL_error(NULL, 0, NULL, ERR_TYPE, ATOM_integer, timeout); if ( tmo <= 0 ) tmo = TIMEOUT_VERY_LONG; Hvalue = DdeClientTransaction(NULL, 0, conv_handle[hdl], Hitem, CF_TEXT, XTYP_REQUEST, (DWORD)tmo, &result); ddeErr = DdeGetLastError(ddeInst); DdeFreeStringHandle(ddeInst, Hitem); if ( Hvalue) { char * valuebuf; char * valuedata; valuedata = DdeAccessData(Hvalue, &valuelen); valuebuf = (char *)malloc((size_t)valuelen+1); strncpy(valuebuf, valuedata, valuelen+1); DdeUnaccessData(Hvalue); valuebuf[valuelen] = EOS; rval = PL_unify_string_chars(value, valuebuf); free(valuebuf); return rval; } else { const char * errmsg = dde_error_message(ddeErr); return PL_unify_term(value, PL_FUNCTOR, FUNCTOR_error1, /* error(Message) */ PL_CHARS, errmsg); } }
static PyObject *bip_sum(term_t t) { PyObject *seq; PyObject *result = NULL; PyObject *temp, *item, *iter; if (!PL_get_arg(1, t, t)) return NULL; seq = term_to_python(t, true); iter = PyObject_GetIter(seq); if (iter == NULL) return NULL; if (result == NULL) { #if PY_MAJOR_VERSION < 3 result = PyInt_FromLong(0); #else result = PyLong_FromLong(0); #endif if (result == NULL) { Py_DECREF(iter); return NULL; } } else { #if PY_MAJOR_VERSION < 3 /* reject string values for 'start' parameter */ if (PyObject_TypeCheck(result, &PyBaseString_Type)) { PyErr_SetString(PyExc_TypeError, "sum() can't sum strings [use ''.join(seq) instead]"); Py_DECREF(iter); return NULL; } Py_INCREF(result); #endif } #ifndef SLOW_SUM /* Fast addition by keeping temporary sums in C instead of new Python objects. Assumes all inputs are the same type. If the assumption fails, default to the more general routine. */ #if PY_MAJOR_VERSION < 3 if (PyInt_CheckExact(result)) { long i_result = PyInt_AS_LONG(result); #else if (PyLong_CheckExact(result)) { long i_result = PyLong_AS_LONG(result); #endif Py_DECREF(result); result = NULL; while (result == NULL) { item = PyIter_Next(iter); if (item == NULL) { Py_DECREF(iter); if (PyErr_Occurred()) return NULL; #if PY_MAJOR_VERSION < 3 return PyInt_FromLong(i_result); #else return PyLong_FromLong(i_result); #endif } #if PY_MAJOR_VERSION < 3 if (PyInt_CheckExact(item)) { long b = PyInt_AS_LONG(item); #else if (PyLong_CheckExact(item)) { long b = PyLong_AS_LONG(item); #endif long x = i_result + b; if ((x ^ i_result) >= 0 || (x ^ b) >= 0) { i_result = x; Py_DECREF(item); continue; } } /* Either overflowed or is not an int. Restore real objects and process normally */ #if PY_MAJOR_VERSION < 3 result = PyInt_FromLong(i_result); #else result = PyLong_FromLong(i_result); #endif temp = PyNumber_Add(result, item); Py_DECREF(result); Py_DECREF(item); result = temp; if (result == NULL) { Py_DECREF(iter); return NULL; } } } if (PyFloat_CheckExact(result)) { double f_result = PyFloat_AS_DOUBLE(result); Py_DECREF(result); result = NULL; while (result == NULL) { item = PyIter_Next(iter); if (item == NULL) { Py_DECREF(iter); if (PyErr_Occurred()) return NULL; return PyFloat_FromDouble(f_result); } if (PyFloat_CheckExact(item)) { PyFPE_START_PROTECT("add", Py_DECREF(item); Py_DECREF(iter); return 0) f_result += PyFloat_AS_DOUBLE(item); PyFPE_END_PROTECT(f_result) Py_DECREF(item); continue; } #if PY_MAJOR_VERSION < 3 if (PyInt_CheckExact(item)) { PyFPE_START_PROTECT("add", Py_DECREF(item); Py_DECREF(iter); return 0) f_result += (double)PyInt_AS_LONG(item); PyFPE_END_PROTECT(f_result) Py_DECREF(item); continue; } #else if (PyLong_CheckExact(item)) { PyFPE_START_PROTECT("add", Py_DECREF(item); Py_DECREF(iter); return 0) f_result += PyLong_AsDouble(item); PyFPE_END_PROTECT(f_result) Py_DECREF(item); continue; } #endif result = PyFloat_FromDouble(f_result); temp = PyNumber_Add(result, item); Py_DECREF(result); Py_DECREF(item); result = temp; if (result == NULL) { Py_DECREF(iter); return NULL; } } #endif } for (;;) { item = PyIter_Next(iter); if (item == NULL) { /* error, or end-of-sequence */ if (PyErr_Occurred()) { Py_DECREF(result); result = NULL; } break; } /* It's tempting to use PyNumber_InPlaceAdd instead of PyNumber_Add here, to avoid quadratic running time when doing 'sum(list_of_lists, [])'. However, this would produce a change in behaviour: a snippet like empty = [] sum([[x] for x in range(10)], empty) would change the value of empty. */ temp = PyNumber_Add(result, item); Py_DECREF(result); Py_DECREF(item); result = temp; if (result == NULL) break; } Py_DECREF(iter); return result; } //@} static long get_int(term_t arg, bool eval) { long low; if (!PL_get_long(arg, &low)) { PyObject *low = term_to_python(arg, eval); if (PyLong_Check(low)) { return PyLong_AsLong(low); #if PY_MAJOR_VERSION < 3 } else if (PyInt_Check(low)) { return PyInt_AsLong(low); #endif } else { return 0; } } return low; } /* Return number of items in range/xrange (lo, hi, step). step > 0 * required. Return a value < 0 if & only if the true value is too * large to fit in a signed long. */ static long get_len_of_range(long lo, long hi, long step) { /* ------------------------------------------------------------- If lo >= hi, the range is empty. Else if n values are in the range, the last one is lo + (n-1)*step, which must be <= hi-1. Rearranging, n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so the RHS is non-negative and so truncation is the same as the floor. Letting M be the largest positive long, the worst case for the RHS numerator is hi=M, lo=-M-1, and then hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough precision to compute the RHS exactly. ---------------------------------------------------------------*/ long n = 0; if (lo < hi) { unsigned long uhi = (unsigned long)hi; unsigned long ulo = (unsigned long)lo; unsigned long diff = uhi - ulo - 1; n = (long)(diff / (unsigned long)step + 1); } return n; }