473,671 Members | 2,193 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

TCL/PHP problem involving a PHP function that has to utilize a TCL proc

I wrote this PHP function in the hopes that it would properly use a TCL
proc I wrote about 4 years ago:

if (!function_exis ts('proper_case ')) {
/**
* Ths function will convert a string into a proper case format using
the customized TCL proc "PROPER_CAS E" from the included TCL string
tools libraries
*
* @access public
* @param mixed $text
* @param mixed $tclLibPath Path to TCL Library files
* @param DBActionPerform er $dbAP You must generate a descendant of
MethodGenerator ForActionPerfor mer to retrieve customized command-line
formatting to call TCL shell
* @return mixed $text properly formatted in Proper Case Form
* @see DBActionPerform er
* @uses tcl_string_tool s::PROPER_CASE
*/
function &proper_case($t ext, $tclLibPath, $dbAP) {
if (!is_object($db AP)) $dbAP =& new DBActionPerform er(); // NO NEED TO
CONNECT NOR DISCONNECT
list('tclKomman d', 'tclRedirect') =
@array_values($ dbAP->getKommandOSAr ray('tcl'));
$tclSourceStrin g = @tcl_lib_includ e($tclLibPath);
if (!preg_match('/;[\n\r\s\t]*$/i', $tclSourceStrin g))
$tclSourceStrin g .= ';'; // ADD ";" TO ADD ONE MORE TCL COMMAND TO THE
SINGLE LINE
$msg = exec("$tclKomma nd \"$tclSourceStr ing puts [PROPER_CASE
{$text}]\" $tclRedirect");
if (preg_match('/^[eE](rror:)/i', $msg)) {
trigger_error(" Error involving TCL proc \"PROPER_CAS E\" on \"$text\":
" . nl2br($msg), E_USER_WARNING) ; // GENERATE WARNING ONLY
return $text;
} else {
return $msg;
}
}
}

-----------------------------

Problem is very simple: <b>tclsh</b>. I have no idea how to put all of
the TCL commands onto the same line as "tclsh" command. ELSE I have no
idea how to work with the generated <b>tclsh</b> environment from
Apache/PHP.

In short, I'm stuck. I have to get this up and running and rather than
rewriting an entire series of TCL procs into PHP, I need a faster and
more practical solution to this one!

thanx
Phil

Mar 8 '06 #1
4 1956
# Problem is very simple: <b>tclsh</b>. I have no idea how to put all of
# the TCL commands onto the same line as "tclsh" command. ELSE I have no
# idea how to work with the generated <b>tclsh</b> environment from
# Apache/PHP.

How about
exec(".../tclsh <<':eof'\ntcl script\ntcl script\n...\n:e of",&output)

Also probably needs updating:

/*
PHP=/usr/local/src/php-4.0.4pl1
ZEND=/usr/local/src/php-4.0.4pl1/Zend
tclphp.o: $(GENERIC_DIR)/tclphp.c
$(CC) -w -DCOMPILE_DL=1 -I$(PHP) -I$(PHP)/main -I$(PHP)/TSRM -I$(ZEND) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclphp.c
tclphp.so: ${OBJS} tclphp.o ${STUB_LIB_FILE }
rm -f ${TCL_LIB_FILE}
${SHLIB_LD} -o tclphp.so ${OBJS} tclphp.o ${LIBS}
$(RANLIB) tclphp.so

<?php
//dl("tclphp.so") ;

$param = "MiXeD cAsE";
$return = tclphp("string tolower \{$param}");

print("We sent \"$param\" and got \"$return\"" );
?>
*/
/*
tclphp [type] script

Standard Tcl plus one function:
php expression ...

tclphp.so
This function.
tcl8.3.so
*/

#define IS_EXT_MODULE

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "php.h"
#include "tcl.h"

static int isLong(Tcl_Obj *obj,long *lval) {
char *s = Tcl_GetStringFr omObj(obj,0),*t ;
*lval = strtol(s,&t,0);
return s!=t && !*t;
}
static Tcl_Interp *interp = 0;

/* declaration of functions to be exported */
ZEND_FUNCTION(t clphp);
ZEND_MINIT_FUNC TION(tclphp);
ZEND_MSHUTDOWN_ FUNCTION(tclphp );

/* compiled function list so Zend knows what's in this module */
zend_function_e ntry tclphp_function s[] = {
ZEND_FE(tclphp, NULL)
{NULL,NULL,NULL }
};

/* compiled module information */
zend_module_ent ry tclphp_module_e ntry = {
"tclphp module",
tclphp_function s,
ZEND_MINIT(tclp hp),ZEND_MSHUTD OWN(tclphp),NUL L,NULL,NULL,
STANDARD_MODULE _PROPERTIES
};

/* implement standard "stub" routine to introduce ourselves to Zend */
#if COMPILE_DL
ZEND_GET_MODULE (tclphp)
#endif

ZEND_MINIT_FUNC TION(tclphp) {
char initialisation[] =
"source $tcl_pkgPath/tcl$tcl_version/init.tcl\n"
;
interp = Tcl_CreateInter p();
#ifdef TCL_MEM_DEBUG
Tcl_InitMemory( interp);
#endif
if (Tcl_Init(inter p)==TCL_ERROR) {
Tcl_DString S;
Tcl_DStringInit (&S);
Tcl_DStringAppe nd(&S,"interpre tter Tcl_Init failed: ",-1);
Tcl_DStringAppe nd(&S,Tcl_GetSt ringResult(inte rp),-1);
zend_error(E_WA RNING,Tcl_DStri ngValue(&S));
Tcl_DStringFree (&S);
return FAILURE;
}
Tcl_SetVar(inte rp,"tcl_rcFileN ame","~/.tclshrc",TCL_G LOBAL_ONLY);
Tcl_SourceRCFil e(interp);
if (Tcl_Eval(inter p,initialisatio n)!=TCL_OK) {
Tcl_DString S;
Tcl_DStringInit (&S);
Tcl_DStringAppe nd(&S,"interpre tter initialisation failed: ",-1);
Tcl_DStringAppe nd(&S,Tcl_GetSt ringResult(inte rp),-1);
Tcl_DStringAppe nd(&S,": ",-1);
Tcl_DStringAppe nd(&S,initialis ation,-1);
zend_error(E_WA RNING,Tcl_DStri ngValue(&S));
Tcl_DStringFree (&S);
return FAILURE;
}
return SUCCESS;
}

ZEND_MSHUTDOWN_ FUNCTION(tclphp ) {
Tcl_DeleteInter p(interp);
interp = 0;
return SUCCESS;
}

/* implement function that is meant to be made available to PHP */
ZEND_FUNCTION(t clphp) {
int argc = ZEND_NUM_ARGS() ;
zval **script;
zval **type;
char Type;
int rc;
Tcl_Obj *Script,*result ;

/*
Argument processing.
*/
if (argc==1) {
if (zend_get_param eters_ex(1,&scr ipt)!=SUCCESS) WRONG_PARAM_COU NT;
Type = 's';
}else if (argc==2) {
if (zend_get_param eters_ex(2,&typ e,&script)!=SUC CESS) WRONG_PARAM_COU NT;
if (argc==2 && (*type)->type!=IS_STRIN G) convert_to_stri ng_ex(type);
Type = tolower(Z_STRVA L_PP(type)[0]);
}else {
WRONG_PARAM_COU NT;
}
if ((*script)->type!=IS_STRIN G) {
convert_to_stri ng_ex(script);
}

/*
Evaluate the script and coerce to the desired return value.
*/
Script = Tcl_NewStringOb j(Z_STRVAL_PP(s cript),Z_STRLEN _PP(script));
Tcl_IncrRefCoun t(Script);
rc = Tcl_EvalObjEx(i nterp,Script,TC L_EVAL_DIRECT|T CL_EVAL_GLOBAL) ;
Tcl_DecrRefCoun t(Script);
result = Tcl_GetObjResul t(interp);
switch (rc==TCL_OK ? Type : 0) {
case 0: /*error*/ error: {
char *s = Tcl_GetStringRe sult(interp);
zend_error(E_WA RNING,s);
RETVAL_NULL();
} break;
case 'd': /*double*/ {
double d;
if (Tcl_GetDoubleF romObj(interp,r esult,&d)!=TCL_ OK) goto error;
RETVAL_DOUBLE(d );
} break;
case 'i': case 'l': /*long int*/ {
long l;
if (Tcl_GetLongFro mObj(interp,res ult,&l)!=TCL_OK ) goto error;
RETVAL_LONG(l);
} break;
case 'b': /*boolean*/ {
int b;
if (Tcl_GetBoolean FromObj(interp, result,&b)!=TCL _OK) goto error;
if (b) {RETVAL_TRUE;}
else {RETVAL_FALSE;}
} break;
case 'a': /*array*/ {
int N; Tcl_Obj **P;
if (Tcl_ListObjGet Elements(interp ,result,&N,&P)! =TCL_OK) goto error;
else if (N&1) {
Tcl_SetResult(i nterp,"returned list for array has odd number of elements",TCL_S TATIC);
goto error;
}
array_init(retu rn_value);
for (; N>0; N-=2,P+=2) {
long lval; int bval; double dval; char *sval; int slen;
if (isLong(P[0],&lval)) {
long index = lval;
if (isLong(P[1],&lval)) {
add_index_long( return_value,in dex,lval);
}else if (Tcl_GetDoubleF romObj(0,P[1],&dval)==TCL_OK ) {
add_index_doubl e(return_value, index,dval);
}else if (Tcl_GetLongFro mObj(0,P[1],&lval)==TCL_OK ) {
add_index_long( return_value,in dex,lval);
}else if (Tcl_GetBoolean FromObj(0,P[1],&bval)==TCL_OK ) {
add_index_long( return_value,in dex,(long)bval) ;
}else {
sval = Tcl_GetStringFr omObj(P[1],&slen);
add_index_strin gl(return_value ,index,sval,sle n,1);
}
}else {
char *key = Tcl_GetStringFr omObj(P[0],0);
if (isLong(P[1],&lval)) {
add_assoc_long( return_value,ke y,lval);
}else if (Tcl_GetDoubleF romObj(0,P[1],&dval)==TCL_OK ) {
add_assoc_doubl e(return_value, key,dval);
}else if (Tcl_GetLongFro mObj(0,P[1],&lval)==TCL_OK ) {
add_assoc_long( return_value,ke y,lval);
}else if (Tcl_GetBoolean FromObj(0,P[1],&bval)==TCL_OK ) {
add_assoc_long( return_value,ke y,(long)bval);
}else {
sval = Tcl_GetStringFr omObj(P[1],&slen);
add_assoc_strin gl(return_value ,key,sval,slen, 1);
}
}
}
} break;
default: /*string*/ {
int n; char *s = Tcl_GetStringFr omObj(result,&n );
RETVAL_STRINGL( s,n,1);
} break;
}

/*
Clean up and quit.
*/
Tcl_ResetResult (interp);
return;
}


--
SM Ryan http://www.rawbw.com/~wyrmwif/
Where do you get those wonderful toys?
Mar 8 '06 #2

SM Ryan wrote:
# Problem is very simple: <b>tclsh</b>. I have no idea how to put all of
# the TCL commands onto the same line as "tclsh" command. ELSE I have no
# idea how to work with the generated <b>tclsh</b> environment from
# Apache/PHP.

How about
exec(".../tclsh <<':eof'\ntcl script\ntcl script\n...\n:e of",&output)

Ok this is what I did based on yoru suggestion:

if (!function_exis ts('proper_case ')) {
/**
* Ths function will convert a string into a proper case format using
the customized TCL proc "PROPER_CAS E" from the included TCL string
tools libraries
*
* @access public
* @param mixed $text
* @param mixed $tclLibPath Path to TCL Library files
* @param DBActionPerform er $dbAP You must generate a descendant of
MethodGenerator ForActionPerfor mer to retrieve customized command-line
formatting to call TCL shell
* @return mixed $text properly formatted in Proper Case Form
* @see DBActionPerform er
* @uses tcl_string_tool s::PROPER_CASE
*/
function &proper_case($t ext, $tclLibPath, $dbAP) {
if (!is_object($db AP)) $dbAP =& new DBActionPerform er(); // NO NEED TO
CONNECT NOR DISCONNECT
list($tclKomman d, $tclRedirect) =
@array_values($ dbAP->getKommandOSAr ray('tcl'));
$tclSourceStrin g = @tcl_lib_includ e($tclLibPath);
if (!preg_match('/;[\n\r\s\t]*$/i', $tclSourceStrin g))
$tclSourceStrin g .= ';'; // ADD ";" TO ADD ONE MORE TCL COMMAND TO THE
SINGLE LINE
$tclSourceStrin g = str_replace(';' , ";\n", $tclSourceStrin g);
$msg = exec("$tclKomma nd \"':eof'\n$tclS ourceString puts [PROPER_CASE
\{$text}]\n:eof\" $tclRedirect");
if (preg_match('/^[eE](rror:)/i', $msg) ||
strcmp(strtolow er(trim($msg)), strtolower(trim ($text))) != 0) {
trigger_error(" Error involving TCL proc \"PROPER_CAS E\" on \"$text\":
" . nl2br($msg), E_USER_WARNING) ; // GENERATE WARNING ONLY
return $text;
} else {
return $msg;
}
}
}

produces this warning:

Warning: Error involving TCL proc "PROPER_CAS E" on "John
O'Neill-Labrador": :eof": no such file or directory

Didn't try tclphp, that was beyond me completely, have no idea what to
do with that, sorry, please help.

Thanx
Phil

Also probably needs updating:

/*
PHP=/usr/local/src/php-4.0.4pl1
ZEND=/usr/local/src/php-4.0.4pl1/Zend
tclphp.o: $(GENERIC_DIR)/tclphp.c
$(CC) -w -DCOMPILE_DL=1 -I$(PHP) -I$(PHP)/main -I$(PHP)/TSRM -I$(ZEND) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclphp.c
tclphp.so: ${OBJS} tclphp.o ${STUB_LIB_FILE }
rm -f ${TCL_LIB_FILE}
${SHLIB_LD} -o tclphp.so ${OBJS} tclphp.o ${LIBS}
$(RANLIB) tclphp.so

<?php
//dl("tclphp.so") ;

$param = "MiXeD cAsE";
$return = tclphp("string tolower \{$param}");

print("We sent \"$param\" and got \"$return\"" );
?>
*/
/*
tclphp [type] script

Standard Tcl plus one function:
php expression ...

tclphp.so
This function.
tcl8.3.so
*/

#define IS_EXT_MODULE

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "php.h"
#include "tcl.h"

static int isLong(Tcl_Obj *obj,long *lval) {
char *s = Tcl_GetStringFr omObj(obj,0),*t ;
*lval = strtol(s,&t,0);
return s!=t && !*t;
}
static Tcl_Interp *interp = 0;

/* declaration of functions to be exported */
ZEND_FUNCTION(t clphp);
ZEND_MINIT_FUNC TION(tclphp);
ZEND_MSHUTDOWN_ FUNCTION(tclphp );

/* compiled function list so Zend knows what's in this module */
zend_function_e ntry tclphp_function s[] = {
ZEND_FE(tclphp, NULL)
{NULL,NULL,NULL }
};

/* compiled module information */
zend_module_ent ry tclphp_module_e ntry = {
"tclphp module",
tclphp_function s,
ZEND_MINIT(tclp hp),ZEND_MSHUTD OWN(tclphp),NUL L,NULL,NULL,
STANDARD_MODULE _PROPERTIES
};

/* implement standard "stub" routine to introduce ourselves to Zend */
#if COMPILE_DL
ZEND_GET_MODULE (tclphp)
#endif

ZEND_MINIT_FUNC TION(tclphp) {
char initialisation[] =
"source $tcl_pkgPath/tcl$tcl_version/init.tcl\n"
;
interp = Tcl_CreateInter p();
#ifdef TCL_MEM_DEBUG
Tcl_InitMemory( interp);
#endif
if (Tcl_Init(inter p)==TCL_ERROR) {
Tcl_DString S;
Tcl_DStringInit (&S);
Tcl_DStringAppe nd(&S,"interpre tter Tcl_Init failed: ",-1);
Tcl_DStringAppe nd(&S,Tcl_GetSt ringResult(inte rp),-1);
zend_error(E_WA RNING,Tcl_DStri ngValue(&S));
Tcl_DStringFree (&S);
return FAILURE;
}
Tcl_SetVar(inte rp,"tcl_rcFileN ame","~/.tclshrc",TCL_G LOBAL_ONLY);
Tcl_SourceRCFil e(interp);
if (Tcl_Eval(inter p,initialisatio n)!=TCL_OK) {
Tcl_DString S;
Tcl_DStringInit (&S);
Tcl_DStringAppe nd(&S,"interpre tter initialisation failed: ",-1);
Tcl_DStringAppe nd(&S,Tcl_GetSt ringResult(inte rp),-1);
Tcl_DStringAppe nd(&S,": ",-1);
Tcl_DStringAppe nd(&S,initialis ation,-1);
zend_error(E_WA RNING,Tcl_DStri ngValue(&S));
Tcl_DStringFree (&S);
return FAILURE;
}
return SUCCESS;
}

ZEND_MSHUTDOWN_ FUNCTION(tclphp ) {
Tcl_DeleteInter p(interp);
interp = 0;
return SUCCESS;
}

/* implement function that is meant to be made available to PHP */
ZEND_FUNCTION(t clphp) {
int argc = ZEND_NUM_ARGS() ;
zval **script;
zval **type;
char Type;
int rc;
Tcl_Obj *Script,*result ;

/*
Argument processing.
*/
if (argc==1) {
if (zend_get_param eters_ex(1,&scr ipt)!=SUCCESS) WRONG_PARAM_COU NT;
Type = 's';
}else if (argc==2) {
if (zend_get_param eters_ex(2,&typ e,&script)!=SUC CESS) WRONG_PARAM_COU NT;
if (argc==2 && (*type)->type!=IS_STRIN G) convert_to_stri ng_ex(type);
Type = tolower(Z_STRVA L_PP(type)[0]);
}else {
WRONG_PARAM_COU NT;
}
if ((*script)->type!=IS_STRIN G) {
convert_to_stri ng_ex(script);
}

/*
Evaluate the script and coerce to the desired return value.
*/
Script = Tcl_NewStringOb j(Z_STRVAL_PP(s cript),Z_STRLEN _PP(script));
Tcl_IncrRefCoun t(Script);
rc = Tcl_EvalObjEx(i nterp,Script,TC L_EVAL_DIRECT|T CL_EVAL_GLOBAL) ;
Tcl_DecrRefCoun t(Script);
result = Tcl_GetObjResul t(interp);
switch (rc==TCL_OK ? Type : 0) {
case 0: /*error*/ error: {
char *s = Tcl_GetStringRe sult(interp);
zend_error(E_WA RNING,s);
RETVAL_NULL();
} break;
case 'd': /*double*/ {
double d;
if (Tcl_GetDoubleF romObj(interp,r esult,&d)!=TCL_ OK) goto error;
RETVAL_DOUBLE(d );
} break;
case 'i': case 'l': /*long int*/ {
long l;
if (Tcl_GetLongFro mObj(interp,res ult,&l)!=TCL_OK ) goto error;
RETVAL_LONG(l);
} break;
case 'b': /*boolean*/ {
int b;
if (Tcl_GetBoolean FromObj(interp, result,&b)!=TCL _OK) goto error;
if (b) {RETVAL_TRUE;}
else {RETVAL_FALSE;}
} break;
case 'a': /*array*/ {
int N; Tcl_Obj **P;
if (Tcl_ListObjGet Elements(interp ,result,&N,&P)! =TCL_OK) goto error;
else if (N&1) {
Tcl_SetResult(i nterp,"returned list for array has odd number of elements",TCL_S TATIC);
goto error;
}
array_init(retu rn_value);
for (; N>0; N-=2,P+=2) {
long lval; int bval; double dval; char *sval; int slen;
if (isLong(P[0],&lval)) {
long index = lval;
if (isLong(P[1],&lval)) {
add_index_long( return_value,in dex,lval);
}else if (Tcl_GetDoubleF romObj(0,P[1],&dval)==TCL_OK ) {
add_index_doubl e(return_value, index,dval);
}else if (Tcl_GetLongFro mObj(0,P[1],&lval)==TCL_OK ) {
add_index_long( return_value,in dex,lval);
}else if (Tcl_GetBoolean FromObj(0,P[1],&bval)==TCL_OK ) {
add_index_long( return_value,in dex,(long)bval) ;
}else {
sval = Tcl_GetStringFr omObj(P[1],&slen);
add_index_strin gl(return_value ,index,sval,sle n,1);
}
}else {
char *key = Tcl_GetStringFr omObj(P[0],0);
if (isLong(P[1],&lval)) {
add_assoc_long( return_value,ke y,lval);
}else if (Tcl_GetDoubleF romObj(0,P[1],&dval)==TCL_OK ) {
add_assoc_doubl e(return_value, key,dval);
}else if (Tcl_GetLongFro mObj(0,P[1],&lval)==TCL_OK ) {
add_assoc_long( return_value,ke y,lval);
}else if (Tcl_GetBoolean FromObj(0,P[1],&bval)==TCL_OK ) {
add_assoc_long( return_value,ke y,(long)bval);
}else {
sval = Tcl_GetStringFr omObj(P[1],&slen);
add_assoc_strin gl(return_value ,key,sval,slen, 1);
}
}
}
} break;
default: /*string*/ {
int n; char *s = Tcl_GetStringFr omObj(result,&n );
RETVAL_STRINGL( s,n,1);
} break;
}

/*
Clean up and quit.
*/
Tcl_ResetResult (interp);
return;
}


--
SM Ryan http://www.rawbw.com/~wyrmwif/
Where do you get those wonderful toys?


Mar 8 '06 #3

SM Ryan wrote:
# Problem is very simple: <b>tclsh</b>. I have no idea how to put all of
# the TCL commands onto the same line as "tclsh" command. ELSE I have no
# idea how to work with the generated <b>tclsh</b> environment from
# Apache/PHP.

How about
exec(".../tclsh <<':eof'\ntcl script\ntcl script\n...\n:e of",&output)

I got it, thanx!

if (!function_exis ts('proper_case ')) {
/**
* Ths function will convert a string into a proper case format using
the customized TCL proc "PROPER_CAS E" from the included TCL string
tools libraries
*
* @access public
* @param mixed $text
* @param mixed $tclLibPath Path to TCL Library files
* @param DBActionPerform er $dbAP You must generate a descendant of
MethodGenerator ForActionPerfor mer to retrieve customized command-line
formatting to call TCL shell
* @return mixed $text properly formatted in Proper Case Form
* @see DBActionPerform er
* @uses tcl_string_tool s::PROPER_CASE
*/
function &proper_case($t ext, $tclLibPath, $dbAP) {
if (!is_object($db AP)) $dbAP =& new DBActionPerform er(); // NO NEED TO
CONNECT NOR DISCONNECT
list($tclKomman d, $tclRedirect) =
@array_values($ dbAP->getKommandOSAr ray('tcl'));
$tclSourceStrin g = tcl_lib_include ($tclLibPath);
if (!preg_match('/;[\n\r\s\t]*$/i', $tclSourceStrin g))
$tclSourceStrin g .= ';'; // ADD ";" TO ADD ONE MORE TCL COMMAND TO THE
SINGLE LINE
$tclSourceStrin g = str_replace(';' , ";\n", $tclSourceStrin g);
$msg = exec("$tclKomma nd << ':eof'\n$tclSou rceString puts [PROPER_CASE
\{$text}]\n:eof $tclRedirect");
if (preg_match('/^[eE](rror:)/i', $msg) ||
strcmp(strtolow er(trim($msg)), strtolower(trim ($text))) != 0) {
trigger_error(" Error involving TCL proc \"PROPER_CAS E\" on \"$text\":
" . nl2br($msg), E_USER_WARNING) ; // GENERATE WARNING ONLY
return $text;
} else {
return $msg;
}
}
}

I have one last question: How will this be optimized to equally work in
Windows?

Thanx
Phil
Also probably needs updating:

/*
PHP=/usr/local/src/php-4.0.4pl1
ZEND=/usr/local/src/php-4.0.4pl1/Zend
tclphp.o: $(GENERIC_DIR)/tclphp.c
$(CC) -w -DCOMPILE_DL=1 -I$(PHP) -I$(PHP)/main -I$(PHP)/TSRM -I$(ZEND) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclphp.c
tclphp.so: ${OBJS} tclphp.o ${STUB_LIB_FILE }
rm -f ${TCL_LIB_FILE}
${SHLIB_LD} -o tclphp.so ${OBJS} tclphp.o ${LIBS}
$(RANLIB) tclphp.so

<?php
//dl("tclphp.so") ;

$param = "MiXeD cAsE";
$return = tclphp("string tolower \{$param}");

print("We sent \"$param\" and got \"$return\"" );
?>
*/
/*
tclphp [type] script

Standard Tcl plus one function:
php expression ...

tclphp.so
This function.
tcl8.3.so
*/

#define IS_EXT_MODULE

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "php.h"
#include "tcl.h"

static int isLong(Tcl_Obj *obj,long *lval) {
char *s = Tcl_GetStringFr omObj(obj,0),*t ;
*lval = strtol(s,&t,0);
return s!=t && !*t;
}
static Tcl_Interp *interp = 0;

/* declaration of functions to be exported */
ZEND_FUNCTION(t clphp);
ZEND_MINIT_FUNC TION(tclphp);
ZEND_MSHUTDOWN_ FUNCTION(tclphp );

/* compiled function list so Zend knows what's in this module */
zend_function_e ntry tclphp_function s[] = {
ZEND_FE(tclphp, NULL)
{NULL,NULL,NULL }
};

/* compiled module information */
zend_module_ent ry tclphp_module_e ntry = {
"tclphp module",
tclphp_function s,
ZEND_MINIT(tclp hp),ZEND_MSHUTD OWN(tclphp),NUL L,NULL,NULL,
STANDARD_MODULE _PROPERTIES
};

/* implement standard "stub" routine to introduce ourselves to Zend */
#if COMPILE_DL
ZEND_GET_MODULE (tclphp)
#endif

ZEND_MINIT_FUNC TION(tclphp) {
char initialisation[] =
"source $tcl_pkgPath/tcl$tcl_version/init.tcl\n"
;
interp = Tcl_CreateInter p();
#ifdef TCL_MEM_DEBUG
Tcl_InitMemory( interp);
#endif
if (Tcl_Init(inter p)==TCL_ERROR) {
Tcl_DString S;
Tcl_DStringInit (&S);
Tcl_DStringAppe nd(&S,"interpre tter Tcl_Init failed: ",-1);
Tcl_DStringAppe nd(&S,Tcl_GetSt ringResult(inte rp),-1);
zend_error(E_WA RNING,Tcl_DStri ngValue(&S));
Tcl_DStringFree (&S);
return FAILURE;
}
Tcl_SetVar(inte rp,"tcl_rcFileN ame","~/.tclshrc",TCL_G LOBAL_ONLY);
Tcl_SourceRCFil e(interp);
if (Tcl_Eval(inter p,initialisatio n)!=TCL_OK) {
Tcl_DString S;
Tcl_DStringInit (&S);
Tcl_DStringAppe nd(&S,"interpre tter initialisation failed: ",-1);
Tcl_DStringAppe nd(&S,Tcl_GetSt ringResult(inte rp),-1);
Tcl_DStringAppe nd(&S,": ",-1);
Tcl_DStringAppe nd(&S,initialis ation,-1);
zend_error(E_WA RNING,Tcl_DStri ngValue(&S));
Tcl_DStringFree (&S);
return FAILURE;
}
return SUCCESS;
}

ZEND_MSHUTDOWN_ FUNCTION(tclphp ) {
Tcl_DeleteInter p(interp);
interp = 0;
return SUCCESS;
}

/* implement function that is meant to be made available to PHP */
ZEND_FUNCTION(t clphp) {
int argc = ZEND_NUM_ARGS() ;
zval **script;
zval **type;
char Type;
int rc;
Tcl_Obj *Script,*result ;

/*
Argument processing.
*/
if (argc==1) {
if (zend_get_param eters_ex(1,&scr ipt)!=SUCCESS) WRONG_PARAM_COU NT;
Type = 's';
}else if (argc==2) {
if (zend_get_param eters_ex(2,&typ e,&script)!=SUC CESS) WRONG_PARAM_COU NT;
if (argc==2 && (*type)->type!=IS_STRIN G) convert_to_stri ng_ex(type);
Type = tolower(Z_STRVA L_PP(type)[0]);
}else {
WRONG_PARAM_COU NT;
}
if ((*script)->type!=IS_STRIN G) {
convert_to_stri ng_ex(script);
}

/*
Evaluate the script and coerce to the desired return value.
*/
Script = Tcl_NewStringOb j(Z_STRVAL_PP(s cript),Z_STRLEN _PP(script));
Tcl_IncrRefCoun t(Script);
rc = Tcl_EvalObjEx(i nterp,Script,TC L_EVAL_DIRECT|T CL_EVAL_GLOBAL) ;
Tcl_DecrRefCoun t(Script);
result = Tcl_GetObjResul t(interp);
switch (rc==TCL_OK ? Type : 0) {
case 0: /*error*/ error: {
char *s = Tcl_GetStringRe sult(interp);
zend_error(E_WA RNING,s);
RETVAL_NULL();
} break;
case 'd': /*double*/ {
double d;
if (Tcl_GetDoubleF romObj(interp,r esult,&d)!=TCL_ OK) goto error;
RETVAL_DOUBLE(d );
} break;
case 'i': case 'l': /*long int*/ {
long l;
if (Tcl_GetLongFro mObj(interp,res ult,&l)!=TCL_OK ) goto error;
RETVAL_LONG(l);
} break;
case 'b': /*boolean*/ {
int b;
if (Tcl_GetBoolean FromObj(interp, result,&b)!=TCL _OK) goto error;
if (b) {RETVAL_TRUE;}
else {RETVAL_FALSE;}
} break;
case 'a': /*array*/ {
int N; Tcl_Obj **P;
if (Tcl_ListObjGet Elements(interp ,result,&N,&P)! =TCL_OK) goto error;
else if (N&1) {
Tcl_SetResult(i nterp,"returned list for array has odd number of elements",TCL_S TATIC);
goto error;
}
array_init(retu rn_value);
for (; N>0; N-=2,P+=2) {
long lval; int bval; double dval; char *sval; int slen;
if (isLong(P[0],&lval)) {
long index = lval;
if (isLong(P[1],&lval)) {
add_index_long( return_value,in dex,lval);
}else if (Tcl_GetDoubleF romObj(0,P[1],&dval)==TCL_OK ) {
add_index_doubl e(return_value, index,dval);
}else if (Tcl_GetLongFro mObj(0,P[1],&lval)==TCL_OK ) {
add_index_long( return_value,in dex,lval);
}else if (Tcl_GetBoolean FromObj(0,P[1],&bval)==TCL_OK ) {
add_index_long( return_value,in dex,(long)bval) ;
}else {
sval = Tcl_GetStringFr omObj(P[1],&slen);
add_index_strin gl(return_value ,index,sval,sle n,1);
}
}else {
char *key = Tcl_GetStringFr omObj(P[0],0);
if (isLong(P[1],&lval)) {
add_assoc_long( return_value,ke y,lval);
}else if (Tcl_GetDoubleF romObj(0,P[1],&dval)==TCL_OK ) {
add_assoc_doubl e(return_value, key,dval);
}else if (Tcl_GetLongFro mObj(0,P[1],&lval)==TCL_OK ) {
add_assoc_long( return_value,ke y,lval);
}else if (Tcl_GetBoolean FromObj(0,P[1],&bval)==TCL_OK ) {
add_assoc_long( return_value,ke y,(long)bval);
}else {
sval = Tcl_GetStringFr omObj(P[1],&slen);
add_assoc_strin gl(return_value ,key,sval,slen, 1);
}
}
}
} break;
default: /*string*/ {
int n; char *s = Tcl_GetStringFr omObj(result,&n );
RETVAL_STRINGL( s,n,1);
} break;
}

/*
Clean up and quit.
*/
Tcl_ResetResult (interp);
return;
}


--
SM Ryan http://www.rawbw.com/~wyrmwif/
Where do you get those wonderful toys?


Mar 8 '06 #4
In article <11************ *********@j52g2 000cwj.googlegr oups.com>,
comp.lang.tcl <ph************ **@gmail.com> wrote:
I wrote this PHP function in the hopes that it would properly use a TCL
proc I wrote about 4 years ago:

Mar 9 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
2467
by: Phil Powell | last post by:
/*-------------------------------------------------------------------------------------------- This function will utilize the ability to use HTTP-based WWW Authentication, checking for the global authorized password against the password entered in the client project's CSV file. Will not function unless this password exists. See http://www.php.net/manual/en/features.http-auth.php for more info...
8
11361
by: vpadial | last post by:
Hello, I want to build a library to help exporting c++ functions to a scripting languagge. The scripting language provides a function to register functions like: ANY f0() ANY f1(ANY) ANY f2(ANY, ANY) ANY f3(ANY, ANY, ANY)
10
2332
by: Dirk Vanhaute | last post by:
I have only small knowledge of c++, but I would like to compile the example in http://support.microsoft.com/kb/q246772/ HOWTO: Retrieve and Set the Default Printer in Windows I included "#include <Windows.h>" at the start, and the following goes wrong : BOOL DPGetDefaultPrinter(LPTSTR pPrinterName, LPDWORD pdwBufferSize) { ....
12
9516
by: Newbie | last post by:
how can i call an oracle function to get data without using a select statement or stored procedures? given a project_no, i need to call the function: ops$sqltime.pa_new_job_no_fn which will return the next job_no thanks in advance.
16
2627
by: NOtcarvinSPAM | last post by:
It occurs to me that if I have a work object that gets executed via QueueUserWorkItem AND the work proc accesses only that object's instance data I STILL may have to lock because the object constructor ran in a different thread. That therefpre means that without a lock the threadpool thread might not get the correct view of the instance data. (Specifically, it might still be seen as null). Has this ever come up before? Thanks,
1
1643
by: Kathir | last post by:
In C, I have a doubt about Function pointers. Lets say , typedef void (*test_audit_proc_t)( int *t, int index, int instnb); typedef struct a_index {
2
3848
by: Amal P | last post by:
Hi, This is the program that i made to test the usage of inline function. I am using vc 6.0 compiler. Please see the below program. int NonInline( int a, int b ) { return ( a b )? a: b; }
8
11255
by: colmkav | last post by:
Can someone tell me how I can access the return value of a function called from Oracle as opposed to a store proc from oracle? my oracle function is get_num_dates_varposfile. I am only used to using this method with store procs that dont return a value back to Access. Hope this makes sense. Set Cmd = New Command With Cmd Set .ActiveConnection = get_XE_Conn 'makes a connection Oracle XE
7
7051
by: jamesclose | last post by:
My problem is this (apologies if this is a little long ... hang in there): I can define a function in VB.NET with optional parameters that wraps a SQL procedure: Sub Test(Optional ByVal Arg1 As Integer = 0, _ Optional ByVal Arg2 As Integer = 0, _ Optional ByVal Arg3 As Integer = 0) ' Call my SQL proc with the same signature
0
8909
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8819
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8667
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6222
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5690
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4399
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2806
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2048
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1801
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.