}
}
+# try to find source file corresponding to the specified header and either
+# inject macro IMPLEMENT_STANDARD_RTTIEXT in it, or check it already present,
+# and depending on this, return suffix to be used for corresponding macro
+# DEFINE_STANDARD_RTTI... (either inline or out-of-line variant)
+proc DefineExplicitRtti {hxxfile class base theSourceExtensions} {
+ # if current file is not a header (by extension), exit with "inline" variant
+ # (there is no need to bother with out-of-line instantiations for local class)
+ set ext [string range [file extension $hxxfile] 1 end]
+ if { [lsearch -exact [split $theSourceExtensions ,] $ext] >=0 } {
+ return "_INLINE"
+ }
+
+ # try to find source file with the same name but source-type extension
+ # in the same folder
+ set filename [file rootname $hxxfile]
+ foreach ext [split $theSourceExtensions ,] {
+# puts "Checking ${filename}.$ext"
+ if { ! [file readable ${filename}.$ext] } { continue }
+
+ # check the file content
+ set aFileContent [ReadFileToList ${filename}.$ext aFileRawContent aEOL]
+
+ # try to find existing macro IMPLEMENT_STANDARD_RTTIEXT and check that
+ # it is consistent
+ foreach line $aFileContent {
+ if { [regexp "^\\s*IMPLEMENT_STANDARD_RTTIEXT\\s*\\(\\s*$class\\s*,\\s*(\[A-Za-z0-9_\]+)\\s*\\)" $line res impl_base] } {
+ # implementation is in place, just report warning if second argument
+ # is different
+ if { $base != $impl_base } {
+ logwarn "Warning in ${filename}.$ext: second argument of macro"
+ logwarn " IMPLEMENT_STANDARD_RTTIEXT($class,$impl_base)"
+ logwarn " is not the same as detected base class, $base"
+ }
+ return "EXT"
+ }
+ }
+
+ # inject a new macro before the first non-empty, non-comment, and
+ # non-preprocessor line
+ set aNewFileContent {}
+ set injected 0
+ set inc_found 0
+ foreach line $aFileContent {
+ if { ! $injected } {
+ # add macro before first non-empty line after #includes
+ if { [regexp {^\s*$} $line] } {
+ } elseif { [regexp {^\s*\#\s*include} $line] } {
+ set inc_found 1
+ } elseif { $inc_found } {
+ set injected 1
+ lappend aNewFileContent "IMPLEMENT_STANDARD_RTTIEXT($class,$base)"
+ if { ! [regexp "^IMPLEMENT_" $line] } {
+ lappend aNewFileContent ""
+ }
+ }
+ }
+ lappend aNewFileContent $line
+ }
+ if { ! $injected } {
+ lappend aNewFileContent "IMPLEMENT_STANDARD_RTTIEXT($class,$base)"
+ }
+ SaveListToFile ${filename}.$ext $aNewFileContent $aEOL
+
+ return "EXT"
+ }
+
+ logwarn "Warning in ${hxxfile}: cannot find corresponding source file,"
+ logwarn " will use inline version of DEFINE_STANDARD_RTTI"
+ return "_INLINE"
+}
+
# Parse source files and:
#
# - add second argument to macro DEFINE_STANDARD_RTTI specifying first base
# find all instances of DEFINE_STANDARD_RTTI with single or two arguments
set index 0
- set pattern_rtti {^(\s*DEFINE_STANDARD_RTTI\s*)\(\s*([A-Za-z_0-9,\s]+)\s*\)}
+ set pattern_rtti {^(\s*DEFINE_STANDARD_RTTI)([_A-Z]+)?\s*\(\s*([A-Za-z_0-9,\s]+)\s*\)}
while { [regexp -start $index -indices -lineanchor $pattern_rtti \
- $aProcessedFileContent location start clist] } {
+ $aProcessedFileContent location start suffix clist] } {
set index [lindex $location 1]
- set start [eval string range \$aProcessedFileContent $start]
- set clist [split [eval string range \$aProcessedFileContent $clist] ,]
+ set start [eval string range \$aProcessedFileContent $start]
+ set suffix [eval string range \$aProcessedFileContent $suffix]
+ set clist [split [eval string range \$aProcessedFileContent $clist] ,]
if { [llength $clist] == 1 } {
set class [string trim [lindex $clist 0]]
logwarn "macro DEFINE_STANDARD_RTTI is changed assuming it inherits $inherits($class), please check!"
}
set change_flag 1
- ReplaceSubString aProcessedFileContent $location "${start}($class, $inherits($class))" index
+ ReplaceSubString aProcessedFileContent $location \
+ "${start}EXT($class,$inherits($class))" index
}
} else {
logwarn "Error in $aProcessedFile: Macro DEFINE_STANDARD_RTTI used for class $class whose declaration is not found in this file, cannot fix"
set base [string trim [lindex $clist 1]]
if { ! [info exists inherits($class)] } {
logwarn "Warning in $aProcessedFile: Macro DEFINE_STANDARD_RTTI used for class $class whose declaration is not found in this file"
- } elseif { $base != $inherits($class) } {
+ } elseif { $base != $inherits($class) && ! [info exists inherits($class,multiple)] } {
logwarn "Warning in $aProcessedFile: Second argument in macro DEFINE_STANDARD_RTTI for class $class is $base while $class seems to inherit from $inherits($class)"
- if { ! $theCheckMode && ! [info exists inherits($class,multiple)] } {
- set change_flag 1
- ReplaceSubString aProcessedFileContent $location "${start}($class, $inherits($class))" index
- }
+ }
+ # convert intermediate version of macro DEFINE_STANDARD_RTTI
+ # with two arguments to either _INLINE or EXT variant
+ if { ! $theCheckMode && "$suffix" == "" } {
+ set change_flag 1
+ # try to inject macro IMPLEMENT_STANDARD_RTTIEXT in the
+ # corresponding source file (or check it already present),
+ # and depending on this, use either inline or out-of-line variant
+ set rtti_suffix [DefineExplicitRtti $aProcessedFile $class $base $theSourceExtensions]
+ ReplaceSubString aProcessedFileContent $location \
+ "${start}${rtti_suffix}($class,$base)" index
}
}
}
set index 0
set first_newline \n\n
set pattern_implement {\\?\n\s*IMPLEMENT_(DOWNCAST|STANDARD_[A-Z_]+|HARRAY1|HARRAY2|HUBTREE|HEBTREE|HSEQUENCE)\s*\([A-Za-z0-9_ ,]*\)\s*;?}
- while { [regexp -start $index -indices -lineanchor $pattern_implement $aProcessedFileContent location] } {
+ while { [regexp -start $index -indices -lineanchor $pattern_implement $aProcessedFileContent location macro] } {
set index [lindex $location 1]
+ # macro IMPLEMENT_STANDARD_RTTIEXT is retained
+ if { [eval string range \$aProcessedFileContent $macro] == "STANDARD_RTTIEXT" } {
+ continue
+ }
if { ! $theCheckMode } {
set change_flag 1
ReplaceSubString aProcessedFileContent $location $first_newline index
# find all uses of macro STANDARD_TYPE and method DownCast and ensure that
# argument class is explicitly included
- set pattern_incbeg {\s*#\s*include\s*[\"<]\s*}
+ set pattern_incbeg {\s*#\s*include\s*[\"<]\s*([A-Za-z0-9_/]*/)?}
set pattern_incend {[.][a-zA-Z]+\s*[\">]}
set index 0
set addtype {}
if { ! $theCheckMode } {
set addinc ""
foreach type $addtype {
- append addinc "\n#include <$type.hxx>"
+ if { "$aProcessedFileName" != "$type.hxx" } {
+ append addinc "\n#include <$type.hxx>"
+ }
}
if { [regexp -indices ".*\n${pattern_incbeg}\[A-Za-z0-9_/\]+${pattern_incend}" $aProcessedFileContent location] } {
set change_flag 1
# iterate by header files
foreach aHeader [glob -nocomplain -type f -directory $theTargetPath *.{$theExtensions}] {
+ set aCurrentHeaderName [file tail $aHeader]
# skip gxx files, as names Handle_xxx used there are in most cases
# placeholders of the argument types substituted by #define
set anUpdatedHeaderContent {}
set pattern_handle {\mHandle_([A-Za-z0-9_]+)}
foreach line $aHeaderContent {
- # do not touch #include and #if... statements
- if { [regexp {\s*\#\s*include} $line] || [regexp {\s*\#\s*if} $line] } {
+ # do not touch typedefs, #include, and #if... statements
+ if { [regexp {^\s*typedef} $line] ||
+ [regexp {^\s*\#\s*include} $line] || [regexp {^\s*\#\s*if} $line] } {
lappend anUpdatedHeaderContent $line
continue
}
} else {
# replace by forward declaration of a class or its include unless
# it is already declared or included
- if { ! [regexp "^\s*\#\s*include\s*\[\<\"\]\s*$aForwardDeclHandledClass\s*\[\>\"\]" $aHeaderContent] } {
- if { $isQObject } {
+ if { ! [regexp "\#\\s*include\\s*\[\<\"\]\\s*(\[A-Za-z0-9_/\]*/)?$aForwardDeclHandledClass\[.\]hxx\\s*\[\>\"\]" $aHeaderContent] } {
+ if { $isQObject && "$aCurrentHeaderName" != "${aForwardDeclHandledClass}.hxx" } {
lappend anUpdatedHeaderContent "#include <${aForwardDeclHandledClass}.hxx>"
if { ! [SearchForFile $theIncPaths ${aForwardDeclHandledClass}.hxx] } {
loginfo "Warning: include ${aForwardDeclHandledClass}.hxx added in $aHeader, assuming it exists and defines Handle_$aForwardDeclHandledClass"
while { [regexp -start $index -indices -lineanchor $pattern_refcast0 $hxx location class var] } {
set index [lindex $location 1]
- logwarn "Warning in $afile: C-style cast: [eval string range \$hxx $location]"
+ set var [eval string range \$hxx $var]
+ if { "$var" != "const" && "$var" != "Standard_OVERRIDE" } {
+ logwarn "Warning in $afile: C-style cast: [eval string range \$hxx $location]"
+ }
}
# replace const Handle(A)& a = Handle(B)::DownCast (b); by
set aFileContent [read $aFile]
close $aFile
- set aFileEOL "\r"
- if [regexp "\r\n" $aFileContent] {
+ # detect DOS end-of-lines
+ if { [regexp "\r\n" $aFileContent] } {
set aFileEOL "\r\n"
- } elseif [regexp "\n" $aFileContent] {
+ set aList [split [regsub -all "\r\n" $aFileContent "\n"] "\r\n"]
+ } else {
+ # standard UNIX end-of-lines
set aFileEOL "\n"
- }
-
- # convert to unix eol
- if {"$aFileEOL" != "\n"} {
- regsub -all {$aFileEOL} $aFileContent "\n" aFileContent
- }
-
- set aList {}
- foreach aLine [split $aFileContent "\n"] {
- lappend aList [string trimright $aLine]
+ set aList [split $aFileContent "\n"]
}
return $aList
fconfigure $aFile -translation binary
puts -nonewline $aFile [join $theData $anUsedEol]
close $aFile
+
+ loginfo "File $theFilePath modified"
}
# collect all subdirs of theBaseDir