home *** CD-ROM | disk | FTP | other *** search
- #---------------------------------------------------------------------------
- #
- # Copyright (c) 1997 by Cayenne Software, 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 Cayenne Software, Inc.
- #
- #---------------------------------------------------------------------------
- #
- # File : fortegen.tcl
- # Author :
- # Original date : May 1997
- # Description : Classes for code generation
- #
- #---------------------------------------------------------------------------
-
- #---------------------------------------------------------------------------
- # File: @(#)ftconstant.tcl /main/hindenburg/2
- #---------------------------------------------------------------------------
-
- # Start user added include file section
- # End user added include file section
-
-
- Class FTConstants : {Object} {
- constructor
- method destructor
- }
-
- global FTConstants::startCtor
- set FTConstants::startCtor "Start constructor user section"
-
- global FTConstants::endCtor
- set FTConstants::endCtor "End constructor user section"
-
- global FTConstants::obsoleteCode
- set FTConstants::obsoleteCode "OBSOLETE_CODE"
-
- global FTConstants::oldCode
- set FTConstants::oldCode "OLDCODE"
-
-
- constructor FTConstants {class this} {
- set this [Object::constructor $class $this $name]
- # Start constructor user section
- # End constructor user section
- return $this
- }
-
- method FTConstants::destructor {this} {
- # Start destructor user section
- # End destructor user section
- }
-
- # Do not delete this line -- regeneration end marker
-
- #---------------------------------------------------------------------------
- # File: @(#)ftfilehand.tcl /main/hindenburg/2
- #---------------------------------------------------------------------------
-
- # Start user added include file section
- # End user added include file section
-
- require "filehandle.tcl"
-
- Class FTFileHandler : {FileHandler} {
- constructor
- method destructor
- method getSpecialFiles
- method getFileTypes
- attribute fileType
- attribute xtraFileType
- }
-
- constructor FTFileHandler {class this} {
- set this [FileHandler::constructor $class $this]
- $this fileType "cex"
- $this xtraFileType "hex"
- # Start constructor user section
- # End constructor user section
- return $this
- }
-
- method FTFileHandler::destructor {this} {
- # Start destructor user section
- # End destructor user section
- $this FileHandler::destructor
- }
-
- method FTFileHandler::getSpecialFiles {this} {
- return [List new]
- }
-
- method FTFileHandler::getFileTypes {this} {
- set list [List new]
- $list append [$this fileType]
- $list append [$this xtraFileType]
- return $list
- }
-
- # Do not delete this line -- regeneration end marker
-
- #---------------------------------------------------------------------------
- # File: @(#)ftgenerato.tcl /main/hindenburg/2
- #---------------------------------------------------------------------------
-
- # Start user added include file section
- # End user added include file section
-
- require "generator.tcl"
-
- Class FTGenerator : {Generator} {
- constructor
- method destructor
- method generate
- attribute fileHandler
- }
-
- constructor FTGenerator {class this} {
- set this [Generator::constructor $class $this]
- # Start constructor user section
- $this fileHandler [FTFileHandler new]
- # End constructor user section
- return $this
- }
-
- method FTGenerator::destructor {this} {
- # Start destructor user section
- # End destructor user section
- $this Generator::destructor
- }
-
- method FTGenerator::generate {this classList} {
- set typeToClassDict [Dictionary new]
- set tgtModel [FTModel new]
- set regenerator [FTRegenerator new]
- set fileType [[$this fileHandler] fileType]
-
- $classList foreach class {
- $class generate $tgtModel
-
- set fileDesc [[$this fileHandler] openFile $class $fileType]
- if {$fileDesc != ""} {
- $regenerator regenerate $class $fileDesc $tgtModel
- [$this fileHandler] closeFile $fileDesc
- }
- }
-
- $tgtModel generate $typeToClassDict
- return $typeToClassDict
- }
-
- # Do not delete this line -- regeneration end marker
-
- #---------------------------------------------------------------------------
- # File: @(#)ftregenera.tcl /main/hindenburg/5
- #---------------------------------------------------------------------------
-
- # Start user added include file section
- # End user added include file section
-
- require "regenerato.tcl"
-
- Class FTRegenerator : {Regenerator} {
- constructor
- method destructor
- method regenerate
- method checkFile
- method processClass
- method processClassDecl
- method processClassUserBody
- method processClassInit
- method processCursor
- method makeObsolete
- method hasSameKind
- attribute tgtClass
- }
-
- constructor FTRegenerator {class this} {
- set this [Regenerator::constructor $class $this]
- # Start constructor user section
- # End constructor user section
- return $this
- }
-
- method FTRegenerator::destructor {this} {
- # Start destructor user section
- # End destructor user section
- $this Regenerator::destructor
- }
-
- method FTRegenerator::regenerate {this class fileDesc tgtModel} {
- if {[$this checkFile $fileDesc]} {
- m4_error $E_OBSOLETESECT [$class getName]
- m4_warning $M_NO_REGEN [$class getName]
- return
- }
-
- $this tgtClass [$tgtModel findDefinition [$class getName]]
- if {[$this tgtClass] == ""} {
- # an error has occurred while GEnerating for this class, REgeneration
- # is needless
- return
- }
-
- set kind ""
- while {![eof $fileDesc]} {
- set line [gets $fileDesc]
- if {[string match *begin* $line]} {
- if {![regexp {^[- \t]*begin ([^;]+);$} $line dummy kind]} {
- m4_warning $E_ILL_HEADER [$class getName] $line
- m4_warning $M_NO_REGEN [$class getName]
- return
- }
- break
- }
- }
- if {$kind == ""} {
- m4_warning $E_NO_HEADER [$class getName]
- m4_warning $M_NO_REGEN [$class getName]
- return
- }
-
- # only CLASS and CURSOR are regenerated
- #
- if {$kind == "CLASS"} {
- if {[$this hasSameKind $class $kind]} {
- $this processClass $fileDesc
- } else {
- m4_warning $M_NO_REGEN [$class getName]
- }
- } elseif {$kind == "CURSOR"} {
- if {[$this hasSameKind $class $kind]} {
- $this processCursor $fileDesc
- } else {
- m4_warning $M_NO_REGEN [$class getName]
- }
- } else {
- $this hasSameKind $class $kind
- }
- }
-
- method FTRegenerator::checkFile {this fileDesc} {
- # check whether there is still OBSOLETE CODE in the file
- #
- while {![eof $fileDesc]} {
- set line [gets $fileDesc]
- if {[string match *${FTConstants::obsoleteCode}* $line]} {
- seek $fileDesc 0
- return 1
- }
- }
-
- seek $fileDesc 0
- return 0
- }
-
- method FTRegenerator::processClass {this fileDesc} {
- set WS "\[ \t]*"
- set WSn "\[ \t]+"
- set state START
- while {![eof $fileDesc]} {
- set line [gets $fileDesc]
- if {$state == "START"} {
- if {[regexp "^${WS}class${WSn}" $line]} {
- $this processClassDecl $fileDesc
- set state DEF
- }
- } elseif {[regexp "^${WS}method${WSn}" $line]} {
- $this processClassUserBody $fileDesc $line method
- } elseif {[regexp "^${WS}event handler${WSn}" $line]} {
- $this processClassUserBody $fileDesc $line event
- }
- }
- }
-
- method FTRegenerator::processClassDecl {this fileDesc} {
- # class declaration -> props, map
- #
- set WS "\[ \t]*"
- set WSn "\[ \t]+"
- set state START
- while {![eof $fileDesc]} {
- set line [gets $fileDesc]
- if {[regexp "^${WS}end${WS}class${WS};" $line]} {
- return
- } elseif {[regexp "^${WS}$" $line]} {
- continue
- } elseif {[regexp "^${WS}has${WS}property" $line]} {
- set sect [[[$this tgtClass] sections] getSection property]
- if {$sect != ""} {
- $sect append "$line\n"
- set state PROPS
- }
- } elseif {[regexp "^${WS}has${WS}$" $line]} {
- set sect [[[$this tgtClass] sections] getSection map]
- if {$sect != ""} {
- set state MAP1
- }
- } elseif {[regexp "^\[-+]" $line]} {
- if {$state == "MAP1"} {
- $sect append "has\n"
- set state MAP
- }
- if {$state == "MAP"} {
- $sect append "$line\n"
- }
- if {[regexp "^-" $line]} {
- set state END
- }
- } elseif {$state == "PROPS"} {
- $sect append "$line\n"
- }
- }
- }
-
- method FTRegenerator::processClassUserBody {this fileDesc line kind} {
- # kind is one of method, event (meaning "event handler")
- # Init -> user sect
- # methods, event handlers -> body
- #
- set methSect [TextSection new]
- $methSect append "$line\n"
-
- set name ""
- set WS "\[ \t]*"
- set kind2 $kind
- if {$kind == "event"} {
- set kind2 "event handler"
- }
- # ^ <kind> <system> '.' <name>
- regexp "^${WS}$kind2${WS}\[^.]+\.(\[_0-9A-Za-z]+)" $line dummy name
-
- set tgtMethods [[$this tgtClass] findMethods $name $kind]
- if {[llength $tgtMethods] == 0} {
- # no method found, make OBSOLETE
- #
- m4_warning $W_OBSOLETECODE [[$this tgtClass] name] $name
- $this makeObsolete $fileDesc $methSect $kind
- return
- }
- if {[llength $tgtMethods] == 1 && [[lindex $tgtMethods 0] isGenerated]} {
- # the method that was found, has been generated; we guess that the user
- # did not overload it
- #
- return
- }
-
- # special treatment for method 'Init'
- #
- if {$name == "Init"} {
- $this processClassInit $fileDesc [lindex $tgtMethods 0]
- return
- }
-
- # create a list of the method's parameter types
- # find out the return type of the method
- #
- set parTypes {}
- set parType ""
- # read 1st param, i.e. '(' <name> ':' <type>
- # may be followed by '=' or ',' or ')'
- regexp "\\(\[^:)]*:${WS}(\[^=,)]*)" $line dummy parType
- if {[string trim $parType] != ""} {
- lappend parTypes [string trim $parType]
- }
- set methType ""
- if {$kind == "method"} {
- # read method type, i.e. ':' ["copy"] <type>
- regexp ":${WS}(\[^:=,)]*)$" $line dummy methType
- }
-
- while {![eof $fileDesc]} {
- set line [gets $fileDesc]
- $methSect append "$line\n"
- if {[regexp "^${WS}begin${WS}$" $line]} {
- break
- } elseif {[regexp "^${WS}end${WS}$kind" $line]} {
- break
- } else {
- set parType ""
- # read 2nd param, i.e. <name> ':' <type>
- # may be followed by '=' or ',' or ')'
- regexp "\[^:)]*:${WS}(\[^=,)]*)" $line dummy parType
- if {[string trim $parType] != ""} {
- lappend parTypes [string trim $parType]
- }
- if {$kind == "method" && $methType == ""} {
- # read method type, i.e. ':' ["copy"] <type>
- regexp ":${WS}(\[^:=,)]*)$" $line dummy methType
- }
- }
- }
- if {$kind == "method"} {
- regsub "${WS}copy${WS}" $methType "" methType
- set methType [string trim $methType]
- }
-
- # now, find the best match possible
- # first one found will be taken
- #
- set tgtMethod ""
- set properMatch 0
- foreach mx [[$this tgtClass] findMethodsX $name $kind] {
- set meth [lindex $mx 0]
- if {[$meth isGenerated] || [$meth userCode] != ""} {
- continue
- }
-
- set parTypesX [lindex [lindex $mx 1] 0]
- if {$parTypesX != $parTypes} {
- if {$tgtMethod == ""} {
- set tgtMethod $meth
- }
- continue
- }
-
- set methTypeX [lindex [lindex $mx 1] 1]
- if {$methTypeX != $methType} {
- if {$tgtMethod == ""} {
- set tgtMethod $meth
- }
- continue
- }
-
- set tgtMethod $meth
- set properMatch 1
- break
- }
-
- # no method found: make OBSOLETE
- #
- if {$tgtMethod == ""} {
- m4_warning $W_OBSOLETECODE [[$this tgtClass] name] $name
- $this makeObsolete $fileDesc $methSect $kind
- return
- }
-
- # no proper match: generate OLDCODE
- #
- if {!$properMatch} {
- $tgtMethod hasOldCode 1
- }
-
- # regenerate
- #
- set sect ""
- while {![eof $fileDesc]} {
- set line [gets $fileDesc]
- if {[regexp "^${WS}end${WS}$kind" $line]} {
- return
- } else {
- if {$sect == ""} {
- set sect [$tgtMethod getUserCode]
- }
- $sect append "$line\n"
- }
- }
- }
-
- method FTRegenerator::processClassInit {this fileDesc tgtMethod} {
- set sect ""
- set WS "\[ \t]*"
- set state START
- while {![eof $fileDesc]} {
- set line [gets $fileDesc]
- if {[regexp "^${WS}end${WS}method" $line]} {
- return
- } elseif {[string match *${FTConstants::startCtor} $line]} {
- set state COPY
- } elseif {[string match *${FTConstants::endCtor} $line]} {
- return
- } elseif {$state == "COPY"} {
- if {$sect == ""} {
- set sect [$tgtMethod getUserCode]
- }
- $sect append "$line\n"
- }
- }
- }
-
- method FTRegenerator::processCursor {this fileDesc} {
- # all lines between "begin" and the final "end;" line will be regenerated
- #
- set tgtMethod [[[$this tgtClass] methSet] index 0]
- set sect ""
- set WS "\[ \t]*"
- set state START
- while {![eof $fileDesc]} {
- set line [gets $fileDesc]
- if {$state == "START"} {
- if {[regexp "^${WS}begin${WS}$" $line]} {
- set state BODY
- }
- } elseif {[regexp "^${WS}end${WS};${WS}$" $line]} {
- if {$state == "BODY"} {
- set state OPT_BODY
- } else {
- # state == OPT_BODY
- $sect appendSect $optSect
- }
- set optSect [TextSection new]
- $optSect append "$line\n"
- } elseif {$state == "BODY"} {
- if {$sect == ""} {
- set sect [$tgtMethod getUserCode]
- }
- $sect append "$line\n"
- } else {
- # state == OPT_BODY
- $optSect append "$line\n"
- }
- }
- }
-
- method FTRegenerator::makeObsolete {this fileDesc methSect kind} {
- set sect [[[$this tgtClass] sections] getSection obsolete]
- if {$sect == ""} {
- return
- }
- $sect appendSect $methSect
- set WS "\[ \t]*"
- while {![eof $fileDesc]} {
- set line [gets $fileDesc]
- $sect append "$line\n"
- if {[regexp "^${WS}end${WS}$kind" $line]} {
- break
- }
- }
- $sect append "\n"
- }
-
- method FTRegenerator::hasSameKind {this class kind} {
- if {$kind == [[$this tgtClass] kind]} {
- return 1
- }
-
- m4_warning $W_KIND_CHANGE [$class getName] $kind [[$this tgtClass] kind]
- return 0
- }
-
- # Do not delete this line -- regeneration end marker
-
-