5 * 14407 SW Teal Blvd. #C
11 /* This file contains the code that manages the run-time options -- The
12 * values that can be modified via the "set" command.
18 #define NULL (char *)0
20 extern char *getenv();
22 /* maximum width to permit for strings, including ="" */
25 /* These are the default values of all options */
26 char o_autoindent
[1] = {FALSE
};
27 char o_autoprint
[1] = {TRUE
};
28 char o_autotab
[1] = {TRUE
};
29 char o_autowrite
[1] = {FALSE
};
30 char o_columns
[3] = {80, 32, 255};
31 char o_directory
[30] = TMPDIR
;
32 char o_edcompatible
[1] = {FALSE
};
33 char o_equalprg
[80] = {"fmt"};
34 char o_errorbells
[1] = {TRUE
};
35 char o_exrefresh
[1] = {TRUE
};
36 char o_ignorecase
[1] = {FALSE
};
37 char o_keytime
[3] = {2, 0, 50};
38 char o_keywordprg
[80] = {KEYWORDPRG
};
39 char o_lines
[3] = {25, 2, 66};
40 char o_list
[1] = {FALSE
};
41 char o_number
[1] = {FALSE
};
42 char o_readonly
[1] = {FALSE
};
43 char o_report
[3] = {5, 1, 127};
44 char o_scroll
[3] = {12, 1, 127};
45 char o_shell
[60] = SHELL
;
46 char o_shiftwidth
[3] = {8, 1, 255};
47 char o_sidescroll
[3] = {8, 1, 40};
48 char o_sync
[1] = {NEEDSYNC
};
49 char o_tabstop
[3] = {8, 1, 40};
50 char o_term
[30] = "?";
51 char o_vbell
[1] = {TRUE
};
52 char o_warn
[1] = {TRUE
};
53 char o_wrapscan
[1] = {TRUE
};
56 char o_beautify
[1] = {FALSE
};
57 char o_exrc
[1] = {FALSE
};
58 char o_mesg
[1] = {TRUE
};
59 char o_more
[1] = {TRUE
};
60 char o_novice
[1] = {FALSE
};
61 char o_prompt
[1] = {TRUE
};
62 char o_taglength
[3] = {0, 0, 30};
63 char o_terse
[1] = {FALSE
};
64 char o_window
[3] = {24, 1, 24};
65 char o_wrapmargin
[3] = {0, 0, 255};
66 char o_writeany
[1] = {FALSE
};
70 char o_cc
[30] = {CC_COMMAND
};
71 char o_make
[30] = {MAKE_COMMAND
};
75 char o_charattr
[1] = {FALSE
};
79 char o_digraph
[1] = {FALSE
};
82 = {"\207\200\201\232\202\220\204\216\206\217\221\222\224\231\244\245"}
85 /* initialized by initopts() */
91 char o_hideformat
[1] = {FALSE
};
95 char o_inputmode
[1] = {FALSE
};
96 char o_ruler
[1] = {FALSE
};
100 char o_magic
[1] = {TRUE
};
104 char o_modeline
[1] = {FALSE
};
108 char o_paragraphs
[30] = "PPppIPLPQP";
109 char o_sections
[30] = "NHSHSSSEse";
113 char o_pcbios
[1] = {TRUE
};
117 char o_showmatch
[1] = {FALSE
};
121 char o_smd
[1] = {FALSE
};
125 /* The following describes the names & types of all options */
129 #define SET 0x01 /* this option has had its value altered */
130 #define CANSET 0x02 /* this option can be set at any time */
131 #define RCSET 0x06 /* this option can be set in a .exrc file only */
132 #define NOSAVE 0x0a /* this option should never be saved by mkexrc */
133 #define MR 0x40 /* does this option affect the way text is displayed? */
136 char *name
; /* name of an option */
137 char *nm
; /* short name of an option */
138 char type
; /* type of an option */
139 char flags
; /* boolean: has this option been set? */
140 char *value
; /* value */
144 /* name type flags value */
145 { "autoindent", "ai", BOOL
, CANSET
, o_autoindent
},
146 { "autoprint", "ap", BOOL
, CANSET
, o_autoprint
},
147 { "autotab", "at", BOOL
, CANSET
, o_autotab
},
148 { "autowrite", "aw", BOOL
, CANSET
, o_autowrite
},
150 { "beautify", "bf", BOOL
, CANSET
, o_beautify
},
153 { "cc", "cc", STR
, CANSET
, o_cc
},
156 { "charattr", "ca", BOOL
, CANSET
|MR
, o_charattr
},
158 { "columns", "co", NUM
, SET
|NOSAVE
|MR
, o_columns
},
160 { "digraph", "dig", BOOL
, CANSET
, o_digraph
},
162 { "directory", "dir", STR
, RCSET
, o_directory
},
163 { "edcompatible","ed", BOOL
, CANSET
, o_edcompatible
},
164 { "equalprg", "ep", STR
, CANSET
, o_equalprg
},
165 { "errorbells", "eb", BOOL
, CANSET
, o_errorbells
},
167 { "exrc", "exrc", BOOL
, CANSET
, o_exrc
},
169 { "exrefresh", "er", BOOL
, CANSET
, o_exrefresh
},
171 { "flash", "fl", BOOL
, CANSET
, o_vbell
},
174 { "flipcase", "fc", STR
, CANSET
, o_flipcase
},
177 { "hideformat", "hf", BOOL
, CANSET
|MR
, o_hideformat
},
179 { "ignorecase", "ic", BOOL
, CANSET
, o_ignorecase
},
180 #ifndef NO_EXTENSIONS
181 { "inputmode", "im", BOOL
, CANSET
, o_inputmode
},
183 { "keytime", "kt", NUM
, CANSET
, o_keytime
},
184 { "keywordprg", "kp", STR
, CANSET
, o_keywordprg
},
185 { "lines", "ls", NUM
, SET
|NOSAVE
|MR
, o_lines
},
186 { "list", "li", BOOL
, CANSET
|MR
, o_list
},
188 { "magic", "ma", BOOL
, CANSET
, o_magic
},
191 { "make", "mk", STR
, CANSET
, o_make
},
194 { "mesg", "me", BOOL
, CANSET
, o_mesg
},
198 { "modelines", "ml", BOOL
, CANSET
, o_modeline
},
200 { "modeline", "ml", BOOL
, CANSET
, o_modeline
},
204 { "more", "mo", BOOL
, CANSET
, o_more
},
205 { "novice", "nov", BOOL
, CANSET
, o_novice
},
207 { "number", "nu", BOOL
, CANSET
|MR
, o_number
},
209 { "paragraphs", "pa", STR
, CANSET
, o_paragraphs
},
212 { "pcbios", "pc", BOOL
, SET
|NOSAVE
, o_pcbios
},
215 { "prompt", "pr", BOOL
, CANSET
, o_prompt
},
217 { "readonly", "ro", BOOL
, CANSET
, o_readonly
},
218 { "report", "re", NUM
, CANSET
, o_report
},
219 #ifndef NO_EXTENSIONS
220 { "ruler", "ru", BOOL
, CANSET
, o_ruler
},
222 { "scroll", "sc", NUM
, CANSET
, o_scroll
},
224 { "sections", "se", STR
, CANSET
, o_sections
},
226 { "shell", "sh", STR
, CANSET
, o_shell
},
228 { "showmatch", "sm", BOOL
, CANSET
, o_showmatch
},
231 { "showmode", "smd", BOOL
, CANSET
, o_smd
},
233 { "shiftwidth", "sw", NUM
, CANSET
, o_shiftwidth
},
234 { "sidescroll", "ss", NUM
, CANSET
, o_sidescroll
},
235 { "sync", "sy", BOOL
, CANSET
, o_sync
},
236 { "tabstop", "ts", NUM
, CANSET
|MR
, o_tabstop
},
238 { "taglength", "tl", NUM
, CANSET
, o_taglength
},
240 { "term", "te", STR
, SET
, o_term
},
242 { "terse", "tr", BOOL
, CANSET
, o_terse
},
243 { "timeout", "to", BOOL
, CANSET
, o_keytime
},
246 { "vbell", "vb", BOOL
, CANSET
, o_vbell
},
248 { "warn", "wa", BOOL
, CANSET
, o_warn
},
250 { "window", "wi", NUM
, CANSET
|MR
, o_window
},
251 { "wrapmargin", "wm", NUM
, CANSET
, o_wrapmargin
},
253 { "wrapscan", "ws", BOOL
, CANSET
, o_wrapscan
},
255 { "writeany", "wr", BOOL
, CANSET
, o_writeany
},
257 { NULL
, NULL
, 0, CANSET
, NULL
}
261 /* This function initializes certain options from environment variables, etc. */
267 /* set some stuff from environment variables */
269 if (val
= getenv("COMSPEC")) /* yes, ASSIGNMENT! */
271 if (val
= getenv("SHELL")) /* yes, ASSIGNMENT! */
274 strcpy(o_shell
, val
);
277 strcpy(o_term
, termtype
);
279 if (strcmp(termtype
, "pcbios"))
290 if ((val
= getenv("TMP")) /* yes, ASSIGNMENT! */
291 || (val
= getenv("TEMP")))
292 strcpy(o_directory
, val
);
296 if ((val
= getenv("LINES")) && atoi(val
) > 30) /* yes, ASSIGNMENT! */
300 if ((val
= getenv("COLUMNS")) && atoi(val
) > 4) /* yes, ASSIGNMENT! */
307 *o_scroll
= LINES
/ 2 - 1;
309 *o_window
= *o_lines
- 1;
312 /* disable the vbell option if we don't know how to do a vbell */
315 for (i
= 0; opts
[i
].value
!= o_vbell
; i
++)
318 opts
[i
].flags
&= ~CANSET
;
324 for (i
= 0, val
= o_flipcase
; i
< 32; i
++)
326 /* leave out the multiply/divide symbols */
330 /* add lower/uppercase pair */
335 # endif /* CS_LATIN1 */
337 /* initialize the ctype package */
338 _ct_init(o_flipcase
);
341 #endif /* not NO_DIGRAPH */
344 /* This function lists the current values of all options */
346 int all
; /* boolean: dump all options, or just set ones? */
350 char nbuf
[4]; /* used for converting numbers to ASCII */
351 int widths
[5]; /* width of each column, including gap */
352 int ncols
; /* number of columns */
353 int nrows
; /* number of options per column */
354 int nset
; /* number of options to be output */
355 int width
; /* width of a particular option */
356 int todump
[60]; /* indicies of options to be dumped */
358 /* step 1: count the number of set options */
359 for (nset
= i
= 0; opts
[i
].name
; i
++)
361 if (all
|| (opts
[i
].flags
& SET
))
367 /* step two: try to use as many columns as possible */
368 for (ncols
= (nset
> 5 ? 5 : nset
); ncols
> 1; ncols
--)
370 /* how many would go in this column? */
371 nrows
= (nset
+ ncols
- 1) / ncols
;
373 /* figure out the width of each column */
374 for (i
= 0; i
< ncols
; i
++)
377 for (j
= 0, k
= nrows
* i
; j
< nrows
&& k
< nset
; j
++, k
++)
379 /* figure out the width of a particular option */
380 switch (opts
[todump
[k
]].type
)
383 if (!*opts
[todump
[k
]].value
)
390 width
= 3 + strlen(opts
[todump
[k
]].value
);
391 if (width
> MAXWIDTH
)
399 width
+= strlen(opts
[todump
[k
]].name
);
401 /* if this is the widest so far, widen col */
402 if (width
> widths
[i
])
410 /* if the total width is narrow enough, then use it */
411 for (width
= -2, i
= 0; i
< ncols
; i
++)
413 width
+= widths
[i
] + 2;
415 if (width
< COLS
- 1)
421 /* step 3: output the columns */
422 nrows
= (nset
+ ncols
- 1) / ncols
;
423 for (i
= 0; i
< nrows
; i
++)
425 for (j
= 0; j
< ncols
; j
++)
427 /* if we hit the end of the options, quit */
434 /* output this option's value */
436 switch (opts
[todump
[k
]].type
)
439 if (!*opts
[todump
[k
]].value
)
445 qaddstr(opts
[todump
[k
]].name
);
446 width
+= strlen(opts
[todump
[k
]].name
);
450 sprintf(nbuf
, "%-3d", UCHAR(*opts
[todump
[k
]].value
));
451 qaddstr(opts
[todump
[k
]].name
);
454 width
= 4 + strlen(opts
[todump
[k
]].name
);
458 qaddstr(opts
[todump
[k
]].name
);
461 strcpy(tmpblk
.c
, opts
[todump
[k
]].value
);
462 width
= 3 + strlen(tmpblk
.c
);
463 if (width
> MAXWIDTH
)
466 strcpy(tmpblk
.c
+ MAXWIDTH
- 6, "...");
470 width
+= strlen(opts
[todump
[k
]].name
);
474 /* pad the field to the correct size */
475 if (k
+ nrows
<= nset
)
477 while (width
< widths
[j
] + 2)
492 for (i
= col
= 0; opts
[i
].name
; i
++)
494 /* if not set and not all, ignore this option */
495 if (!all
&& !(opts
[i
].flags
& SET
))
500 /* align this option in one of the columns */
523 switch (opts
[i
].type
)
532 qaddstr(opts
[i
].name
);
533 col
+= strlen(opts
[i
].name
);
537 sprintf(nbuf
, "%-3d", UCHAR(*opts
[i
].value
));
538 qaddstr(opts
[i
].name
);
541 col
+= 4 + strlen(opts
[i
].name
);
545 qaddstr(opts
[i
].name
);
548 qaddstr(opts
[i
].value
);
550 col
+= 3 + strlen(opts
[i
].name
) + strlen(opts
[i
].value
);
564 /* This function saves the current configuration of options to a file */
566 int fd
; /* file descriptor to write to */
571 /* write each set options */
572 for (i
= 0; opts
[i
].name
; i
++)
574 /* if unset or unsettable, ignore this option */
575 if ((opts
[i
].flags
& (SET
|CANSET
|NOSAVE
)) != (SET
|CANSET
))
582 switch (opts
[i
].type
)
590 strcpy(pos
, opts
[i
].name
);
595 sprintf(pos
, "%s=%-3d\n", opts
[i
].name
, *opts
[i
].value
& 0xff);
599 sprintf(pos
, "%s=\"%s\"\n", opts
[i
].name
, opts
[i
].value
);
602 twrite(fd
, buf
, strlen(buf
));
608 /* This function changes the values of one or more options. */
609 void setopts(assignments
)
610 char *assignments
; /* a string containing option assignments */
612 char *name
; /* name of variable in assignments */
613 char *value
; /* value of the variable */
614 char *scan
; /* used for moving through strings */
615 char *prefix
; /* pointer to "~" or "no" at front of a boolean */
619 /* reset the upper limit of "window" option to lines-1 */
620 *o_window
= *o_lines
- 1;
623 /* for each assignment... */
624 for (name
= assignments
; *name
; )
626 /* skip whitespace */
627 if (*name
== ' ' || *name
== '\t')
633 /* find the value, if any */
634 for (scan
= name
; *scan
>= 'a' && *scan
<= 'z'; scan
++)
640 if (*scan
== '"' && !QTST(scan
))
643 while (*scan
&& *scan
!= '"')
655 while (*scan
&& (*scan
!= ' ' && *scan
!= '\t' || QTST(scan
)))
665 else /* no "=" so it is probably boolean... */
674 if (!strcmp(name
, "novice"))
675 /* don't check for a "no" prefix */;
678 if (prefix
[0] == 'n' && prefix
[1] == 'o')
680 else if (prefix
[0] == 'n' && prefix
[1] == 'e' && prefix
[2] == 'g')
684 /* find the variable */
686 opts
[i
].name
&& strcmp(opts
[i
].name
, name
) && strcmp(opts
[i
].nm
, name
);
691 /* change the variable */
694 msg("invalid option name \"%s\"", name
);
696 else if ((opts
[i
].flags
& CANSET
) != CANSET
)
698 msg("option \"%s\" can't be altered", name
);
700 else if ((opts
[i
].flags
& RCSET
) != CANSET
&& nlines
>= 1L)
702 msg("option \"%s\" can only be set in a %s file", name
, EXRC
);
706 switch (opts
[i
].type
)
709 msg("option \"[no]%s\" is boolean", name
);
714 if (j
== 0 && *value
!= '0')
716 msg("option \"%s\" must have a numeric value", name
);
718 else if (j
< opts
[i
].value
[1] || j
> (opts
[i
].value
[2] & 0xff))
720 msg("option \"%s\" must have a value between %d and %d",
721 name
, opts
[i
].value
[1], opts
[i
].value
[2] & 0xff);
725 *opts
[i
].value
= atoi(value
);
726 opts
[i
].flags
|= SET
;
731 strcpy(opts
[i
].value
, value
);
732 opts
[i
].flags
|= SET
;
735 if (opts
[i
].flags
& MR
)
737 redraw(MARK_UNSET
, FALSE
);
740 else /* valid option, no value */
742 if (opts
[i
].type
== BOOL
)
745 *opts
[i
].value
= TRUE
;
746 else if (prefix
[1] == 'o')
747 *opts
[i
].value
= FALSE
;
749 *opts
[i
].value
= !*opts
[i
].value
;
751 opts
[i
].flags
|= SET
;
752 if (opts
[i
].flags
& MR
)
754 redraw(MARK_UNSET
, FALSE
);
759 msg("option \"%s\" must be given a value", name
);
763 /* move on to the next option */
767 /* special processing ... */
770 /* if "novice" is set, then ":set report=1 showmode nomagic" */
783 /* if "readonly" then set the READONLY flag for this file */
786 setflag(file
, READONLY
);
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);