Added ole::ref self for passing an IDispatch to a tcl procedure.
Made use of the variant tcl type
Improvements to the http package.
package require tclole
namespace eval ::ole::http {
- variable version 1.1.0
+ variable version 1.2.0
variable watchlist {}
variable watchtimer {}
}
if {$state(-query) ne ""} { set state(method) POST }
- set state(xmlhttp) [ole::ref createobject MSXML2.XMLHTTP]
+ set state(xmlhttp) ""
+ foreach progid {MSXML2.XMLHTTP.6.0 MSXML2.XMLHTTP.5.0 MSXML2.XMLHTTP.4.0 \
+ MSXML2.XMLHTTP.3.0 MSXML2.XMLHTTP.2.6 Microsoft.XMLHTTP} {
+ if {![catch {set state(xmlhttp) [ole::ref createobject MSXML2.XMLHTTP]}]} {
+ break
+ }
+ }
+ if {$state(xmlhttp) eq {}} { return -code error "error: no suitable XMLHttp object available" }
$state(xmlhttp) open $state(method) $url True
+ $state(xmlhttp) -put onreadystatechange [ole::ref self [list [namespace origin Callback] $token]]
foreach {hdr val} $state(-headers) {
$state(xmlhttp) setRequestHeader $hdr $val
}
}
return $token
}
-
+
+proc ::ole::http::Callback {token dispid args} {
+ # replace the polling stuff with a check of ...
+ upvar #0 $token state
+ if {[$state(xmlhttp) readyState] == 4} {
+ # do stuff
+ }
+}
+
proc ::ole::http::wait {token} {
upvar #0 $token state
watch $token
set state(meta) {}
foreach line [split [$state(xmlhttp) getAllResponseHeaders] "\n"] {
if {[regexp {^([^:]+): ?(.*)} $line -> h v]} {
- lappend state(meta) $h $v
+ lappend state(meta) $h [string trimright $v]
}
}
if {$state(-command) ne ""} {
upvar #0 $token state
return $state(code)
}
-proc ::ole::http::meta {token} {
+proc ::ole::http::meta {token {header {}}} {
upvar #0 $token state
- return $state(meta)
+ if {$header ne {}} {
+ set header [string tolower $header]
+ foreach {h v} $state(meta) {
+ if {[string equal $header [string tolower $h]]} {
+ return $v
+ }
+ }
+ } else {
+ return $state(meta)
+ }
+ return {}
}
proc ::ole::http::cleanup {token} {
upvar #0 $token state
OleInterpCom *this = (OleInterpCom *)This;
Tcl_HashEntry *entryPtr = NULL;
HRESULT hr = S_OK;
- Tcl_Obj **objv;
- unsigned int n, objc = 0;
+ Tcl_Obj **objv, **tmpv;
+ unsigned int n, objc = 0, tmpc = 0;
if (memcmp(riid, &IID_NULL, sizeof(IID)) != 0) {
return E_FAIL;
return E_FAIL;
}
- objv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (dpPtr->cArgs + 2));
- objv[objc] = this->cmdObj;
- Tcl_IncrRefCount(objv[objc++]);
- objv[objc] = Tcl_NewIntObj(dispidMember);
- Tcl_IncrRefCount(objv[objc++]);
+ /* append dispid and the variant args to the command list */
+ Tcl_ListObjGetElements(NULL, this->cmdObj, &objc, &objv);
+ tmpv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc + dpPtr->cArgs + 1));
+ for (tmpc = 0; tmpc < objc; ++tmpc) {
+ tmpv[tmpc] = objv[tmpc];
+ Tcl_IncrRefCount(tmpv[tmpc]);
+ }
+ tmpv[tmpc] = Tcl_NewIntObj(dispidMember);
+ Tcl_IncrRefCount(tmpv[tmpc]);
+ ++tmpc;
for (n = 0; SUCCEEDED(hr) && n < dpPtr->cArgs; ++n) {
- hr = OleVariantObj(this->interp, &dpPtr->rgvarg[dpPtr->cArgs - n - 1], &objv[objc]);
+ hr = OleVariantObj(this->interp, &dpPtr->rgvarg[dpPtr->cArgs - n - 1], &tmpv[tmpc]);
if (SUCCEEDED(hr)) {
- Tcl_IncrRefCount(objv[objc]);
+ Tcl_IncrRefCount(tmpv[tmpc]);
}
- ++objc;
+ ++tmpc;
}
if (SUCCEEDED(hr)) {
- hr = EvalObjv(this->interp, objc, objv, eiPtr);
+ hr = EvalObjv(this->interp, tmpc, tmpv, eiPtr);
}
- for (n = 0; n < objc; ++n) {
- Tcl_DecrRefCount(objv[n]);
+ for (n = 0; n < tmpc; ++n) {
+ Tcl_DecrRefCount(tmpv[n]);
}
+ ckfree((char *)tmpv);
return hr;
}
break;
case VT_CY: case VT_DECIMAL: case VT_DATE:
case VT_VARIANT:
- /* *resultPtrPtr = Ole_NewVariantObj(vPtr);*/
- /* break; */
+ *resultPtrPtr = Ole_NewVariantObj(vPtr);
+ break;
default: {
VARIANT vv;
VariantInit(&vv);
}
OleDispParamsFree(dp);
if (SUCCEEDED(hr)) {
- Tcl_Obj *resultObj = Ole_NewVariantObj(v);
+ Tcl_Obj *resultObj = NULL; /* Ole_NewVariantObj(&v); */
hr = OleVariantObj(interp, &v, &resultObj);
if (SUCCEEDED(hr)) {
Tcl_SetObjResult(interp, resultObj);
}
}
+ if (ei.bstrDescription != NULL) SysFreeString(ei.bstrDescription);
+ if (ei.bstrSource != NULL) SysFreeString(ei.bstrSource);
+ if (ei.bstrHelpFile != NULL) SysFreeString(ei.bstrHelpFile);
+
VariantClear(&v);
}
if (FAILED(hr)) {
+ /* if hr == DISP_E_EXCEPTION */
+
Tcl_SetObjResult(interp, Ole_Win32ErrorObj(interp, "invoke", hr));
return TCL_ERROR;
}
Tcl_CreateObjCommand(interp, "ole::ref", RefCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "ole::foreach", OleForeachCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "ole::bind", OleBindCmd, (ClientData)pkgPtr, NULL);
+ Tcl_CreateObjCommand(interp, "ole::type", OleTypeCmd, (ClientData)pkgPtr, NULL);
Tcl_PkgProvideEx(interp, PACKAGE_NAME, PACKAGE_VERSION, NULL);
return TCL_OK;
/* varobj.c */
-Tcl_Obj * Ole_NewVariantObj(const VARIANT v);
-void Ole_SetVariantObj(Tcl_Obj *objPtr, const VARIANT v);
+Tcl_Obj * Ole_NewVariantObj(const VARIANT *varPtr);
+void Ole_SetVariantObj(Tcl_Obj *objPtr, const VARIANT *varPtr);
+int OleTypeCmd(ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
#ifdef __cplusplus
}
Tcl_Obj *
-Ole_NewVariantObj(const VARIANT v)
+Ole_NewVariantObj(const VARIANT *varPtr)
{
Tcl_Obj *objPtr = Tcl_NewObj();
- Ole_SetVariantObj(objPtr, v);
+ Ole_SetVariantObj(objPtr, varPtr);
return objPtr;
}
void
-Ole_SetVariantObj(Tcl_Obj *objPtr, const VARIANT v)
+Ole_SetVariantObj(Tcl_Obj *objPtr, const VARIANT *varPtr)
{
- VARIANT *varPtr;
+ VARIANT *newPtr;
if (Tcl_IsShared(objPtr)) {
Tcl_Panic("%s called with shared object", "Ole_SetVariantObj");
if (objPtr->typePtr && objPtr->typePtr->freeIntRepProc != NULL) {
objPtr->typePtr->freeIntRepProc(objPtr);
}
- varPtr = (VARIANT *)ckalloc(sizeof(VARIANT));
- VariantInit(varPtr);
- VariantCopy(varPtr, GET_VARIANTREP(objPtr));
- SET_VARIANTREP(objPtr, varPtr);
+ newPtr = (VARIANT *)ckalloc(sizeof(VARIANT));
+ VariantInit(newPtr);
+ VariantCopy(newPtr, (VARIANT *)varPtr);
+ SET_VARIANTREP(objPtr, newPtr);
objPtr->typePtr = &tclVariantType;
}
+int
+OleVariantCmd(ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[])
+{
+ int n, eltc = 0;
+ Tcl_Obj **eltv = NULL;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "type value");
+ return TCL_ERROR;
+ }
+
+ if (Tcl_ListObjGetElements(interp, objv[1], &eltc, &eltv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ for (n = 0; n < eltc; ++n) {
+ const char *s = Tcl_GetString(eltv[n]);
+
+ }
+
+ return TCL_ERROR;
+}
+
+int
+OleTypeCmd(ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[])
+{
+ const char *name = "string";
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "value");
+ return TCL_ERROR;
+ }
+ if (objv[1]->typePtr) {
+ name = objv[1]->typePtr->name;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1));
+ return TCL_OK;
+}
+
/*
* Local variables:
* indent-tabs-mode: t
#pragma comment (lib, "kernel32.lib")
#include <stdio.h>
#include <math.h>
+
+/*
+ * This library is required for x64 builds with _some_ versions of MSVC
+ */
#if defined(_M_IA64) || defined(_M_AMD64)
+#if _MSC_VER >= 1400 && _MSC_VER < 1500
#pragma comment(lib, "bufferoverflowU")
#endif
+#endif
/* ISO hack for dumb VC++ */
#ifdef _MSC_VER
return !(strstr(Out.buffer, "D4002") != NULL
|| strstr(Err.buffer, "D4002") != NULL
|| strstr(Out.buffer, "D9002") != NULL
- || strstr(Err.buffer, "D9002") != NULL);
+ || strstr(Err.buffer, "D9002") != NULL
+ || strstr(Out.buffer, "D2021") != NULL
+ || strstr(Err.buffer, "D2021") != NULL);
}
\f
int
!if ![echo VCVERSION=_MSC_VER > vercl.x] \
&& ![cl -nologo -TC -P vercl.x $(ERRNULL)]
!include vercl.i
-!if $(VCVERSION) >= 1400
+!if $(VCVERSION) >= 1500
+VCVER=9
+!elseif $(VCVERSION) >= 1400
VCVER=8
-_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
-_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
!elseif $(VCVERSION) >= 1300
VCVER=7
!elseif $(VCVERSION) >= 1200
!endif
!endif
+# Since MSVC8 we must deal with manifest resources.
+!if $(VCVERSION) >= 1400
+_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
+_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
+!endif
+
#----------------------------------------------------------
# Decode the options requested.
#----------------------------------------------------------