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