home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1707 / opts.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  9.5 KB  |  459 lines

  1. /* opts.c */
  2.  
  3. /* Author:
  4.  *    Steve Kirkendall
  5.  *    16820 SW Tallac Way
  6.  *    Beaverton, OR 97006
  7.  *    kirkenda@jove.cs.pdx.edu, or ...uunet!tektronix!psueea!jove!kirkenda
  8.  */
  9.  
  10.  
  11. /* This file contains the code that manages the run-time options -- The 
  12.  * values that can be modified via the "set" command.
  13.  */
  14.  
  15. #include "config.h"
  16. #include "vi.h"
  17. #ifndef NULL
  18. #define NULL (char *)0
  19. #endif
  20. extern char    *getenv();
  21.  
  22. /* These are the default values of all options */
  23. char    o_autoindent[1] =    {FALSE};
  24. char    o_autowrite[1] =     {FALSE};
  25. #ifndef NO_CHARATTR
  26. char    o_charattr[1] =        {FALSE};
  27. #endif
  28. char    o_columns[3] =        {80, 32, 255};
  29. char    o_directory[30] =    TMPDIR;
  30. char    o_errorbells[1] =    {TRUE};
  31. char    o_exrefresh[1] =    {TRUE};
  32. #ifndef NO_SENTENCE
  33. char    o_hideformat[1] =    {FALSE};
  34. #endif
  35. char    o_ignorecase[1] =    {FALSE};
  36. #ifndef NO_EXTENSIONS
  37. char    o_inputmode[1] =    {FALSE};
  38. #endif
  39. char    o_keytime[3] =        {2, 0, 5};
  40. char    o_keywordprg[80] =    KEYWORDPRG;
  41. char    o_lines[3] =        {25, 2, 50};    /* More lines? Enlarge kbuf */
  42. char    o_list[1] =        {FALSE};
  43. #ifndef NO_MAGIC
  44. char    o_magic[1] =        {TRUE};
  45. #endif
  46. #ifndef NO_SENTENCE
  47. char    o_paragraphs[30] =    "PPppPApa";
  48. #endif
  49. #if MSDOS
  50. char    o_pcbios[1] =        {TRUE};
  51. #endif
  52. char    o_readonly[1] =        {FALSE};
  53. char    o_report[3] =        {5, 1, 127};
  54. char    o_scroll[3] =        {12, 1, 127};
  55. #ifndef NO_SENTENCE
  56. char    o_sections[30] =    "SEseSHsh";
  57. #endif
  58. char    o_shell[60] =        "/bin/sh";
  59. char    o_shiftwidth[3] =    {8, 1, 255};
  60. #ifndef    NO_SHOWMODE
  61. char    o_showmode[1] =        {FALSE};
  62. #endif
  63. char    o_sidescroll[3] =    {8, 1, 40};
  64. char    o_sync[1] =        {FALSE};
  65. char    o_tabstop[3] =        {8, 1, 40};
  66. char    o_term[30] =        "?";
  67. char    o_vbell[1] =        {TRUE};
  68. char    o_warn[1] =        {TRUE};
  69. char    o_wrapmargin[3] =    {0, 0, 255};
  70. char    o_wrapscan[1] =        {TRUE};
  71.  
  72.  
  73. /* The following describes the names & types of all options */
  74. #define BOOL    0
  75. #define    NUM    1
  76. #define    STR    2
  77. #define SET    0x01    /* this option has had its value altered */
  78. #define CANSET    0x02    /* this option can be set at any time */
  79. #define RCSET    0x06    /* this option can be set in a .exrc file only */
  80. #define MR    0x40    /* does this option affect the way text is displayed? */
  81. struct
  82. {
  83.     char    *name;    /* name of an option */
  84.     char    *nm;    /* short name of an option */
  85.     char    type;    /* type of an option */
  86.     char    flags;    /* boolean: has this option been set? */
  87.     char    *value;    /* value */
  88. }
  89.     opts[] =
  90. {
  91.     /* name            type    flags    redraw    value */
  92.     { "autoindent",    "ai",    BOOL,    CANSET    ,    o_autoindent    },
  93.     { "autowrite",    "aw",    BOOL,    CANSET    ,    o_autowrite    },
  94. #ifndef NO_CHARATTR
  95.     { "charattr",    "ca",    BOOL,    CANSET    | MR,    o_charattr    },
  96. #endif
  97.     { "columns",    "co",    NUM,    SET    ,    o_columns    },
  98.     { "directory",    "dir",    STR,    RCSET    ,    o_directory    },
  99.     { "errorbells",    "eb",    BOOL,    CANSET    ,    o_errorbells    },
  100.     { "exrefresh",    "er",    BOOL,    CANSET    ,    o_exrefresh    },
  101. #ifndef NO_SENTENCE
  102.     { "hideformat",    "hf",    BOOL,    CANSET    | MR,    o_hideformat    },
  103. #endif
  104.     { "ignorecase",    "ic",    BOOL,    CANSET    ,    o_ignorecase    },
  105. #ifndef NO_EXTENSIONS
  106.     { "inputmode",    "im",    BOOL,    CANSET    ,    o_inputmode    },
  107. #endif
  108.     { "keytime",    "kt",    NUM,    CANSET    ,    o_keytime    },
  109.     { "keywordprg",    "kp",    STR,    CANSET    ,    o_keywordprg    },
  110.     { "lines",    "ls",    NUM,    SET    ,    o_lines        },
  111.     { "list",    "li",    BOOL,    CANSET    | MR,    o_list        },
  112. #ifndef NO_MAGIC
  113.     { "magic",    "ma",    BOOL,    CANSET    ,    o_magic        },
  114. #endif
  115. #ifndef NO_SENTENCE
  116.     { "paragraphs",    "pa",    STR,    CANSET    ,    o_paragraphs    },
  117. #endif
  118. #if    MSDOS
  119.     { "pcbios",    "pc",    BOOL,    SET    ,    o_pcbios    },
  120. #endif
  121.     { "readonly",    "ro",    BOOL,    CANSET    ,    o_readonly    },
  122.     { "report",    "re",    NUM,    CANSET    ,    o_report    },
  123.     { "scroll",    "sc",    NUM,    CANSET    ,    o_scroll    },
  124. #ifndef NO_SENTENCE
  125.     { "sections",    "se",    STR,    CANSET    ,    o_sections    },
  126. #endif
  127.     { "shell",    "sh",    STR,    CANSET    ,    o_shell        },
  128. #ifndef    NO_SHOWMODE
  129.     { "showmode",    "sho",    BOOL,    CANSET    ,    o_showmode    },
  130. #endif
  131.     { "shiftwidth",    "sw",    NUM,    CANSET    ,    o_shiftwidth    },
  132.     { "sidescroll",    "ss",    NUM,    CANSET    ,    o_sidescroll    },
  133.     { "sync",    "sy",    BOOL,    CANSET    ,    o_sync        },
  134.     { "tabstop",    "ts",    NUM,    CANSET    | MR,    o_tabstop    },
  135.     { "term",    "te",    STR,    SET    ,    o_term        },
  136.     { "vbell",    "vb",    BOOL,    CANSET    ,    o_vbell        },
  137.     { "warn",    "wa",    BOOL,    CANSET    ,    o_warn        },
  138.     { "wrapmargin",    "wm",    NUM,    CANSET    ,    o_wrapmargin    },
  139.     { "wrapscan",    "ws",    BOOL,    CANSET    ,    o_wrapscan    },
  140.     { NULL, NULL, 0, CANSET, NULL }
  141. };
  142.  
  143.  
  144. /* This function initializes certain options from environment variables, etc. */
  145. initopts()
  146. {
  147.     char    *val;
  148.     int    i;
  149.  
  150.     /* set some stuff from environment variables */
  151. #if    ANY_UNIX || TOS
  152.     if (val = getenv("SHELL")) /* yes, ASSIGNMENT! */
  153.     {
  154.         strcpy(o_shell, val);
  155.     }
  156.     if (val = getenv("TERM")) /* yes, ASSIGNMENT! */
  157.     {
  158.         strcpy(o_term, val);
  159.     }
  160. #endif
  161. #if    MSDOS
  162.     if (val = getenv("COMSPEC")) /* yes, ASSIGNMENT! */
  163.     {
  164.         strcpy(o_shell, val);
  165.     }
  166.     if ((val = getenv("TERM")) /* yes, ASSIGNMENT! */
  167.         && strcmp(val, "pcbios"))
  168.     {
  169.         strcpy(o_term, val);
  170.         o_pcbios[0] = 0;
  171.     }
  172.     else
  173.     {
  174.         strcpy(o_term, "pcbios");
  175.         o_pcbios[0] = 1;
  176.     }
  177. #endif
  178. #if    MSDOS || TOS
  179.     if ((val = getenv("TMP")) /* yes, ASSIGNMENT! */
  180.     ||  (val = getenv("TEMP")))
  181.         strcpy(o_directory, val);
  182. #endif
  183.  
  184.     *o_scroll = LINES / 2 - 1;
  185.  
  186.     /* disable the vbell option if we don't know how to do a vbell */
  187.     if (!has_VB)
  188.     {
  189.         for (i = 0; opts[i].value != o_vbell; i++)
  190.         {
  191.         }
  192.         opts[i].flags &= ~CANSET;
  193.         *o_vbell = FALSE;
  194.     }
  195. }
  196.  
  197. /* This function lists the current values of all options */
  198. dumpopts(all)
  199.     int    all;    /* boolean: dump all options, or just set ones? */
  200. {
  201.     int    i;
  202.     int    col;
  203.     char    nbuf[4];
  204.  
  205.     for (i = col = 0; opts[i].name; i++)
  206.     {
  207.         /* if not set and not all, ignore this option */
  208.         if (!all && !(opts[i].flags & SET))
  209.         {
  210.             continue;
  211.         }
  212.  
  213.         /* align this option in one of the columns */
  214.         if (col > 52)
  215.         {
  216.             addch('\n');
  217.             col = 0;
  218.         }
  219.         else if (col > 26)
  220.         {
  221.             while (col < 52)
  222.             {
  223.                 qaddch(' ');
  224.                 col++;
  225.             }
  226.         }
  227.         else if (col > 0)
  228.         {
  229.             while (col < 26)
  230.             {
  231.                 qaddch(' ');
  232.                 col++;
  233.             }
  234.         }
  235.  
  236.         switch (opts[i].type)
  237.         {
  238.           case BOOL:
  239.             if (!*opts[i].value)
  240.             {
  241.                 qaddch('n');
  242.                 qaddch('o');
  243.                 col += 2;
  244.             }
  245.             qaddstr(opts[i].name);
  246.             col += strlen(opts[i].name);
  247.             break;
  248.  
  249.           case NUM:
  250.             sprintf(nbuf, "%-3d", UCHAR(*opts[i].value));
  251.             qaddstr(opts[i].name);
  252.             qaddch('=');
  253.             qaddstr(nbuf);
  254.             col += 4 + strlen(opts[i].name);
  255.             break;
  256.  
  257.           case STR:
  258.             qaddstr(opts[i].name);
  259.             qaddch('=');
  260.             qaddch('"');
  261.             qaddstr(opts[i].value);
  262.             qaddch('"');
  263.             col += 3 + strlen(opts[i].name) + strlen(opts[i].value);
  264.             break;
  265.         }
  266.         exrefresh();
  267.     }
  268.     if (col > 0)
  269.     {
  270.         addch('\n');
  271.         exrefresh();
  272.     }
  273. }
  274.  
  275. /* This function saves the current configuarion of options to a file */
  276. saveopts(fd)
  277.     int    fd;    /* file descriptor to write to */
  278. {
  279.     int    i;
  280.     char    buf[256], *pos;
  281.  
  282.     /* write each set options */
  283.     for (i = 0; opts[i].name; i++)
  284.     {
  285.         /* if unset or unsettable, ignore this option */
  286.         if (!(opts[i].flags & SET) || !(opts[i].flags & CANSET))
  287.         {
  288.             continue;
  289.         }
  290.  
  291.         strcpy(buf, "set ");
  292.         pos = &buf[4];
  293.         switch (opts[i].type)
  294.         {
  295.           case BOOL:
  296.             if (!*opts[i].value)
  297.             {
  298.                 *pos++='n';
  299.                 *pos++='o';
  300.             }
  301.             strcpy(pos, opts[i].name);
  302.             strcat(pos, "\n");
  303.             break;
  304.  
  305.           case NUM:
  306.             sprintf(pos, "%s=%-3d\n", opts[i].name, *opts[i].value & 0xff);
  307.             break;
  308.  
  309.           case STR:
  310.             sprintf(pos, "%s=\"%s\"\n", opts[i].name, opts[i].value);
  311.             break;
  312.         }
  313.         twrite(fd, buf, strlen(buf));
  314.     }
  315. }
  316.  
  317.  
  318. /* This function changes the values of one or more options. */
  319. setopts(assignments)
  320.     char    *assignments;    /* a string containing option assignments */
  321. {
  322.     char    *name;        /* name of variable in assignments */
  323.     char    *value;        /* value of the variable */
  324.     char    *scan;        /* used for moving through strings */
  325.     int    i, j;
  326.  
  327.     /* for each assignment... */
  328.     for (name = assignments; *name; )
  329.     {
  330.         /* skip whitespace */
  331.         if (*name == ' ' || *name == '\t')
  332.         {
  333.             name++;
  334.             continue;
  335.         }
  336.  
  337.         /* find the value, if any */
  338.         for (scan = name; *scan >= 'a' && *scan <= 'z'; scan++)
  339.         {
  340.         }
  341.         if (*scan == '=')
  342.         {
  343.             *scan++ = '\0';
  344.             if (*scan == '"')
  345.             {
  346.                 value = ++scan;
  347.                 while (*scan && *scan != '"')
  348.                 {
  349.                     scan++;
  350.                 }
  351.                 if (*scan)
  352.                 {
  353.                     *scan++ = '\0';
  354.                 }
  355.             }
  356.             else
  357.             {
  358.                 value = scan;
  359.                 while (*scan && *scan != ' ' && *scan != '\t')
  360.                 {
  361.                     scan++;
  362.                 }
  363.                 if (*scan)
  364.                 {
  365.                     *scan++ = '\0';
  366.                 }
  367.             }
  368.         }
  369.         else
  370.         {
  371.             if (*scan)
  372.             {
  373.                 *scan++ = '\0';
  374.             }
  375.             value = NULL;
  376.             if (name[0] == 'n' && name[1] == 'o')
  377.             {
  378.                 name += 2;
  379.             }
  380.         }
  381.  
  382.         /* find the variable */
  383.         for (i = 0;
  384.              opts[i].name && strcmp(opts[i].name, name) && strcmp(opts[i].nm, name);
  385.              i++)
  386.         {
  387.         }
  388.  
  389.         /* change the variable */
  390.         if (!opts[i].name)
  391.         {
  392.             msg("invalid option name \"%s\"", name);
  393.         }
  394.         else if ((opts[i].flags & CANSET) != CANSET)
  395.         {
  396.             msg("option \"%s\" can't be altered", name);
  397.         }
  398.         else if ((opts[i].flags & RCSET) != CANSET && nlines >= 1L)
  399.         {
  400.             msg("option \"%s\" can only be set in a %s file", name, EXRC);
  401.         }
  402.         else if (value)
  403.         {
  404.             switch (opts[i].type)
  405.             {
  406.               case BOOL:
  407.                 msg("option \"[no]%s\" is boolean", name);
  408.                 break;
  409.  
  410.               case NUM:
  411.                 j = atoi(value);
  412.                 if (j == 0 && *value != '0')
  413.                 {
  414.                     msg("option \"%s\" must have a numeric value", name);
  415.                 }
  416.                 else if (j < opts[i].value[1] || j > (opts[i].value[2] & 0xff))
  417.                 {
  418.                     msg("option \"%s\" must have a value between %d and %d",
  419.                         name, opts[i].value[1], opts[i].value[2] & 0xff);
  420.                 }
  421.                 else
  422.                 {
  423.                     *opts[i].value = atoi(value);
  424.                     opts[i].flags |= SET;
  425.                 }
  426.                 break;
  427.  
  428.               case STR:
  429.                 strcpy(opts[i].value, value);
  430.                 opts[i].flags |= SET;
  431.                 break;
  432.             }
  433.             if (opts[i].flags & MR)
  434.             {
  435.                 mustredraw = TRUE;
  436.             }
  437.         }
  438.         else /* valid option, no value */
  439.         {
  440.             if (opts[i].type == BOOL)
  441.             {
  442.                 *opts[i].value = (name[-1] != 'o');
  443.                 opts[i].flags |= SET;
  444.                 if (opts[i].flags & MR)
  445.                 {
  446.                     mustredraw = TRUE;
  447.                 }
  448.             }
  449.             else
  450.             {
  451.                 msg("option \"%s\" must be given a value", name);
  452.             }
  453.         }
  454.  
  455.         /* move on to the next option */
  456.         name = scan;
  457.     }
  458. }
  459.