refactor swig init out of the library
This commit is contained in:
parent
0c97a10f9a
commit
d713166a48
|
|
@ -65,7 +65,6 @@ set(STA_WRAP ${CMAKE_CURRENT_BINARY_DIR}/StaApp_wrap.cc)
|
||||||
set(STA_SOURCE
|
set(STA_SOURCE
|
||||||
app/StaMain.cc
|
app/StaMain.cc
|
||||||
app/TclInitVar.cc
|
app/TclInitVar.cc
|
||||||
${STA_WRAP}
|
|
||||||
|
|
||||||
dcalc/ArcDelayCalc.cc
|
dcalc/ArcDelayCalc.cc
|
||||||
dcalc/ArnoldiDelayCalc.cc
|
dcalc/ArnoldiDelayCalc.cc
|
||||||
|
|
@ -699,7 +698,8 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${STA_HOME}/app)
|
||||||
# Note executable and lib name cannot be the same because
|
# Note executable and lib name cannot be the same because
|
||||||
# on osx something is case insensitive. Using STA for the
|
# on osx something is case insensitive. Using STA for the
|
||||||
# lib name results in "No rule to make target ../depend.
|
# lib name results in "No rule to make target ../depend.
|
||||||
add_executable(sta app/Main.cc)
|
add_executable(sta app/Main.cc ${STA_WRAP})
|
||||||
|
|
||||||
target_link_libraries(sta
|
target_link_libraries(sta
|
||||||
OpenSTA
|
OpenSTA
|
||||||
${TCL_LIB}
|
${TCL_LIB}
|
||||||
|
|
|
||||||
136
app/Main.cc
136
app/Main.cc
|
|
@ -15,32 +15,58 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <tcl.h>
|
||||||
#include "Machine.hh"
|
#include "Machine.hh"
|
||||||
#include "StaConfig.hh" // STA_VERSION
|
#include "StaConfig.hh" // STA_VERSION
|
||||||
#include "StringUtil.hh"
|
#include "StringUtil.hh"
|
||||||
#include "Sta.hh"
|
#include "Sta.hh"
|
||||||
#include "StaMain.hh"
|
#include "StaMain.hh"
|
||||||
|
|
||||||
|
|
||||||
|
namespace sta {
|
||||||
|
extern const char *tcl_inits[];
|
||||||
|
}
|
||||||
|
|
||||||
using sta::stringEq;
|
using sta::stringEq;
|
||||||
|
using sta::findCmdLineFlag;
|
||||||
using sta::Sta;
|
using sta::Sta;
|
||||||
using sta::staMain;
|
using sta::initSta;
|
||||||
using sta::showUsage;
|
using sta::evalTclInit;
|
||||||
|
using sta::stringPrintTmp;
|
||||||
|
using sta::sourceTclFile;
|
||||||
|
using sta::parseThreadsArg;
|
||||||
|
using sta::tcl_inits;
|
||||||
|
|
||||||
// Swig uses C linkage for init functions.
|
// Swig uses C linkage for init functions.
|
||||||
extern "C" {
|
extern "C" {
|
||||||
extern int Sta_Init(Tcl_Interp *interp);
|
extern int Sta_Init(Tcl_Interp *interp);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace sta {
|
static int cmd_argc;
|
||||||
extern const char *tcl_inits[];
|
static char **cmd_argv;
|
||||||
}
|
static const char *init_filename = ".sta";
|
||||||
|
|
||||||
|
static void
|
||||||
|
showUsage(const char *prog,
|
||||||
|
const char *init_filename);
|
||||||
|
static int
|
||||||
|
tclAppInit(Tcl_Interp *interp);
|
||||||
|
static int
|
||||||
|
staTclAppInit(int argc,
|
||||||
|
char *argv[],
|
||||||
|
const char *init_filename,
|
||||||
|
Tcl_Interp *interp);
|
||||||
|
static void
|
||||||
|
initStaApp(int argc,
|
||||||
|
char *argv[],
|
||||||
|
Tcl_Interp *interp);
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc,
|
main(int argc,
|
||||||
char *argv[])
|
char *argv[])
|
||||||
{
|
{
|
||||||
if (argc == 2 && stringEq(argv[1], "-help")) {
|
if (argc == 2 && stringEq(argv[1], "-help")) {
|
||||||
showUsage(argv[0]);
|
showUsage(argv[0], init_filename);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (argc == 2 && stringEq(argv[1], "-version")) {
|
else if (argc == 2 && stringEq(argv[1], "-version")) {
|
||||||
|
|
@ -48,8 +74,102 @@ main(int argc,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Sta *sta = new Sta;
|
// Set argc to 1 so Tcl_Main doesn't source any files.
|
||||||
staMain(sta, argc, argv, ".sta", Sta_Init, sta::tcl_inits);
|
// Tcl_Main never returns.
|
||||||
|
#if 0
|
||||||
|
// It should be possible to pass argc/argv to staTclAppInit with
|
||||||
|
// a closure but I couldn't get the signature to match Tcl_AppInitProc.
|
||||||
|
Tcl_Main(1, argv, [=](Tcl_Interp *interp)
|
||||||
|
{ sta::staTclAppInit(argc, argv, interp);
|
||||||
|
return 1;
|
||||||
|
});
|
||||||
|
#else
|
||||||
|
// Workaround.
|
||||||
|
cmd_argc = argc;
|
||||||
|
cmd_argv = argv;
|
||||||
|
Tcl_Main(1, argv, tclAppInit);
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
tclAppInit(Tcl_Interp *interp)
|
||||||
|
{
|
||||||
|
return staTclAppInit(cmd_argc, cmd_argv, init_filename, interp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tcl init executed inside Tcl_Main.
|
||||||
|
static int
|
||||||
|
staTclAppInit(int argc,
|
||||||
|
char *argv[],
|
||||||
|
const char *init_filename,
|
||||||
|
Tcl_Interp *interp)
|
||||||
|
{
|
||||||
|
// source init.tcl
|
||||||
|
Tcl_Init(interp);
|
||||||
|
|
||||||
|
initStaApp(argc, argv, interp);
|
||||||
|
|
||||||
|
if (!findCmdLineFlag(argc, argv, "-no_splash"))
|
||||||
|
Tcl_Eval(interp, "sta::show_splash");
|
||||||
|
|
||||||
|
if (!findCmdLineFlag(argc, argv, "-no_init")) {
|
||||||
|
char *init_path = stringPrintTmp("[file join $env(HOME) %s]",
|
||||||
|
init_filename);
|
||||||
|
sourceTclFile(init_path, true, true, interp);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool exit_after_cmd_file = findCmdLineFlag(argc, argv, "-exit");
|
||||||
|
|
||||||
|
if (argc > 2 ||
|
||||||
|
(argc > 1 && argv[1][0] == '-'))
|
||||||
|
showUsage(argv[0], init_filename);
|
||||||
|
else {
|
||||||
|
if (argc == 2) {
|
||||||
|
char *cmd_file = argv[1];
|
||||||
|
if (cmd_file) {
|
||||||
|
sourceTclFile(cmd_file, false, false, interp);
|
||||||
|
if (exit_after_cmd_file)
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
initStaApp(int argc,
|
||||||
|
char *argv[],
|
||||||
|
Tcl_Interp *interp)
|
||||||
|
{
|
||||||
|
initSta();
|
||||||
|
Sta *sta = new Sta;
|
||||||
|
Sta::setSta(sta);
|
||||||
|
sta->makeComponents();
|
||||||
|
sta->setTclInterp(interp);
|
||||||
|
int thread_count = parseThreadsArg(argc, argv);
|
||||||
|
sta->setThreadCount(thread_count);
|
||||||
|
|
||||||
|
// Define swig TCL commands.
|
||||||
|
Sta_Init(interp);
|
||||||
|
// Eval encoded sta TCL sources.
|
||||||
|
evalTclInit(interp, tcl_inits);
|
||||||
|
// Import exported commands from sta namespace to global namespace.
|
||||||
|
Tcl_Eval(interp, "sta::define_sta_cmds");
|
||||||
|
Tcl_Eval(interp, "namespace import sta::*");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
showUsage(const char *prog,
|
||||||
|
const char *init_filename)
|
||||||
|
{
|
||||||
|
printf("Usage: %s [-help] [-version] [-no_init] [-exit] cmd_file\n", prog);
|
||||||
|
printf(" -help show help and exit\n");
|
||||||
|
printf(" -version show version and exit\n");
|
||||||
|
printf(" -no_init do not read %s init file\n", init_filename);
|
||||||
|
printf(" -threads count|max use count threads\n");
|
||||||
|
printf(" -no_splash do not show the license splash at startup\n");
|
||||||
|
printf(" -exit exit after reading cmd_file\n");
|
||||||
|
printf(" cmd_file source cmd_file\n");
|
||||||
|
}
|
||||||
|
|
|
||||||
109
app/StaMain.cc
109
app/StaMain.cc
|
|
@ -24,37 +24,6 @@
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
typedef sta::Vector<SwigInitFunc> SwigInitFuncSeq;
|
|
||||||
|
|
||||||
// "Arguments" passed to staTclAppInit.
|
|
||||||
static int sta_argc;
|
|
||||||
static char **sta_argv;
|
|
||||||
static const char *sta_init_filename;
|
|
||||||
static const char **sta_tcl_inits;
|
|
||||||
static SwigInitFunc sta_swig_init;
|
|
||||||
|
|
||||||
void
|
|
||||||
staMain(Sta *sta,
|
|
||||||
int argc,
|
|
||||||
char *argv[],
|
|
||||||
const char *init_filename,
|
|
||||||
SwigInitFunc swig_init,
|
|
||||||
const char *tcl_inits[])
|
|
||||||
{
|
|
||||||
initSta();
|
|
||||||
|
|
||||||
Sta::setSta(sta);
|
|
||||||
sta->makeComponents();
|
|
||||||
|
|
||||||
int thread_count = parseThreadsArg(argc, argv);
|
|
||||||
sta->setThreadCount(thread_count);
|
|
||||||
|
|
||||||
staSetupAppInit(argc, argv, init_filename, swig_init, tcl_inits);
|
|
||||||
// Set argc to 1 so Tcl_Main doesn't source any files.
|
|
||||||
// Tcl_Main never returns.
|
|
||||||
Tcl_Main(1, argv, staTclAppInit);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
parseThreadsArg(int &argc,
|
parseThreadsArg(int &argc,
|
||||||
char *argv[])
|
char *argv[])
|
||||||
|
|
@ -71,71 +40,6 @@ parseThreadsArg(int &argc,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set globals to pass to staTclAppInit.
|
|
||||||
void
|
|
||||||
staSetupAppInit(int argc,
|
|
||||||
char *argv[],
|
|
||||||
const char *init_filename,
|
|
||||||
SwigInitFunc swig_init,
|
|
||||||
const char *tcl_inits[])
|
|
||||||
{
|
|
||||||
sta_argc = argc;
|
|
||||||
sta_argv = argv;
|
|
||||||
sta_init_filename = init_filename;
|
|
||||||
sta_tcl_inits = tcl_inits;
|
|
||||||
sta_swig_init = swig_init;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tcl init executed inside Tcl_Main.
|
|
||||||
int
|
|
||||||
staTclAppInit(Tcl_Interp *interp)
|
|
||||||
{
|
|
||||||
int argc = sta_argc;
|
|
||||||
char **argv = sta_argv;
|
|
||||||
|
|
||||||
// source init.tcl
|
|
||||||
Tcl_Init(interp);
|
|
||||||
|
|
||||||
// Define swig commands.
|
|
||||||
sta_swig_init(interp);
|
|
||||||
|
|
||||||
Sta *sta = Sta::sta();
|
|
||||||
sta->setTclInterp(interp);
|
|
||||||
|
|
||||||
// Eval encoded sta TCL sources.
|
|
||||||
evalTclInit(interp, sta_tcl_inits);
|
|
||||||
|
|
||||||
if (!findCmdLineFlag(argc, argv, "-no_splash"))
|
|
||||||
Tcl_Eval(interp, "sta::show_splash");
|
|
||||||
|
|
||||||
// Import exported commands from sta namespace to global namespace.
|
|
||||||
Tcl_Eval(interp, "sta::define_sta_cmds");
|
|
||||||
Tcl_Eval(interp, "namespace import sta::*");
|
|
||||||
|
|
||||||
if (!findCmdLineFlag(argc, argv, "-no_init")) {
|
|
||||||
char *init_path = stringPrintTmp("[file join $env(HOME) %s]",
|
|
||||||
sta_init_filename);
|
|
||||||
sourceTclFile(init_path, true, true, interp);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool exit_after_cmd_file = findCmdLineFlag(argc, argv, "-exit");
|
|
||||||
|
|
||||||
if (argc > 2 ||
|
|
||||||
(argc > 1 && argv[1][0] == '-'))
|
|
||||||
showUsage(argv[0]);
|
|
||||||
else {
|
|
||||||
if (argc == 2) {
|
|
||||||
char *cmd_file = argv[1];
|
|
||||||
if (cmd_file) {
|
|
||||||
sourceTclFile(cmd_file, false, false, interp);
|
|
||||||
if (exit_after_cmd_file)
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return TCL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
findCmdLineFlag(int &argc,
|
findCmdLineFlag(int &argc,
|
||||||
char *argv[],
|
char *argv[],
|
||||||
|
|
@ -220,17 +124,4 @@ evalTclInit(Tcl_Interp *interp,
|
||||||
delete [] unencoded;
|
delete [] unencoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
showUsage(const char * prog)
|
|
||||||
{
|
|
||||||
printf("Usage: %s [-help] [-version] [-no_init] [-exit] cmd_file\n", prog);
|
|
||||||
printf(" -help show help and exit\n");
|
|
||||||
printf(" -version show version and exit\n");
|
|
||||||
printf(" -no_init do not read .sta init file\n");
|
|
||||||
printf(" -threads count|max use count threads\n");
|
|
||||||
printf(" -no_splash do not show the license splash at startup\n");
|
|
||||||
printf(" -exit exit after reading cmd_file\n");
|
|
||||||
printf(" cmd_file source cmd_file\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
||||||
|
|
@ -22,28 +22,20 @@ struct Tcl_Interp;
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
class Sta;
|
class Sta;
|
||||||
typedef int (*SwigInitFunc)(Tcl_Interp *);
|
|
||||||
|
|
||||||
// The swig_init function is called to define the swig interface
|
|
||||||
// functions to the tcl interpreter.
|
|
||||||
void
|
|
||||||
staMain(Sta *sta,
|
|
||||||
int argc,
|
|
||||||
char *argv[],
|
|
||||||
const char *init_filename,
|
|
||||||
SwigInitFunc swig_init,
|
|
||||||
const char *tcl_inits[]);
|
|
||||||
|
|
||||||
// Set arguments passed to staTclAppInit inside the tcl interpreter.
|
|
||||||
void
|
|
||||||
staSetupAppInit(int argc,
|
|
||||||
char *argv[],
|
|
||||||
const char *init_filename,
|
|
||||||
SwigInitFunc swig_init,
|
|
||||||
const char *tcl_inits[]);
|
|
||||||
|
|
||||||
|
// Parse command line argument
|
||||||
int
|
int
|
||||||
staTclAppInit(Tcl_Interp *interp);
|
staTclAppInit(int argc,
|
||||||
|
char *argv[],
|
||||||
|
const char *init_filename,
|
||||||
|
Tcl_Interp *interp);
|
||||||
|
|
||||||
|
// Sta initialization.
|
||||||
|
// Makes the Sta object and registers TCL commands.
|
||||||
|
void
|
||||||
|
initSta(int argc,
|
||||||
|
char *argv[],
|
||||||
|
Tcl_Interp *interp);
|
||||||
|
|
||||||
// TCL init files are encoded into the string init using the three
|
// TCL init files are encoded into the string init using the three
|
||||||
// digit decimal equivalent for each ascii character. This function
|
// digit decimal equivalent for each ascii character. This function
|
||||||
|
|
@ -63,8 +55,6 @@ findCmdLineKey(int &argc,
|
||||||
char *argv[],
|
char *argv[],
|
||||||
const char *key);
|
const char *key);
|
||||||
|
|
||||||
void
|
|
||||||
showUsage(const char *prog);
|
|
||||||
int
|
int
|
||||||
parseThreadsArg(int &argc,
|
parseThreadsArg(int &argc,
|
||||||
char *argv[]);
|
char *argv[]);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue