([RJM]) Here some code is presented that can be used to read C-header files. This should apparently aid in developing and managing less error-prone bilangual C/Tcl projects. Further comments is in the code below. Extensions and ideas are welcomed. ====== # C-header file parser # will parse simple #define commands and enums as long as these are in a section # that acts as a parse delimiter areas as well as a comment in C as to indicate # that sections are also used by tcl programs. # Using C macros aid in readability of Tcl/C-projects as well as reduce potential # error sources. # Delimiters: //tcl on and //tcl off (yet not /*tcl on*/) # all #defines are stored in ordinary variables in order to keep accesses as # straightforward as possible. Normally no conflicts occurs when #defines are # capitalized. In procs, defines shall be dereferenced with prefixed ::, which # aid also in quick visual recognition besides not needing 'global' commands. proc h-parse {filename} { global _H_PARSE_ set _H_PARSE_ off set fid [open $filename r] while {![eof $fid]} { set line [gets $fid] # ToDo: /*...*/ comment remover if {[regexp ^//tcl $line]} { set _H_PARSE_ [lindex $line 1] continue } regsub //(.*?)$ $line "" line if {$_H_PARSE_ != "on"} continue set line _C_[string trimright $line \;] eval $line } } proc _C_ {} { } # assign enums as macros (alternatively consider storage in array because it # corresponds to its nature in C. However this compromises readability # of typical enum usage in switch statements) proc _C_enum {name ids} { # name ignored # ids: do assignments in enums without spaces! set index 0 foreach element [split [regsub -all " " $ids ""] ,] { lassign [split $element =] name value if {$value != ""} { set index $value } set ::$name $index incr index } } proc _C_#define {args} { lassign $args name value set ::$name $value } if 1 { proc test {} { h-parse test.h puts "===== list of globals with \"A\" =====" foreach var [info globals *A*] { puts $var\t\t[set ::$var] } puts "===== some usage examples =====" for {set i 0} {$i < 20} {incr i} { # note the omission of outer brackets - variable substitution! switch -- $i default { puts -nonewline . } $::ALPHA { puts alpha } $::BETA { puts beta } $::GAMMA { puts gamma } $::ETA { puts eta } $::OMEGA { puts omega } } if {$::MACRO_EMPTY == "" } {puts "empty macro"} if {$::MACRO_VALUE != "" } {puts "macro: $::MACRO_VALUE"} } } ====== And here a sample header file is quoted that is used for the test case above: ====== //tcl on enum hallo {ALPHA, BETA, GAMMA=6, ETA , OMEGA = 21}; //tcl off /* stuff that tcl ignores */ blah, blah //tcl on #define MACRO_EMPTY #define MACRO_COMMENT // test comment // here a line with some whitespaces #define MACRO_STRING "TESTVAL" #define MACRO_VALUE 123 ====== <> Category Development