1# The functions in this file were contributed by Dave Grace 2# I have dropped them in here in no particular order 3# NOTE: I broke most of these when I changed the syntax of the 4# search and replace commands -- TMS 5 6# FormatTable 7# 8# Generates C-style data tables. 9# 10# listName is the name of a list variable containing the elements of the table 11# type is the data type (i.e. "unsigned long" or UINT32) 12# tableName is the name of the table in the C program 13# format is the printing format for each element (defaults to "\t%4d") 14# nColumns is the number of columns for the table (defaults to 4) 15proc FormatTable {args} \ 16{ 17 if {[llength $args] > 2} \ 18 { 19 set listName [lindex $args 0] 20 set type [lindex $args 1] 21 set tableName [lindex $args 2] 22 23 if {[llength $args] > 3} \ 24 { 25 set format [lindex $args 3] 26 } \ 27 else \ 28 { 29 set format "\t%4d" 30 } 31 32 if {[llength $args] > 4} \ 33 { 34 set nColumns [lindex $args 4] 35 } \ 36 else \ 37 { 38 set nColumns 4 39 } 40 41 upvar $listName list 42 set listLength [llength $list] 43 set returnString "$type\t$tableName\[$listLength\] = \{\n" 44 set i 0 45 foreach value $list \ 46 { 47 if {[expr $i % $nColumns]==0} \ 48 { 49 append returnString "\t" 50 set trimFormat [string trimleft $format] 51 } \ 52 else \ 53 { 54 set trimFormat $format 55 } 56 append returnString [format $trimFormat $value] 57 58 if {$i < [expr $listLength-1]} \ 59 { 60 append returnString "," 61 } 62 63 if {([expr $i % $nColumns]==[expr $nColumns-1]) || ($i == [expr $listLength-1])} \ 64 { 65 append returnString "\n" 66 } 67 incr i 68 } 69 append returnString "\};\n" 70 } \ 71 else \ 72 { 73 set returnString "Wrong # args: must be \"FormatTable listName type tableName ?format? ?nColumns?\"" 74 } 75 return $returnString 76} 77 78 79# 80# bin2hex.tcl -- 81# 82# Implementation of bin2hex conversions for e93 editor. 83# 84# Copyright (c) 1999 D. Grace 85# 86# See the file "license.txt" for information on usage and redistribution 87# of this file, and for a DISCLAIMER OF ALL WARRANTIES. 88# 89 90package provide hex 1.0 91namespace eval hex { 92 #internal variables 93 94 # exported functions 95 namespace export OpenList 96} 97 98 99# hex::OpenList -- 100# 101# Convert the (binary) contents of a file to a C-style character array, 102# suitable for including from C code. Useful for compiling binaries directly 103# into code to reduce load times. Returns the buffer containing the hex data. 104# 105# Arguments: 106# theBuffer the buffer whose contents to convert. 107# 108# Results: 109# A buffer name, or an error code. 110 111proc hex::OpenList { fileList } { 112 set nFiles [llength $fileList] 113 set fileNum 0 114 set code 0 115 foreach fileName $fileList { 116 # get file size 117 if {![set code [catch {file size $fileName} error]]} { 118 # check if empty file 119 if {[set fileSize $error] > 0} { 120 # open file for reading 121 if {![set code [catch {open $fileName "r"} error]]} { 122 set fd $error 123 # set binary mode to avoid confusion on CR/LF's 124 fconfigure $fd -translation binary 125 # create the buffer for the new file 126 if {![catch {NewWindow} error]} { 127 set theBuffer $error 128 } 129 insert $theBuffer [format "unsigned char %s_data\[\] = \{\n" [file root [file tail $fileName]]] 130 set offset 0 131 while {$offset < $fileSize} { 132 insert $theBuffer [format "\t\""] 133 binary scan [read $fd 32] "H64" data 134 incr offset 32 135 set text "" 136 for {set i 0} {$i < 64} {incr i 2} { 137 append text [format "\\x%s" [string range $data [expr $i] [expr $i+1]]] 138 } 139 insert $theBuffer $text 140 insert $theBuffer [format "\"\n"] 141 } 142 insert $theBuffer [format "\};\n"] 143 close $fd 144 } 145 } else { 146 set error [format "Error: file \"%s\" contains no data" $fileName] 147 set code 1 148 } 149 } 150 if {$code} { 151 if {$fileNum == ($nFiles-1)} { 152 okdialog [format "Failed to open \"%s\":\n%s" $fileName $error] 153 } else { 154 okcanceldialog [format "Failed to open \"%s\":\n%s\n\nContinue?" $fileName $error] 155 } 156 } 157 } 158 if {!$code} { 159 return $theBuffer 160 } 161 error $error 162} 163 164 165 166# add handy menu functions 167addmenu {C} LASTCHILD 1 "Open As Hex..." {} {hex::OpenList [set path [opendialog "Open File As Hex:" $curPath]];set curPath [file dirname [lindex $path 0]]} 168 169 170 171 172 173# 174# brace.tcl -- 175# 176# Implementation of brace matching for e93 editor. 177# 178# Copyright (c) 1998 D. Grace 179# 180# See the file "license.txt" for information on usage and redistribution 181# of this file, and for a DISCLAIMER OF ALL WARRANTIES. 182# 183 184package provide brace 1.0 185namespace eval brace { 186 #internal variables 187 variable Braces 188 variable searchBackwards 0 189 190 # exported functions 191 namespace export MatchBrace 192 namespace export MatchIfDef 193 194 # build up table of braces 195 set Braces(\{.match) \} 196 set Braces(\{.open) 1 197 set Braces(\}.match) \{ 198 set Braces(\}.open) 0 199 set Braces(\(.match) ) 200 set Braces(\(.open) 1 201 set Braces(\).match) ( 202 set Braces(\).open) 0 203 set Braces(\[.match) \] 204 set Braces(\[.open) 1 205 set Braces(\].match) \[ 206 set Braces(\].open) 0 207} 208 209 210# brace::MatchBrace -- 211# 212# If the cursor is next to a curly brace, parenthesis, bracket etc., find 213# the matching brace and move the cursor to it. If no brace, beep. 214# 215# Arguments: 216# theWindow The e93 buffer in which to search. 217# 218# Results: 219# The character index of the matching brace, or -1 if none found. 220 221proc brace::MatchBrace {theWindow} { 222 variable Braces 223 224 set selectionEnds [getselectionends $theWindow] 225 set start [lindex $selectionEnds 0] 226 set end [lindex $selectionEnds 1] 227 if {$start == $end} { 228 # no text is selected, so check for brace next to cursor 229 # brace to the right of cursor gets priority 230 set matchBrace "" 231 setselectionends $theWindow $start [expr $end+1] 232 set selectedText [join [selectedtextlist $theWindow]] 233 if {[regexp {\{|\}|\(|\)|\[|\]} $selectedText brace] != 0} { 234 set matchBrace $Braces($brace.match) 235 set searchForwards $Braces($brace.open) 236 if {$searchForwards} { 237 set searchStart [expr $end+1] 238 } else { 239 set searchStart $start 240 } 241 } else { 242 # check to the left of the cursor 243 setselectionends $theWindow [expr $start-1] $end 244 set selectedText [join [selectedtextlist $theWindow]] 245 if {[regexp {\{|\}|\(|\)|\[|\]} $selectedText brace] != 0} { 246 set matchBrace $Braces($brace.match) 247 set searchForwards $Braces($brace.open) 248 if {$searchForwards} { 249 set searchStart $end 250 } else { 251 set searchStart [expr $start-1] 252 } 253 } 254 } 255 if {$matchBrace != ""} { 256 # found a brace next to the cursor. Now find the matching 257 # brace by searching in the specified direction and counting 258 # brace levels 259 setselectionends $theWindow $searchStart $searchStart 260 TextToBuffer tempFindBuffer "\\$brace|\\$matchBrace" 261 set braceLevel 1 262 while {$braceLevel > 0} { 263 if {[catch {find $theWindow tempFindBuffer [expr !$searchForwards] 0 1 0} message] == 0} { 264 if {$message != -1} { 265 # found a brace 266 set selectedText [join [selectedtextlist $theWindow]] 267 if {$selectedText == $brace} { 268 incr braceLevel 1 269 } elseif {$selectedText == $matchBrace} { 270 incr braceLevel -1 271 } 272 } else { 273 # hit the end of the file 274 break 275 } 276 } 277 } 278 if {$braceLevel == 0} { 279 # found the matching brace, and it's currently selected 280 # set cursor position to the brace 281 set selectionEnds [getselectionends $theWindow] 282 set start [lindex $selectionEnds 0] 283 setselectionends $theWindow $start $start 284 homewindow $theWindow LENIENT 285 return $start 286 } 287 } 288 setselectionends $theWindow $start $end 289 } 290 beep 291 return -1 292} 293 294 295# brace::MatchIfDef -- 296# 297# If the current selection contains a preprocessor directive like #ifdef, find the 298# matching #else or #endif and move the cursor to it. If the selection does not 299# contain a token, find the closest one. If no token found, beep. 300# 301# Arguments: 302# theWindow The e93 buffer in which to search. 303# 304# Results: 305# The character index of the matching token, or -1 if none found. 306 307proc brace::MatchIfDef {theWindow} { 308 variable searchBackwards 309 310 set code 1 311 set selectionEnds [getselectionends $theWindow] 312 set start [lindex $selectionEnds 0] 313 set end [lindex $selectionEnds 1] 314 set searchExp "^\[ \t\]*#\[ \t\]*(if|else|endif)" 315 TextToBuffer tempFindBuffer $searchExp 316 if {[regexp $searchExp [string tolower [join [selectedtextlist $theWindow]]] match token]} { 317 # the current selection contains a token - find its match if possible 318 if {$token == "if"} { 319 set searchBackwards 0 320 } elseif {$token == "endif"} { 321 set searchBackwards 1 322 } else { 323 # found an "else": search in whatever direction was searched last 324 } 325 set code 0 326 set level 1 327 while {(!$code) && ($level>0)} { 328 if {[catch {find $theWindow tempFindBuffer $searchBackwards 0 1 1} message] == 0} { 329 if {$message != -1} { 330 # found a token 331 regexp $searchExp [string tolower [join [selectedtextlist $theWindow]]] match token 332 if {$token == "else"} { 333 if {$level == 1} { 334 break 335 } 336 } else { 337 if {!$searchBackwards} { 338 if {$token == "if"} { 339 incr level 1 340 } else { 341 incr level -1 342 } 343 } else { 344 if {$token == "if"} { 345 incr level -1 346 } else { 347 incr level 1 348 } 349 } 350 } 351 } else { 352 # hit the end of the file 353 set code 1 354 } 355 } 356 } 357 if {!$code} { 358 if {$token == "if"} { 359 set searchBackwards 0 360 } elseif {$token == "endif"} { 361 set searchBackwards 1 362 } else { 363 # found an "else": search in whatever direction was searched last 364 } 365 } 366 } else { 367 # no token in the current selection, so find the nearest one (try forward first) 368 if {(![catch {find $theWindow tempFindBuffer 0 0 1 1} message]) && ($message!=-1)} { 369 set code 0 370 } elseif {(![catch {find $theWindow tempFindBuffer 1 0 1 1} message]) && ($message!=-1)} { 371 set code 0 372 } 373 if {!$code} { 374 regexp $searchExp [string tolower [join [selectedtextlist $theWindow]]] match token 375 if {$token == "if"} { 376 set searchBackwards 0 377 } elseif {$token == "endif"} { 378 set searchBackwards 1 379 } else { 380 # found an "else": search in whatever direction was searched last 381 } 382 } 383 } 384 if {!$code} { 385 # set cursor position to the token 386 homewindow $theWindow LENIENT 387 return $start 388 } 389 setselectionends $theWindow $start $end 390 beep 391 return -1 392} 393 394 395# Bind keys to various useful things. 396# l=caps lock, s=shift, c=control, 0-7 are additional modifiers such as command, alt, option, command, etc... 397# Bind flags lsc01234567 (x means don't care, 0 means not pressed, 1 means pressed) 398 399bindkey bracketleft {x0100000000} {brace::MatchBrace [ActiveWindowOrBeep]} 400bindkey bracketright {x0100000000} {brace::MatchBrace [ActiveWindowOrBeep]} 401bindkey bracketleft {x1100000000} {brace::MatchIfDef [ActiveWindowOrBeep]} 402bindkey bracketright {x1100000000} {brace::MatchIfDef [ActiveWindowOrBeep]} 403 404 405 406############################################################################## 407############################################################################## 408############################################################################## 409 410# new updated bracketing stuff 411 412############################################################################## 413############################################################################## 414############################################################################## 415 416 417# 418# brace.tcl -- 419# 420# Implementation of brace matching for e93 editor. 421# 422# Copyright (c) 1998 D. Grace 423# 424# See the file "license.txt" for information on usage and redistribution 425# of this file, and for a DISCLAIMER OF ALL WARRANTIES. 426# 427 428package provide brace 1.0 429namespace eval brace { 430 #internal variables 431 variable Braces 432 variable searchBackwards 0 433 434 # exported functions 435 namespace export MatchBrace 436 namespace export MatchIfDef 437 438 # build up table of braces 439 set Braces(\{.match) \} 440 set Braces(\{.open) 1 441 set Braces(\}.match) \{ 442 set Braces(\}.open) 0 443 set Braces(\(.match) ) 444 set Braces(\(.open) 1 445 set Braces(\).match) ( 446 set Braces(\).open) 0 447 set Braces(\[.match) \] 448 set Braces(\[.open) 1 449 set Braces(\].match) \[ 450 set Braces(\].open) 0 451} 452 453 454# brace::MatchBrace -- 455# 456# If the cursor is next to a curly brace, parenthesis, bracket etc., find 457# the matching brace and move the cursor to it. If no brace, beep. 458# 459# Arguments: 460# theWindow The e93 buffer in which to search. 461# 462# Results: 463# The character index of the matching brace, or -1 if none found. 464 465proc brace::MatchBrace {theWindow} { 466 variable Braces 467 468 set selectionEnds [getselectionends $theWindow] 469 set start [lindex $selectionEnds 0] 470 set end [lindex $selectionEnds 1] 471 if {$start == $end} { 472 # no text is selected, so check for brace next to cursor 473 # brace to the right of cursor gets priority 474 set matchBrace "" 475 setselectionends $theWindow $start [expr $end+1] 476 set selectedText [join [selectedtextlist $theWindow]] 477 if {[regexp {\{|\}|\(|\)|\[|\]} $selectedText brace] != 0} { 478 set matchBrace $Braces($brace.match) 479 set searchForwards $Braces($brace.open) 480 if {$searchForwards} { 481 set searchStart [expr $end+1] 482 } else { 483 set searchStart $start 484 } 485 } else { 486 # check to the left of the cursor 487 setselectionends $theWindow [expr $start-1] $end 488 set selectedText [join [selectedtextlist $theWindow]] 489 if {[regexp {\{|\}|\(|\)|\[|\]} $selectedText brace] != 0} { 490 set matchBrace $Braces($brace.match) 491 set searchForwards $Braces($brace.open) 492 if {$searchForwards} { 493 set searchStart $end 494 } else { 495 set searchStart [expr $start-1] 496 } 497 } 498 } 499 if {$matchBrace != ""} { 500 # found a brace next to the cursor. Now find the matching 501 # brace by searching in the specified direction and counting 502 # brace levels 503 setselectionends $theWindow $searchStart $searchStart 504 TextToBuffer tempFindBuffer "\\$brace|\\$matchBrace" 505 set braceLevel 1 506 while {$braceLevel > 0} { 507 set findArgs "-regex" 508 if {!$searchForwards} { 509 append findArgs " -backward" 510 } 511 if {[catch {eval find \$theWindow tempFindBuffer $findArgs} message] == 0} { 512 if {$message != -1} { 513 # found a brace 514 set selectedText [join [selectedtextlist $theWindow]] 515 if {$selectedText == $brace} { 516 incr braceLevel 1 517 } elseif {$selectedText == $matchBrace} { 518 incr braceLevel -1 519 } 520 } else { 521 # hit the end of the file 522 break 523 } 524 } 525 } 526 if {$braceLevel == 0} { 527 # found the matching brace, and it's currently selected 528 # set cursor position to the brace 529 set selectionEnds [getselectionends $theWindow] 530 set start [lindex $selectionEnds 0] 531 setselectionends $theWindow $start $start 532 eval homewindow \$theWindow [getselectionends $theWindow] -lenient 533 return $start 534 } 535 } 536 setselectionends $theWindow $start $end 537 } 538 beep 539 return -1 540} 541 542 543# brace::MatchIfDef -- 544# 545# If the current selection contains a preprocessor directive like #ifdef, find the 546# matching #else or #endif and move the cursor to it. If the selection does not 547# contain a token, find the closest one. If no token found, beep. 548# 549# Arguments: 550# theWindow The e93 buffer in which to search. 551# 552# Results: 553# The character index of the matching token, or -1 if none found. 554 555proc brace::MatchIfDef {theWindow} { 556 variable searchBackwards 557 558 set code 1 559 set selectionEnds [getselectionends $theWindow] 560 set start [lindex $selectionEnds 0] 561 set end [lindex $selectionEnds 1] 562 set searchExp "^\[ \t\]*#\[ \t\]*(if|else|endif)" 563 TextToBuffer tempFindBuffer $searchExp 564 if {[regexp $searchExp [string tolower [join [selectedtextlist $theWindow]]] match token]} { 565 # the current selection contains a token - find its match if possible 566 if {$token == "if"} { 567 set searchBackwards 0 568 } elseif {$token == "endif"} { 569 set searchBackwards 1 570 } else { 571 # found an "else": search in whatever direction was searched last 572 } 573 set code 0 574 set level 1 575 while {(!$code) && ($level>0)} { 576 set findArgs "-regex -ignorecase" 577 if {$searchBackwards} { 578 append findArgs " -backward" 579 } 580 if {[catch {find $theWindow tempFindBuffer $findArgs} message] == 0} { 581 if {$message != -1} { 582 # found a token 583 regexp $searchExp [string tolower [join [selectedtextlist $theWindow]]] match token 584 if {$token == "else"} { 585 if {$level == 1} { 586 break 587 } 588 } else { 589 if {!$searchBackwards} { 590 if {$token == "if"} { 591 incr level 1 592 } else { 593 incr level -1 594 } 595 } else { 596 if {$token == "if"} { 597 incr level -1 598 } else { 599 incr level 1 600 } 601 } 602 } 603 } else { 604 # hit the end of the file 605 set code 1 606 } 607 } 608 } 609 if {!$code} { 610 if {$token == "if"} { 611 set searchBackwards 0 612 } elseif {$token == "endif"} { 613 set searchBackwards 1 614 } else { 615 # found an "else": search in whatever direction was searched last 616 } 617 } 618 } else { 619 # no token in the current selection, so find the nearest one (try forward first) 620 if {(![catch {find $theWindow tempFindBuffer -regex -ignorecase} message]) && ($message!=-1)} { 621 set code 0 622 } elseif {(![catch {find $theWindow tempFindBuffer -backward -regex -ignorecase} message]) && ($message!=-1)} { 623 set code 0 624 } 625 if {!$code} { 626 regexp $searchExp [string tolower [join [selectedtextlist $theWindow]]] match token 627 if {$token == "if"} { 628 set searchBackwards 0 629 } elseif {$token == "endif"} { 630 set searchBackwards 1 631 } else { 632 # found an "else": search in whatever direction was searched last 633 } 634 } 635 } 636 if {!$code} { 637 # set cursor position to the token 638 eval homewindow \$theWindow [getselectionends $theWindow] -lenient 639 return $start 640 } 641 setselectionends $theWindow $start $end 642 beep 643 return -1 644} 645