00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "config.h"
00016 #include "vi.h"
00017 #include "ctype.h"
00018 #ifndef NULL
00019 #define NULL (char *)0
00020 #endif
00021 extern char *getenv();
00022
00023
00024 #define MAXWIDTH 20
00025
00026
00027 char o_autoindent[1] = {FALSE};
00028 char o_autoprint[1] = {TRUE};
00029 char o_autotab[1] = {TRUE};
00030 char o_autowrite[1] = {FALSE};
00031 char o_columns[3] = {80, 32, 255};
00032 char o_directory[30] = TMPDIR;
00033 char o_edcompatible[1] = {FALSE};
00034 char o_equalprg[80] = {"fmt"};
00035 char o_errorbells[1] = {TRUE};
00036 char o_exrefresh[1] = {TRUE};
00037 char o_ignorecase[1] = {FALSE};
00038 char o_keytime[3] = {1, 0, 50};
00039 char o_keywordprg[80] = {KEYWORDPRG};
00040 char o_lines[3] = {25, 2, 96};
00041 char o_list[1] = {FALSE};
00042 char o_number[1] = {FALSE};
00043 char o_readonly[1] = {FALSE};
00044 char o_remap[1] = {TRUE};
00045 char o_report[3] = {5, 1, 127};
00046 char o_scroll[3] = {12, 1, 127};
00047 char o_shell[60] = SHELL;
00048 char o_shiftwidth[3] = {8, 1, 255};
00049 char o_sidescroll[3] = {8, 1, 40};
00050 char o_sync[1] = {NEEDSYNC};
00051 char o_tabstop[3] = {8, 1, 40};
00052 char o_term[30] = "?";
00053 char o_flash[1] = {TRUE};
00054 char o_warn[1] = {TRUE};
00055 char o_wrapscan[1] = {TRUE};
00056
00057 #ifndef CRUNCH
00058 char o_beautify[1] = {FALSE};
00059 char o_exrc[1] = {FALSE};
00060 char o_mesg[1] = {TRUE};
00061 char o_more[1] = {TRUE};
00062 char o_novice[1] = {FALSE};
00063 char o_prompt[1] = {TRUE};
00064 char o_taglength[3] = {0, 0, 30};
00065 char o_terse[1] = {FALSE};
00066 char o_window[3] = {0, 1, 24};
00067 char o_wrapmargin[3] = {0, 0, 255};
00068 char o_writeany[1] = {FALSE};
00069 #endif
00070
00071 #ifndef NO_ERRLIST
00072 char o_cc[30] = {CC_COMMAND};
00073 char o_make[30] = {MAKE_COMMAND};
00074 #endif
00075
00076 #ifndef NO_CHARATTR
00077 char o_charattr[1] = {FALSE};
00078 #endif
00079
00080 #ifndef NO_DIGRAPH
00081 char o_digraph[1] = {FALSE};
00082 char o_flipcase[80]
00083 # ifdef CS_IBMPC
00084 = {"\207\200\201\232\202\220\204\216\206\217\221\222\224\231\244\245"}
00085 # endif
00086 # ifdef CS_LATIN1
00087
00088 # endif
00089 ;
00090 #endif
00091
00092 #ifndef NO_SENTENCE
00093 char o_hideformat[1] = {FALSE};
00094 #endif
00095
00096 #ifndef NO_EXTENSIONS
00097 char o_inputmode[1] = {FALSE};
00098 char o_ruler[1] = {FALSE};
00099 #endif
00100
00101 #ifndef NO_MAGIC
00102 char o_magic[1] = {TRUE};
00103 #endif
00104
00105 #ifndef NO_MODELINES
00106 char o_modelines[1] = {FALSE};
00107 #endif
00108
00109 #ifndef NO_SENTENCE
00110 char o_paragraphs[30] = "PPppIPLPQP";
00111 char o_sections[30] = "NHSHSSSEse";
00112 #endif
00113
00114 #if MSDOS
00115 char o_pcbios[1] = {TRUE};
00116 #endif
00117
00118 #ifndef NO_SHOWMATCH
00119 char o_showmatch[1] = {FALSE};
00120 #endif
00121
00122 #ifndef NO_SHOWMODE
00123 char o_smd[1] = {FALSE};
00124 #endif
00125
00126
00127
00128 #define BOOL 0
00129 #define NUM 1
00130 #define STR 2
00131 #define SET 0x01
00132 #define CANSET 0x02
00133 #define RCSET 0x06
00134 #define NOSAVE 0x0a
00135 #define WSET 0x20
00136 #define MR 0x40
00137 struct
00138 {
00139 char *name;
00140 char *nm;
00141 char type;
00142 char flags;
00143 char *value;
00144 }
00145 opts[] =
00146 {
00147
00148 { "autoindent", "ai", BOOL, CANSET, o_autoindent },
00149 { "autoprint", "ap", BOOL, CANSET, o_autoprint },
00150 { "autotab", "at", BOOL, CANSET, o_autotab },
00151 { "autowrite", "aw", BOOL, CANSET, o_autowrite },
00152 #ifndef CRUNCH
00153 { "beautify", "bf", BOOL, CANSET, o_beautify },
00154 #endif
00155 #ifndef NO_ERRLIST
00156 { "cc", "cc", STR, CANSET, o_cc },
00157 #endif
00158 #ifndef NO_CHARATTR
00159 { "charattr", "ca", BOOL, CANSET|MR, o_charattr },
00160 #endif
00161 { "columns", "co", NUM, SET|NOSAVE|MR, o_columns },
00162 #ifndef NO_DIGRAPH
00163 { "digraph", "dig", BOOL, CANSET, o_digraph },
00164 #endif
00165 { "directory", "dir", STR, RCSET, o_directory },
00166 { "edcompatible","ed", BOOL, CANSET, o_edcompatible },
00167 { "equalprg", "ep", STR, CANSET, o_equalprg },
00168 { "errorbells", "eb", BOOL, CANSET, o_errorbells },
00169 #ifndef CRUNCH
00170 { "exrc", "exrc", BOOL, CANSET, o_exrc },
00171 #endif
00172 { "exrefresh", "er", BOOL, CANSET, o_exrefresh },
00173 { "flash", "vbell",BOOL, CANSET, o_flash },
00174 #ifndef NO_DIGRAPH
00175 { "flipcase", "fc", STR, CANSET, o_flipcase },
00176 #endif
00177 #ifndef NO_SENTENCE
00178 { "hideformat", "hf", BOOL, CANSET|MR, o_hideformat },
00179 #endif
00180 { "ignorecase", "ic", BOOL, CANSET, o_ignorecase },
00181 #ifndef NO_EXTENSIONS
00182 { "inputmode", "im", BOOL, CANSET, o_inputmode },
00183 #endif
00184 { "keytime", "kt", NUM, CANSET, o_keytime },
00185 { "keywordprg", "kp", STR, CANSET, o_keywordprg },
00186 { "lines", "ls", NUM, SET|NOSAVE|MR, o_lines },
00187 { "list", "li", BOOL, CANSET|MR, o_list },
00188 #ifndef NO_MAGIC
00189 { "magic", "ma", BOOL, CANSET, o_magic },
00190 #endif
00191 #ifndef NO_ERRLIST
00192 { "make", "mk", STR, CANSET, o_make },
00193 #endif
00194 #ifndef CRUNCH
00195 { "mesg", "me", BOOL, CANSET, o_mesg },
00196 #endif
00197 #ifndef NO_MODELINES
00198 { "modelines", "ml", BOOL, CANSET, o_modelines },
00199 #endif
00200 #ifndef CRUNCH
00201 { "more", "mo", BOOL, CANSET, o_more },
00202 { "novice", "nov", BOOL, CANSET, o_novice },
00203 #endif
00204 { "number", "nu", BOOL, CANSET|MR, o_number },
00205 #ifndef NO_SENTENCE
00206 { "paragraphs", "para", STR, CANSET, o_paragraphs },
00207 #endif
00208 #if MSDOS
00209 { "pcbios", "pc", BOOL, SET|NOSAVE, o_pcbios },
00210 #endif
00211 #ifndef CRUNCH
00212 { "prompt", "pr", BOOL, CANSET, o_prompt },
00213 #endif
00214 { "readonly", "ro", BOOL, CANSET, o_readonly },
00215 { "remap", "remap",BOOL, CANSET, o_remap },
00216 { "report", "re", NUM, CANSET, o_report },
00217 #ifndef NO_EXTENSIONS
00218 { "ruler", "ru", BOOL, CANSET, o_ruler },
00219 #endif
00220 { "scroll", "sc", NUM, CANSET, o_scroll },
00221 #ifndef NO_SENTENCE
00222 { "sections", "sect", STR, CANSET, o_sections },
00223 #endif
00224 { "shell", "sh", STR, CANSET, o_shell },
00225 #ifndef NO_SHOWMATCH
00226 { "showmatch", "sm", BOOL, CANSET, o_showmatch },
00227 #endif
00228 #ifndef NO_SHOWMODE
00229 { "showmode", "smd", BOOL, CANSET, o_smd },
00230 #endif
00231 { "shiftwidth", "sw", NUM, CANSET, o_shiftwidth },
00232 { "sidescroll", "ss", NUM, CANSET, o_sidescroll },
00233 { "sync", "sy", BOOL, CANSET, o_sync },
00234 { "tabstop", "ts", NUM, CANSET|MR, o_tabstop },
00235 #ifndef CRUNCH
00236 { "taglength", "tl", NUM, CANSET, o_taglength },
00237 #endif
00238 { "term", "te", STR, SET, o_term },
00239 #ifndef CRUNCH
00240 { "terse", "tr", BOOL, CANSET, o_terse },
00241 { "timeout", "to", BOOL, CANSET, o_keytime },
00242 #endif
00243 #ifndef CRUNCH
00244 { "window", "wi", NUM, CANSET|MR|WSET, o_window },
00245 { "wrapmargin", "wm", NUM, CANSET, o_wrapmargin },
00246 #endif
00247 { "wrapscan", "ws", BOOL, CANSET, o_wrapscan },
00248 #ifndef CRUNCH
00249 { "writeany", "wr", BOOL, CANSET, o_writeany },
00250 #endif
00251 { NULL, NULL, 0, CANSET, NULL }
00252 };
00253
00254
00255
00256 void initopts()
00257 {
00258 char *val;
00259 int i;
00260
00261
00262 #if MSDOS
00263 if (val = getenv("COMSPEC"))
00264 #else
00265 if (val = getenv("SHELL"))
00266 #endif
00267 {
00268 strcpy(o_shell, val);
00269 }
00270
00271 strcpy(o_term, termtype);
00272 #if MSDOS
00273 if (strcmp(termtype, "pcbios"))
00274 {
00275 o_pcbios[0] = FALSE;
00276 }
00277 else
00278 {
00279 o_pcbios[0] = TRUE;
00280 }
00281 #endif
00282
00283 #if AMIGA || MSDOS || TOS
00284 if ((val = getenv("TMP"))
00285 || (val = getenv("TEMP")))
00286 strcpy(o_directory, val);
00287 #endif
00288
00289 #ifndef CRUNCH
00290 if ((val = getenv("LINES")) && atoi(val) > 4)
00291 {
00292 LINES = atoi(val);
00293 }
00294 if ((val = getenv("COLUMNS")) && atoi(val) > 30)
00295 {
00296 COLS = atoi(val);
00297 }
00298 #endif
00299 *o_lines = LINES;
00300 *o_columns = COLS;
00301 *o_scroll = LINES / 2 - 1;
00302 #ifndef CRUNCH
00303 if (o_window[0] == 0)
00304 {
00305 o_window[0] = o_window[2] = *o_lines;
00306 }
00307 #endif
00308
00309
00310 if (!has_VB)
00311 {
00312 for (i = 0; opts[i].value != o_flash; i++)
00313 {
00314 }
00315 opts[i].flags &= ~CANSET;
00316 *o_flash = FALSE;
00317 }
00318
00319 #ifndef NO_DIGRAPH
00320 # ifdef CS_LATIN1
00321 for (i = 0, val = o_flipcase; i < 32; i++)
00322 {
00323
00324 if (i == 23)
00325 continue;
00326
00327
00328 *val++ = i + 0xe0;
00329 *val++ = i + 0xc0;
00330 }
00331 *val = '\0';
00332 # endif
00333
00334
00335 _ct_init(o_flipcase);
00336 #else
00337 _ct_init("");
00338 #endif
00339 }
00340
00341
00342 void dumpopts(all)
00343 int all;
00344 {
00345 #ifndef NO_OPTCOLS
00346 int i, j, k;
00347 char nbuf[4];
00348 int widths[5];
00349 int ncols;
00350 int nrows;
00351 int nset;
00352 int width;
00353 int todump[60];
00354
00355
00356 for (nset = i = 0; opts[i].name; i++)
00357 {
00358 if (all || (opts[i].flags & SET))
00359 {
00360 todump[nset++] = i;
00361 }
00362 }
00363
00364
00365 for (ncols = (nset > 5 ? 5 : nset); ncols > 1; ncols--)
00366 {
00367
00368 nrows = (nset + ncols - 1) / ncols;
00369
00370
00371 for (i = 0; i < ncols; i++)
00372 {
00373 widths[i] = 0;
00374 for (j = 0, k = nrows * i; j < nrows && k < nset; j++, k++)
00375 {
00376
00377 switch (opts[todump[k]].type)
00378 {
00379 case BOOL:
00380 if (!*opts[todump[k]].value)
00381 width = 2;
00382 else
00383 width = 0;
00384 break;
00385
00386 case STR:
00387 width = 3 + strlen(opts[todump[k]].value);
00388 if (width > MAXWIDTH)
00389 width = MAXWIDTH;
00390 break;
00391
00392 case NUM:
00393 width = 4;
00394 break;
00395 }
00396 width += strlen(opts[todump[k]].name);
00397
00398
00399 if (width > widths[i])
00400 {
00401 widths[i] = width;
00402 }
00403 }
00404
00405 }
00406
00407
00408 for (width = -2, i = 0; i < ncols; i++)
00409 {
00410 width += widths[i] + 2;
00411 }
00412 if (width < COLS - 1)
00413 {
00414 break;
00415 }
00416 }
00417
00418
00419 nrows = (nset + ncols - 1) / ncols;
00420 for (i = 0; i < nrows; i++)
00421 {
00422 for (j = 0; j < ncols; j++)
00423 {
00424
00425 k = i + j * nrows;
00426 if (k >= nset)
00427 {
00428 break;
00429 }
00430
00431
00432 width = 0;
00433 switch (opts[todump[k]].type)
00434 {
00435 case BOOL:
00436 if (!*opts[todump[k]].value)
00437 {
00438 qaddch('n');
00439 qaddch('o');
00440 width = 2;
00441 }
00442 qaddstr(opts[todump[k]].name);
00443 width += strlen(opts[todump[k]].name);
00444 break;
00445
00446 case NUM:
00447 sprintf(nbuf, "%-3d", UCHAR(*opts[todump[k]].value));
00448 qaddstr(opts[todump[k]].name);
00449 qaddch('=');
00450 qaddstr(nbuf);
00451 width = 4 + strlen(opts[todump[k]].name);
00452 break;
00453
00454 case STR:
00455 qaddstr(opts[todump[k]].name);
00456 qaddch('=');
00457 qaddch('"');
00458 strcpy(tmpblk.c, opts[todump[k]].value);
00459 width = 3 + strlen(tmpblk.c);
00460 if (width > MAXWIDTH)
00461 {
00462 width = MAXWIDTH;
00463 strcpy(tmpblk.c + MAXWIDTH - 6, "...");
00464 }
00465 qaddstr(tmpblk.c);
00466 qaddch('"');
00467 width += strlen(opts[todump[k]].name);
00468 break;
00469 }
00470
00471
00472 if (k + nrows <= nset)
00473 {
00474 while (width < widths[j] + 2)
00475 {
00476 qaddch(' ');
00477 width++;
00478 }
00479 }
00480 }
00481 addch('\n');
00482 exrefresh();
00483 }
00484 #else
00485 int i;
00486 int col;
00487 char nbuf[4];
00488
00489 for (i = col = 0; opts[i].name; i++)
00490 {
00491
00492 if (!all && !(opts[i].flags & SET))
00493 {
00494 continue;
00495 }
00496
00497
00498 if (col > 52)
00499 {
00500 addch('\n');
00501 col = 0;
00502 }
00503 else if (col > 26)
00504 {
00505 while (col < 52)
00506 {
00507 qaddch(' ');
00508 col++;
00509 }
00510 }
00511 else if (col > 0)
00512 {
00513 while (col < 26)
00514 {
00515 qaddch(' ');
00516 col++;
00517 }
00518 }
00519
00520 switch (opts[i].type)
00521 {
00522 case BOOL:
00523 if (!*opts[i].value)
00524 {
00525 qaddch('n');
00526 qaddch('o');
00527 col += 2;
00528 }
00529 qaddstr(opts[i].name);
00530 col += strlen(opts[i].name);
00531 break;
00532
00533 case NUM:
00534 sprintf(nbuf, "%-3d", UCHAR(*opts[i].value));
00535 qaddstr(opts[i].name);
00536 qaddch('=');
00537 qaddstr(nbuf);
00538 col += 4 + strlen(opts[i].name);
00539 break;
00540
00541 case STR:
00542 qaddstr(opts[i].name);
00543 qaddch('=');
00544 qaddch('"');
00545 qaddstr(opts[i].value);
00546 qaddch('"');
00547 col += 3 + strlen(opts[i].name) + strlen(opts[i].value);
00548 break;
00549 }
00550 exrefresh();
00551 }
00552 if (col > 0)
00553 {
00554 addch('\n');
00555 exrefresh();
00556 }
00557 #endif
00558 }
00559
00560 #ifndef NO_MKEXRC
00561
00562 void saveopts(fd)
00563 int fd;
00564 {
00565 int i;
00566 char buf[256], *pos;
00567
00568
00569 for (i = 0; opts[i].name; i++)
00570 {
00571
00572 if ((opts[i].flags & (SET|CANSET|NOSAVE)) != (SET|CANSET))
00573 {
00574 continue;
00575 }
00576
00577 strcpy(buf, "set ");
00578 pos = &buf[4];
00579 switch (opts[i].type)
00580 {
00581 case BOOL:
00582 if (!*opts[i].value)
00583 {
00584 *pos++='n';
00585 *pos++='o';
00586 }
00587 strcpy(pos, opts[i].name);
00588 strcat(pos, "\n");
00589 break;
00590
00591 case NUM:
00592 sprintf(pos, "%s=%-3d\n", opts[i].name, *opts[i].value & 0xff);
00593 break;
00594
00595 case STR:
00596 sprintf(pos, "%s=\"%s\"\n", opts[i].name, opts[i].value);
00597 break;
00598 }
00599 twrite(fd, buf, (unsigned)strlen(buf));
00600 }
00601 }
00602 #endif
00603
00604
00605
00606 void setopts(assignments)
00607 char *assignments;
00608 {
00609 char *name;
00610 char *value;
00611 char *scan;
00612 char *build;
00613 char *prefix;
00614 int quote;
00615 int i, j;
00616
00617 #ifndef CRUNCH
00618
00619 *o_window = *o_lines - 1;
00620 #endif
00621
00622
00623 for (name = assignments; *name; )
00624 {
00625
00626 if (*name == ' ' || *name == '\t')
00627 {
00628 name++;
00629 continue;
00630 }
00631
00632
00633 for (scan = name; isalnum(*scan); scan++)
00634 {
00635 }
00636 if (*scan == '=')
00637 {
00638 *scan++ = '\0';
00639 value = build = scan;
00640 for (quote = FALSE; *scan && (quote || !isspace(*scan)); scan++)
00641 {
00642 if (*scan == '"')
00643 {
00644 quote = !quote;
00645 }
00646 else if (*scan == '\\' && scan[1])
00647 {
00648 *build++ = *++scan;
00649 }
00650 else
00651 {
00652 *build++ = *scan;
00653 }
00654 }
00655 if (*scan)
00656 scan++;
00657 *build = '\0';
00658 }
00659 else
00660 {
00661 if (*scan)
00662 {
00663 *scan++ = '\0';
00664 }
00665 value = NULL;
00666 prefix = name;
00667 #ifndef CRUNCH
00668 if (!strcmp(name, "novice"))
00669 ;
00670 else
00671 #endif
00672 if (prefix[0] == 'n' && prefix[1] == 'o')
00673 name += 2;
00674 else if (prefix[0] == 'n' && prefix[1] == 'e' && prefix[2] == 'g')
00675 name += 3;
00676 }
00677
00678
00679 for (i = 0;
00680 opts[i].name && strcmp(opts[i].name, name) && strcmp(opts[i].nm, name);
00681 i++)
00682 {
00683 }
00684
00685
00686 if (!opts[i].name)
00687 {
00688 msg("invalid option name \"%s\"", name);
00689 }
00690 else if ((opts[i].flags & CANSET) != CANSET)
00691 {
00692 msg("option \"%s\" can't be altered", name);
00693 }
00694 else if ((opts[i].flags & RCSET) != CANSET && nlines >= 1L)
00695 {
00696 msg("option \"%s\" can only be set in a %s file", name, EXRC);
00697 }
00698 else if (value)
00699 {
00700 switch (opts[i].type)
00701 {
00702 case BOOL:
00703 msg("option \"[no]%s\" is boolean", name);
00704 break;
00705
00706 case NUM:
00707 j = atoi(value);
00708 if (j == 0 && *value != '0')
00709 {
00710 msg("option \"%s\" must have a numeric value", name);
00711 }
00712 else if (j < opts[i].value[1] || j > (opts[i].value[2] & 0xff))
00713 {
00714 msg("option \"%s\" must have a value between %d and %d",
00715 name, opts[i].value[1], opts[i].value[2] & 0xff);
00716 }
00717 else
00718 {
00719 *opts[i].value = atoi(value);
00720 opts[i].flags |= SET;
00721 }
00722 break;
00723
00724 case STR:
00725 strcpy(opts[i].value, value);
00726 opts[i].flags |= SET;
00727 break;
00728 }
00729 if (opts[i].flags & MR)
00730 {
00731 redraw(MARK_UNSET, FALSE);
00732 }
00733 #ifndef CRUNCH
00734 if (opts[i].flags & WSET)
00735 {
00736 wset = TRUE;
00737 }
00738 #endif
00739 }
00740 else
00741 {
00742 if (opts[i].type == BOOL)
00743 {
00744 if (prefix == name)
00745 *opts[i].value = TRUE;
00746 else if (prefix[1] == 'o')
00747 *opts[i].value = FALSE;
00748 else
00749 *opts[i].value = !*opts[i].value;
00750
00751 opts[i].flags |= SET;
00752 if (opts[i].flags & MR)
00753 {
00754 redraw(MARK_UNSET, FALSE);
00755 }
00756 }
00757 else
00758 {
00759 msg("option \"%s\" must be given a value", name);
00760 }
00761 }
00762
00763
00764 name = scan;
00765 }
00766
00767
00768
00769 #ifndef CRUNCH
00770
00771 if (*o_novice)
00772 {
00773 *o_report = 1;
00774 # ifndef NO_SHOWMODE
00775 *o_smd = TRUE;
00776 # endif
00777 # ifndef NO_MAGIC
00778 *o_magic = FALSE;
00779 # endif
00780 }
00781 #endif
00782
00783
00784 if (*o_readonly)
00785 {
00786 setflag(file, READONLY);
00787 }
00788
00789 #ifndef NO_DIGRAPH
00790
00791 _ct_init(o_flipcase);
00792 #endif
00793
00794
00795 LINES = (*o_lines & 255);
00796 COLS = (*o_columns & 255);
00797 }