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
|
#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
|
EMSCRIPTEN_KEEPALIVE int
|
||||||
|
|
@ -134,7 +145,6 @@ magic_wasm_run_command(const char *command)
|
||||||
EMSCRIPTEN_KEEPALIVE int
|
EMSCRIPTEN_KEEPALIVE int
|
||||||
magic_wasm_source_file(const char *path)
|
magic_wasm_source_file(const char *path)
|
||||||
{
|
{
|
||||||
FILE *f;
|
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
status = magic_wasm_init();
|
status = magic_wasm_init();
|
||||||
|
|
@ -144,27 +154,30 @@ magic_wasm_source_file(const char *path)
|
||||||
if ((path == NULL) || (*path == '\0'))
|
if ((path == NULL) || (*path == '\0'))
|
||||||
return -1;
|
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,
|
TxSetPoint(GrScreenRect.r_xtop / 2, GrScreenRect.r_ytop / 2,
|
||||||
WIND_UNKNOWN_WINDOW);
|
WIND_UNKNOWN_WINDOW);
|
||||||
|
|
||||||
TxDispatch(f);
|
#ifdef MAGIC_WRAPPER
|
||||||
fclose(f);
|
/* In wrapper mode the file contains Tcl; evaluate it through the
|
||||||
return 0;
|
* 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
|
EMSCRIPTEN_KEEPALIVE void
|
||||||
|
|
|
||||||
|
|
@ -656,6 +656,37 @@ process_rlimit_startup_check(void)
|
||||||
#endif /* HAVE_GETRLIMIT */
|
#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 */
|
/* Main startup procedure */
|
||||||
/*------------------------------------------------------*/
|
/*------------------------------------------------------*/
|
||||||
|
|
|
||||||
|
|
@ -32,5 +32,7 @@ extern void MakeWindowCommand();
|
||||||
|
|
||||||
extern const char *Tclmagic_InitStubsVersion;
|
extern const char *Tclmagic_InitStubsVersion;
|
||||||
|
|
||||||
|
extern void TclmagicRegisterCommands(Tcl_Interp *interp);
|
||||||
|
|
||||||
#endif /* MAGIC_WRAPPER */
|
#endif /* MAGIC_WRAPPER */
|
||||||
#endif /* _MAGIC__TCLTK__TCLMAGIC_H */
|
#endif /* _MAGIC__TCLTK__TCLMAGIC_H */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue