fix(tcl-wasm): register magic:: Tcl commands after C initialization completes
magic_wasm_init() called Tclmagic_Init() and magicMainInit() but never ran the command-registration loop in _magic_initialize(), so magic::tech, magic::load, magic::gds and all other Magic commands were missing from the Tcl interpreter. Add TclmagicRegisterCommands() in tclmagic.c containing the WindNextClient/WindGetCommandTable loop and call it from magic_wasm_init() after magicMainInit() succeeds. Also change magic_wasm_source_file() to use Tcl_EvalFile in MAGIC_WRAPPER mode so scripts with magic:: commands are evaluated through the Tcl interpreter instead of the plain text dispatcher.
This commit is contained in:
parent
4eb8a4da40
commit
8fdd2eec20
|
|
@ -98,7 +98,18 @@ magic_wasm_init(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
return magicMainInit(5, argv);
|
||||
{
|
||||
static int commandsRegistered = FALSE;
|
||||
int rc = magicMainInit(5, argv);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
if (rc == 0 && !commandsRegistered)
|
||||
{
|
||||
TclmagicRegisterCommands(magicinterp);
|
||||
commandsRegistered = TRUE;
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE int
|
||||
|
|
@ -134,7 +145,6 @@ magic_wasm_run_command(const char *command)
|
|||
EMSCRIPTEN_KEEPALIVE int
|
||||
magic_wasm_source_file(const char *path)
|
||||
{
|
||||
FILE *f;
|
||||
int status;
|
||||
|
||||
status = magic_wasm_init();
|
||||
|
|
@ -144,27 +154,30 @@ magic_wasm_source_file(const char *path)
|
|||
if ((path == NULL) || (*path == '\0'))
|
||||
return -1;
|
||||
|
||||
f = PaOpen((char *)path, "r", (char *)NULL, ".", (char *)NULL,
|
||||
(char **)NULL);
|
||||
if (f == NULL)
|
||||
{
|
||||
TxError("Unable to open command file \"%s\".\n", path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the current point to the centre of the screen so that
|
||||
* WindSendCommand routes all commands from the file to the layout
|
||||
* window client, just as magic_wasm_run_command does for single
|
||||
* commands. Without this, commands arrive with point (0,0) and
|
||||
* end up in the border/windClient context where most commands are
|
||||
* unknown.
|
||||
*/
|
||||
TxSetPoint(GrScreenRect.r_xtop / 2, GrScreenRect.r_ytop / 2,
|
||||
WIND_UNKNOWN_WINDOW);
|
||||
|
||||
TxDispatch(f);
|
||||
fclose(f);
|
||||
return 0;
|
||||
#ifdef MAGIC_WRAPPER
|
||||
/* In wrapper mode the file contains Tcl; evaluate it through the
|
||||
* Tcl interpreter so that magic:: commands are dispatched via
|
||||
* _tcl_dispatch just like magic_wasm_run_command does for strings. */
|
||||
if (magicinterp == NULL)
|
||||
return -1;
|
||||
return Tcl_EvalFile(magicinterp, path);
|
||||
#else
|
||||
{
|
||||
FILE *f = PaOpen((char *)path, "r", (char *)NULL, ".", (char *)NULL,
|
||||
(char **)NULL);
|
||||
if (f == NULL)
|
||||
{
|
||||
TxError("Unable to open command file \"%s\".\n", path);
|
||||
return -1;
|
||||
}
|
||||
TxDispatch(f);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void
|
||||
|
|
|
|||
|
|
@ -656,6 +656,37 @@ process_rlimit_startup_check(void)
|
|||
#endif /* HAVE_GETRLIMIT */
|
||||
}
|
||||
|
||||
/*------------------------------------------------------*/
|
||||
/* Register magic:: commands with the Tcl interpreter. */
|
||||
/* Called after Magic's C subsystems are fully */
|
||||
/* initialized (i.e. after magicMainInit returns 0) */
|
||||
/* so that WindNextClient / WindGetCommandTable return */
|
||||
/* populated tables. */
|
||||
/*------------------------------------------------------*/
|
||||
|
||||
void
|
||||
TclmagicRegisterCommands(Tcl_Interp *interp)
|
||||
{
|
||||
WindClient client;
|
||||
int n;
|
||||
char keyword[100];
|
||||
char *kwptr = keyword + 7;
|
||||
const char * const *commandTable;
|
||||
|
||||
sprintf(keyword, "magic::");
|
||||
client = (WindClient)NULL;
|
||||
while ((client = WindNextClient(client)) != NULL)
|
||||
{
|
||||
commandTable = WindGetCommandTable(client);
|
||||
for (n = 0; commandTable[n] != NULL; n++)
|
||||
{
|
||||
sscanf(commandTable[n], "%s ", kwptr);
|
||||
Tcl_CreateCommand(interp, keyword, (Tcl_CmdProc *)_tcl_dispatch,
|
||||
(ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------*/
|
||||
/* Main startup procedure */
|
||||
/*------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -32,5 +32,7 @@ extern void MakeWindowCommand();
|
|||
|
||||
extern const char *Tclmagic_InitStubsVersion;
|
||||
|
||||
extern void TclmagicRegisterCommands(Tcl_Interp *interp);
|
||||
|
||||
#endif /* MAGIC_WRAPPER */
|
||||
#endif /* _MAGIC__TCLTK__TCLMAGIC_H */
|
||||
|
|
|
|||
Loading…
Reference in New Issue