summaryrefslogtreecommitdiff
path: root/gdb/gdbtk/library/targetselection.itb
blob: 959b51a7a6861e2225cea7c2f5bf6e60af0fb7cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
# Target selection dialog for Insight.
# Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License (GPL) as published by
# the Free Software Foundation; either version 2 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.


# ----------------------------------------------------------------------
# Implements GDB TargetSelection dialog
# ----------------------------------------------------------------------

# ------------------------------------------------------------------
#  CONSTRUCTOR - create new target selection window
# ------------------------------------------------------------------
itcl::body TargetSelection::constructor {args} {
  eval itk_initialize $args
  set top [winfo toplevel $itk_interior]
  _init
  build_win
}

itcl::body TargetSelection::getname {target name} {

  # Init target database if we haven't already done so
  init_target_db

  if {[info exists gdb_target($target,$name)]} {
    return $gdb_target($target,$name)
  } else {
    return ""
  }
}

itcl::body TargetSelection::init_target_db {} {
  # check to see if we already initialized this database
  if {$db_inited} { 
    return 
  }
  set db_inited 1

  # Target Database
  # Set the following members:
  # TARGET,pretty-name: Name to display to user
  # TARGET,debaud: Default baudrate
  # TARGET,baud-rates: Permissible baudrates
  # TARGET,cmd: Abstracted command to run for this target (tcpX and com1 are
  #          replaced with the real port and host/port in set_target)
  # TARGET,runlist: List of preferences for the target: {attach download run cont}
  # TARGET,after_attaching: a command to run after attaching to the target

  # Default target
  set gdb_target(default,pretty-name) "Default"
  set gdb_target(default,defbaud) ""
  set gdb_target(default,baud-rates) {}
  set gdb_target(default,cmd) ""
  set gdb_target(default,runlist) {0 0 1 0}
  set gdb_target(default,options) ""
  set gdb_target(default,after_attaching) {}

  # Exec target
  set gdb_target(exec,pretty-name) "Exec"
  set gdb_target(exec,defbaud) ""
  set gdb_target(exec,baud-rates) {}
  set gdb_target(exec,cmd) ""
  set gdb_target(exec,runlist) {0 0 1 0}
  set gdb_target(exec,options) ""
  set gdb_target(exec,after_attaching) {}

  # ADS board w/SDS protocol
  set gdb_target(sds,pretty-name) "SDS"
  set gdb_target(sds,defbaud) "38400"
  set gdb_target(sds,baud-rates) {9600 38400}
  set gdb_target(sds,cmd) "sds com1"
  set gdb_target(sds,runlist) {1 1 0 1}
  set gdb_target(sds,after_attaching) {}

  # Simulator
  set gdb_target(sim,pretty-name) "Simulator"
  set gdb_target(sim,defbaud) ""
  set gdb_target(sim,baud-rates) {}
  set gdb_target(sim,cmd) "sim"
  set gdb_target(sim,runlist) {1 1 1 0}
  set gdb_target(sim,options) ""
  set gdb_target(sim,after_attaching) {}

  # Remote
  set gdb_target(remote,pretty-name) "Remote/Serial"
  set gdb_target(remote,defbaud) "9600"
  set gdb_target(remote,baud-rates) {9600 19200 38400 57600 115200}
  set gdb_target(remote,cmd) "remote com1"
  set gdb_target(remote,runlist) {1 1 0 1}
  set gdb_target(remote,after_attaching) {}
  set gdb_target(remotetcp,pretty-name) "Remote/TCP"
  set gdb_target(remotetcp,defbaud) "TCP"
  set gdb_target(remotetcp,baud-rates) {}
  set gdb_target(remotetcp,cmd) "remote tcpX"
  set gdb_target(remotetcp,runlist) {1 1 0 1}
  set gdb_target(remotetcp,after_attaching) {}

  # ARM Angel
  set gdb_target(rdi,pretty-name) "ARM Angel/Serial"
  set gdb_target(rdi,defbaud) "9600"
  set gdb_target(rdi,baud-rates) {9600 19200 38400 57600 115200}
  set gdb_target(rdi,cmd) "rdi com1"
  set gdb_target(rdi,runlist) {1 1 0 1}
  set gdb_target(rdi,after_attaching) {}

  # ARM Angel/Ethernet
  set gdb_target(rditcp,pretty-name) "ARM Angel/Ethernet"
  set gdb_target(rditcp,defbaud) "ETH"
  set gdb_target(rditcp,baud-rates) {}
  set gdb_target(rditcp,cmd) "rdi ethX"
  set gdb_target(rditcp,runlist) {1 1 0 1}
  set gdb_target(rditcp,after_attaching) {}

  # ARM Remote
  set gdb_target(rdp,pretty-name) "ARM Remote/Serial"
  set gdb_target(rdp,defbaud) "9600"
  set gdb_target(rdp,baud-rates) {9600}
  set gdb_target(rdp,cmd) "rdp com1"
  set gdb_target(rdp,runlist) {1 1 0 1}
  set gdb_target(rdp,after_attaching) {}
  set gdb_target(rdptcp,pretty-name) "ARM Remote/TCP"
  set gdb_target(rdptcp,defbaud) "TCP"
  set gdb_target(rdptcp,baud-rates) {}
  set gdb_target(rdptcp,cmd) "rdp tcpX"
  set gdb_target(rdptcp,runlist) {1 1 0 1}
  set gdb_target(rdptcp,after_attaching) {}

  # m32r rev C
  set gdb_target(m32r,pretty-name) "M32R/Serial"
  set gdb_target(m32r,defbaud) "9600"
  set gdb_target(m32r,baud-rates) {9600}
  set gdb_target(m32r,cmd) "m32r com1"
  set gdb_target(m32r,runlist) {1 1 0 1}
  set gdb_target(m32r,after_attaching) {}
  set gdb_target(m32rtcp,pretty-name) "M32R/TCP"
  set gdb_target(m32rtcp,defbaud) "TCP"
  set gdb_target(m32rtcp,baud-rates) {}
  set gdb_target(m32rtcp,cmd) "m32r tcpX"
  set gdb_target(m32rtcp,runlist) {1 1 0 1}
  set gdb_target(m32rtcp,after_attaching) {}

  # m32r msa2000
  set gdb_target(mon2000,pretty-name) "MON2000/Serial"
  set gdb_target(mon2000,defbaud) "9600"
  set gdb_target(mon2000,baud-rates) {9600}
  set gdb_target(mon2000,cmd) "mon2000 com1"
  set gdb_target(mon2000,runlist) {1 1 0 1}
  set gdb_target(mon2000,after_attaching) {}
  set gdb_target(mon2000tcp,pretty-name) "MON2000/TCP"
  set gdb_target(mon2000tcp,defbaud) "TCP"
  set gdb_target(mon2000tcp,baud-rates) {}
  set gdb_target(mon2000tcp,cmd) "mon2000 tcpX"
  set gdb_target(mon2000tcp,runlist) {1 1 0 1}
  set gdb_target(mon2000tcp,after_attaching) {}

  # sparclite
  set gdb_target(sparclite,pretty-name) "SPARClite/Serial"
  set gdb_target(sparclite,defbaud) "9600"
  set gdb_target(sparclite,baud-rates) {9600}
  set gdb_target(sparclite,cmd) "sparclite com1"
  set gdb_target(sparclite,runlist) {1 1 0 1}
  set gdb_target(sparclite,after_attaching) {}
  set gdb_target(sparclitetcp,pretty-name) "SPARClite/TCP"
  set gdb_target(sparclitetcp,defbaud) "TCP"
  set gdb_target(sparclitetcp,baud-rates) {}
  set gdb_target(sparclitetcp,cmd) "sparclite tcpX"
  set gdb_target(sparclitetcp,runlist) {1 1 0 1}
  set gdb_target(sparclitetcp,after_attaching) {}

  # V850 ICE
  set gdb_target(ice,pretty-name) "V850 ICE"
  set gdb_target(ice,defbaud) ""
  set gdb_target(ice,baud-rates) {}
  set gdb_target(ice,cmd) "ice"
  set gdb_target(ice,runlist) {1 1 0 1}
  set gdb_target(ice,after_attaching) {}

  # MIPS
  set gdb_target(mips,pretty-name) "MIPS/Serial"
  set gdb_target(mips,defbaud) "9600"
  set gdb_target(mips,baud-rates) {9600}
  set gdb_target(mips,cmd) "mips com1"
  set gdb_target(mips,runlist) {1 1 0 1}
  set gdb_target(mips,after_attaching) {}
  set gdb_target(mipstcp,pretty-name) "MIPS/TCP"
  set gdb_target(mipstcp,defbaud) "TCP"
  set gdb_target(mipstcp,baud-rates) {}
  set gdb_target(mipstcp,cmd) "mips tcpX"
  set gdb_target(mipstcp,runlist) {1 1 0 1}
  set gdb_target(mipstcp,after_attaching) {}

  # PMON
  set gdb_target(pmon,pretty-name) "PMON/Serial"
  set gdb_target(pmon,defbaud) "9600"
  set gdb_target(pmon,baud-rates) {9600 19200 38400}
  set gdb_target(pmon,cmd) "pmon com1"
  set gdb_target(pmon,runlist) {1 1 0 1}
  set gdb_target(pmon,after_attaching) {}
  set gdb_target(pmontcp,pretty-name) "PMON/TCP"
  set gdb_target(pmontcp,defbaud) "TCP"
  set gdb_target(pmontcp,baud-rates) {}
  set gdb_target(pmontcp,cmd) "pmon tcpX"
  set gdb_target(pmontcp,runlist) {1 1 0 1}
  set gdb_target(pmontcp,after_attaching) {}

  # DDB
  set gdb_target(ddb,pretty-name) "DDB/Serial"
  set gdb_target(ddb,defbaud) "19200"
  set gdb_target(ddb,baud-rates) {9600 19200 38400}
  set gdb_target(ddb,cmd) "ddb com1"
  set gdb_target(ddb,runlist) {1 1 0 1}
  set gdb_target(ddb,after_attaching) {}
  set gdb_target(ddbtcp,pretty-name) "DDB/TCP"
  set gdb_target(ddbtcp,defbaud) "TCP"
  set gdb_target(ddbtcp,baud-rates) {}
  set gdb_target(ddbtcp,cmd) "ddb tcpX"
  set gdb_target(ddbtcp,runlist) {1 1 0 1}
  set gdb_target(ddbtcp,after_attaching) {}

  # Picobug
  set gdb_target(picobug,pretty-name) "Picobug/Serial"
  set gdb_target(picobug,defbaud) "19200"
  set gdb_target(picobug,baud-rates) {19200}
  set gdb_target(picobug,cmd) "picobug com1"
  set gdb_target(picobug,runlist) {1 1 0 1}
  set gdb_target(picobug,after_attaching) {}
  set gdb_target(picobugtcp,pretty-name) "Picobug/TCP"
  set gdb_target(picobugtcp,defbaud) "TCP"
  set gdb_target(picobugtcp,baud-rates) {}
  set gdb_target(picobugtcp,cmd) "picobug tcpX"
  set gdb_target(picobugtcp,runlist) {1 1 0 1}
  set gdb_target(picobugtcp,after_attaching) {}

  # Cisco.
  set gdb_target(cisco,pretty-name) "Cisco/Serial"
  set gdb_target(cisco,defbaud) "38400"
  set gdb_target(cisco,baud-rates) {9600 19200 38400 56000}
  set gdb_target(cisco,cmd) "cisco com1"
  set gdb_target(cisco,runlist) {1 0 0 0}
  set gdb_target(cisco,after_attaching) "set os cisco"
  set gdb_target(ciscotcp,pretty-name) "Cisco/TCP"
  set gdb_target(ciscotcp,defbaud) "TCP"
  set gdb_target(ciscotcp,baud-rates) {}
  set gdb_target(ciscotcp,cmd) "cisco tcpX"
  set gdb_target(ciscotcp,runlist) {1 0 0 0}
  set gdb_target(ciscotcp,after_attaching) "set os cisco"

  # VxWorks
  set gdb_target(vxworks,pretty-name) "VxWorks RDB"
  set gdb_target(vxworks,defbaud) "ETH"
  set gdb_target(vxworks,baud-rates) {}
  set gdb_target(vxworks,cmd) "vxworks ethX"
  set gdb_target(vxworks,runlist) { 1 0 1 1}
  set gdb_target(vxworks,after_attaching) { sym vxWorks.st }

  # GDBServer, libremote, rda, etc
  set gdb_target(gdbserver,pretty-name) "GDBserver"
  set gdb_target(gdbserver,pretty-name) "GDBserver/Serial"
  set gdb_target(gdbserver,defbaud) "9600"
  set gdb_target(gdbserver,baud-rates) {9600 19200 38400 57600 115200}
  set gdb_target(gdbserver,cmd) "remote com1"
  set gdb_target(gdbserver,runlist) {1 0 0 1}
  set gdb_target(gdbserver,after_attaching) {}
  set gdb_target(gdbservertcp,pretty-name) "GDBserver/TCP"
  set gdb_target(gdbservertcp,defbaud) "TCP"
  set gdb_target(gdbservertcp,baud-rates) {}
  set gdb_target(gdbservertcp,cmd) "remote tcpX"
  set gdb_target(gdbservertcp,runlist) {1 0 0 1}
  set gdb_target(gdbservertcp,after_attaching) {}
}

itcl::body TargetSelection::default_port {} {
  global tcl_platform
  switch -regexp $tcl_platform(os) {
    Windows { set port com1 }
    Linux   { set port /dev/ttyS0 }
    SunOS   { set port /dev/ttya }
    AIX     { set port /dev/foo1 }
    ULTRIX  { set port /dev/foo1 }
    IRIX    { set port /dev/foo1 }
    OSF1    { set port /dev/foo1 }
    NetBSD  { set port /dev/foo1 }
    HP-UX   { 
      # Special case...
      switch -regexp $tcl_platform(osVersion) {
	A.09 { set port /dev/tty00 }
	B.10 -
	B.11 { set port /dev/tty0p0 }
      }
    }
    default { set port /dev/ttya }
  }
  
  return $port
}


itcl::body TargetSelection::_init_prefs {} {

  if {$prefs_inited} {
    return
  }
  set prefs_inited 1

  # these are not target-specific

  pref define gdb/load/main 1
  pref define gdb/load/exit 1
  pref define gdb/load/check 0

  # these are target-specific
  # set up the defaults
  pref define gdb/load/default-verbose 0
  pref define gdb/load/default-port [default_port]
  pref define gdb/load/default-hostname ""
  pref define gdb/load/default-after_attaching {}
}

itcl::body TargetSelection::_init_target {} {
  global gdb_target_name
  set target_list [get_target_list]
  set target $gdb_target_name

  # target = CANCEL should never come into here.  If the target was
  # returned as CANCEL, it should be fixed by the caller...  But it
  # should not be harmful if it gets in here.

  if {$target == "" || [string compare $target CANCEL] == 0} {
    set target default
  }
    
  set defbaud $gdb_target($target,defbaud)
  pref define gdb/load/$target-baud $defbaud
  pref define gdb/load/$target-port [pref get gdb/load/default-port]
  pref define gdb/load/$target-verbose [pref get gdb/load/default-verbose]
  pref define gdb/load/$target-portname 1000
  pref define gdb/load/$target-hostname [pref get gdb/load/default-hostname]
  
  set err [catch {pref get gdb/load/$target-runlist} run_list]
  if {$err} {
    set run_list $gdb_target($target,runlist)
    pref setd gdb/load/$target-runlist $run_list
  }
  pref set gdb/src/run_attach [lindex $run_list 0]
  pref set gdb/src/run_load   [lindex $run_list 1]
  pref set gdb/src/run_run    [lindex $run_list 2]
  pref set gdb/src/run_cont   [lindex $run_list 3]
  
  set err [catch {pref get gdb/load/$target-after_attaching} aa]
  if {$err} {
    set aa $gdb_target($target,after_attaching)
    pref setd gdb/load/$target-after_attaching $aa
  }
}

itcl::body TargetSelection::_init {} {

  if {!$trace_inited} {
    # Trace all gdb_loaded changes based on target
    trace variable gdb_loaded w [code TargetSelection::target_trace]
  }
  set trace_inited 1

  init_target_db	;# initialize database
  _init_prefs	;# initialize load prefs 
  _init_target	;# initialize target prefs
  set_saved

  # This tells us that the target system is inited.  Some of these
  # init functions need to be called every time the target dialog is
  # posted, some only once.  The latter functions can check inited to
  # see what they should do.

}

# ------------------------------------------------------------------
#  METHOD:  build_win - build the dialog
# ------------------------------------------------------------------
itcl::body TargetSelection::build_win {} {
  global tcl_platform PREFS_state gdb_ImageDir gdb_target_name

  set f [frame $itk_interior.f]
  set opts [frame $itk_interior.moreoptions]
  frame $itk_interior.moreoptionsframe
  set btns [frame $itk_interior.buttons]

  #labelled frame "Connection"
  iwidgets::Labeledframe $f.lab -labelpos nw -labeltext [gettext "Connection"]
  set fr [$f.lab childsite]

  # target name
  label $fr.tarl -text [gettext "Target:"]
  combobox::combobox $fr.tar -editable 0 -command [code $this change_target] \
    -width $Width -maxheight 10 -bg $::Colors(textbg)

  # baud rate combobox
  label $fr.cbl -text [gettext "Baud Rate:"]
  combobox::combobox $fr.cb -editable 0 -command [code $this change_baud] \
    -textvariable [pref varname gdb/load/$target-baud] -width $Width \
    -maxheight 10 -bg $::Colors(textbg)

  if {[catch {gdb_cmd "show remotebaud"} res]} {
    set baud [pref get gdb/load/$target-baud]
  } else {
    set baud [lindex $res end]
    set baud [string trimright $baud "."]
    # When uninitialized, GDB returns a baud rate of 2^32
    # Detect this and ignore it.
    if {$baud > 4000000000} {
      set baud [pref get gdb/load/$target-baud]
    } else {
      pref setd gdb/load/$target-baud $baud
    }
  }

  # host entry widget
  entry $fr.host -textvariable [pref varname gdb/load/$target-hostname] \
    -width $Width

  # port combobox
  if {$tcl_platform(platform) == "windows"} {
    set editable 0
  } else {
    set editable 1
  }

  label $fr.portl -text [gettext "Port:"]
  combobox::combobox $fr.port -editable $editable \
    -textvariable [pref varname gdb/load/$target-port] \
    -width $Width -maxheight 10 -bg $::Colors(textbg)

  # load baud rates into combobox
  fill_rates

  # load port combobox
  if {$tcl_platform(platform) == "windows"} {
    foreach val [port_list] {
      $fr.port list insert end $val
    }
  } else {
    # fixme:  how do I find valid values for these????
    switch $tcl_platform(os) {
      Linux { set ports [list /dev/cua0 /dev/ttyS0 /dev/ttyS1 /dev/ttyS2 /dev/ttyS3]}
      SunOS { set ports [list /dev/ttya /dev/ttyb] }
      AIX   { set ports [list /dev/foo1 /dev/foo2] }
      ULTRIX { set ports [list /dev/foo1 /dev/foo2] }
      IRIX   { set ports [list /dev/foo1 /dev/foo2] }
      OSF1   { set ports [list /dev/foo1 /dev/foo2] }
      NetBSD { set ports [list /dev/foo1 /dev/foo2] }
      HP-UX  { 
	# Special case...
	switch -regexp $tcl_platform(osVersion) {
	  A.09 { set ports [list /dev/tty00 /dev/tty01] }
	  B.10 -
	  B.11 { set ports [list /dev/tty0p0 /dev/tty1p0] }
	}
      }
      default { set ports [list UNKNOWN UNKNOWN] }
    }
    foreach val $ports {
      $fr.port list insert end $val
    }
  }

  # Port entry widget
  entry $fr.porte -textvariable [pref varname gdb/load/$target-port] -width $Width

  frame $f.fr
  checkbutton $f.fr.main -text [gettext "Set breakpoint at 'main'"] \
    -variable [pref varname gdb/load/main]
  checkbutton $f.fr.exit -text [gettext "Set breakpoint at 'exit'"] \
    -variable [pref varname gdb/load/exit]
  frame $f.fr.bp
  checkbutton $f.fr.bp.at_func -text [gettext "Set breakpoint at"] \
    -variable [pref varname gdb/load/bp_at_func]
  entry $f.fr.bp.func -textvariable [pref varname gdb/load/bp_func] -width 20
  checkbutton $f.fr.verb -text [gettext "Display Download Dialog"] \
    -variable [pref varname gdb/load/$target-verbose]
  checkbutton $f.fr.xterm -text [gettext "Use xterm as inferior's tty"] \
    -variable [pref varname gdb/process/xtermtty] \
    -onvalue yes -offvalue no

  if {![pref get gdb/control_target]} {
    $f.fr.main configure -state disabled
    $f.fr.exit configure -state disabled
    $f.fr.verb configure -state disabled
    $f.fr.bp.at_func configure -state disabled
    $f.fr.bp.func configure -state disabled
    checkbutton $f.fr.check -text [gettext "Compare to remote executable"] \
      -variable [pref varname gdb/load/check]
    if { $gdb_target_name == "exec" } {
      $f.fr.check configure -state disabled
    }
  }

  grid $fr.tarl $fr.tar -sticky w -padx 5 -pady 5
  grid $fr.cbl $fr.cb -sticky w -padx 5 -pady 5
  grid $fr.portl $fr.port -sticky w -padx 5 -pady 5
  set mapped1 $fr.cb
  set mapped2 $fr.port

  grid $f.fr.main -sticky w -padx 5 -pady 5
  grid $f.fr.exit -sticky w -padx 5 -pady 5
  pack $f.fr.bp.at_func $f.fr.bp.func -side left
  grid $f.fr.bp -sticky w -padx 5 -pady 5
  grid $f.fr.verb -sticky w -padx 5 -pady 5
  grid $f.fr.xterm -sticky w -padx 5 -pady 5
  if {![pref get gdb/control_target]} {
    grid $f.fr.check -sticky w -padx 5 -pady 5
  }

  grid $f.lab $f.fr -sticky w -padx 5 -pady 5

  # Create the "More Options" thingy
  if {[lsearch [image names] _MORE_] == -1} {
    image create photo _MORE_ -file [file join $gdb_ImageDir more.gif]
    image create photo _LESS_ -file [file join $gdb_ImageDir less.gif]
  }

  set MoreButton [button $opts.button -image _MORE_ \
		    -relief flat -command [code $this toggle_more_options]]
  set MoreLabel [label $opts.lbl -text {More Options}]
  frame $opts.frame -relief raised -bd 1
  pack $opts.button $opts.lbl -side left
  place $opts.frame -relx 1 -x -10 -rely 0.5 -relwidth 0.73 -height 2 -anchor e

  # Create the (hidden) more options frame
  set MoreFrame [iwidgets::Labeledframe $itk_interior.moreoptionsframe.frame \
		   -labelpos nw -labeltext {Run Options}]
  set frame [$MoreFrame childsite]

  set var [pref varname gdb/src/run_attach]
  checkbutton $frame.attach -text {Attach to Target} -variable $var

  set var [pref varname gdb/src/run_load]
  checkbutton $frame.load -text {Download Program} -variable $var

  set rm_frame [iwidgets::labeledframe $frame.run_method -labelpos nw -labeltext "Run Method" ]
  set RunMethod [ $rm_frame childsite ]

  set var [pref varname gdb/src/run_cont]
  radiobutton $RunMethod.cont -text {Continue from Last Stop} -value 1 -variable $var \
    -command [code $this set_run run]
  
  set var [pref varname gdb/src/run_run]
  radiobutton $RunMethod.run -text {Run Program} -value 1 -variable $var \
    -command [code $this set_run cont]

  # The after attaching command entry
  set _after_entry [entry $frame.aftere]
  label $frame.afterl -text {Command to issue after attaching:}

  grid $frame.attach -column 0 -row 1 -padx 10 -sticky w
  grid $frame.load -column 0 -row 2 -padx 10 -sticky w

  grid $RunMethod.run -column 0 -row 1 -sticky w -ipady 2
  grid $RunMethod.cont -column 0 -row 2 -sticky w -ipady 2
  
  grid $rm_frame -column 1 -row 1 -rowspan 2 -sticky nsew -ipady 2

  grid $frame.afterl -row 4 -sticky we -columnspan 2 -ipady 2
  grid $frame.aftere -sticky we -columnspan 2 -ipady 2
  grid columnconfigure $frame 0 -weight 1
  grid columnconfigure $frame 1 -weight 1

  # Map everything onto the screen
  # This looks like a possible packing bug -- our topmost frame
  # will not resize itself. So, instead, use the topmost frame.
  #pack $f $opts $itk_interior.moreoptionsframe -side top -fill x
  pack $MoreFrame -fill x -expand yes
  pack $f $opts -side top -fill x

  change_target $gdb_target($target,pretty-name)

  button $btns.ok -text [gettext OK] -width 7 -command [code $this save] \
    -default active
  button $btns.cancel -text [gettext Cancel] -width 7 \
    -command [code $this cancel]
  button $btns.help -text [gettext Help] -width 7 -command [code $this help] \
    -state disabled
  standard_button_box $btns
  bind $btns.ok <Return> "$btns.ok flash; $btns.ok invoke"
  bind $btns.cancel <Return> "$btns.cancel flash; $btns.cancel invoke"
  bind $btns.help <Return> "$btns.help flash; $btns.help invoke"

  pack $btns -side bottom -anchor e
  focus $btns.ok
  
  # set up balloon help
  balloon register $f.fr.bp.at_func "Set User-Speficied Breakpoints at Run Time"
  balloon register $f.fr.bp.func "Enter a List of Functions for Breakpoints"

  window_name "Target Selection"

  if {[valid_target $target]} {
    $fr.tar configure -value $gdb_target($target,pretty-name)
  }
  fill_targets


}

# ------------------------------------------------------------------
#  METHOD:  set_saved - set saved values
# ------------------------------------------------------------------
itcl::body TargetSelection::set_saved {} {
  set saved_baud [pref get gdb/load/$target-baud]
  set saved_port [pref get gdb/load/$target-port]
  set saved_main [pref get gdb/load/main]
  set saved_exit [pref get gdb/load/exit]
  set saved_check [pref get gdb/load/check]
  set saved_verb [pref get gdb/load/$target-verbose]
  set saved_portname [pref get gdb/load/$target-portname]
  set saved_hostname [pref get gdb/load/$target-hostname]
  set saved_attach [pref get gdb/src/run_attach]
  set saved_load   [pref get gdb/src/run_load]
  set saved_run    [pref get gdb/src/run_run]
  set saved_cont   [pref get gdb/src/run_cont]
  if {[info exists gdb_target($target,options)]} {
    if {[catch {pref get gdb/load/$target-opts} saved_options]} {
      set saved_options ""
    }
  }
}

# ------------------------------------------------------------------
#  METHOD:  write_saved - write saved values to preferences
# ------------------------------------------------------------------
itcl::body TargetSelection::write_saved {} {
  pref setd gdb/load/$target-baud $saved_baud
  pref setd gdb/load/$target-port $saved_port
  pref setd gdb/load/main $saved_main
  pref setd gdb/load/exit $saved_exit
  pref setd gdb/load/check $saved_check
  pref setd gdb/load/$target-verbose $saved_verb
  pref setd gdb/load/$target-portname $saved_portname
  pref setd gdb/load/$target-hostname $saved_hostname
  pref setd gdb/load/$target-runlist [list $saved_attach $saved_load $saved_run $saved_cont]
  if {[info exists gdb_target($target,options)]} {
    pref setd gdb/load/$target-opts $saved_options
  }
  if {[catch {$_after_entry get} saved_after_attaching]} {
    set saved_after_attaching ""
  }
  pref setd gdb/load/$target-after_attaching $saved_after_attaching
}

# ------------------------------------------------------------------
#  METHOD:  fill_rates - fill baud rate combobox
# ------------------------------------------------------------------
itcl::body TargetSelection::fill_rates {} {
  $fr.cb list delete 0 end

  if {$gdb_target($target,baud-rates) != ""} {
    foreach val $gdb_target($target,baud-rates) {
      $fr.cb list insert end $val
    }
  }
}

# ------------------------------------------------------------------
#  METHOD:  fill_targets - fill target combobox
# ------------------------------------------------------------------
itcl::body TargetSelection::fill_targets {} {
  #[$fr.tar subwidget listbox] delete 0 end
  $fr.tar list delete 0 end

  foreach val $target_list {
    if {[info exists gdb_target($val,pretty-name)]} {
      $fr.tar list insert end $gdb_target($val,pretty-name)

      # Insert TCP target, if it exists
      if {[info exists gdb_target(${val}tcp,pretty-name)]} {
	$fr.tar list insert end $gdb_target(${val}tcp,pretty-name)
      }
    }
  }
}

# ------------------------------------------------------------------
#  METHOD:  config_dialog - Convenience method to map/unmap/rename
#            components onto the screen based on target T.
# ------------------------------------------------------------------
itcl::body TargetSelection::config_dialog {t} {
  pref define gdb/load/$t-verbose [pref get gdb/load/verbose]
  $f.fr.verb config -variable [pref varname gdb/load/$t-verbose]
  # Map the correct entries and comboboxes onto the screen
  if {$gdb_target($t,defbaud) == "TCP"} {
    # we have a tcp target
    # map host and porte
    if {$mapped1 != "$fr.host"} {
      grid forget $mapped1
      set mapped1 $fr.host
      grid $mapped1 -row 1 -column 1 -sticky w -padx 5 -pady 5
    }
    $fr.cbl configure -text "Hostname:"
    $fr.host config -textvariable [pref varname gdb/load/$t-hostname]

    if {$mapped2 != "$fr.porte"} {
      grid forget $mapped2
      set mapped2 $fr.porte
      grid $mapped2 -row 2 -column 1 -sticky w -padx 5 -pady 5
    }
    $fr.portl configure -text {Port:}
    $fr.porte config -textvariable [pref varname gdb/load/$t-portname] -fg black

    $mapped1 configure -state normal
    $mapped2 configure -state normal
  } elseif {$gdb_target($t,defbaud) == "ETH"} {
    # we have a udp target
    # map host and porte
    if {$mapped1 != "$fr.host"} {
      grid forget $mapped1
      set mapped1 $fr.host
      grid $mapped1 -row 1 -column 1 -sticky w -padx 5 -pady 5
    }
    $fr.cbl configure -text "Hostname:"
    $fr.host config -textvariable [pref varname gdb/load/$t-hostname]

    if {$mapped2 != "$fr.porte"} {
      grid forget $mapped2
    }
    $fr.portl configure -text {Port: N/A (fixed)}

    $mapped1 configure -state normal
    $mapped2 configure -state disabled
  } elseif {$gdb_target($t,defbaud) != ""} {
    # we have a serial target
    # map port and cb
    if {$mapped1 != "$fr.cb"} {
      grid forget $mapped1
      set mapped1 $fr.cb
      grid $mapped1 -row 1 -column 1 -sticky w -padx 5 -pady 5
    }
    $fr.cbl configure -text "Baud Rate:"
    $fr.cb configure -textvariable [pref varname gdb/load/$t-baud]
    
    if {$mapped2 != "$fr.port"} {
      grid forget $mapped2
      set mapped2 $fr.port
      grid $mapped2 -row 2 -column 1 -sticky w -padx 5 -pady 5
    }
    $fr.portl configure -text {Port:}
    $fr.port configure -textvariable [pref varname gdb/load/$t-port]

    $mapped1 configure -state normal
    $mapped2 configure -state normal
  } else {
    # we have a non-remote(-like) target
    # disable all (except tar) and check for
    # options
    $mapped1 configure -state disabled
    $mapped2 configure -state disabled
    $fr.porte configure -fg gray

    if {[info exists gdb_target($t,options)]} {
      if {$mapped1 != "$fr.host"} {
	grid forget $mapped1
	set mapped1 $fr.host
	grid $mapped1 -row 1 -column 1 -sticky w -padx 5 -pady 5
      }
      $mapped1 configure -state normal
      $fr.host config -textvariable [pref varname gdb/load/$t-opts]

      # We call options "arguments" for the exec target
      # FIXME: this is really overloaded!!
      if {$t == "exec"} {
	set text "Arguments:"
      } else {
	set text "Options:"
      }
      $fr.cbl configure -text $text
    }
  }
}

# ------------------------------------------------------------------
#  METHOD:  change_target - callback for target combobox
# ------------------------------------------------------------------
itcl::body TargetSelection::change_target {w {name ""}} {
  if {$name == ""} {return}
  set target [get_target $name]

  if { "$target" == "exec" } {
    $RunMethod.run configure -state disabled -value 1
    $RunMethod.cont configure -state disabled
  } else {
    $RunMethod.run configure -state normal
    $RunMethod.cont configure -state normal
  }

  debug "$target"
  set defbaud $gdb_target($target,defbaud)
  pref define gdb/load/$target-baud $defbaud
  pref define gdb/load/$target-portname 1000
  pref define gdb/load/$target-hostname [pref get gdb/load/default-hostname]
  if {$defbaud == ""} {
    pref define gdb/load/$target-port ""
  } else {
    pref define gdb/load/$target-port [pref get gdb/load/default-port]
  }

  config_dialog $target
  fill_rates

  # Configure the default run options for this target
  set err [catch {pref get gdb/load/$target-runlist} run_list]
  if {$err} {
    set run_list $gdb_target($target,runlist)
    pref setd gdb/load/$target-runlist $run_list
  }

  pref set gdb/src/run_attach [lindex $run_list 0]
  pref set gdb/src/run_load   [lindex $run_list 1]
  pref set gdb/src/run_run    [lindex $run_list 2]
  pref set gdb/src/run_cont   [lindex $run_list 3]
  set_check_button $name

  set err [catch {pref get gdb/load/$target-after_attaching} aa]
  if {$err} {
    set aa $gdb_target($target,after_attaching)
    pref setd gdb/load/$target-after_attaching $aa
  }

  $_after_entry delete 0 end
  $_after_entry insert 0 $aa

  set_saved

  set changes 0
}

# ------------------------------------------------------------------
#  PRIVATE METHOD:  change_baud - called when the baud rate is changed.
#  If GDB is running, set baud rate in GDB and read it back.
# ------------------------------------------------------------------
itcl::body TargetSelection::change_baud {w {baud ""}} {
  if {$baud != ""} {
    if {([string compare $baud "TCP"] != 0)
        && ([string compare $baud "ETH"] != 0)} {
      gdb_cmd "set remotebaud $baud"
      if {[catch {gdb_cmd "show remotebaud"} res]} {
	set newbaud 0
      } else {
	set newbaud [lindex $res end]
	set newbaud [string trimright $newbaud "."]
	if {$newbaud > 4000000} {
	  set newbaud 0
	}
      }
      if {$newbaud != $baud} {
	pref set gdb/load/$target-baud $newbaud
      }
    }
  }
}


# ------------------------------------------------------------------
#  METHOD:  port_list - return a list of valid ports for Windows
# ------------------------------------------------------------------
itcl::body TargetSelection::port_list {} {
  set plist ""
  # Scan com1 - com8 trying to open each one.
  # If permission is denied that means it is in use,
  # which is OK because we may be using it or the user
  # may be setting up the remote target manually with
  # a terminal program.
  set quit 0
  for {set i 1} {!$quit} {incr i} {
    if {[catch { set fd [::open COM$i: RDWR] } msg]} {
      # Failed.  Find out why.
      if {[string first "permission denied" $msg] != -1} {
	# Port is there, but busy right now. That's OK.
	lappend plist com$i
      } elseif {$i > 4} {
	# if we've scanned the first 4 ports, then quit when we find no more 
	set quit 1
      }
    } else {
      # We got it.  Now close it and add to list.
      close $fd
      lappend plist com$i
    }
  }
  return $plist
}

# ------------------------------------------------------------------
#  METHOD:  get_target_list - return a list of targets supported
#  by this GDB.  Parses the output of "help target"
# ------------------------------------------------------------------
itcl::body TargetSelection::get_target_list {} {
  set native [native_debugging]
  set names ""
  set res [gdb_cmd "help target"]
  foreach line [split $res \n] {
    if {![string compare [lindex $line 0] "target"]} {
      set name [lindex $line 1]

      # For cross debuggers, do not allow the target "exec"
      if {$name == "exec" && !$native} {
	continue
      }
      lappend names $name
    }
  }
  lappend names gdbserver
  return $names
}

# ------------------------------------------------------------------
#  METHOD:  save - save values
# ------------------------------------------------------------------
itcl::body TargetSelection::save {} {
  global gdb_target_name
  set err [catch {
    set_saved
    write_saved
    set gdb_target_name $target
    pref setd gdb/load/target $target
  } errtxt]
  if {$err} {debug "target: $errtxt"}
  if {[valid_target $gdb_target_name]} {
    # Dismiss the dialog box
    unpost
  } else {
    tk_messageBox -message "The current target is not valid."
  }
  
}


# ------------------------------------------------------------------
#  METHOD:  cancel - restore previous values
# ------------------------------------------------------------------
itcl::body TargetSelection::cancel {} {
  global gdb_target_name
  catch {gdb_cmd "set remotebaud $saved_baud"}

  $fr.cb configure -value $saved_baud
  write_saved
  if {$exportcancel} {
    set gdb_target_name CANCEL
  }

  # Now dismiss the dialog
  unpost
}

# ------------------------------------------------------------------
#  METHOD: set_check_button - enable/disable compare-section command 
# ------------------------------------------------------------------
itcl::body TargetSelection::set_check_button {name} {
  if {[winfo exists  $itk_interior.f.fr.check]} {
    if { $name == "exec" } {
      $itk_interior.f.fr.check configure -state disabled
    } else {
      $itk_interior.f.fr.check configure -state normal
    }
  }
}

# ------------------------------------------------------------------
#  METHOD:  help - launches context sensitive help.
# ------------------------------------------------------------------
itcl::body TargetSelection::help {} {
}

# ------------------------------------------------------------------
#  METHOD:  reconfig - used when preferences change
# ------------------------------------------------------------------
itcl::body TargetSelection::reconfig {} {
  # for now, just delete and recreate
  destroy $itk_interior.f
  build_win
}

# ------------------------------------------------------------------
#  METHOD:  get_target - get the internal name of a target from the
#              pretty-name
# ------------------------------------------------------------------
itcl::body TargetSelection::get_target {name} {
  set t {}
  set list [array get gdb_target *,pretty-name]
  set i [lsearch -exact $list $name]
  if {$i != -1} {
    incr i -1
    set t [lindex [split [lindex $list $i] ,] 0]
  } else {
    debug "unknown pretty-name \"$name\""
  }
  return $t
}

# ------------------------------------------------------------------
#  METHOD: toggle_more_options -- toggle displaying the  More/Fewer
#                Options pane
# ------------------------------------------------------------------
itcl::body TargetSelection::toggle_more_options {} {
  if {[$MoreLabel cget -text] == "More Options"} {
    $MoreLabel configure -text "Fewer Options"
    $MoreButton configure -image _LESS_
    # Bug in Tk? The top-most frame does not shrink...
    #pack $MoreFrame
    pack $itk_interior.moreoptionsframe -after $itk_interior.moreoptions -fill both -padx 5 -pady 5
  } else {
    $MoreLabel configure -text "More Options"
    $MoreButton configure -image _MORE_
    #pack forget $MoreFrame
    pack forget $itk_interior.moreoptionsframe
  }
}

# ------------------------------------------------------------------
#  METHOD:  set_run - set the run button. Make sure not both run and
#                     continue are selected.
# ------------------------------------------------------------------
itcl::body TargetSelection::set_run {check_which} {
  global PREFS_state
  set var [pref varname gdb/src/run_$check_which]
  global $var
  if {[set $var]} {
    set $var 0
  }
}

# ------------------------------------------------------------------
#   PROCEDURE: target_trace
#          This procedure is used to configure gdb_loaded
#          and possible more) whenever the value of gdb_loaded
#          is changed based on the current target.
# ------------------------------------------------------------------
itcl::body TargetSelection::target_trace {variable index op} {
  global gdb_target_name gdb_loaded

  switch $gdb_target_name {

    exec {
      # The exec target is always loaded.
      set gdb_loaded 1
    }
  }
}

# Returns 1 if TARGET is a _runnable_ target for this gdb.
itcl::body TargetSelection::valid_target {target} {

  # always allow gdbserver
  if {$target == "gdbserver"} {return 1}

  set err [catch {gdb_cmd "help target $target"}]
  if {$target == "exec" && ![native_debugging]} {
    set err 1
  }

  if {[regexp "tcp$" $target]} {
    # Special case (of course)
    regsub tcp$ $target {} foo
    return [valid_target $foo]
  }

  return [expr {$err == 0}]
}

# Returns 1 if this is not a cross debugger.
itcl::body TargetSelection::native_debugging {} {
  global GDBStartup

  set r [string compare $GDBStartup(host_name) $GDBStartup(target_name)]
  return [expr {!$r}]
}