#!/usr/bin/tclsh set usage { Usage: spellsift.tcl The named .c and .h source files comment blocks are spell-checked. } if {[llength $argv] == 0} { puts stderr $usage exit 0 } # Want a Tcl version with 3-argument close. package require Tcl 8.6 set ::spellchk "aspell --extra-dicts ./custom.rws list" # Run text through aspell with custom dictionary, return finds. proc misspelled {text} { set spellerr [open "|$::spellchk" r+] puts $spellerr $text flush $spellerr close $spellerr write set huhq [regsub {\s*$} [read $spellerr] {}] close $spellerr read return [split $huhq "\n"] } # Eliminate some common patterns that need not be well spelled. proc decruft {text} { set nopp [regsub -all "\n *#\[^\n\]*\n" $text "\n\n" ] set noticket [regsub -all {Ticket \[?[0-9a-f]+\]?} $nopp "" ] return $noticket } # Sift out common variable spellings not in normal dictionaries. proc varsift {words} { set rv [list] foreach w $words { set n [string length $w] set cr [string range $w 1 end] if {[string tolower $cr] ne $cr} continue lappend rv $w; } return $rv } foreach fname $argv { set ich [open $fname r] set dtext [decruft [read $ich]] close $ich set cbounds [regexp -indices -inline -all {(/\*)|(\*/)} $dtext] set ccb -1 set cblocks [list] foreach {ap cb ce} $cbounds { set cib [lindex $cb 1] set cie [lindex $ce 0] if {$cie != -1} { if {$ccb != -1} { set cce [expr $cie - 1] set destar [string map [list * " "] [string range $dtext $ccb $cce]] lappend cblocks $destar set ccb -1 } else continue } elseif {$cib != -1} { set ccb [expr $cib + 1] } } set oddspells [varsift [misspelled [join $cblocks "\n"]]] if {[llength $oddspells] > 0} { puts "!? Misspellings from $fname:" puts [join [lsort -nocase -unique $oddspells] "\n"] } }