tclreadline support

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2022-10-24 09:18:01 -07:00
parent a06b796154
commit 15d93339f9
10 changed files with 111 additions and 25 deletions

View File

@ -215,6 +215,7 @@ set(STA_SOURCE
# Source files. # Source files.
set(STA_TCL_FILES set(STA_TCL_FILES
tcl/Init.tcl
tcl/Util.tcl tcl/Util.tcl
tcl/Graph.tcl tcl/Graph.tcl
tcl/Liberty.tcl tcl/Liberty.tcl
@ -384,6 +385,31 @@ add_custom_command(OUTPUT ${STA_TCL_INIT}
# Do not use REQUIRED because it also requires TK, which is not used by OpenSTA. # Do not use REQUIRED because it also requires TK, which is not used by OpenSTA.
find_package(TCL) find_package(TCL)
option(USE_TCL_READLINE "Use TCL readliine package")
set(TCL_READLINE 0)
# check for tclReadline
if (USE_TCL_READLINE)
find_library(TCL_READLINE_LIBRARY tclreadline)
if (TCL_READLINE_LIBRARY)
message(STATUS "TCL readline: ${TCL_READLINE_LIBRARY}")
# Referenced by StaConfig.hh.cmake
set(TCL_READLINE 1)
get_filename_component(TCL_READLINE_LIB_DIR "${TCL_READLINE_LIBRARY}" PATH)
get_filename_component(TCL_READLINE_LIB_PARENT "${TCL_READLINE_LIB_DIR}" PATH)
find_file(TCL_READLINE_HEADER tclreadline.h
PATHS ${TCL_READLINE_LIB_PARENT}
PATH_SUFFIXES include
NO_DEFAULT_PATH
)
message(STATUS "TCL readline header: ${TCL_READLINE_HEADER}")
get_filename_component(TCL_READLINE_INCLUDE "${TCL_READLINE_HEADER}" PATH)
else()
message(STATUS "TCL readline: not found")
endif()
endif()
# Zlib # Zlib
include(FindZLIB) include(FindZLIB)
@ -409,7 +435,7 @@ if (USE_CUDD)
if (CUDD_HEADER) if (CUDD_HEADER)
get_filename_component(CUDD_INCLUDE "${CUDD_HEADER}" PATH) get_filename_component(CUDD_INCLUDE "${CUDD_HEADER}" PATH)
message(STATUS "CUDD header: ${CUDD_HEADER}") message(STATUS "CUDD header: ${CUDD_HEADER}")
# CUDD referenced by StaConfig.hh.cmake # Referenced by StaConfig.hh.cmake
set(CUDD 1) set(CUDD 1)
else() else()
message(STATUS "CUDD header: not found") message(STATUS "CUDD header: not found")
@ -460,6 +486,7 @@ target_include_directories(OpenSTA
PUBLIC PUBLIC
include include
${TCL_INCLUDE_PATH} ${TCL_INCLUDE_PATH}
${TCL_READLINE_INCLUDE}
PRIVATE PRIVATE
include/sta include/sta
@ -497,6 +524,10 @@ target_link_libraries(sta
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_THREAD_LIBS_INIT}
) )
if (TCL_READLINE_LIBRARY)
target_link_libraries(sta ${TCL_READLINE_LIBRARY})
endif()
if (ZLIB_LIBRARIES) if (ZLIB_LIBRARIES)
target_link_libraries(sta ${ZLIB_LIBRARIES}) target_link_libraries(sta ${ZLIB_LIBRARIES})
endif() endif()

View File

@ -79,10 +79,24 @@ are illegal in c++17.
These packages are **optional**: These packages are **optional**:
``` ```
tclreadline 2.3.8
libz 1.1.4 1.2.5 1.2.8 libz 1.1.4 1.2.5 1.2.8
cudd 2.4.1 3.0.0 cudd 2.4.1 3.0.0
``` ```
The [TCL readline library](https://tclreadline.sourceforge.net/tclreadline.html)
links the GNU readline library to the TCL interpreter for command line editing
On OSX, Homebrew does not support tclreadline, but the macports system does
(see https://www.macports.org). To enable TCL readline support use the following
Cmake option:
```
cmake .. -DUSE_TCL_READLINE=ON
```
The Zlib library is an optional. If CMake finds libz, OpenSTA can
read Verilog, SDF, SPF, and SPEF files compressed with gzip.
CUDD is a binary decision diageram (BDD) package that is used to CUDD is a binary decision diageram (BDD) package that is used to
improve conditional timing arc handling. OpenSTA does not require it improve conditional timing arc handling. OpenSTA does not require it
to be installed. It is available to be installed. It is available
@ -109,9 +123,6 @@ cd <opensta>/build
cmake .. -DUSE_CUDD=ON -DCUDD_DIR=$HOME/cudd cmake .. -DUSE_CUDD=ON -DCUDD_DIR=$HOME/cudd
``` ```
The Zlib library is an optional. If CMake finds libz, OpenSTA can
read Verilog, SDF, SPF, and SPEF files compressed with gzip.
### Installing with CMake ### Installing with CMake
Use the following commands to checkout the git repository and build the Use the following commands to checkout the git repository and build the

View File

@ -15,15 +15,17 @@
// 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 "StaMain.hh" #include "StaMain.hh"
#include "StaConfig.hh" // STA_VERSION
#include <stdio.h> #include <stdio.h>
#include <cstdlib> // exit #include <cstdlib> // exit
#include <tcl.h> #include <tcl.h>
#if TCL_READLINE
#include <tclreadline.h>
#endif
#include "StaConfig.hh" // STA_VERSION
#include "Sta.hh" #include "Sta.hh"
namespace sta { namespace sta {
extern const char *tcl_inits[]; extern const char *tcl_inits[];
} }
@ -109,7 +111,16 @@ staTclAppInit(int argc,
Tcl_Interp *interp) Tcl_Interp *interp)
{ {
// source init.tcl // source init.tcl
Tcl_Init(interp); if (Tcl_Init(interp) == TCL_ERROR)
return TCL_ERROR;
#if TCL_READLINE
if (Tclreadline_Init(interp) == TCL_ERROR)
return TCL_ERROR;
Tcl_StaticPackage(interp, "tclreadline", Tclreadline_Init, Tclreadline_SafeInit);
if (Tcl_EvalFile(interp, TCLRL_LIBRARY "/tclreadlineInit.tcl") != TCL_OK)
printf("Failed to load tclreadline.tcl\n");
#endif
initStaApp(argc, argv, interp); initStaApp(argc, argv, interp);
@ -146,7 +157,11 @@ staTclAppInit(int argc,
} }
} }
} }
#if TCL_READLINE
return Tcl_Eval(interp, "::tclreadline::Loop");
#else
return TCL_OK; return TCL_OK;
#endif
} }
static void static void
@ -166,9 +181,7 @@ initStaApp(int &argc,
Sta_Init(interp); Sta_Init(interp);
// Eval encoded sta TCL sources. // Eval encoded sta TCL sources.
evalTclInit(interp, tcl_inits); evalTclInit(interp, tcl_inits);
// Import exported commands from sta namespace to global namespace. Tcl_Eval(interp, "init_sta");
Tcl_Eval(interp, "sta::define_sta_cmds");
Tcl_Eval(interp, "namespace import sta::*");
} }
static void static void

BIN
app/sta.noreadline Executable file

Binary file not shown.

View File

@ -33,7 +33,7 @@ if (NOT TCL_LIB_PATHS)
set(TCL_LIB_PATHS /usr/local/lib /opt/homebrew/opt/tcl-tk/lib) set(TCL_LIB_PATHS /usr/local/lib /opt/homebrew/opt/tcl-tk/lib)
set(TCL_NO_DEFAULT_PATH TRUE) set(TCL_NO_DEFAULT_PATH TRUE)
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux") elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(TCL_LIB_PATHS /usr/lib /usr/local/lib) set(TCL_LIB_PATHS /usr/lib /usr/lib64 /usr/local/lib)
set(TCL_NO_DEFAULT_PATH FALSE) set(TCL_NO_DEFAULT_PATH FALSE)
endif() endif()
endif() endif()

View File

@ -17,7 +17,7 @@
This file summarizes STA API changes for each release. This file summarizes STA API changes for each release.
Release 2.3.1 2022/06/12 Release 2.3.1 2022/06/12
-------------------------
LibertyCellTimingArcSetIterator has been removed. LibertyCellTimingArcSetIterator has been removed.
Use range iteration as shown below: Use range iteration as shown below:
for (TimingArcSet *arc_set : cell->timingArcSets()) for (TimingArcSet *arc_set : cell->timingArcSets())
@ -31,11 +31,12 @@ LibertyCellSequentialIterator has been removed.
for (Sequential *seq : cell->sequentials()) for (Sequential *seq : cell->sequentials())
Release 2.1.1 2020/12/13 Release 2.1.1 2020/12/13
-------------------------
Report::error, Report::warn functions now take a unique message ID as a first argument. Report::error, Report::warn functions now take a unique message ID as a first argument.
InternalError has been renamed Report::cricical. InternalError has been renamed Report::cricical.
Release 2.1.0 2020/04/05 Release 2.1.0 2020/04/05
-------------------------
All public headers files have been moved to include/sta. All public headers files have been moved to include/sta.
The following iterators have been removed. The following iterators have been removed.

View File

@ -7,6 +7,11 @@ The report_parasitics_annotation command reports SPEF annotation completeness.
report_parasitics_annotation [-report_unannotated] report_parasitics_annotation [-report_unannotated]
Release 2.3.3 2022/09/24
-------------------------
TCL readline support added. See README.md for build instructions.
Release 2.3.2 2022/07/03 Release 2.3.2 2022/07/03
------------------------- -------------------------

33
tcl/Init.tcl Normal file
View File

@ -0,0 +1,33 @@
# OpenSTA, Static Timing Analyzer
# Copyright (c) 2022, Parallax Software, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
proc init_sta {} {
global auto_index
# Import exported commands from sta namespace to global namespace.
sta::define_sta_cmds
namespace import sta::*
if { [info exists tclreadline::version] } {
history
history event
eval $auto_index(::tclreadline::ScriptCompleter)
::tclreadline::readline builtincompleter true
::tclreadline::readline customcompleter ::tclreadline::ScriptCompleter
proc ::tclreadline::prompt1 {} { return {% } }
proc ::tclreadline::prompt2 {} { return {> } }
}
}

View File

@ -437,16 +437,6 @@ proc sta_unknown { args } {
return -code error \ return -code error \
"ambiguous command name \"$name\": [lsort $cmds]" "ambiguous command name \"$name\": [lsort $cmds]"
} }
} else {
# I cannot figure out why the first call to ::history add
# that presumably loads history.tcl causes the following error:
# Error: history.tcl, 306 invoked "return" outside of a proc.
# But this squashes the error.
if { [lindex $args 0] == "::history" } {
return ""
} else {
return [uplevel 1 builtin_unknown $args]
}
} }
} }
} }

View File

@ -7,3 +7,5 @@
#define CUDD ${CUDD} #define CUDD ${CUDD}
#define SSTA ${SSTA} #define SSTA ${SSTA}
#define TCL_READLINE ${TCL_READLINE}