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 #include <dos.h>
26 #include "wstdefs.h"
27 #include "wstglob.h"
28 #include "wsthist.h"
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 history_screen(cur_scr)
52 SCREEN *cur_scr;
53 {
54 int ch;
55 ITEM_INFO item;
56 int offset;
57 int code;
58 char line[SCREEN_COLS+2];
59 char stat_mess[SCREEN_COLS+1];
60 int selection;
61
62
63 save_wst_screen(cur_scr);
64
65
66 cursor_move(HIDE_CURSOR_ROW,HIDE_CURSOR_COL);
67
68 ch = NONE;
69 offset = HIST_DEFAULT_0_ARG;
70
71
72 wst_screen_clear(&wst_tmp_screen);
73 wst_screen_printline(&wst_tmp_screen,"");
74
75
76 init_history_display(&item);
77
78
79 while (uppercase(ch) != 'Q' && item.start_chars_in_buff > NONE) {
80
81
82 code = extract_hist_lines(&item,offset,line);
83
84 if (code >= 0)
85
86 wst_screen_printline(&wst_tmp_screen,line);
87
88
89 if (code < 0 || item.cur_display_count >= HIST_MAX_LINES) {
90
91
92 restore_wst_screen(&wst_tmp_screen);
93
94
95 cursor_move(HIDE_CURSOR_ROW,HIDE_CURSOR_COL);
96
97
98 if (item.cur_chars_in_buff < 1)
99 sprintf(stat_mess,
100 "HISTORY SCREEN: offset %3d <ALT-H>-help [<Q>,<RETURN>,<P>,<N>,<L>,<R>]",
101 offset);
102 else
103 sprintf(stat_mess,
104 "HISTORY SCREEN(more): offset %3d <ALT-H>-help [<Q>,<RETURN>,<P>,<N>,<L>,<R>]",
105 offset);
106
107 status_line(stat_mess);
108
109
110 selection = HIST_DEFAULT_0_ARG;
111
112 while (TRUE) {
113 ch = getkey(BLOCK);
114
115
116 if (ch >= SMALLEST_DECI_DIGIT && ch <= LARGEST_DECI_DIGIT) {
117 if (selection >= MAX_ARG_LIMIT) {
118 selection = HIST_DEFAULT_0_ARG;
119 beep();
120 }
121 else {
122 selection *= 10;
123 selection += ch - '0';
124 }
125 }
126
127
128 else if (uppercase(ch) == 'R') {
129
130
131 if (offset > NONE) {
132
133
134 if (selection < 1) selection = 1;
135 if (offset >= selection)
136 offset -= selection;
137 else
138 offset = NONE;
139
140
141 reset_hist_page(&item);
142 selection = HIST_DEFAULT_0_ARG;
143
144
145
146
147
148
149 while (uppercase((ch = checkkey())) == 'R' ||
150 uppercase(ch) == 'L') {
151 ch = getkey(BLOCK);
152 if (uppercase(ch) == 'L') {
153 if (offset < HIST_MAX_SCREEN_SHIFT)
154 offset++;
155 }
156 else {
157 if (offset > NONE)
158 offset--;
159 }
160 }
161
162 break;
163 }
164 selection = HIST_DEFAULT_0_ARG;
165 }
166
167
168 else if (uppercase(ch) == 'L') {
169
170
171 if (offset < HIST_MAX_SCREEN_SHIFT) {
172
173
174 if (selection < 1) selection = 1;
175 if (offset + selection <= HIST_MAX_SCREEN_SHIFT)
176 offset += selection;
177 else
178 offset = HIST_MAX_SCREEN_SHIFT;
179
180
181 reset_hist_page(&item);
182 selection = HIST_DEFAULT_0_ARG;
183
184
185
186
187
188
189 while (uppercase((ch = checkkey())) == 'L' ||
190 uppercase(ch) == 'R') {
191 ch = getkey(BLOCK);
192 if (uppercase(ch) == 'L') {
193 if (offset < HIST_MAX_SCREEN_SHIFT)
194 offset++;
195 }
196 else {
197 if (offset > NONE)
198 offset--;
199 }
200 }
201
202 break;
203 }
204 selection = HIST_DEFAULT_0_ARG;
205 }
206
207
208 else if (ch == RETURN_KEY && selection > NONE) {
209
210
211 if (fetch_nth_command(selection,
212 edlin.line, &edlin.length) < 0) {
213 selection = HIST_DEFAULT_0_ARG;
214 }
215
216
217 else {
218
219 ch = 'Q';
220
221 break;
222 }
223 }
224
225
226 else if (ch == ' ' || uppercase(ch) == 'N') {
227 selection = HIST_DEFAULT_0_ARG;
228 if (next_hist_page(&item) >= 0)
229 break;
230 else
231 beep();
232 }
233
234
235 else if (uppercase(ch) == 'P') {
236 selection = HIST_DEFAULT_0_ARG;
237 if (previous_hist_page(&item) >= 0)
238 break;
239 else
240 beep();
241 }
242
243
244 else if (uppercase(ch) == 'Q') {
245
246 selection = HIST_DEFAULT_0_ARG;
247 break;
248 }
249
250
251 else if (ch == ALT_H) {
252 help(HISTORY_HELP);
253 status_line(stat_mess);
254 }
255
256
257 else {
258 selection = HIST_DEFAULT_0_ARG;
259 beep();
260 }
261 }
262
263
264 wst_screen_clear(&wst_tmp_screen);
265 wst_screen_printline(&wst_tmp_screen,"");
266 }
267 }
268
269
270 restore_wst_screen(cur_scr);
271
272
273
274
275 if (selection > NONE) {
276
277 update_echo_flags(&edlin);
278
279 erase_edit_line(&edlin);
280
281
282 edlin.index = ZERO_INDEX_VALUE;
283
284 edlin.escape_flag = NO_ESC_FUNC;
285 edlin.escape_arg = NO_ESC_ARG;
286 redraw_edit_line(&edlin);
287 cursor_eol(&edlin);
288 }
289 }
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311 save_to_histbuff(str,item_size)
312 char *str;
313 int item_size;
314 {
315 int i, j;
316 int lo_byte;
317 int hi_byte;
318 int first_chunk;
319 int buffer_empty;
320
321
322 if (item_size+TOTAL_SIZE_SPEC_BYTES >= HIST_BUFF_SIZE) {
323 beep();
324 return;
325 }
326
327
328 while (hbi.chars_free < item_size+TOTAL_SIZE_SPEC_BYTES) {
329
330 i = (hbi.tail + hbi.tail_item_size) % HIST_BUFF_SIZE;
331
332
333 if (i == hbi.head && hbi.chars_free == NONE) {
334
335 init_histbuff();
336 break;
337 }
338
339
340 hbi.tail = i;
341
342
343 lo_byte = hbi.kb[i];
344 i = (i+1)%HIST_BUFF_SIZE;
345 hi_byte = hbi.kb[i];
346
347
348 hbi.chars_free += hbi.tail_item_size;
349
350
351 hbi.tail_item_size = (hi_byte * MAX_7_BIT_VAL) + lo_byte;
352 }
353
354
355 if (hbi.head == hbi.tail && hbi.chars_free == HIST_BUFF_SIZE)
356 buffer_empty = TRUE;
357 else
358 buffer_empty = FALSE;
359
360
361 hbi.head_item_size = item_size+TOTAL_SIZE_SPEC_BYTES;
362
363 hbi.chars_free -= hbi.head_item_size;
364
365
366 lo_byte = hbi.head_item_size % MAX_7_BIT_VAL;
367 hi_byte = hbi.head_item_size / MAX_7_BIT_VAL;
368
369
370 i = hbi.head;
371 hbi.kb[i] = lo_byte;
372 i = (i+1)%HIST_BUFF_SIZE;
373 hbi.kb[i] = hi_byte;
374 i = (i+1)%HIST_BUFF_SIZE;
375
376
377 if (i+item_size > HIST_BUFF_SIZE) {
378
379
380 first_chunk = HIST_BUFF_SIZE - i;
381
382 item_size -= first_chunk;
383
384
385 for (j = ZERO_INDEX_VALUE; j < first_chunk; j++)
386 hbi.kb[i++] = str[j];
387 for (i = ZERO_INDEX_VALUE; i < item_size; i++)
388 hbi.kb[i] = str[j++];
389
390 }
391
392
393 else {
394 for (j = ZERO_INDEX_VALUE; j < item_size; j++)
395 hbi.kb[i++] = str[j];
396 }
397
398
399 i = i % HIST_BUFF_SIZE;
400 hbi.kb[i] = lo_byte;
401 i = (i+1) % HIST_BUFF_SIZE;
402 hbi.kb[i] = hi_byte;
403 i = (i+1) % HIST_BUFF_SIZE;
404
405
406 if (buffer_empty) {
407 hbi.tail = hbi.head;
408 hbi.tail_item_size = hbi.head_item_size;
409 }
410
411 hbi.head = i;
412
413
414 hbi.current = hbi.head;
415 hbi.current_size = hbi.head_item_size;
416 hbi.head_of_histbuff = TRUE;
417
418
419 hbi.direction = HIST_START_DIR;
420
421 }
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440 init_histbuff()
441 {
442
443
444 hbi.head = ZERO_INDEX_VALUE;
445 hbi.tail = ZERO_INDEX_VALUE;
446 hbi.current = ZERO_INDEX_VALUE;
447
448
449 hbi.head_item_size = ZERO_BYTES;
450 hbi.tail_item_size = ZERO_BYTES;
451 hbi.current_size = ZERO_BYTES;
452
453
454 hbi.chars_free = HIST_BUFF_SIZE;
455
456
457 hbi.head_of_histbuff = TRUE;
458
459
460 hbi.direction = HIST_START_DIR;
461 }
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481 init_history_display(item)
482 ITEM_INFO *item;
483 {
484
485
486 item->start_item_no = ZERO_BYTES;
487
488
489 item->start_chars_in_buff = HIST_BUFF_SIZE - hbi.chars_free;
490
491
492 item->start_item_index = hbi.head;
493
494
495 item->start_display_count = ZERO_BYTES;
496
497
498 item->start_size = hbi.head_item_size;
499
500
501 item->cur_item_no = item->start_item_no;
502 item->cur_chars_in_buff = item->start_chars_in_buff;
503 item->cur_item_index = item->start_item_index;
504 item->cur_display_count = item->start_display_count;
505 item->cur_size = item->start_size;
506 }
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527 reset_hist_page(item)
528 ITEM_INFO *item;
529 {
530
531
532 item->cur_item_no = item->start_item_no;
533 item->cur_chars_in_buff = item->start_chars_in_buff;
534 item->cur_item_index = item->start_item_index;
535 item->cur_display_count = item->start_display_count = ZERO_BYTES;
536 item->cur_size = item->start_size;
537
538 return(0);
539 }
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561 next_hist_page(item)
562 ITEM_INFO *item;
563 {
564
565 if (item->cur_chars_in_buff < 1)
566 return(-1);
567
568
569 item->start_item_no = item->cur_item_no;
570 item->start_chars_in_buff = item->cur_chars_in_buff;
571 item->start_item_index = item->cur_item_index;
572 item->start_display_count = item->cur_display_count = ZERO_BYTES;
573 item->start_size = item->cur_size;
574
575 return(0);
576 }
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597 previous_hist_page(item)
598 ITEM_INFO *item;
599 {
600 int i;
601 int hi, lo;
602 int cnt;
603 int times;
604
605
606
607
608 if (item->start_item_no < HIST_MAX_LINES)
609 return(-1);
610
611
612 for (times = 0; times < HIST_MAX_LINES; times++) {
613
614
615 i = item->start_item_index;
616
617
618 lo = hbi.kb[i];
619 i = (i+1)%HIST_BUFF_SIZE;
620 hi = hbi.kb[i];
621 i = (i+1)%HIST_BUFF_SIZE;
622
623 cnt = (hi * MAX_7_BIT_VAL) + lo;
624
625
626 item->start_item_index = (item->start_item_index + cnt)%HIST_BUFF_SIZE;
627
628
629 item->start_item_no--;
630
631
632 item->start_chars_in_buff += cnt;
633
634
635 item->start_size = cnt;
636
637 }
638
639
640 item->cur_item_index = item->start_item_index;
641 item->cur_item_no = item->start_item_no;
642 item->cur_chars_in_buff = item->start_chars_in_buff;
643 item->cur_display_count = item->start_display_count = ZERO_BYTES;
644 item->cur_size = item->start_size;
645
646 return(0);
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 extract_hist_lines(item,offset,line)
681 ITEM_INFO *item;
682 int offset;
683 char *line;
684 {
685 int i, j;
686 int lo, hi;
687 int cnt;
688 int linelen;
689 int previous;
690
691
692 if (item->cur_chars_in_buff < 1)
693 return(-1);
694
695
696 i = item->cur_item_index;
697
698
699 if (i == hbi.tail && !hbi.head_of_histbuff)
700 return(-1);
701
702
703 previous = (item->cur_item_index + HIST_BUFF_SIZE - item->cur_size)
704 % HIST_BUFF_SIZE;
705 i = previous;
706
707
708 if (item->cur_chars_in_buff > NONE) {
709
710
711 lo = hbi.kb[i];
712 i = (i+1)%HIST_BUFF_SIZE;
713 hi = hbi.kb[i];
714 i = (i+1)%HIST_BUFF_SIZE;
715
716 cnt = (hi * MAX_7_BIT_VAL) + lo;
717
718
719
720 cnt -= TOTAL_SIZE_SPEC_BYTES;
721 item->cur_chars_in_buff -= TOTAL_SIZE_SPEC_BYTES;
722
723
724 sprintf(line,"%3d ", item->cur_item_no+1);
725 linelen = strlen(line);
726
727
728
729 if (cnt > offset) {
730
731
732 i = (i+offset) % HIST_BUFF_SIZE;
733 item->cur_chars_in_buff -= offset;
734 cnt -= offset;
735
736
737 for (j = 0; j < cnt; j++) {
738
739
740
741 if (linelen < SCREEN_COLS) {
742
743
744
745 if (hbi.kb[i] < ' ') {
746 line[linelen++] = '^';
747 line[linelen++] = hbi.kb[i] + '@';
748 }
749 else {
750 line[linelen++] = hbi.kb[i];
751 }
752 }
753
754 i = (i+1)%HIST_BUFF_SIZE;
755 item->cur_chars_in_buff--;
756 }
757 }
758
759 else {
760 i = (i+cnt) % HIST_BUFF_SIZE;
761 item->cur_chars_in_buff -= cnt;
762 }
763
764
765
766 if (linelen > SCREEN_COLS-1) {
767 line[SCREEN_COLS-1] = '$';
768 line[SCREEN_COLS] = NUL_TERMINATOR;
769 }
770 else
771 line[linelen] = NUL_TERMINATOR;
772
773
774
775 item->cur_item_no++;
776 item->cur_item_index = previous;
777 item->cur_display_count++;
778
779
780
781 if (previous != hbi.tail) {
782 previous = (previous + HIST_BUFF_SIZE - N_SIZE_SPEC_BYTES)
783 % HIST_BUFF_SIZE;
784 lo = hbi.kb[previous];
785 previous = (previous+1) % HIST_BUFF_SIZE;
786 hi = hbi.kb[previous];
787 item->cur_size = (hi * MAX_7_BIT_VAL) + lo;
788 }
789
790 return(0);
791 }
792 return(-1);
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 fetch_next_command(n_times,cmd,cmd_len)
821 int n_times;
822 char *cmd;
823 int *cmd_len;
824 {
825 int i, j;
826 int cnt;
827 int lo, hi;
828 int times;
829 int prev_index;
830
831
832 if (hbi.chars_free == HIST_BUFF_SIZE)
833 return(-1);
834
835 prev_index = (hbi.head+HIST_BUFF_SIZE-hbi.head_item_size) % HIST_BUFF_SIZE;
836
837
838 if (hbi.direction == HIST_PREVIOUS_DIR && prev_index != hbi.tail)
839 n_times++;
840
841 hbi.direction = HIST_NEXT_DIR;
842
843 for (times = 0; times < n_times; times++) {
844
845 if (hbi.current == hbi.head) {
846 hbi.head_of_histbuff = TRUE;
847 beep();
848 return(-1);
849 }
850
851 i = hbi.current;
852
853 lo = hbi.kb[i];
854 i = (i+1)%HIST_BUFF_SIZE;
855 hi = hbi.kb[i];
856 i = (i+1)%HIST_BUFF_SIZE;
857
858 cnt = (hi * MAX_7_BIT_VAL) + lo;
859 hbi.current_size = cnt;
860 cnt -= TOTAL_SIZE_SPEC_BYTES;
861
862
863 if (times == n_times-1) {
864 *cmd_len = cnt;
865 for (j = 0; j < cnt; j++) {
866 cmd[j] = hbi.kb[i];
867 i = (i+1)%HIST_BUFF_SIZE;
868 }
869 }
870
871 else
872 i = (i+cnt)%HIST_BUFF_SIZE;
873
874 i = (i+1)%HIST_BUFF_SIZE;
875 i = (i+1)%HIST_BUFF_SIZE;
876
877 hbi.current = i;
878 }
879
880 return(0);
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 fetch_previous_command(n_times,cmd,cmd_len)
909 int n_times;
910 char *cmd;
911 int *cmd_len;
912 {
913 int i, j;
914 int cnt;
915 int lo, hi;
916 int previous;
917 int times;
918 int prev_index;
919
920
921 if (hbi.chars_free == HIST_BUFF_SIZE)
922 return(-1);
923
924 prev_index = (hbi.head+HIST_BUFF_SIZE-hbi.head_item_size) % HIST_BUFF_SIZE;
925
926
927
928
929
930 if (hbi.direction == HIST_NEXT_DIR && prev_index != hbi.tail)
931 n_times++;
932
933 hbi.direction = HIST_PREVIOUS_DIR;
934
935
936 for (times = 0; times < n_times; times++) {
937
938
939 if (hbi.current == hbi.tail && !hbi.head_of_histbuff) {
940 beep();
941 return(-1);
942 }
943
944
945 previous = (hbi.current + HIST_BUFF_SIZE - hbi.current_size) %
946 HIST_BUFF_SIZE;
947
948 i = previous;
949
950
951 lo = hbi.kb[i];
952 i = (i+1)%HIST_BUFF_SIZE;
953 hi = hbi.kb[i];
954 i = (i+1)%HIST_BUFF_SIZE;
955
956 cnt = (hi * MAX_7_BIT_VAL) + lo;
957
958
959 cnt -= TOTAL_SIZE_SPEC_BYTES;
960
961
962 if (times == n_times-1) {
963 *cmd_len = cnt;
964
965
966 for (j = 0; j < cnt; j++) {
967 cmd[j] = hbi.kb[i];
968 i = (i+1)%HIST_BUFF_SIZE;
969 }
970 }
971
972
973 else
974 i = (i+cnt)%HIST_BUFF_SIZE;
975
976
977
978 hbi.current = previous;
979 if (previous != hbi.tail) {
980 previous = (previous + HIST_BUFF_SIZE - N_SIZE_SPEC_BYTES)
981 % HIST_BUFF_SIZE;
982 lo = hbi.kb[previous];
983 previous = (previous+1) % HIST_BUFF_SIZE;
984 hi = hbi.kb[previous];
985 hbi.current_size = (hi * MAX_7_BIT_VAL)+lo;
986 }
987
988
989 hbi.head_of_histbuff = FALSE;
990 }
991
992 return(0);
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 fetch_nth_command(cmd_num,cmd,cmd_len)
1022 int cmd_num;
1023 char *cmd;
1024 int *cmd_len;
1025 {
1026 int i, j;
1027 int cnt;
1028 int lo, hi;
1029 int previous;
1030 int times;
1031 int at_head;
1032 int cur_index;
1033 int cur_size;
1034
1035
1036 if (hbi.chars_free == HIST_BUFF_SIZE)
1037 return(-1);
1038
1039
1040 cur_index = hbi.head;
1041 cur_size = hbi.head_item_size;
1042 at_head = hbi.head_of_histbuff;
1043
1044
1045 for (times = ZERO_INDEX_VALUE; times < cmd_num; times++) {
1046
1047
1048 if (cur_index == hbi.tail && !at_head) {
1049 beep();
1050 return(-1);
1051 }
1052
1053
1054 previous = (cur_index + HIST_BUFF_SIZE - cur_size) %
1055 HIST_BUFF_SIZE;
1056 i = previous;
1057
1058
1059 lo = hbi.kb[i];
1060 i = (i+1)%HIST_BUFF_SIZE;
1061 hi = hbi.kb[i];
1062 i = (i+1)%HIST_BUFF_SIZE;
1063
1064 cnt = (hi * MAX_7_BIT_VAL) + lo;
1065
1066
1067 cnt -= TOTAL_SIZE_SPEC_BYTES;
1068
1069 *cmd_len = cnt;
1070
1071
1072 for (j = ZERO_INDEX_VALUE; j < cnt; j++) {
1073 cmd[j] = hbi.kb[i];
1074 i = (i+1)%HIST_BUFF_SIZE;
1075 }
1076
1077
1078 cur_index = previous;
1079
1080
1081 if (previous != hbi.tail) {
1082 previous = (previous + HIST_BUFF_SIZE - N_SIZE_SPEC_BYTES)
1083 % HIST_BUFF_SIZE;
1084 lo = hbi.kb[previous];
1085 previous = (previous+1) % HIST_BUFF_SIZE;
1086 hi = hbi.kb[previous];
1087 cur_size = (hi * MAX_7_BIT_VAL)+lo;
1088 }
1089
1090
1091 at_head = FALSE;
1092 }
1093
1094
1095 hbi.current = cur_index;
1096 hbi.current_size = cur_size;
1097 hbi.head_of_histbuff = at_head;
1098 hbi.direction = HIST_PREVIOUS_DIR;
1099
1100 return(0);
1101 }
1102