home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / ADC_TP3.ZIP / CMDKEY.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1987-03-01  |  9.4 KB  |  282 lines

  1. Program CommandKeys;
  2. {$U-,C-}
  3. {Written March 27, 1985 by Carl Neiburger, Los Osos, Calif.}
  4.  
  5. {Here are four subroutines that install and interpret function
  6. key commands.
  7.  
  8. They can allow you to:
  9.     1: Write programs that can be installed on computers that use
  10.        different function keys (ie arrows);
  11.     2: Change your mind about what what you want function keys to do.
  12.  
  13. Getcmd works like the [C]ommand part of Tinst.  It asks you to
  14. type command keys and prompts. The prompts are not necessary but can be
  15. used in a help feature. As written, Getcmd identifies the commands
  16. by number.  You can substitute a list of names like "Cursor Up" or
  17. "Delete Word."  Getcmd lets you review (and change) the commands and
  18. then writes the file "COMMAND.FIL" to preserve your choices.
  19.  
  20. Install retrieves the commands from the disk.
  21.  
  22. The main program initializes all the commands as empty strings.
  23. This is necessary to prevent garbage.  In an application, the program
  24. can look for "COMMAND.FIL."  If it doesn't find it, it can initialize
  25. the commands and invoke Getcmd.
  26.  
  27. Cmdkey is the heart of the program. When invoked, it returns the
  28. command number or zero if it doesn't recognize the command. The
  29. statement, "case cmdkey of" can invoke other subroutines.
  30.  
  31. Test_Loop demonstrates the other subroutines.}
  32.  
  33. const
  34.     cmdnum =    10; {This tells how many commands there will be}
  35.  
  36. type
  37.     nos =       set of byte;
  38.     str6 =      string[6];
  39.     str15 =     string[15];
  40.     cmdrec =    record
  41.                   cmd:  str6;     {command sequences}
  42.                   key:  str15     {prompts}
  43.                 end;
  44.     recarray =  array[1..cmdnum] of cmdrec;
  45.  
  46. const
  47.     keynos:     nos = [1..cmdnum];
  48.  
  49. var
  50.     cmdarray:   recarray;          {list of commands}
  51.     cmdfile:    file of recarray;
  52.     i:          integer;
  53.     choice,
  54.     ch:         char;
  55.  
  56. procedure getcmds;
  57.  
  58. var
  59.   len:   byte; {counts the length of screen displays}
  60.  
  61.   procedure printchar(ch: char);
  62.   {This interprets commands on the screen}
  63.  
  64.   begin
  65.     case ord(ch) of
  66.        0..31:   begin  {command character}
  67.                   write('^', chr(ord(ch) + 64));
  68.                   len:= len + 3
  69.                 end;
  70.        33..126: begin  {printable character}
  71.                   write(ch);
  72.                   len:= len + 2
  73.                 end
  74.        else     begin  {delete or byte > 126}
  75.                   write(ord(ch));
  76.                   len:= len + 4
  77.                 end
  78.     end; {case}
  79.     write(' ')  {space between characters}
  80.   end; {printchar}
  81.  
  82.  procedure readarray;
  83.  
  84.  var
  85.     i, j, k:  byte;
  86.     ok:       boolean;   {if no duplicates are present}
  87.     ch:       char;
  88.     rec:      cmdrec;    {dummy record}
  89.  
  90.   procedure readrecord(var item: cmdrec);
  91.  
  92.   var
  93.     done:     boolean;
  94.  
  95.   begin;
  96.     with item do begin
  97.        cmd:= '';         {initialize dummy record}
  98.        key:= '';
  99.        write('Command ', i, ': ');
  100.        if cmdarray[i].cmd = '' then write('<nothing>            ')
  101.        else begin        {if command exists, say so}
  102.          len:= 0;
  103.          for j:= 1 to length(cmdarray[i].cmd) do printchar(cmdarray[i].cmd[j]);
  104.          for j:= len to 20 do write(' ')
  105.        end;
  106.        len:= 0;
  107.        repeat
  108.          read(kbd, ch);
  109.          if cmd = '' then begin    {if first character of command}
  110.            case ch of
  111.              '-' : done:= true;    {erase sequence}
  112.              ^m  : begin           {copy sequence}
  113.                      done:= true;
  114.                      item:= cmdarray[i];
  115.                      for j:= 1 to length(cmd) do printchar(cmd[j])
  116.                    end
  117.              else done:= false     {get new sequence}
  118.            end; {case}
  119.          end
  120.          else if ch = ^m then done:= true; {carriage return means stop}
  121.          if not done then begin
  122.             printchar(ch);         {print new sequence}
  123.             cmd := cmd + ch        {and remember it}
  124.          end
  125.        until (length(cmd) = 6) or done; {six is the maximum length allowed}
  126.        if cmd = '' then writeln('<nothing>')
  127.        else begin
  128.          for j:= len to 20 do write(' ');
  129.          write('Name: ');
  130.          if key = '' then readln(key)  {if it's an old one, it has a prompt}
  131.          else writeln(key)             {it it's a new one, it doesn't}
  132.        end {else}
  133.     end {with}
  134.   end; {readrecord}
  135.  
  136.  begin  {readarray}
  137.    for i:= 1 to cmdnum do begin
  138.      ok:= true;                 {assume there's no duplication}
  139.      writeln;
  140.      readrecord(rec);
  141.      with rec do begin          {start looking for duplicates}
  142.        if (i > 1) and (cmd <> '') then begin
  143.          j:= 1;
  144.          repeat                 {if you find one and it's not a blank...}
  145.            if (cmd <> '') and (cmd = cmdarray[j].cmd) then begin
  146.               ok:= false;
  147.               writeln;
  148.               write('Commands ', i, ' and ', j, ' are both defined as ');
  149.               for k:= 1 to length(cmd) do printchar(cmd[k]);
  150.               writeln('Redefine command ', i);
  151.               writeln;
  152.               readrecord(rec)   {...ask for a different key sequence}
  153.            end {if}
  154.            else ok:= true;
  155.            if ok then j:= j + 1
  156.          until ok and (i = j)
  157.        end {if i}
  158.      end; {with}
  159.      cmdarray[i]:= rec
  160.    end {for}
  161.  end; {readarray}
  162.  
  163. begin {getcmds}                 {This part just gives instructions}
  164.   writeln('Enter command sequences of up to six characters and key');
  165.   writeln('prompts of up to 15 characters. To terminate, enter a');
  166.   writeln('carriage return.  Entering a carriage return alone retains');
  167.   writeln('the old sequence. To delete "-".');
  168.   repeat
  169.     readarray;
  170.     writeln;
  171.     write('To continue, enter "C"; To review, enter "R"; To abort, enter "X".');
  172.     repeat
  173.       read(kbd, choice);
  174.     until upcase(choice) in ['C', 'R', 'X'];
  175.     if upcase(choice) = 'X' then halt;
  176.     writeln
  177.   until upcase(choice) = 'C';
  178.   rewrite(cmdfile);            {and records new COMMAND.FIL}
  179.   write(cmdfile,cmdarray);
  180.   close(cmdfile);
  181.   clrscr
  182. end; {getcmds}
  183.  
  184. procedure install;
  185. {To read COMMAND.FIL back into memory}
  186.  
  187. begin
  188.   reset(cmdfile);
  189.   read(cmdfile, cmdarray)
  190. end;
  191.  
  192. Function Cmdkey(ch: char): integer;
  193. {To identify function keys, Cmdkey looks at the characters
  194. one at a time.  It keeps track of the functions in the set
  195. "keys."  It throws out the functions that don't match until
  196. it either finds a complete match or runs out of possibilities.}
  197.  
  198. var
  199.    command:    integer;  {dummy value for Cmdkey}
  200.    keys:       nos;      {set of function numbers}
  201.    i,                    {index of characters in a command sequence}
  202.    j:       byte;        {index of commands in array}
  203.  
  204. begin
  205.    command:= 0;
  206.    keys:= keynos;        {list all the function in the set}
  207.    i:= 1;                {start with the first character  }
  208.    repeat
  209.      j:= 1;              {start with the first command in array}
  210.      repeat
  211.        if j in keys then begin                  {If command j hasn't}
  212.            if ch <> cmdarray[j].cmd[i]          {been eliminated then}
  213.              then keys:= keys - [j]             {consider eliminating it.}
  214.            else if length(cmdarray[j].cmd) = i  {if it survives and}
  215.               then command:= j                  {the length is right,}
  216.         end; {if j}                             {it's a match. If it isn't,}
  217.         if command = 0 then j:= j + 1           {try the next command}
  218.      until (j = cmdnum + 1)                {till you reach the end of array}
  219.         or (command <> 0)                  {or find a match}
  220.         or (keys = []);                    {or run out of possibilities.}
  221.      if (keys <> [])                       {If you haven't exhausted}
  222.         and (command = 0) then begin       {the possibilities,then}
  223.         j:= 1;                             {go to the top of the array}
  224.         i:= succ(i);                       {and try the next character.}
  225.         read(kbd, ch)
  226.      end
  227.    until (i = 7)                        {until you've run out of characters}
  228.       or (keys = [])                    {or possible matches}
  229.       or (command <> 0);                {or have found a match}
  230.    cmdkey:= command
  231. end;
  232.  
  233. procedure test_loop;
  234. {This procedure prints normal characters and carriage returns.
  235. It evaluates any other characters and tells you if it recognizes
  236. them as a command sequence. It stops when you type the last
  237. command key on your list, so don't forget what that is.}
  238.  
  239. var
  240.     num:        integer;
  241.  
  242. begin
  243.   writeln('Type ', cmdarray[cmdnum].key, ' to exit.');
  244.   repeat
  245.     num:= 0;
  246.     read(kbd,ch);
  247.     case ch of
  248.       ^m:    writeln;
  249.       ' '..'~': write(ch)
  250.       else begin
  251.          num:= cmdkey(ch);
  252.          writeln;
  253.          if num > 0 then writeln('>', cmdarray[num].key, '<')
  254.          else writeln('Unrecognized command.')
  255.       end
  256.     end {case}
  257.   until num = cmdnum
  258. end;
  259.  
  260. begin; {main}
  261.  clrscr;
  262.  for i:= 1 to cmdnum do with cmdarray[i] do begin   {initialize array}
  263.     cmd:= '';
  264.     key:= ''
  265.  end;
  266.  assign(cmdfile, 'COMMAND.FIL');
  267.  repeat
  268.    writeln('1: create commands');
  269.    writeln('2: recall commands');
  270.    writeln('3: test commands');
  271.    writeln('4: exit');
  272.    write('==>');
  273.    read(kbd, choice);
  274.    clrscr;
  275.    case choice of
  276.         '1':   getcmds;
  277.         '2':   install;
  278.         '3':   test_loop
  279.    end {case}
  280.  until choice = '4'
  281. end.
  282.