. satisfy some gcc warnings (uninitialized/unused variables)
[minix3.git] / commands / elvis / opts.c
blob0d72ba58dae296fd4f964d3b62ec1863cf20a55a
1 /* opts.c */
3 /* Author:
4 * Steve Kirkendall
5 * 14407 SW Teal Blvd. #C
6 * Beaverton, OR 97005
7 * kirkenda@cs.pdx.edu
8 */
11 /* This file contains the code that manages the run-time options -- The
12 * values that can be modified via the "set" command.
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();
23 /* maximum width to permit for strings, including ="" */
24 #define MAXWIDTH 20
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] = {1, 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};
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_novice[1] = {FALSE};
63 char o_prompt[1] = {TRUE};
64 char o_taglength[3] = {0, 0, 30};
65 char o_terse[1] = {FALSE};
66 char o_window[3] = {0, 1, 24};
67 char o_wrapmargin[3] = {0, 0, 255};
68 char o_writeany[1] = {FALSE};
69 #endif
71 #ifndef NO_ERRLIST
72 char o_cc[30] = {CC_COMMAND};
73 char o_make[30] = {MAKE_COMMAND};
74 #endif
76 #ifndef NO_CHARATTR
77 char o_charattr[1] = {FALSE};
78 #endif
80 #ifndef NO_DIGRAPH
81 char o_digraph[1] = {FALSE};
82 char o_flipcase[80]
83 # ifdef CS_IBMPC
84 = {"\207\200\201\232\202\220\204\216\206\217\221\222\224\231\244\245"}
85 # endif
86 # ifdef CS_LATIN1
87 /* initialized by initopts() */
88 # endif
90 #endif
92 #ifndef NO_SENTENCE
93 char o_hideformat[1] = {FALSE};
94 #endif
96 #ifndef NO_EXTENSIONS
97 char o_inputmode[1] = {FALSE};
98 char o_ruler[1] = {FALSE};
99 #endif
101 #ifndef NO_MAGIC
102 char o_magic[1] = {TRUE};
103 #endif
105 #ifndef NO_MODELINES
106 char o_modelines[1] = {FALSE};
107 #endif
109 #ifndef NO_SENTENCE
110 char o_paragraphs[30] = "PPppIPLPQP";
111 char o_sections[30] = "NHSHSSSEse";
112 #endif
114 #if MSDOS
115 char o_pcbios[1] = {TRUE};
116 #endif
118 #ifndef NO_SHOWMATCH
119 char o_showmatch[1] = {FALSE};
120 #endif
122 #ifndef NO_SHOWMODE
123 char o_smd[1] = {FALSE};
124 #endif
127 /* The following describes the names & types of all options */
128 #define BOOL 0
129 #define NUM 1
130 #define STR 2
131 #define SET 0x01 /* this option has had its value altered */
132 #define CANSET 0x02 /* this option can be set at any time */
133 #define RCSET 0x06 /* this option can be set in a .exrc file only */
134 #define NOSAVE 0x0a /* this option should never be saved by mkexrc */
135 #define WSET 0x20 /* is this the "window" size option? */
136 #define MR 0x40 /* does this option affect the way text is displayed? */
137 struct
139 char *name; /* name of an option */
140 char *nm; /* short name of an option */
141 char type; /* type of an option */
142 char flags; /* boolean: has this option been set? */
143 char *value; /* value */
145 opts[] =
147 /* name type flags value */
148 { "autoindent", "ai", BOOL, CANSET, o_autoindent },
149 { "autoprint", "ap", BOOL, CANSET, o_autoprint },
150 { "autotab", "at", BOOL, CANSET, o_autotab },
151 { "autowrite", "aw", BOOL, CANSET, o_autowrite },
152 #ifndef CRUNCH
153 { "beautify", "bf", BOOL, CANSET, o_beautify },
154 #endif
155 #ifndef NO_ERRLIST
156 { "cc", "cc", STR, CANSET, o_cc },
157 #endif
158 #ifndef NO_CHARATTR
159 { "charattr", "ca", BOOL, CANSET|MR, o_charattr },
160 #endif
161 { "columns", "co", NUM, SET|NOSAVE|MR, o_columns },
162 #ifndef NO_DIGRAPH
163 { "digraph", "dig", BOOL, CANSET, o_digraph },
164 #endif
165 { "directory", "dir", STR, RCSET, o_directory },
166 { "edcompatible","ed", BOOL, CANSET, o_edcompatible },
167 { "equalprg", "ep", STR, CANSET, o_equalprg },
168 { "errorbells", "eb", BOOL, CANSET, o_errorbells },
169 #ifndef CRUNCH
170 { "exrc", "exrc", BOOL, CANSET, o_exrc },
171 #endif
172 { "exrefresh", "er", BOOL, CANSET, o_exrefresh },
173 { "flash", "vbell",BOOL, CANSET, o_flash },
174 #ifndef NO_DIGRAPH
175 { "flipcase", "fc", STR, CANSET, o_flipcase },
176 #endif
177 #ifndef NO_SENTENCE
178 { "hideformat", "hf", BOOL, CANSET|MR, o_hideformat },
179 #endif
180 { "ignorecase", "ic", BOOL, CANSET, o_ignorecase },
181 #ifndef NO_EXTENSIONS
182 { "inputmode", "im", BOOL, CANSET, o_inputmode },
183 #endif
184 { "keytime", "kt", NUM, CANSET, o_keytime },
185 { "keywordprg", "kp", STR, CANSET, o_keywordprg },
186 { "lines", "ls", NUM, SET|NOSAVE|MR, o_lines },
187 { "list", "li", BOOL, CANSET|MR, o_list },
188 #ifndef NO_MAGIC
189 { "magic", "ma", BOOL, CANSET, o_magic },
190 #endif
191 #ifndef NO_ERRLIST
192 { "make", "mk", STR, CANSET, o_make },
193 #endif
194 #ifndef CRUNCH
195 { "mesg", "me", BOOL, CANSET, o_mesg },
196 #endif
197 #ifndef NO_MODELINES
198 { "modelines", "ml", BOOL, CANSET, o_modelines },
199 #endif
200 #ifndef CRUNCH
201 { "more", "mo", BOOL, CANSET, o_more },
202 { "novice", "nov", BOOL, CANSET, o_novice },
203 #endif
204 { "number", "nu", BOOL, CANSET|MR, o_number },
205 #ifndef NO_SENTENCE
206 { "paragraphs", "para", STR, CANSET, o_paragraphs },
207 #endif
208 #if MSDOS
209 { "pcbios", "pc", BOOL, SET|NOSAVE, o_pcbios },
210 #endif
211 #ifndef CRUNCH
212 { "prompt", "pr", BOOL, CANSET, o_prompt },
213 #endif
214 { "readonly", "ro", BOOL, CANSET, o_readonly },
215 { "remap", "remap",BOOL, CANSET, o_remap },
216 { "report", "re", NUM, CANSET, o_report },
217 #ifndef NO_EXTENSIONS
218 { "ruler", "ru", BOOL, CANSET, o_ruler },
219 #endif
220 { "scroll", "sc", NUM, CANSET, o_scroll },
221 #ifndef NO_SENTENCE
222 { "sections", "sect", STR, CANSET, o_sections },
223 #endif
224 { "shell", "sh", STR, CANSET, o_shell },
225 #ifndef NO_SHOWMATCH
226 { "showmatch", "sm", BOOL, CANSET, o_showmatch },
227 #endif
228 #ifndef NO_SHOWMODE
229 { "showmode", "smd", BOOL, CANSET, o_smd },
230 #endif
231 { "shiftwidth", "sw", NUM, CANSET, o_shiftwidth },
232 { "sidescroll", "ss", NUM, CANSET, o_sidescroll },
233 { "sync", "sy", BOOL, CANSET, o_sync },
234 { "tabstop", "ts", NUM, CANSET|MR, o_tabstop },
235 #ifndef CRUNCH
236 { "taglength", "tl", NUM, CANSET, o_taglength },
237 #endif
238 { "term", "te", STR, SET, o_term },
239 #ifndef CRUNCH
240 { "terse", "tr", BOOL, CANSET, o_terse },
241 { "timeout", "to", BOOL, CANSET, o_keytime },
242 #endif
243 #ifndef CRUNCH
244 { "window", "wi", NUM, CANSET|MR|WSET, o_window },
245 { "wrapmargin", "wm", NUM, CANSET, o_wrapmargin },
246 #endif
247 { "wrapscan", "ws", BOOL, CANSET, o_wrapscan },
248 #ifndef CRUNCH
249 { "writeany", "wr", BOOL, CANSET, o_writeany },
250 #endif
251 { NULL, NULL, 0, CANSET, NULL }
255 /* This function initializes certain options from environment variables, etc. */
256 void initopts()
258 char *val;
259 int i;
261 /* set some stuff from environment variables */
262 #if MSDOS
263 if (val = getenv("COMSPEC")) /* yes, ASSIGNMENT! */
264 #else
265 if (val = getenv("SHELL")) /* yes, ASSIGNMENT! */
266 #endif
268 strcpy(o_shell, val);
271 strcpy(o_term, termtype);
272 #if MSDOS
273 if (strcmp(termtype, "pcbios"))
275 o_pcbios[0] = FALSE;
277 else
279 o_pcbios[0] = TRUE;
281 #endif
283 #if AMIGA || MSDOS || TOS
284 if ((val = getenv("TMP")) /* yes, ASSIGNMENT! */
285 || (val = getenv("TEMP")))
286 strcpy(o_directory, val);
287 #endif
289 #ifndef CRUNCH
290 if ((val = getenv("LINES")) && atoi(val) > 4) /* yes, ASSIGNMENT! */
292 LINES = atoi(val);
294 if ((val = getenv("COLUMNS")) && atoi(val) > 30) /* yes, ASSIGNMENT! */
296 COLS = atoi(val);
298 #endif
299 *o_lines = LINES;
300 *o_columns = COLS;
301 *o_scroll = LINES / 2 - 1;
302 #ifndef CRUNCH
303 if (o_window[0] == 0)
305 o_window[0] = o_window[2] = *o_lines;
307 #endif
309 /* disable the flash option if we don't know how to do a flash */
310 if (!has_VB)
312 for (i = 0; opts[i].value != o_flash; i++)
315 opts[i].flags &= ~CANSET;
316 *o_flash = FALSE;
319 #ifndef NO_DIGRAPH
320 # ifdef CS_LATIN1
321 for (i = 0, val = o_flipcase; i < 32; i++)
323 /* leave out the multiply/divide symbols */
324 if (i == 23)
325 continue;
327 /* add lower/uppercase pair */
328 *val++ = i + 0xe0;
329 *val++ = i + 0xc0;
331 *val = '\0';
332 # endif /* CS_LATIN1 */
334 /* initialize the ctype package */
335 _ct_init(o_flipcase);
336 #else
337 _ct_init("");
338 #endif /* not NO_DIGRAPH */
341 /* This function lists the current values of all options */
342 void dumpopts(all)
343 int all; /* boolean: dump all options, or just set ones? */
345 #ifndef NO_OPTCOLS
346 int i, j, k;
347 char nbuf[4]; /* used for converting numbers to ASCII */
348 int widths[5]; /* width of each column, including gap */
349 int ncols; /* number of columns */
350 int nrows; /* number of options per column */
351 int nset; /* number of options to be output */
352 int width; /* width of a particular option */
353 int todump[60]; /* indicies of options to be dumped */
355 /* step 1: count the number of set options */
356 for (nset = i = 0; opts[i].name; i++)
358 if (all || (opts[i].flags & SET))
360 todump[nset++] = i;
364 /* step two: try to use as many columns as possible */
365 for (ncols = (nset > 5 ? 5 : nset); ncols > 1; ncols--)
367 /* how many would go in this column? */
368 nrows = (nset + ncols - 1) / ncols;
370 /* figure out the width of each column */
371 for (i = 0; i < ncols; i++)
373 widths[i] = 0;
374 for (j = 0, k = nrows * i; j < nrows && k < nset; j++, k++)
376 /* figure out the width of a particular option */
377 switch (opts[todump[k]].type)
379 case BOOL:
380 if (!*opts[todump[k]].value)
381 width = 2;
382 else
383 width = 0;
384 break;
386 case STR:
387 width = 3 + strlen(opts[todump[k]].value);
388 if (width > MAXWIDTH)
389 width = MAXWIDTH;
390 break;
392 case NUM:
393 width = 4;
394 break;
396 width += strlen(opts[todump[k]].name);
398 /* if this is the widest so far, widen col */
399 if (width > widths[i])
401 widths[i] = width;
407 /* if the total width is narrow enough, then use it */
408 for (width = -2, i = 0; i < ncols; i++)
410 width += widths[i] + 2;
412 if (width < COLS - 1)
414 break;
418 /* step 3: output the columns */
419 nrows = (nset + ncols - 1) / ncols;
420 for (i = 0; i < nrows; i++)
422 for (j = 0; j < ncols; j++)
424 /* if we hit the end of the options, quit */
425 k = i + j * nrows;
426 if (k >= nset)
428 break;
431 /* output this option's value */
432 width = 0;
433 switch (opts[todump[k]].type)
435 case BOOL:
436 if (!*opts[todump[k]].value)
438 qaddch('n');
439 qaddch('o');
440 width = 2;
442 qaddstr(opts[todump[k]].name);
443 width += strlen(opts[todump[k]].name);
444 break;
446 case NUM:
447 sprintf(nbuf, "%-3d", UCHAR(*opts[todump[k]].value));
448 qaddstr(opts[todump[k]].name);
449 qaddch('=');
450 qaddstr(nbuf);
451 width = 4 + strlen(opts[todump[k]].name);
452 break;
454 case STR:
455 qaddstr(opts[todump[k]].name);
456 qaddch('=');
457 qaddch('"');
458 strcpy(tmpblk.c, opts[todump[k]].value);
459 width = 3 + strlen(tmpblk.c);
460 if (width > MAXWIDTH)
462 width = MAXWIDTH;
463 strcpy(tmpblk.c + MAXWIDTH - 6, "...");
465 qaddstr(tmpblk.c);
466 qaddch('"');
467 width += strlen(opts[todump[k]].name);
468 break;
471 /* pad the field to the correct size */
472 if (k + nrows <= nset)
474 while (width < widths[j] + 2)
476 qaddch(' ');
477 width++;
481 addch('\n');
482 exrefresh();
484 #else
485 int i;
486 int col;
487 char nbuf[4];
489 for (i = col = 0; opts[i].name; i++)
491 /* if not set and not all, ignore this option */
492 if (!all && !(opts[i].flags & SET))
494 continue;
497 /* align this option in one of the columns */
498 if (col > 52)
500 addch('\n');
501 col = 0;
503 else if (col > 26)
505 while (col < 52)
507 qaddch(' ');
508 col++;
511 else if (col > 0)
513 while (col < 26)
515 qaddch(' ');
516 col++;
520 switch (opts[i].type)
522 case BOOL:
523 if (!*opts[i].value)
525 qaddch('n');
526 qaddch('o');
527 col += 2;
529 qaddstr(opts[i].name);
530 col += strlen(opts[i].name);
531 break;
533 case NUM:
534 sprintf(nbuf, "%-3d", UCHAR(*opts[i].value));
535 qaddstr(opts[i].name);
536 qaddch('=');
537 qaddstr(nbuf);
538 col += 4 + strlen(opts[i].name);
539 break;
541 case STR:
542 qaddstr(opts[i].name);
543 qaddch('=');
544 qaddch('"');
545 qaddstr(opts[i].value);
546 qaddch('"');
547 col += 3 + strlen(opts[i].name) + strlen(opts[i].value);
548 break;
550 exrefresh();
552 if (col > 0)
554 addch('\n');
555 exrefresh();
557 #endif
560 #ifndef NO_MKEXRC
561 /* This function saves the current configuration of options to a file */
562 void saveopts(fd)
563 int fd; /* file descriptor to write to */
565 int i;
566 char buf[256], *pos;
568 /* write each set options */
569 for (i = 0; opts[i].name; i++)
571 /* if unset or unsettable, ignore this option */
572 if ((opts[i].flags & (SET|CANSET|NOSAVE)) != (SET|CANSET))
574 continue;
577 strcpy(buf, "set ");
578 pos = &buf[4];
579 switch (opts[i].type)
581 case BOOL:
582 if (!*opts[i].value)
584 *pos++='n';
585 *pos++='o';
587 strcpy(pos, opts[i].name);
588 strcat(pos, "\n");
589 break;
591 case NUM:
592 sprintf(pos, "%s=%-3d\n", opts[i].name, *opts[i].value & 0xff);
593 break;
595 case STR:
596 sprintf(pos, "%s=\"%s\"\n", opts[i].name, opts[i].value);
597 break;
599 twrite(fd, buf, (unsigned)strlen(buf));
602 #endif
605 /* This function changes the values of one or more options. */
606 void setopts(assignments)
607 char *assignments; /* a string containing option assignments */
609 char *name; /* name of variable in assignments */
610 char *value; /* value of the variable */
611 char *scan; /* used for moving through strings */
612 char *build; /* used for copying chars from "scan" */
613 char *prefix; /* pointer to "neg" or "no" at front of a boolean */
614 int quote; /* boolean: inside '"' quotes? */
615 int i, j;
617 #ifndef CRUNCH
618 /* reset the upper limit of "window" option to lines-1 */
619 *o_window = *o_lines - 1;
620 #endif
622 /* for each assignment... */
623 for (name = assignments; *name; )
625 /* skip whitespace */
626 if (*name == ' ' || *name == '\t')
628 name++;
629 continue;
632 /* after the name, find the value (if any) */
633 for (scan = name; isalnum(*scan); scan++)
636 if (*scan == '=')
638 *scan++ = '\0';
639 value = build = scan;
640 for (quote = FALSE; *scan && (quote || !isspace(*scan)); scan++)
642 if (*scan == '"')
644 quote = !quote;
646 else if (*scan == '\\' && scan[1])
648 *build++ = *++scan;
650 else
652 *build++ = *scan;
655 if (*scan)
656 scan++;
657 *build = '\0';
659 else /* no "=" so it is probably boolean... */
661 if (*scan)
663 *scan++ = '\0';
665 value = NULL;
666 prefix = name;
667 #ifndef CRUNCH
668 if (!strcmp(name, "novice"))
669 /* don't check for a "no" prefix */;
670 else
671 #endif
672 if (prefix[0] == 'n' && prefix[1] == 'o')
673 name += 2;
674 else if (prefix[0] == 'n' && prefix[1] == 'e' && prefix[2] == 'g')
675 name += 3;
678 /* find the variable */
679 for (i = 0;
680 opts[i].name && strcmp(opts[i].name, name) && strcmp(opts[i].nm, name);
681 i++)
685 /* change the variable */
686 if (!opts[i].name)
688 msg("invalid option name \"%s\"", name);
690 else if ((opts[i].flags & CANSET) != CANSET)
692 msg("option \"%s\" can't be altered", name);
694 else if ((opts[i].flags & RCSET) != CANSET && nlines >= 1L)
696 msg("option \"%s\" can only be set in a %s file", name, EXRC);
698 else if (value)
700 switch (opts[i].type)
702 case BOOL:
703 msg("option \"[no]%s\" is boolean", name);
704 break;
706 case NUM:
707 j = atoi(value);
708 if (j == 0 && *value != '0')
710 msg("option \"%s\" must have a numeric value", name);
712 else if (j < opts[i].value[1] || j > (opts[i].value[2] & 0xff))
714 msg("option \"%s\" must have a value between %d and %d",
715 name, opts[i].value[1], opts[i].value[2] & 0xff);
717 else
719 *opts[i].value = atoi(value);
720 opts[i].flags |= SET;
722 break;
724 case STR:
725 strcpy(opts[i].value, value);
726 opts[i].flags |= SET;
727 break;
729 if (opts[i].flags & MR)
731 redraw(MARK_UNSET, FALSE);
733 #ifndef CRUNCH
734 if (opts[i].flags & WSET)
736 wset = TRUE;
738 #endif
740 else /* valid option, no value */
742 if (opts[i].type == BOOL)
744 if (prefix == name)
745 *opts[i].value = TRUE;
746 else if (prefix[1] == 'o')
747 *opts[i].value = FALSE;
748 else
749 *opts[i].value = !*opts[i].value;
751 opts[i].flags |= SET;
752 if (opts[i].flags & MR)
754 redraw(MARK_UNSET, FALSE);
757 else
759 msg("option \"%s\" must be given a value", name);
763 /* move on to the next option */
764 name = scan;
767 /* special processing ... */
769 #ifndef CRUNCH
770 /* if "novice" is set, then ":set report=1 showmode nomagic" */
771 if (*o_novice)
773 *o_report = 1;
774 # ifndef NO_SHOWMODE
775 *o_smd = TRUE;
776 # endif
777 # ifndef NO_MAGIC
778 *o_magic = FALSE;
779 # endif
781 #endif
783 /* if "readonly" then set the READONLY flag for this file */
784 if (*o_readonly)
786 setflag(file, READONLY);
789 #ifndef NO_DIGRAPH
790 /* re-initialize the ctype package */
791 _ct_init(o_flipcase);
792 #endif /* not NO_DIGRAPH */
794 /* copy o_lines and o_columns into LINES and COLS */
795 LINES = (*o_lines & 255);
796 COLS = (*o_columns & 255);