| File: | src/usr.bin/vi/build/../common/options.c |
| Warning: | line 854, column 20 Division by zero |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* $OpenBSD: options.c,v 1.29 2021/04/13 15:39:21 millert Exp $ */ | |||
| 2 | ||||
| 3 | /*- | |||
| 4 | * Copyright (c) 1991, 1993, 1994 | |||
| 5 | * The Regents of the University of California. All rights reserved. | |||
| 6 | * Copyright (c) 1991, 1993, 1994, 1995, 1996 | |||
| 7 | * Keith Bostic. All rights reserved. | |||
| 8 | * | |||
| 9 | * See the LICENSE file for redistribution information. | |||
| 10 | */ | |||
| 11 | ||||
| 12 | #include "config.h" | |||
| 13 | ||||
| 14 | #include <sys/types.h> | |||
| 15 | #include <sys/queue.h> | |||
| 16 | #include <sys/stat.h> | |||
| 17 | #include <sys/time.h> | |||
| 18 | ||||
| 19 | #include <bitstring.h> | |||
| 20 | #include <ctype.h> | |||
| 21 | #include <errno(*__errno()).h> | |||
| 22 | #include <limits.h> | |||
| 23 | #include <paths.h> | |||
| 24 | #include <stdio.h> | |||
| 25 | #include <stdlib.h> | |||
| 26 | #include <string.h> | |||
| 27 | #include <unistd.h> | |||
| 28 | ||||
| 29 | #include "common.h" | |||
| 30 | #include "../vi/vi.h" | |||
| 31 | #include "pathnames.h" | |||
| 32 | ||||
| 33 | static int opts_abbcmp(const void *, const void *); | |||
| 34 | static int opts_cmp(const void *, const void *); | |||
| 35 | static int opts_print(SCR *, OPTLIST const *); | |||
| 36 | ||||
| 37 | /* | |||
| 38 | * O'Reilly noted options and abbreviations are from "Learning the VI Editor", | |||
| 39 | * Fifth Edition, May 1992. There's no way of knowing what systems they are | |||
| 40 | * actually from. | |||
| 41 | * | |||
| 42 | * HPUX noted options and abbreviations are from "The Ultimate Guide to the | |||
| 43 | * VI and EX Text Editors", 1990. | |||
| 44 | */ | |||
| 45 | OPTLIST const optlist[] = { | |||
| 46 | /* O_ALTWERASE 4.4BSD */ | |||
| 47 | {"altwerase", f_altwerase, OPT_0BOOL, 0}, | |||
| 48 | /* O_AUTOINDENT 4BSD */ | |||
| 49 | {"autoindent", NULL((void *)0), OPT_0BOOL, 0}, | |||
| 50 | /* O_AUTOPRINT 4BSD */ | |||
| 51 | {"autoprint", NULL((void *)0), OPT_1BOOL, 0}, | |||
| 52 | /* O_AUTOWRITE 4BSD */ | |||
| 53 | {"autowrite", NULL((void *)0), OPT_0BOOL, 0}, | |||
| 54 | /* O_BACKUP 4.4BSD */ | |||
| 55 | {"backup", NULL((void *)0), OPT_STR, 0}, | |||
| 56 | /* O_BEAUTIFY 4BSD */ | |||
| 57 | {"beautify", NULL((void *)0), OPT_0BOOL, 0}, | |||
| 58 | /* O_CDPATH 4.4BSD */ | |||
| 59 | {"cdpath", NULL((void *)0), OPT_STR, 0}, | |||
| 60 | /* O_CEDIT 4.4BSD */ | |||
| 61 | {"cedit", NULL((void *)0), OPT_STR, 0}, | |||
| 62 | /* O_COLUMNS 4.4BSD */ | |||
| 63 | {"columns", f_columns, OPT_NUM, OPT_NOSAVE0x008}, | |||
| 64 | /* O_COMMENT 4.4BSD */ | |||
| 65 | {"comment", NULL((void *)0), OPT_0BOOL, 0}, | |||
| 66 | /* O_EDCOMPATIBLE 4BSD */ | |||
| 67 | {"edcompatible",NULL((void *)0), OPT_0BOOL, 0}, | |||
| 68 | /* O_ESCAPETIME 4.4BSD */ | |||
| 69 | {"escapetime", NULL((void *)0), OPT_NUM, 0}, | |||
| 70 | /* O_ERRORBELLS 4BSD */ | |||
| 71 | {"errorbells", NULL((void *)0), OPT_0BOOL, 0}, | |||
| 72 | /* O_EXPANDTAB NetBSD 5.0 */ | |||
| 73 | {"expandtab", NULL((void *)0), OPT_0BOOL, 0}, | |||
| 74 | /* O_EXRC System V (undocumented) */ | |||
| 75 | {"exrc", NULL((void *)0), OPT_0BOOL, 0}, | |||
| 76 | /* O_EXTENDED 4.4BSD */ | |||
| 77 | {"extended", f_recompile, OPT_0BOOL, 0}, | |||
| 78 | /* O_FILEC 4.4BSD */ | |||
| 79 | {"filec", NULL((void *)0), OPT_STR, 0}, | |||
| 80 | /* O_FLASH HPUX */ | |||
| 81 | {"flash", NULL((void *)0), OPT_0BOOL, 0}, | |||
| 82 | /* O_HARDTABS 4BSD */ | |||
| 83 | {"hardtabs", NULL((void *)0), OPT_NUM, 0}, | |||
| 84 | /* O_ICLOWER 4.4BSD */ | |||
| 85 | {"iclower", f_recompile, OPT_0BOOL, 0}, | |||
| 86 | /* O_IGNORECASE 4BSD */ | |||
| 87 | {"ignorecase", f_recompile, OPT_0BOOL, 0}, | |||
| 88 | /* O_KEYTIME 4.4BSD */ | |||
| 89 | {"keytime", NULL((void *)0), OPT_NUM, 0}, | |||
| 90 | /* O_LEFTRIGHT 4.4BSD */ | |||
| 91 | {"leftright", f_reformat, OPT_0BOOL, 0}, | |||
| 92 | /* O_LINES 4.4BSD */ | |||
| 93 | {"lines", f_lines, OPT_NUM, OPT_NOSAVE0x008}, | |||
| 94 | /* O_LIST 4BSD */ | |||
| 95 | {"list", f_reformat, OPT_0BOOL, 0}, | |||
| 96 | /* O_LOCKFILES 4.4BSD | |||
| 97 | * XXX | |||
| 98 | * Locking isn't reliable enough over NFS to require it, in addition, | |||
| 99 | * it's a serious startup performance problem over some remote links. | |||
| 100 | */ | |||
| 101 | {"lock", NULL((void *)0), OPT_1BOOL, 0}, | |||
| 102 | /* O_MAGIC 4BSD */ | |||
| 103 | {"magic", NULL((void *)0), OPT_1BOOL, 0}, | |||
| 104 | /* O_MATCHTIME 4.4BSD */ | |||
| 105 | {"matchtime", NULL((void *)0), OPT_NUM, 0}, | |||
| 106 | /* O_MESG 4BSD */ | |||
| 107 | {"mesg", NULL((void *)0), OPT_1BOOL, 0}, | |||
| 108 | /* O_NOPRINT 4.4BSD */ | |||
| 109 | {"noprint", f_print, OPT_STR, OPT_EARLYSET0x080}, | |||
| 110 | /* O_NUMBER 4BSD */ | |||
| 111 | {"number", f_reformat, OPT_0BOOL, 0}, | |||
| 112 | /* O_OCTAL 4.4BSD */ | |||
| 113 | {"octal", f_print, OPT_0BOOL, OPT_EARLYSET0x080}, | |||
| 114 | /* O_OPEN 4BSD */ | |||
| 115 | {"open", NULL((void *)0), OPT_1BOOL, 0}, | |||
| 116 | /* O_PARAGRAPHS 4BSD */ | |||
| 117 | {"paragraphs", f_paragraph, OPT_STR, 0}, | |||
| 118 | /* O_PATH 4.4BSD */ | |||
| 119 | {"path", NULL((void *)0), OPT_STR, 0}, | |||
| 120 | /* O_PRINT 4.4BSD */ | |||
| 121 | {"print", f_print, OPT_STR, OPT_EARLYSET0x080}, | |||
| 122 | /* O_PROMPT 4BSD */ | |||
| 123 | {"prompt", NULL((void *)0), OPT_1BOOL, 0}, | |||
| 124 | /* O_READONLY 4BSD (undocumented) */ | |||
| 125 | {"readonly", f_readonly, OPT_0BOOL, OPT_ALWAYS0x002}, | |||
| 126 | /* O_RECDIR 4.4BSD */ | |||
| 127 | {"recdir", NULL((void *)0), OPT_STR, 0}, | |||
| 128 | /* O_REMAP 4BSD */ | |||
| 129 | {"remap", NULL((void *)0), OPT_1BOOL, 0}, | |||
| 130 | /* O_REPORT 4BSD */ | |||
| 131 | {"report", NULL((void *)0), OPT_NUM, 0}, | |||
| 132 | /* O_RULER 4.4BSD */ | |||
| 133 | {"ruler", NULL((void *)0), OPT_0BOOL, 0}, | |||
| 134 | /* O_SCROLL 4BSD */ | |||
| 135 | {"scroll", NULL((void *)0), OPT_NUM, 0}, | |||
| 136 | /* O_SEARCHINCR 4.4BSD */ | |||
| 137 | {"searchincr", NULL((void *)0), OPT_0BOOL, 0}, | |||
| 138 | /* O_SECTIONS 4BSD */ | |||
| 139 | {"sections", f_section, OPT_STR, 0}, | |||
| 140 | /* O_SECURE 4.4BSD */ | |||
| 141 | {"secure", f_secure, OPT_0BOOL, OPT_NOUNSET0x020}, | |||
| 142 | /* O_SHELL 4BSD */ | |||
| 143 | {"shell", NULL((void *)0), OPT_STR, 0}, | |||
| 144 | /* O_SHELLMETA 4.4BSD */ | |||
| 145 | {"shellmeta", NULL((void *)0), OPT_STR, 0}, | |||
| 146 | /* O_SHIFTWIDTH 4BSD */ | |||
| 147 | {"shiftwidth", NULL((void *)0), OPT_NUM, OPT_NOZERO0x040}, | |||
| 148 | /* O_SHOWMATCH 4BSD */ | |||
| 149 | {"showmatch", NULL((void *)0), OPT_0BOOL, 0}, | |||
| 150 | /* O_SHOWMODE 4.4BSD */ | |||
| 151 | {"showmode", NULL((void *)0), OPT_0BOOL, 0}, | |||
| 152 | /* O_SIDESCROLL 4.4BSD */ | |||
| 153 | {"sidescroll", NULL((void *)0), OPT_NUM, OPT_NOZERO0x040}, | |||
| 154 | /* O_TABSTOP 4BSD */ | |||
| 155 | {"tabstop", f_reformat, OPT_NUM, OPT_NOZERO0x040}, | |||
| 156 | /* O_TAGLENGTH 4BSD */ | |||
| 157 | {"taglength", NULL((void *)0), OPT_NUM, 0}, | |||
| 158 | /* O_TAGS 4BSD */ | |||
| 159 | {"tags", NULL((void *)0), OPT_STR, 0}, | |||
| 160 | /* O_TERM 4BSD | |||
| 161 | * !!! | |||
| 162 | * By default, the historic vi always displayed information about two | |||
| 163 | * options, redraw and term. Term seems sufficient. | |||
| 164 | */ | |||
| 165 | {"term", NULL((void *)0), OPT_STR, OPT_ADISP0x001|OPT_NOSAVE0x008}, | |||
| 166 | /* O_TERSE 4BSD */ | |||
| 167 | {"terse", NULL((void *)0), OPT_0BOOL, 0}, | |||
| 168 | /* O_TILDEOP 4.4BSD */ | |||
| 169 | {"tildeop", NULL((void *)0), OPT_0BOOL, 0}, | |||
| 170 | /* O_TIMEOUT 4BSD (undocumented) */ | |||
| 171 | {"timeout", NULL((void *)0), OPT_1BOOL, 0}, | |||
| 172 | /* O_TTYWERASE 4.4BSD */ | |||
| 173 | {"ttywerase", f_ttywerase, OPT_0BOOL, 0}, | |||
| 174 | /* O_VERBOSE 4.4BSD */ | |||
| 175 | {"verbose", NULL((void *)0), OPT_0BOOL, 0}, | |||
| 176 | /* O_W1200 4BSD */ | |||
| 177 | {"w1200", f_w1200, OPT_NUM, OPT_NDISP0x004|OPT_NOSAVE0x008}, | |||
| 178 | /* O_W300 4BSD */ | |||
| 179 | {"w300", f_w300, OPT_NUM, OPT_NDISP0x004|OPT_NOSAVE0x008}, | |||
| 180 | /* O_W9600 4BSD */ | |||
| 181 | {"w9600", f_w9600, OPT_NUM, OPT_NDISP0x004|OPT_NOSAVE0x008}, | |||
| 182 | /* O_WARN 4BSD */ | |||
| 183 | {"warn", NULL((void *)0), OPT_1BOOL, 0}, | |||
| 184 | /* O_WINDOW 4BSD */ | |||
| 185 | {"window", f_window, OPT_NUM, OPT_NOZERO0x040}, | |||
| 186 | /* O_WINDOWNAME 4BSD */ | |||
| 187 | {"windowname", NULL((void *)0), OPT_0BOOL, 0}, | |||
| 188 | /* O_WRAPLEN 4.4BSD */ | |||
| 189 | {"wraplen", NULL((void *)0), OPT_NUM, 0}, | |||
| 190 | /* O_WRAPMARGIN 4BSD */ | |||
| 191 | {"wrapmargin", NULL((void *)0), OPT_NUM, 0}, | |||
| 192 | /* O_WRAPSCAN 4BSD */ | |||
| 193 | {"wrapscan", NULL((void *)0), OPT_1BOOL, 0}, | |||
| 194 | /* O_WRITEANY 4BSD */ | |||
| 195 | {"writeany", NULL((void *)0), OPT_0BOOL, 0}, | |||
| 196 | {NULL((void *)0)}, | |||
| 197 | }; | |||
| 198 | ||||
| 199 | typedef struct abbrev { | |||
| 200 | char *name; | |||
| 201 | int offset; | |||
| 202 | } OABBREV; | |||
| 203 | ||||
| 204 | static OABBREV const abbrev[] = { | |||
| 205 | {"ai", O_AUTOINDENT}, /* 4BSD */ | |||
| 206 | {"ap", O_AUTOPRINT}, /* 4BSD */ | |||
| 207 | {"aw", O_AUTOWRITE}, /* 4BSD */ | |||
| 208 | {"bf", O_BEAUTIFY}, /* 4BSD */ | |||
| 209 | {"co", O_COLUMNS}, /* 4.4BSD */ | |||
| 210 | {"eb", O_ERRORBELLS}, /* 4BSD */ | |||
| 211 | {"ed", O_EDCOMPATIBLE}, /* 4BSD */ | |||
| 212 | {"et", O_EXPANDTAB}, /* NetBSD 5.0 */ | |||
| 213 | {"ex", O_EXRC}, /* System V (undocumented) */ | |||
| 214 | {"ht", O_HARDTABS}, /* 4BSD */ | |||
| 215 | {"ic", O_IGNORECASE}, /* 4BSD */ | |||
| 216 | {"li", O_LINES}, /* 4.4BSD */ | |||
| 217 | {"nu", O_NUMBER}, /* 4BSD */ | |||
| 218 | {"para", O_PARAGRAPHS}, /* 4BSD */ | |||
| 219 | {"ro", O_READONLY}, /* 4BSD (undocumented) */ | |||
| 220 | {"scr", O_SCROLL}, /* 4BSD (undocumented) */ | |||
| 221 | {"sect", O_SECTIONS}, /* O'Reilly */ | |||
| 222 | {"sh", O_SHELL}, /* 4BSD */ | |||
| 223 | {"sm", O_SHOWMATCH}, /* 4BSD */ | |||
| 224 | {"smd", O_SHOWMODE}, /* 4BSD */ | |||
| 225 | {"sw", O_SHIFTWIDTH}, /* 4BSD */ | |||
| 226 | {"tag", O_TAGS}, /* 4BSD (undocumented) */ | |||
| 227 | {"tl", O_TAGLENGTH}, /* 4BSD */ | |||
| 228 | {"to", O_TIMEOUT}, /* 4BSD (undocumented) */ | |||
| 229 | {"ts", O_TABSTOP}, /* 4BSD */ | |||
| 230 | {"tty", O_TERM}, /* 4BSD (undocumented) */ | |||
| 231 | {"ttytype", O_TERM}, /* 4BSD (undocumented) */ | |||
| 232 | {"w", O_WINDOW}, /* O'Reilly */ | |||
| 233 | {"wa", O_WRITEANY}, /* 4BSD */ | |||
| 234 | {"wi", O_WINDOW}, /* 4BSD (undocumented) */ | |||
| 235 | {"wl", O_WRAPLEN}, /* 4.4BSD */ | |||
| 236 | {"wm", O_WRAPMARGIN}, /* 4BSD */ | |||
| 237 | {"ws", O_WRAPSCAN}, /* 4BSD */ | |||
| 238 | {NULL((void *)0)}, | |||
| 239 | }; | |||
| 240 | ||||
| 241 | /* | |||
| 242 | * opts_init -- | |||
| 243 | * Initialize some of the options. | |||
| 244 | * | |||
| 245 | * PUBLIC: int opts_init(SCR *, int *); | |||
| 246 | */ | |||
| 247 | int | |||
| 248 | opts_init(SCR *sp, int *oargs) | |||
| 249 | { | |||
| 250 | ARGS *argv[2], a, b; | |||
| 251 | OPTLIST const *op; | |||
| 252 | u_long v; | |||
| 253 | int optindx; | |||
| 254 | char *s, b1[1024]; | |||
| 255 | ||||
| 256 | a.bp = b1; | |||
| 257 | b.bp = NULL((void *)0); | |||
| 258 | a.len = b.len = 0; | |||
| 259 | argv[0] = &a; | |||
| 260 | argv[1] = &b; | |||
| 261 | ||||
| 262 | /* Set numeric and string default values. */ | |||
| 263 | #define OI_b1(indx) { \ | |||
| 264 | a.len = strlen(b1); \ | |||
| 265 | if (opts_set(sp, argv, NULL((void *)0))) { \ | |||
| 266 | optindx = indx; \ | |||
| 267 | goto err; \ | |||
| 268 | } \ | |||
| 269 | } | |||
| 270 | #define OI(indx, str) { \ | |||
| 271 | (void)strlcpy(b1, (str), sizeof(b1)); \ | |||
| 272 | OI_b1(indx); \ | |||
| 273 | } | |||
| 274 | ||||
| 275 | /* | |||
| 276 | * Indirect global options to global space. Specifically, set up | |||
| 277 | * terminal, lines, columns first, they're used by other options. | |||
| 278 | * Note, don't set the flags until we've set up the indirection. | |||
| 279 | */ | |||
| 280 | if (o_set(sp, O_TERM, 0, NULL((void *)0), GO_TERM3)) { | |||
| 281 | optindx = O_TERM; | |||
| 282 | goto err; | |||
| 283 | } | |||
| 284 | F_SET(&sp->opts[O_TERM], OPT_GLOBAL)(((&sp->opts[O_TERM])->flags) |= ((0x01))); | |||
| 285 | if (o_set(sp, O_LINES, 0, NULL((void *)0), GO_LINES1)) { | |||
| 286 | optindx = O_LINES; | |||
| 287 | goto err; | |||
| 288 | } | |||
| 289 | F_SET(&sp->opts[O_LINES], OPT_GLOBAL)(((&sp->opts[O_LINES])->flags) |= ((0x01))); | |||
| 290 | if (o_set(sp, O_COLUMNS, 0, NULL((void *)0), GO_COLUMNS0)) { | |||
| 291 | optindx = O_COLUMNS; | |||
| 292 | goto err; | |||
| 293 | } | |||
| 294 | F_SET(&sp->opts[O_COLUMNS], OPT_GLOBAL)(((&sp->opts[O_COLUMNS])->flags) |= ((0x01))); | |||
| 295 | if (o_set(sp, O_SECURE, 0, NULL((void *)0), GO_SECURE2)) { | |||
| 296 | optindx = O_SECURE; | |||
| 297 | goto err; | |||
| 298 | } | |||
| 299 | F_SET(&sp->opts[O_SECURE], OPT_GLOBAL)(((&sp->opts[O_SECURE])->flags) |= ((0x01))); | |||
| 300 | ||||
| 301 | /* Initialize string values. */ | |||
| 302 | (void)snprintf(b1, sizeof(b1), | |||
| 303 | "cdpath=%s", (s = getenv("CDPATH")) == NULL((void *)0) ? ":" : s); | |||
| 304 | OI_b1(O_CDPATH); | |||
| 305 | OI(O_ESCAPETIME, "escapetime=1"); | |||
| 306 | OI(O_FILEC, "filec=\t"); | |||
| 307 | OI(O_KEYTIME, "keytime=6"); | |||
| 308 | OI(O_MATCHTIME, "matchtime=7"); | |||
| 309 | OI(O_REPORT, "report=5"); | |||
| 310 | OI(O_PARAGRAPHS, "paragraphs=IPLPPPQPP LIpplpipbpBlBdPpLpIt"); | |||
| 311 | OI(O_PATH, "path="); | |||
| 312 | (void)snprintf(b1, sizeof(b1), "recdir=%s", _PATH_PRESERVE"/tmp/vi.recover"); | |||
| 313 | OI_b1(O_RECDIR); | |||
| 314 | OI(O_SECTIONS, "sections=NHSHH HUnhshShSs"); | |||
| 315 | (void)snprintf(b1, sizeof(b1), | |||
| 316 | "shell=%s", (s = getenv("SHELL")) == NULL((void *)0) ? _PATH_BSHELL"/bin/sh" : s); | |||
| 317 | OI_b1(O_SHELL); | |||
| 318 | OI(O_SHELLMETA, "shellmeta=~{[*?$`'\"\\"); | |||
| 319 | OI(O_SHIFTWIDTH, "shiftwidth=8"); | |||
| 320 | OI(O_SIDESCROLL, "sidescroll=16"); | |||
| 321 | OI(O_TABSTOP, "tabstop=8"); | |||
| 322 | (void)snprintf(b1, sizeof(b1), "tags=%s", _PATH_TAGS"tags"); | |||
| 323 | OI_b1(O_TAGS); | |||
| 324 | ||||
| 325 | /* | |||
| 326 | * XXX | |||
| 327 | * Initialize O_SCROLL here, after term; initializing term should | |||
| 328 | * have created a LINES/COLUMNS value. | |||
| 329 | */ | |||
| 330 | if ((v = (O_VAL(sp, O_LINES)((((&((sp))->opts[((O_LINES))])->flags) & ((0x01 ))) ? ((sp))->gp->opts[((sp))->opts[((O_LINES))].o_cur .val].o_cur.val : ((sp))->opts[((O_LINES))].o_cur.val) - 1) / 2) == 0) | |||
| 331 | v = 1; | |||
| 332 | (void)snprintf(b1, sizeof(b1), "scroll=%ld", v); | |||
| 333 | OI_b1(O_SCROLL); | |||
| 334 | ||||
| 335 | /* | |||
| 336 | * The default window option values are: | |||
| 337 | * 8 if baud rate <= 600 | |||
| 338 | * 16 if baud rate <= 1200 | |||
| 339 | * LINES - 1 if baud rate > 1200 | |||
| 340 | * | |||
| 341 | * Note, the windows option code will correct any too-large value | |||
| 342 | * or when the O_LINES value is 1. | |||
| 343 | */ | |||
| 344 | if (sp->gp->scr_baud(sp, &v)) | |||
| 345 | return (1); | |||
| 346 | if (v <= 600) | |||
| 347 | v = 8; | |||
| 348 | else if (v <= 1200) | |||
| 349 | v = 16; | |||
| 350 | else | |||
| 351 | v = O_VAL(sp, O_LINES)((((&((sp))->opts[((O_LINES))])->flags) & ((0x01 ))) ? ((sp))->gp->opts[((sp))->opts[((O_LINES))].o_cur .val].o_cur.val : ((sp))->opts[((O_LINES))].o_cur.val) - 1; | |||
| 352 | (void)snprintf(b1, sizeof(b1), "window=%lu", v); | |||
| 353 | OI_b1(O_WINDOW); | |||
| 354 | ||||
| 355 | /* | |||
| 356 | * Set boolean default values, and copy all settings into the default | |||
| 357 | * information. OS_NOFREE is set, we're copying, not replacing. | |||
| 358 | */ | |||
| 359 | for (op = optlist, optindx = 0; op->name != NULL((void *)0); ++op, ++optindx) | |||
| 360 | switch (op->type) { | |||
| 361 | case OPT_0BOOL: | |||
| 362 | break; | |||
| 363 | case OPT_1BOOL: | |||
| 364 | O_SET(sp, optindx)o_set((sp), (optindx), 0, ((void *)0), 1); | |||
| 365 | O_D_SET(sp, optindx)o_set((sp), (optindx), 0x01, ((void *)0), 1); | |||
| 366 | break; | |||
| 367 | case OPT_NUM: | |||
| 368 | o_set(sp, optindx, OS_DEF0x01, NULL((void *)0), O_VAL(sp, optindx)((((&((sp))->opts[((optindx))])->flags) & ((0x01 ))) ? ((sp))->gp->opts[((sp))->opts[((optindx))].o_cur .val].o_cur.val : ((sp))->opts[((optindx))].o_cur.val)); | |||
| 369 | break; | |||
| 370 | case OPT_STR: | |||
| 371 | if (O_STR(sp, optindx)((((&((sp))->opts[((optindx))])->flags) & ((0x01 ))) ? ((sp))->gp->opts[((sp))->opts[((optindx))].o_cur .val].o_cur.str : ((sp))->opts[((optindx))].o_cur.str) != NULL((void *)0) && o_set(sp, optindx, | |||
| 372 | OS_DEF0x01 | OS_NOFREE0x02 | OS_STRDUP0x08, O_STR(sp, optindx)((((&((sp))->opts[((optindx))])->flags) & ((0x01 ))) ? ((sp))->gp->opts[((sp))->opts[((optindx))].o_cur .val].o_cur.str : ((sp))->opts[((optindx))].o_cur.str), 0)) | |||
| 373 | goto err; | |||
| 374 | break; | |||
| 375 | default: | |||
| 376 | abort(); | |||
| 377 | } | |||
| 378 | ||||
| 379 | /* | |||
| 380 | * !!! | |||
| 381 | * Some options can be initialized by the command name or the | |||
| 382 | * command-line arguments. They don't set the default values, | |||
| 383 | * it's historic practice. | |||
| 384 | */ | |||
| 385 | for (; *oargs != -1; ++oargs) | |||
| 386 | OI(*oargs, optlist[*oargs].name); | |||
| 387 | return (0); | |||
| 388 | #undef OI | |||
| 389 | #undef OI_b1 | |||
| 390 | ||||
| 391 | err: msgq(sp, M_ERR, | |||
| 392 | "Unable to set default %s option", optlist[optindx].name); | |||
| 393 | return (1); | |||
| 394 | } | |||
| 395 | ||||
| 396 | /* | |||
| 397 | * opts_set -- | |||
| 398 | * Change the values of one or more options. | |||
| 399 | * | |||
| 400 | * PUBLIC: int opts_set(SCR *, ARGS *[], char *); | |||
| 401 | */ | |||
| 402 | int | |||
| 403 | opts_set(SCR *sp, ARGS *argv[], char *usage) | |||
| 404 | { | |||
| 405 | enum optdisp disp; | |||
| 406 | enum nresult nret; | |||
| 407 | OPTLIST const *op; | |||
| 408 | OPTION *spo; | |||
| 409 | u_long value, turnoff; | |||
| 410 | int ch, equals, nf, nf2, offset, qmark, rval; | |||
| 411 | char *endp, *name, *p, *sep, *t; | |||
| 412 | ||||
| 413 | disp = NO_DISPLAY; | |||
| 414 | for (rval = 0; argv[0]->len != 0; ++argv) { | |||
| 415 | /* | |||
| 416 | * The historic vi dumped the options for each occurrence of | |||
| 417 | * "all" in the set list. Puhleeze. | |||
| 418 | */ | |||
| 419 | if (!strcmp(argv[0]->bp, "all")) { | |||
| 420 | disp = ALL_DISPLAY; | |||
| 421 | continue; | |||
| 422 | } | |||
| 423 | ||||
| 424 | /* Find equals sign or question mark. */ | |||
| 425 | for (sep = NULL((void *)0), equals = qmark = 0, | |||
| 426 | p = name = argv[0]->bp; (ch = *p) != '\0'; ++p) | |||
| 427 | if (ch == '=' || ch == '?') { | |||
| 428 | if (p == name) { | |||
| 429 | if (usage != NULL((void *)0)) | |||
| 430 | msgq(sp, M_ERR, | |||
| 431 | "Usage: %s", usage); | |||
| 432 | return (1); | |||
| 433 | } | |||
| 434 | sep = p; | |||
| 435 | if (ch == '=') | |||
| 436 | equals = 1; | |||
| 437 | else | |||
| 438 | qmark = 1; | |||
| 439 | break; | |||
| 440 | } | |||
| 441 | ||||
| 442 | turnoff = 0; | |||
| 443 | op = NULL((void *)0); | |||
| 444 | if (sep != NULL((void *)0)) | |||
| 445 | *sep++ = '\0'; | |||
| 446 | ||||
| 447 | /* Search for the name, then name without any leading "no". */ | |||
| 448 | if ((op = opts_search(name)) == NULL((void *)0) && | |||
| 449 | name[0] == 'n' && name[1] == 'o') { | |||
| 450 | turnoff = 1; | |||
| 451 | name += 2; | |||
| 452 | op = opts_search(name); | |||
| 453 | } | |||
| 454 | if (op == NULL((void *)0)) { | |||
| 455 | opts_nomatch(sp, name); | |||
| 456 | rval = 1; | |||
| 457 | continue; | |||
| 458 | } | |||
| 459 | ||||
| 460 | /* Find current option values. */ | |||
| 461 | offset = op - optlist; | |||
| 462 | spo = sp->opts + offset; | |||
| 463 | ||||
| 464 | /* | |||
| 465 | * !!! | |||
| 466 | * Historically, the question mark could be a separate | |||
| 467 | * argument. | |||
| 468 | */ | |||
| 469 | if (!equals && !qmark && | |||
| 470 | argv[1]->len == 1 && argv[1]->bp[0] == '?') { | |||
| 471 | ++argv; | |||
| 472 | qmark = 1; | |||
| 473 | } | |||
| 474 | ||||
| 475 | /* Set name, value. */ | |||
| 476 | switch (op->type) { | |||
| 477 | case OPT_0BOOL: | |||
| 478 | case OPT_1BOOL: | |||
| 479 | /* Some options may not be reset. */ | |||
| 480 | if (F_ISSET(op, OPT_NOUNSET)(((op)->flags) & ((0x020))) && turnoff) { | |||
| 481 | msgq_str(sp, M_ERR, name, | |||
| 482 | "set: the %s option may not be turned off"); | |||
| 483 | rval = 1; | |||
| 484 | break; | |||
| 485 | } | |||
| 486 | ||||
| 487 | if (equals) { | |||
| 488 | msgq_str(sp, M_ERR, name, | |||
| 489 | "set: [no]%s option doesn't take a value"); | |||
| 490 | rval = 1; | |||
| 491 | break; | |||
| 492 | } | |||
| 493 | if (qmark) { | |||
| 494 | if (!disp) | |||
| 495 | disp = SELECT_DISPLAY; | |||
| 496 | F_SET(spo, OPT_SELECTED)(((spo)->flags) |= ((0x02))); | |||
| 497 | break; | |||
| 498 | } | |||
| 499 | ||||
| 500 | /* | |||
| 501 | * Do nothing if the value is unchanged, the underlying | |||
| 502 | * functions can be expensive. | |||
| 503 | */ | |||
| 504 | if (!F_ISSET(op, OPT_ALWAYS)(((op)->flags) & ((0x002)))) { | |||
| 505 | if (turnoff) { | |||
| 506 | if (!O_ISSET(sp, offset)((((&(((sp)))->opts[(((offset)))])->flags) & (( 0x01))) ? (((sp)))->gp->opts[(((sp)))->opts[(((offset )))].o_cur.val].o_cur.val : (((sp)))->opts[(((offset)))].o_cur .val)) | |||
| 507 | break; | |||
| 508 | } else { | |||
| 509 | if (O_ISSET(sp, offset)((((&(((sp)))->opts[(((offset)))])->flags) & (( 0x01))) ? (((sp)))->gp->opts[(((sp)))->opts[(((offset )))].o_cur.val].o_cur.val : (((sp)))->opts[(((offset)))].o_cur .val)) | |||
| 510 | break; | |||
| 511 | } | |||
| 512 | } | |||
| 513 | ||||
| 514 | if (F_ISSET(op, OPT_EARLYSET)(((op)->flags) & ((0x080)))) { | |||
| 515 | /* Set the value. */ | |||
| 516 | if (turnoff) | |||
| 517 | O_CLR(sp, offset)o_set((sp), (offset), 0, ((void *)0), 0); | |||
| 518 | else | |||
| 519 | O_SET(sp, offset)o_set((sp), (offset), 0, ((void *)0), 1); | |||
| 520 | } | |||
| 521 | ||||
| 522 | /* Report to subsystems. */ | |||
| 523 | if ((op->func != NULL((void *)0) && | |||
| 524 | op->func(sp, spo, NULL((void *)0), &turnoff)) || | |||
| 525 | ex_optchange(sp, offset, NULL((void *)0), &turnoff) || | |||
| 526 | v_optchange(sp, offset, NULL((void *)0), &turnoff) || | |||
| 527 | sp->gp->scr_optchange(sp, offset, NULL((void *)0), &turnoff)) { | |||
| 528 | rval = 1; | |||
| 529 | break; | |||
| 530 | } | |||
| 531 | ||||
| 532 | if (!F_ISSET(op, OPT_EARLYSET)(((op)->flags) & ((0x080)))) { | |||
| 533 | /* Set the value. */ | |||
| 534 | if (turnoff) | |||
| 535 | O_CLR(sp, offset)o_set((sp), (offset), 0, ((void *)0), 0); | |||
| 536 | else | |||
| 537 | O_SET(sp, offset)o_set((sp), (offset), 0, ((void *)0), 1); | |||
| 538 | } | |||
| 539 | break; | |||
| 540 | case OPT_NUM: | |||
| 541 | if (turnoff) { | |||
| 542 | msgq_str(sp, M_ERR, name, | |||
| 543 | "set: %s option isn't a boolean"); | |||
| 544 | rval = 1; | |||
| 545 | break; | |||
| 546 | } | |||
| 547 | if (qmark || !equals) { | |||
| 548 | if (!disp) | |||
| 549 | disp = SELECT_DISPLAY; | |||
| 550 | F_SET(spo, OPT_SELECTED)(((spo)->flags) |= ((0x02))); | |||
| 551 | break; | |||
| 552 | } | |||
| 553 | ||||
| 554 | if (!isdigit(sep[0])) | |||
| 555 | goto badnum; | |||
| 556 | if ((nret = | |||
| 557 | nget_uslong(&value, sep, &endp, 10)) != NUM_OK) { | |||
| 558 | p = msg_print(sp, name, &nf); | |||
| 559 | t = msg_print(sp, sep, &nf2); | |||
| 560 | switch (nret) { | |||
| 561 | case NUM_ERR: | |||
| 562 | msgq(sp, M_SYSERR, | |||
| 563 | "set: %s option: %s", p, t); | |||
| 564 | break; | |||
| 565 | case NUM_OVER: | |||
| 566 | msgq(sp, M_ERR, | |||
| 567 | "set: %s option: %s: value overflow", p, t); | |||
| 568 | break; | |||
| 569 | case NUM_OK: | |||
| 570 | case NUM_UNDER: | |||
| 571 | abort(); | |||
| 572 | } | |||
| 573 | if (nf) | |||
| 574 | FREE_SPACE(sp, p, 0){ GS *L__gp = (sp) == ((void *)0) ? ((void *)0) : (sp)->gp ; if (L__gp != ((void *)0) && (p) == L__gp->tmp_bp ) (((L__gp)->flags) &= ~((0x0100))); else free(p); }; | |||
| 575 | if (nf2) | |||
| 576 | FREE_SPACE(sp, t, 0){ GS *L__gp = (sp) == ((void *)0) ? ((void *)0) : (sp)->gp ; if (L__gp != ((void *)0) && (t) == L__gp->tmp_bp ) (((L__gp)->flags) &= ~((0x0100))); else free(t); }; | |||
| 577 | rval = 1; | |||
| 578 | break; | |||
| 579 | } | |||
| 580 | if (*endp && !isblank(*endp)) { | |||
| 581 | badnum: p = msg_print(sp, name, &nf); | |||
| 582 | t = msg_print(sp, sep, &nf2); | |||
| 583 | msgq(sp, M_ERR, | |||
| 584 | "set: %s option: %s is an illegal number", p, t); | |||
| 585 | if (nf) | |||
| 586 | FREE_SPACE(sp, p, 0){ GS *L__gp = (sp) == ((void *)0) ? ((void *)0) : (sp)->gp ; if (L__gp != ((void *)0) && (p) == L__gp->tmp_bp ) (((L__gp)->flags) &= ~((0x0100))); else free(p); }; | |||
| 587 | if (nf2) | |||
| 588 | FREE_SPACE(sp, t, 0){ GS *L__gp = (sp) == ((void *)0) ? ((void *)0) : (sp)->gp ; if (L__gp != ((void *)0) && (t) == L__gp->tmp_bp ) (((L__gp)->flags) &= ~((0x0100))); else free(t); }; | |||
| 589 | rval = 1; | |||
| 590 | break; | |||
| 591 | } | |||
| 592 | ||||
| 593 | /* Some options may never be set to zero. */ | |||
| 594 | if (F_ISSET(op, OPT_NOZERO)(((op)->flags) & ((0x040))) && value == 0) { | |||
| 595 | msgq_str(sp, M_ERR, name, | |||
| 596 | "set: the %s option may never be set to 0"); | |||
| 597 | rval = 1; | |||
| 598 | break; | |||
| 599 | } | |||
| 600 | ||||
| 601 | /* | |||
| 602 | * Do nothing if the value is unchanged, the underlying | |||
| 603 | * functions can be expensive. | |||
| 604 | */ | |||
| 605 | if (!F_ISSET(op, OPT_ALWAYS)(((op)->flags) & ((0x002))) && | |||
| 606 | O_VAL(sp, offset)((((&((sp))->opts[((offset))])->flags) & ((0x01 ))) ? ((sp))->gp->opts[((sp))->opts[((offset))].o_cur .val].o_cur.val : ((sp))->opts[((offset))].o_cur.val) == value) | |||
| 607 | break; | |||
| 608 | ||||
| 609 | if (F_ISSET(op, OPT_EARLYSET)(((op)->flags) & ((0x080)))) { | |||
| 610 | /* Set the value. */ | |||
| 611 | if (o_set(sp, offset, 0, NULL((void *)0), value)) { | |||
| 612 | rval = 1; | |||
| 613 | break; | |||
| 614 | } | |||
| 615 | } | |||
| 616 | ||||
| 617 | /* Report to subsystems. */ | |||
| 618 | if ((op->func != NULL((void *)0) && | |||
| 619 | op->func(sp, spo, sep, &value)) || | |||
| 620 | ex_optchange(sp, offset, sep, &value) || | |||
| 621 | v_optchange(sp, offset, sep, &value) || | |||
| 622 | sp->gp->scr_optchange(sp, offset, sep, &value)) { | |||
| 623 | rval = 1; | |||
| 624 | break; | |||
| 625 | } | |||
| 626 | ||||
| 627 | if (!F_ISSET(op, OPT_EARLYSET)(((op)->flags) & ((0x080)))) { | |||
| 628 | /* Set the value. */ | |||
| 629 | if (o_set(sp, offset, 0, NULL((void *)0), value)) | |||
| 630 | rval = 1; | |||
| 631 | } | |||
| 632 | break; | |||
| 633 | case OPT_STR: | |||
| 634 | if (turnoff) { | |||
| 635 | msgq_str(sp, M_ERR, name, | |||
| 636 | "set: %s option isn't a boolean"); | |||
| 637 | rval = 1; | |||
| 638 | break; | |||
| 639 | } | |||
| 640 | if (qmark || !equals) { | |||
| 641 | if (!disp) | |||
| 642 | disp = SELECT_DISPLAY; | |||
| 643 | F_SET(spo, OPT_SELECTED)(((spo)->flags) |= ((0x02))); | |||
| 644 | break; | |||
| 645 | } | |||
| 646 | ||||
| 647 | /* | |||
| 648 | * Do nothing if the value is unchanged, the underlying | |||
| 649 | * functions can be expensive. | |||
| 650 | */ | |||
| 651 | if (!F_ISSET(op, OPT_ALWAYS)(((op)->flags) & ((0x002))) && | |||
| 652 | O_STR(sp, offset)((((&((sp))->opts[((offset))])->flags) & ((0x01 ))) ? ((sp))->gp->opts[((sp))->opts[((offset))].o_cur .val].o_cur.str : ((sp))->opts[((offset))].o_cur.str) != NULL((void *)0) && | |||
| 653 | !strcmp(O_STR(sp, offset)((((&((sp))->opts[((offset))])->flags) & ((0x01 ))) ? ((sp))->gp->opts[((sp))->opts[((offset))].o_cur .val].o_cur.str : ((sp))->opts[((offset))].o_cur.str), sep)) | |||
| 654 | break; | |||
| 655 | ||||
| 656 | if (F_ISSET(op, OPT_EARLYSET)(((op)->flags) & ((0x080)))) { | |||
| 657 | /* Set the value. */ | |||
| 658 | if (o_set(sp, offset, OS_STRDUP0x08, sep, 0)) { | |||
| 659 | rval = 1; | |||
| 660 | break; | |||
| 661 | } | |||
| 662 | } | |||
| 663 | ||||
| 664 | /* Report to subsystems. */ | |||
| 665 | if ((op->func != NULL((void *)0) && | |||
| 666 | op->func(sp, spo, sep, NULL((void *)0))) || | |||
| 667 | ex_optchange(sp, offset, sep, NULL((void *)0)) || | |||
| 668 | v_optchange(sp, offset, sep, NULL((void *)0)) || | |||
| 669 | sp->gp->scr_optchange(sp, offset, sep, NULL((void *)0))) { | |||
| 670 | rval = 1; | |||
| 671 | break; | |||
| 672 | } | |||
| 673 | ||||
| 674 | if (!F_ISSET(op, OPT_EARLYSET)(((op)->flags) & ((0x080)))) { | |||
| 675 | /* Set the value. */ | |||
| 676 | if (o_set(sp, offset, OS_STRDUP0x08, sep, 0)) | |||
| 677 | rval = 1; | |||
| 678 | } | |||
| 679 | break; | |||
| 680 | default: | |||
| 681 | abort(); | |||
| 682 | } | |||
| 683 | } | |||
| 684 | if (disp != NO_DISPLAY) | |||
| 685 | opts_dump(sp, disp); | |||
| 686 | return (rval); | |||
| 687 | } | |||
| 688 | ||||
| 689 | /* | |||
| 690 | * o_set -- | |||
| 691 | * Set an option's value. | |||
| 692 | * | |||
| 693 | * PUBLIC: int o_set(SCR *, int, u_int, char *, u_long); | |||
| 694 | */ | |||
| 695 | int | |||
| 696 | o_set(SCR *sp, int opt, u_int flags, char *str, u_long val) | |||
| 697 | { | |||
| 698 | OPTION *op; | |||
| 699 | ||||
| 700 | /* Set a pointer to the options area. */ | |||
| 701 | op = F_ISSET(&sp->opts[opt], OPT_GLOBAL)(((&sp->opts[opt])->flags) & ((0x01))) ? | |||
| 702 | &sp->gp->opts[sp->opts[opt].o_cur.val] : &sp->opts[opt]; | |||
| 703 | ||||
| 704 | /* Copy the string, if requested. */ | |||
| 705 | if (LF_ISSET(OS_STRDUP)((flags) & ((0x08))) && (str = strdup(str)) == NULL((void *)0)) { | |||
| 706 | msgq(sp, M_SYSERR, NULL((void *)0)); | |||
| 707 | return (1); | |||
| 708 | } | |||
| 709 | ||||
| 710 | /* Free the previous string, if requested, and set the value. */ | |||
| 711 | if (LF_ISSET(OS_DEF)((flags) & ((0x01)))) | |||
| 712 | if (LF_ISSET(OS_STR | OS_STRDUP)((flags) & ((0x04 | 0x08)))) { | |||
| 713 | if (!LF_ISSET(OS_NOFREE)((flags) & ((0x02))) && op->o_def.str != NULL((void *)0)) | |||
| 714 | free(op->o_def.str); | |||
| 715 | op->o_def.str = str; | |||
| 716 | } else | |||
| 717 | op->o_def.val = val; | |||
| 718 | else | |||
| 719 | if (LF_ISSET(OS_STR | OS_STRDUP)((flags) & ((0x04 | 0x08)))) { | |||
| 720 | if (!LF_ISSET(OS_NOFREE)((flags) & ((0x02))) && op->o_cur.str != NULL((void *)0)) | |||
| 721 | free(op->o_cur.str); | |||
| 722 | op->o_cur.str = str; | |||
| 723 | } else | |||
| 724 | op->o_cur.val = val; | |||
| 725 | return (0); | |||
| 726 | } | |||
| 727 | ||||
| 728 | /* | |||
| 729 | * opts_empty -- | |||
| 730 | * Return 1 if the string option is invalid, 0 if it's OK. | |||
| 731 | * | |||
| 732 | * PUBLIC: int opts_empty(SCR *, int, int); | |||
| 733 | */ | |||
| 734 | int | |||
| 735 | opts_empty(SCR *sp, int off, int silent) | |||
| 736 | { | |||
| 737 | char *p; | |||
| 738 | ||||
| 739 | if ((p = O_STR(sp, off)((((&((sp))->opts[((off))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((off))].o_cur.val] .o_cur.str : ((sp))->opts[((off))].o_cur.str)) == NULL((void *)0) || p[0] == '\0') { | |||
| 740 | if (!silent) | |||
| 741 | msgq_str(sp, M_ERR, optlist[off].name, | |||
| 742 | "No %s edit option specified"); | |||
| 743 | return (1); | |||
| 744 | } | |||
| 745 | return (0); | |||
| 746 | } | |||
| 747 | ||||
| 748 | /* | |||
| 749 | * opts_dump -- | |||
| 750 | * List the current values of selected options. | |||
| 751 | * | |||
| 752 | * PUBLIC: void opts_dump(SCR *, enum optdisp); | |||
| 753 | */ | |||
| 754 | void | |||
| 755 | opts_dump(SCR *sp, enum optdisp type) | |||
| 756 | { | |||
| 757 | OPTLIST const *op; | |||
| 758 | int base, b_num, cnt, col, colwidth, curlen, s_num; | |||
| 759 | int numcols, numrows, row; | |||
| 760 | int b_op[O_OPTIONCOUNT], s_op[O_OPTIONCOUNT]; | |||
| 761 | char nbuf[20]; | |||
| 762 | ||||
| 763 | /* | |||
| 764 | * Options are output in two groups -- those that fit in a column and | |||
| 765 | * those that don't. Output is done on 6 character "tab" boundaries | |||
| 766 | * for no particular reason. (Since we don't output tab characters, | |||
| 767 | * we can ignore the terminal's tab settings.) Ignore the user's tab | |||
| 768 | * setting because we have no idea how reasonable it is. | |||
| 769 | * | |||
| 770 | * Find a column width we can live with, testing from 10 columns to 1. | |||
| 771 | */ | |||
| 772 | for (numcols = 10; numcols > 1; --numcols) { | |||
| ||||
| 773 | colwidth = sp->cols / numcols & ~(STANDARD_TAB6 - 1); | |||
| 774 | if (colwidth >= 10) { | |||
| 775 | colwidth = | |||
| 776 | (colwidth + STANDARD_TAB6) & ~(STANDARD_TAB6 - 1); | |||
| 777 | numcols = sp->cols / colwidth; | |||
| 778 | break; | |||
| 779 | } | |||
| 780 | colwidth = 0; | |||
| 781 | } | |||
| 782 | ||||
| 783 | /* | |||
| 784 | * Get the set of options to list, entering them into | |||
| 785 | * the column list or the overflow list. | |||
| 786 | */ | |||
| 787 | for (b_num = s_num = 0, op = optlist; op->name != NULL((void *)0); ++op) { | |||
| 788 | cnt = op - optlist; | |||
| 789 | ||||
| 790 | /* If OPT_NDISP set, it's never displayed. */ | |||
| 791 | if (F_ISSET(op, OPT_NDISP)(((op)->flags) & ((0x004)))) | |||
| 792 | continue; | |||
| 793 | ||||
| 794 | switch (type) { | |||
| 795 | case ALL_DISPLAY: /* Display all. */ | |||
| 796 | break; | |||
| 797 | case CHANGED_DISPLAY: /* Display changed. */ | |||
| 798 | /* If OPT_ADISP set, it's always "changed". */ | |||
| 799 | if (F_ISSET(op, OPT_ADISP)(((op)->flags) & ((0x001)))) | |||
| 800 | break; | |||
| 801 | switch (op->type) { | |||
| 802 | case OPT_0BOOL: | |||
| 803 | case OPT_1BOOL: | |||
| 804 | case OPT_NUM: | |||
| 805 | if (O_VAL(sp, cnt)((((&((sp))->opts[((cnt))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((cnt))].o_cur.val] .o_cur.val : ((sp))->opts[((cnt))].o_cur.val) == O_D_VAL(sp, cnt)((((&((sp))->opts[((cnt))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((cnt))].o_cur.val] .o_def.val : ((sp))->opts[((cnt))].o_def.val)) | |||
| 806 | continue; | |||
| 807 | break; | |||
| 808 | case OPT_STR: | |||
| 809 | if (O_STR(sp, cnt)((((&((sp))->opts[((cnt))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((cnt))].o_cur.val] .o_cur.str : ((sp))->opts[((cnt))].o_cur.str) == O_D_STR(sp, cnt)((((&((sp))->opts[((cnt))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((cnt))].o_cur.val] .o_def.str : ((sp))->opts[((cnt))].o_def.str) || | |||
| 810 | (O_D_STR(sp, cnt)((((&((sp))->opts[((cnt))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((cnt))].o_cur.val] .o_def.str : ((sp))->opts[((cnt))].o_def.str) != NULL((void *)0) && | |||
| 811 | !strcmp(O_STR(sp, cnt)((((&((sp))->opts[((cnt))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((cnt))].o_cur.val] .o_cur.str : ((sp))->opts[((cnt))].o_cur.str), O_D_STR(sp, cnt)((((&((sp))->opts[((cnt))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((cnt))].o_cur.val] .o_def.str : ((sp))->opts[((cnt))].o_def.str)))) | |||
| 812 | continue; | |||
| 813 | break; | |||
| 814 | } | |||
| 815 | break; | |||
| 816 | case SELECT_DISPLAY: /* Display selected. */ | |||
| 817 | if (!F_ISSET(&sp->opts[cnt], OPT_SELECTED)(((&sp->opts[cnt])->flags) & ((0x02)))) | |||
| 818 | continue; | |||
| 819 | break; | |||
| 820 | default: | |||
| 821 | case NO_DISPLAY: | |||
| 822 | abort(); | |||
| 823 | } | |||
| 824 | F_CLR(&sp->opts[cnt], OPT_SELECTED)(((&sp->opts[cnt])->flags) &= ~((0x02))); | |||
| 825 | ||||
| 826 | curlen = strlen(op->name); | |||
| 827 | switch (op->type) { | |||
| 828 | case OPT_0BOOL: | |||
| 829 | case OPT_1BOOL: | |||
| 830 | if (!O_ISSET(sp, cnt)((((&(((sp)))->opts[(((cnt)))])->flags) & ((0x01 ))) ? (((sp)))->gp->opts[(((sp)))->opts[(((cnt)))].o_cur .val].o_cur.val : (((sp)))->opts[(((cnt)))].o_cur.val)) | |||
| 831 | curlen += 2; | |||
| 832 | break; | |||
| 833 | case OPT_NUM: | |||
| 834 | (void)snprintf(nbuf, | |||
| 835 | sizeof(nbuf), "%ld", O_VAL(sp, cnt)((((&((sp))->opts[((cnt))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((cnt))].o_cur.val] .o_cur.val : ((sp))->opts[((cnt))].o_cur.val)); | |||
| 836 | curlen += strlen(nbuf); | |||
| 837 | break; | |||
| 838 | case OPT_STR: | |||
| 839 | if (O_STR(sp, cnt)((((&((sp))->opts[((cnt))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((cnt))].o_cur.val] .o_cur.str : ((sp))->opts[((cnt))].o_cur.str) != NULL((void *)0)) | |||
| 840 | curlen += strlen(O_STR(sp, cnt)((((&((sp))->opts[((cnt))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((cnt))].o_cur.val] .o_cur.str : ((sp))->opts[((cnt))].o_cur.str)); | |||
| 841 | curlen += 3; | |||
| 842 | break; | |||
| 843 | } | |||
| 844 | /* Offset by 2 so there's a gap. */ | |||
| 845 | if (curlen <= colwidth - 2) | |||
| 846 | s_op[s_num++] = cnt; | |||
| 847 | else | |||
| 848 | b_op[b_num++] = cnt; | |||
| 849 | } | |||
| 850 | ||||
| 851 | if (s_num
| |||
| 852 | /* Figure out the number of rows. */ | |||
| 853 | if (s_num > numcols) { | |||
| 854 | numrows = s_num / numcols; | |||
| ||||
| 855 | if (s_num % numcols) | |||
| 856 | ++numrows; | |||
| 857 | } else | |||
| 858 | numrows = 1; | |||
| 859 | ||||
| 860 | /* Display the options in sorted order. */ | |||
| 861 | for (row = 0; row < numrows;) { | |||
| 862 | for (base = row, col = 0; col < numcols; ++col) { | |||
| 863 | cnt = opts_print(sp, &optlist[s_op[base]]); | |||
| 864 | if ((base += numrows) >= s_num) | |||
| 865 | break; | |||
| 866 | (void)ex_printf(sp, "%*s", | |||
| 867 | (int)(colwidth - cnt), ""); | |||
| 868 | } | |||
| 869 | if (++row < numrows || b_num) | |||
| 870 | (void)ex_puts(sp, "\n"); | |||
| 871 | } | |||
| 872 | } | |||
| 873 | ||||
| 874 | for (row = 0; row < b_num;) { | |||
| 875 | (void)opts_print(sp, &optlist[b_op[row]]); | |||
| 876 | if (++row < b_num) | |||
| 877 | (void)ex_puts(sp, "\n"); | |||
| 878 | } | |||
| 879 | (void)ex_puts(sp, "\n"); | |||
| 880 | } | |||
| 881 | ||||
| 882 | /* | |||
| 883 | * opts_print -- | |||
| 884 | * Print out an option. | |||
| 885 | */ | |||
| 886 | static int | |||
| 887 | opts_print(SCR *sp, OPTLIST const *op) | |||
| 888 | { | |||
| 889 | int curlen, offset; | |||
| 890 | ||||
| 891 | curlen = 0; | |||
| 892 | offset = op - optlist; | |||
| 893 | switch (op->type) { | |||
| 894 | case OPT_0BOOL: | |||
| 895 | case OPT_1BOOL: | |||
| 896 | curlen += ex_printf(sp, | |||
| 897 | "%s%s", O_ISSET(sp, offset)((((&(((sp)))->opts[(((offset)))])->flags) & (( 0x01))) ? (((sp)))->gp->opts[(((sp)))->opts[(((offset )))].o_cur.val].o_cur.val : (((sp)))->opts[(((offset)))].o_cur .val) ? "" : "no", op->name); | |||
| 898 | break; | |||
| 899 | case OPT_NUM: | |||
| 900 | curlen += ex_printf(sp, "%s=%ld", op->name, O_VAL(sp, offset)((((&((sp))->opts[((offset))])->flags) & ((0x01 ))) ? ((sp))->gp->opts[((sp))->opts[((offset))].o_cur .val].o_cur.val : ((sp))->opts[((offset))].o_cur.val)); | |||
| 901 | break; | |||
| 902 | case OPT_STR: | |||
| 903 | curlen += ex_printf(sp, "%s=\"%s\"", op->name, | |||
| 904 | O_STR(sp, offset)((((&((sp))->opts[((offset))])->flags) & ((0x01 ))) ? ((sp))->gp->opts[((sp))->opts[((offset))].o_cur .val].o_cur.str : ((sp))->opts[((offset))].o_cur.str) == NULL((void *)0) ? "" : O_STR(sp, offset)((((&((sp))->opts[((offset))])->flags) & ((0x01 ))) ? ((sp))->gp->opts[((sp))->opts[((offset))].o_cur .val].o_cur.str : ((sp))->opts[((offset))].o_cur.str)); | |||
| 905 | break; | |||
| 906 | } | |||
| 907 | return (curlen); | |||
| 908 | } | |||
| 909 | ||||
| 910 | /* | |||
| 911 | * opts_save -- | |||
| 912 | * Write the current configuration to a file. | |||
| 913 | * | |||
| 914 | * PUBLIC: int opts_save(SCR *, FILE *); | |||
| 915 | */ | |||
| 916 | int | |||
| 917 | opts_save(SCR *sp, FILE *fp) | |||
| 918 | { | |||
| 919 | OPTLIST const *op; | |||
| 920 | int ch, cnt; | |||
| 921 | char *p; | |||
| 922 | ||||
| 923 | for (op = optlist; op->name != NULL((void *)0); ++op) { | |||
| 924 | if (F_ISSET(op, OPT_NOSAVE)(((op)->flags) & ((0x008)))) | |||
| 925 | continue; | |||
| 926 | cnt = op - optlist; | |||
| 927 | switch (op->type) { | |||
| 928 | case OPT_0BOOL: | |||
| 929 | case OPT_1BOOL: | |||
| 930 | if (O_ISSET(sp, cnt)((((&(((sp)))->opts[(((cnt)))])->flags) & ((0x01 ))) ? (((sp)))->gp->opts[(((sp)))->opts[(((cnt)))].o_cur .val].o_cur.val : (((sp)))->opts[(((cnt)))].o_cur.val)) | |||
| 931 | (void)fprintf(fp, "set %s\n", op->name); | |||
| 932 | else | |||
| 933 | (void)fprintf(fp, "set no%s\n", op->name); | |||
| 934 | break; | |||
| 935 | case OPT_NUM: | |||
| 936 | (void)fprintf(fp, | |||
| 937 | "set %s=%-3ld\n", op->name, O_VAL(sp, cnt)((((&((sp))->opts[((cnt))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((cnt))].o_cur.val] .o_cur.val : ((sp))->opts[((cnt))].o_cur.val)); | |||
| 938 | break; | |||
| 939 | case OPT_STR: | |||
| 940 | if (O_STR(sp, cnt)((((&((sp))->opts[((cnt))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((cnt))].o_cur.val] .o_cur.str : ((sp))->opts[((cnt))].o_cur.str) == NULL((void *)0)) | |||
| 941 | break; | |||
| 942 | (void)fprintf(fp, "set "); | |||
| 943 | for (p = op->name; (ch = *p) != '\0'; ++p) { | |||
| 944 | if (isblank(ch) || ch == '\\') | |||
| 945 | (void)putc('\\', fp)(!__isthreaded ? __sputc('\\', fp) : (putc)('\\', fp)); | |||
| 946 | (void)putc(ch, fp)(!__isthreaded ? __sputc(ch, fp) : (putc)(ch, fp)); | |||
| 947 | } | |||
| 948 | (void)putc('=', fp)(!__isthreaded ? __sputc('=', fp) : (putc)('=', fp)); | |||
| 949 | for (p = O_STR(sp, cnt)((((&((sp))->opts[((cnt))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((cnt))].o_cur.val] .o_cur.str : ((sp))->opts[((cnt))].o_cur.str); (ch = *p) != '\0'; ++p) { | |||
| 950 | if (isblank(ch) || ch == '\\') | |||
| 951 | (void)putc('\\', fp)(!__isthreaded ? __sputc('\\', fp) : (putc)('\\', fp)); | |||
| 952 | (void)putc(ch, fp)(!__isthreaded ? __sputc(ch, fp) : (putc)(ch, fp)); | |||
| 953 | } | |||
| 954 | (void)putc('\n', fp)(!__isthreaded ? __sputc('\n', fp) : (putc)('\n', fp)); | |||
| 955 | break; | |||
| 956 | } | |||
| 957 | if (ferror(fp)(!__isthreaded ? (((fp)->_flags & 0x0040) != 0) : (ferror )(fp))) { | |||
| 958 | msgq(sp, M_SYSERR, NULL((void *)0)); | |||
| 959 | return (1); | |||
| 960 | } | |||
| 961 | } | |||
| 962 | return (0); | |||
| 963 | } | |||
| 964 | ||||
| 965 | /* | |||
| 966 | * opts_search -- | |||
| 967 | * Search for an option. | |||
| 968 | * | |||
| 969 | * PUBLIC: OPTLIST const *opts_search(char *); | |||
| 970 | */ | |||
| 971 | OPTLIST const * | |||
| 972 | opts_search(char *name) | |||
| 973 | { | |||
| 974 | OPTLIST const *op, *found; | |||
| 975 | OABBREV atmp, *ap; | |||
| 976 | OPTLIST otmp; | |||
| 977 | size_t len; | |||
| 978 | ||||
| 979 | /* Check list of abbreviations. */ | |||
| 980 | atmp.name = name; | |||
| 981 | if ((ap = bsearch(&atmp, abbrev, sizeof(abbrev) / sizeof(OABBREV) - 1, | |||
| 982 | sizeof(OABBREV), opts_abbcmp)) != NULL((void *)0)) | |||
| 983 | return (optlist + ap->offset); | |||
| 984 | ||||
| 985 | /* Check list of options. */ | |||
| 986 | otmp.name = name; | |||
| 987 | if ((op = bsearch(&otmp, optlist, sizeof(optlist) / sizeof(OPTLIST) - 1, | |||
| 988 | sizeof(OPTLIST), opts_cmp)) != NULL((void *)0)) | |||
| 989 | return (op); | |||
| 990 | ||||
| 991 | /* | |||
| 992 | * Check to see if the name is the prefix of one (and only one) | |||
| 993 | * option. If so, return the option. | |||
| 994 | */ | |||
| 995 | len = strlen(name); | |||
| 996 | for (found = NULL((void *)0), op = optlist; op->name != NULL((void *)0); ++op) { | |||
| 997 | if (op->name[0] < name[0]) | |||
| 998 | continue; | |||
| 999 | if (op->name[0] > name[0]) | |||
| 1000 | break; | |||
| 1001 | if (!memcmp(op->name, name, len)) { | |||
| 1002 | if (found != NULL((void *)0)) | |||
| 1003 | return (NULL((void *)0)); | |||
| 1004 | found = op; | |||
| 1005 | } | |||
| 1006 | } | |||
| 1007 | return (found); | |||
| 1008 | } | |||
| 1009 | ||||
| 1010 | /* | |||
| 1011 | * opts_nomatch -- | |||
| 1012 | * Standard nomatch error message for options. | |||
| 1013 | * | |||
| 1014 | * PUBLIC: void opts_nomatch(SCR *, char *); | |||
| 1015 | */ | |||
| 1016 | void | |||
| 1017 | opts_nomatch(SCR *sp, char *name) | |||
| 1018 | { | |||
| 1019 | msgq_str(sp, M_ERR, name, | |||
| 1020 | "set: no %s option: 'set all' gives all option values"); | |||
| 1021 | } | |||
| 1022 | ||||
| 1023 | static int | |||
| 1024 | opts_abbcmp(const void *a, const void *b) | |||
| 1025 | { | |||
| 1026 | return(strcmp(((OABBREV *)a)->name, ((OABBREV *)b)->name)); | |||
| 1027 | } | |||
| 1028 | ||||
| 1029 | static int | |||
| 1030 | opts_cmp(const void *a, const void *b) | |||
| 1031 | { | |||
| 1032 | return(strcmp(((OPTLIST *)a)->name, ((OPTLIST *)b)->name)); | |||
| 1033 | } | |||
| 1034 | ||||
| 1035 | /* | |||
| 1036 | * opts_copy -- | |||
| 1037 | * Copy a screen's OPTION array. | |||
| 1038 | * | |||
| 1039 | * PUBLIC: int opts_copy(SCR *, SCR *); | |||
| 1040 | */ | |||
| 1041 | int | |||
| 1042 | opts_copy(SCR *orig, SCR *sp) | |||
| 1043 | { | |||
| 1044 | int cnt, rval; | |||
| 1045 | ||||
| 1046 | /* Copy most everything without change. */ | |||
| 1047 | memcpy(sp->opts, orig->opts, sizeof(orig->opts)); | |||
| 1048 | ||||
| 1049 | /* Copy the string edit options. */ | |||
| 1050 | for (cnt = rval = 0; cnt < O_OPTIONCOUNT; ++cnt) { | |||
| 1051 | if (optlist[cnt].type != OPT_STR || | |||
| 1052 | F_ISSET(&optlist[cnt], OPT_GLOBAL)(((&optlist[cnt])->flags) & ((0x01)))) | |||
| 1053 | continue; | |||
| 1054 | /* | |||
| 1055 | * If never set, or already failed, NULL out the entries -- | |||
| 1056 | * have to continue after failure, otherwise would have two | |||
| 1057 | * screens referencing the same memory. | |||
| 1058 | */ | |||
| 1059 | if (rval || O_STR(sp, cnt)((((&((sp))->opts[((cnt))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((cnt))].o_cur.val] .o_cur.str : ((sp))->opts[((cnt))].o_cur.str) == NULL((void *)0)) { | |||
| 1060 | o_set(sp, cnt, OS_NOFREE0x02 | OS_STR0x04, NULL((void *)0), 0); | |||
| 1061 | o_set(sp, cnt, OS_DEF0x01 | OS_NOFREE0x02 | OS_STR0x04, NULL((void *)0), 0); | |||
| 1062 | continue; | |||
| 1063 | } | |||
| 1064 | ||||
| 1065 | /* Copy the current string. */ | |||
| 1066 | if (o_set(sp, cnt, OS_NOFREE0x02 | OS_STRDUP0x08, O_STR(sp, cnt)((((&((sp))->opts[((cnt))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((cnt))].o_cur.val] .o_cur.str : ((sp))->opts[((cnt))].o_cur.str), 0)) { | |||
| 1067 | o_set(sp, cnt, OS_DEF0x01 | OS_NOFREE0x02 | OS_STR0x04, NULL((void *)0), 0); | |||
| 1068 | goto nomem; | |||
| 1069 | } | |||
| 1070 | ||||
| 1071 | /* Copy the default string. */ | |||
| 1072 | if (O_D_STR(sp, cnt)((((&((sp))->opts[((cnt))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((cnt))].o_cur.val] .o_def.str : ((sp))->opts[((cnt))].o_def.str) != NULL((void *)0) && o_set(sp, cnt, | |||
| 1073 | OS_DEF0x01 | OS_NOFREE0x02 | OS_STRDUP0x08, O_D_STR(sp, cnt)((((&((sp))->opts[((cnt))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((cnt))].o_cur.val] .o_def.str : ((sp))->opts[((cnt))].o_def.str), 0)) { | |||
| 1074 | nomem: msgq(orig, M_SYSERR, NULL((void *)0)); | |||
| 1075 | rval = 1; | |||
| 1076 | } | |||
| 1077 | } | |||
| 1078 | return (rval); | |||
| 1079 | } | |||
| 1080 | ||||
| 1081 | /* | |||
| 1082 | * opts_free -- | |||
| 1083 | * Free all option strings | |||
| 1084 | * | |||
| 1085 | * PUBLIC: void opts_free(SCR *); | |||
| 1086 | */ | |||
| 1087 | void | |||
| 1088 | opts_free(SCR *sp) | |||
| 1089 | { | |||
| 1090 | int cnt; | |||
| 1091 | ||||
| 1092 | for (cnt = 0; cnt < O_OPTIONCOUNT; ++cnt) { | |||
| 1093 | if (optlist[cnt].type != OPT_STR || | |||
| 1094 | F_ISSET(&optlist[cnt], OPT_GLOBAL)(((&optlist[cnt])->flags) & ((0x01)))) | |||
| 1095 | continue; | |||
| 1096 | free(O_STR(sp, cnt)((((&((sp))->opts[((cnt))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((cnt))].o_cur.val] .o_cur.str : ((sp))->opts[((cnt))].o_cur.str)); | |||
| 1097 | free(O_D_STR(sp, cnt)((((&((sp))->opts[((cnt))])->flags) & ((0x01))) ? ((sp))->gp->opts[((sp))->opts[((cnt))].o_cur.val] .o_def.str : ((sp))->opts[((cnt))].o_def.str)); | |||
| 1098 | } | |||
| 1099 | } |