home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / progmisc / tde221.zip / CFGFILE.C < prev    next >
C/C++ Source or Header  |  1993-04-01  |  32KB  |  933 lines

  1. /*
  2.  * This module contains all the routines needed to redefine key, colors, and
  3.  *   modes via a configuration file.
  4.  *
  5.  * Program Name:  tdecfg
  6.  * Author:        Frank Davis
  7.  * Date:          June 5, 1992
  8.  */
  9.  
  10.  
  11. #include <io.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15.  
  16. #include "tdecfg.h"
  17. #include "cfgfile.h"
  18.  
  19.  
  20. /*
  21.  * reference the structures in config files.
  22.  */
  23. extern struct vcfg cfg;
  24. extern FILE *tde_exe;                  /* FILE pointer to tde.exe */
  25. extern KEY_FUNC key_func;
  26. extern MACRO macros;
  27. extern COLORS temp_colours;
  28. extern MODE_INFO in_modes;
  29.  
  30.  
  31.  
  32. char line_in[2000];             /* line buffer */
  33. int  stroke_count;              /* global variable for macro strokes */
  34. unsigned int line_no;           /* global variable for line count */
  35. int modes[NUM_MODES];
  36.  
  37.  
  38. TWO_KEY two_key_list;
  39.  
  40. SORT_ORDER sort_order;
  41.  
  42.  
  43. /*
  44.  * Name:    tdecfgfile
  45.  * Date:    June 5, 1992
  46.  * Notes:   read in a configuration file
  47.  */
  48. void tdecfgfile( void )
  49. {
  50. FILE *config;
  51. char fname[80];
  52. int  rc;
  53.  
  54.    /*
  55.     * prompt for the configuration file name.
  56.     */
  57.    cls( );
  58.    xygoto( 0, 3 );
  59.    puts( "Enter configuration file name, e.g. tde.cfg  :" );
  60.    gets( fname );
  61.  
  62.    if (strlen( fname ) != 0) {
  63.       rc = OK;
  64.       if ((rc = access( fname, EXIST )) != 0) {
  65.          puts( "\n\n Error: File not found." );
  66.          getkey( );
  67.          rc = ERROR;
  68.       } else if ((config = fopen( fname, "r" )) == NULL ) {
  69.          puts( "\n\nError: Cannot open configuration file." );
  70.          getkey( );
  71.          rc = ERROR;
  72.       }
  73.  
  74.       /*
  75.        * if everything is everthing so far, get the current editor settings.
  76.        */
  77.       if (rc == OK) {
  78.          fseek( tde_exe, KEYS_OFFSET, SEEK_SET );
  79.          fread( (void *)&key_func, sizeof(KEY_FUNC), 1, tde_exe );
  80.          fseek( tde_exe, TWO_KEY_OFFSET, SEEK_SET );
  81.          fread( (void *)&two_key_list, sizeof(TWO_KEY), 1, tde_exe );
  82.          fseek( tde_exe, MACRO_OFFSET, SEEK_SET );
  83.          fread( (void *)¯os, sizeof(MACRO), 1, tde_exe );
  84.          fseek( tde_exe, COLOR_OFFSET, SEEK_SET );
  85.          fread( (void *)&temp_colours, sizeof(COLORS), 1, tde_exe );
  86.          fseek( tde_exe, MODE_OFFSET, SEEK_SET );
  87.          fread( (void *)&in_modes, sizeof( MODE_INFO ), 1, tde_exe );
  88.          fseek( tde_exe, SORT_OFFSET, SEEK_SET );
  89.          fread( (void *)&sort_order, sizeof( SORT_ORDER ), 1, tde_exe );
  90.  
  91.          stroke_count = get_stroke_count( );
  92.  
  93.          /*
  94.           * put the current modes into an array.  it's easier to work
  95.           *   with them in an array.  This is from cfgmode.c.
  96.           */
  97.          modes[Ins]         = in_modes.insert;
  98.          modes[Ind]         = in_modes.indent;
  99.          modes[PTAB]        = in_modes.ptab_size;
  100.          modes[LTAB]        = in_modes.ltab_size;
  101.          modes[Smart]       = in_modes.smart_tab;
  102.          modes[Write_Z]     = in_modes.control_z;
  103.          modes[Crlf]        = in_modes.crlf;
  104.          modes[Trim]        = in_modes.trailing;
  105.          modes[Eol]         = in_modes.show_eol;
  106.          modes[WW]          = in_modes.word_wrap;
  107.          modes[Left]        = in_modes.left_margin;
  108.          modes[Para]        = in_modes.parg_margin;
  109.          modes[Right]       = in_modes.right_margin;
  110.          modes[Size]        = in_modes.cursor_size;
  111.          modes[Backup]      = in_modes.do_backups;
  112.          modes[Ruler]       = in_modes.ruler;
  113.          modes[Date]        = in_modes.date_style;
  114.          modes[Time]        = in_modes.time_style;
  115.          modes[InflateTabs] = in_modes.inflate_tabs;
  116.          modes[Initcase]    = in_modes.search_case;
  117.          modes[JustRM]      = in_modes.right_justify;
  118.  
  119.          line_no = 1;
  120.          while (!feof( config )) {
  121.             if (fgets( line_in, 1500, config ) == NULL)
  122.                break;
  123.             parse_line( line_in );
  124.             ++line_no;
  125.          }
  126.  
  127.          /*
  128.           *  if we changed any modes, reset them b4 we write them to tde.exe.
  129.           */
  130.          in_modes.insert        = modes[Ins];
  131.          in_modes.indent        = modes[Ind];
  132.          in_modes.ptab_size     = modes[PTAB];
  133.          in_modes.ltab_size     = modes[LTAB];
  134.          in_modes.smart_tab     = modes[Smart];
  135.          in_modes.control_z     = modes[Write_Z];
  136.          in_modes.crlf          = modes[Crlf];
  137.          in_modes.trailing      = modes[Trim];
  138.          in_modes.show_eol      = modes[Eol];
  139.          in_modes.word_wrap     = modes[WW];
  140.          in_modes.left_margin   = modes[Left];
  141.          in_modes.parg_margin   = modes[Para];
  142.          in_modes.right_margin  = modes[Right];
  143.          in_modes.cursor_size   = modes[Size];
  144.          in_modes.do_backups    = modes[Backup];
  145.          in_modes.ruler         = modes[Ruler];
  146.          in_modes.date_style    = modes[Date];
  147.          in_modes.time_style    = modes[Time];
  148.          in_modes.inflate_tabs  = modes[InflateTabs];
  149.          in_modes.search_case   = modes[Initcase];
  150.          in_modes.right_justify = modes[JustRM];
  151.  
  152.          fseek( tde_exe, KEYS_OFFSET, SEEK_SET );
  153.          fwrite( (void *)&key_func, sizeof(KEY_FUNC), 1, tde_exe );
  154.          fseek( tde_exe, TWO_KEY_OFFSET, SEEK_SET );
  155.          fwrite( (void *)&two_key_list, sizeof(TWO_KEY), 1, tde_exe );
  156.          fseek( tde_exe, MACRO_OFFSET, SEEK_SET );
  157.          fwrite( (void *)¯os, sizeof(MACRO), 1, tde_exe );
  158.          fseek( tde_exe, COLOR_OFFSET, SEEK_SET );
  159.          fwrite( (void *)&temp_colours, sizeof(COLORS), 1, tde_exe );
  160.          fseek( tde_exe, MODE_OFFSET, SEEK_SET );
  161.          fwrite( (void *)&in_modes, sizeof( MODE_INFO ), 1, tde_exe );
  162.          fseek( tde_exe, SORT_OFFSET, SEEK_SET );
  163.          fwrite( (void *)&sort_order, sizeof( SORT_ORDER ), 1, tde_exe );
  164.          fclose( config );
  165.          printf( "\n\n    Configuration file read.  Press a key to continue :" );
  166.          getkey( );
  167.       }
  168.    }
  169.    cls( );
  170. }
  171.  
  172.  
  173. /*
  174.  * Name:    parse_line
  175.  * Purpose: real work horse of the configuration utility, figure out what
  176.  *          we need to do with each line of the config file.
  177.  * Date:    June 5, 1992
  178.  * Passed:  line:  line that contains the text to parse
  179.  */
  180. void parse_line( char *line )
  181. {
  182. char key[1042];         /* buffer to hold any token that we parse */
  183. char *residue;          /* pointer to next item in line, if it exists */
  184. int key_no;             /* index into key array */
  185. int parent_key;         /* 1st of two-combination keys */
  186. int color;              /* color field */
  187. int mode_index;         /* index in mode array */
  188. int func_no;            /* function number we want to assign to a key */
  189. int color_no;           /* attribute we want to assign to a color field */
  190. int mode_no;            /* mode number we want to assign to a mode */
  191. int found;              /* boolean, did we find a valid key, color, or mode? */
  192. int i;
  193.  
  194.    /*
  195.     * find the first token and put it in key.  residue points to next token.
  196.     */
  197.    residue = parse_token( line, key );
  198.    if (*key != '\0' && *key != ';') {
  199.       if (strlen( key ) > 1) {
  200.          /*
  201.           * try to find a valid key
  202.           */
  203.          found = FALSE;
  204.          key_no = search( key, valid_keys, AVAIL_KEYS-1 );
  205.          if (key_no != ERROR) {
  206.             /*
  207.              * find the function assignment
  208.              */
  209.             found = TRUE;
  210.             if (residue != NULL) {
  211.                residue = parse_token( residue, key );
  212.  
  213.                /*
  214.                 * if this is not a comment, find the function to assign
  215.                 *   to key.  clear any previous macro or key assignment.
  216.                 */
  217.                if (*key != '\0' && *key != ';') {
  218.                   func_no = search( key, valid_func, NUM_FUNC );
  219.                   if (func_no != ERROR) {
  220.                      clear_previous_twokey( key_no );
  221.                      clear_previous_macro( key_no );
  222.                      key_func.key[key_no] = func_no;
  223.                      if (func_no == PlayBack)
  224.                         parse_macro( key_no, residue );
  225.                   } else {
  226.                      parent_key = key_no;
  227.  
  228.                      /*
  229.                       * was the second key one letter?
  230.                       */
  231.                      if (strlen( key ) == 1) {
  232.                         key_no = *key;
  233.                         residue = parse_token( residue, key );
  234.                         if (*key != '\0' && *key != ';') {
  235.                            func_no = search( key, valid_func, NUM_FUNC );
  236.                            if (func_no != ERROR && func_no != PlayBack) {
  237.                               if (insert_twokey( parent_key+256, key_no,
  238.                                                           func_no ) == ERROR) {
  239.                                  printf( "==> %s", line_in );
  240.                                  printf( "Out of room for two-key: line %u  : function %s\n",
  241.                                       line_no, key );
  242.                               }
  243.                            } else {
  244.                               printf( "==> %s", line_in );
  245.                               if ( func_no == ERROR)
  246.                                  printf( "Unrecognized function: line %u  : function %s\n",
  247.                                          line_no, key );
  248.                               else
  249.                                  printf( "Cannot assign a macro to two-keys: line %u  : function %s\n",
  250.                                          line_no, key );
  251.                            }
  252.                         }
  253.                      } else {
  254.                         residue = parse_token( residue, key );
  255.                         key_no = search( key, valid_keys, AVAIL_KEYS-1 );
  256.                         if (key_no != ERROR && *key != '\0' && *key != ';') {
  257.                            func_no = search( key, valid_func, NUM_FUNC );
  258.                            if (func_no != ERROR && func_no != PlayBack) {
  259.                               if (insert_twokey( parent_key+256, key_no+256,
  260.                                                         func_no )  == ERROR) {
  261.                                  printf( "==> %s", line_in );
  262.                                  printf( "Out of room for two-key: line %u  : function %s\n",
  263.                                       line_no, key );
  264.                               }
  265.                            } else {
  266.                               printf( "==> %s", line_in );
  267.                               if ( func_no == ERROR)
  268.                                  printf( "Unrecognized function: line %u  : function %s\n",
  269.                                          line_no, key );
  270.                               else
  271.                                  printf( "Cannot assign a macro to two-keys: line %u  : function %s\n",
  272.                                          line_no, key );
  273.                            }
  274.                         } else {
  275.                            printf( "==> %s", line_in );
  276.                            printf( "Unrecognized function: line %u  : function %s\n",
  277.                                    line_no, key );
  278.                         }
  279.                      }
  280.                   }
  281.                }
  282.             }
  283.          }
  284.  
  285.          /*
  286.           * valid key not found, now try a valid color
  287.           */
  288.          if (!found) {
  289.             color = search( key, valid_colors, (NUM_COLORS * 2) - 1 );
  290.             if (color != ERROR) {
  291.                if (*key == 'm')
  292.                   i = 0;
  293.                else
  294.                   i = 1;
  295.                found = TRUE;
  296.                if (residue != NULL) {
  297.                   residue = parse_token( residue, key );
  298.  
  299.                   /*
  300.                    * we found a color field and attribute.  now, make sure
  301.                    *   everything is everything before we assign the attribute
  302.                    *   to the color field.
  303.                    */
  304.                   if (*key != '\0' && *key != ';') {
  305.                      color_no = atoi( key );
  306.                      if (color_no >= 0 && color_no <= 127)
  307.                         temp_colours.clr[i][color] = color_no;
  308.                      else {
  309.                         printf( "==> %s", line_in );
  310.                         printf( "Color number out of range: line %u  : number %s\n",
  311.                                  line_no, key );
  312.                      }
  313.                   }
  314.                }
  315.             }
  316.          }
  317.  
  318.          /*
  319.           * valid color not found, now try a valid mode
  320.           */
  321.          if (!found) {
  322.             mode_index = search( key, valid_modes, NUM_MODES-1 );
  323.             if (mode_index != ERROR) {
  324.                found = TRUE;
  325.  
  326.                /*
  327.                 * if we find a valid mode, we need to search different
  328.                 *   option arrays before we find a valid assignment.
  329.                 */
  330.                if (residue != NULL) {
  331.                   residue = parse_token( residue, key );
  332.                   if (*key != '\0' && *key != ';') {
  333.                      switch ( mode_index ) {
  334.                         case Ins         :
  335.                         case Ind         :
  336.                         case Smart       :
  337.                         case Trim        :
  338.                         case Eol         :
  339.                         case Backup      :
  340.                         case Ruler       :
  341.                         case InflateTabs :
  342.                         case JustRM      :
  343.                            mode_no = search( key, off_on, 1 );
  344.                            if (mode_no == ERROR) {
  345.                               printf( "==> %s", line_in );
  346.                               printf( "Off/On error: " );
  347.                            }
  348.                            break;
  349.                         case LTAB     :
  350.                         case PTAB     :
  351.                            mode_no = atoi( key );
  352.                            if (mode_no > 520 || mode_no < 1) {
  353.                               mode_no = ERROR;
  354.                               printf( "==> %s", line_in );
  355.                               printf( "Tab error: " );
  356.                            }
  357.                            break;
  358.                         case Left    :
  359.                            mode_no = atoi( key );
  360.                            if (mode_no < 1 || mode_no > modes[Right]) {
  361.                               mode_no = ERROR;
  362.                               printf( "==> %s", line_in );
  363.                               printf( "Left margin error: " );
  364.                            } else
  365.                               --mode_no;
  366.                            break;
  367.                         case Para    :
  368.                            mode_no = atoi( key );
  369.                            if (mode_no < 1 || mode_no > modes[Right]) {
  370.                               mode_no = ERROR;
  371.                               printf( "==> %s", line_in );
  372.                               printf( "Paragraph margin error: " );
  373.                            } else
  374.                               --mode_no;
  375.                            break;
  376.                         case Right   :
  377.                            mode_no = atoi( key );
  378.                            if (mode_no < modes[Left] || mode_no > 1040) {
  379.                               mode_no = ERROR;
  380.                               printf( "==> %s", line_in );
  381.                               printf( "Right margin error: " );
  382.                            } else
  383.                               --mode_no;
  384.                            break;
  385.                         case Crlf    :
  386.                            mode_no = search( key, valid_crlf, 1 );
  387.                            if (mode_no == ERROR) {
  388.                               printf( "==> %s", line_in );
  389.                               printf( "CRLF or LF error: " );
  390.                            }
  391.                            break;
  392.                         case WW      :
  393.                            mode_no = search( key, valid_wraps, 2 );
  394.                            if (mode_no == ERROR) {
  395.                               printf( "==> %s", line_in );
  396.                               printf( "Word wrap error: " );
  397.                            }
  398.                            break;
  399.                         case Size    :
  400.                            mode_no = search( key, valid_cursor, 1 );
  401.                            if (mode_no == ERROR) {
  402.                               printf( "==> %s", line_in );
  403.                               printf( "Cursor size error: " );
  404.                            }
  405.                            break;
  406.                         case Write_Z :
  407.                            mode_no = search( key, valid_z, 1 );
  408.                            if (mode_no == ERROR) {
  409.                               printf( "==> %s", line_in );
  410.                               printf( "Control Z error: " );
  411.                            }
  412.                            break;
  413.                         case Date    :
  414.                            mode_no = search( key, valid_dates, 5 );
  415.                            if (mode_no == ERROR) {
  416.                               printf( "==> %s", line_in );
  417.                               printf( "Date format error: " );
  418.                            }
  419.                            break;
  420.                         case Time    :
  421.                            mode_no = search( key, valid_times, 1 );
  422.                            if (mode_no == ERROR) {
  423.                               printf( "==> %s", line_in );
  424.                               printf( "Time format error: " );
  425.                            }
  426.                            break;
  427.                         case Initcase    :
  428.                            mode_no = search( key, init_case_modes, 1 );
  429.                            if (mode_no == ERROR) {
  430.                               printf( "==> %s", line_in );
  431.                               printf( "Initial Case Mode error: " );
  432.                            }
  433.                            break;
  434.                         case Match   :
  435.                            for (i=0; i<256; i++)
  436.                               sort_order.match[i] = (char)i;
  437.                            new_sort_order( key, sort_order.match );
  438.                            break;
  439.                         case Ignore  :
  440.                            for (i=0; i<256; i++)
  441.                               sort_order.ignore[i] = (char)i;
  442.                            for (i=65; i<91; i++)
  443.                               sort_order.ignore[i] = (char)(i + 32);
  444.                            new_sort_order( key, sort_order.ignore );
  445.                            break;
  446.                      }
  447.                      if (mode_no != ERROR)
  448.                         modes[mode_index] = mode_no;
  449.                      else
  450.                         printf( " line = %u  :  unknown mode = %s\n",
  451.                               line_no, key );
  452.                   }
  453.                }
  454.             }
  455.          }
  456.          if (!found) {
  457.             printf( "==> %s", line_in );
  458.             printf( "Unrecognized editor setting: line %u  :  %s\n", line_no, key );
  459.          }
  460.       }
  461.    }
  462. }
  463.  
  464.  
  465. /*
  466.  * Name:    parse_token
  467.  * Purpose: given an input line, find the first token
  468.  * Date:    June 5, 1992
  469.  * Passed:  line:  line that contains the text to parse
  470.  *          token:   buffer to hold token
  471.  * Returns: pointer in line to start next token search.
  472.  * Notes:   assume tokens are delimited by spaces.
  473.  */
  474. char *parse_token( char *line, char *token )
  475. {
  476.    /*
  477.     * skip over any leading spaces.
  478.     */
  479.    while (*line == ' ')
  480.       ++line;
  481.  
  482.    /*
  483.     * put the characters into the token array until we run into a space
  484.     *   or the terminating '\0';
  485.     */
  486.    while (*line != ' ' && *line != '\0' && *line != '\n')
  487.       *token++ = *line++;
  488.    *token = '\0';
  489.  
  490.    /*
  491.     * return what's left on the line, if anything.
  492.     */
  493.    if (*line != '\0' && *line != '\n')
  494.       return( line );
  495.    else
  496.       return( NULL );
  497. }
  498.  
  499.  
  500. /*
  501.  * Name:    search
  502.  * Purpose: binary search a CONFIG_DEFS structure
  503.  * Date:    June 5, 1992
  504.  * Passed:  token:  token to search for
  505.  *          list:   list of valid tokens
  506.  *          num:    number of valid tokens in list
  507.  * Returns: value of token assigned to matching token.
  508.  * Notes:   do a standard binary search.
  509.  *          instead of returning mid, lets return the value of the token
  510.  *          assigned to mid.
  511.  */
  512. int  search( char *token, CONFIG_DEFS list[], int num )
  513. {
  514. int bot;
  515. int mid;
  516. int top;
  517. int rc;
  518.  
  519.    bot = 0;
  520.    top = num;
  521.    while (bot <= top) {
  522.       mid = (bot + top) / 2;
  523.       rc = stricmp( token, list[mid].key );
  524.       if (rc == 0)
  525.          return( list[mid].key_index );
  526.       else if (rc < 0)
  527.          top = mid - 1;
  528.       else
  529.          bot = mid + 1;
  530.    }
  531.    return( ERROR );
  532. }
  533.  
  534.  
  535. /*
  536.  * Name:    parse_macro
  537.  * Purpose: separate literals from keys in a macro definition
  538.  * Date:    June 5, 1992
  539.  * Passed:  macro_key:  key that we are a assigning a macro to
  540.  *          residue:    pointer to macro defs
  541.  * Notes:   for each token in macro def, find out if it's a literal or a
  542.  *             function key.
  543.  *          a literal begins with a ".  to put a " in a macro def, precede
  544.  *             a " with a ".
  545.  */
  546. void parse_macro( int macro_key, char *residue )
  547. {
  548. int  rc;
  549. char literal[1042];
  550. char *l;
  551. int  key_no;
  552.  
  553.    /*
  554.     * reset any previous macro def.
  555.     */
  556.    initialize_macro( macro_key );
  557.    while (residue != NULL) {
  558.       /*
  559.        * skip over any leading spaces.
  560.        */
  561.       while (*residue == ' ')
  562.          ++residue;
  563.  
  564.       /*
  565.        * done if we hit a comment
  566.        */
  567.       if (*residue == ';')
  568.          residue = NULL;
  569.  
  570.       /*
  571.        * check for a literal.
  572.        */
  573.       else if (*residue == '\"') {
  574.          rc = parse_literal( macro_key, residue, literal, &residue );
  575.          if (rc == OK) {
  576.             l = literal;
  577.             while (*l != '\0'  &&  rc == OK) {
  578.                rc = record_keys( macro_key, *l );
  579.                ++l;
  580.             }
  581.          } else {
  582.             printf( "==> %s", line_in );
  583.             printf( "Literal not recognized: line %u  : literal  %s\n", line_no, literal );
  584.          }
  585.  
  586.       /*
  587.        * check for a function key.
  588.        */
  589.       } else {
  590.          residue = parse_token( residue, literal );
  591.          key_no = search( literal, valid_keys, AVAIL_KEYS );
  592.          if (key_no != ERROR)
  593.             record_keys( macro_key, key_no+256 );
  594.          else {
  595.             printf( "==> %s", line_in );
  596.             printf( "Unrecognized key: line %u  : key %s\n", line_no, literal );
  597.          }
  598.       }
  599.    }
  600.    check_macro( macro_key );
  601. }
  602.  
  603.  
  604. /*
  605.  * Name:    parse_literal
  606.  * Purpose: get all letters in a literal
  607.  * Date:    June 5, 1992
  608.  * Passed:  macro_key:  key that we are a assigning a macro to
  609.  *          line:       current line position
  610.  *          literal:    buffer to hold literal
  611.  *          residue:    pointer to next token in line
  612.  * Notes:   a literal begins with a ".  to put a " in a macro def, precede
  613.  *             a " with a ".
  614.  */
  615. int  parse_literal( int macro_key, char *line, char *literal, char **residue )
  616. {
  617. int quote_state = 1;    /* we've already seen one " before we get here */
  618.  
  619.    line++;
  620.    /*
  621.     * put the characters into the literal array until we run into the
  622.     *   end of literal or terminating '\0';
  623.     */
  624.    while (*line != '\0' && *line != '\n') {
  625.       if (*line != '\"')
  626.          *literal++ = *line++;
  627.       else {
  628.          if (*(line+1) == '\"') {
  629.             *literal++ = '\"';
  630.             line++;
  631.             line++;
  632.          } else {
  633.             line++;
  634.             --quote_state;
  635.             break;
  636.          }
  637.       }
  638.    }
  639.    *literal = '\0';
  640.  
  641.    /*
  642.     * return what's left on the line, if anything.
  643.     */
  644.    if (*line != '\0' && *line != '\n')
  645.       *residue = line;
  646.    else
  647.       *residue = NULL;
  648.    if (quote_state != 0) {
  649.       *residue = NULL;
  650.       return( ERROR );
  651.    } else
  652.       return( OK );
  653. }
  654.  
  655.  
  656. /*
  657.  * Name:    initialize_macro
  658.  * Purpose: initialize the first key of a macro def
  659.  * Date:    June 5, 1992
  660.  * Passed:  macro_key:  key that we are a assigning a macro to
  661.  * Notes:   this function is ported directly from tde.
  662.  */
  663. void initialize_macro( int macro_key )
  664. {
  665. register int next;
  666. int  prev;
  667.  
  668.    next = macros.first_stroke[macro_key];
  669.  
  670.    /*
  671.     * initialize the first key in a macro def
  672.     */
  673.    if (next != STROKE_LIMIT+1) {
  674.       do {
  675.          prev = next;
  676.          next = macros.strokes[next].next;
  677.          macros.strokes[prev].key  = MAX_KEYS+1;
  678.          macros.strokes[prev].next = STROKE_LIMIT+1;
  679.          ++stroke_count;
  680.       } while (next != -1);
  681.    }
  682.  
  683.    /*
  684.     * find the first open space and initialize
  685.     */
  686.    for (next=0; macros.strokes[next].next != STROKE_LIMIT+1;)
  687.       next++;
  688.    macros.first_stroke[macro_key] = next;
  689.    macros.strokes[next].key  = -1;
  690.    macros.strokes[next].next = -1;
  691. }
  692.  
  693.  
  694. /*
  695.  * Name:    clear_previous_macro
  696.  * Purpose: clear any macro previously assigned to a key
  697.  * Date:    June 5, 1992
  698.  * Passed:  macro_key:  key that we are a assigning a macro to
  699.  * Notes:   this function is ported directly from tde.
  700.  */
  701. void clear_previous_macro( int macro_key )
  702. {
  703. register int next;
  704. int prev;
  705.  
  706.    next = macros.first_stroke[macro_key];
  707.  
  708.    /*
  709.     * if key has already been assigned to a macro, clear macro def.
  710.     */
  711.    if (next != STROKE_LIMIT+1) {
  712.       do {
  713.          prev = next;
  714.          next = macros.strokes[next].next;
  715.          macros.strokes[prev].key  = MAX_KEYS+1;
  716.          macros.strokes[prev].next = STROKE_LIMIT+1;
  717.       } while (next != -1);
  718.    }
  719.  
  720.    macros.first_stroke[macro_key] = STROKE_LIMIT+1;
  721. }
  722.  
  723.  
  724. /*
  725.  * Name:    check_macro
  726.  * Purpose: see if macro def has any valid key.  if not, clear macro
  727.  * Date:    June 5, 1992
  728.  * Passed:  macro_key:  key that we are a assigning a macro to
  729.  * Notes:   this function is ported directly from tde.
  730.  */
  731. void check_macro( int macro_key )
  732. {
  733. register int next;
  734. register int key;
  735.  
  736.    /*
  737.     * see if the macro has any keystrokes.  if not, then wipe it out.
  738.     */
  739.    key = macro_key;
  740.    if (key != 0) {
  741.       next = macros.first_stroke[key];
  742.       if (macros.strokes[next].key == -1) {
  743.          macros.strokes[next].key  = MAX_KEYS+1;
  744.          macros.strokes[next].next = STROKE_LIMIT+1;
  745.          macros.first_stroke[key-256] = STROKE_LIMIT+1;
  746.          if (key_func.key[key] == PlayBack)
  747.             key_func.key[key] = 0;
  748.       }
  749.    }
  750. }
  751.  
  752.  
  753. /*
  754.  * Name:    record_keys
  755.  * Purpose: save keystrokes in keystroke buffer
  756.  * Date:    June 5, 1992
  757.  * Passed:  line: line to display prompts
  758.  * Notes:   -1 in .next field indicates the end of a recording
  759.  *          STROKE_LIMIT+1 in .next field indicates an unused space.
  760.  *           Recall, return codes are for macros.  Since we do not allow
  761.  *           keys to be assigned to macro functions, let's just return OK;
  762.  */
  763. int  record_keys( int macro_key, int key )
  764. {
  765. register int next;
  766. register int prev;
  767. int func;
  768. int rc;
  769.  
  770.    rc = OK;
  771.    if (stroke_count == 0) {
  772.       printf( "==> %s", line_in );
  773.       printf( "No more room in macro buffer:  line %u\n",
  774.                line_no );
  775.       rc = ERROR;
  776.    } else {
  777.       func = getfunc( key );
  778.       if (func != RecordMacro && func != SaveMacro && func != LoadMacro &&
  779.           func != ClearAllMacros) {
  780.  
  781.          /*
  782.           * a -1 in the next field marks the end of the keystroke recording.
  783.           */
  784.          next = macros.first_stroke[macro_key];
  785.          if (macros.strokes[next].next != STROKE_LIMIT+1) {
  786.             while (macros.strokes[next].next != -1)
  787.                next = macros.strokes[next].next;
  788.          }
  789.          prev = next;
  790.  
  791.          /*
  792.           * now find an open space to record the current key.
  793.           */
  794.          if (macros.strokes[next].key != -1) {
  795.             for (; next < STROKE_LIMIT &&
  796.                          macros.strokes[next].next != STROKE_LIMIT+1;)
  797.                next++;
  798.             if (next == STROKE_LIMIT) {
  799.                for (next=0; next < prev &&
  800.                             macros.strokes[next].next != STROKE_LIMIT+1;)
  801.                   next++;
  802.             }
  803.          }
  804.          if (next == prev && macros.strokes[prev].key != -1) {
  805.             rc = ERROR;
  806.          } else {
  807.          /*
  808.           * next == prev if we are recording the initial macro node.
  809.           */
  810.             macros.strokes[prev].next = next;
  811.             macros.strokes[next].next = -1;
  812.             macros.strokes[next].key  = key;
  813.             stroke_count--;
  814.          }
  815.       }
  816.    }
  817.    return( rc );
  818. }
  819.  
  820.  
  821. /*
  822.  * Name:    new_sort_order
  823.  * Purpose: change the sort order
  824.  * Date:    October 31, 1992
  825.  * Notes:   New sort oder starts at the @ sign
  826.  */
  827. void new_sort_order( unsigned char *residue, unsigned char *sort )
  828. {
  829. int i;
  830.  
  831.    sort += 33;
  832.    for (i=33; *residue != '\0'  &&  *residue != '\n' && i <= 255; i++)
  833.       *sort++ = *residue++;
  834. }
  835.  
  836.  
  837. /*
  838.  * Name:    get_stroke_count
  839.  * Purpose: count unassigned nodes in macro buff
  840.  * Date:    June 5, 1992
  841.  * Returns: number of strokes left in macro buffer.
  842.  */
  843. int  get_stroke_count( void )
  844. {
  845. int count = 0;
  846. int i;
  847.  
  848.    for (i=0; i<STROKE_LIMIT; i++)
  849.       if (macros.strokes[i].next == STROKE_LIMIT+1)
  850.          ++count;
  851.    return( count );
  852. }
  853.  
  854.  
  855.  
  856. /*
  857.  * Name:    getfunc
  858.  * Purpose: get the function assigned to key c
  859.  * Date:    June 5, 1992
  860.  * Passed:  c:  key just pressed
  861.  * Notes:   key codes less than 256 or 0x100 are not assigned a function.
  862.  *          The codes in the range 0-255 are ASCII and extended ASCII chars.
  863.  */
  864. int  getfunc( int c )
  865. {
  866. register int i = c;
  867.  
  868.    if (i <= 256)
  869.       i = 0;
  870.    else
  871.       i = key_func.key[i-256];
  872.    return( i );
  873. }
  874.  
  875.  
  876. /*
  877.  * Name:    clear_previous_twokey
  878.  * Purpose: clear any previously assigned two-key combos
  879.  * Date:    April 1, 1993
  880.  * Passed:  macro_key:  key that we are clearing
  881.  */
  882. void clear_previous_twokey( int two_key )
  883. {
  884. int i;
  885.  
  886.    for (i=0; i < MAX_TWO_KEYS; i++) {
  887.       if (two_key == two_key_list.key[i].parent_key) {
  888.          two_key_list.key[i].parent_key = 0;
  889.          two_key_list.key[i].child_key  = 0;
  890.          two_key_list.key[i].func       = 0;
  891.       }
  892.    }
  893. }
  894.  
  895.  
  896. /*
  897.  * Name:    insert_twokey
  898.  * Purpose: find an open slot and insert the new two-key combination
  899.  * Date:    April 1, 1993
  900.  * Passed:  parent_key:  1st key
  901.  *          child_key:   2nd key
  902.  *          func_no:     function number to assign to this combo
  903.  * Notes:   find the first avaible open slot.  clear any previously defined
  904.  *          previous parent-child combo.
  905.  */
  906. int  insert_twokey( int parent_key, int child_key, int func_no )
  907. {
  908. register int i;
  909. int  rc;
  910.  
  911.    for (i=0; i < MAX_TWO_KEYS; i++) {
  912.       if (parent_key == two_key_list.key[i].parent_key) {
  913.          if (child_key == two_key_list.key[i].child_key) {
  914.             two_key_list.key[i].parent_key = 0;
  915.             two_key_list.key[i].child_key  = 0;
  916.             two_key_list.key[i].func       = 0;
  917.          }
  918.       }
  919.    }
  920.    for (i=0; i < MAX_TWO_KEYS; i++) {
  921.       if (two_key_list.key[i].parent_key == 0) {
  922.          two_key_list.key[i].parent_key = parent_key;
  923.          two_key_list.key[i].child_key  = child_key;
  924.          two_key_list.key[i].func       = func_no;
  925.          break;
  926.       }
  927.    }
  928.    rc = OK;
  929.    if (i == MAX_TWO_KEYS)
  930.       rc = ERROR;
  931.    return( rc );
  932. }
  933.