home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 1997 November
/
PCWorld_1997-11_cd.bin
/
software
/
programy
/
komix
/
DATA.Z
/
cpp_regen.tcl
< prev
next >
Wrap
Text File
|
1997-04-07
|
8KB
|
292 lines
#---------------------------------------------------------------------------
#
# Copyright (c) 1993-1995 by Cadre Technologies Inc.
#
# This software is furnished under a license and may be used only in
# accordance with the terms of such license and with the inclusion of
# the above copyright notice. This software or any other copies thereof
# may not be provided or otherwise made available to any other person.
# No title to and ownership of the software is hereby transferred.
#
# The information in this software is subject to change without notice
# and should not be construed as a commitment by Cadre Technologies Inc.
#
#---------------------------------------------------------------------------
#
# File : @(#)cpp_regen.tcl /main/hindenburg/1
# Original date : 14-7-1993
# Description : Regeneration code
# regenerates user added method bodies
# regenerates start-end bounded pieces of code
#
#---------------------------------------------------------------------------
#
proc prepare_regeneration {class} {
global re_user_includes re_ctor re_found_ctor re_dtor re_split
catch {unset re_split}
set re_user_includes ""
set re_ctor ""
set re_found_ctor 0
set re_dtor ""
class2tgtfiles $class src_file h_file
if {![fstorage::exists $src_file]} {
return
}
if [catch {set fd [fstorage::open $src_file r]}] {
return
}
check_code $class $fd
# include piece
seek $fd 0
global START_INCLUDE_MESSAGE END_INCLUDE_MESSAGE
process_start_end_piece $fd $START_INCLUDE_MESSAGE \
$END_INCLUDE_MESSAGE re_user_includes
# constructor piece
# expect constructor/destructor after include part
set pos [tell $fd]
global START_CTOR_MESSAGE END_CTOR_MESSAGE
set re_found_ctor [process_start_end_piece $fd $START_CTOR_MESSAGE \
$END_CTOR_MESSAGE re_ctor]
# destructor piece
# do NOT expect it after the constructor
# so reset to pos
seek $fd $pos
global START_DTOR_MESSAGE END_DTOR_MESSAGE
process_start_end_piece $fd $START_DTOR_MESSAGE \
$END_DTOR_MESSAGE re_dtor
seek $fd 0
process_user_added_methods $fd
fstorage::close $fd
}
# check for OLDCODE
# check for OBSOLETE CODE
# check for braces that disturb regeneration process (=braces at column 0)
proc check_code {class fd} {
set line [gets $fd]
set opener 0
set closer 0
while {![eof $fd] && $line != "#ifdef OLDCODE" && \
$line != "#ifdef OBSOLETE_CODE" } {
if {[regexp {^\}.+} $line] || [regexp {^\{.+} $line]} {
m4_error $E_REGEN [braces_error_msg $class $line]
}
if {[regexp {^\{$} $line] } {
incr opener
}
if {[regexp {^\}$} $line] } {
if {($opener - $closer) >= 1} {
incr closer
} else {
m4_error $E_REGEN [braces_error_msg $class $line]
}
}
set line [gets $fd]
}
if {$opener != $closer} {
m4_error $E_REGEN [braces_error_msg $class $line]
}
if {$line == "#ifdef OLDCODE" || $line == "#ifdef OBSOLETE_CODE"} {
m4_error $E_REGEN [oldcode_error_msg $class $line]
}
}
proc process_start_end_piece {fd st_msg end_msg result} {
upvar $result lresult
set lresult ""
set found 0
set line [gets $fd]
while {![eof $fd] && ![string match *$st_msg $line]} {
set line [gets $fd]
}
set found [string match *$st_msg $line]
set line [gets $fd]
while {![eof $fd] && ![string match *$end_msg $line]} {
append lresult "$line\n"
set line [gets $fd]
}
return $found
}
# Fill the global array 're_split' with all the method bodies.
# The key is the method name.
# The contents is a list of method type and method contents.
# For each overloaded method this list is extended with
# another type and contents. The order of this list is the file order.
proc process_user_added_methods {fd} {
global re_split
while {![eof $fd]} {
set line [gets $fd]
if {$line == $REGEN_END} {
break
}
set exp_method {^[^ ].*::(.*)(\(.*[\)t:]$)}
if [regexp $exp_method $line dummy method type] {
set result ""
set tr_type [string trimright $type :]
if {$tr_type != $type} {
# also remove whitspace from type
set type [string trimright $tr_type]
append result " :"
}
# append result "\n"
set line [gets $fd]
set f 0
set br 0
while {![eof $fd] && \
($f == 0 || ($br > 0 && $f == 1))} {
append result "\n"
if {[regexp {^\{$} $line]} {
set f 1
incr br
}
if {$f == 1 && [regexp {^\}$} $line] } {
incr br -1
}
append result "$line"
set line [gets $fd]
}
if [info exist re_split($method)] {
lappend re_split($method) $type
lappend re_split($method) $result
} else {
set re_split($method) [list $type $result]
}
}
}
}
# provide a method body; a default message or a previously edited one
# look in global array 're_split' for user added method bodies.
#
# if var_name is not empty, this name is used for the ...not_yet_implemented
# variable
proc get_method_body {method_name method_type section {var_name ""}} {
global re_split
if {$var_name == ""} {
set var_name ${method_name}_is_not_yet_implemented
} else {
set var_name ${var_name}_is_not_yet_implemented
}
if {![info exists re_split($method_name)]} {
# no match, provide the default message
expand_text $section {
{
// !! Implement this function !!
int ~${var_name};
}
}
return
}
set avail [lsearch $re_split($method_name) $method_type]
if {$avail != -1} {
# full match, name and type
lvarpop re_split($method_name) $avail
expand_text $section {
~[lvarpop re_split($method_name) $avail]
}
} else {
# method name matched, method type not
# probabely this is the one, but the
# parameters have changed
# just pick the first one of the list
global cpp_error_state
if {! $cpp_error_state } {
puts stdout "WARNING: generated OLDCODE section"
}
lvarpop re_split($method_name)
expand_text $section {
#ifdef OLDCODE
~[lvarpop re_split($method_name)]
#else
{
// !! Implement this function !!
int ~${var_name};
}
#endif
}
}
if {[llength $re_split($method_name)] == 0} {
unset re_split($method_name)
}
}
proc oldcode_error_msg {class line} {
class2tgtfiles $class src_file h_file
set msg "file '$src_file' still contains '$line' line"
return $msg
}
proc braces_error_msg {class line} {
class2tgtfiles $class src_file h_file
set msg "braces in file '$src_file' do not match"
if {$line != ""} {
append msg " code regeneration failed for line '$line'"
}
append msg " (code regeneration is based on method-braces at start of line)"
return $msg
}
proc regen_unset {method_name method_type} {
global re_split
if {![info exists re_split($method_name)]} {
return
}
set avail [lsearch $re_split($method_name) $method_type]
if {$avail != -1} {
set x [lvarpop re_split($method_name) $avail]
lvarpop re_split($method_name) $avail
} else {
# just pick the first one
lvarpop re_split($method_name)
lvarpop re_split($method_name)
}
if {[llength $re_split($method_name)] == 0} {
unset re_split($method_name)
}
}
proc append_obsolete_code {class} {
global re_split
if {! [info exists re_split]} {
return
}
if {[array names re_split] == ""} {
return
}
global cpp_error_state
if {! $cpp_error_state } {
puts "WARNING: appending obsolete code section"
}
set sect $cpp_sections(c_impl_no_regen_sect)
$sect append "\n#ifdef OBSOLETE_CODE\n"
foreach el [array names re_split] {
while {[llength $re_split($el)] != 0} {
set nmfc "[$class getName]::$el[lvarpop re_split($el)]"
$sect append "// Function $nmfc:\n"
$sect append "[lvarpop re_split($el)]\n"
}
}
section append $sect "#endif\n"
}