Merge branch 'master' into ord

This commit is contained in:
James Cherry 2020-04-25 13:33:17 -07:00
commit 658be26021
13 changed files with 343 additions and 305 deletions

View File

@ -1,16 +1,27 @@
# This is "close" to correct but has a number of bugs that prevent
# using it on the source tree.
Language: Cpp
BasedOnStyle: Google
AlignOperands: false
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortFunctionsOnASingleLine: InlineOnly
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: TopLevel
BinPackArguments: false
# fails
BinPackParameters: false
BraceWrapping:
AfterClass: true
AfterStruct: true
AfterFunction: true
BeforeElse: true
BreakBeforeBraces: Custom
# fails
# fails if all initializers fit on one line
BreakConstructorInitializers: AfterColon
ColumnLimit: 0
# fails
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 2
IncludeBlocks: Preserve

View File

@ -24,7 +24,9 @@ if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.14)
cmake_policy(SET CMP0086 NEW)
endif()
project(STA VERSION 2.1.0)
project(STA VERSION 2.1.0
LANGUAGES CXX
)
option(CUDD_DIR "CUDD BDD package directory")
@ -474,11 +476,14 @@ target_link_libraries(sta
OpenSTA
sta_swig
${TCL_LIBRARY}
${ZLIB_LIBRARIES}
)
if (ZLIB_LIBRARIES)
target_link_libraries(sta ${ZLIB_LIBRARIES})
endif()
if (CUDD_LIB)
target_link_libraries(sta ${CUDD_LIB})
target_link_libraries(sta ${CUDD_LIB})
endif()
message(STATUS "STA executable: ${STA_HOME}/app/sta")

View File

@ -7,7 +7,6 @@ RUN yum group install -y "Development Tools" \
&& yum install -y https://centos7.iuscommunity.org/ius-release.rpm \
&& yum install -y wget git centos-release-scl devtoolset-8 \
devtoolset-8-libatomic-devel tcl-devel tcl tk libstdc++ tk-devel pcre-devel \
python36u python36u-libs python36u-devel python36u-pip && \
yum clean -y all && \
rm -rf /var/lib/apt/lists/*

View File

@ -35,12 +35,10 @@ if (NOT TCL_LIB_PATHS)
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(TCL_LIB_PATHS /usr/local/lib)
set(TCL_NO_DEFAULT_PATH TRUE)
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(TCL_LIB_PATHS /usr/lib /usr/local/lib)
set(TCL_NO_DEFAULT_PATH FALSE)
endif()
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(TCL_LIB_PATHS /usr/lib
/usr/local/lib
)
set(TCL_NO_DEFAULT_PATH FALSE)
endif()
if (NOT TCL_LIBRARY)

View File

@ -515,9 +515,14 @@ Graph::makeArrivals(Vertex *vertex,
}
Arrival *
Graph::arrivals(Vertex *vertex) const
Graph::arrivals(Vertex *vertex)
{
return arrivals_.pointer(vertex->arrivals());
Arrival *arrivals;
{
UniqueLock lock(arrivals_lock_);
arrivals = arrivals_.pointer(vertex->arrivals());
}
return arrivals;
}
void
@ -1169,6 +1174,16 @@ Vertex::setHasRequireds(bool has_req)
has_requireds_ = has_req;
}
void
Vertex::deletePaths()
{
arrivals_ = arrival_null;
prev_paths_ = prev_path_null;
tag_group_index_ = tag_group_index_max;
has_requireds_ = false;
crpr_path_pruning_disabled_ = false;
}
LogicValue
Vertex::simValue() const
{

View File

@ -100,7 +100,7 @@ public:
VertexId vertexCount() { return vertices_->size(); }
Arrival *makeArrivals(Vertex *vertex,
uint32_t count);
Arrival *arrivals(Vertex *vertex) const;
Arrival *arrivals(Vertex *vertex);
void clearArrivals();
PathVertexRep *makePrevPaths(Vertex *vertex,
uint32_t count);
@ -274,8 +274,7 @@ public:
bool isRoot() const{ return level_ == 0; }
LevelColor color() const { return static_cast<LevelColor>(color_); }
void setColor(LevelColor color);
ArrivalId arrivals() const { return arrivals_; }
void setArrivals(ArrivalId id);
ArrivalId arrivals() { return arrivals_; }
PrevPathId prevPaths() const { return prev_paths_; }
void setPrevPaths(PrevPathId id);
// Requireds optionally follow arrivals in the same array.
@ -325,6 +324,8 @@ public:
// ObjectTable interface.
ObjectIdx objectIdx() const { return object_idx_; }
void setObjectIdx(ObjectIdx idx);
// private to Search.cc
void deletePaths();
static int transitionCount() { return 2; } // rise/fall
@ -332,6 +333,7 @@ protected:
void init(Pin *pin,
bool is_bidirect_drvr,
bool is_reg_clk);
void setArrivals(ArrivalId id);
Pin *pin_;
ArrivalId arrivals_;

View File

@ -19,6 +19,7 @@
#include <stdio.h>
#include <stdarg.h>
#include <string>
#include <mutex>
#include "DisallowCopyAssign.hh"
struct Tcl_Interp;
@ -113,6 +114,7 @@ protected:
char *buffer_;
// Length of string in buffer.
size_t buffer_length_;
std::mutex buffer_lock_;
private:
DISALLOW_COPY_AND_ASSIGN(Report);

View File

@ -482,7 +482,6 @@ protected:
const PathAnalysisPt *path_ap);
void deletePaths();
void deletePaths(Vertex *vertex);
void deletePaths1(Vertex *vertex);
TagGroup *findTagGroup(TagGroupBldr *group_bldr);
void deleteFilterTags();
void deleteFilterTagGroups();

View File

@ -132,7 +132,7 @@ PathVertexRep::tag(const StaState *sta) const
Arrival
PathVertexRep::arrival(const StaState *sta) const
{
const Graph *graph = sta->graph();
Graph *graph = sta->graph();
const Search *search = sta->search();
Tag *tag = search->tag(tag_index_);
Vertex *vertex = graph->vertex(vertex_id_);

View File

@ -397,7 +397,7 @@ Search::deletePaths()
VertexIterator vertex_iter(graph_);
while (vertex_iter.hasNext()) {
Vertex *vertex = vertex_iter.next();
deletePaths1(vertex);
vertex->deletePaths();
}
graph_->clearArrivals();
graph_->clearPrevPaths();
@ -405,23 +405,13 @@ Search::deletePaths()
}
}
void
Search::deletePaths1(Vertex *vertex)
{
vertex->setArrivals(arrival_null);
vertex->setPrevPaths(prev_path_null);
vertex->setTagGroupIndex(tag_group_index_max);
vertex->setHasRequireds(false);
vertex->setCrprPathPruningDisabled(false);
}
void
Search::deletePaths(Vertex *vertex)
{
tnsNotifyBefore(vertex);
if (worst_slacks_)
worst_slacks_->worstSlackNotifyBefore(vertex);
deletePaths1(vertex);
vertex->deletePaths();
}
////////////////////////////////////////////////////////////////
@ -720,7 +710,7 @@ void
Search::arrivalInvalidDelete(Vertex *vertex)
{
arrivalInvalid(vertex);
deletePaths1(vertex);
vertex->deletePaths();
}
void

View File

@ -194,7 +194,7 @@ proc check_path_divider { divider } {
################################################################
define_cmd_args "set_units" \
{[-capacitance cap_unit] [-resistance res_unit] [-time time_unit]\
{[-time time_unit] [-capacitance cap_unit] [-resistance res_unit]\
[-voltage voltage_unit] [-current current_unit] [-power power_unit]\
[-distance distance_unit]}
@ -206,11 +206,12 @@ proc set_units { args } {
keys {-capacitance -resistance -time -voltage -current -power -distance} \
flags {}
check_argc_eq0 "set_units" $args
check_unit "capacitance" -capacitance "f" keys
check_unit "time" -time "s" keys
check_unit "capacitance" -capacitance "f" keys
check_unit "resistance" -resistance "ohm" keys
check_unit "voltage" -voltage "v" keys
check_unit "current" -current "A" keys
check_unit "resistance" -resistance "ohm" keys
check_unit "power" -power "W" keys
check_unit "distance" -distance "m" keys
}
@ -1512,11 +1513,11 @@ proc set_sense { args } {
if { [info exists keys(-type)] } {
set type $keys(-type)
if { $type == "data" } {
sdc_warn "set_sense -type data not supported."
sta_warn "set_sense -type data not supported."
} elseif { $type == "clock" } {
set_clock_sense_cmd1 "set_sense" $args
} else {
sdc_error "set_sense -type clock|data"
sta_error "set_sense -type clock|data"
}
}
}
@ -1527,7 +1528,7 @@ define_cmd_args "set_clock_sense" \
[-clock clocks] pins}
proc set_clock_sense { args } {
sdc_warn "set_clock_sense is deprecated as of SDC 2.1. Use set_sense -type clock."
sta_warn "set_clock_sense is deprecated as of SDC 2.1. Use set_sense -type clock."
set_clock_sense_cmd1 "set_clock_sense" $args
}
@ -1904,26 +1905,24 @@ proc set_false_path { args } {
check_exception_pins $from $to
if { $arg_error } {
delete_from_thrus_to $from $thrus $to
sta_error "set_false_path command failed."
}
} else {
check_for_key_args $cmd args
if { $args != {} } {
sta_warn "'$args' ignored."
}
if { ($from == "NULL" && $thrus == "" && $to == "NULL") } {
delete_from_thrus_to $from $thrus $to
sta_warn "-from, -through or -to required."
} else {
if [info exists flags(-reset_path)] {
reset_path_cmd $from $thrus $to $min_max
}
check_for_key_args $cmd args
if { $args != {} } {
delete_from_thrus_to $from $thrus $to
sta_error "positional arguments not supported."
}
if { ($from == "NULL" && $thrus == "" && $to == "NULL") } {
delete_from_thrus_to $from $thrus $to
sta_error "-from, -through or -to required."
}
set comment [parse_comment_key keys]
if [info exists flags(-reset_path)] {
reset_path_cmd $from $thrus $to $min_max
make_false_path $from $thrus $to $min_max $comment
}
}
set comment [parse_comment_key keys]
make_false_path $from $thrus $to $min_max $comment
}
################################################################
@ -2049,32 +2048,30 @@ proc set_path_delay { cmd args min_max } {
set to [parse_to_arg keys flags arg_error]
if { $arg_error } {
delete_from_thrus_to $from $thrus $to
sta_error "set_path_delay command failed."
}
check_for_key_args $cmd args
if { [llength $args] == 0 } {
delete_from_thrus_to $from $thrus $to
sta_error "missing delay argument."
} elseif { [llength $args] == 1 } {
set delay $args
check_float "$cmd delay" $delay
set delay [time_ui_sta $delay]
} else {
delete_from_thrus_to $from $thrus $to
sta_error "extra positional arguments."
check_for_key_args $cmd args
if { [llength $args] == 0 } {
delete_from_thrus_to $from $thrus $to
sta_error "missing delay argument."
} elseif { [llength $args] == 1 } {
set delay $args
check_float "$cmd delay" $delay
set delay [time_ui_sta $delay]
} else {
sta_warn "'$args' ignored."
}
set ignore_clk_latency [info exists flags(-ignore_clock_latency)]
if [info exists flags(-reset_path)] {
reset_path_cmd $from $thrus $to "all"
}
set comment [parse_comment_key keys]
make_path_delay $from $thrus $to $min_max $ignore_clk_latency \
$delay $comment
}
set ignore_clk_latency [info exists flags(-ignore_clock_latency)]
if [info exists flags(-reset_path)] {
reset_path_cmd $from $thrus $to "all"
}
set comment [parse_comment_key keys]
make_path_delay $from $thrus $to $min_max $ignore_clk_latency \
$delay $comment
}
################################################################
@ -2182,40 +2179,38 @@ proc set_multicycle_path { args } {
check_exception_pins $from $to
if { $arg_error } {
delete_from_thrus_to $from $thrus $to
sta_error "set_multicycle_path command failed."
}
check_for_key_args $cmd args
if { [llength $args] == 0 } {
delete_from_thrus_to $from $thrus $to
sta_error "missing path multiplier argument."
} elseif { [llength $args] == 1 } {
set path_multiplier $args
check_integer "path multiplier" $path_multiplier
} else {
delete_from_thrus_to $from $thrus $to
sta_error "extra positional arguments."
check_for_key_args $cmd args
if { [llength $args] == 0 } {
delete_from_thrus_to $from $thrus $to
sta_error "missing path multiplier argument."
} elseif { [llength $args] == 1 } {
set path_multiplier $args
check_integer "path multiplier" $path_multiplier
} else {
sta_warn "'$args' ignored."
}
set start [info exists flags(-start)]
set end [info exists flags(-end)]
if { $start && $end } {
delete_from_thrus_to $from $thrus $to
sta_error "cannot use -start with -end."
} elseif { $start } {
set use_end_clk 0
} elseif { $end } {
set use_end_clk 1
}
if [info exists flags(-reset_path)] {
reset_path_cmd $from $thrus $to $min_max
}
set comment [parse_comment_key keys]
make_multicycle_path $from $thrus $to $min_max $use_end_clk \
$path_multiplier $comment
}
set start [info exists flags(-start)]
set end [info exists flags(-end)]
if { $start && $end } {
delete_from_thrus_to $from $thrus $to
sta_error "cannot use -start with -end."
} elseif { $start } {
set use_end_clk 0
} elseif { $end } {
set use_end_clk 1
}
if [info exists flags(-reset_path)] {
reset_path_cmd $from $thrus $to $min_max
}
set comment [parse_comment_key keys]
make_multicycle_path $from $thrus $to $min_max $use_end_clk \
$path_multiplier $comment
}
################################################################
@ -2793,7 +2788,7 @@ proc parse_from_arg { keys_var arg_error_var } {
if {$from_pins == {} && $from_insts == {} && $from_clks == {}} {
upvar 1 $arg_error_var arg_error
set arg_error 1
sta_error "no valid objects specified for $key."
sta_warn "no valid objects specified for $key."
return "NULL"
}
return [make_exception_from $from_pins $from_clks $from_insts $tr]
@ -2810,10 +2805,13 @@ proc parse_thrus_arg { args_var arg_error_var } {
set tr ""
if { $arg == "-through" } {
set tr "rise_fall"
set key "-through"
} elseif { $arg == "-rise_through" } {
set tr "rise"
set key "-rise_through"
} elseif { $arg == "-fall_through" } {
set tr "fall"
set key "-fall_through"
}
if { $tr != "" } {
if { [llength $args] > 1 } {
@ -2823,7 +2821,7 @@ proc parse_thrus_arg { args_var arg_error_var } {
if {$pins == {} && $insts == {} && $nets == {}} {
upvar 1 $arg_error_var arg_error
set arg_error 1
sta_error "no valid objects specified for -through."
sta_warn "no valid objects specified for $key"
} else {
lappend thrus [make_exception_thru $pins $nets $insts $tr]
}
@ -2872,7 +2870,7 @@ proc parse_to_arg1 { keys_var end_rf arg_error_var } {
if {$to_pins == {} && $to_insts == {} && $to_clks == {}} {
upvar 1 $arg_error_var arg_error
set arg_error 1
puts "Error: no valid objects specified for $key."
sta_warn "no valid objects specified for $key."
return "NULL"
}
return [make_exception_to $to_pins $to_clks $to_insts $to_rf $end_rf]

View File

@ -88,6 +88,7 @@ Report::print(const string &str)
void
Report::vprint(const char *fmt, va_list args)
{
std::unique_lock<std::mutex> lock(buffer_lock_);
printToBuffer(fmt, args);
printString(buffer_, buffer_length_);
}
@ -121,6 +122,7 @@ Report::printError(const char *buffer, size_t length)
void
Report::vprintError(const char *fmt, va_list args)
{
std::unique_lock<std::mutex> lock(buffer_lock_);
printToBuffer(fmt, args);
printError(buffer_, buffer_length_);
}

View File

@ -1,33 +1,33 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2020, 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/>.
#include "ReportTcl.hh"
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
namespace sta {
using ::Tcl_Channel;
using ::Tcl_GetChannelType;
using ::Tcl_ChannelType;
using ::ClientData;
using ::Tcl_GetChannelInstanceData;
using ::Tcl_DriverOutputProc;
using ::Tcl_Channel;
using ::Tcl_ChannelOutputProc;
using ::Tcl_ChannelType;
using ::Tcl_DriverOutputProc;
using ::Tcl_GetChannelInstanceData;
using ::Tcl_GetChannelType;
extern "C" {
@ -38,153 +38,166 @@ extern "C" {
#endif
static int
encapOutputProc(ClientData instanceData, CONST84 char *buf, int toWrite,
int *errorCodePtr);
encapOutputProc(ClientData instanceData,
CONST84 char *buf,
int toWrite,
int *errorCodePtr);
static int
encapErrorOutputProc(ClientData instanceData, CONST84 char *buf, int toWrite,
int *errorCodePtr);
encapErrorOutputProc(ClientData instanceData,
CONST84 char *buf,
int toWrite,
int *errorCodePtr);
static int
encapCloseProc(ClientData instanceData, Tcl_Interp *interp);
static int
encapSetOptionProc(ClientData instanceData, Tcl_Interp *interp,
CONST84 char *optionName, CONST84 char *value);
encapSetOptionProc(ClientData instanceData,
Tcl_Interp *interp,
CONST84 char *optionName,
CONST84 char *value);
static int
encapGetOptionProc(ClientData instanceData, Tcl_Interp *interp,
CONST84 char *optionName, Tcl_DString *dsPtr);
encapGetOptionProc(ClientData instanceData,
Tcl_Interp *interp,
CONST84 char *optionName,
Tcl_DString *dsPtr);
static int
encapInputProc(ClientData instanceData, char *buf, int bufSize,
int *errorCodePtr);
encapInputProc(ClientData instanceData,
char *buf,
int bufSize,
int *errorCodePtr);
static int
encapSeekProc(ClientData instanceData, long offset, int seekMode,
int *errorCodePtr);
encapSeekProc(ClientData instanceData,
long offset,
int seekMode,
int *errorCodePtr);
static void
encapWatchProc(ClientData instanceData, int mask);
static int
encapGetHandleProc(ClientData instanceData, int direction,
ClientData *handlePtr);
encapGetHandleProc(ClientData instanceData,
int direction,
ClientData *handlePtr);
static int
encapBlockModeProc(ClientData instanceData, int mode);
} // extern "C"
#ifdef TCL_CHANNEL_VERSION_5
Tcl_ChannelType tcl_encap_type_stdout = {
const_cast<char*>("file"),
TCL_CHANNEL_VERSION_4,
encapCloseProc,
encapInputProc,
encapOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr, // close2Proc
encapBlockModeProc,
nullptr, // flushProc
nullptr, // handlerProc
nullptr, // wideSeekProc
nullptr, // threadActionProc
nullptr // truncateProc
const_cast<char *>("file"),
TCL_CHANNEL_VERSION_4,
encapCloseProc,
encapInputProc,
encapOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr, // close2Proc
encapBlockModeProc,
nullptr, // flushProc
nullptr, // handlerProc
nullptr, // wideSeekProc
nullptr, // threadActionProc
nullptr // truncateProc
};
Tcl_ChannelType tcl_encap_type_stderr = {
const_cast<char*>("file"),
TCL_CHANNEL_VERSION_4,
encapCloseProc,
encapInputProc,
encapErrorOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr, // close2Proc
encapBlockModeProc,
nullptr, // flushProc
nullptr, // handlerProc
nullptr, // wideSeekProc
nullptr, // threadActionProc
nullptr // truncateProc
const_cast<char *>("file"),
TCL_CHANNEL_VERSION_4,
encapCloseProc,
encapInputProc,
encapErrorOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr, // close2Proc
encapBlockModeProc,
nullptr, // flushProc
nullptr, // handlerProc
nullptr, // wideSeekProc
nullptr, // threadActionProc
nullptr // truncateProc
};
#else
#ifdef TCL_CHANNEL_VERSION_4
// Tcl 8.4.12
Tcl_ChannelType tcl_encap_type_stdout = {
const_cast<char*>("file"),
TCL_CHANNEL_VERSION_4,
encapCloseProc,
encapInputProc,
encapOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr, // close2Proc
encapBlockModeProc,
nullptr, // flushProc
nullptr, // handlerProc
nullptr, // wideSeekProc
nullptr // threadActionProc
const_cast<char *>("file"),
TCL_CHANNEL_VERSION_4,
encapCloseProc,
encapInputProc,
encapOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr, // close2Proc
encapBlockModeProc,
nullptr, // flushProc
nullptr, // handlerProc
nullptr, // wideSeekProc
nullptr // threadActionProc
};
Tcl_ChannelType tcl_encap_type_stderr = {
const_cast<char*>("file"),
TCL_CHANNEL_VERSION_4,
encapCloseProc,
encapInputProc,
encapErrorOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr, // close2Proc
encapBlockModeProc,
nullptr, // flushProc
nullptr, // handlerProc
nullptr, // wideSeekProc
nullptr // threadActionProc
const_cast<char *>("file"),
TCL_CHANNEL_VERSION_4,
encapCloseProc,
encapInputProc,
encapErrorOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr, // close2Proc
encapBlockModeProc,
nullptr, // flushProc
nullptr, // handlerProc
nullptr, // wideSeekProc
nullptr // threadActionProc
};
#else
#ifdef TCL_CHANNEL_VERSION_3
// Tcl 8.4
Tcl_ChannelType tcl_encap_type_stdout = {
const_cast<char*>("file"),
TCL_CHANNEL_VERSION_3,
encapCloseProc,
encapInputProc,
encapOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr, // close2Proc
encapBlockModeProc,
nullptr, // flushProc
nullptr, // handlerProc
nullptr // wideSeekProc
const_cast<char *>("file"),
TCL_CHANNEL_VERSION_3,
encapCloseProc,
encapInputProc,
encapOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr, // close2Proc
encapBlockModeProc,
nullptr, // flushProc
nullptr, // handlerProc
nullptr // wideSeekProc
};
Tcl_ChannelType tcl_encap_type_stderr = {
const_cast<char*>("file"),
TCL_CHANNEL_VERSION_3,
encapCloseProc,
encapInputProc,
encapErrorOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr, // close2Proc
encapBlockModeProc,
nullptr, // flushProc
nullptr, // handlerProc
nullptr // wideSeekProc
const_cast<char *>("file"),
TCL_CHANNEL_VERSION_3,
encapCloseProc,
encapInputProc,
encapErrorOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr, // close2Proc
encapBlockModeProc,
nullptr, // flushProc
nullptr, // handlerProc
nullptr // wideSeekProc
};
#else
@ -192,68 +205,68 @@ Tcl_ChannelType tcl_encap_type_stderr = {
// Tcl 8.3.2
Tcl_ChannelType tcl_encap_type_stdout = {
const_cast<char*>("file"),
TCL_CHANNEL_VERSION_2,
encapCloseProc,
encapInputProc,
encapOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr, // close2Proc
encapBlockModeProc,
nullptr, // flushProc
nullptr // handlerProc
const_cast<char *>("file"),
TCL_CHANNEL_VERSION_2,
encapCloseProc,
encapInputProc,
encapOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr, // close2Proc
encapBlockModeProc,
nullptr, // flushProc
nullptr // handlerProc
};
Tcl_ChannelType tcl_encap_type_stderr = {
const_cast<char*>("file"),
TCL_CHANNEL_VERSION_2,
encapCloseProc,
encapInputProc,
encapErrorOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr, // close2Proc
encapBlockModeProc,
nullptr, // flushProc
nullptr // handlerProc
const_cast<char *>("file"),
TCL_CHANNEL_VERSION_2,
encapCloseProc,
encapInputProc,
encapErrorOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr, // close2Proc
encapBlockModeProc,
nullptr, // flushProc
nullptr // handlerProc
};
#else
// Tcl 8.2
Tcl_ChannelType tcl_encap_type_stdout = {
const_cast<char*>("file"),
encapBlockModeProc,
encapCloseProc,
encapInputProc,
encapOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr // close2Proc
const_cast<char *>("file"),
encapBlockModeProc,
encapCloseProc,
encapInputProc,
encapOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr // close2Proc
};
Tcl_ChannelType tcl_encap_type_stderr = {
const_cast<char*>("file"),
encapBlockModeProc,
encapCloseProc,
encapInputProc,
encapErrorOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr // close2Proc
const_cast<char *>("file"),
encapBlockModeProc,
encapCloseProc,
encapInputProc,
encapErrorOutputProc,
encapSeekProc,
encapSetOptionProc,
encapGetOptionProc,
encapWatchProc,
encapGetHandleProc,
nullptr // close2Proc
};
#endif
@ -264,12 +277,8 @@ Tcl_ChannelType tcl_encap_type_stderr = {
////////////////////////////////////////////////////////////////
ReportTcl::ReportTcl() :
Report(),
interp_(nullptr),
tcl_stdout_(nullptr),
tcl_stderr_(nullptr),
tcl_encap_stdout_(nullptr),
tcl_encap_stderr_(nullptr)
Report(), interp_(nullptr), tcl_stdout_(nullptr), tcl_stderr_(nullptr),
tcl_encap_stdout_(nullptr), tcl_encap_stderr_(nullptr)
{
}
@ -290,10 +299,16 @@ ReportTcl::setTclInterp(Tcl_Interp *interp)
interp_ = interp;
tcl_stdout_ = Tcl_GetStdChannel(TCL_STDOUT);
tcl_stderr_ = Tcl_GetStdChannel(TCL_STDERR);
tcl_encap_stdout_ = Tcl_StackChannel(interp, &tcl_encap_type_stdout, this,
TCL_WRITABLE, tcl_stdout_);
tcl_encap_stderr_ = Tcl_StackChannel(interp, &tcl_encap_type_stderr, this,
TCL_WRITABLE, tcl_stderr_);
tcl_encap_stdout_ = Tcl_StackChannel(interp,
&tcl_encap_type_stdout,
this,
TCL_WRITABLE,
tcl_stdout_);
tcl_encap_stderr_ = Tcl_StackChannel(interp,
&tcl_encap_type_stderr,
this,
TCL_WRITABLE,
tcl_stderr_);
}
size_t
@ -315,9 +330,10 @@ ReportTcl::printTcl(Tcl_Channel channel, const char *buffer, size_t length)
Tcl_DriverOutputProc *output_proc = Tcl_ChannelOutputProc(ch_type);
int error_code;
ClientData clientData = Tcl_GetChannelInstanceData(channel);
return output_proc(clientData, const_cast<char*>(buffer),
static_cast<int>(length),
&error_code);
return output_proc(clientData,
const_cast<char *>(buffer),
length,
&error_code);
}
// Tcl_Main can eval multiple commands before the flushing the command
@ -389,19 +405,20 @@ ReportTcl::redirectStringEnd()
////////////////////////////////////////////////////////////////
static int
encapOutputProc(ClientData instanceData, CONST84 char *buf, int toWrite,
int *)
encapOutputProc(ClientData instanceData, CONST84 char *buf, int toWrite, int *)
{
ReportTcl *report = reinterpret_cast<ReportTcl*>(instanceData);
return static_cast<int>(report->printString(buf, toWrite));
ReportTcl *report = reinterpret_cast<ReportTcl *>(instanceData);
return report->printString(buf, toWrite);
}
static int
encapErrorOutputProc(ClientData instanceData, CONST84 char *buf, int toWrite,
int *)
encapErrorOutputProc(ClientData instanceData,
CONST84 char *buf,
int toWrite,
int *)
{
ReportTcl *report = reinterpret_cast<ReportTcl*>(instanceData);
return static_cast<int>(report->printString(buf, toWrite));
ReportTcl *report = reinterpret_cast<ReportTcl *>(instanceData);
return report->printString(buf, toWrite);
}
static int
@ -413,7 +430,7 @@ encapInputProc(ClientData, char *, int, int *)
static int
encapCloseProc(ClientData instanceData, Tcl_Interp *)
{
ReportTcl *report = reinterpret_cast<ReportTcl*>(instanceData);
ReportTcl *report = reinterpret_cast<ReportTcl *>(instanceData);
report->logEnd();
report->redirectFileEnd();
report->redirectStringEnd();
@ -455,4 +472,4 @@ encapBlockModeProc(ClientData, int)
return 0;
}
} // namespace
} // namespace sta