1/* BEGIN LICENSE BLOCK 2 * Version: CMPL 1.1 3 * 4 * The contents of this file are subject to the Cisco-style Mozilla Public 5 * License Version 1.1 (the "License"); you may not use this file except 6 * in compliance with the License. You may obtain a copy of the License 7 * at www.eclipse-clp.org/license. 8 * 9 * Software distributed under the License is distributed on an "AS IS" 10 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 11 * the License for the specific language governing rights and limitations 12 * under the License. 13 * 14 * The Original Code is The ECLiPSe Constraint Logic Programming System. 15 * The Initial Developer of the Original Code is Cisco Systems, Inc. 16 * Portions created by the Initial Developer are 17 * Copyright (C) 1997-2006 Cisco Systems, Inc. All Rights Reserved. 18 * 19 * Contributor(s): 20 * 21 * END LICENSE BLOCK */ 22 23/* 24 * System: Eclipse 25 * 26 * $Id: tkeclipse.c,v 1.4 2013/04/17 01:34:20 jschimpf Exp $ 27 * 28 * Code for embedding eclipse into a tcl program 29 */ 30 31#include <stdio.h> 32#include <stdlib.h> 33#include <errno.h> 34#include <signal.h> 35#include <string.h> 36 37#include <tcl.h> 38#include "eclipse.h" 39 40#include "tkcommon.h" 41 42#ifdef __STDC__ 43int EcInit(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []); 44int EcCleanup(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []); 45int EcSetOption(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []); 46int EcPostString(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []); 47int EcPostGoal(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []); 48int EcPostEvent(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []); 49int EcResume(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []); 50int EcRunning(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []); 51int EcResumeStatus(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []); 52int EcHandleEvents(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []); 53int EcQueueWrite(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []); 54int EcQueueRead(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []); 55int EcQueueOpen(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []); 56int EcStreamNr(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []); 57#endif 58 59 60/*--------------------------------------------------------------------------- 61 * ec_init 62 * ec_cleanup 63 *---------------------------------------------------------------------------*/ 64 65int 66EcInit(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) 67{ 68 if (objc != 1) 69 { 70 Tcl_WrongNumArgs(interp, 1, objv, ""); 71 return TCL_ERROR; 72 } 73 if (ec_init() != PSUCCEED) 74 { 75 Tcl_SetResult(interp, "couldn't initialize ECLiPSe", TCL_STATIC); 76 return TCL_ERROR; 77 } 78 return TCL_OK; 79} 80 81int 82EcCleanup(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) 83{ 84 if (objc != 1) 85 { 86 Tcl_WrongNumArgs(interp, 1, objv, ""); 87 return TCL_ERROR; 88 } 89 ec_cleanup(); 90 return TCL_OK; 91} 92 93/*--------------------------------------------------------------------------- 94 * ec_set_option option_name option_val 95 *---------------------------------------------------------------------------*/ 96 97int 98EcSetOption(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) 99{ 100 long option_id; 101 uword option_val; 102 int err; 103 104 if (objc != 3) 105 { 106 Tcl_WrongNumArgs(interp, 1, objv, "option_name option_value"); 107 return TCL_ERROR; 108 } 109 err = Tcl_GetLongFromObj(interp, objv[1], &option_id); 110 if (err != TCL_OK) 111 { 112 char *option_name = Tcl_GetStringFromObj(objv[1], NULL); 113 Tcl_ResetResult(interp); 114 if (!strcmp(option_name, "localsize")) option_id = EC_OPTION_LOCALSIZE; 115 else if (!strcmp(option_name, "globalsize")) option_id = EC_OPTION_GLOBALSIZE; 116 else if (!strcmp(option_name, "privatesize")) option_id = EC_OPTION_PRIVATESIZE; 117 else if (!strcmp(option_name, "sharedsize")) option_id = EC_OPTION_SHAREDSIZE; 118 else if (!strcmp(option_name, "default_module")) option_id = EC_OPTION_DEFAULT_MODULE; 119 else if (!strcmp(option_name, "default_language")) option_id = EC_OPTION_DEFAULT_LANGUAGE; 120 else if (!strcmp(option_name, "eclipsedir")) option_id = EC_OPTION_ECLIPSEDIR; 121 else if (!strcmp(option_name, "io")) option_id = EC_OPTION_IO; 122 else if (!strcmp(option_name, "cwd_separate")) option_id = EC_OPTION_CWD_SEPARATE; 123 else { 124 Tcl_SetResult(interp, "invalid option name", TCL_STATIC); 125 return TCL_ERROR; 126 } 127 } 128 err = ec_set_option_ptr(option_id, NULL); 129 if (err == PSUCCEED) /* it's a valid string option */ 130 { 131 char *s = Tcl_GetStringFromObj(objv[2], NULL); 132 (void) ec_set_option_ptr(option_id, strcpy(Tcl_Alloc(strlen(s)+1), s)); 133 } 134 else /* it must be an integer option */ 135 { 136#if (SIZEOF_LONG == SIZEOF_CHAR_P) 137 err = Tcl_GetLongFromObj(interp, objv[2], (long *)&option_val); 138#elif (SIZEOF_CHAR_P == __SIZEOF_LONG_LONG__) 139 /* assumes Tcl_WideInt is same size as word */ 140 err = Tcl_GetWideIntFromObj(interp, objv[2], (Tcl_WideInt *)&option_val); 141#else 142 PROBLEM: cannot deal with this word size 143#endif 144 if (err != TCL_OK) 145 { 146 Tcl_SetResult(interp, "integer expected", TCL_STATIC); 147 return TCL_ERROR; 148 } 149 err = ec_set_option_long(option_id, option_val); 150 if (err != PSUCCEED) 151 { 152 Tcl_SetResult(interp, "invalid option number", TCL_STATIC); 153 return TCL_ERROR; 154 } 155 } 156 return TCL_OK; 157} 158 159/*--------------------------------------------------------------------------- 160 * ec_post_event event_string 161 *---------------------------------------------------------------------------*/ 162 163int 164EcPostEvent(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) 165{ 166 if (objc != 2) 167 { 168 Tcl_WrongNumArgs(interp, 1, objv, "event_string"); 169 return TCL_ERROR; 170 } 171 if (ec_post_event_string(Tcl_GetStringFromObj(objv[1], NULL)) != PSUCCEED) 172 { 173 Tcl_SetResult(interp, "could not post event to ECLiPSe", TCL_STATIC); 174 return TCL_ERROR; 175 } 176 return TCL_OK; 177} 178 179 180/*--------------------------------------------------------------------------- 181 * ec_resume 182 *---------------------------------------------------------------------------*/ 183 184int 185EcResume(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) 186{ 187 int async, res; 188 long arg = 0; 189 Tcl_Obj *obj; 190 191 if (objc == 1) 192 { 193 async = 0; 194 } 195 else if (objc == 2) 196 { 197 int res = Tcl_GetBooleanFromObj(interp, objv[1], &async); 198 if (res != TCL_OK) { 199 Tcl_SetResult(interp, "ec_resume_: boolean expected", TCL_STATIC); 200 return TCL_ERROR; 201 } 202 } 203 else 204 { 205 Tcl_WrongNumArgs(interp, 1, objv, "?async?"); 206 return TCL_ERROR; 207 } 208 /* ec_resume_async() can only return PSUCCEED, PRUNNING or SYS_ERROR */ 209 res = async ? ec_resume_async() : ec_resume_long(&arg); 210 switch (res) 211 { 212 case PSUCCEED: 213 Tcl_SetResult(interp, "success", TCL_STATIC); 214 return TCL_OK; 215 case PFAIL: 216 Tcl_SetResult(interp, "fail", TCL_STATIC); 217 return TCL_OK; 218 case PTHROW: 219 Tcl_SetResult(interp, "throw", TCL_STATIC); 220 return TCL_OK; 221 case PRUNNING: 222 Tcl_SetResult(interp, "running", TCL_STATIC); 223 return TCL_OK; 224 case PYIELD: 225 obj = Tcl_NewStringObj("yield", -1); 226 break; 227 case PWAITIO: 228 obj = Tcl_NewStringObj("waitio", -1); 229 break; 230 case PFLUSHIO: 231 obj = Tcl_NewStringObj("flushio", -1); 232 break; 233 default: 234 Tcl_SetResult(interp, async 235 ? "could not start ECLiPSe thread in ec_resume_async()" 236 : "unrecognized return code from ec_resume()", TCL_STATIC); 237 return TCL_ERROR; 238 } 239 Tcl_ListObjAppendElement(interp, obj, Tcl_NewLongObj(arg)); 240 Tcl_SetObjResult(interp, obj); 241 return TCL_OK; 242} 243 244 245/*--------------------------------------------------------------------------- 246 * ec_handle_events 247 * Ignore posted goals, don't continue -> only handle events 248 * Event handlers must not fail, throw or yield. 249 * Allowed is only success, waitio, flushio. 250 * In case of previous ec_resume_async we may also still be running. 251 *---------------------------------------------------------------------------*/ 252 253int 254EcHandleEvents(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) 255{ 256 long arg; 257 Tcl_Obj *obj; 258 int res; 259 260 if (objc != 1) 261 { 262 Tcl_WrongNumArgs(interp, 1, objv, ""); 263 return TCL_ERROR; 264 } 265 266 res = ec_handle_events(&arg); 267 switch (res) 268 { 269 case PRUNNING: 270 Tcl_SetResult(interp, "running", TCL_STATIC); 271 return TCL_OK; 272 case PSUCCEED: 273 Tcl_SetResult(interp, "success", TCL_STATIC); 274 return TCL_OK; 275 case PWAITIO: 276 obj = Tcl_NewStringObj("waitio", -1); 277 break; 278 case PFLUSHIO: 279 obj = Tcl_NewStringObj("flushio", -1); 280 break; 281 282 case PFAIL: 283 Tcl_SetResult(interp, "fail", TCL_STATIC); 284 return TCL_ERROR; 285 case PTHROW: 286 Tcl_SetResult(interp, "throw", TCL_STATIC); 287 return TCL_ERROR; 288 case PYIELD: 289 Tcl_SetResult(interp, "yield", TCL_STATIC); 290 return TCL_ERROR; 291 default: 292 Tcl_SetResult(interp, "unrecognized return code from ec_handle_events()", TCL_STATIC); 293 return TCL_ERROR; 294 } 295 Tcl_ListObjAppendElement(interp, obj, Tcl_NewLongObj(arg)); 296 Tcl_SetObjResult(interp, obj); 297 return TCL_OK; 298} 299 300 301/*--------------------------------------------------------------------------- 302 * ec_running 303 * returns a boolean indicating whether an eclipse thread is running. 304 *---------------------------------------------------------------------------*/ 305 306int 307EcRunning(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) 308{ 309 if (objc != 1) 310 { 311 Tcl_WrongNumArgs(interp, 1, objv, ""); 312 return TCL_ERROR; 313 } 314 Tcl_SetObjResult(interp, Tcl_NewBooleanObj(ec_running())); 315 return TCL_OK; 316} 317 318/*--------------------------------------------------------------------------- 319 * ec_resume_status ?timeout? 320 * returns (again) the status of the last ec_resume or ec_handle_events 321 *---------------------------------------------------------------------------*/ 322 323int 324EcResumeStatus(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) 325{ 326 long arg; 327 Tcl_Obj *obj; 328 int timeout; 329 int err; 330 331 if (objc == 1) 332 { 333 timeout = 0; 334 } 335 else if (objc == 2) 336 { 337 err = Tcl_GetIntFromObj(interp, objv[1], &timeout); 338 if (err != TCL_OK) 339 { 340 Tcl_SetResult(interp, "ec_resume_status: integer expected", TCL_STATIC); 341 return TCL_ERROR; 342 } 343 } 344 else 345 { 346 Tcl_WrongNumArgs(interp, 1, objv, "?timeout?"); 347 return TCL_ERROR; 348 } 349 switch (ec_wait_resume_status_long(&arg, timeout)) 350 { 351 case PSUCCEED: 352 Tcl_SetResult(interp, "success", TCL_STATIC); 353 return TCL_OK; 354 case PFAIL: 355 Tcl_SetResult(interp, "fail", TCL_STATIC); 356 return TCL_OK; 357 case PTHROW: 358 Tcl_SetResult(interp, "throw", TCL_STATIC); 359 return TCL_OK; 360 case PRUNNING: 361 Tcl_SetResult(interp, "running", TCL_STATIC); 362 return TCL_OK; 363 case PYIELD: 364 obj = Tcl_NewStringObj("yield", -1); 365 break; 366 case PWAITIO: 367 obj = Tcl_NewStringObj("waitio", -1); 368 break; 369 case PFLUSHIO: 370 obj = Tcl_NewStringObj("flushio", -1); 371 break; 372 default: 373 Tcl_SetResult(interp, "unrecognized return code from ec_resume_status()", TCL_STATIC); 374 return TCL_ERROR; 375 } 376 Tcl_ListObjAppendElement(interp, obj, Tcl_NewLongObj(arg)); 377 Tcl_SetObjResult(interp, obj); 378 return TCL_OK; 379} 380 381/*--------------------------------------------------------------------------- 382 * read/write directly from/to ECLiPSe queue 383 *---------------------------------------------------------------------------*/ 384 385int 386EcQueueWrite(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) 387{ 388 int stream_nr, len; 389 char *s; 390 int err; 391 392 if (objc != 3) 393 { 394 Tcl_WrongNumArgs(interp, 1, objv, "eclipse_name data"); 395 return TCL_ERROR; 396 } 397 398 /* get the eclipse stream number, objv[1] is number or string */ 399 err = Tcl_GetIntFromObj(interp, objv[1], &stream_nr); 400 if (err != TCL_OK) 401 { 402 stream_nr = ec_stream_nr(Tcl_GetStringFromObj(objv[1], NULL)); 403 if (stream_nr < 0) 404 { 405 Tcl_SetResult(interp, "ec_queue_write: no such ECLiPSe stream", TCL_STATIC); 406 return TCL_ERROR; 407 } 408 Tcl_ResetResult(interp); 409 } 410 s = Tcl_GetByteArrayFromObj(objv[2], &len); 411 if (ec_queue_write(stream_nr, s, len) < 0) 412 { 413 Tcl_SetResult(interp, "ec_queue_write: cannot write ECLiPSe stream", TCL_STATIC); 414 return TCL_ERROR; 415 } 416 return TCL_OK; 417} 418 419int 420EcQueueRead(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) 421{ 422 Tcl_Obj *result; 423 int stream_nr, len; 424 int err; 425 426 if (objc != 3) 427 { 428 Tcl_WrongNumArgs(interp, 1, objv, "eclipse_name size"); 429 return TCL_ERROR; 430 } 431 432 /* get the eclipse stream number, objv[1] is number or string */ 433 err = Tcl_GetIntFromObj(interp, objv[1], &stream_nr); 434 if (err != TCL_OK) 435 { 436 stream_nr = ec_stream_nr(Tcl_GetStringFromObj(objv[1], NULL)); 437 if (stream_nr < 0) 438 { 439 Tcl_SetResult(interp, "ec_queue_read: no such ECLiPSe stream", TCL_STATIC); 440 return TCL_ERROR; 441 } 442 Tcl_ResetResult(interp); 443 } 444 err = Tcl_GetIntFromObj(interp, objv[2], &len); 445 if (err != TCL_OK) 446 { 447 Tcl_SetResult(interp, "ec_queue_read: integer expected", TCL_STATIC); 448 return TCL_ERROR; 449 } 450 result = Tcl_NewObj(); 451 len = ec_queue_read(stream_nr, Tcl_SetByteArrayLength(result,len), len); 452 if (len < 0) 453 { 454 interp->result = "ec_queue_read: cannot read from ECLiPSe stream"; 455 return TCL_ERROR; 456 } 457 Tcl_SetByteArrayLength(result, len); 458 Tcl_SetObjResult(interp, result); 459 return TCL_OK; 460} 461 462 463/*--------------------------------------------------------------------------- 464 * Channel driver: mapping ECLiPSe streams to TCL channels 465 *---------------------------------------------------------------------------*/ 466 467static int EcStreamClose(ClientData, Tcl_Interp *); 468static int EcStreamInput(ClientData, char *, int, int *); 469static int EcStreamOutput(ClientData, const char *, int, int *); 470static void EcStreamWatch(ClientData, int); 471static int EcStreamGetHandle(ClientData, int, ClientData *); 472 473/*ARGSUSED*/ 474static int 475EcStreamClose(ClientData nst, Tcl_Interp *interp) 476{ 477 return 0; 478} 479 480static int 481EcStreamInput(ClientData stream_nr, char *buf, int size, int *err) 482{ 483 int nread; 484 nread = ec_queue_read((int)(word)stream_nr, buf, size); 485 if (nread < 0) 486 { 487 *err = EIO; 488 return -1; 489 } 490 return nread; 491} 492 493static int 494EcStreamOutput(ClientData stream_nr, const char *buf, int size, int *err) 495{ 496 int nread; 497 nread = ec_queue_write((int)(word)stream_nr, (char *) buf, size); 498 if (nread < 0) 499 { 500 *err = EIO; 501 return -1; 502 } 503 return nread; 504} 505 506/*ARGSUSED*/ 507static void 508EcStreamWatch(ClientData stream_nr, int mask) 509{ 510} 511 512/*ARGSUSED*/ 513static int 514EcStreamGetHandle(ClientData stream_nr, int direction, ClientData *handlePtr) 515{ 516 return TCL_ERROR; 517} 518 519 520Tcl_ChannelType ec_stream_channel = { 521 "eclipse_stream", 522 NULL, 523 EcStreamClose, 524 EcStreamInput, 525 EcStreamOutput, 526 NULL, 527 NULL, 528 NULL, 529 EcStreamWatch, 530 EcStreamGetHandle 531 }; 532 533 534/*--------------------------------------------------------------------------- 535 * ec_queue_open eclipse_name access 536 *---------------------------------------------------------------------------*/ 537 538int 539EcQueueOpen(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) 540{ 541 int stream_nr, mask; 542 char *accessvar; 543 char mode; 544 Tcl_Channel channel; 545 char channelName[16]; 546 int err; 547 548 if (objc != 3) 549 { 550 Tcl_WrongNumArgs(interp, 1, objv, "eclipse_name access_mode"); 551 return TCL_ERROR; 552 } 553 554 /* get the eclipse stream number, objv[1] is number or string */ 555 err = Tcl_GetIntFromObj(interp, objv[1], &stream_nr); 556 if (err != TCL_OK) 557 { 558 stream_nr = ec_stream_nr(Tcl_GetStringFromObj(objv[1], NULL)); 559 if (stream_nr < 0) 560 { 561 Tcl_SetResult(interp, "no such ECLiPSe stream", TCL_STATIC); 562 return TCL_ERROR; 563 } 564 } 565 566 accessvar = Tcl_GetStringFromObj(objv[2], NULL); 567 /* convert fromec to r, toec to w */ 568 if (strcmp(accessvar, "fromec\0") == 0 || strcmp(accessvar, "r\0") == 0) 569 { 570 mode = 'r'; 571 } else if (strcmp(accessvar, "toec\0") == 0 || strcmp(accessvar, "w\0") == 0) 572 { 573 mode = 'w'; 574 } else { 575 Tcl_SetResult(interp, "arg 2: fromec (r) or toec (w) expected", TCL_STATIC); 576 return TCL_ERROR; 577 } 578 mask = (mode == 'r') ? TCL_READABLE : TCL_WRITABLE; 579 580 sprintf(channelName, "ec_queue%d", stream_nr); 581 if (Tcl_GetChannel(interp, channelName, NULL) != NULL) 582 { 583 Tcl_SetResult(interp, "channel name exists already", TCL_STATIC); 584 return TCL_ERROR; 585 } 586 channel = Tcl_CreateChannel(&ec_stream_channel, channelName, 587 (ClientData)(word)stream_nr, mask); 588 if (!channel) 589 { 590 Tcl_SetResult(interp, "couldn't create channel", TCL_STATIC); 591 return TCL_ERROR; 592 } 593 (void) Tcl_SetChannelOption(NULL, (Tcl_Channel) channel, 594 "-translation", "binary"); 595 (void) Tcl_SetChannelOption(NULL, (Tcl_Channel) channel, 596 "-buffering", "none"); 597 Tcl_RegisterChannel(interp, channel); 598 Tcl_SetObjResult(interp, Tcl_NewStringObj(channelName, -1)); 599 return TCL_OK; 600} 601 602 603/*--------------------------------------------------------------------------- 604 * ec_stream_nr stream_name 605 *---------------------------------------------------------------------------*/ 606 607int 608EcStreamNr(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) 609{ 610 int err, stream_nr; 611 612 if (objc != 2) 613 { 614 Tcl_WrongNumArgs(interp, 1, objv, "stream_name"); 615 return TCL_ERROR; 616 } 617 err = Tcl_GetIntFromObj(interp, objv[1], &stream_nr); 618 if (err != TCL_OK) 619 { 620 stream_nr = ec_stream_nr(Tcl_GetStringFromObj(objv[1], NULL)); 621 } 622 if (stream_nr < 0) 623 { 624 Tcl_SetResult(interp, "no such ECLiPSe stream", TCL_STATIC); 625 return TCL_ERROR; 626 } 627 Tcl_SetObjResult(interp, Tcl_NewIntObj(stream_nr)); 628 return TCL_OK; 629 630} 631 632 633/*--------------------------------------------------------------------------- 634 * ec_post_goal goal ?format? 635 *---------------------------------------------------------------------------*/ 636 637int 638EcPostGoal(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) 639{ 640 char *exdr_string; 641 int len; 642 int res = EcTcl2Exdr(clientdata, interp, objc, objv); 643 if (res != TCL_OK) 644 return res; 645 exdr_string = Tcl_GetByteArrayFromObj(Tcl_GetObjResult(interp), &len); 646 ec_post_exdr(len, exdr_string); 647 Tcl_ResetResult(interp); 648 return TCL_OK; 649} 650 651 652/*--------------------------------------------------------------------------- 653 * Create the Tcl commands 654 *---------------------------------------------------------------------------*/ 655 656int 657Tkeclipse_Init(Tcl_Interp *interp) 658{ 659 Tcl_CreateObjCommand(interp, "ec_init_", EcInit, 660 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); 661 Tcl_CreateObjCommand(interp, "ec_cleanup", EcCleanup, 662 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); 663 Tcl_CreateObjCommand(interp, "ec_set_option", EcSetOption, 664 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); 665 Tcl_CreateObjCommand(interp, "ec_post_goal", EcPostGoal, 666 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); 667 Tcl_CreateObjCommand(interp, "ec_post_event", EcPostEvent, 668 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); 669 Tcl_CreateObjCommand(interp, "ec_resume_", EcResume, 670 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); 671 Tcl_CreateObjCommand(interp, "ec_running", EcRunning, 672 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); 673 Tcl_CreateObjCommand(interp, "ec_resume_status", EcResumeStatus, 674 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); 675 Tcl_CreateObjCommand(interp, "ec_handle_events_", EcHandleEvents, 676 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); 677 Tcl_CreateObjCommand(interp, "ec_queue_write", EcQueueWrite, 678 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); 679 Tcl_CreateObjCommand(interp, "ec_queue_read", EcQueueRead, 680 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); 681 Tcl_CreateObjCommand(interp, "ec_stream_nr", EcStreamNr, 682 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); 683 684 Tcl_CreateObjCommand(interp, "ec_queue_open_", EcQueueOpen, 685 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); 686 687 return TCL_OK; 688} 689 690