home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / apps / text_ed / elv16b2 / st / opts.c < prev    next >
C/C++ Source or Header  |  1992-05-13  |  18KB  |  811 lines

  1. /* opts.c */
  2.  
  3. /* Author:
  4.  *    Steve Kirkendall
  5.  *    14407 SW Teal Blvd. #C
  6.  *    Beaverton, OR 97005
  7.  *    kirkenda@cs.pdx.edu
  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. #include "ctype.h"
  18. #ifndef NULL
  19. #define NULL (char *)0
  20. #endif
  21. extern char    *getenv();
  22.  
  23. /* maximum width to permit for strings, including ="" */
  24. #define MAXWIDTH 20
  25.  
  26. /* These are the default values of all options */
  27. char    o_autoindent[1] =    {FALSE};
  28. char    o_autoprint[1] =    {TRUE};
  29. char    o_autotab[1] =        {TRUE};
  30. char    o_autowrite[1] =     {FALSE};
  31. char    o_columns[3] =        {80, 32, 255};
  32. char    o_directory[30] =    TMPDIR;
  33. char    o_edcompatible[1] =    {FALSE};
  34. char    o_equalprg[80] =    {"fmt"};
  35. char    o_errorbells[1] =    {TRUE};
  36. char    o_exrefresh[1] =    {TRUE};
  37. char    o_ignorecase[1] =    {FALSE};
  38. char    o_keytime[3] =        {2, 0, 50};
  39. char    o_keywordprg[80] =    {KEYWORDPRG};
  40. char    o_lines[3] =        {25, 2, 96};
  41. char    o_list[1] =        {FALSE};
  42. char    o_number[1] =        {FALSE};
  43. char    o_readonly[1] =        {FALSE};
  44. char    o_remap[1] =        {TRUE};
  45. char    o_report[3] =        {5, 1, 127};
  46. char    o_scroll[3] =        {12, 1, 127};
  47. char    o_shell[60] =        SHELL;
  48. char    o_shiftwidth[3] =    {8, 1, 255};
  49. char    o_sidescroll[3] =    {8, 1, 40};
  50. char    o_sync[1] =        {NEEDSYNC};
  51. char    o_tabstop[3] =        {8, 1, 40};
  52. char    o_term[30] =        "?";
  53. char    o_flash[1] =        {TRUE};
  54. char    o_warn[1] =        {TRUE};
  55. char    o_wrapscan[1] =        {TRUE};
  56.  
  57. #ifndef CRUNCH
  58. char    o_beautify[1] =        {FALSE};
  59. char    o_exrc[1] =        {FALSE};
  60. char    o_mesg[1] =        {TRUE};
  61. char    o_more[1] =        {TRUE};
  62. char    o_nearscroll[3] =    {15, 0, 255};
  63. char    o_novice[1] =        {FALSE};
  64. char    o_prompt[1] =        {TRUE};
  65. char    o_taglength[3] =    {0, 0, 30};
  66. char    o_terse[1] =        {FALSE};
  67. char    o_window[3] =        {0, 1, 24};
  68. char    o_wrapmargin[3] =    {0, 0, 255};
  69. char    o_writeany[1] =        {FALSE};
  70. #endif
  71.  
  72. #ifndef NO_ERRLIST
  73. char    o_cc[30] =        {CC_COMMAND};
  74. char    o_make[30] =        {MAKE_COMMAND};
  75. #endif
  76.  
  77. #ifndef NO_CHARATTR
  78. char    o_charattr[1] =        {FALSE};
  79. #endif
  80.  
  81. #ifndef NO_DIGRAPH
  82. char    o_digraph[1] =        {FALSE};
  83. char    o_flipcase[80]
  84. # ifdef CS_IBMPC
  85.     = {"\207\200\201\232\202\220\204\216\206\217\221\222\224\231\244\245"}
  86. # endif
  87. # ifdef CS_LATIN1
  88.     /* initialized by initopts() */
  89. # endif
  90.     ;
  91. #endif
  92.  
  93. #ifndef NO_SENTENCE
  94. char    o_hideformat[1] =    {FALSE};
  95. #endif
  96.  
  97. #ifndef NO_EXTENSIONS
  98. char    o_inputmode[1] =    {FALSE};
  99. char    o_ruler[1] =        {FALSE};
  100. #endif
  101.  
  102. #ifndef NO_MAGIC
  103. char    o_magic[1] =        {TRUE};
  104. #endif
  105.  
  106. #ifndef NO_MODELINES
  107. char    o_modelines[1] =    {FALSE};
  108. #endif
  109.  
  110. #ifndef NO_SENTENCE
  111. char    o_paragraphs[30] =    "PPppIPLPQP";
  112. char    o_sections[30] =    "NHSHSSSEse";
  113. #endif
  114.  
  115. #if MSDOS
  116. char    o_pcbios[1] =        {TRUE};
  117. #endif
  118.  
  119. #ifndef NO_SHOWMATCH
  120. char    o_showmatch[1] =    {FALSE};
  121. #endif
  122.  
  123. #ifndef    NO_SHOWMODE
  124. char    o_smd[1] =        {FALSE};
  125. #endif
  126.  
  127. #if MINT
  128. char    o_stbios[1] =        {FALSE};
  129. char    o_crlf[1] =        {TRUE};
  130. #endif
  131.  
  132.  
  133. /* The following describes the names & types of all options */
  134. #define BOOL    0
  135. #define    NUM    1
  136. #define    STR    2
  137. #define SET    0x01    /* this option has had its value altered */
  138. #define CANSET    0x02    /* this option can be set at any time */
  139. #define RCSET    0x06    /* this option can be set in a .exrc file only */
  140. #define NOSAVE    0x0a    /* this option should never be saved by mkexrc */
  141. #define WSET    0x20    /* is this the "window" size option? */
  142. #define MR    0x40    /* does this option affect the way text is displayed? */
  143. struct
  144. {
  145.     char    *name;    /* name of an option */
  146.     char    *nm;    /* short name of an option */
  147.     char    type;    /* type of an option */
  148.     char    flags;    /* boolean: has this option been set? */
  149.     char    *value;    /* value */
  150. }
  151.     opts[] =
  152. {
  153.     /* name            type    flags        value */
  154.     { "autoindent",    "ai",    BOOL,    CANSET,        o_autoindent    },
  155.     { "autoprint",    "ap",    BOOL,    CANSET,        o_autoprint    },
  156.     { "autotab",    "at",    BOOL,    CANSET,        o_autotab    },
  157.     { "autowrite",    "aw",    BOOL,    CANSET,        o_autowrite    },
  158. #ifndef CRUNCH
  159.     { "beautify",    "bf",    BOOL,    CANSET,        o_beautify    },
  160. #endif
  161. #ifndef NO_ERRLIST
  162.     { "cc",        "cc",    STR,    CANSET,        o_cc        },
  163. #endif
  164. #ifndef NO_CHARATTR
  165.     { "charattr",    "ca",    BOOL,    CANSET|MR,    o_charattr    },
  166. #endif
  167.     { "columns",    "co",    NUM,    SET|NOSAVE|MR,    o_columns    },
  168. #if MINT
  169.     { "crlf",    "cr",    BOOL,    CANSET    ,    o_crlf        },
  170. #endif
  171. #ifndef NO_DIGRAPH
  172.     { "digraph",    "dig",    BOOL,    CANSET,        o_digraph    },
  173. #endif
  174.     { "directory",    "dir",    STR,    RCSET,        o_directory    },
  175.     { "edcompatible","ed",    BOOL,    CANSET,        o_edcompatible    },
  176.     { "equalprg",    "ep",    STR,    CANSET,        o_equalprg    },
  177.     { "errorbells",    "eb",    BOOL,    CANSET,        o_errorbells    },
  178. #ifndef CRUNCH
  179.     { "exrc",    "exrc",    BOOL,    CANSET,        o_exrc        },
  180. #endif
  181.     { "exrefresh",    "er",    BOOL,    CANSET,        o_exrefresh    },
  182.     { "flash",    "vbell",BOOL,    CANSET,        o_flash        },
  183. #ifndef NO_DIGRAPH
  184.     { "flipcase",    "fc",    STR,    CANSET,        o_flipcase    },
  185. #endif
  186. #ifndef NO_SENTENCE
  187.     { "hideformat",    "hf",    BOOL,    CANSET|MR,    o_hideformat    },
  188. #endif
  189.     { "ignorecase",    "ic",    BOOL,    CANSET,        o_ignorecase    },
  190. #ifndef NO_EXTENSIONS
  191.     { "inputmode",    "im",    BOOL,    CANSET,        o_inputmode    },
  192. #endif
  193.     { "keytime",    "kt",    NUM,    CANSET,        o_keytime    },
  194.     { "keywordprg",    "kp",    STR,    CANSET,        o_keywordprg    },
  195.     { "lines",    "ls",    NUM,    SET|NOSAVE|MR,    o_lines        },
  196.     { "list",    "li",    BOOL,    CANSET|MR,    o_list        },
  197. #ifndef NO_MAGIC
  198.     { "magic",    "ma",    BOOL,    CANSET,        o_magic        },
  199. #endif
  200. #ifndef NO_ERRLIST
  201.     { "make",    "mk",    STR,    CANSET,        o_make        },
  202. #endif
  203. #ifndef CRUNCH
  204.     { "mesg",    "me",    BOOL,    CANSET,        o_mesg        },
  205. #endif
  206. #ifndef NO_MODELINES
  207.     { "modelines",    "ml",    BOOL,    CANSET,        o_modelines    },
  208. #endif
  209. #ifndef CRUNCH
  210.     { "more",    "mo",    BOOL,    CANSET,        o_more        },
  211.     { "nearscroll",    "ns",    NUM,    CANSET,        o_nearscroll    },
  212.     { "novice",    "nov",    BOOL,    CANSET,        o_novice    },
  213. #endif
  214.     { "number",    "nu",    BOOL,    CANSET|MR,    o_number    },
  215. #ifndef NO_SENTENCE
  216.     { "paragraphs",    "para",    STR,    CANSET,        o_paragraphs    },
  217. #endif
  218. #if MSDOS
  219.     { "pcbios",    "pc",    BOOL,    SET|NOSAVE,    o_pcbios    },
  220. #endif
  221. #ifndef CRUNCH
  222.     { "prompt",    "pr",    BOOL,    CANSET,        o_prompt    },
  223. #endif
  224.     { "readonly",    "ro",    BOOL,    CANSET,        o_readonly    },
  225.     { "remap",    "remap",BOOL,    CANSET,        o_remap        },
  226.     { "report",    "re",    NUM,    CANSET,        o_report    },
  227. #ifndef NO_EXTENSIONS
  228.     { "ruler",    "ru",    BOOL,    CANSET,        o_ruler        },
  229. #endif
  230.     { "scroll",    "sc",    NUM,    CANSET,        o_scroll    },
  231. #ifndef NO_SENTENCE
  232.     { "sections",    "sect",    STR,    CANSET,        o_sections    },
  233. #endif
  234.     { "shell",    "sh",    STR,    CANSET,        o_shell        },
  235. #ifndef NO_SHOWMATCH
  236.     { "showmatch",    "sm",    BOOL,    CANSET,        o_showmatch    },
  237. #endif
  238. #ifndef    NO_SHOWMODE
  239.     { "showmode",    "smd",    BOOL,    CANSET,        o_smd        },
  240. #endif
  241.     { "shiftwidth",    "sw",    NUM,    CANSET,        o_shiftwidth    },
  242.     { "sidescroll",    "ss",    NUM,    CANSET,        o_sidescroll    },
  243. #if MINT
  244.     { "stbios",    "st",    BOOL,    RCSET | SET ,    o_stbios    },
  245. #endif
  246.     { "sync",    "sy",    BOOL,    CANSET,        o_sync        },
  247.     { "tabstop",    "ts",    NUM,    CANSET|MR,    o_tabstop    },
  248. #ifndef CRUNCH
  249.     { "taglength",    "tl",    NUM,    CANSET,        o_taglength    },
  250. #endif
  251.     { "term",    "te",    STR,    SET,        o_term        },
  252. #ifndef CRUNCH
  253.     { "terse",    "tr",    BOOL,    CANSET,        o_terse        },
  254.     { "timeout",    "to",    BOOL,    CANSET,        o_keytime    },
  255. #endif
  256. #ifndef CRUNCH
  257.     { "window",    "wi",    NUM,    CANSET|MR|WSET,    o_window    },
  258.     { "wrapmargin",    "wm",    NUM,    CANSET,        o_wrapmargin    },
  259. #endif
  260.     { "wrapscan",    "ws",    BOOL,    CANSET,        o_wrapscan    },
  261. #ifndef CRUNCH
  262.     { "writeany",    "wr",    BOOL,    CANSET,        o_writeany    },
  263. #endif
  264.     { NULL, NULL, 0, CANSET, NULL }
  265. };
  266.  
  267. /* This function initializes certain options from environment variables, etc. */
  268. void initopts()
  269. {
  270.     char    *val;
  271.     int    i;
  272.  
  273.     /* set some stuff from environment variables */
  274. #if MSDOS
  275.     if (val = getenv("COMSPEC")) /* yes, ASSIGNMENT! */
  276. #else
  277.     if (val = getenv("SHELL")) /* yes, ASSIGNMENT! */
  278. #endif
  279.     {
  280.         strcpy(o_shell, val);
  281.     }
  282.  
  283.     strcpy(o_term, termtype);
  284. #if MSDOS
  285.     if (strcmp(termtype, "pcbios"))
  286.     {
  287.         o_pcbios[0] = FALSE;
  288.     }
  289.     else
  290.     {
  291.         o_pcbios[0] = TRUE;
  292.     }
  293. #endif
  294.  
  295. #if AMIGA || MSDOS || TOS || MINT
  296.     if ((val = getenv("TMP")) /* yes, ASSIGNMENT! */
  297.     ||  (val = getenv("TEMP")))
  298.         strcpy(o_directory, val);
  299. #endif
  300.  
  301. #ifndef CRUNCH
  302.     if ((val = getenv("LINES")) && atoi(val) > 4) /* yes, ASSIGNMENT! */
  303.     {
  304.         LINES = atoi(val);
  305.     }
  306.     if ((val = getenv("COLUMNS")) && atoi(val) > 30) /* yes, ASSIGNMENT! */
  307.     {
  308.         COLS = atoi(val);
  309.     }
  310. #endif
  311.     *o_lines = LINES;
  312.     *o_columns = COLS;
  313.     *o_scroll = LINES / 2 - 1;
  314. #ifndef CRUNCH
  315.     if (o_window[0] == 0)
  316.     {
  317.         o_window[0] = o_window[2] = *o_lines;
  318.     }
  319.     *o_nearscroll = *o_lines;
  320. #endif
  321.  
  322.     /* disable the flash option if we don't know how to do a flash */
  323.     if (!has_VB)
  324.     {
  325.         for (i = 0; opts[i].value != o_flash; i++)
  326.         {
  327.         }
  328.         opts[i].flags &= ~CANSET;
  329.         *o_flash = FALSE;
  330.     }
  331.  
  332. #ifndef NO_DIGRAPH
  333. # ifdef CS_LATIN1
  334.     for (i = 0, val = o_flipcase; i < 32; i++)
  335.     {
  336.         /* leave out the multiply/divide symbols */
  337.         if (i == 23)
  338.             continue;
  339.  
  340.         /* add lower/uppercase pair */
  341.         *val++ = i + 0xe0;
  342.         *val++ = i + 0xc0;
  343.     }
  344.     *val = '\0';
  345. # endif /* CS_LATIN1 */
  346.  
  347.     /* initialize the ctype package */
  348.     _ct_init(o_flipcase);
  349. #else
  350.     _ct_init("");
  351. #endif /* not NO_DIGRAPH */
  352. }
  353.  
  354. /* This function lists the current values of all options */
  355. void dumpopts(all)
  356.     int    all;    /* boolean: dump all options, or just set ones? */
  357. {
  358. #ifndef NO_OPTCOLS
  359.     int    i, j, k;
  360.     char    nbuf[4];    /* used for converting numbers to ASCII */
  361.     int    widths[5];    /* width of each column, including gap */
  362.     int    ncols;        /* number of columns */
  363.     int    nrows;        /* number of options per column */
  364.     int    nset;        /* number of options to be output */
  365.     int    width;        /* width of a particular option */
  366.     int    todump[60];    /* indicies of options to be dumped */
  367.  
  368.     /* step 1: count the number of set options */
  369.     for (nset = i = 0; opts[i].name; i++)
  370.     {
  371.         if (all || (opts[i].flags & SET))
  372.         {
  373.             todump[nset++] = i;
  374.         }
  375.     }
  376.  
  377.     /* step two: try to use as many columns as possible */
  378.     for (ncols = (nset > 5 ? 5 : nset); ncols > 1; ncols--)
  379.     {
  380.         /* how many would go in this column? */
  381.         nrows = (nset + ncols - 1) / ncols;
  382.  
  383.         /* figure out the width of each column */
  384.         for (i = 0; i < ncols; i++)
  385.         {
  386.             widths[i] = 0;
  387.             for (j = 0, k = nrows * i; j < nrows && k < nset; j++, k++)
  388.             {
  389.                 /* figure out the width of a particular option */
  390.                 switch (opts[todump[k]].type)
  391.                 {
  392.                   case BOOL:
  393.                     if (!*opts[todump[k]].value)
  394.                         width = 2;
  395.                     else
  396.                         width = 0;
  397.                     break;
  398.  
  399.                   case STR:
  400.                     width = 3 + strlen(opts[todump[k]].value);
  401.                     if (width > MAXWIDTH)
  402.                         width = MAXWIDTH;
  403.                     break;
  404.  
  405.                   case NUM:
  406.                     width = 4;
  407.                     break;
  408.                 }
  409.                 width += strlen(opts[todump[k]].name);
  410.  
  411.                 /* if this is the widest so far, widen col */
  412.                 if (width > widths[i])
  413.                 {
  414.                     widths[i] = width;
  415.                 }
  416.             }
  417.  
  418.         }
  419.  
  420.         /* if the total width is narrow enough, then use it */
  421.         for (width = -2, i = 0; i < ncols; i++)
  422.         {
  423.             width += widths[i] + 2;
  424.         }
  425.         if (width < COLS - 1)
  426.         {
  427.             break;
  428.         }
  429.     }
  430.  
  431.     /* step 3: output the columns */
  432.     nrows = (nset + ncols - 1) / ncols;
  433.     for (i = 0; i < nrows; i++)
  434.     {
  435.         for (j = 0; j < ncols; j++)
  436.         {
  437.             /* if we hit the end of the options, quit */
  438.             k = i + j * nrows;
  439.             if (k >= nset)
  440.             {
  441.                 break;
  442.             }
  443.  
  444.             /* output this option's value */
  445.             width = 0;
  446.             switch (opts[todump[k]].type)
  447.             {
  448.               case BOOL:
  449.                 if (!*opts[todump[k]].value)
  450.                 {
  451.                     qaddch('n');
  452.                     qaddch('o');
  453.                     width = 2;
  454.                 }
  455.                 qaddstr(opts[todump[k]].name);
  456.                 width += strlen(opts[todump[k]].name);
  457.                 break;
  458.  
  459.               case NUM:
  460.                 sprintf(nbuf, "%-3d", UCHAR(*opts[todump[k]].value));
  461.                 qaddstr(opts[todump[k]].name);
  462.                 qaddch('=');
  463.                 qaddstr(nbuf);
  464.                 width = 4 + strlen(opts[todump[k]].name);
  465.                 break;
  466.  
  467.               case STR:
  468.                 qaddstr(opts[todump[k]].name);
  469.                 qaddch('=');
  470.                 qaddch('"');
  471.                 strcpy(tmpblk.c, opts[todump[k]].value);
  472.                 width = 3 + strlen(tmpblk.c);
  473.                 if (width > MAXWIDTH)
  474.                 {
  475.                     width = MAXWIDTH;
  476.                     strcpy(tmpblk.c + MAXWIDTH - 6, "...");
  477.                 }
  478.                 qaddstr(tmpblk.c);
  479.                 qaddch('"');
  480.                 width += strlen(opts[todump[k]].name);
  481.                 break;
  482.             }
  483.  
  484.             /* pad the field to the correct size */
  485.             if (k + nrows <= nset)
  486.             {
  487.                 while (width < widths[j] + 2)
  488.                 {
  489.                     qaddch(' ');
  490.                     width++;
  491.                 }
  492.             }
  493.         }
  494.         addch('\n');
  495.         exrefresh();
  496.     }
  497. #else
  498.     int    i;
  499.     int    col;
  500.     char    nbuf[4];
  501.  
  502.     for (i = col = 0; opts[i].name; i++)
  503.     {
  504.         /* if not set and not all, ignore this option */
  505.         if (!all && !(opts[i].flags & SET))
  506.         {
  507.             continue;
  508.         }
  509.  
  510.         /* align this option in one of the columns */
  511.         if (col > 52)
  512.         {
  513.             addch('\n');
  514.             col = 0;
  515.         }
  516.         else if (col > 26)
  517.         {
  518.             while (col < 52)
  519.             {
  520.                 qaddch(' ');
  521.                 col++;
  522.             }
  523.         }
  524.         else if (col > 0)
  525.         {
  526.             while (col < 26)
  527.             {
  528.                 qaddch(' ');
  529.                 col++;
  530.             }
  531.         }
  532.  
  533.         switch (opts[i].type)
  534.         {
  535.           case BOOL:
  536.             if (!*opts[i].value)
  537.             {
  538.                 qaddch('n');
  539.                 qaddch('o');
  540.                 col += 2;
  541.             }
  542.             qaddstr(opts[i].name);
  543.             col += strlen(opts[i].name);
  544.             break;
  545.  
  546.           case NUM:
  547.             sprintf(nbuf, "%-3d", UCHAR(*opts[i].value));
  548.             qaddstr(opts[i].name);
  549.             qaddch('=');
  550.             qaddstr(nbuf);
  551.             col += 4 + strlen(opts[i].name);
  552.             break;
  553.  
  554.           case STR:
  555.             qaddstr(opts[i].name);
  556.             qaddch('=');
  557.             qaddch('"');
  558.             qaddstr(opts[i].value);
  559.             qaddch('"');
  560.             col += 3 + strlen(opts[i].name) + strlen(opts[i].value);
  561.             break;
  562.         }
  563.         exrefresh();
  564.     }
  565.     if (col > 0)
  566.     {
  567.         addch('\n');
  568.         exrefresh();
  569.     }
  570. #endif
  571. }
  572.  
  573. #ifndef NO_MKEXRC
  574. /* This function saves the current configuration of options to a file */
  575. void saveopts(fd)
  576.     int    fd;    /* file descriptor to write to */
  577. {
  578.     int    i;
  579.     char    buf[256], *pos;
  580.  
  581.     /* write each set options */
  582.     for (i = 0; opts[i].name; i++)
  583.     {
  584.         /* if unset or unsettable, ignore this option */
  585.         if ((opts[i].flags & (SET|CANSET|NOSAVE)) != (SET|CANSET))
  586.         {
  587.             continue;
  588.         }
  589.  
  590.         strcpy(buf, "set ");
  591.         pos = &buf[4];
  592.         switch (opts[i].type)
  593.         {
  594.           case BOOL:
  595.             if (!*opts[i].value)
  596.             {
  597.                 *pos++='n';
  598.                 *pos++='o';
  599.             }
  600.             strcpy(pos, opts[i].name);
  601.             strcat(pos, "\n");
  602.             break;
  603.  
  604.           case NUM:
  605.             sprintf(pos, "%s=%-3d\n", opts[i].name, *opts[i].value & 0xff);
  606.             break;
  607.  
  608.           case STR:
  609.             sprintf(pos, "%s=\"%s\"\n", opts[i].name, opts[i].value);
  610.             break;
  611.         }
  612.         twrite(fd, buf, (unsigned)strlen(buf));
  613.     }
  614. }
  615. #endif
  616.  
  617.  
  618. /* This function changes the values of one or more options. */
  619. void setopts(assignments)
  620.     char    *assignments;    /* a string containing option assignments */
  621. {
  622.     char    *name;        /* name of variable in assignments */
  623.     char    *value;        /* value of the variable */
  624.     char    *scan;        /* used for moving through strings */
  625.     char    *build;        /* used for copying chars from "scan" */
  626.     char    *prefix;    /* pointer to "neg" or "no" at front of a boolean */
  627.     int    quote;        /* boolean: inside '"' quotes? */
  628.     int    i, j;
  629.  
  630. #ifndef CRUNCH
  631.     /* reset the upper limit of "window" option to lines-1 */
  632.     *o_window = *o_lines - 1;
  633. #endif
  634.  
  635.     /* for each assignment... */
  636.     for (name = assignments; *name; )
  637.     {
  638.         /* skip whitespace */
  639.         if (*name == ' ' || *name == '\t')
  640.         {
  641.             name++;
  642.             continue;
  643.         }
  644.  
  645.         /* after the name, find the value (if any) */
  646.         for (scan = name; isalnum(*scan); scan++)
  647.         {
  648.         }
  649.         if (*scan == '=')
  650.         {
  651.             *scan++ = '\0';
  652.             value = build = scan;
  653.             for (quote = FALSE; *scan && (quote || !isspace(*scan)); scan++)
  654.             {
  655.                 if (*scan == '"')
  656.                 {
  657.                     quote = !quote;
  658.                 }
  659.                 else if (*scan == '\\' && scan[1])
  660.                 {
  661.                     *build++ = *++scan;
  662.                 }
  663.                 else
  664.                 {
  665.                     *build++ = *scan;
  666.                 }
  667.             }
  668.             if (*scan)
  669.                 scan++;
  670.             *build = '\0';
  671.         }
  672.         else /* no "=" so it is probably boolean... */
  673.         {
  674.             if (*scan)
  675.             {
  676.                 *scan++ = '\0';
  677.             }
  678.             value = NULL;
  679.             prefix = name;
  680. #ifndef CRUNCH
  681.             if (!strcmp(name, "novice"))
  682.                 /* don't check for a "no" prefix */;
  683.             else
  684. #endif
  685.             if (prefix[0] == 'n' && prefix[1] == 'o')
  686.                 name += 2;
  687.             else if (prefix[0] == 'n' && prefix[1] == 'e' && prefix[2] == 'g')
  688.                 name += 3;
  689.         }
  690.  
  691.         /* find the variable */
  692.         for (i = 0;
  693.              opts[i].name && strcmp(opts[i].name, name) && strcmp(opts[i].nm, name);
  694.              i++)
  695.         {
  696.         }
  697.  
  698.         /* change the variable */
  699.         if (!opts[i].name)
  700.         {
  701.             msg("invalid option name \"%s\"", name);
  702.         }
  703.         else if ((opts[i].flags & CANSET) != CANSET)
  704.         {
  705.             msg("option \"%s\" can't be altered", name);
  706.         }
  707.         else if ((opts[i].flags & RCSET) != CANSET && nlines >= 1L)
  708.         {
  709.             msg("option \"%s\" can only be set in a %s file", name, EXRC);
  710.         }
  711.         else if (value)
  712.         {
  713.             switch (opts[i].type)
  714.             {
  715.               case BOOL:
  716.                 msg("option \"[no]%s\" is boolean", name);
  717.                 break;
  718.  
  719.               case NUM:
  720.                 j = atoi(value);
  721.                 if (j == 0 && *value != '0')
  722.                 {
  723.                     msg("option \"%s\" must have a numeric value", name);
  724.                 }
  725.                 else if (j < opts[i].value[1] || j > (opts[i].value[2] & 0xff))
  726.                 {
  727.                     msg("option \"%s\" must have a value between %d and %d",
  728.                         name, opts[i].value[1], opts[i].value[2] & 0xff);
  729.                 }
  730.                 else
  731.                 {
  732.                     *opts[i].value = atoi(value);
  733.                     opts[i].flags |= SET;
  734.                 }
  735.                 break;
  736.  
  737.               case STR:
  738.                 strcpy(opts[i].value, value);
  739.                 opts[i].flags |= SET;
  740.                 break;
  741.             }
  742.             if (opts[i].flags & MR)
  743.             {
  744.                 redraw(MARK_UNSET, FALSE);
  745.             }
  746. #ifndef CRUNCH
  747.             if (opts[i].flags & WSET)
  748.             {
  749.                 wset = TRUE;
  750.             }
  751. #endif
  752.         }
  753.         else /* valid option, no value */
  754.         {
  755.             if (opts[i].type == BOOL)
  756.             {
  757.                 if (prefix == name)
  758.                     *opts[i].value = TRUE;
  759.                 else if (prefix[1] == 'o')
  760.                     *opts[i].value = FALSE;
  761.                 else
  762.                     *opts[i].value = !*opts[i].value;
  763.  
  764.                 opts[i].flags |= SET;
  765.                 if (opts[i].flags & MR)
  766.                 {
  767.                     redraw(MARK_UNSET, FALSE);
  768.                 }
  769.             }
  770.             else
  771.             {
  772.                 msg("option \"%s\" must be given a value", name);
  773.             }
  774.         }
  775.  
  776.         /* move on to the next option */
  777.         name = scan;
  778.     }
  779.  
  780.     /* special processing ... */
  781.  
  782. #ifndef CRUNCH
  783.     /* if "novice" is set, then ":set report=1 showmode nomagic" */
  784.     if (*o_novice)
  785.     {
  786.         *o_report = 1;
  787. # ifndef NO_SHOWMODE
  788.         *o_smd = TRUE;
  789. # endif
  790. # ifndef NO_MAGIC
  791.         *o_magic = FALSE;
  792. # endif
  793.     }
  794. #endif
  795.  
  796.     /* if "readonly" then set the READONLY flag for this file */
  797.     if (*o_readonly)
  798.     {
  799.         setflag(file, READONLY);
  800.     }
  801.  
  802. #ifndef NO_DIGRAPH
  803.     /* re-initialize the ctype package */
  804.     _ct_init(o_flipcase);
  805. #endif /* not NO_DIGRAPH */
  806.  
  807.     /* copy o_lines and o_columns into LINES and COLS */
  808.     LINES = (*o_lines & 255);
  809.     COLS = (*o_columns & 255);
  810. }
  811.