/* vi:ts=4:sw=4 * * VIM - Vi IMproved * * Code Contributions By: Bram Moolenaar mool@oce.nl * Tim Thompson twitch!tjt * Tony Andrews onecom!wldrdg!tony * G. R. (Fred) Walter watmath!watcgl!grwalter */ /* * Code to handle user-settable parameters. This is all pretty much table- * driven. To add a new parameter, put it in the params array, and add a * variable for it in param.h. If it's a numeric parameter, add any necessary * bounds checks to doset(). */ #include "vim.h" #include "globals.h" #include "proto.h" #include "param.h" #ifdef JP #include "jp.h" #endif #ifdef FEPCTRL #include "fepctrl.h" #endif struct param { char *fullname; /* full parameter name */ char *shortname; /* permissible abbreviation */ int flags; /* see below */ char *var; /* pointer to variable */ }; /* * Flags */ #define P_BOOL 0x01 /* the parameter is boolean */ #define P_NUM 0x02 /* the parameter is numeric */ #define P_STRING 0x04 /* the parameter is a string */ #define P_CHANGED 0x08 /* the parameter has been changed */ #define P_EXPAND 0x10 /* environment expansion */ /* * The param structure is initialized here. * The order of the parameters should be alfabetic * The parameters with a NULL variable are 'hidden': a set command for * them is ignored and they are not printed. */ struct param params[] = { {"autoindent", "ai", P_BOOL, (char *)&p_ai}, {"autoprint", "ap", P_BOOL, (char *)NULL}, {"autowrite", "aw", P_BOOL, (char *)&p_aw}, {"backspace", "bs", P_NUM, (char *)&p_bs}, {"backup", "bk", P_BOOL, (char *)&p_bk}, #ifdef UNIX {"backupdir", "bdir", P_STRING|P_EXPAND, (char *)&p_bdir}, #endif {"beautify", "bf", P_BOOL, (char *)NULL}, {"binary", "bin", P_BOOL, (char *)&p_bin}, #if defined(MSDOS) && !defined(DOSGEN) {"bioskey", "biosk",P_BOOL, (char *)&p_biosk}, #endif {"columns", "co", P_NUM, (char *)&Columns}, {"compatible", "cp", P_BOOL, (char *)&p_cp}, #ifdef DIGRAPHS {"digraph", "dg", P_BOOL, (char *)&p_dg}, #endif /* DIGRAPHS */ {"directory", "dir", P_STRING|P_EXPAND, (char *)&p_dir}, {"edcompatible",NULL, P_BOOL, (char *)&p_ed}, {"equalprg", "ep", P_STRING|P_EXPAND, (char *)&p_ep}, {"errorbells", "eb", P_BOOL, (char *)&p_eb}, {"errorfile", "ef", P_STRING|P_EXPAND, (char *)&p_ef}, {"errorformat", "efm", P_STRING, (char *)&p_efm}, {"esckeys", "ek", P_BOOL, (char *)&p_ek}, {"expandtab", "et", P_BOOL, (char *)&p_et}, {"exrc", NULL, P_BOOL, (char *)&p_exrc}, #ifdef FEPCTRL {"fepctrl", "fc", P_BOOL, (char *)&p_fc}, # ifndef WIN32 {"fepskipret", "fsr", P_NUM, (char *)&p_fsr}, # else {"fepsync", "fs", P_BOOL, (char *)&p_fs}, # endif #endif {"formatprg", "fp", P_STRING|P_EXPAND, (char *)&p_fp}, {"floatmsg", "fm", P_BOOL, (char *)&p_fm}, {"graphic", "gr", P_BOOL, (char *)&p_gr}, {"hardtabs", "ht", P_NUM, (char *)NULL}, {"helpfile", "hf", P_STRING|P_EXPAND, (char *)&p_hf}, {"history", "hi", P_NUM, (char *)&p_hi}, {"ignorecase", "ic", P_BOOL, (char *)&p_ic}, {"insertmode", "im", P_BOOL, (char *)&p_im}, {"joinspaces", "js", P_BOOL, (char *)&p_js}, #ifdef JP {"jmask", "jm", P_STRING, (char *)&p_jp}, {"jcode", "jc", P_STRING, (char *)&p_jc}, {"jtilde", "jt", P_BOOL, (char *)&p_jt}, {"jsjiseuc", "jse", P_BOOL, (char *)&p_jse}, #endif #if defined(JPFEP) || defined(FEPCTRL) {"jiauto", "ja", P_NUM, (char *)&p_ja}, {"jinsertmode", "ji", P_STRING, (char *)&p_ji}, #endif {"keywordprg", "kp", P_STRING|P_EXPAND, (char *)&p_kp}, {"lines", NULL, P_NUM, (char *)&Rows}, {"lisp", NULL, P_BOOL, (char *)NULL}, {"list", NULL, P_BOOL, (char *)&p_list}, {"magic", NULL, P_BOOL, (char *)&p_magic}, {"makeprg", "mp", P_STRING|P_EXPAND, (char *)&p_mp}, {"mesg", NULL, P_BOOL, (char *)NULL}, {"modeline", "ml", P_BOOL, (char *)&p_ml}, {"modelines", "mls", P_NUM, (char *)&p_mls}, {"number", "nu", P_BOOL, (char *)&p_nu}, #ifdef ONEW {"ockakutei", "okc", P_BOOL, (char *)&p_okc}, {"onewhankaku", "oh", P_BOOL, (char *)&p_oh}, #endif {"open", NULL, P_BOOL, (char *)NULL}, {"optimize", "opt", P_BOOL, (char *)NULL}, {"paragraphs", "para", P_STRING, (char *)&p_para}, {"paste", NULL, P_BOOL, (char *)&p_paste}, {"prompt", NULL, P_BOOL, (char *)NULL}, {"readonly", "ro", P_BOOL, (char *)&p_ro}, {"redraw", NULL, P_BOOL, (char *)NULL}, {"remap", NULL, P_BOOL, (char *)&p_remap}, {"report", NULL, P_NUM, (char *)&p_report}, {"revins", "ri", P_BOOL, (char *)&p_ri}, {"ruler", "ru", P_BOOL, (char *)&p_ru}, {"secure", NULL, P_BOOL, (char *)&p_secure}, {"scroll", NULL, P_NUM, (char *)&p_scroll}, {"scrolljump", "sj", P_NUM, (char *)&p_sj}, {"sections", "sect", P_STRING, (char *)&p_sections}, {"shell", "sh", P_STRING|P_EXPAND, (char *)&p_sh}, {"shelltype", "st", P_NUM, (char *)&p_st}, {"shiftround", "sr", P_BOOL, (char *)&p_sr}, {"shiftwidth", "sw", P_NUM, (char *)&p_sw}, #if !defined(MSDOS) || defined(WIN32) {"shortname", "sn", P_BOOL, (char *)&p_sn}, #endif {"showcmd", "sc", P_BOOL, (char *)&p_sc}, {"showmatch", "sm", P_BOOL, (char *)&p_sm}, {"showmode", "smd", P_BOOL, (char *)&p_smd}, {"sidescroll", "ss", P_NUM, (char *)&p_ss}, {"slowopen", "slow", P_BOOL, (char *)NULL}, {"smartindent", "si", P_BOOL, (char *)&p_si}, {"sourceany", NULL, P_BOOL, (char *)NULL}, {"suffixes", "su", P_STRING, (char *)&p_su}, {"tabstop", "ts", P_NUM, (char *)&p_ts}, {"taglength", "tl", P_NUM, (char *)&p_tl}, {"tags", NULL, P_STRING|P_EXPAND, (char *)&p_tags}, {"term", NULL, P_STRING|P_EXPAND, (char *)&term_strings.t_name}, {"terse", NULL, P_BOOL, (char *)NULL}, {"textauto", "ta", P_BOOL, (char *)&p_ta}, {"textmode", "tx", P_BOOL, (char *)&p_tx}, {"textwidth", "tw", P_NUM, (char *)&p_tw}, {"tildeop", "to", P_BOOL, (char *)&p_to}, {"timeout", NULL, P_BOOL, (char *)&p_timeout}, {"timeoutlen", "tm", P_NUM, (char *)&p_tm}, {"trackset", "trs", P_STRING, (char *)&p_trs}, {"ttrack", "tt", P_BOOL, (char *)&p_tt}, {"ttimeout", NULL, P_BOOL, (char *)&p_ttimeout}, {"ttytype", NULL, P_STRING, (char *)NULL}, {"undolevels", "ul", P_NUM, (char *)&p_ul}, {"updatecount", "uc", P_NUM, (char *)&p_uc}, {"updatetime", "ut", P_NUM, (char *)&p_ut}, {"visualbell", "vb", P_BOOL, (char *)&p_vb}, {"warn", NULL, P_BOOL, (char *)&p_warn}, {"wildchar", "wc", P_NUM, (char *)&p_wc}, {"window", NULL, P_NUM, (char *)NULL}, {"w300", NULL, P_NUM, (char *)NULL}, {"w1200", NULL, P_NUM, (char *)NULL}, {"w9600", NULL, P_NUM, (char *)NULL}, {"wrap", NULL, P_BOOL, (char *)&p_wrap}, {"wrapscan", "ws", P_BOOL, (char *)&p_ws}, {"wrapmargin", "wm", P_NUM, (char *)&p_wm}, {"writeany", "wa", P_BOOL, (char *)&p_wa}, {"writebackup", "wb", P_BOOL, (char *)&p_wb}, {"yankendofline", "ye", P_BOOL, (char *)&p_ye}, /* terminal output codes */ {"t_el", NULL, P_STRING, (char *)&term_strings.t_el}, {"t_il", NULL, P_STRING, (char *)&term_strings.t_il}, {"t_cil", NULL, P_STRING, (char *)&term_strings.t_cil}, {"t_dl", NULL, P_STRING, (char *)&term_strings.t_dl}, {"t_cdl", NULL, P_STRING, (char *)&term_strings.t_cdl}, {"t_ed", NULL, P_STRING, (char *)&term_strings.t_ed}, {"t_ci", NULL, P_STRING, (char *)&term_strings.t_ci}, {"t_cv", NULL, P_STRING, (char *)&term_strings.t_cv}, {"t_tp", NULL, P_STRING, (char *)&term_strings.t_tp}, {"t_ti", NULL, P_STRING, (char *)&term_strings.t_ti}, #ifdef JPFEP {"t_ue", NULL, P_STRING, (char *)&term_strings.t_ue}, {"t_us", NULL, P_STRING, (char *)&term_strings.t_us}, #endif {"t_cm", NULL, P_STRING, (char *)&term_strings.t_cm}, {"t_sr", NULL, P_STRING, (char *)&term_strings.t_sr}, {"t_cri", NULL, P_STRING, (char *)&term_strings.t_cri}, {"t_vb", NULL, P_STRING, (char *)&term_strings.t_vb}, {"t_ks", NULL, P_STRING, (char *)&term_strings.t_ks}, {"t_ke", NULL, P_STRING, (char *)&term_strings.t_ke}, {"t_ts", NULL, P_STRING, (char *)&term_strings.t_ts}, {"t_te", NULL, P_STRING, (char *)&term_strings.t_te}, /* terminal key codes */ {"t_ku", NULL, P_STRING, (char *)&term_strings.t_ku}, {"t_kd", NULL, P_STRING, (char *)&term_strings.t_kd}, {"t_kr", NULL, P_STRING, (char *)&term_strings.t_kr}, {"t_kl", NULL, P_STRING, (char *)&term_strings.t_kl}, {"t_sku", NULL, P_STRING, (char *)&term_strings.t_sku}, {"t_skd", NULL, P_STRING, (char *)&term_strings.t_skd}, {"t_skr", NULL, P_STRING, (char *)&term_strings.t_skr}, {"t_skl", NULL, P_STRING, (char *)&term_strings.t_skl}, {"t_f1", NULL, P_STRING, (char *)&term_strings.t_f1}, {"t_f2", NULL, P_STRING, (char *)&term_strings.t_f2}, {"t_f3", NULL, P_STRING, (char *)&term_strings.t_f3}, {"t_f4", NULL, P_STRING, (char *)&term_strings.t_f4}, {"t_f5", NULL, P_STRING, (char *)&term_strings.t_f5}, {"t_f6", NULL, P_STRING, (char *)&term_strings.t_f6}, {"t_f7", NULL, P_STRING, (char *)&term_strings.t_f7}, {"t_f8", NULL, P_STRING, (char *)&term_strings.t_f8}, {"t_f9", NULL, P_STRING, (char *)&term_strings.t_f9}, {"t_f10", NULL, P_STRING, (char *)&term_strings.t_f10}, {"t_sf1", NULL, P_STRING, (char *)&term_strings.t_sf1}, {"t_sf2", NULL, P_STRING, (char *)&term_strings.t_sf2}, {"t_sf3", NULL, P_STRING, (char *)&term_strings.t_sf3}, {"t_sf4", NULL, P_STRING, (char *)&term_strings.t_sf4}, {"t_sf5", NULL, P_STRING, (char *)&term_strings.t_sf5}, {"t_sf6", NULL, P_STRING, (char *)&term_strings.t_sf6}, {"t_sf7", NULL, P_STRING, (char *)&term_strings.t_sf7}, {"t_sf8", NULL, P_STRING, (char *)&term_strings.t_sf8}, {"t_sf9", NULL, P_STRING, (char *)&term_strings.t_sf9}, {"t_sf10", NULL, P_STRING, (char *)&term_strings.t_sf10}, {"t_help", NULL, P_STRING, (char *)&term_strings.t_help}, {"t_undo", NULL, P_STRING, (char *)&term_strings.t_undo}, #ifdef ONEW /* onew interface modes */ {"o_rvmsg", NULL, P_BOOL, (char *)&onew_rvmsg}, #endif #ifdef MDOMAIN /* network parameters */ {"n_curl", "curl", P_STRING, (char *)&p_curl}, {"n_proxy", "proxy",P_STRING, (char *)&p_proxy}, {"n_trace", "ntr", P_BOOL, (char *)&p_ntr}, {"n_timeout", "nto", P_NUM, (char *)&p_nto}, #endif {NULL, NULL, 0, NULL} /* end marker */ }; static void param_expand __ARGS((int, int)); static int findparam __ARGS((char *)); static void showparams __ARGS((int)); static void showonep __ARGS((struct param *)); static int istermparam __ARGS((struct param *)); #ifdef MDOMAIN static int isnetparam __ARGS((struct param *)); #endif /* * Initialize the shell parameter and scroll size. */ void set_init() { char *p; int i; if ((p = (char *)vimgetenv("SHELL")) != NULL #ifdef MSDOS || (p = (char *)vimgetenv("COMSPEC")) != NULL #endif ) { p = strsave(p); if (p != NULL) /* we don't want a NULL */ p_sh = p; } p_scroll = (Rows >> 1); comp_col(); /* * expand environment variables in some string options */ for (i = 0; params[i].fullname != NULL; i++) param_expand(i, FALSE); } /* * parse 'arg' for option settings * 'arg' may be IObuff, but only when no errors can be present. */ int doset(arg) char *arg; /* parameter string (may be written to!) */ { register int i; char *s; char *errmsg; char *startarg; int prefix; /* 0: nothing, 1: "no", 2: "inv" in front of name */ int nextchar; int len; int flags; long value; long olduc = p_uc; /* remember old update count */ long oldRows = Rows; /* remember old Rows */ int errcnt = 0; /* number of errornous entries */ static long save_tw = 0; /* saved options for 'paste' */ static int save_ai = 0; static int save_si = 0; static int save_sm = 0; static int save_ru = 0; static int save_ri = 0; static int did_paste = FALSE; /* when TRUE saved values have been set */ int do_wait = FALSE; /* call wait_return() at the end */ int did_show = FALSE; /* already showed one value */ #ifdef FEPCTRL int oldfc = p_fc; #endif if (*arg == NUL) { showparams(0); return 0; } while (*arg) /* loop to process all parameters */ { errmsg = NULL; startarg = arg; /* remember for error message */ if (strncmp(arg, "all", (size_t)3) == 0) showparams(1); else if (strncmp(arg, "termcap", (size_t)7) == 0) showparams(2); #ifdef MDOMAIN else if (strncmp(arg, "net", (size_t)3) == 0) showparams(3); #endif else { prefix = 1; if (strncmp(arg, "no", (size_t)2) == 0) { prefix = 0; arg += 2; } else if (strncmp(arg, "inv", (size_t)3) == 0) { prefix = 2; arg += 3; } /* find end of name */ for (len = 0; isalnum(arg[len]) || arg[len] == '_'; ++len) ; nextchar = arg[len]; arg[len] = 0; /* name ends with 0 */ i = findparam(arg); arg[len] = nextchar; /* restore nextchar */ if (i == -1) /* found a mismatch: skip the rest */ { errmsg = "Unknown option"; goto skip; } if (!params[i].var) /* hidden option */ goto skip; flags = params[i].flags; /* * allow '=' and ':' as MSDOS command.com allows only one * '=' character per "set" command line. grrr. (jw) */ if (nextchar == '?' || (prefix == 1 && nextchar != '=' && nextchar != ':' && !(flags & P_BOOL))) { /* print value */ if (did_show) { outchar('\n'); /* cursor below last one */ do_wait = TRUE; /* have to call wait_return() */ } else { gotocmdline(TRUE, NUL); /* cursor at status line */ did_show = TRUE; /* remember that we did a line */ } showonep(¶ms[i]); /* check if the message is too long to fit in one line */ if ((flags & P_STRING) && strlen(params[i].fullname) + (*(char **)(params[i].var) == NULL ? 0 : strsize(*(char **)(params[i].var))) + 1 >= (unsigned)sc_col) do_wait = TRUE; } else { if (nextchar != NUL && strchr("=: \t", nextchar) == NULL) { errmsg = e_invarg; goto skip; } else if (flags & P_BOOL) /* boolean */ { if (nextchar == '=' || nextchar == ':') { errmsg = e_invarg; goto skip; } /* * in secure mode, setting of the secure option is not allowed */ if (secure && (int *)params[i].var == &p_secure) { errmsg = "not allowed here"; goto skip; } if (prefix == 2) *(int *)(params[i].var) ^= 1; /* invert it */ else *(int *)(params[i].var) = prefix; /* handle compatbile option here */ if ((int *)params[i].var == &p_cp && p_cp) { p_bs = 0; /* normal backspace */ p_bk = 0; /* no backup file */ #ifdef DIGRAPHS p_dg = 0; /* no digraphs */ #endif /* DIGRAPHS */ p_ek = 0; /* no ESC keys in insert mode */ p_et = 0; /* no expansion of tabs */ p_hi = 0; /* no history */ p_im = 0; /* do not start in insert mode */ p_js = 1; /* insert 2 spaces after period */ p_ml = 0; /* no modelines */ p_ru = 0; /* no ruler */ p_ri = 0; /* no reverse insert */ p_sj = 1; /* no scrolljump */ p_sr = 0; /* do not round indent to shiftwidth */ p_sc = 0; /* no showcommand */ p_smd = 0; /* no showmode */ p_si = 0; /* no smartindent */ p_ta = 0; /* no automatic textmode detection */ p_tw = 0; /* no automatic line wrap */ p_to = 0; /* no tilde operator */ p_ttimeout = 0; /* no terminal timeout */ p_ul = 0; /* no multilevel undo */ p_uc = 0; /* no autoscript file */ p_wb = 0; /* no backup file */ if (p_wc == TAB) p_wc = Ctrl('E'); /* normal use for TAB */ p_ye = 0; /* no yank to end of line */ } if ((int *)params[i].var == &p_bin && p_bin) /* handle bin */ { p_tw = 0; /* no automatic line wrap */ p_tx = 0; /* no text mode */ p_ta = 0; /* no text auto */ p_ml = 0; /* no modelines */ p_et = 0; /* no expandtab */ } if ((int *)params[i].var == &p_paste) /* handle paste here */ { if (p_paste) { save_tw = p_tw; /* save current values */ save_ai = p_ai; save_si = p_si; save_sm = p_sm; save_ru = p_ru; save_ri = p_ri; p_tw = 0; /* textwidth is 0 */ p_ai = 0; /* no auto-indent */ p_si = 0; /* no smart-indent */ p_sm = 0; /* no showmatch */ p_ru = 0; /* no ruler */ p_ri = 0; /* no reverse insert */ did_paste = TRUE; } else if (did_paste) /* restore old values */ { p_tw = save_tw; p_ai = save_ai; p_si = save_si; p_sm = save_sm; p_ru = save_ru; p_ri = save_ri; } } } else /* numeric or string */ { if ((nextchar != '=' && nextchar != ':') || prefix != 1) { errmsg = e_invarg; goto skip; } if (flags & P_NUM) /* numeric */ { value = atol(arg + len + 1); /* wrapmargin is translated into textwidth */ if ((long *)params[i].var == &p_wm) { if (value == 0) /* switch it off */ p_tw = 0; else { if (value >= (int)Columns) value = (int)Columns - 1; p_tw = Columns - value; } } *(long *)(params[i].var) = value; } else /* string */ { arg += len + 1; /* jump to after the '=' */ prefix = *arg; /* remember first char of arg */ s = alloc((unsigned)(strlen(arg) + 1)); /* get a bit too much */ if (s == NULL) break; if (flags & P_CHANGED) free(*(char **)(params[i].var)); *(char **)(params[i].var) = s; /* copy the string */ while (*arg && *arg != ' ') { if (*arg == '\\' && *(arg + 1)) /* skip over escaped chars */ ++arg; *s++ = *arg++; } *s = NUL; if (prefix == '$') param_expand(i, TRUE); /* expand environment variables */ /* * options that need some action * to perform when changed (jw) */ if (params[i].var == (char *)&term_strings.t_name) set_term(term_strings.t_name); else if (istermparam(¶ms[i])) { ttest(FALSE); if (params[i].var == (char *)&term_strings.t_tp) { outstr(T_TP); updateScreen(CLEAR); } } #ifdef JP else if (params[i].var == (char *)&p_jc) { if (strlen(p_jc) != 1) { emsg("single letter" ); p_jc = p_jp + 2; } if ('a' <= *p_jc && *p_jc <= 'z') *p_jc -= 'a' - 'A'; if (!strchr(JP_STR, *p_jc)) { emsg(JP_STR); p_jc = p_jp + 2; } } else if (params[i].var == (char *)&p_jp) { char *cp; if (strlen(p_jp) != 3) { emsg("file, display, and new file" ); p_jp = JP; } for(cp = p_jp; *cp; cp++) { if ('a' <= *cp && *cp <= 'z') *cp -= 'a' - 'A'; if (!strchr(JP_STR, *cp)) { *cp = JP_NONE; emsg(JP_STR); } } } #endif #ifdef JPFEP else if (params[i].var == (char *)&p_ji && (strlen(p_ji) != 1 || !strchr("jJaA", *p_ji))) { emsg("j, J, a, A"); p_ji = "a"; } #endif #ifdef MDOMAIN else if (params[i].var == (char *)&p_curl) url_init(p_curl); #endif } } params[i].flags |= P_CHANGED; } } skip: /* * Check the bounds for numeric parameters here */ if (Rows < 2) { Rows = 2; errmsg = "Need at least 2 lines"; } /* * If the screenheight has been changed, assume it is the physical * screenheight, set Rows_max. */ if (oldRows != Rows) { Rows_max = Rows; #ifdef MSDOS set_window(); /* active window may have changed */ #endif } if (p_ts <= 0) { errmsg = e_positive; p_ts = 8; } if (p_tm < 0) { errmsg = e_positive; p_tm = 0; } if (p_scroll <= 0 || p_scroll > Rows) { if (p_scroll != 0) errmsg = e_scroll; p_scroll = Rows >> 1; } if (p_report < 0) { errmsg = e_positive; p_report = 1; } if (p_sj < 0 || p_sj >= Rows) { errmsg = e_scroll; p_sj = 1; } if (p_uc < 0) { errmsg = e_positive; p_uc = 100; } if (p_ut < 0) { errmsg = e_positive; p_ut = 2000; } if (p_ss < 0) { errmsg = e_positive; p_ss = 0; } #ifdef FEPCTRL if (p_fc != oldfc) { if (oldfc) fep_term(); else fep_init(); } #endif if (errmsg) { strcpy(IObuff, errmsg); strcat(IObuff, ": "); s = IObuff + strlen(IObuff); while (*startarg && !isspace(*startarg)) *s++ = *startarg++; *s = NUL; emsg(IObuff); arg = startarg; /* skip to next argument */ ++errcnt; /* count number of errors */ } skiptospace(&arg); /* skip to next white space */ skipspace(&arg); /* skip spaces */ } if (p_uc == 0 && olduc != 0) /* p_uc changed from on to off */ stopscript(); if (p_uc > 0 && olduc == 0) /* p_uc changed from off to on */ startscript(); comp_col(); /* * Update the screen in case we changed something like "tabstop" or * "lines" or "list" that will change its appearance. * If we messed up the screen by showing more than one line of param * values call wait_return(), which will also update the screen.. */ if (do_wait) { outchar('\n'); wait_return(TRUE); } else updateScreen(NOT_VALID); return errcnt; } /* * expand environment variable at the start of some string options */ static void param_expand(i, dofree) int i; int dofree; { char *p; if ((params[i].flags & P_EXPAND) && (p = *(char **)(params[i].var)) != NULL && *p == '$') { expand_env(*(char **)(params[i].var), IObuff, IOSIZE); p = strsave(IObuff); if (p) { if (dofree) free(*(char **)(params[i].var)); *(char **)(params[i].var) = p; } } } /* * find index for option 'arg' * return -1 if not found */ static int findparam(arg) char *arg; { int i; char *s; for (i = 0; (s = params[i].fullname) != NULL; i++) { if (strcmp(arg, s) == 0) /* match full name */ break; } if (s == NULL) { for (i = 0; params[i].fullname != NULL; i++) { s = params[i].shortname; if (s != NULL && strcmp(arg, s) == 0) /* match short name */ break; s = NULL; } } if (s == NULL) i = -1; return i; } /* * mark option 'arg' changed */ void paramchanged(arg) char *arg; { int i; i = findparam(arg); if (i >= 0) params[i].flags |= P_CHANGED; } /* * if 'all' == 0: show changed parameters * if 'all' == 1: show all normal parameters * if 'all' == 2: show all terminal parameters * if 'all' == 3: show all network parameters */ static void showparams(all) int all; { struct param *p; int col = 0; int inc; int isterm; #ifdef MDOMAIN int isnet; #endif gotocmdline(TRUE, NUL); outstrn("Parameters:\n"); #ifdef AMIGA settmode(0); /* set cooked mode so output can be halted */ #endif for (p = ¶ms[0]; p->fullname != NULL; p++) { isterm = istermparam(p); #ifdef MDOMAIN isnet = isnetparam(p); #endif if (p->var && ( #ifdef MDOMAIN (all == 3 && isnet) || #endif (all == 2 && isterm) || (all == 1 && !isterm) || (all == 0 && (p->flags & P_CHANGED)))) { if ((p->flags & P_STRING) && *(char **)(p->var) != NULL) { inc = strlen(p->fullname) + strsize(*(char **)(p->var)) + 1; if (inc < 18) inc = 18; } else inc = 18; if (col + inc >= Columns) { #ifdef DOSGEN if (kbhit()) { getch(); getch(); } #endif col = 0; if (Rows != Rows_max) windgoto((int)Rows_max - 1, 0); outchar('\n'); /* scroll screen one line up */ } windgoto((int)Rows - 1, col); /* make columns */ showonep(p); col += inc; col += 19 - col % 19; flushbuf(); } } if (col) outchar('\n'); #ifdef AMIGA settmode(1); #endif wait_return(TRUE); } /* * showonep: show the value of one option * must not be called with a hidden option! */ static void showonep(p) struct param *p; { char buf[64]; if ((p->flags & P_BOOL) && !*(int *)(p->var)) outstrn("no"); outstrn(p->fullname); if (!(p->flags & P_BOOL)) { outchar('='); if (p->flags & P_NUM) { sprintf(buf, "%ld", *(long *)(p->var)); outstrn(buf); } else if (*(char **)(p->var) != NULL) outtrans(*(char **)(p->var), -1); } } /* * Write modified parameters as set command to a file. * Return 1 on error. */ int makeset(fd) FILE *fd; { struct param *p; char *s; int e; for (p = ¶ms[0]; p->fullname != NULL; p++) if ((p->flags & P_CHANGED) && p->var) { if (p->flags & P_BOOL) fprintf(fd, "set %s%s", *(int *)(p->var) ? "" : "no", p->fullname); else if (p->flags & P_NUM) fprintf(fd, "set %s=%ld", p->fullname, *(long *)(p->var)); else { fprintf(fd, "set %s=", p->fullname); s = *(char **)(p->var); /* some characters hav to be escaped with CTRL-V or backslash */ if (s != NULL && putescstr(fd, s, TRUE) < 0) return 1; } #ifdef MSDOS putc('\r', fd); #endif /* * Only check error for this putc, should catch at least * the "disk full" situation. */ e = putc('\n', fd); if (e < 0) return 1; } return 0; } /* * Clear all the terminal parameters. * If the parameter has been changed, free the allocated memory. * Reset the "changed" flag, so the new value will not be freed. */ void clear_termparam() { struct param *p; for (p = ¶ms[0]; p->fullname != NULL; p++) if (istermparam(p)) /* terminal parameters must never be hidden */ { if (p->flags & P_CHANGED) free(*(char **)(p->var)); *(char **)(p->var) = NULL; p->flags &= ~P_CHANGED; } } static int istermparam(p) struct param *p; { return (p->fullname[0] == 't' && p->fullname[1] == '_'); } #ifdef MDOMAIN static int isnetparam(p) struct param *p; { return (p->fullname[0] == 'n' && p->fullname[1] == '_'); } #endif /* * Compute columns for ruler and shown command. 'sc_col' is also used to * decide what the maximum length of a message on the status line can be. */ #define COL_SHOWCMD 10 /* columns needed by shown command */ #define COL_RULER 17 /* columns needed by ruler */ void comp_col() { sc_col = 0; ru_col = 0; if (p_ru && !p_fm) ru_col = sc_col = COL_RULER + 1; if (p_sc && !p_fm) { sc_col += COL_SHOWCMD; if (!p_ru) ++sc_col; } sc_col = Columns - sc_col; ru_col = Columns - ru_col; }