[BACK]Return to option.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / vim

Annotation of src/usr.bin/vim/option.c, Revision 1.3

1.3     ! downsj      1: /* $OpenBSD: option.c,v 1.2 1996/09/21 06:23:14 downsj Exp $   */
1.1       downsj      2: /* vi:set ts=4 sw=4:
                      3:  *
                      4:  * VIM - Vi IMproved       by Bram Moolenaar
                      5:  *
                      6:  * Do ":help uganda"  in Vim to read copying and usage conditions.
                      7:  * Do ":help credits" in Vim to see a list of people who contributed.
                      8:  */
                      9:
                     10: /*
                     11:  * Code to handle user-settable options. This is all pretty much table-
                     12:  * driven. To add a new option, put it in the options array, and add a
                     13:  * variable for it in option.h. If it's a numeric option, add any necessary
                     14:  * bounds checks to do_set().
                     15:  */
                     16:
                     17: #include "vim.h"
                     18: #include "globals.h"
                     19: #include "proto.h"
                     20: #include "option.h"
                     21:
                     22: struct option
                     23: {
                     24:    char        *fullname;      /* full option name */
                     25:    char        *shortname;     /* permissible abbreviation */
                     26:    short       flags;          /* see below */
                     27:    char_u      *var;           /* pointer to variable */
                     28:    char_u      *def_val;       /* default value for variable (can be the same
                     29:                                    as the actual value) */
                     30: };
                     31:
                     32: /*
                     33:  * Flags
                     34:  *
                     35:  * Note: P_EXPAND and P_IND can never be used at the same time.
                     36:  * Note: P_IND cannot be used for a terminal option.
                     37:  */
                     38: #define P_BOOL         0x01    /* the option is boolean */
                     39: #define P_NUM          0x02    /* the option is numeric */
                     40: #define P_STRING       0x04    /* the option is a string */
                     41: #define P_ALLOCED      0x08    /* the string option is in allocated memory,
                     42:                                    must use vim_free() when assigning new
                     43:                                    value. Not set if default is the same. */
                     44: #define P_EXPAND       0x10    /* environment expansion */
                     45: #define P_IND          0x20    /* indirect, is in curwin or curbuf */
                     46: #define P_NODEFAULT        0x40    /* has no default value */
                     47: #define P_DEF_ALLOCED  0x80    /* default value is in allocated memory, must
                     48:                                    use vim_free() when assigning new value */
                     49: #define P_WAS_SET      0x100   /* option has been set/reset */
                     50: #define P_NO_MKRC      0x200   /* don't include in :mkvimrc output */
                     51:
                     52: /*
                     53:  * The options that are in curwin or curbuf have P_IND set and a var field
                     54:  * that contains one of the values below.
                     55:  */
                     56: #define PV_LIST        1
                     57: #define PV_NU      2
                     58: #define PV_SCROLL  3
                     59: #define PV_WRAP        4
                     60: #define PV_LBR     5
                     61:
                     62: #define PV_AI      6
                     63: #define PV_BIN     7
                     64: #define PV_CIN     8
                     65: #define PV_CINK        9
                     66: #define PV_CINO        10
                     67: #define PV_CINW        11
                     68: #define PV_COM     12
                     69: #define PV_EOL     13
                     70: #define PV_ET      14
                     71: #define PV_FO      15
                     72: #define PV_LISP        16
                     73: #define PV_ML      17
                     74: #define PV_MOD     18
                     75: #define PV_RO      20
                     76: #define PV_SI      21
                     77: #define PV_SN      22
                     78: #define PV_SW      23
                     79: #define PV_TS      24
                     80: #define PV_TW      25
                     81: #define PV_TX      26
                     82: #define PV_WM      27
                     83: #define PV_ISK     28
                     84: #define PV_INF     29
                     85: #define PV_RL      30
                     86:
                     87: /*
                     88:  * The option structure is initialized here.
                     89:  * The order of the options should be alphabetic for ":set all".
                     90:  * The options with a NULL variable are 'hidden': a set command for
                     91:  * them is ignored and they are not printed.
                     92:  */
                     93: static struct option options[] =
                     94: {
                     95: #ifdef RIGHTLEFT
                     96:    {"aleph",       "al",   P_NUM,              (char_u *)&p_aleph,
                     97: # if defined(MSDOS) || defined(WIN32) || defined(OS2)
                     98:                            (char_u *)128L},
                     99: # else
                    100:                            (char_u *)224L},
                    101: # endif
                    102: #endif
                    103:    {"autoindent",  "ai",   P_BOOL|P_IND,       (char_u *)PV_AI,
                    104:                            (char_u *)FALSE},
                    105:    {"autoprint",   "ap",   P_BOOL,             (char_u *)NULL,
                    106:                            (char_u *)FALSE},
                    107:    {"autowrite",   "aw",   P_BOOL,             (char_u *)&p_aw,
                    108:                            (char_u *)FALSE},
                    109:    {"backspace",   "bs",   P_NUM,              (char_u *)&p_bs,
                    110:                            (char_u *)0L},
                    111:    {"backup",      "bk",   P_BOOL,             (char_u *)&p_bk,
                    112:                            (char_u *)FALSE},
                    113:    {"backupdir",   "bdir", P_STRING|P_EXPAND,
                    114:                                                (char_u *)&p_bdir,
                    115:                            (char_u *)DEF_BDIR},
                    116:    {"backupext",   "bex",  P_STRING,           (char_u *)&p_bex,
                    117: #ifdef VMS
                    118:                            (char_u *)"_"},
                    119: #else
                    120:                            (char_u *)"~"},
                    121: #endif
                    122:    {"beautify",    "bf",   P_BOOL,             (char_u *)NULL,
                    123:                            (char_u *)FALSE},
                    124:    {"binary",      "bin",  P_BOOL|P_IND,       (char_u *)PV_BIN,
                    125:                            (char_u *)FALSE},
                    126:    {"bioskey",     "biosk",P_BOOL,
                    127: #ifdef MSDOS
                    128:                                                (char_u *)&p_biosk,
                    129: #else
                    130:                                                (char_u *)NULL,
                    131: #endif
                    132:                            (char_u *)TRUE},
                    133:    {"breakat",     "brk",  P_STRING,           (char_u *)&p_breakat,
                    134:                            (char_u *)" \t!@*-+_;:,./?"},
                    135: #ifdef CINDENT
                    136:    {"cindent",     "cin",  P_BOOL|P_IND,       (char_u *)PV_CIN,
                    137:                            (char_u *)FALSE},
                    138:    {"cinkeys",     "cink", P_STRING|P_IND|P_ALLOCED,   (char_u *)PV_CINK,
                    139:                            (char_u *)"0{,0},:,0#,!^F,o,O,e"},
                    140:    {"cinoptions",  "cino", P_STRING|P_IND|P_ALLOCED,   (char_u *)PV_CINO,
                    141:                            (char_u *)""},
                    142: #endif /* CINDENT */
                    143: #if defined(SMARTINDENT) || defined(CINDENT)
                    144:    {"cinwords",    "cinw", P_STRING|P_IND|P_ALLOCED,   (char_u *)PV_CINW,
                    145:                            (char_u *)"if,else,while,do,for,switch"},
                    146: #endif
                    147:    {"cmdheight",   "ch",   P_NUM,              (char_u *)&p_ch,
                    148:                            (char_u *)1L},
                    149:    {"columns",     "co",   P_NUM|P_NODEFAULT|P_NO_MKRC, (char_u *)&Columns,
                    150:                            (char_u *)80L},
                    151:    {"comments",    "com",  P_STRING|P_IND|P_ALLOCED,   (char_u *)PV_COM,
                    152:                            (char_u *)"sr:/*,mb:*,el:*/,://,b:#,:%,:XCOMM,n:>,fb:-"},
                    153:    {"compatible",  "cp",   P_BOOL,             (char_u *)&p_cp,
                    154:                            (char_u *)FALSE},
                    155:    {"cpoptions",   "cpo",  P_STRING,           (char_u *)&p_cpo,
                    156: #ifdef COMPATIBLE
                    157:                            (char_u *)CPO_ALL},
                    158: #else
                    159:                            (char_u *)CPO_DEFAULT},
                    160: #endif
                    161:    {"define",      "def",  P_STRING,           (char_u *)&p_def,
                    162:                            (char_u *)"^#[ \\t]*define"},
                    163:    {"dictionary",  "dict", P_STRING|P_EXPAND,  (char_u *)&p_dict,
                    164:                            (char_u *)""},
                    165:    {"digraph",     "dg",   P_BOOL,
                    166: #ifdef DIGRAPHS
                    167:                                                (char_u *)&p_dg,
                    168: #else
                    169:                                                (char_u *)NULL,
                    170: #endif /* DIGRAPHS */
                    171:                            (char_u *)FALSE},
                    172:    {"directory",   "dir",  P_STRING|P_EXPAND,  (char_u *)&p_dir,
                    173:                            (char_u *)DEF_DIR},
                    174:    {"edcompatible","ed",   P_BOOL,             (char_u *)&p_ed,
                    175:                            (char_u *)FALSE},
                    176:    {"endofline",   "eol",  P_BOOL|P_IND|P_NO_MKRC, (char_u *)PV_EOL,
                    177:                            (char_u *)FALSE},
                    178:    {"equalalways", "ea",   P_BOOL,             (char_u *)&p_ea,
                    179:                            (char_u *)TRUE},
                    180:    {"equalprg",    "ep",   P_STRING|P_EXPAND,  (char_u *)&p_ep,
                    181:                            (char_u *)""},
                    182:    {"errorbells",  "eb",   P_BOOL,             (char_u *)&p_eb,
                    183:                            (char_u *)FALSE},
                    184:    {"errorfile",   "ef",   P_STRING|P_EXPAND,  (char_u *)&p_ef,
                    185: #ifdef AMIGA
                    186:                            (char_u *)"AztecC.Err"},
                    187: #else
                    188:                            (char_u *)"errors.vim"},
                    189: #endif
                    190:    {"errorformat", "efm",  P_STRING,           (char_u *)&p_efm,
                    191: #ifdef AMIGA
                    192:                        /* don't use [^0-9] here, Manx C can't handle it */
                    193:                            (char_u *)"%f>%l:%c:%t:%n:%m,%f:%l: %t%*[^0123456789]%n: %m,%f %l %t%*[^0123456789]%n: %m,%*[^\"]\"%f\"%*[^0123456789]%l: %m,%f:%l:%m"},
                    194: #else
                    195: # if defined MSDOS  ||  defined WIN32
                    196:                            (char_u *)"%*[^\"]\"%f\"%*[^0-9]%l: %m,%f(%l) : %m,%*[^ ] %f %l: %m,%f:%l:%m"},
                    197: # else
1.2       downsj    198: #  if defined(__EMX__) /* put most common here (i.e. gcc format) at front */
                    199:                            (char_u *)"%f:%l:%m,%*[^\"]\"%f\"%*[^0-9]%l: %m,\"%f\"%*[^0-9]%l: %m,%f(%l:%c) : %m"},
                    200: #  else
                    201: #   if defined(__QNX__)
                    202:                            (char_u *)"%f(%l):%*[^WE]%t%*[^0123456789]%n:%m"},
                    203: #   else /* Unix, probably */
                    204:                            (char_u *)"%*[^\"]\"%f\"%*[^0-9]%l: %m,\"%f\"%*[^0-9]%l: %m,%f:%l:%m,\"%f\"\\, line %l%*[^0-9]%c%*[^ ] %m"},
                    205: #   endif
                    206: #  endif
1.1       downsj    207: # endif
                    208: #endif
                    209:    {"esckeys",     "ek",   P_BOOL,             (char_u *)&p_ek,
                    210: #ifdef COMPATIBLE
                    211:                            (char_u *)FALSE},
                    212: #else
                    213:                            (char_u *)TRUE},
                    214: #endif
                    215:    {"expandtab",   "et",   P_BOOL|P_IND,       (char_u *)PV_ET,
                    216:                            (char_u *)FALSE},
                    217:    {"exrc",        NULL,   P_BOOL,             (char_u *)&p_exrc,
                    218:                            (char_u *)FALSE},
                    219:    {"flash",       "fl",   P_BOOL,             (char_u *)NULL,
                    220:                            (char_u *)FALSE},
                    221:    {"formatoptions","fo",  P_STRING|P_IND|P_ALLOCED,   (char_u *)PV_FO,
                    222: #ifdef COMPATIBLE
                    223:                            (char_u *)FO_DFLT_VI},
                    224: #else
                    225:                            (char_u *)FO_DFLT},
                    226: #endif
                    227:    {"formatprg",   "fp",   P_STRING|P_EXPAND,  (char_u *)&p_fp,
                    228:                            (char_u *)""},
                    229:    {"gdefault",    "gd",   P_BOOL,             (char_u *)&p_gd,
                    230:                            (char_u *)FALSE},
                    231:    {"graphic",     "gr",   P_BOOL,             (char_u *)NULL,
                    232:                            (char_u *)FALSE},
                    233:    {"guifont",     "gfn",  P_STRING,
                    234: #ifdef USE_GUI
                    235:                                                (char_u *)&p_guifont,
                    236:                            (char_u *)""},
                    237: #else
                    238:                                                (char_u *)NULL,
                    239:                            (char_u *)NULL},
                    240: #endif
                    241:    {"guioptions",  "go",   P_STRING,
                    242: #ifdef USE_GUI
                    243:                                                (char_u *)&p_guioptions,
                    244: # ifdef UNIX
1.2       downsj    245:                            (char_u *)"agmr"},
1.1       downsj    246: # else
1.2       downsj    247:                            (char_u *)"gmr"},
1.1       downsj    248: # endif
                    249: #else
                    250:                                                (char_u *)NULL,
                    251:                            (char_u *)NULL},
                    252: #endif
                    253: #if defined(USE_GUI)
                    254:    {"guipty",      NULL,   P_BOOL,             (char_u *)&p_guipty,
                    255:                            (char_u *)FALSE},
                    256: #endif
                    257:    {"hardtabs",    "ht",   P_NUM,              (char_u *)NULL,
                    258:                            (char_u *)0L},
                    259:    {"helpfile",    "hf",   P_STRING|P_EXPAND,  (char_u *)&p_hf,
                    260:                            (char_u *)""},
                    261:    {"helpheight",  "hh",   P_NUM,              (char_u *)&p_hh,
                    262:                            (char_u *)20L},
                    263:    {"hidden",      "hid",  P_BOOL,             (char_u *)&p_hid,
                    264:                            (char_u *)FALSE},
                    265:    {"highlight",   "hl",   P_STRING,           (char_u *)&p_hl,
1.3     ! downsj    266:                            (char_u *)"8b,db,es,mb,Mn,nu,rs,sr,tb,vr,ws"},
1.1       downsj    267:    {"history",     "hi",   P_NUM,              (char_u *)&p_hi,
                    268: #ifdef COMPATIBLE
                    269:                            (char_u *)0L},
                    270: #else
                    271:                            (char_u *)20L},
                    272: #endif
                    273: #ifdef RIGHTLEFT
                    274:    {"hkmap",       "hk",   P_BOOL,             (char_u *)&p_hkmap,
                    275:                            (char_u *)FALSE},
                    276: #endif
                    277:    {"icon",        NULL,   P_BOOL,             (char_u *)&p_icon,
                    278:                            (char_u *)FALSE},
                    279:    {"ignorecase",  "ic",   P_BOOL,             (char_u *)&p_ic,
                    280:                            (char_u *)FALSE},
                    281:    {"include",     "inc",  P_STRING,           (char_u *)&p_inc,
                    282:                            (char_u *)"^#[ \\t]*include"},
                    283:    {"incsearch",   "is",   P_BOOL,             (char_u *)&p_is,
                    284:                            (char_u *)FALSE},
                    285:    {"infercase",   "inf",  P_BOOL|P_IND,       (char_u *)PV_INF,
                    286:                            (char_u *)FALSE},
                    287:    {"insertmode",  "im",   P_BOOL,             (char_u *)&p_im,
                    288:                            (char_u *)FALSE},
                    289:    {"isfname",     "isf",  P_STRING,           (char_u *)&p_isf,
                    290: #ifdef BACKSLASH_IN_FILENAME
                    291:                            (char_u *)"@,48-57,/,.,-,_,+,,,$,:,\\"},
                    292: #else
                    293: # ifdef AMIGA
                    294:                            (char_u *)"@,48-57,/,.,-,_,+,,,$,:"},
                    295: # else /* UNIX */
                    296:                            (char_u *)"@,48-57,/,.,-,_,+,,,$,:,~"},
                    297: # endif
                    298: #endif
                    299:    {"isident",     "isi",  P_STRING,           (char_u *)&p_isi,
                    300: #if defined(MSDOS) || defined(WIN32) || defined(OS2)
                    301:                            (char_u *)"@,48-57,_,128-167,224-235"},
                    302: #else
                    303:                            (char_u *)"@,48-57,_,192-255"},
                    304: #endif
                    305:    {"iskeyword",   "isk",  P_STRING|P_IND|P_ALLOCED,   (char_u *)PV_ISK,
                    306: #ifdef COMPATIBLE
                    307:                            (char_u *)"@,48-57,_"},
                    308: #else
                    309: # if defined MSDOS  ||  defined WIN32
                    310:                            (char_u *)"@,48-57,_,128-167,224-235"},
                    311: # else
                    312:                            (char_u *)"@,48-57,_,192-255"},
                    313: # endif
                    314: #endif
                    315:    {"isprint",     "isp",  P_STRING,           (char_u *)&p_isp,
                    316: #if defined MSDOS  ||  defined WIN32
                    317:                            (char_u *)"@,~-255"},
                    318: #else
                    319:                            (char_u *)"@,161-255"},
                    320: #endif
                    321:    {"joinspaces",  "js",   P_BOOL,             (char_u *)&p_js,
                    322:                            (char_u *)TRUE},
                    323:    {"keywordprg",  "kp",   P_STRING|P_EXPAND,  (char_u *)&p_kp,
                    324: #if defined(MSDOS) ||  defined(WIN32)
                    325:                            (char_u *)""},
                    326: #else
                    327:                            (char_u *)"man"},
                    328: #endif
                    329:    {"langmap",     "lmap", P_STRING,
                    330: #ifdef HAVE_LANGMAP
                    331:                                                (char_u *)&p_langmap,
                    332:                            (char_u *)""},
                    333: #else
                    334:                                                (char_u *)NULL,
                    335:                            (char_u *)NULL},
                    336: #endif
                    337:    {"laststatus",  "ls",   P_NUM,              (char_u *)&p_ls,
                    338:                            (char_u *)1L},
                    339:    {"linebreak",   "lbr",  P_BOOL|P_IND,       (char_u *)PV_LBR,
                    340:                            (char_u *)FALSE},
                    341:    {"lines",       NULL,   P_NUM|P_NODEFAULT|P_NO_MKRC, (char_u *)&Rows,
                    342: #if defined MSDOS  ||  defined WIN32
                    343:                            (char_u *)25L},
                    344: #else
                    345:                            (char_u *)24L},
                    346: #endif
                    347:    {"lisp",        NULL,   P_BOOL|P_IND,       (char_u *)PV_LISP,
                    348:                            (char_u *)FALSE},
                    349:    {"list",        NULL,   P_BOOL|P_IND,       (char_u *)PV_LIST,
                    350:                            (char_u *)FALSE},
                    351:    {"magic",       NULL,   P_BOOL,             (char_u *)&p_magic,
                    352:                            (char_u *)TRUE},
                    353:    {"makeprg",     "mp",   P_STRING|P_EXPAND,  (char_u *)&p_mp,
                    354:                            (char_u *)"make"},
                    355:    {"maxmapdepth", "mmd",  P_NUM,              (char_u *)&p_mmd,
                    356:                            (char_u *)1000L},
                    357:    {"maxmem",      "mm",   P_NUM,              (char_u *)&p_mm,
                    358:                            (char_u *)MAXMEM},
                    359:    {"maxmemtot",   "mmt",  P_NUM,              (char_u *)&p_mmt,
                    360:                            (char_u *)MAXMEMTOT},
                    361:    {"mesg",        NULL,   P_BOOL,             (char_u *)NULL,
                    362:                            (char_u *)FALSE},
                    363:    {"modeline",    "ml",   P_BOOL|P_IND,       (char_u *)PV_ML,
                    364: #ifdef COMPATIBLE
                    365:                            (char_u *)FALSE},
                    366: #else
                    367:                            (char_u *)TRUE},
                    368: #endif
                    369:    {"modelines",   "mls",  P_NUM,              (char_u *)&p_mls,
                    370:                            (char_u *)5L},
                    371:    {"modified",    "mod",  P_BOOL|P_IND|P_NO_MKRC, (char_u *)PV_MOD,
                    372:                            (char_u *)FALSE},
                    373:    {"more",        NULL,   P_BOOL,             (char_u *)&p_more,
                    374: #ifdef COMPATIBLE
                    375:                            (char_u *)FALSE},
                    376: #else
                    377:                            (char_u *)TRUE},
                    378: #endif
                    379:    {"mouse",       NULL,   P_STRING,           (char_u *)&p_mouse,
                    380: #if defined(MSDOS) || defined(WIN32)
                    381:                            (char_u *)"a"},
                    382: #else
                    383:                            (char_u *)""},
                    384: #endif
                    385:    {"mousetime",   "mouset",   P_NUM,          (char_u *)&p_mouset,
                    386:                            (char_u *)500L},
                    387:    {"novice",      NULL,   P_BOOL,             (char_u *)NULL,
                    388:                            (char_u *)FALSE},
                    389:    {"number",      "nu",   P_BOOL|P_IND,       (char_u *)PV_NU,
                    390:                            (char_u *)FALSE},
                    391:    {"open",        NULL,   P_BOOL,             (char_u *)NULL,
                    392:                            (char_u *)FALSE},
                    393:    {"optimize",    "opt",  P_BOOL,             (char_u *)NULL,
                    394:                            (char_u *)FALSE},
                    395:    {"paragraphs",  "para", P_STRING,           (char_u *)&p_para,
                    396:                            (char_u *)"IPLPPPQPP LIpplpipbp"},
                    397:    {"paste",       NULL,   P_BOOL,             (char_u *)&p_paste,
                    398:                            (char_u *)FALSE},
                    399:    {"patchmode",   "pm",   P_STRING,           (char_u *)&p_pm,
                    400:                            (char_u *)""},
                    401:    {"path",        "pa",   P_STRING|P_EXPAND,  (char_u *)&p_path,
                    402: #if defined AMIGA  ||  defined MSDOS  ||  defined WIN32
                    403:                            (char_u *)".,,"},
1.2       downsj    404: #else
                    405: # if defined(__EMX__)
1.1       downsj    406:                            (char_u *)".,/emx/include,,"},
1.2       downsj    407: # else /* Unix, probably */
1.1       downsj    408:                            (char_u *)".,/usr/include,,"},
1.2       downsj    409: # endif
1.1       downsj    410: #endif
                    411:    {"prompt",      NULL,   P_BOOL,             (char_u *)NULL,
                    412:                            (char_u *)FALSE},
                    413:    {"readonly",    "ro",   P_BOOL|P_IND,       (char_u *)PV_RO,
                    414:                            (char_u *)FALSE},
                    415:    {"redraw",      NULL,   P_BOOL,             (char_u *)NULL,
                    416:                            (char_u *)FALSE},
                    417:    {"remap",       NULL,   P_BOOL,             (char_u *)&p_remap,
                    418:                            (char_u *)TRUE},
                    419:    {"report",      NULL,   P_NUM,              (char_u *)&p_report,
                    420:                            (char_u *)2L},
                    421: #ifdef WIN32
                    422:    {"restorescreen", "rs", P_BOOL,             (char_u *)&p_rs,
                    423:                            (char_u *)TRUE},
                    424: #endif
                    425: #ifdef RIGHTLEFT
                    426:    {"revins",      "ri",   P_BOOL,             (char_u *)&p_ri,
                    427:                            (char_u *)FALSE},
                    428:    {"rightleft",   "rl",   P_BOOL|P_IND,       (char_u *)PV_RL,
                    429:                            (char_u *)FALSE},
                    430: #endif
                    431:    {"ruler",       "ru",   P_BOOL,             (char_u *)&p_ru,
                    432:                            (char_u *)FALSE},
                    433:    {"scroll",      "scr",  P_NUM|P_IND|P_NO_MKRC, (char_u *)PV_SCROLL,
                    434:                            (char_u *)12L},
                    435:    {"scrolljump",  "sj",   P_NUM,              (char_u *)&p_sj,
                    436:                            (char_u *)1L},
                    437:    {"scrolloff",   "so",   P_NUM,              (char_u *)&p_so,
                    438:                            (char_u *)0L},
                    439:    {"sections",    "sect", P_STRING,           (char_u *)&p_sections,
                    440:                            (char_u *)"SHNHH HUnhsh"},
                    441:    {"secure",      NULL,   P_BOOL,             (char_u *)&p_secure,
                    442:                            (char_u *)FALSE},
                    443:    {"shell",       "sh",   P_STRING|P_EXPAND,  (char_u *)&p_sh,
1.2       downsj    444: #if defined(MSDOS)
1.1       downsj    445:                            (char_u *)"command"},
1.2       downsj    446: #else
                    447: # if defined(WIN32)
1.1       downsj    448:                            (char_u *)""},      /* set in set_init_1() */
1.2       downsj    449: # else
                    450: #  if defined(__EMX__)
1.1       downsj    451:                            (char_u *)"cmd.exe"},
1.2       downsj    452: #  else
                    453: #   if defined(ARCHIE)
1.1       downsj    454:                            (char_u *)"gos"},
1.2       downsj    455: #   else
                    456:                            (char_u *)"sh"},
                    457: #   endif
                    458: #  endif
                    459: # endif
                    460: #endif
                    461:    {"shellcmdflag","shcf", P_STRING,           (char_u *)&p_shcf,
                    462: #if defined(MSDOS) || defined(WIN32)
                    463:                            (char_u *)"/c"},
1.1       downsj    464: #else
1.2       downsj    465:                            (char_u *)"-c"},
1.1       downsj    466: #endif
                    467:    {"shellpipe",   "sp",   P_STRING,           (char_u *)&p_sp,
                    468: #if defined(UNIX) || defined(OS2)
                    469: # ifdef ARCHIE
                    470:                            (char_u *)"2>"},
                    471: # else
                    472:                            (char_u *)"| tee"},
                    473: # endif
                    474: #else
                    475:                            (char_u *)">"},
                    476: #endif
1.2       downsj    477:    {"shellquote",  "shq",  P_STRING,           (char_u *)&p_shq,
                    478:                            (char_u *)""},
1.1       downsj    479:    {"shellredir",  "srr",  P_STRING,           (char_u *)&p_srr,
                    480:                            (char_u *)">"},
                    481:    {"shelltype",   "st",   P_NUM,              (char_u *)&p_st,
                    482:                            (char_u *)0L},
                    483:    {"shiftround",  "sr",   P_BOOL,             (char_u *)&p_sr,
                    484:                            (char_u *)FALSE},
                    485:    {"shiftwidth",  "sw",   P_NUM|P_IND,        (char_u *)PV_SW,
                    486:                            (char_u *)8L},
                    487:    {"shortmess",   "shm",  P_STRING,           (char_u *)&p_shm,
                    488:                            (char_u *)""},
                    489:    {"shortname",   "sn",   P_BOOL|P_IND,
                    490: #ifdef SHORT_FNAME
                    491:                                                (char_u *)NULL,
                    492: #else
                    493:                                                (char_u *)PV_SN,
                    494: #endif
                    495:                            (char_u *)FALSE},
                    496:    {"showbreak",   "sbr",  P_STRING,           (char_u *)&p_sbr,
                    497:                            (char_u *)""},
                    498:    {"showcmd",     "sc",   P_BOOL,             (char_u *)&p_sc,
                    499: #if defined(COMPATIBLE) || defined(UNIX)
                    500:                            (char_u *)FALSE},
                    501: #else
                    502:                            (char_u *)TRUE},
                    503: #endif
                    504:    {"showmatch",   "sm",   P_BOOL,             (char_u *)&p_sm,
                    505:                            (char_u *)FALSE},
                    506:    {"showmode",    "smd",  P_BOOL,             (char_u *)&p_smd,
                    507: #if defined(COMPATIBLE)
                    508:                            (char_u *)FALSE},
                    509: #else
                    510:                            (char_u *)TRUE},
                    511: #endif
                    512:    {"sidescroll",  "ss",   P_NUM,              (char_u *)&p_ss,
                    513:                            (char_u *)0L},
                    514:    {"slowopen",    "slow", P_BOOL,             (char_u *)NULL,
                    515:                            (char_u *)FALSE},
                    516:    {"smartcase",   "scs",  P_BOOL,             (char_u *)&p_scs,
                    517:                            (char_u *)FALSE},
                    518: #ifdef SMARTINDENT
                    519:    {"smartindent", "si",   P_BOOL|P_IND,       (char_u *)PV_SI,
                    520:                            (char_u *)FALSE},
                    521: #endif
                    522:    {"smarttab",    "sta",  P_BOOL,             (char_u *)&p_sta,
                    523:                            (char_u *)FALSE},
                    524:    {"sourceany",   NULL,   P_BOOL,             (char_u *)NULL,
                    525:                            (char_u *)FALSE},
                    526:    {"splitbelow",  "sb",   P_BOOL,             (char_u *)&p_sb,
                    527:                            (char_u *)FALSE},
                    528:    {"startofline", "sol",  P_BOOL,             (char_u *)&p_sol,
                    529:                            (char_u *)TRUE},
                    530:    {"suffixes",    "su",   P_STRING,           (char_u *)&p_su,
                    531:                            (char_u *)".bak,~,.o,.h,.info,.swp"},
                    532:    {"swapsync",    "sws",  P_STRING,           (char_u *)&p_sws,
                    533:                            (char_u *)"fsync"},
                    534:    {"tabstop",     "ts",   P_NUM|P_IND,        (char_u *)PV_TS,
                    535:                            (char_u *)8L},
                    536:    {"taglength",   "tl",   P_NUM,              (char_u *)&p_tl,
                    537:                            (char_u *)0L},
                    538:    {"tagrelative", "tr",   P_BOOL,             (char_u *)&p_tr,
                    539: #if defined(COMPATIBLE)
                    540:                            (char_u *)FALSE},
                    541: #else
                    542:                            (char_u *)TRUE},
                    543: #endif
                    544:    {"tags",        "tag",  P_STRING|P_EXPAND,  (char_u *)&p_tags,
                    545: #ifdef EMACS_TAGS
                    546:                            (char_u *)"./tags,./TAGS,tags,TAGS"},
                    547: #else
                    548:                            (char_u *)"./tags,tags"},
                    549: #endif
                    550:    {"tagstack",    "tgst", P_BOOL,             (char_u *)NULL,
                    551:                            (char_u *)FALSE},
                    552:    {"term",        NULL,   P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC,
                    553:                                            (char_u *)&term_strings[KS_NAME],
                    554:                            (char_u *)""},
                    555:    {"terse",       NULL,   P_BOOL,             (char_u *)&p_terse,
                    556:                            (char_u *)FALSE},
                    557:    {"textauto",    "ta",   P_BOOL,             (char_u *)&p_ta,
                    558: #if defined(COMPATIBLE)
                    559:                            (char_u *)FALSE},
                    560: #else
                    561:                            (char_u *)TRUE},
                    562: #endif
                    563:    {"textmode",    "tx",   P_BOOL|P_IND,       (char_u *)PV_TX,
                    564: #ifdef USE_CRNL
                    565:                            (char_u *)TRUE},
                    566: #else
                    567:                            (char_u *)FALSE},
                    568: #endif
                    569:    {"textwidth",   "tw",   P_NUM|P_IND,        (char_u *)PV_TW,
                    570:                            (char_u *)0L},
                    571:    {"tildeop",     "top",  P_BOOL,             (char_u *)&p_to,
                    572:                            (char_u *)FALSE},
                    573:    {"timeout",     "to",   P_BOOL,             (char_u *)&p_timeout,
                    574:                            (char_u *)TRUE},
                    575:    {"timeoutlen",  "tm",   P_NUM,              (char_u *)&p_tm,
                    576:                            (char_u *)1000L},
                    577:    {"title",       NULL,   P_BOOL,             (char_u *)&p_title,
                    578:                            (char_u *)FALSE},
1.2       downsj    579:    {"titlelen",    NULL,   P_NUM,              (char_u *)&p_titlelen,
                    580:                            (char_u *)85L},
1.1       downsj    581:    {"ttimeout",    NULL,   P_BOOL,             (char_u *)&p_ttimeout,
                    582:                            (char_u *)FALSE},
                    583:    {"ttimeoutlen", "ttm",  P_NUM,              (char_u *)&p_ttm,
                    584:                            (char_u *)-1L},
                    585:    {"ttybuiltin",  "tbi",  P_BOOL,             (char_u *)&p_tbi,
                    586:                            (char_u *)TRUE},
                    587:    {"ttyfast",     "tf",   P_BOOL|P_NO_MKRC,   (char_u *)&p_tf,
                    588:                            (char_u *)FALSE},
                    589:    {"ttyscroll",   "tsl",  P_NUM,              (char_u *)&p_ttyscroll,
                    590:                            (char_u *)999L},
                    591:    {"ttytype",     "tty",  P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC,
                    592:                                            (char_u *)&term_strings[KS_NAME],
                    593:                            (char_u *)""},
                    594:    {"undolevels",  "ul",   P_NUM,              (char_u *)&p_ul,
                    595: #ifdef COMPATIBLE
                    596:                            (char_u *)0L},
                    597: #else
                    598: # if defined(UNIX) || defined(WIN32) || defined(OS2)
                    599:                            (char_u *)1000L},
                    600: # else
                    601:                            (char_u *)100L},
                    602: # endif
                    603: #endif
                    604:    {"updatecount", "uc",   P_NUM,              (char_u *)&p_uc,
                    605: #ifdef COMPATIBLE
                    606:                            (char_u *)0L},
                    607: #else
                    608:                            (char_u *)200L},
                    609: #endif
                    610:    {"updatetime",  "ut",   P_NUM,              (char_u *)&p_ut,
                    611:                            (char_u *)4000L},
                    612:    {"viminfo",     "vi",   P_STRING,
                    613: #ifdef VIMINFO
                    614:                                                (char_u *)&p_viminfo,
                    615: #else
                    616:                                                (char_u *)NULL,
                    617: #endif /* VIMINFO */
                    618:                            (char_u *)""},
                    619:    {"visualbell",  "vb",   P_BOOL,             (char_u *)&p_vb,
                    620:                            (char_u *)FALSE},
                    621:    {"w300",        NULL,   P_NUM,              (char_u *)NULL,
                    622:                            (char_u *)0L},
                    623:    {"w1200",       NULL,   P_NUM,              (char_u *)NULL,
                    624:                            (char_u *)0L},
                    625:    {"w9600",       NULL,   P_NUM,              (char_u *)NULL,
                    626:                            (char_u *)0L},
                    627:    {"warn",        NULL,   P_BOOL,             (char_u *)&p_warn,
                    628:                            (char_u *)TRUE},
                    629:    {"weirdinvert", "wiv",  P_BOOL,             (char_u *)&p_wiv,
                    630:                            (char_u *)FALSE},
                    631:    {"whichwrap",   "ww",   P_STRING,           (char_u *)&p_ww,
                    632: #ifdef COMPATIBLE
                    633:                            (char_u *)""},
                    634: #else
                    635:                            (char_u *)"b,s"},
                    636: #endif
                    637:    {"wildchar",    "wc",   P_NUM,              (char_u *)&p_wc,
                    638: #ifdef COMPATIBLE
                    639:                            (char_u *)(long)Ctrl('E')},
                    640: #else
                    641:                            (char_u *)(long)TAB},
                    642: #endif
                    643:    {"window",      "wi",   P_NUM,              (char_u *)NULL,
                    644:                            (char_u *)0L},
                    645:    {"winheight",   "wh",   P_NUM,              (char_u *)&p_wh,
                    646:                            (char_u *)0L},
                    647:    {"wrap",        NULL,   P_BOOL|P_IND,       (char_u *)PV_WRAP,
                    648:                            (char_u *)TRUE},
                    649:    {"wrapmargin",  "wm",   P_NUM|P_IND,        (char_u *)PV_WM,
                    650:                            (char_u *)0L},
                    651:    {"wrapscan",    "ws",   P_BOOL,             (char_u *)&p_ws,
                    652:                            (char_u *)TRUE},
                    653:    {"writeany",    "wa",   P_BOOL,             (char_u *)&p_wa,
                    654:                            (char_u *)FALSE},
                    655:    {"writebackup", "wb",   P_BOOL,             (char_u *)&p_wb,
                    656: #if defined(COMPATIBLE) && !defined(WRITEBACKUP)
                    657:                            (char_u *)FALSE},
                    658: #else
                    659:                            (char_u *)TRUE},
                    660: #endif
                    661:    {"writedelay",  "wd",   P_NUM,              (char_u *)&p_wd,
                    662:                            (char_u *)0L},
                    663:
                    664: /* terminal output codes */
                    665:    {"t_AL",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CAL],
                    666:                            (char_u *)""},
                    667:    {"t_al",        NULL,   P_STRING,   (char_u *)&term_strings[KS_AL],
                    668:                            (char_u *)""},
                    669:    {"t_cd",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CD],
                    670:                            (char_u *)""},
                    671:    {"t_ce",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CE],
                    672:                            (char_u *)""},
                    673:    {"t_cl",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CL],
                    674:                            (char_u *)""},
                    675:    {"t_cm",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CM],
                    676:                            (char_u *)""},
                    677:    {"t_CS",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CSC],
                    678:                            (char_u *)""},
                    679:    {"t_cs",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CS],
                    680:                            (char_u *)""},
                    681:    {"t_da",        NULL,   P_STRING,   (char_u *)&term_strings[KS_DA],
                    682:                            (char_u *)""},
                    683:    {"t_db",        NULL,   P_STRING,   (char_u *)&term_strings[KS_DB],
                    684:                            (char_u *)""},
                    685:    {"t_DL",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CDL],
                    686:                            (char_u *)""},
                    687:    {"t_dl",        NULL,   P_STRING,   (char_u *)&term_strings[KS_DL],
                    688:                            (char_u *)""},
                    689:    {"t_ke",        NULL,   P_STRING,   (char_u *)&term_strings[KS_KE],
                    690:                            (char_u *)""},
                    691:    {"t_ks",        NULL,   P_STRING,   (char_u *)&term_strings[KS_KS],
                    692:                            (char_u *)""},
                    693:    {"t_md",        NULL,   P_STRING,   (char_u *)&term_strings[KS_MD],
                    694:                            (char_u *)""},
                    695:    {"t_me",        NULL,   P_STRING,   (char_u *)&term_strings[KS_ME],
                    696:                            (char_u *)""},
                    697:    {"t_mr",        NULL,   P_STRING,   (char_u *)&term_strings[KS_MR],
                    698:                            (char_u *)""},
                    699:    {"t_ms",        NULL,   P_STRING,   (char_u *)&term_strings[KS_MS],
                    700:                            (char_u *)""},
                    701:    {"t_RI",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CRI],
                    702:                            (char_u *)""},
                    703:    {"t_se",        NULL,   P_STRING,   (char_u *)&term_strings[KS_SE],
                    704:                            (char_u *)""},
                    705:    {"t_so",        NULL,   P_STRING,   (char_u *)&term_strings[KS_SO],
                    706:                            (char_u *)""},
                    707:    {"t_sr",        NULL,   P_STRING,   (char_u *)&term_strings[KS_SR],
                    708:                            (char_u *)""},
                    709:    {"t_te",        NULL,   P_STRING,   (char_u *)&term_strings[KS_TE],
                    710:                            (char_u *)""},
                    711:    {"t_ti",        NULL,   P_STRING,   (char_u *)&term_strings[KS_TI],
                    712:                            (char_u *)""},
                    713:    {"t_ue",        NULL,   P_STRING,   (char_u *)&term_strings[KS_UE],
                    714:                            (char_u *)""},
                    715:    {"t_us",        NULL,   P_STRING,   (char_u *)&term_strings[KS_US],
                    716:                            (char_u *)""},
                    717:    {"t_vb",        NULL,   P_STRING,   (char_u *)&term_strings[KS_VB],
                    718:                            (char_u *)""},
                    719:    {"t_ve",        NULL,   P_STRING,   (char_u *)&term_strings[KS_VE],
                    720:                            (char_u *)""},
                    721:    {"t_vi",        NULL,   P_STRING,   (char_u *)&term_strings[KS_VI],
                    722:                            (char_u *)""},
                    723:    {"t_vs",        NULL,   P_STRING,   (char_u *)&term_strings[KS_VS],
                    724:                            (char_u *)""},
                    725:    {"t_ZH",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CZH],
                    726:                            (char_u *)""},
                    727:    {"t_ZR",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CZR],
                    728:                            (char_u *)""},
                    729:
                    730: /* terminal key codes are not here */
                    731:
                    732:    {NULL, NULL, 0, NULL, NULL}         /* end marker */
                    733: };
                    734:
                    735: #define PARAM_COUNT (sizeof(options) / sizeof(struct option))
                    736:
                    737: #ifdef AUTOCMD
                    738: /*
                    739:  * structures for automatic commands
                    740:  */
                    741:
                    742: typedef struct AutoCmd
                    743: {
                    744:    char_u          *cmd;                   /* The command to be executed */
                    745:    struct AutoCmd  *next;                  /* Next AutoCmd in list */
                    746: } AutoCmd;
                    747:
                    748: typedef struct AutoPat
                    749: {
                    750:    char_u          *pat;                   /* pattern as typed */
                    751:    char_u          *reg_pat;               /* pattern converted to regexp */
                    752:    int             allow_directories;      /* Pattern may match whole path */
                    753:    AutoCmd         *cmds;                  /* list of commands to do */
                    754:    struct AutoPat  *next;                  /* next AutoPat in AutoPat list */
                    755: } AutoPat;
                    756:
                    757: static struct event_name
                    758: {
                    759:    char    *name;      /* event name */
                    760:    int     event;      /* event number */
                    761: } event_names[] =
                    762: {
                    763:    {"BufEnter",        EVENT_BUFENTER},
                    764:    {"BufLeave",        EVENT_BUFLEAVE},
                    765:    {"BufNewFile",      EVENT_BUFNEWFILE},
                    766:    {"BufReadPost",     EVENT_BUFREADPOST},
                    767:    {"BufReadPre",      EVENT_BUFREADPRE},
                    768:    {"BufRead",         EVENT_BUFREADPOST},
                    769:    {"BufWritePost",    EVENT_BUFWRITEPOST},
                    770:    {"BufWritePre",     EVENT_BUFWRITEPRE},
                    771:    {"BufWrite",        EVENT_BUFWRITEPRE},
                    772:    {"FileAppendPost",  EVENT_FILEAPPENDPOST},
                    773:    {"FileAppendPre",   EVENT_FILEAPPENDPRE},
                    774:    {"FileReadPost",    EVENT_FILEREADPOST},
                    775:    {"FileReadPre",     EVENT_FILEREADPRE},
                    776:    {"FileWritePost",   EVENT_FILEWRITEPOST},
                    777:    {"FileWritePre",    EVENT_FILEWRITEPRE},
                    778:    {"FilterReadPost",  EVENT_FILTERREADPOST},
                    779:    {"FilterReadPre",   EVENT_FILTERREADPRE},
                    780:    {"FilterWritePost", EVENT_FILTERWRITEPOST},
                    781:    {"FilterWritePre",  EVENT_FILTERWRITEPRE},
                    782:    {"VimLeave",        EVENT_VIMLEAVE},
                    783:    {"WinEnter",        EVENT_WINENTER},
                    784:    {"WinLeave",        EVENT_WINLEAVE},
                    785:    {NULL,          0}
                    786: };
                    787:
                    788: static AutoPat *first_autopat[NUM_EVENTS] =
                    789: {
                    790:    NULL, NULL, NULL, NULL, NULL,
                    791:    NULL, NULL, NULL, NULL, NULL,
                    792:    NULL, NULL, NULL, NULL, NULL,
                    793:    NULL, NULL, NULL, NULL, NULL
                    794: };
                    795: #endif
                    796:
                    797: static void set_option_default __ARGS((int, int));
                    798: static void illegal_char __ARGS((char_u *, int));
                    799: static char_u *option_expand __ARGS((int));
                    800: static int findoption __ARGS((char_u *));
                    801: static int find_key_option __ARGS((char_u *));
                    802: static void    showoptions __ARGS((int));
                    803: static int option_changed __ARGS((struct option *));
                    804: static void showoneopt __ARGS((struct option *));
                    805: static int  istermoption __ARGS((struct option *));
                    806: static char_u *get_varp __ARGS((struct option *));
                    807: static void option_value2string __ARGS((struct option *));
                    808: #ifdef HAVE_LANGMAP
                    809: static void langmap_init __ARGS((void));
                    810: static void langmap_set __ARGS((void));
                    811: #endif
                    812: static void paste_option_changed __ARGS((void));
                    813: static void p_compatible_set __ARGS((void));
                    814: static void fill_breakat_flags __ARGS((void));
                    815:
                    816: /*
                    817:  * Initialize the options, first part.
                    818:  *
                    819:  * Called only once from main(), just after creating the first buffer.
                    820:  */
                    821:    void
                    822: set_init_1()
                    823: {
                    824:    char_u  *p;
                    825:    int     opt_idx;
                    826:    long    n;
                    827:
                    828: #ifdef HAVE_LANGMAP
                    829:    langmap_init();
                    830: #endif
                    831:
                    832: /*
                    833:  * Find default value for 'shell' option.
                    834:  */
                    835:    if ((p = vim_getenv((char_u *)"SHELL")) != NULL
                    836: #if defined(MSDOS) || defined(WIN32) || defined(OS2)
                    837: # ifdef __EMX__
                    838:            || (p = vim_getenv((char_u *)"EMXSHELL")) != NULL
                    839: # endif
                    840:            || (p = vim_getenv((char_u *)"COMSPEC")) != NULL
                    841: # ifdef WIN32
                    842:            || (p = default_shell()) != NULL
                    843: # endif
                    844: #endif
                    845:                                                            )
                    846:    {
                    847:        p = strsave(p);
                    848:        if (p != NULL)          /* we don't want a NULL */
                    849:        {
                    850:            opt_idx = findoption((char_u *)"sh");
                    851:            options[opt_idx].def_val = p;
                    852:            options[opt_idx].flags |= P_DEF_ALLOCED;
                    853:        }
                    854:    }
                    855:
                    856: /*
                    857:  * Set default for 'helpfile' option. This cannot be done at compile time,
                    858:  * because for Unix it is an external variable.
                    859:  */
                    860:    opt_idx = findoption((char_u *)"hf");
                    861: #if defined(HAVE_CONFIG_H) || defined(OS2)
                    862:    options[opt_idx].def_val = help_fname;
                    863: #else
                    864:    options[opt_idx].def_val = (char_u *)VIM_HLP;
                    865: #endif
                    866:
                    867: /*
                    868:  * 'maxmemtot' and 'maxmem' may have to be adjusted for available memory
                    869:  */
                    870:    opt_idx = findoption((char_u *)"maxmemtot");
                    871:    if (options[opt_idx].def_val == (char_u *)0L)
                    872:    {
                    873:        n = (mch_avail_mem(FALSE) >> 11);
                    874:        options[opt_idx].def_val = (char_u *)n;
                    875:        opt_idx = findoption((char_u *)"maxmem");
                    876:        if ((long)options[opt_idx].def_val > n ||
                    877:                                         (long)options[opt_idx].def_val == 0L)
                    878:            options[opt_idx].def_val = (char_u *)n;
                    879:    }
                    880:
                    881: /*
                    882:  * set all the options (except the terminal options) to their default value
                    883:  */
                    884:    for (opt_idx = 0; !istermoption(&options[opt_idx]); opt_idx++)
                    885:        if (!(options[opt_idx].flags & P_NODEFAULT))
                    886:            set_option_default(opt_idx, FALSE);
                    887:
                    888:    curbuf->b_p_initialized = TRUE;
                    889:    check_buf_options(curbuf);
                    890:    check_options();
                    891:
                    892:    /*
                    893:     * initialize the table for 'iskeyword' et.al.
                    894:     * Must be before option_expand(), because that one needs isidchar()
                    895:     */
                    896:    init_chartab();
                    897:
                    898:    /*
                    899:     * initialize the table for 'breakat'.
                    900:     */
                    901:    fill_breakat_flags();
                    902:
                    903:    /*
                    904:     * Expand environment variables and things like "~" for the defaults.
                    905:     * If option_expand() returns non-NULL the variable is expanded. This can
                    906:     * only happen for non-indirect options.
                    907:     * Also set the default to the expanded value, so ":set" does not list
                    908:     * them. Don't set the P_ALLOCED flag, because we don't want to free the
                    909:     * default.
                    910:     */
                    911:    for (opt_idx = 0; !istermoption(&options[opt_idx]); opt_idx++)
                    912:    {
                    913:        p = option_expand(opt_idx);
                    914:        if (p != NULL)
                    915:        {
                    916:            *(char_u **)options[opt_idx].var = p;
                    917:            options[opt_idx].def_val = p;
                    918:            options[opt_idx].flags |= P_DEF_ALLOCED;
                    919:        }
                    920:    }
                    921: }
                    922:
                    923: /*
                    924:  * Set an option to its default value.
                    925:  */
                    926:    static void
                    927: set_option_default(opt_idx, dofree)
                    928:    int     opt_idx;
                    929:    int     dofree;     /* TRUE when old value may be freed */
                    930: {
                    931:    char_u      *varp;          /* pointer to variable for current option */
                    932:
                    933:    varp = get_varp(&(options[opt_idx]));
                    934:    if (varp != NULL)       /* nothing to do for hidden option */
                    935:    {
                    936:        if (options[opt_idx].flags & P_STRING)
                    937:        {
                    938:            /* indirect options are always in allocated memory */
                    939:            if (options[opt_idx].flags & P_IND)
                    940:                set_string_option(NULL, opt_idx,
                    941:                                            options[opt_idx].def_val, dofree);
                    942:            else
                    943:            {
                    944:                if (dofree && (options[opt_idx].flags & P_ALLOCED))
                    945:                    free_string_option(*(char_u **)(varp));
                    946:                *(char_u **)varp = options[opt_idx].def_val;
                    947:                options[opt_idx].flags &= ~P_ALLOCED;
                    948:            }
                    949:        }
                    950:        else if (options[opt_idx].flags & P_NUM)
                    951:            *(long *)varp = (long)options[opt_idx].def_val;
                    952:        else    /* P_BOOL */
                    953:                /* the cast to long is required for Manx C */
                    954:            *(int *)varp = (int)(long)options[opt_idx].def_val;
                    955:    }
                    956: }
                    957:
                    958: /*
                    959:  * Initialize the options, part two: After getting Rows and Columns
                    960:  */
                    961:    void
                    962: set_init_2()
                    963: {
                    964: /*
                    965:  * 'scroll' defaults to half the window height. Note that this default is
                    966:  * wrong when the window height changes.
                    967:  */
                    968:    options[findoption((char_u *)"scroll")].def_val = (char_u *)(Rows >> 1);
                    969:
                    970:    comp_col();
                    971: }
                    972:
                    973: /*
                    974:  * Initialize the options, part three: After reading the .vimrc
                    975:  */
                    976:    void
                    977: set_init_3()
                    978: {
                    979:    int     idx1;
                    980:
                    981: #if defined(UNIX) || defined(OS2)
                    982: /*
                    983:  * Set 'shellpipe' and 'shellredir', depending on the 'shell' option.
                    984:  * This is done after other initializations, where 'shell' might have been
                    985:  * set, but only if they have not been set before.
                    986:  */
                    987:    char_u  *p;
                    988:    int     idx2;
                    989:    int     do_sp;
                    990:    int     do_srr;
                    991:
                    992:    idx1 = findoption((char_u *)"sp");
                    993:    idx2 = findoption((char_u *)"srr");
                    994:    do_sp = !(options[idx1].flags & P_WAS_SET);
                    995:    do_srr = !(options[idx2].flags & P_WAS_SET);
                    996:
                    997:    /*
                    998:     * Default for p_sp is "| tee", for p_srr is ">".
                    999:     * For known shells it is changed here to include stderr.
                   1000:     */
                   1001:    p = gettail(p_sh);
                   1002:    if (    fnamecmp(p, "csh") == 0 ||
                   1003:            fnamecmp(p, "tcsh") == 0
                   1004: # ifdef OS2            /* also check with .exe extension */
                   1005:            || fnamecmp(p, "csh.exe") == 0
                   1006:            || fnamecmp(p, "tcsh.exe") == 0
                   1007: # endif
                   1008:                                            )
                   1009:    {
                   1010:        if (do_sp)
                   1011:        {
                   1012:            p_sp = (char_u *)"|& tee";
                   1013:            options[idx1].def_val = p_sp;
                   1014:        }
                   1015:        if (do_srr)
                   1016:        {
                   1017:            p_srr = (char_u *)">&";
                   1018:            options[idx2].def_val = p_srr;
                   1019:        }
                   1020:    }
                   1021:    else
                   1022: # ifndef OS2   /* Always use bourne shell style redirection if we reach this */
                   1023:        if (    STRCMP(p, "sh") == 0 ||
                   1024:                STRCMP(p, "ksh") == 0 ||
                   1025:                STRCMP(p, "zsh") == 0 ||
                   1026:                STRCMP(p, "bash") == 0)
                   1027: # endif
                   1028:    {
                   1029:        if (do_sp)
                   1030:        {
                   1031:            p_sp = (char_u *)"2>&1| tee";
                   1032:            options[idx1].def_val = p_sp;
                   1033:        }
                   1034:        if (do_srr)
                   1035:        {
                   1036:            p_srr = (char_u *)">%s 2>&1";
                   1037:            options[idx2].def_val = p_srr;
                   1038:        }
                   1039:    }
                   1040: #endif
                   1041:
1.2       downsj   1042: #if defined(MSDOS) || defined(WIN32)
                   1043:    /*
                   1044:     * Set 'shellcmdflag and 'shellquote' depending on the 'shell' option.
                   1045:     * This is done after other initializations, where 'shell' might have been
                   1046:     * set, but only if they have not been set before.  Default for p_shcf is
                   1047:     * "/c", for p_shq is "".  For "sh" like  shells it is changed here to
                   1048:     * "-c" and "\"".
                   1049:     */
                   1050:    if (strstr((char *)p_sh, "sh") != NULL)
                   1051:    {
                   1052:        idx1 = findoption((char_u *)"shcf");
                   1053:        if (!(options[idx1].flags & P_WAS_SET))
                   1054:        {
                   1055:            p_shcf = (char_u *)"-c";
                   1056:            options[idx1].def_val = p_shcf;
                   1057:        }
                   1058:
                   1059:        idx1 = findoption((char_u *)"shq");
                   1060:        if (!(options[idx1].flags & P_WAS_SET))
                   1061:        {
                   1062:            p_shq = (char_u *)"\"";
                   1063:            options[idx1].def_val = p_shq;
                   1064:        }
                   1065:    }
                   1066: #endif
                   1067:
1.1       downsj   1068: /*
                   1069:  * 'title' and 'icon' only default to true if they have not been set or reset
                   1070:  * in .vimrc and we can read the old value.
                   1071:  * When 'title' and 'icon' have been reset in .vimrc, we won't even check if
1.2       downsj   1072:  * they can be reset.  This reduces startup time when using X on a remote
1.1       downsj   1073:  * machine.
                   1074:  */
                   1075:    idx1 = findoption((char_u *)"title");
                   1076:    if (!(options[idx1].flags & P_WAS_SET) && mch_can_restore_title())
                   1077:    {
                   1078:        options[idx1].def_val = (char_u *)TRUE;
                   1079:        p_title = TRUE;
                   1080:    }
                   1081:    idx1 = findoption((char_u *)"icon");
                   1082:    if (!(options[idx1].flags & P_WAS_SET) && mch_can_restore_icon())
                   1083:    {
                   1084:        options[idx1].def_val = (char_u *)TRUE;
                   1085:        p_icon = TRUE;
                   1086:    }
                   1087: }
                   1088:
                   1089: /*
                   1090:  * Parse 'arg' for option settings.
                   1091:  *
                   1092:  * 'arg' may be IObuff, but only when no errors can be present and option
                   1093:  * does not need to be expanded with option_expand().
                   1094:  *
                   1095:  * return FAIL if errors are detected, OK otherwise
                   1096:  */
                   1097:    int
                   1098: do_set(arg)
                   1099:    char_u      *arg;   /* option string (may be written to!) */
                   1100: {
                   1101:    register int opt_idx;
                   1102:    char_u      *errmsg;
                   1103:    char_u      errbuf[80];
                   1104:    char_u      *startarg;
                   1105:    int         prefix; /* 1: nothing, 0: "no", 2: "inv" in front of name */
                   1106:    int         nextchar;           /* next non-white char after option name */
                   1107:    int         afterchar;          /* character just after option name */
                   1108:    int         len;
                   1109:    int         i;
                   1110:    int         key;
                   1111:    int         flags;              /* flags for current option */
                   1112:    char_u      *varp = NULL;       /* pointer to variable for current option */
                   1113:    char_u      *oldval;            /* previous value if *varp */
                   1114:    int         errcnt = 0;         /* number of errornous entries */
                   1115:    long        oldRows = Rows;     /* remember old Rows */
                   1116:    long        oldColumns = Columns;   /* remember old Columns */
                   1117:    int         oldbin;             /* remember old bin option */
                   1118:    long        oldch = p_ch;       /* remember old command line height */
                   1119:    int         oldea = p_ea;       /* remember old 'equalalways' */
                   1120:    long        olduc = p_uc;       /* remember old 'updatecount' */
                   1121:    int         did_show = FALSE;   /* already showed one value */
                   1122:    WIN         *wp;
                   1123:
                   1124:    if (*arg == NUL)
                   1125:    {
                   1126:        showoptions(0);
                   1127:        return OK;
                   1128:    }
                   1129:
                   1130:    while (*arg)        /* loop to process all options */
                   1131:    {
                   1132:        errmsg = NULL;
                   1133:        startarg = arg;     /* remember for error message */
                   1134:
                   1135:        if (STRNCMP(arg, "all", (size_t)3) == 0)
                   1136:        {
                   1137:            showoptions(1);
                   1138:            arg += 3;
                   1139:        }
                   1140:        else if (STRNCMP(arg, "termcap", (size_t)7) == 0)
                   1141:        {
                   1142:            showoptions(2);
                   1143:            show_termcodes();
                   1144:            arg += 7;
                   1145:        }
                   1146:        else
                   1147:        {
                   1148:            prefix = 1;
                   1149:            if (STRNCMP(arg, "no", (size_t)2) == 0)
                   1150:            {
                   1151:                prefix = 0;
                   1152:                arg += 2;
                   1153:            }
                   1154:            else if (STRNCMP(arg, "inv", (size_t)3) == 0)
                   1155:            {
                   1156:                prefix = 2;
                   1157:                arg += 3;
                   1158:            }
                   1159:                /* find end of name */
                   1160:            if (*arg == '<')
                   1161:            {
                   1162:                opt_idx = -1;
                   1163:                /* check for <t_>;> */
                   1164:                if (arg[1] == 't' && arg[2] == '_' && arg[3] && arg[4])
                   1165:                    len = 5;
                   1166:                else
                   1167:                {
                   1168:                    len = 1;
                   1169:                    while (arg[len] != NUL && arg[len] != '>')
                   1170:                        ++len;
                   1171:                }
                   1172:                if (arg[len] != '>')
                   1173:                {
                   1174:                    errmsg = e_invarg;
                   1175:                    goto skip;
                   1176:                }
                   1177:                nextchar = arg[len];
                   1178:                arg[len] = NUL;                     /* put NUL after name */
                   1179:                if (arg[1] == 't' && arg[2] == '_') /* could be term code */
                   1180:                    opt_idx = findoption(arg + 1);
                   1181:                key = 0;
                   1182:                if (opt_idx == -1)
                   1183:                    key = find_key_option(arg + 1);
                   1184:                arg[len++] = nextchar;              /* restore nextchar */
                   1185:                nextchar = arg[len];
                   1186:            }
                   1187:            else
                   1188:            {
                   1189:                len = 0;
                   1190:                /*
                   1191:                 * The two characters after "t_" may not be alphanumeric.
                   1192:                 */
                   1193:                if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
                   1194:                {
                   1195:                    len = 4;
                   1196:                }
                   1197:                else
                   1198:                {
                   1199:                    while (isalnum(arg[len]) || arg[len] == '_')
                   1200:                        ++len;
                   1201:                }
                   1202:                nextchar = arg[len];
                   1203:                arg[len] = NUL;                     /* put NUL after name */
                   1204:                opt_idx = findoption(arg);
                   1205:                key = 0;
                   1206:                if (opt_idx == -1)
                   1207:                    key = find_key_option(arg);
                   1208:                arg[len] = nextchar;                /* restore nextchar */
                   1209:            }
                   1210:
                   1211:            if (opt_idx == -1 && key == 0)      /* found a mismatch: skip */
                   1212:            {
                   1213:                errmsg = (char_u *)"Unknown option";
                   1214:                goto skip;
                   1215:            }
                   1216:
                   1217:            if (opt_idx >= 0)
                   1218:            {
                   1219:                if (options[opt_idx].var == NULL)   /* hidden option: skip */
                   1220:                    goto skip;
                   1221:
                   1222:                flags = options[opt_idx].flags;
                   1223:                varp = get_varp(&(options[opt_idx]));
                   1224:            }
                   1225:            else
                   1226:                flags = P_STRING;
                   1227:
                   1228:            /* remember character after option name */
                   1229:            afterchar = nextchar;
                   1230:
                   1231:            /* skip white space, allow ":set ai  ?" */
                   1232:            while (vim_iswhite(nextchar))
                   1233:                nextchar = arg[++len];
                   1234:
                   1235:            if (vim_strchr((char_u *)"?=:!&", nextchar) != NULL)
                   1236:            {
                   1237:                arg += len;
                   1238:                len = 0;
                   1239:            }
                   1240:
                   1241:            /*
                   1242:             * allow '=' and ':' as MSDOS command.com allows only one
                   1243:             * '=' character per "set" command line. grrr. (jw)
                   1244:             */
                   1245:            if (nextchar == '?' || (prefix == 1 && vim_strchr((char_u *)"=:&",
                   1246:                                      nextchar) == NULL && !(flags & P_BOOL)))
                   1247:            {                                       /* print value */
                   1248:                if (did_show)
                   1249:                    msg_outchar('\n');      /* cursor below last one */
                   1250:                else
                   1251:                {
                   1252:                    gotocmdline(TRUE);      /* cursor at status line */
                   1253:                    did_show = TRUE;        /* remember that we did a line */
                   1254:                }
                   1255:                if (opt_idx >= 0)
                   1256:                    showoneopt(&options[opt_idx]);
                   1257:                else
                   1258:                {
                   1259:                    char_u          name[2];
                   1260:                    char_u          *p;
                   1261:
                   1262:                    name[0] = KEY2TERMCAP0(key);
                   1263:                    name[1] = KEY2TERMCAP1(key);
                   1264:                    p = find_termcode(name);
                   1265:                    if (p == NULL)
                   1266:                    {
                   1267:                        errmsg = (char_u *)"Unknown option";
                   1268:                        goto skip;
                   1269:                    }
                   1270:                    else
                   1271:                        (void)show_one_termcode(name, p, TRUE);
                   1272:                }
                   1273:                if (nextchar != '?' && nextchar != NUL &&
                   1274:                                                      !vim_iswhite(afterchar))
                   1275:                    errmsg = e_trailing;
                   1276:            }
                   1277:            else
                   1278:            {
                   1279:                if (flags & P_BOOL)                 /* boolean */
                   1280:                {
                   1281:                    if (nextchar == '=' || nextchar == ':')
                   1282:                    {
                   1283:                        errmsg = e_invarg;
                   1284:                        goto skip;
                   1285:                    }
                   1286:
                   1287:                    /*
                   1288:                     * in secure mode, setting of the secure option is not
                   1289:                     * allowed
                   1290:                     */
                   1291:                    if (secure && (int *)varp == &p_secure)
                   1292:                    {
                   1293:                        errmsg = (char_u *)"not allowed here";
                   1294:                        goto skip;
                   1295:                    }
                   1296:
                   1297:                    oldbin = curbuf->b_p_bin;   /* remember old bin option */
                   1298:
                   1299:                    /*
                   1300:                     * ":set opt!" or ":set invopt": invert
                   1301:                     * ":set opt&": reset to default value
                   1302:                     * ":set opt" or ":set noopt": set or reset
                   1303:                     */
                   1304:                    if (prefix == 2 || nextchar == '!')
                   1305:                        *(int *)(varp) ^= 1;
                   1306:                    else if (nextchar == '&')
                   1307:                                /* the cast to long is required for Manx C */
                   1308:                        *(int *)(varp) = (int)(long)options[opt_idx].def_val;
                   1309:                    else
                   1310:                        *(int *)(varp) = prefix;
                   1311:
                   1312:                    /* handle the setting of the compatible option */
                   1313:                    if ((int *)varp == &p_cp && p_cp)
                   1314:                    {
                   1315:                        p_compatible_set();
                   1316:                    }
                   1317:                    /* when 'readonly' is reset, also reset readonlymode */
                   1318:                    else if ((int *)varp == &curbuf->b_p_ro && !curbuf->b_p_ro)
                   1319:                        readonlymode = FALSE;
                   1320:
                   1321:                    /* when 'bin' is set also set some other options */
                   1322:                    else if ((int *)varp == &curbuf->b_p_bin)
                   1323:                    {
                   1324:                        set_options_bin(oldbin, curbuf->b_p_bin);
                   1325:                    }
                   1326:                    /* when 'terse' is set change 'shortmess' */
                   1327:                    else if ((int *)varp == &p_terse)
                   1328:                    {
                   1329:                        char_u  *p;
                   1330:
                   1331:                        p = vim_strchr(p_shm, SHM_SEARCH);
                   1332:
                   1333:                        /* insert 's' in p_shm */
                   1334:                        if (p_terse && p == NULL)
                   1335:                        {
                   1336:                            STRCPY(IObuff, p_shm);
                   1337:                            STRCAT(IObuff, "s");
                   1338:                            set_string_option((char_u *)"shm", -1,
                   1339:                                                                IObuff, TRUE);
                   1340:                        }
                   1341:                        /* remove 's' from p_shm */
                   1342:                        else if (!p_terse && p != NULL)
                   1343:                            vim_memmove(p, p + 1, STRLEN(p));
                   1344:                    }
                   1345:                    /* when 'paste' is set or reset also change other options */
                   1346:                    else if ((int *)varp == &p_paste)
                   1347:                    {
                   1348:                        paste_option_changed();
                   1349:                    }
                   1350:                    /*
                   1351:                     * When 'lisp' option changes include/exclude '-' in
                   1352:                     * keyword characters.
                   1353:                     */
                   1354:                    else if (varp == (char_u *)&(curbuf->b_p_lisp))
                   1355:                        init_chartab();     /* ignore errors */
                   1356:
1.2       downsj   1357:                    else if (!starting &&
                   1358: #ifdef USE_GUI
                   1359:                                !gui.starting &&
                   1360: #endif
                   1361:                          ((int *)varp == &p_title || (int *)varp == &p_icon))
1.1       downsj   1362:                    {
                   1363:                        /*
                   1364:                         * When setting 'title' or 'icon' on, call maketitle()
                   1365:                         * to create and display it.
                   1366:                         * When resetting 'title' or 'icon', call maketitle()
                   1367:                         * to clear it and call mch_restore_title() to get the
                   1368:                         * old value back.
                   1369:                         */
                   1370:                        maketitle();
                   1371:                        if (!*(int *)varp)
                   1372:                            mch_restore_title((int *)varp == &p_title ? 1 : 2);
                   1373:                    }
                   1374:                }
                   1375:                else                                /* numeric or string */
                   1376:                {
                   1377:                    if (vim_strchr((char_u *)"=:&", nextchar) == NULL ||
                   1378:                                                                  prefix != 1)
                   1379:                    {
                   1380:                        errmsg = e_invarg;
                   1381:                        goto skip;
                   1382:                    }
                   1383:                    if (flags & P_NUM)              /* numeric */
                   1384:                    {
                   1385:                        /*
                   1386:                         * Different ways to set a number option:
                   1387:                         * &        set to default value
                   1388:                         * <xx>     accept special key codes for 'wildchar'
                   1389:                         * c        accept any non-digit for 'wildchar'
                   1390:                         * 0-9      set number
                   1391:                         * other    error
                   1392:                         */
                   1393:                        arg += len + 1;
                   1394:                        if (nextchar == '&')
                   1395:                            *(long *)(varp) = (long)options[opt_idx].def_val;
                   1396:                        else if ((long *)varp == &p_wc &&
                   1397:                                                (*arg == '<' || *arg == '^' ||
                   1398:                                          ((!arg[1] || vim_iswhite(arg[1])) &&
                   1399:                                                             !isdigit(*arg))))
                   1400:                        {
                   1401:                            if (*arg == '<')
                   1402:                            {
                   1403:                                i = get_special_key_code(arg + 1);
                   1404:                                if (i == 0)
                   1405:                                    i = find_key_option(arg + 1);
                   1406:                            }
                   1407:                            else if (*arg == '^')
                   1408:                                i = arg[1] ^ 0x40;
                   1409:                            else
                   1410:                                i = *arg;
                   1411:                            if (i == 0)
                   1412:                            {
                   1413:                                errmsg = e_invarg;
                   1414:                                goto skip;
                   1415:                            }
                   1416:                            p_wc = i;
                   1417:                        }
                   1418:                                /* allow negative numbers (for 'undolevels') */
                   1419:                        else if (*arg == '-' || isdigit(*arg))
                   1420:                        {
                   1421:                            i = 0;
                   1422:                            if (*arg == '-')
                   1423:                                i = 1;
                   1424: #ifdef HAVE_STRTOL
                   1425:                            *(long *)(varp) = strtol((char *)arg, NULL, 0);
                   1426:                            if (arg[i] == '0' && TO_UPPER(arg[i + 1]) == 'X')
                   1427:                                i += 2;
                   1428: #else
                   1429:                            *(long *)(varp) = atol((char *)arg);
                   1430: #endif
                   1431:                            while (isdigit(arg[i]))
                   1432:                                ++i;
                   1433:                            if (arg[i] != NUL && !vim_iswhite(arg[i]))
                   1434:                            {
                   1435:                                errmsg = e_invarg;
                   1436:                                goto skip;
                   1437:                            }
                   1438:                        }
                   1439:                        else
                   1440:                        {
                   1441:                            errmsg = (char_u *)"Number required after =";
                   1442:                            goto skip;
                   1443:                        }
                   1444:
                   1445:                        /*
                   1446:                         * Number options that need some action when changed
                   1447:                         */
                   1448:                        if ((long *)varp == &p_wh || (long *)varp == &p_hh)
                   1449:                        {
                   1450:                            if (p_wh < 0)
                   1451:                            {
                   1452:                                errmsg = e_positive;
                   1453:                                p_wh = 0;
                   1454:                            }
                   1455:                            if (p_hh < 0)
                   1456:                            {
                   1457:                                errmsg = e_positive;
                   1458:                                p_hh = 0;
                   1459:                            }
                   1460:                                /* Change window height NOW */
                   1461:                            if (p_wh && lastwin != firstwin)
                   1462:                            {
                   1463:                                win_equal(curwin, FALSE);
                   1464:                                must_redraw = CLEAR;
                   1465:                            }
                   1466:                        }
                   1467:                        /* (re)set last window status line */
                   1468:                        if ((long *)varp == &p_ls)
                   1469:                            last_status();
1.2       downsj   1470:                        if ((long *)varp == &p_titlelen && !starting)
                   1471:                            maketitle();
1.1       downsj   1472:                    }
                   1473:                    else if (opt_idx >= 0)                  /* string */
                   1474:                    {
                   1475:                        char_u      *save_arg = NULL;
                   1476:                        char_u      *s, *p;
                   1477:                        int         new_value_alloced;  /* new string option
                   1478:                                                           was allocated */
                   1479:
                   1480:                        /* The old value is kept until we are sure that the new
                   1481:                         * value is valid. set_option_default() is therefore
                   1482:                         * called with FALSE
                   1483:                         */
                   1484:                        oldval = *(char_u **)(varp);
                   1485:                        if (nextchar == '&')        /* set to default val */
                   1486:                        {
                   1487:                            set_option_default(opt_idx, FALSE);
                   1488:                            new_value_alloced =
                   1489:                                         (options[opt_idx].flags & P_ALLOCED);
                   1490:                        }
                   1491:                        else
                   1492:                        {
                   1493:                            arg += len + 1; /* jump to after the '=' or ':' */
                   1494:
                   1495:                            /*
                   1496:                             * Convert 'whichwrap' number to string, for
                   1497:                             * backwards compatibility with Vim 3.0.
                   1498:                             * Misuse errbuf[] for the resulting string.
                   1499:                             */
                   1500:                            if (varp == (char_u *)&p_ww && isdigit(*arg))
                   1501:                            {
                   1502:                                *errbuf = NUL;
                   1503:                                i = getdigits(&arg);
                   1504:                                if (i & 1)
                   1505:                                    STRCAT(errbuf, "b,");
                   1506:                                if (i & 2)
                   1507:                                    STRCAT(errbuf, "s,");
                   1508:                                if (i & 4)
                   1509:                                    STRCAT(errbuf, "h,l,");
                   1510:                                if (i & 8)
                   1511:                                    STRCAT(errbuf, "<,>,");
                   1512:                                if (i & 16)
                   1513:                                    STRCAT(errbuf, "[,],");
                   1514:                                if (*errbuf != NUL)     /* remove trailing , */
                   1515:                                    errbuf[STRLEN(errbuf) - 1] = NUL;
                   1516:                                save_arg = arg;
                   1517:                                arg = errbuf;
                   1518:                            }
                   1519:                            /*
                   1520:                             * Remove '>' before 'dir' and 'bdir', for
                   1521:                             * backwards compatibility with version 3.0
                   1522:                             */
                   1523:                            else if (*arg == '>' && (varp == (char_u *)&p_dir ||
                   1524:                                                   varp == (char_u *)&p_bdir))
                   1525:                            {
                   1526:                                ++arg;
                   1527:                            }
                   1528:
                   1529:                            /*
                   1530:                             * Copy the new string into allocated memory.
                   1531:                             * Can't use set_string_option(), because we need
                   1532:                             * to remove the backslashes.
                   1533:                             */
                   1534:                                                /* get a bit too much */
                   1535:                            s = alloc((unsigned)(STRLEN(arg) + 1));
                   1536:                            if (s == NULL)  /* out of memory, don't change */
                   1537:                                break;
                   1538:                            *(char_u **)(varp) = s;
                   1539:
                   1540:                            /*
                   1541:                             * Copy the string, skip over escaped chars.
                   1542:                             * For MS-DOS and WIN32 backslashes before normal
                   1543:                             * file name characters are not removed.
                   1544:                             */
                   1545:                            while (*arg && !vim_iswhite(*arg))
                   1546:                            {
                   1547:                                if (*arg == '\\' && arg[1] != NUL
                   1548: #ifdef BACKSLASH_IN_FILENAME
                   1549:                                        && !((flags & P_EXPAND)
                   1550:                                                && isfilechar(arg[1])
                   1551:                                                && arg[1] != '\\')
                   1552: #endif
                   1553:                                                                    )
                   1554:                                    ++arg;
                   1555:                                *s++ = *arg++;
                   1556:                            }
                   1557:                            *s = NUL;
                   1558:                            if (save_arg != NULL)   /* number for 'whichwrap' */
                   1559:                                arg = save_arg;
                   1560:                            new_value_alloced = TRUE;
                   1561:                        }
                   1562:
                   1563:                            /* expand environment variables and ~ */
                   1564:                        s = option_expand(opt_idx);
                   1565:                        if (s != NULL)
                   1566:                        {
                   1567:                            if (new_value_alloced)
                   1568:                                vim_free(*(char_u **)(varp));
                   1569:                            *(char_u **)(varp) = s;
                   1570:                            new_value_alloced = TRUE;
                   1571:                        }
                   1572:
                   1573:                        /*
                   1574:                         * options that need some action
                   1575:                         * to perform when changed (jw)
                   1576:                         */
                   1577:                        if (varp == (char_u *)&term_strings[KS_NAME])
                   1578:                        {
                   1579:                            if (term_strings[KS_NAME][0] == NUL)
                   1580:                                errmsg = (char_u *)"Cannot set 'term' to empty string";
                   1581: #ifdef USE_GUI
                   1582:                            if (gui.in_use)
                   1583:                                errmsg = (char_u *)"Cannot change term in GUI";
                   1584: #endif
                   1585:                            else if (set_termname(term_strings[KS_NAME]) ==
                   1586:                                                                         FAIL)
                   1587:                                errmsg = (char_u *)"Not found in termcap";
                   1588:                            else
                   1589:                            {
                   1590:                                /* Screen colors may have changed. */
                   1591:                                outstr(T_ME);
                   1592:                                updateScreen(CLEAR);
                   1593:                            }
                   1594:                        }
                   1595:
                   1596:                        else if ((varp == (char_u *)&p_bex ||
                   1597:                                                     varp == (char_u *)&p_pm))
                   1598:                        {
                   1599:                            if (STRCMP(*p_bex == '.' ? p_bex + 1 : p_bex,
                   1600:                                         *p_pm == '.' ? p_pm + 1 : p_pm) == 0)
                   1601:                                errmsg = (char_u *)"'backupext' and 'patchmode' are equal";
                   1602:                        }
                   1603:                        /*
                   1604:                         * 'isident', 'iskeyword', 'isprint or 'isfname'
                   1605:                         *  option: refill chartab[]
                   1606:                         * If the new option is invalid, use old value.
                   1607:                         * 'lisp' option: refill chartab[] for '-' char
                   1608:                         */
                   1609:                        else if (varp == (char_u *)&p_isi ||
                   1610:                                 varp == (char_u *)&(curbuf->b_p_isk) ||
                   1611:                                 varp == (char_u *)&p_isp ||
                   1612:                                 varp == (char_u *)&p_isf)
                   1613:                        {
                   1614:                            if (init_chartab() == FAIL)
                   1615:                                errmsg = e_invarg;      /* error in value */
                   1616:                        }
                   1617:                        else if (varp == (char_u *)&p_hl)
                   1618:                        {
                   1619:                            /* Check 'highlight' */
                   1620:                            for (s = p_hl; *s; )
                   1621:                            {
                   1622:                                if (vim_strchr((char_u *)"8dehmMnrstvw",
                   1623:                                                        (i = s[0])) == NULL ||
                   1624:                                    vim_strchr((char_u *)"bsnuir",
                   1625:                                                        (i = s[1])) == NULL ||
                   1626:                                              ((i = s[2]) != NUL && i != ','))
                   1627:                                {
                   1628:                                    illegal_char(errbuf, i);
                   1629:                                    errmsg = errbuf;
                   1630:                                    break;
                   1631:                                }
                   1632:                                if (s[2] == NUL)
                   1633:                                    break;
                   1634:                                s = skipwhite(s + 3);
                   1635:                            }
                   1636:                        }
                   1637:                        else if (varp == (char_u *)&(curbuf->b_p_com))
                   1638:                        {
                   1639:                            for (s = curbuf->b_p_com; *s; )
                   1640:                            {
                   1641:                                while (*s && *s != ':')
                   1642:                                {
                   1643:                                    if (vim_strchr((char_u *)COM_ALL, *s) == NULL)
                   1644:                                    {
                   1645:                                        errmsg = (char_u *)"Illegal flag";
                   1646:                                        break;
                   1647:                                    }
                   1648:                                    ++s;
                   1649:                                }
                   1650:                                if (*s++ == NUL)
                   1651:                                    errmsg = (char_u *)"Missing colon";
1.2       downsj   1652:                                else if (*s == ',' || *s == NUL)
1.1       downsj   1653:                                    errmsg = (char_u *)"Zero length string";
                   1654:                                if (errmsg != NULL)
                   1655:                                    break;
                   1656:                                while (*s && *s != ',')
                   1657:                                {
                   1658:                                    if (*s == '\\' && s[1] != NUL)
                   1659:                                        ++s;
                   1660:                                    ++s;
                   1661:                                }
                   1662:                                s = skip_to_option_part(s);
                   1663:                            }
                   1664:                        }
                   1665: #ifdef VIMINFO
                   1666:                        else if (varp == (char_u *)&(p_viminfo))
                   1667:                        {
                   1668:                            for (s = p_viminfo; *s;)
                   1669:                            {
                   1670:                                /* Check it's a valid character */
                   1671:                                if (vim_strchr((char_u *)"\"'fr:/", *s) == NULL)
                   1672:                                {
                   1673:                                    illegal_char(errbuf, *s);
                   1674:                                    errmsg = errbuf;
                   1675:                                    break;
                   1676:                                }
                   1677:                                if (*s == 'r')
                   1678:                                {
                   1679:                                    while (*++s && *s != ',')
                   1680:                                        ;
                   1681:                                }
                   1682:                                else
                   1683:                                {
                   1684:                                    while (isdigit(*++s))
                   1685:                                        ;
                   1686:
                   1687:                                    /* Must be a number after the character */
                   1688:                                    if (!isdigit(*(s - 1)))
                   1689:                                    {
                   1690:                                        sprintf((char *)errbuf,
                   1691:                                                "Missing number after <%s>",
                   1692:                                                transchar(*(s - 1)));
                   1693:                                        errmsg = errbuf;
                   1694:                                        break;
                   1695:                                    }
                   1696:                                }
                   1697:                                s = skip_to_option_part(s);
                   1698:                            }
                   1699:                            if (*p_viminfo && errmsg == NULL
                   1700:                                            && get_viminfo_parameter('\'') < 0)
                   1701:                                errmsg = (char_u *)"Must specify a ' value";
                   1702:                        }
                   1703: #endif /* VIMINFO */
                   1704:                        else if (istermoption(&options[opt_idx]) && full_screen)
                   1705:                        {
                   1706:                            ttest(FALSE);
                   1707:                            if (varp == (char_u *)&term_strings[KS_ME])
                   1708:                            {
                   1709:                                outstr(T_ME);
                   1710:                                updateScreen(CLEAR);
                   1711:                            }
                   1712:                        }
                   1713:                        else if (varp == (char_u *)&p_sbr)
                   1714:                        {
                   1715:                            for (s = p_sbr; *s; ++s)
                   1716:                                if (charsize(*s) != 1)
                   1717:                                    errmsg = (char_u *)"contains unprintable character";
                   1718:                        }
                   1719: #ifdef USE_GUI
                   1720:                        else if (varp == (char_u *)&p_guifont)
                   1721:                        {
                   1722:                            gui_init_font();
                   1723:                        }
                   1724: #endif /* USE_GUI */
                   1725: #ifdef HAVE_LANGMAP
                   1726:                        else if (varp == (char_u *)&p_langmap)
                   1727:                            langmap_set();
                   1728: #endif
                   1729:                        else if (varp == (char_u *)&p_breakat)
                   1730:                            fill_breakat_flags();
                   1731:                        else
                   1732:                        {
                   1733:                            /*
                   1734:                             * Check options that are a list of flags.
                   1735:                             */
                   1736:                            p = NULL;
                   1737:                            if (varp == (char_u *)&p_ww)
                   1738:                                p = (char_u *)WW_ALL;
                   1739:                            if (varp == (char_u *)&p_shm)
                   1740:                                p = (char_u *)SHM_ALL;
                   1741:                            else if (varp == (char_u *)&(p_cpo))
                   1742:                                p = (char_u *)CPO_ALL;
                   1743:                            else if (varp == (char_u *)&(curbuf->b_p_fo))
                   1744:                                p = (char_u *)FO_ALL;
                   1745:                            else if (varp == (char_u *)&p_mouse)
                   1746:                            {
                   1747: #ifdef USE_MOUSE
                   1748:                                p = (char_u *)MOUSE_ALL;
                   1749: #else
                   1750:                                if (*p_mouse != NUL)
                   1751:                                    errmsg = (char_u *)"No mouse support";
                   1752: #endif
                   1753:                            }
                   1754: #ifdef USE_GUI
                   1755:                            else if (varp == (char_u *)&p_guioptions)
                   1756:                                p = (char_u *)GO_ALL;
                   1757: #endif /* USE_GUI */
                   1758:                            if (p != NULL)
                   1759:                            {
                   1760:                                for (s = *(char_u **)(varp); *s; ++s)
                   1761:                                    if (vim_strchr(p, *s) == NULL)
                   1762:                                    {
                   1763:                                        illegal_char(errbuf, *s);
                   1764:                                        errmsg = errbuf;
                   1765:                                        break;
                   1766:                                    }
                   1767:                            }
                   1768:                        }
                   1769:                        if (errmsg != NULL) /* error detected */
                   1770:                        {
                   1771:                            if (new_value_alloced)
                   1772:                                vim_free(*(char_u **)(varp));
                   1773:                            *(char_u **)(varp) = oldval;
                   1774:                            (void)init_chartab();   /* back to the old value */
                   1775:                            goto skip;
                   1776:                        }
                   1777:
                   1778: #ifdef USE_GUI
                   1779:                        if (varp == (char_u *)&p_guioptions)
                   1780:                            gui_init_which_components(oldval);
                   1781: #endif /* USE_GUI */
                   1782:
                   1783:                        /*
                   1784:                         * Free string options that are in allocated memory.
                   1785:                         */
                   1786:                        if (flags & P_ALLOCED)
                   1787:                            free_string_option(oldval);
                   1788:                        if (new_value_alloced)
                   1789:                            options[opt_idx].flags |= P_ALLOCED;
                   1790:                    }
                   1791:                    else            /* key code option */
                   1792:                    {
                   1793:                        char_u      name[2];
                   1794:                        char_u      *p;
                   1795:
                   1796:                        name[0] = KEY2TERMCAP0(key);
                   1797:                        name[1] = KEY2TERMCAP1(key);
                   1798:                        if (nextchar == '&')
                   1799:                        {
                   1800:                            if (add_termcap_entry(name, TRUE) == FAIL)
                   1801:                                errmsg = (char_u *)"Not found in termcap";
                   1802:                        }
                   1803:                        else
                   1804:                        {
                   1805:                            arg += len + 1; /* jump to after the '=' or ':' */
                   1806:                            for(p = arg; *p && !vim_iswhite(*p); ++p)
                   1807:                            {
                   1808:                                if (*p == '\\' && *(p + 1))
                   1809:                                    ++p;
                   1810:                            }
                   1811:                            nextchar = *p;
                   1812:                            *p = NUL;
                   1813:                            add_termcode(name, arg);
                   1814:                            *p = nextchar;
                   1815:                        }
                   1816:                        if (full_screen)
                   1817:                            ttest(FALSE);
                   1818:                    }
                   1819:                }
                   1820:                if (opt_idx >= 0)
                   1821:                    options[opt_idx].flags |= P_WAS_SET;
                   1822:            }
                   1823:
                   1824: skip:
                   1825:            /*
                   1826:             * Check the bounds for numeric options here
                   1827:             */
                   1828:            if (Rows < min_rows() && full_screen)
                   1829:            {
                   1830:                sprintf((char *)errbuf, "Need at least %d lines", min_rows());
                   1831:                errmsg = errbuf;
                   1832:                Rows = min_rows();
                   1833:            }
                   1834:            if (Columns < MIN_COLUMNS && full_screen)
                   1835:            {
                   1836:                sprintf((char *)errbuf, "Need at least %d columns",
                   1837:                                                                 MIN_COLUMNS);
                   1838:                errmsg = errbuf;
                   1839:                Columns = MIN_COLUMNS;
                   1840:            }
                   1841:            /*
                   1842:             * If the screenheight has been changed, assume it is the physical
                   1843:             * screenheight.
                   1844:             */
                   1845:            if ((oldRows != Rows || oldColumns != Columns) && full_screen)
                   1846:            {
                   1847:                mch_set_winsize();          /* try to change the window size */
                   1848:                check_winsize();            /* in case 'columns' changed */
                   1849: #ifdef MSDOS
                   1850:                set_window();       /* active window may have changed */
                   1851: #endif
                   1852:            }
                   1853:
                   1854:            if (curbuf->b_p_ts <= 0)
                   1855:            {
                   1856:                errmsg = e_positive;
                   1857:                curbuf->b_p_ts = 8;
                   1858:            }
                   1859:            if (curbuf->b_p_tw < 0)
                   1860:            {
                   1861:                errmsg = e_positive;
                   1862:                curbuf->b_p_tw = 0;
                   1863:            }
                   1864:            if (p_tm < 0)
                   1865:            {
                   1866:                errmsg = e_positive;
                   1867:                p_tm = 0;
                   1868:            }
1.2       downsj   1869:            if (p_titlelen <= 0)
                   1870:            {
                   1871:                errmsg = e_positive;
                   1872:                p_titlelen = 85;
                   1873:            }
1.1       downsj   1874:            if ((curwin->w_p_scroll <= 0 ||
                   1875:                        curwin->w_p_scroll > curwin->w_height) && full_screen)
                   1876:            {
                   1877:                if (curwin->w_p_scroll != 0)
                   1878:                    errmsg = e_scroll;
                   1879:                win_comp_scroll(curwin);
                   1880:            }
                   1881:            if (p_report < 0)
                   1882:            {
                   1883:                errmsg = e_positive;
                   1884:                p_report = 1;
                   1885:            }
                   1886:            if ((p_sj < 0 || p_sj >= Rows) && full_screen)
                   1887:            {
                   1888:                if (Rows != oldRows)        /* Rows changed, just adjust p_sj */
                   1889:                    p_sj = Rows / 2;
                   1890:                else
                   1891:                {
                   1892:                    errmsg = e_scroll;
                   1893:                    p_sj = 1;
                   1894:                }
                   1895:            }
                   1896:            if (p_so < 0 && full_screen)
                   1897:            {
                   1898:                errmsg = e_scroll;
                   1899:                p_so = 0;
                   1900:            }
                   1901:            if (p_uc < 0)
                   1902:            {
                   1903:                errmsg = e_positive;
                   1904:                p_uc = 100;
                   1905:            }
                   1906:            if (p_ch < 1)
                   1907:            {
                   1908:                errmsg = e_positive;
                   1909:                p_ch = 1;
                   1910:            }
                   1911:            if (p_ut < 0)
                   1912:            {
                   1913:                errmsg = e_positive;
                   1914:                p_ut = 2000;
                   1915:            }
                   1916:            if (p_ss < 0)
                   1917:            {
                   1918:                errmsg = e_positive;
                   1919:                p_ss = 0;
                   1920:            }
                   1921:
                   1922:            /*
                   1923:             * Advance to next argument.
                   1924:             * - skip until a blank found, taking care of backslashes
                   1925:             * - skip blanks
                   1926:             */
                   1927:            while (*arg != NUL && !vim_iswhite(*arg))
                   1928:                if (*arg++ == '\\' && *arg != NUL)
                   1929:                    ++arg;
                   1930:        }
                   1931:        arg = skipwhite(arg);
                   1932:
                   1933:        if (errmsg)
                   1934:        {
                   1935:            ++no_wait_return;   /* wait_return done below */
                   1936: #ifdef SLEEP_IN_EMSG
                   1937:            ++dont_sleep;       /* don't wait in emsg() */
                   1938: #endif
                   1939:            emsg(errmsg);       /* show error highlighted */
                   1940: #ifdef SLEEP_IN_EMSG
                   1941:            --dont_sleep;
                   1942: #endif
                   1943:            MSG_OUTSTR(": ");
                   1944:                                /* show argument normal */
                   1945:            while (startarg < arg)
                   1946:                msg_outstr(transchar(*startarg++));
                   1947:            msg_end();          /* check for scrolling */
                   1948:            --no_wait_return;
                   1949:
                   1950:            ++errcnt;           /* count number of errors */
                   1951:            did_show = TRUE;    /* error message counts as show */
                   1952:            if (sourcing_name != NULL)
                   1953:                break;
                   1954:        }
                   1955:    }
                   1956:
                   1957:    /*
                   1958:     * when 'updatecount' changes from zero to non-zero, open swap files
                   1959:     */
                   1960:    if (p_uc && !olduc)
                   1961:        ml_open_files();
                   1962:
                   1963:    if (p_ch != oldch)              /* p_ch changed value */
                   1964:        command_height();
                   1965: #ifdef USE_MOUSE
                   1966:    if (*p_mouse == NUL)
                   1967:        mch_setmouse(FALSE);        /* switch mouse off */
                   1968:    else
                   1969:        setmouse();                 /* in case 'mouse' changed */
                   1970: #endif
                   1971:    comp_col();                     /* in case 'ruler' or 'showcmd' changed */
                   1972:    curwin->w_set_curswant = TRUE;  /* in case 'list' changed */
                   1973:
                   1974:    /*
                   1975:     * Update the screen in case we changed something like "tabstop" or
                   1976:     * "lines" or "list" that will change its appearance.
                   1977:     * Also update the cursor position, in case 'wrap' is changed.
                   1978:     */
                   1979:    for (wp = firstwin; wp; wp = wp->w_next)
                   1980:        wp->w_redr_status = TRUE;       /* mark all status lines dirty */
                   1981:    if (p_ea && !oldea)
                   1982:        win_equal(curwin, FALSE);
                   1983:    updateScreen(CURSUPD);
                   1984:    return (errcnt == 0 ? OK : FAIL);
                   1985: }
                   1986:
                   1987:    static void
                   1988: illegal_char(errbuf, c)
                   1989:    char_u      *errbuf;
                   1990:    int         c;
                   1991: {
                   1992:    sprintf((char *)errbuf, "Illegal character <%s>", (char *)transchar(c));
                   1993: }
                   1994:
                   1995: /*
                   1996:  * set_options_bin -  called when 'bin' changes value.
                   1997:  */
                   1998:    void
                   1999: set_options_bin(oldval, newval)
                   2000:    int     oldval;
                   2001:    int     newval;
                   2002: {
                   2003:    /*
                   2004:     * The option values that are changed when 'bin' changes are
                   2005:     * copied when 'bin is set and restored when 'bin' is reset.
                   2006:     */
                   2007:    if (newval)
                   2008:    {
                   2009:        if (!oldval)            /* switched on */
                   2010:        {
                   2011:            curbuf->b_p_tw_nobin = curbuf->b_p_tw;
                   2012:            curbuf->b_p_wm_nobin = curbuf->b_p_wm;
                   2013:            curbuf->b_p_tx_nobin = curbuf->b_p_tx;
                   2014:            curbuf->b_p_ta_nobin = p_ta;
                   2015:            curbuf->b_p_ml_nobin = curbuf->b_p_ml;
                   2016:            curbuf->b_p_et_nobin = curbuf->b_p_et;
                   2017:        }
                   2018:
                   2019:        curbuf->b_p_tw = 0;     /* no automatic line wrap */
                   2020:        curbuf->b_p_wm = 0;     /* no automatic line wrap */
                   2021:        curbuf->b_p_tx = 0;     /* no text mode */
                   2022:        p_ta           = 0;     /* no text auto */
                   2023:        curbuf->b_p_ml = 0;     /* no modelines */
                   2024:        curbuf->b_p_et = 0;     /* no expandtab */
                   2025:    }
                   2026:    else if (oldval)            /* switched off */
                   2027:    {
                   2028:        curbuf->b_p_tw = curbuf->b_p_tw_nobin;
                   2029:        curbuf->b_p_wm = curbuf->b_p_wm_nobin;
                   2030:        curbuf->b_p_tx = curbuf->b_p_tx_nobin;
                   2031:        p_ta           = curbuf->b_p_ta_nobin;
                   2032:        curbuf->b_p_ml = curbuf->b_p_ml_nobin;
                   2033:        curbuf->b_p_et = curbuf->b_p_et_nobin;
                   2034:    }
                   2035: }
                   2036:
                   2037: #ifdef VIMINFO
                   2038: /*
                   2039:  * Find the parameter represented by the given character (eg ', :, ", or /),
                   2040:  * and return its associated value in the 'viminfo' string.  If the parameter
                   2041:  * is not specified in the string, return -1.
                   2042:  */
                   2043:    int
                   2044: get_viminfo_parameter(type)
                   2045:    int     type;
                   2046: {
                   2047:    char_u  *p;
                   2048:
                   2049:    p = vim_strchr(p_viminfo, type);
                   2050:    if (p != NULL && isdigit(*++p))
                   2051:        return (int)atol((char *)p);
                   2052:    return -1;
                   2053: }
                   2054: #endif
                   2055:
                   2056: /*
                   2057:  * Expand environment variables for some string options.
                   2058:  * These string options cannot be indirect!
                   2059:  * Return pointer to allocated memory, or NULL when not expanded.
                   2060:  */
                   2061:    static char_u *
                   2062: option_expand(opt_idx)
                   2063:    int     opt_idx;
                   2064: {
                   2065:    char_u      *p;
                   2066:
                   2067:        /* if option doesn't need expansion or is hidden: nothing to do */
                   2068:    if (!(options[opt_idx].flags & P_EXPAND) || options[opt_idx].var == NULL)
                   2069:        return NULL;
                   2070:
                   2071:    p = *(char_u **)(options[opt_idx].var);
                   2072:
                   2073:    /*
                   2074:     * Expanding this with NameBuff, expand_env() must not be passed IObuff.
                   2075:     */
                   2076:    expand_env(p, NameBuff, MAXPATHL);
                   2077:    if (STRCMP(NameBuff, p) == 0)   /* they are the same */
                   2078:        return NULL;
                   2079:
                   2080:    return strsave(NameBuff);
                   2081: }
                   2082:
                   2083: /*
                   2084:  * Check for string options that are NULL (normally only termcap options).
                   2085:  */
                   2086:    void
                   2087: check_options()
                   2088: {
                   2089:    int     opt_idx;
                   2090:    char_u  **p;
                   2091:
                   2092:    for (opt_idx = 0; options[opt_idx].fullname != NULL; opt_idx++)
                   2093:        if ((options[opt_idx].flags & P_STRING) && options[opt_idx].var != NULL)
                   2094:        {
                   2095:            p = (char_u **)get_varp(&(options[opt_idx]));
                   2096:            if (*p == NULL)
                   2097:                *p = empty_option;
                   2098:        }
                   2099: }
                   2100:
                   2101: /*
                   2102:  * Check string options in a buffer for NULL value.
                   2103:  */
                   2104:    void
                   2105: check_buf_options(buf)
                   2106:    BUF     *buf;
                   2107: {
                   2108:    if (buf->b_p_fo == NULL)
                   2109:        buf->b_p_fo = empty_option;
                   2110:    if (buf->b_p_isk == NULL)
                   2111:        buf->b_p_isk = empty_option;
                   2112:    if (buf->b_p_com == NULL)
                   2113:        buf->b_p_com = empty_option;
                   2114: #ifdef CINDENT
                   2115:    if (buf->b_p_cink == NULL)
                   2116:        buf->b_p_cink = empty_option;
                   2117:    if (buf->b_p_cino == NULL)
                   2118:        buf->b_p_cino = empty_option;
                   2119: #endif
                   2120: #if defined(SMARTINDENT) || defined(CINDENT)
                   2121:    if (buf->b_p_cinw == NULL)
                   2122:        buf->b_p_cinw = empty_option;
                   2123: #endif
                   2124: }
                   2125:
                   2126: /*
                   2127:  * Free the string allocated for an option.
                   2128:  * Checks for the string being empty_option. This may happen if we're out of
                   2129:  * memory, strsave() returned NULL, which was replaced by empty_option by
                   2130:  * check_options().
                   2131:  * Does NOT check for P_ALLOCED flag!
                   2132:  */
                   2133:    void
                   2134: free_string_option(p)
                   2135:    char_u      *p;
                   2136: {
                   2137:    if (p != empty_option)
                   2138:        vim_free(p);
                   2139: }
                   2140:
                   2141: /*
                   2142:  * Set a string option to a new value.
                   2143:  * The string is copied into allocated memory.
                   2144:  * If 'dofree' is set, the old value may be freed.
                   2145:  * if (opt_idx == -1) name is used, otherwise opt_idx is used.
                   2146:  */
                   2147:    void
                   2148: set_string_option(name, opt_idx, val, dofree)
                   2149:    char_u  *name;
                   2150:    int     opt_idx;
                   2151:    char_u  *val;
                   2152:    int     dofree;
                   2153: {
                   2154:    char_u  *s;
                   2155:    char_u  **varp;
                   2156:
                   2157:    if (opt_idx == -1)          /* use name */
                   2158:    {
                   2159:        opt_idx = findoption(name);
                   2160:        if (opt_idx == -1)      /* not found (should not happen) */
                   2161:            return;
                   2162:    }
                   2163:
                   2164:    if (options[opt_idx].var == NULL)   /* don't set hidden option */
                   2165:        return;
                   2166:
                   2167:    s = strsave(val);
                   2168:    if (s != NULL)
                   2169:    {
                   2170:        varp = (char_u **)get_varp(&(options[opt_idx]));
                   2171:        if (dofree && (options[opt_idx].flags & P_ALLOCED))
                   2172:            free_string_option(*varp);
                   2173:        *varp = s;
                   2174:            /* if 'term' option set for the first time: set default value */
                   2175:        if (varp == &(term_strings[KS_NAME]) &&
                   2176:                                           *(options[opt_idx].def_val) == NUL)
                   2177:        {
                   2178:            options[opt_idx].def_val = s;
                   2179:            options[opt_idx].flags |= P_DEF_ALLOCED;
                   2180:        }
                   2181:        else
                   2182:            options[opt_idx].flags |= P_ALLOCED;
                   2183:    }
                   2184: }
                   2185:
                   2186: /*
                   2187:  * find index for option 'arg'
                   2188:  * return -1 if not found
                   2189:  */
                   2190:    static int
                   2191: findoption(arg)
                   2192:    char_u *arg;
                   2193: {
                   2194:    int     opt_idx;
                   2195:    char    *s;
                   2196:
                   2197:    for (opt_idx = 0; (s = options[opt_idx].fullname) != NULL; opt_idx++)
                   2198:    {
                   2199:        if (STRCMP(arg, s) == 0) /* match full name */
                   2200:            break;
                   2201:    }
                   2202:    if (s == NULL)
                   2203:    {
                   2204:        for (opt_idx = 0; options[opt_idx].fullname != NULL; opt_idx++)
                   2205:        {
                   2206:            s = options[opt_idx].shortname;
                   2207:            if (s != NULL && STRCMP(arg, s) == 0) /* match short name */
                   2208:                break;
                   2209:            s = NULL;
                   2210:        }
                   2211:    }
                   2212:    if (s == NULL)
                   2213:        opt_idx = -1;
                   2214:    return opt_idx;
                   2215: }
                   2216:
                   2217:    char_u *
                   2218: get_highlight_default()
                   2219: {
                   2220:    int i;
                   2221:
                   2222:    i = findoption((char_u *)"hl");
                   2223:    if (i >= 0)
                   2224:        return options[i].def_val;
                   2225:    return (char_u *)NULL;
                   2226: }
                   2227:
                   2228:    static int
                   2229: find_key_option(arg)
                   2230:    char_u *arg;
                   2231: {
                   2232:    int         key;
                   2233:    int         c;
                   2234:
                   2235:    /* don't use get_special_key_code() for t_xx, we don't want it to call
                   2236:     * add_termcap_entry() */
                   2237:    if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
                   2238:        key = TERMCAP2KEY(arg[2], arg[3]);
                   2239:
                   2240:    /* <S-Tab> is a special case, because TAB isn't a special key */
                   2241:    else if (vim_strnicmp(arg, (char_u *)"S-Tab", (size_t)5) == 0)
                   2242:        key = K_S_TAB;
                   2243:    else
                   2244:    {
                   2245:        /* Currently only the shift modifier is recognized */
                   2246:        mod_mask = 0;
                   2247:        if (TO_LOWER(arg[0]) == 's' && arg[1] == '-')
                   2248:        {
                   2249:            mod_mask = MOD_MASK_SHIFT;
                   2250:            arg += 2;
                   2251:        }
                   2252:        c = get_special_key_code(arg);
                   2253:        key = check_shifted_spec_key(c);
                   2254:        if (mod_mask && c == key)           /* key can't be shifted */
                   2255:            key = 0;
                   2256:    }
                   2257:    return key;
                   2258: }
                   2259:
                   2260: /*
                   2261:  * if 'all' == 0: show changed options
                   2262:  * if 'all' == 1: show all normal options
                   2263:  * if 'all' == 2: show all terminal options
                   2264:  */
                   2265:    static void
                   2266: showoptions(all)
                   2267:    int         all;
                   2268: {
                   2269:    struct option   *p;
                   2270:    int             col;
                   2271:    int             isterm;
                   2272:    char_u          *varp;
                   2273:    struct option   **items;
                   2274:    int             item_count;
                   2275:    int             run;
                   2276:    int             row, rows;
                   2277:    int             cols;
                   2278:    int             i;
                   2279:    int             len;
                   2280:
                   2281: #define INC    20
                   2282: #define GAP 3
                   2283:
                   2284:    items = (struct option **)alloc((unsigned)(sizeof(struct option *) *
                   2285:                                                                PARAM_COUNT));
                   2286:    if (items == NULL)
                   2287:        return;
                   2288:
                   2289:    set_highlight('t');     /* Highlight title */
                   2290:    start_highlight();
                   2291:    if (all == 2)
                   2292:        MSG_OUTSTR("\n--- Terminal codes ---");
                   2293:    else
                   2294:        MSG_OUTSTR("\n--- Options ---");
                   2295:    stop_highlight();
                   2296:
                   2297:    /*
                   2298:     * do the loop two times:
                   2299:     * 1. display the short items
                   2300:     * 2. display the long items (only strings and numbers)
                   2301:     */
                   2302:    for (run = 1; run <= 2 && !got_int; ++run)
                   2303:    {
                   2304:        /*
                   2305:         * collect the items in items[]
                   2306:         */
                   2307:        item_count = 0;
                   2308:        for (p = &options[0]; p->fullname != NULL; p++)
                   2309:        {
                   2310:            isterm = istermoption(p);
                   2311:            varp = get_varp(p);
                   2312:            if (varp != NULL && (
                   2313:                (all == 2 && isterm) ||
                   2314:                (all == 1 && !isterm) ||
                   2315:                (all == 0 && option_changed(p))))
                   2316:            {
                   2317:                if (p->flags & P_BOOL)
                   2318:                    len = 1;            /* a toggle option fits always */
                   2319:                else
                   2320:                {
                   2321:                    option_value2string(p);
                   2322:                    len = STRLEN(p->fullname) + strsize(NameBuff) + 1;
                   2323:                }
                   2324:                if ((len <= INC - GAP && run == 1) ||
                   2325:                                                (len > INC - GAP && run == 2))
                   2326:                    items[item_count++] = p;
                   2327:            }
                   2328:        }
                   2329:
                   2330:        /*
                   2331:         * display the items
                   2332:         */
                   2333:        if (run == 1)
                   2334:        {
                   2335:            cols = (Columns + GAP - 3) / INC;
                   2336:            if (cols == 0)
                   2337:                cols = 1;
                   2338:            rows = (item_count + cols - 1) / cols;
                   2339:        }
                   2340:        else    /* run == 2 */
                   2341:            rows = item_count;
                   2342:        for (row = 0; row < rows && !got_int; ++row)
                   2343:        {
                   2344:            msg_outchar('\n');                      /* go to next line */
                   2345:            if (got_int)                            /* 'q' typed in more */
                   2346:                break;
                   2347:            col = 0;
                   2348:            for (i = row; i < item_count; i += rows)
                   2349:            {
                   2350:                msg_pos(-1, col);                   /* make columns */
                   2351:                showoneopt(items[i]);
                   2352:                col += INC;
                   2353:            }
                   2354:            flushbuf();
                   2355:            mch_breakcheck();
                   2356:        }
                   2357:    }
                   2358:    vim_free(items);
                   2359: }
                   2360:
                   2361: /*
                   2362:  * Return TRUE if option is different from the default value
                   2363:  */
                   2364:    static int
                   2365: option_changed(p)
                   2366:    struct option   *p;
                   2367: {
                   2368:    char_u  *varp;
                   2369:
                   2370:    varp = get_varp(p);
                   2371:    if (varp == NULL)
                   2372:        return FALSE;   /* hidden option is never changed */
                   2373:
                   2374:    if (p->flags & P_NUM)
                   2375:        return (*(long *)varp != (long)p->def_val);
                   2376:    if (p->flags & P_BOOL)
                   2377:                        /* the cast to long is required for Manx C */
                   2378:        return (*(int *)varp != (int)(long)p->def_val);
                   2379:    /* P_STRING */
                   2380:    return STRCMP(*(char_u **)varp, p->def_val);
                   2381: }
                   2382:
                   2383: /*
                   2384:  * showoneopt: show the value of one option
                   2385:  * must not be called with a hidden option!
                   2386:  */
                   2387:    static void
                   2388: showoneopt(p)
                   2389:    struct option *p;
                   2390: {
                   2391:    char_u          *varp;
                   2392:
                   2393:    varp = get_varp(p);
                   2394:
                   2395:    if ((p->flags & P_BOOL) && !*(int *)varp)
                   2396:        MSG_OUTSTR("no");
                   2397:    else
                   2398:        MSG_OUTSTR("  ");
                   2399:    MSG_OUTSTR(p->fullname);
                   2400:    if (!(p->flags & P_BOOL))
                   2401:    {
                   2402:        msg_outchar('=');
                   2403:        option_value2string(p);     /* put string of option value in NameBuff */
                   2404:        msg_outtrans(NameBuff);
                   2405:    }
                   2406: }
                   2407:
                   2408: /*
                   2409:  * Write modified options as set command to a file.
                   2410:  * Return FAIL on error, OK otherwise.
                   2411:  */
                   2412:    int
                   2413: makeset(fd)
                   2414:    FILE *fd;
                   2415: {
                   2416:    struct option   *p;
                   2417:    char_u          *s;
                   2418:    int             e;
                   2419:    char_u          *varp;
                   2420:
                   2421:    /*
                   2422:     * The options that don't have a default (terminal name, columns, lines)
                   2423:     * are never written. Terminal options are also not written.
                   2424:     */
                   2425:    for (p = &options[0]; !istermoption(p); p++)
                   2426:        if (!(p->flags & P_NO_MKRC) && !istermoption(p) &&
                   2427:                                                          (option_changed(p)))
                   2428:        {
                   2429:            varp = get_varp(p);
                   2430:            if (p->flags & P_BOOL)
                   2431:                fprintf(fd, "set %s%s", *(int *)(varp) ? "" : "no",
                   2432:                                                                 p->fullname);
                   2433:            else if (p->flags & P_NUM)
                   2434:                fprintf(fd, "set %s=%ld", p->fullname, *(long *)(varp));
                   2435:            else    /* P_STRING */
                   2436:            {
                   2437:                fprintf(fd, "set %s=", p->fullname);
                   2438:                s = *(char_u **)(varp);
                   2439:                /* some characters have to be escaped with CTRL-V or
                   2440:                 * backslash */
                   2441:                if (s != NULL && putescstr(fd, s, TRUE) == FAIL)
                   2442:                    return FAIL;
                   2443:            }
                   2444: #ifdef USE_CRNL
                   2445:            putc('\r', fd);
                   2446: #endif
                   2447:                /*
                   2448:                 * Only check error for this putc, should catch at least
                   2449:                 * the "disk full" situation.
                   2450:                 */
                   2451:            e = putc('\n', fd);
                   2452:            if (e < 0)
                   2453:                return FAIL;
                   2454:        }
                   2455:    return OK;
                   2456: }
                   2457:
                   2458: /*
                   2459:  * Clear all the terminal options.
                   2460:  * If the option has been allocated, free the memory.
                   2461:  * Terminal options are never hidden or indirect.
                   2462:  */
                   2463:    void
                   2464: clear_termoptions()
                   2465: {
                   2466:    struct option   *p;
                   2467:
                   2468:    /*
                   2469:     * Reset a few things before clearing the old options. This may cause
                   2470:     * outputting a few things that the terminal doesn't understand, but the
                   2471:     * screen will be cleared later, so this is OK.
                   2472:     */
                   2473: #ifdef USE_MOUSE
                   2474:    mch_setmouse(FALSE);            /* switch mouse off */
                   2475: #endif
                   2476:    mch_restore_title(3);           /* restore window titles */
                   2477: #ifdef WIN32
                   2478:    /*
                   2479:     * Check if this is allowed now.
                   2480:     */
                   2481:    if (can_end_termcap_mode(FALSE) == TRUE)
                   2482: #endif
                   2483:        stoptermcap();                  /* stop termcap mode */
                   2484:
                   2485:    for (p = &options[0]; p->fullname != NULL; p++)
                   2486:        if (istermoption(p))
                   2487:        {
                   2488:            if (p->flags & P_ALLOCED)
                   2489:                free_string_option(*(char_u **)(p->var));
                   2490:            if (p->flags & P_DEF_ALLOCED)
                   2491:                free_string_option(p->def_val);
                   2492:            *(char_u **)(p->var) = empty_option;
                   2493:            p->def_val = empty_option;
                   2494:            p->flags &= ~(P_ALLOCED|P_DEF_ALLOCED);
                   2495:        }
                   2496:    clear_termcodes();
                   2497: }
                   2498:
                   2499: /*
                   2500:  * Set the terminal option defaults to the current value.
                   2501:  * Used after setting the terminal name.
                   2502:  */
                   2503:    void
                   2504: set_term_defaults()
                   2505: {
                   2506:    struct option   *p;
                   2507:
                   2508:    for (p = &options[0]; p->fullname != NULL; p++)
                   2509:        if (istermoption(p) && p->def_val != *(char_u **)(p->var))
                   2510:        {
                   2511:            if (p->flags & P_DEF_ALLOCED)
                   2512:            {
                   2513:                free_string_option(p->def_val);
                   2514:                p->flags &= ~P_DEF_ALLOCED;
                   2515:            }
                   2516:            p->def_val = *(char_u **)(p->var);
                   2517:            if (p->flags & P_ALLOCED)
                   2518:            {
                   2519:                p->flags |= P_DEF_ALLOCED;
                   2520:                p->flags &= ~P_ALLOCED;     /* don't free the value now */
                   2521:            }
                   2522:        }
                   2523: }
                   2524:
                   2525: /*
                   2526:  * return TRUE if 'p' starts with 't_'
                   2527:  */
                   2528:    static int
                   2529: istermoption(p)
                   2530:    struct option *p;
                   2531: {
                   2532:    return (p->fullname[0] == 't' && p->fullname[1] == '_');
                   2533: }
                   2534:
                   2535: /*
                   2536:  * Compute columns for ruler and shown command. 'sc_col' is also used to
                   2537:  * decide what the maximum length of a message on the status line can be.
                   2538:  * If there is a status line for the last window, 'sc_col' is independent
                   2539:  * of 'ru_col'.
                   2540:  */
                   2541:
                   2542: #define COL_RULER 17       /* columns needed by ruler */
                   2543:
                   2544:    void
                   2545: comp_col()
                   2546: {
                   2547:    int last_has_status = (p_ls == 2 || (p_ls == 1 && firstwin != lastwin));
                   2548:
                   2549:    sc_col = 0;
                   2550:    ru_col = 0;
                   2551:    if (p_ru)
                   2552:    {
                   2553:        ru_col = COL_RULER + 1;
                   2554:                            /* no last status line, adjust sc_col */
                   2555:        if (!last_has_status)
                   2556:            sc_col = ru_col;
                   2557:    }
                   2558:    if (p_sc)
                   2559:    {
                   2560:        sc_col += SHOWCMD_COLS;
                   2561:        if (!p_ru || last_has_status)       /* no need for separating space */
                   2562:            ++sc_col;
                   2563:    }
                   2564:    sc_col = Columns - sc_col;
                   2565:    ru_col = Columns - ru_col;
                   2566:    if (sc_col <= 0)            /* screen too narrow, will become a mess */
                   2567:        sc_col = 1;
                   2568:    if (ru_col <= 0)
                   2569:        ru_col = 1;
                   2570: }
                   2571:
                   2572:    static char_u *
                   2573: get_varp(p)
                   2574:    struct option   *p;
                   2575: {
                   2576:    if (!(p->flags & P_IND) || p->var == NULL)
                   2577:        return p->var;
                   2578:
                   2579:    switch ((long)(p->var))
                   2580:    {
                   2581:        case PV_LIST:   return (char_u *)&(curwin->w_p_list);
                   2582:        case PV_NU:     return (char_u *)&(curwin->w_p_nu);
                   2583: #ifdef RIGHTLEFT
                   2584:        case PV_RL:     return (char_u *)&(curwin->w_p_rl);
                   2585: #endif
                   2586:        case PV_SCROLL: return (char_u *)&(curwin->w_p_scroll);
                   2587:        case PV_WRAP:   return (char_u *)&(curwin->w_p_wrap);
                   2588:        case PV_LBR:    return (char_u *)&(curwin->w_p_lbr);
                   2589:
                   2590:        case PV_AI:     return (char_u *)&(curbuf->b_p_ai);
                   2591:        case PV_BIN:    return (char_u *)&(curbuf->b_p_bin);
                   2592: #ifdef CINDENT
                   2593:        case PV_CIN:    return (char_u *)&(curbuf->b_p_cin);
                   2594:        case PV_CINK:   return (char_u *)&(curbuf->b_p_cink);
                   2595:        case PV_CINO:   return (char_u *)&(curbuf->b_p_cino);
                   2596: #endif
                   2597: #if defined(SMARTINDENT) || defined(CINDENT)
                   2598:        case PV_CINW:   return (char_u *)&(curbuf->b_p_cinw);
                   2599: #endif
                   2600:        case PV_COM:    return (char_u *)&(curbuf->b_p_com);
                   2601:        case PV_EOL:    return (char_u *)&(curbuf->b_p_eol);
                   2602:        case PV_ET:     return (char_u *)&(curbuf->b_p_et);
                   2603:        case PV_FO:     return (char_u *)&(curbuf->b_p_fo);
                   2604:        case PV_INF:    return (char_u *)&(curbuf->b_p_inf);
                   2605:        case PV_ISK:    return (char_u *)&(curbuf->b_p_isk);
                   2606:        case PV_LISP:   return (char_u *)&(curbuf->b_p_lisp);
                   2607:        case PV_ML:     return (char_u *)&(curbuf->b_p_ml);
                   2608:        case PV_MOD:    return (char_u *)&(curbuf->b_changed);
                   2609:        case PV_RO:     return (char_u *)&(curbuf->b_p_ro);
                   2610: #ifdef SMARTINDENT
                   2611:        case PV_SI:     return (char_u *)&(curbuf->b_p_si);
                   2612: #endif
                   2613: #ifndef SHORT_FNAME
                   2614:        case PV_SN:     return (char_u *)&(curbuf->b_p_sn);
                   2615: #endif
                   2616:        case PV_SW:     return (char_u *)&(curbuf->b_p_sw);
                   2617:        case PV_TS:     return (char_u *)&(curbuf->b_p_ts);
                   2618:        case PV_TW:     return (char_u *)&(curbuf->b_p_tw);
                   2619:        case PV_TX:     return (char_u *)&(curbuf->b_p_tx);
                   2620:        case PV_WM:     return (char_u *)&(curbuf->b_p_wm);
                   2621:        default:        EMSG("get_varp ERROR");
                   2622:    }
                   2623:    /* always return a valid pointer to avoid a crash! */
                   2624:    return (char_u *)&(curbuf->b_p_wm);
                   2625: }
                   2626:
                   2627: /*
                   2628:  * Copy options from one window to another.
                   2629:  * Used when creating a new window.
                   2630:  * The 'scroll' option is not copied, because it depends on the window height.
                   2631:  */
                   2632:    void
                   2633: win_copy_options(wp_from, wp_to)
                   2634:    WIN     *wp_from;
                   2635:    WIN     *wp_to;
                   2636: {
                   2637:    wp_to->w_p_list = wp_from->w_p_list;
                   2638:    wp_to->w_p_nu = wp_from->w_p_nu;
                   2639: #ifdef RIGHTLEFT
                   2640:    wp_to->w_p_rl = wp_from->w_p_rl;
                   2641: #endif
                   2642:    wp_to->w_p_wrap = wp_from->w_p_wrap;
                   2643:    wp_to->w_p_lbr = wp_from->w_p_lbr;
                   2644: }
                   2645:
                   2646: /*
                   2647:  * Copy options from one buffer to another.
1.2       downsj   2648:  * Used when creating a new buffer and sometimes when entering a buffer.
1.1       downsj   2649:  * When "entering" is TRUE we will enter the bp_to buffer.
1.2       downsj   2650:  * When "always" is TRUE, always copy the options, but only set
                   2651:  * b_p_initialized when appropriate.
1.1       downsj   2652:  */
                   2653:    void
1.2       downsj   2654: buf_copy_options(bp_from, bp_to, entering, always)
1.1       downsj   2655:    BUF     *bp_from;
                   2656:    BUF     *bp_to;
                   2657:    int     entering;
1.2       downsj   2658:    int     always;
1.1       downsj   2659: {
1.2       downsj   2660:    int     should_copy = TRUE;
                   2661:
1.1       downsj   2662:    /*
1.2       downsj   2663:     * Don't do anything of the "to" buffer is invalid.
1.1       downsj   2664:     */
1.2       downsj   2665:    if (bp_to == NULL || !buf_valid(bp_to))
1.1       downsj   2666:        return;
                   2667:
                   2668:    /*
1.2       downsj   2669:     * Only copy if the "from" buffer is valid and "to" and "from" are
                   2670:     * different.
                   2671:     */
                   2672:    if (bp_from != NULL && buf_valid(bp_from) && bp_from != bp_to)
1.1       downsj   2673:    {
1.2       downsj   2674:        /*
                   2675:         * Always copy when entering and 'cpo' contains 'S'.
                   2676:         * Don't copy when already initialized.
                   2677:         * Don't copy when 'cpo' contains 's' and not entering.
                   2678:         * 'S'  entering  initialized   's'  should_copy
                   2679:         * yes    yes          X         X      TRUE
                   2680:         * yes    no          yes        X      FALSE
                   2681:         * no      X          yes        X      FALSE
                   2682:         *  X     no          no        yes     FALSE
                   2683:         *  X     no          no        no      TRUE
                   2684:         * no     yes         no         X      TRUE
                   2685:         */
                   2686:        if ((vim_strchr(p_cpo, CPO_BUFOPTGLOB) == NULL || !entering) &&
                   2687:                (bp_to->b_p_initialized ||
                   2688:                 (!entering && vim_strchr(p_cpo, CPO_BUFOPT) != NULL)))
                   2689:            should_copy = FALSE;
1.1       downsj   2690:
1.2       downsj   2691:        if (should_copy || always)
                   2692:        {
                   2693:            /*
                   2694:             * Always free the allocated strings.
                   2695:             * If not already initialized, set 'readonly' and copy 'textmode'.
                   2696:             */
                   2697:            free_buf_options(bp_to);
                   2698:            if (!bp_to->b_p_initialized)
                   2699:            {
                   2700:                bp_to->b_p_ro = FALSE;              /* don't copy readonly */
                   2701:                bp_to->b_p_tx = bp_from->b_p_tx;
                   2702:                bp_to->b_p_tx_nobin = bp_from->b_p_tx_nobin;
                   2703:            }
                   2704:
                   2705:            bp_to->b_p_ai = bp_from->b_p_ai;
                   2706:            bp_to->b_p_ai_save = bp_from->b_p_ai_save;
                   2707:            bp_to->b_p_sw = bp_from->b_p_sw;
                   2708:            bp_to->b_p_tw = bp_from->b_p_tw;
                   2709:            bp_to->b_p_tw_save = bp_from->b_p_tw_save;
                   2710:            bp_to->b_p_tw_nobin = bp_from->b_p_tw_nobin;
                   2711:            bp_to->b_p_wm = bp_from->b_p_wm;
                   2712:            bp_to->b_p_wm_save = bp_from->b_p_wm_save;
                   2713:            bp_to->b_p_wm_nobin = bp_from->b_p_wm_nobin;
                   2714:            bp_to->b_p_bin = bp_from->b_p_bin;
                   2715:            bp_to->b_p_et = bp_from->b_p_et;
                   2716:            bp_to->b_p_et_nobin = bp_from->b_p_et_nobin;
                   2717:            bp_to->b_p_ml = bp_from->b_p_ml;
                   2718:            bp_to->b_p_ml_nobin = bp_from->b_p_ml_nobin;
                   2719:            bp_to->b_p_inf = bp_from->b_p_inf;
1.1       downsj   2720: #ifndef SHORT_FNAME
1.2       downsj   2721:            bp_to->b_p_sn = bp_from->b_p_sn;
1.1       downsj   2722: #endif
1.2       downsj   2723:            bp_to->b_p_com = strsave(bp_from->b_p_com);
                   2724:            bp_to->b_p_fo = strsave(bp_from->b_p_fo);
1.1       downsj   2725: #ifdef SMARTINDENT
1.2       downsj   2726:            bp_to->b_p_si = bp_from->b_p_si;
                   2727:            bp_to->b_p_si_save = bp_from->b_p_si_save;
1.1       downsj   2728: #endif
                   2729: #ifdef CINDENT
1.2       downsj   2730:            bp_to->b_p_cin = bp_from->b_p_cin;
                   2731:            bp_to->b_p_cin_save = bp_from->b_p_cin_save;
                   2732:            bp_to->b_p_cink = strsave(bp_from->b_p_cink);
                   2733:            bp_to->b_p_cino = strsave(bp_from->b_p_cino);
1.1       downsj   2734: #endif
                   2735: #if defined(SMARTINDENT) || defined(CINDENT)
1.2       downsj   2736:            bp_to->b_p_cinw = strsave(bp_from->b_p_cinw);
1.1       downsj   2737: #endif
                   2738: #ifdef LISPINDENT
1.2       downsj   2739:            bp_to->b_p_lisp = bp_from->b_p_lisp;
                   2740:            bp_to->b_p_lisp_save = bp_from->b_p_lisp_save;
1.1       downsj   2741: #endif
1.2       downsj   2742:            bp_to->b_p_ta_nobin = bp_from->b_p_ta_nobin;
                   2743:
                   2744:            /*
                   2745:             * Don't copy the options set by do_help(), use the saved values
                   2746:             */
                   2747:            if (!keep_help_flag && bp_from->b_help && help_save_isk != NULL)
                   2748:            {
                   2749:                bp_to->b_p_isk = strsave(help_save_isk);
                   2750:                if (bp_to->b_p_isk != NULL)
                   2751:                    init_chartab();
                   2752:                bp_to->b_p_ts = help_save_ts;
                   2753:                bp_to->b_help = FALSE;
                   2754:            }
                   2755:            else
                   2756:            {
                   2757:                bp_to->b_p_isk = strsave(bp_from->b_p_isk);
                   2758:                vim_memmove(bp_to->b_chartab, bp_from->b_chartab, (size_t)256);
                   2759:                bp_to->b_p_ts = bp_from->b_p_ts;
                   2760:                bp_to->b_help = bp_from->b_help;
                   2761:            }
                   2762:        }
1.1       downsj   2763:
1.2       downsj   2764:        /*
                   2765:         * When the options should be copied (ignoring "always"), set the flag
                   2766:         * that indicates that the options have been initialized.
                   2767:         */
                   2768:        if (should_copy)
                   2769:            bp_to->b_p_initialized = TRUE;
1.1       downsj   2770:    }
                   2771:
1.2       downsj   2772:    check_buf_options(bp_to);       /* make sure we don't have NULLs */
1.1       downsj   2773: }
                   2774:
1.2       downsj   2775:
1.1       downsj   2776: static int expand_option_idx = -1;
                   2777: static char_u expand_option_name[5] = {'t', '_', NUL, NUL, NUL};
                   2778:
                   2779:    void
                   2780: set_context_in_set_cmd(arg)
                   2781:    char_u *arg;
                   2782: {
                   2783:    int         nextchar;
                   2784:    int         flags = 0;      /* init for GCC */
                   2785:    int         opt_idx = 0;    /* init for GCC */
                   2786:    char_u      *p;
                   2787:    char_u      *after_blank = NULL;
                   2788:    int         is_term_option = FALSE;
                   2789:    int         key;
                   2790:
                   2791:    expand_context = EXPAND_SETTINGS;
                   2792:    if (*arg == NUL)
                   2793:    {
                   2794:        expand_pattern = arg;
                   2795:        return;
                   2796:    }
                   2797:    p = arg + STRLEN(arg) - 1;
                   2798:    if (*p == ' ' && *(p - 1) != '\\')
                   2799:    {
                   2800:        expand_pattern = p + 1;
                   2801:        return;
                   2802:    }
                   2803:    while (p != arg && (*p != ' ' || *(p - 1) == '\\'))
                   2804:    {
                   2805:        /* remember possible start of file name to expand */
                   2806:        if ((*p == ' ' || (*p == ',' && *(p - 1) != '\\')) &&
                   2807:                                                          after_blank == NULL)
                   2808:            after_blank = p + 1;
                   2809:        p--;
                   2810:    }
                   2811:    if (p != arg)
                   2812:        p++;
                   2813:    if (STRNCMP(p, "no", (size_t) 2) == 0)
                   2814:    {
                   2815:        expand_context = EXPAND_BOOL_SETTINGS;
                   2816:        p += 2;
                   2817:    }
                   2818:    if (STRNCMP(p, "inv", (size_t) 3) == 0)
                   2819:    {
                   2820:        expand_context = EXPAND_BOOL_SETTINGS;
                   2821:        p += 3;
                   2822:    }
                   2823:    expand_pattern = arg = p;
                   2824:    if (*arg == '<')
                   2825:    {
                   2826:        while (*p != '>')
                   2827:            if (*p++ == NUL)        /* expand terminal option name */
                   2828:                return;
                   2829:        key = get_special_key_code(arg + 1);
                   2830:        if (key == 0)               /* unknown name */
                   2831:        {
                   2832:            expand_context = EXPAND_NOTHING;
                   2833:            return;
                   2834:        }
                   2835:        nextchar = *++p;
                   2836:        is_term_option = TRUE;
                   2837:        expand_option_name[2] = KEY2TERMCAP0(key);
                   2838:        expand_option_name[3] = KEY2TERMCAP1(key);
                   2839:    }
                   2840:    else
                   2841:    {
                   2842:        if (p[0] == 't' && p[1] == '_')
                   2843:        {
                   2844:            p += 2;
                   2845:            if (*p != NUL)
                   2846:                ++p;
                   2847:            if (*p == NUL)
                   2848:                return;         /* expand option name */
                   2849:            nextchar = *++p;
                   2850:            is_term_option = TRUE;
                   2851:            expand_option_name[2] = p[-2];
                   2852:            expand_option_name[3] = p[-1];
                   2853:        }
                   2854:        else
                   2855:        {
                   2856:            while (isalnum(*p) || *p == '_' || *p == '*')   /* Allow * wildcard */
                   2857:                p++;
                   2858:            if (*p == NUL)
                   2859:                return;
                   2860:            nextchar = *p;
                   2861:            *p = NUL;
                   2862:            opt_idx = findoption(arg);
                   2863:            *p = nextchar;
                   2864:            if (opt_idx == -1 || options[opt_idx].var == NULL)
                   2865:            {
                   2866:                expand_context = EXPAND_NOTHING;
                   2867:                return;
                   2868:            }
                   2869:            flags = options[opt_idx].flags;
                   2870:            if (flags & P_BOOL)
                   2871:            {
                   2872:                expand_context = EXPAND_NOTHING;
                   2873:                return;
                   2874:            }
                   2875:        }
                   2876:    }
                   2877:    if ((nextchar != '=' && nextchar != ':')
                   2878:                                    || expand_context == EXPAND_BOOL_SETTINGS)
                   2879:    {
                   2880:        expand_context = EXPAND_UNSUCCESSFUL;
                   2881:        return;
                   2882:    }
                   2883:    if (expand_context != EXPAND_BOOL_SETTINGS && p[1] == NUL)
                   2884:    {
                   2885:        expand_context = EXPAND_OLD_SETTING;
                   2886:        if (is_term_option)
                   2887:            expand_option_idx = -1;
                   2888:        else
                   2889:            expand_option_idx = opt_idx;
                   2890:        expand_pattern = p + 1;
                   2891:        return;
                   2892:    }
                   2893:    expand_context = EXPAND_NOTHING;
                   2894:    if (is_term_option || (flags & P_NUM))
                   2895:        return;
                   2896:    if (after_blank != NULL)
                   2897:        expand_pattern = after_blank;
                   2898:    else
                   2899:        expand_pattern = p + 1;
                   2900:    if (flags & P_EXPAND)
                   2901:    {
                   2902:        p = options[opt_idx].var;
                   2903:        if (p == (char_u *)&p_bdir || p == (char_u *)&p_dir ||
                   2904:                                                       p == (char_u *)&p_path)
                   2905:            expand_context = EXPAND_DIRECTORIES;
                   2906:        else
                   2907:            expand_context = EXPAND_FILES;
                   2908:    }
                   2909:    return;
                   2910: }
                   2911:
                   2912:    int
                   2913: ExpandSettings(prog, num_file, file)
                   2914:    regexp      *prog;
                   2915:    int         *num_file;
                   2916:    char_u      ***file;
                   2917: {
                   2918:    int num_normal = 0;     /* Number of matching non-term-code settings */
                   2919:    int num_term = 0;       /* Number of matching terminal code settings */
                   2920:    int opt_idx;
                   2921:    int match;
                   2922:    int count = 0;
                   2923:    char_u *str;
                   2924:    int loop;
                   2925:    int is_term_opt;
                   2926:    char_u  name_buf[MAX_KEY_NAME_LEN];
1.2       downsj   2927:    int save_reg_ic;
1.1       downsj   2928:
                   2929:    /* do this loop twice:
                   2930:     * loop == 0: count the number of matching options
                   2931:     * loop == 1: copy the matching options into allocated memory
                   2932:     */
                   2933:    for (loop = 0; loop <= 1; ++loop)
                   2934:    {
                   2935:        if (expand_context != EXPAND_BOOL_SETTINGS)
                   2936:        {
                   2937:            if (vim_regexec(prog, (char_u *)"all", TRUE))
                   2938:            {
                   2939:                if (loop == 0)
                   2940:                    num_normal++;
                   2941:                else
                   2942:                    (*file)[count++] = strsave((char_u *)"all");
                   2943:            }
                   2944:            if (vim_regexec(prog, (char_u *)"termcap", TRUE))
                   2945:            {
                   2946:                if (loop == 0)
                   2947:                    num_normal++;
                   2948:                else
                   2949:                    (*file)[count++] = strsave((char_u *)"termcap");
                   2950:            }
                   2951:        }
                   2952:        for (opt_idx = 0; (str = (char_u *)options[opt_idx].fullname) != NULL;
                   2953:                                                                    opt_idx++)
                   2954:        {
                   2955:            if (options[opt_idx].var == NULL)
                   2956:                continue;
                   2957:            if (expand_context == EXPAND_BOOL_SETTINGS
                   2958:              && !(options[opt_idx].flags & P_BOOL))
                   2959:                continue;
                   2960:            is_term_opt = istermoption(&options[opt_idx]);
                   2961:            if (is_term_opt && num_normal > 0)
                   2962:                continue;
                   2963:            match = FALSE;
                   2964:            if (vim_regexec(prog, str, TRUE) ||
                   2965:                                        (options[opt_idx].shortname != NULL &&
                   2966:                         vim_regexec(prog,
                   2967:                                 (char_u *)options[opt_idx].shortname, TRUE)))
                   2968:                match = TRUE;
                   2969:            else if (is_term_opt)
                   2970:            {
                   2971:                name_buf[0] = '<';
                   2972:                name_buf[1] = 't';
                   2973:                name_buf[2] = '_';
                   2974:                name_buf[3] = str[2];
                   2975:                name_buf[4] = str[3];
                   2976:                name_buf[5] = '>';
                   2977:                name_buf[6] = NUL;
                   2978:                if (vim_regexec(prog, name_buf, TRUE))
                   2979:                {
                   2980:                    match = TRUE;
                   2981:                    str = name_buf;
                   2982:                }
                   2983:            }
                   2984:            if (match)
                   2985:            {
                   2986:                if (loop == 0)
                   2987:                {
                   2988:                    if (is_term_opt)
                   2989:                        num_term++;
                   2990:                    else
                   2991:                        num_normal++;
                   2992:                }
                   2993:                else
                   2994:                    (*file)[count++] = strsave(str);
                   2995:            }
                   2996:        }
                   2997:        /*
                   2998:         * Check terminal key codes, these are not in the option table
                   2999:         */
                   3000:        if (expand_context != EXPAND_BOOL_SETTINGS  && num_normal == 0)
                   3001:        {
                   3002:            for (opt_idx = 0; (str = get_termcode(opt_idx)) != NULL; opt_idx++)
                   3003:            {
                   3004:                if (!isprint(str[0]) || !isprint(str[1]))
                   3005:                    continue;
                   3006:
                   3007:                name_buf[0] = 't';
                   3008:                name_buf[1] = '_';
                   3009:                name_buf[2] = str[0];
                   3010:                name_buf[3] = str[1];
                   3011:                name_buf[4] = NUL;
                   3012:
                   3013:                match = FALSE;
                   3014:                if (vim_regexec(prog, name_buf, TRUE))
                   3015:                    match = TRUE;
                   3016:                else
                   3017:                {
                   3018:                    name_buf[0] = '<';
                   3019:                    name_buf[1] = 't';
                   3020:                    name_buf[2] = '_';
                   3021:                    name_buf[3] = str[0];
                   3022:                    name_buf[4] = str[1];
                   3023:                    name_buf[5] = '>';
                   3024:                    name_buf[6] = NUL;
                   3025:
                   3026:                    if (vim_regexec(prog, name_buf, TRUE))
                   3027:                        match = TRUE;
                   3028:                }
                   3029:                if (match)
                   3030:                {
                   3031:                    if (loop == 0)
                   3032:                        num_term++;
                   3033:                    else
                   3034:                        (*file)[count++] = strsave(name_buf);
                   3035:                }
                   3036:            }
                   3037:            /*
                   3038:             * Check special key names.
                   3039:             */
                   3040:            for (opt_idx = 0; (str = get_key_name(opt_idx)) != NULL; opt_idx++)
                   3041:            {
                   3042:                name_buf[0] = '<';
                   3043:                STRCPY(name_buf + 1, str);
                   3044:                STRCAT(name_buf, ">");
                   3045:
1.2       downsj   3046:                save_reg_ic = reg_ic;
1.1       downsj   3047:                reg_ic = TRUE;                  /* ignore case here */
                   3048:                if (vim_regexec(prog, name_buf, TRUE))
                   3049:                {
                   3050:                    if (loop == 0)
                   3051:                        num_term++;
                   3052:                    else
                   3053:                        (*file)[count++] = strsave(name_buf);
                   3054:                }
1.2       downsj   3055:                reg_ic = save_reg_ic;
1.1       downsj   3056:            }
                   3057:        }
                   3058:        if (loop == 0)
                   3059:        {
                   3060:            if (num_normal > 0)
                   3061:                *num_file = num_normal;
                   3062:            else if (num_term > 0)
                   3063:                *num_file = num_term;
                   3064:            else
                   3065:                return OK;
                   3066:            *file = (char_u **) alloc((unsigned)(*num_file * sizeof(char_u *)));
                   3067:            if (*file == NULL)
                   3068:            {
                   3069:                *file = (char_u **)"";
                   3070:                return FAIL;
                   3071:            }
                   3072:        }
                   3073:    }
                   3074:    return OK;
                   3075: }
                   3076:
                   3077:    int
                   3078: ExpandOldSetting(num_file, file)
                   3079:    int     *num_file;
                   3080:    char_u  ***file;
                   3081: {
                   3082:    char_u  *var = NULL;        /* init for GCC */
                   3083:    char_u  *buf;
                   3084:
                   3085:    *num_file = 0;
                   3086:    *file = (char_u **)alloc((unsigned)sizeof(char_u *));
                   3087:    if (*file == NULL)
                   3088:        return FAIL;
                   3089:
                   3090:    /*
                   3091:     * For a terminal key code epand_option_idx is < 0.
                   3092:     */
                   3093:    if (expand_option_idx < 0)
                   3094:    {
                   3095:        var = find_termcode(expand_option_name + 2);
                   3096:        if (var == NULL)
                   3097:            expand_option_idx = findoption(expand_option_name);
                   3098:    }
                   3099:
                   3100:    if (expand_option_idx >= 0)
                   3101:    {
                   3102:        /* put string of option value in NameBuff */
                   3103:        option_value2string(&options[expand_option_idx]);
                   3104:        var = NameBuff;
                   3105:    }
                   3106:    else if (var == NULL)
                   3107:        var = (char_u *)"";
                   3108:
                   3109:    /* A backslash is required before some characters */
                   3110:    buf = strsave_escaped(var, escape_chars);
                   3111:
                   3112:    if (buf == NULL)
                   3113:    {
                   3114:        vim_free(*file);
                   3115:        *file = NULL;
                   3116:        return FAIL;
                   3117:    }
                   3118:
                   3119:    *file[0] = buf;
                   3120:    *num_file = 1;
                   3121:    return OK;
                   3122: }
                   3123:
                   3124: /*
                   3125:  * Get the value for the numeric or string option *op in a nice format into
                   3126:  * NameBuff[].  Must not be called with a hidden option!
                   3127:  */
                   3128:    static void
                   3129: option_value2string(op)
                   3130:    struct option   *op;
                   3131: {
                   3132:    char_u  *varp;
                   3133:
                   3134:    varp = get_varp(op);
                   3135:    if (op->flags & P_NUM)
                   3136:    {
                   3137:        if ((long *)varp == &p_wc)
                   3138:        {
                   3139:            if (IS_SPECIAL(p_wc) || find_special_key_in_table((int)p_wc) >= 0)
                   3140:                STRCPY(NameBuff, get_special_key_name((int)p_wc, 0));
                   3141:            else
                   3142:                STRCPY(NameBuff, transchar((int)p_wc));
                   3143:        }
                   3144:        else
                   3145:            sprintf((char *)NameBuff, "%ld", *(long *)varp);
                   3146:    }
                   3147:    else    /* P_STRING */
                   3148:    {
                   3149:        varp = *(char_u **)(varp);
                   3150:        if (varp == NULL)                   /* just in case */
                   3151:            NameBuff[0] = NUL;
                   3152:        else if (op->flags & P_EXPAND)
                   3153:            home_replace(NULL, varp, NameBuff, MAXPATHL);
                   3154:        else
                   3155:            STRNCPY(NameBuff, varp, MAXPATHL);
                   3156:    }
                   3157: }
                   3158:
                   3159: /*
                   3160:  * Convert the given pattern "pat" which has shell style wildcards in it, into
                   3161:  * a regular expression, and return the result.  If there is a directory path
                   3162:  * separator to be matched, then TRUE is put in allow_directories, otherwise
                   3163:  * FALSE is put there -- webb.
                   3164:  */
                   3165:    char_u *
                   3166: file_pat_to_reg_pat(pat, pat_end, allow_directories)
                   3167:    char_u  *pat;
                   3168:    char_u  *pat_end;               /* first char after pattern */
                   3169:    int     *allow_directories;     /* Result passed back out in here */
                   3170: {
                   3171:    int     size;
                   3172:    char_u  *endp;
                   3173:    char_u  *reg_pat;
                   3174:    char_u  *p;
                   3175:    int     i;
                   3176:    int     nested = 0;
                   3177:    int     add_dollar = TRUE;
                   3178:
                   3179:    if (allow_directories != NULL)
                   3180:        *allow_directories = FALSE;
                   3181:
                   3182:    size = 2;               /* '^' at start, '$' at end */
                   3183:    for (p = pat; p < pat_end; p++)
                   3184:    {
                   3185:        switch (*p)
                   3186:        {
                   3187:            case '*':
                   3188:            case '.':
                   3189:            case ',':
                   3190:            case '{':
                   3191:            case '}':
                   3192:            case '~':
                   3193: #ifdef BACKSLASH_IN_FILENAME
                   3194:            case '\\':
                   3195: #endif
                   3196:                size += 2;
                   3197:                break;
                   3198:            default:
                   3199:                size++;
                   3200:                break;
                   3201:        }
                   3202:    }
                   3203:    reg_pat = alloc(size + 1);
                   3204:    if (reg_pat == NULL)
                   3205:        return NULL;
                   3206:    i = 0;
                   3207:    if (pat[0] == '*')
                   3208:        while (pat[0] == '*' && pat < pat_end - 1)
                   3209:            pat++;
                   3210:    else
                   3211:        reg_pat[i++] = '^';
                   3212:    endp = pat_end - 1;
                   3213:    if (*endp == '*')
                   3214:    {
                   3215:        while (endp - pat > 0 && *endp == '*')
                   3216:            endp--;
                   3217:        add_dollar = FALSE;
                   3218:    }
                   3219:    for (p = pat; *p && nested >= 0 && p <= endp; p++)
                   3220:    {
                   3221:        switch (*p)
                   3222:        {
                   3223:            case '*':
                   3224:                reg_pat[i++] = '.';
                   3225:                reg_pat[i++] = '*';
                   3226:                break;
                   3227:            case '.':
                   3228:            case '~':
                   3229:                reg_pat[i++] = '\\';
                   3230:                reg_pat[i++] = *p;
                   3231:                break;
                   3232:            case '?':
                   3233:                reg_pat[i++] = '.';
                   3234:                break;
                   3235:            case '\\':
                   3236:                if (p[1] == NUL)
                   3237:                    break;
                   3238: #ifdef BACKSLASH_IN_FILENAME
                   3239:                /* translate "\x" to "\\x", "\*" to "\\.*", and "\?" to "\\." */
                   3240:                if (isfilechar(p[1]) || p[1] == '*' || p[1] == '?')
                   3241:                {
                   3242:                    reg_pat[i++] = '\\';
                   3243:                    reg_pat[i++] = '\\';
                   3244:                    if (allow_directories != NULL)
                   3245:                        *allow_directories = TRUE;
                   3246:                    break;
                   3247:                }
                   3248:                ++p;
                   3249: #else
                   3250:                if (*++p == '?')
                   3251:                    reg_pat[i++] = '?';
                   3252:                else
                   3253: #endif
                   3254:                     if (*p == ',')
                   3255:                    reg_pat[i++] = ',';
                   3256:                else
                   3257:                {
                   3258:                    if (allow_directories != NULL && ispathsep(*p))
                   3259:                        *allow_directories = TRUE;
                   3260:                    reg_pat[i++] = '\\';
                   3261:                    reg_pat[i++] = *p;
                   3262:                }
                   3263:                break;
                   3264:            case '{':
                   3265:                reg_pat[i++] = '\\';
                   3266:                reg_pat[i++] = '(';
                   3267:                nested++;
                   3268:                break;
                   3269:            case '}':
                   3270:                reg_pat[i++] = '\\';
                   3271:                reg_pat[i++] = ')';
                   3272:                --nested;
                   3273:                break;
                   3274:            case ',':
                   3275:                if (nested)
                   3276:                {
                   3277:                    reg_pat[i++] = '\\';
                   3278:                    reg_pat[i++] = '|';
                   3279:                }
                   3280:                else
                   3281:                    reg_pat[i++] = ',';
                   3282:                break;
                   3283:            default:
                   3284:                if (allow_directories != NULL && ispathsep(*p))
                   3285:                    *allow_directories = TRUE;
                   3286:                reg_pat[i++] = *p;
                   3287:                break;
                   3288:        }
                   3289:    }
                   3290:    if (add_dollar)
                   3291:        reg_pat[i++] = '$';
                   3292:    reg_pat[i] = NUL;
                   3293:    if (nested != 0)
                   3294:    {
                   3295:        if (nested < 0)
                   3296:            EMSG("Missing {.");
                   3297:        else
                   3298:            EMSG("Missing }.");
                   3299:        vim_free(reg_pat);
                   3300:        reg_pat = NULL;
                   3301:    }
                   3302:    return reg_pat;
                   3303: }
                   3304:
                   3305: #ifdef AUTOCMD
                   3306: /*
                   3307:  * functions for automatic commands
                   3308:  */
                   3309:
                   3310: static void show_autocmd __ARGS((AutoPat *ap, int event));
                   3311: static void del_autocmd __ARGS((AutoPat *ap));
                   3312: static void del_autocmd_cmds __ARGS((AutoPat *ap));
                   3313: static int event_name2nr __ARGS((char_u *start, char_u **end));
                   3314: static char *event_nr2name __ARGS((int event));
                   3315: static char_u *find_end_event __ARGS((char_u *arg));
                   3316: static int do_autocmd_event __ARGS((int event, char_u *pat,
1.2       downsj   3317:                                                   char_u *cmd, int forceit));
1.1       downsj   3318:
                   3319:    static void
                   3320: show_autocmd(ap, event)
                   3321:    AutoPat *ap;
                   3322:    int     event;
                   3323: {
                   3324:    AutoCmd *ac;
                   3325:
                   3326:    if (got_int)                /* "q" hit for "--more--" */
                   3327:        return;
                   3328:    msg_outchar('\n');
                   3329:    if (got_int)                /* "q" hit for "--more--" */
                   3330:        return;
                   3331:    msg_outchar('\n');
                   3332:    if (got_int)                /* "q" hit for "--more--" */
                   3333:        return;
                   3334:    MSG_OUTSTR(event_nr2name(event));
                   3335:    MSG_OUTSTR("  ");
                   3336:    msg_outstr(ap->pat);
                   3337:    for (ac = ap->cmds; ac != NULL; ac = ac->next)
                   3338:    {
                   3339:        MSG_OUTSTR("\n    ");
                   3340:        if (got_int)            /* hit "q" at "--more--" prompt */
                   3341:            return;
                   3342:        msg_outtrans(ac->cmd);
                   3343:    }
                   3344: }
                   3345:
                   3346: /*
                   3347:  * Delete an autocommand pattern.
                   3348:  */
                   3349:    static void
                   3350: del_autocmd(ap)
                   3351:    AutoPat *ap;
                   3352: {
                   3353:    vim_free(ap->pat);
                   3354:    vim_free(ap->reg_pat);
                   3355:    del_autocmd_cmds(ap);
                   3356:    vim_free(ap);
                   3357: }
                   3358:
                   3359: /*
                   3360:  * Delete the commands from a pattern.
                   3361:  */
                   3362:    static void
                   3363: del_autocmd_cmds(ap)
                   3364:    AutoPat *ap;
                   3365: {
                   3366:    AutoCmd *ac;
                   3367:
                   3368:    while (ap->cmds != NULL)
                   3369:    {
                   3370:        ac = ap->cmds;
                   3371:        ap->cmds = ac->next;
                   3372:        vim_free(ac->cmd);
                   3373:        vim_free(ac);
                   3374:    }
                   3375: }
                   3376:
                   3377: /*
                   3378:  * Return the event number for event name "start".
                   3379:  * Return -1 if the event name was not found.
                   3380:  * Return a pointer to the next event name in "end".
                   3381:  */
                   3382:    static int
                   3383: event_name2nr(start, end)
                   3384:    char_u  *start;
                   3385:    char_u  **end;
                   3386: {
                   3387:    char_u      *p;
                   3388:    int         i;
                   3389:    int         len;
                   3390:
                   3391:    /* the event name ends with end of line, a blank or a comma */
                   3392:    for (p = start; *p && !vim_iswhite(*p) && *p != ','; ++p)
                   3393:        ;
                   3394:    for (i = 0; event_names[i].name != NULL; ++i)
                   3395:    {
                   3396:        len = strlen(event_names[i].name);
                   3397:        if (len == p - start &&
                   3398:                   vim_strnicmp((char_u *)event_names[i].name, (char_u *)start, (size_t)len) == 0)
                   3399:            break;
                   3400:    }
                   3401:    if (*p == ',')
                   3402:        ++p;
                   3403:    *end = p;
                   3404:    if (event_names[i].name == NULL)
                   3405:        return -1;
                   3406:    return event_names[i].event;
                   3407: }
                   3408:
                   3409: /*
                   3410:  * Return the name for event "event".
                   3411:  */
                   3412:    static char *
                   3413: event_nr2name(event)
                   3414:    int     event;
                   3415: {
                   3416:    int     i;
                   3417:
                   3418:    for (i = 0; event_names[i].name != NULL; ++i)
                   3419:        if (event_names[i].event == event)
                   3420:            return event_names[i].name;
                   3421:    return "Unknown";
                   3422: }
                   3423:
                   3424: /*
                   3425:  * Scan over the events.  "*" stands for all events.
                   3426:  */
                   3427:    static char_u *
                   3428: find_end_event(arg)
                   3429:    char_u  *arg;
                   3430: {
                   3431:    char_u  *pat;
                   3432:    char_u  *p;
                   3433:
                   3434:    if (*arg == '*')
                   3435:    {
                   3436:        if (arg[1] && !vim_iswhite(arg[1]))
                   3437:        {
                   3438:            EMSG2("Illegal character after *: %s", arg);
                   3439:            return NULL;
                   3440:        }
                   3441:        pat = arg + 1;
                   3442:    }
                   3443:    else
                   3444:    {
                   3445:        for (pat = arg; *pat && !vim_iswhite(*pat); pat = p)
                   3446:        {
                   3447:            if (event_name2nr(pat, &p) < 0)
                   3448:            {
                   3449:                EMSG2("No such event: %s", pat);
                   3450:                return NULL;
                   3451:            }
                   3452:        }
                   3453:    }
                   3454:    return pat;
                   3455: }
                   3456:
                   3457: /*
                   3458:  * do_autocmd() -- implements the :autocmd command.  Can be used in the
                   3459:  * following ways:
                   3460:  *
                   3461:  * :autocmd <event> <pat> <cmd>        Add <cmd> to the list of commands that
                   3462:  *                                 will be automatically executed for <event>
                   3463:  *                                 when editing a file matching <pat>.
                   3464:  * :autocmd <event> <pat>          Show the auto-commands associated with
                   3465:  *                                 <event> and <pat>.
                   3466:  * :autocmd    <event>                 Show the auto-commands associated with
                   3467:  *                                 <event>.
                   3468:  * :autocmd                            Show all auto-commands.
                   3469:  * :autocmd! <event> <pat> <cmd>   Remove all auto-commands associated with
                   3470:  *                                 <event> and <pat>, and add the command
                   3471:  *                                 <cmd>.
                   3472:  * :autocmd! <event> <pat>         Remove all auto-commands associated with
                   3473:  *                                 <event> and <pat>.
                   3474:  * :autocmd! <event>               Remove all auto-commands associated with
                   3475:  *                                 <event>.
                   3476:  * :autocmd!                       Remove ALL auto-commands.
                   3477:  *
                   3478:  * Multiple events and patterns may be given separated by commas.  Here are
                   3479:  * some examples:
                   3480:  * :autocmd bufread,bufenter *.c,*.h   set tw=0 smartindent noic
                   3481:  * :autocmd bufleave        *          set tw=79 nosmartindent ic infercase
                   3482:  *
                   3483:  * :autocmd * *.c              show all autocommands for *.c files.
                   3484:  */
                   3485:    void
1.2       downsj   3486: do_autocmd(arg, forceit)
1.1       downsj   3487:    char_u  *arg;
1.2       downsj   3488:    int     forceit;
1.1       downsj   3489: {
                   3490:    char_u  *pat;
                   3491:    char_u  *cmd;
                   3492:    int     event;
                   3493:
                   3494:    /*
                   3495:     * Don't change autocommands while executing one.
                   3496:     */
                   3497:    if (autocmd_busy)
                   3498:        return;
                   3499:
                   3500:    /*
                   3501:     * Scan over the events.
                   3502:     * If we find an illegal name, return here, don't do anything.
                   3503:     */
                   3504:    pat = find_end_event(arg);
                   3505:    if (pat == NULL)
                   3506:        return;
                   3507:
                   3508:    /*
                   3509:     * Scan over the pattern.  Put a NUL at the end.
                   3510:     */
                   3511:    pat = skipwhite(pat);
                   3512:    cmd = pat;
                   3513:    while (*cmd && (!vim_iswhite(*cmd) || cmd[-1] == '\\'))
                   3514:        cmd++;
                   3515:    if (*cmd)
                   3516:        *cmd++ = NUL;
                   3517:
                   3518:    /*
                   3519:     * Find the start of the commands.
                   3520:     */
                   3521:    cmd = skipwhite(cmd);
                   3522:
                   3523:    /*
                   3524:     * Print header when showing autocommands.
                   3525:     */
1.2       downsj   3526:    if (!forceit && *cmd == NUL)
1.1       downsj   3527:    {
                   3528:        set_highlight('t');     /* Highlight title */
                   3529:        start_highlight();
                   3530:        MSG_OUTSTR("\n--- Auto-Commands ---");
                   3531:        stop_highlight();
                   3532:    }
                   3533:
                   3534:    /*
                   3535:     * Loop over the events.
                   3536:     */
                   3537:    if (*arg == '*' || *arg == NUL)
                   3538:    {
                   3539:        for (event = 0; event < NUM_EVENTS; ++event)
1.2       downsj   3540:            if (do_autocmd_event(event, pat, cmd, forceit) == FAIL)
1.1       downsj   3541:                break;
                   3542:    }
                   3543:    else
                   3544:    {
                   3545:        while (*arg && !vim_iswhite(*arg))
                   3546:            if (do_autocmd_event(event_name2nr(arg, &arg), pat,
1.2       downsj   3547:                                                        cmd, forceit) == FAIL)
1.1       downsj   3548:                break;
                   3549:    }
                   3550: }
                   3551:
                   3552: /*
                   3553:  * do_autocmd() for one event.
                   3554:  * If *pat == NUL do for all patterns.
                   3555:  * If *cmd == NUL show entries.
1.2       downsj   3556:  * If forceit == TRUE delete entries.
1.1       downsj   3557:  */
                   3558:    static int
1.2       downsj   3559: do_autocmd_event(event, pat, cmd, forceit)
1.1       downsj   3560:    int     event;
                   3561:    char_u  *pat;
                   3562:    char_u  *cmd;
1.2       downsj   3563:    int     forceit;
1.1       downsj   3564: {
                   3565:    AutoPat     *ap;
                   3566:    AutoPat     *ap2;
                   3567:    AutoPat     **final_ap;
                   3568:    AutoCmd     *ac;
                   3569:    AutoCmd     **final_ac;
                   3570:    int         nested;
                   3571:    char_u      *endpat;
                   3572:    int         len;
                   3573:
                   3574:    /*
                   3575:     * Show or delete all patterns for an event.
                   3576:     */
                   3577:    if (*pat == NUL)
                   3578:    {
                   3579:        for (ap = first_autopat[event]; ap != NULL; ap = ap2)
                   3580:        {
                   3581:            ap2 = ap->next;
1.2       downsj   3582:            if (forceit)
1.1       downsj   3583:                del_autocmd(ap);
                   3584:            else
                   3585:                show_autocmd(ap, event);
                   3586:        }
1.2       downsj   3587:        if (forceit)
1.1       downsj   3588:            first_autopat[event] = NULL;
                   3589:    }
                   3590:
                   3591:    /*
                   3592:     * Loop through all the specified patterns.
                   3593:     */
                   3594:    for ( ; *pat; pat = (*endpat == ',' ? endpat + 1 : endpat))
                   3595:    {
                   3596:        /*
                   3597:         * Find end of the pattern.
                   3598:         * Watch out for a comma in braces, like "*.\{obj,o\}".
                   3599:         */
                   3600:        nested = 0;
                   3601:        for (endpat = pat;
                   3602:                *endpat && (*endpat != ',' || nested || endpat[-1] == '\\');
                   3603:                ++endpat)
                   3604:        {
                   3605:            if (*endpat == '{')
                   3606:                nested++;
                   3607:            else if (*endpat == '}')
                   3608:                nested--;
                   3609:        }
                   3610:        if (pat == endpat)              /* ignore single comma */
                   3611:            continue;
                   3612:
                   3613:        /*
                   3614:         * Find entry with same pattern.
                   3615:         */
                   3616:        final_ap = &first_autopat[event];
                   3617:        for (ap = first_autopat[event]; ap != NULL; ap = *final_ap)
                   3618:        {
                   3619:            len = STRLEN(ap->pat);
                   3620:            if (len == endpat - pat && STRNCMP(pat, ap->pat, len) == 0)
                   3621:                break;
                   3622:            final_ap = &ap->next;
                   3623:        }
                   3624:
                   3625:        /*
                   3626:         * Add a new pattern.
                   3627:         * Show and delete are ignored if pattern is not found.
                   3628:         */
                   3629:        if (ap == NULL)
                   3630:        {
                   3631:            if (*cmd == NUL)
                   3632:                continue;
                   3633:
                   3634:            /* Add the autocmd at the end of the list */
                   3635:            ap = (AutoPat *)alloc((unsigned)sizeof(AutoPat));
                   3636:            if (ap == NULL)
                   3637:                return FAIL;
                   3638:            ap->pat = strnsave(pat, (int)(endpat - pat));
                   3639:            if (ap->pat == NULL)
                   3640:            {
                   3641:                vim_free(ap);
                   3642:                return FAIL;
                   3643:            }
                   3644:            ap->reg_pat = file_pat_to_reg_pat(pat, endpat,
                   3645:                                                      &ap->allow_directories);
                   3646:            if (ap->reg_pat == NULL)
                   3647:            {
                   3648:                vim_free(ap->pat);
                   3649:                vim_free(ap);
                   3650:                return FAIL;
                   3651:            }
                   3652:            ap->cmds = NULL;
                   3653:            *final_ap = ap;
                   3654:            ap->next = NULL;
                   3655:        }
                   3656:
                   3657:        /*
                   3658:         * Remove existing autocommands.
                   3659:         * If not adding any new autocmd's for this pattern, delete the
                   3660:         * pattern from the autopat list
                   3661:         */
1.2       downsj   3662:        else if (forceit)
1.1       downsj   3663:        {
                   3664:            del_autocmd_cmds(ap);
                   3665:            if (*cmd == NUL)
                   3666:            {
                   3667:                if (ap == first_autopat[event])
                   3668:                    first_autopat[event] = ap->next;
                   3669:                else
                   3670:                {
                   3671:                    for (ap2 = first_autopat[event];
                   3672:                            ap2->next != ap;
                   3673:                            ap2 = ap2->next)
                   3674:                        ;
                   3675:                    ap2->next = ap->next;
                   3676:                }
                   3677:                del_autocmd(ap);
                   3678:            }
                   3679:        }
                   3680:
                   3681:        /*
                   3682:         * Show autocmd's for this autopat
                   3683:         */
1.2       downsj   3684:        if (*cmd == NUL && !forceit)
1.1       downsj   3685:        {
                   3686:            show_autocmd(ap, event);
                   3687:        }
                   3688:
                   3689:        /*
                   3690:         * Add the autocmd at the end if it's not already there.
                   3691:         */
                   3692:        else if (*cmd != NUL)
                   3693:        {
                   3694:            final_ac = &(ap->cmds);
                   3695:            for (ac = ap->cmds;
                   3696:                    ac != NULL && STRCMP(cmd, ac->cmd) != 0;
                   3697:                    ac = ac->next)
                   3698:                final_ac = &ac->next;
                   3699:            if (ac == NULL)
                   3700:            {
                   3701:                ac = (AutoCmd *)alloc((unsigned)sizeof(AutoCmd));
                   3702:                if (ac == NULL)
                   3703:                    return FAIL;
                   3704:                ac->cmd = strsave(cmd);
                   3705:                if (ac->cmd == NULL)
                   3706:                {
                   3707:                    vim_free(ac);
                   3708:                    return FAIL;
                   3709:                }
                   3710:                ac->next = NULL;
                   3711:                *final_ac = ac;
                   3712:            }
                   3713:        }
                   3714:    }
                   3715:    return OK;
                   3716: }
                   3717:
                   3718: /*
                   3719:  * Implementation of ":doautocmd event [fname]".
                   3720:  */
                   3721:    void
                   3722: do_doautocmd(arg)
                   3723:    char_u      *arg;
                   3724: {
                   3725:    char_u      *fname;
                   3726:    int         nothing_done = TRUE;
                   3727:
                   3728:    if (*arg == '*')
                   3729:    {
                   3730:        EMSG("Can't execute autocommands for ALL events");
                   3731:        return;
                   3732:    }
                   3733:
                   3734:    /*
                   3735:     * Scan over the events.
                   3736:     * If we find an illegal name, return here, don't do anything.
                   3737:     */
                   3738:    fname = find_end_event(arg);
                   3739:    if (fname == NULL)
                   3740:        return;
                   3741:
                   3742:    fname = skipwhite(fname);
                   3743:
                   3744:    /*
                   3745:     * Loop over the events.
                   3746:     */
                   3747:    while (*arg && !vim_iswhite(*arg))
                   3748:        if (apply_autocmds(event_name2nr(arg, &arg), fname, NULL))
                   3749:            nothing_done = FALSE;
                   3750:
                   3751:    if (nothing_done)
                   3752:        MSG("No matching autocommands");
                   3753: }
                   3754:
                   3755: /*
                   3756:  * Execute autocommands for "event" and file name "fname".
                   3757:  * Return TRUE if some commands were executed.
                   3758:  */
                   3759:    int
                   3760: apply_autocmds(event, fname, fname_io)
                   3761:    int             event;
                   3762:    char_u          *fname;     /* NULL or empty means use actual file name */
                   3763:    char_u          *fname_io;  /* fname to use for "^Vf" on cmdline */
                   3764: {
                   3765:    struct regexp   *prog;
                   3766:    char_u          *tail;
                   3767:    AutoPat         *ap;
                   3768:    AutoCmd         *ac;
                   3769:    int             temp;
                   3770:    int             save_changed = curbuf->b_changed;
1.2       downsj   3771:    BUF             *old_curbuf = curbuf;
1.1       downsj   3772:    char_u          *save_name;
                   3773:    char_u          *full_fname = NULL;
                   3774:    int             retval = FALSE;
                   3775:
                   3776:    if (autocmd_busy)           /* no nesting allowed */
                   3777:        return retval;
1.2       downsj   3778:    /*
                   3779:     * Check if these autocommands are disabled.  Used when doing ":all" or
                   3780:     * ":ball".
                   3781:     */
                   3782:    if (    (autocmd_no_enter &&
                   3783:                (event == EVENT_WINENTER || event == EVENT_BUFENTER)) ||
                   3784:            (autocmd_no_leave &&
                   3785:                (event == EVENT_WINLEAVE || event == EVENT_BUFLEAVE)))
                   3786:        return retval;
1.1       downsj   3787:
                   3788:        /* Don't redraw while doing auto commands. */
                   3789:    temp = RedrawingDisabled;
                   3790:    RedrawingDisabled = TRUE;
                   3791:    save_name = sourcing_name;  /* may be called from .vimrc */
                   3792:    autocmd_fname = fname_io;
                   3793:
                   3794:    /*
                   3795:     * While applying autocmds, we don't want to allow the commands
                   3796:     * :doautocmd or :autocmd.
                   3797:     */
                   3798:    autocmd_busy = TRUE;
                   3799:
                   3800:    /*
                   3801:     * When the file name is NULL or empty, use the file name of the current
                   3802:     * buffer.  Always use the full path of the file name to match with, in
                   3803:     * case "allow_directories" is set.
                   3804:     */
                   3805:    if (fname == NULL || *fname == NUL)
                   3806:    {
                   3807:        fname = curbuf->b_filename;
                   3808:        if (fname == NULL)
                   3809:            fname = (char_u *)"";
                   3810:    }
                   3811:    else
                   3812:    {
                   3813:        full_fname = FullName_save(fname);
                   3814:        fname = full_fname;
                   3815:    }
                   3816:
                   3817:    tail = gettail(fname);
                   3818:
1.2       downsj   3819:    for (ap = first_autopat[event]; ap != NULL && !got_int; ap = ap->next)
1.1       downsj   3820:    {
                   3821: #ifdef CASE_INSENSITIVE_FILENAME
                   3822:        reg_ic = TRUE;      /* Always ignore case */
                   3823: #else
                   3824:        reg_ic = FALSE;     /* Don't ever ignore case */
                   3825: #endif
                   3826:        reg_magic = TRUE;   /* Always use magic */
                   3827:        prog = vim_regcomp(ap->reg_pat);
                   3828:
                   3829:        if (prog != NULL &&
                   3830:            ((ap->allow_directories && vim_regexec(prog, fname, TRUE)) ||
                   3831:            (!ap->allow_directories && vim_regexec(prog, tail, TRUE))))
                   3832:        {
                   3833:            sprintf((char *)IObuff, "%s Auto commands for \"%s\"",
                   3834:                                       event_nr2name(event), (char *)ap->pat);
                   3835:            sourcing_name = strsave(IObuff);
                   3836:            for (ac = ap->cmds; ac != NULL; ac = ac->next)
                   3837:            {
                   3838:                do_cmdline(ac->cmd, TRUE, TRUE);
                   3839:                retval = TRUE;
                   3840:            }
                   3841:            vim_free(sourcing_name);
                   3842:        }
                   3843:        vim_free(prog);
1.2       downsj   3844:        mch_breakcheck();
1.1       downsj   3845:    }
                   3846:    RedrawingDisabled = temp;
                   3847:    autocmd_busy = FALSE;
                   3848:    sourcing_name = save_name;
                   3849:    autocmd_fname = NULL;
                   3850:    vim_free(full_fname);
                   3851:
1.2       downsj   3852:    /*
                   3853:     * Some events don't set or reset the Changed flag.
                   3854:     * Check if still in the same buffer!
                   3855:     */
                   3856:    if (curbuf == old_curbuf &&
                   3857:            (event == EVENT_BUFREADPOST || event == EVENT_BUFWRITEPOST ||
                   3858:            event == EVENT_FILEAPPENDPOST || event == EVENT_VIMLEAVE))
1.1       downsj   3859:        curbuf->b_changed = save_changed;
                   3860:
                   3861:    return retval;
                   3862: }
                   3863:
                   3864:    char_u  *
                   3865: set_context_in_autocmd(arg, doautocmd)
                   3866:    char_u  *arg;
                   3867:    int     doautocmd;      /* TRUE for :doautocmd, FALSE for :autocmd */
                   3868: {
                   3869:    char_u  *p;
                   3870:
                   3871:    /* skip over event name */
                   3872:    for (p = arg; *p && !vim_iswhite(*p); ++p)
                   3873:        if (*p == ',')
                   3874:            arg = p + 1;
                   3875:    if (*p == NUL)
                   3876:    {
                   3877:        expand_context = EXPAND_EVENTS;     /* expand event name */
                   3878:        expand_pattern = arg;
                   3879:        return NULL;
                   3880:    }
                   3881:
                   3882:    /* skip over pattern */
                   3883:    arg = skipwhite(p);
                   3884:    while (*arg && (!vim_iswhite(*arg) || arg[-1] == '\\'))
                   3885:        arg++;
                   3886:    if (*arg)
                   3887:        return arg;                         /* expand (next) command */
                   3888:
                   3889:    if (doautocmd)
                   3890:        expand_context = EXPAND_FILES;      /* expand file names */
                   3891:    else
                   3892:        expand_context = EXPAND_NOTHING;    /* pattern is not expanded */
                   3893:    return NULL;
                   3894: }
                   3895:
                   3896:    int
                   3897: ExpandEvents(prog, num_file, file)
                   3898:    regexp      *prog;
                   3899:    int         *num_file;
                   3900:    char_u      ***file;
                   3901: {
                   3902:    int     i;
                   3903:    int     count;
                   3904:    int     round;
                   3905:
                   3906:    /*
                   3907:     * round == 1: Count the matches.
                   3908:     * round == 2: Save the matches into the array.
                   3909:     */
                   3910:    for (round = 1; round <= 2; ++round)
                   3911:    {
                   3912:        count = 0;
                   3913:        for (i = 0; event_names[i].name != NULL; i++)
                   3914:            if (vim_regexec(prog, (char_u *)event_names[i].name, TRUE))
                   3915:            {
                   3916:                if (round == 1)
                   3917:                    count++;
                   3918:                else
                   3919:                    (*file)[count++] = strsave((char_u *)event_names[i].name);
                   3920:            }
                   3921:        if (round == 1)
                   3922:        {
                   3923:            *num_file = count;
                   3924:            if (count == 0 || (*file = (char_u **)
                   3925:                         alloc((unsigned)(count * sizeof(char_u *)))) == NULL)
                   3926:                return FAIL;
                   3927:        }
                   3928:    }
                   3929:    return OK;
                   3930: }
                   3931:
                   3932: #endif  /* AUTOCMD */
                   3933:
                   3934: #ifdef HAVE_LANGMAP
                   3935: /*
                   3936:  * Any character has an equivalent character.  This is used for keyboards that
                   3937:  * have a special language mode that sends characters above 128 (although
                   3938:  * other characters can be translated too).
                   3939:  */
                   3940:
                   3941: /*
                   3942:  * char_u langmap_mapchar[256];
                   3943:  * Normally maps each of the 128 upper chars to an <128 ascii char; used to
                   3944:  * "translate" native lang chars in normal mode or some cases of
                   3945:  * insert mode without having to tediously switch lang mode back&forth.
                   3946:  */
                   3947:
                   3948:    static void
                   3949: langmap_init()
                   3950: {
                   3951:    int i;
                   3952:
                   3953:    for (i = 0; i < 256; i++)           /* we init with a-one-to one map */
                   3954:        langmap_mapchar[i] = i;
                   3955: }
                   3956:
                   3957: /*
                   3958:  * Called when langmap option is set; the language map can be
                   3959:  * changed at any time!
                   3960:  */
                   3961:    static void
                   3962: langmap_set()
                   3963: {
                   3964:    char_u  *p;
                   3965:    char_u  *p2;
                   3966:    int     from, to;
                   3967:
                   3968:    langmap_init();                         /* back to one-to-one map first */
                   3969:
                   3970:    for (p = p_langmap; p[0]; )
                   3971:    {
                   3972:        for (p2 = p; p2[0] && p2[0] != ',' && p2[0] != ';'; ++p2)
                   3973:            if (p2[0] == '\\' && p2[1])
                   3974:                ++p2;
                   3975:        if (p2[0] == ';')
                   3976:            ++p2;           /* abcd;ABCD form, p2 points to A */
                   3977:        else
                   3978:            p2 = NULL;      /* aAbBcCdD form, p2 is NULL */
                   3979:        while (p[0])
                   3980:        {
                   3981:            if (p[0] == '\\' && p[1])
                   3982:                ++p;
                   3983:            from = p[0];
                   3984:            if (p2 == NULL)
                   3985:            {
                   3986:                if (p[1] == '\\')
                   3987:                    ++p;
                   3988:                to = p[1];
                   3989:            }
                   3990:            else
                   3991:            {
                   3992:                if (p2[0] == '\\')
                   3993:                    ++p2;
                   3994:                to = p2[0];
                   3995:            }
                   3996:            if (to == NUL)
                   3997:            {
                   3998:                EMSG2("'langmap': Matching character missing for %s",
                   3999:                                                             transchar(from));
                   4000:                return;
                   4001:            }
                   4002:            langmap_mapchar[from] = to;
                   4003:
                   4004:            /* Advance to next pair */
                   4005:            if (p2 == NULL)
                   4006:            {
                   4007:                p += 2;
                   4008:                if (p[0] == ',')
                   4009:                {
                   4010:                    ++p;
                   4011:                    break;
                   4012:                }
                   4013:            }
                   4014:            else
                   4015:            {
                   4016:                ++p;
                   4017:                ++p2;
                   4018:                if (*p == ';')
                   4019:                {
                   4020:                    p = p2;
                   4021:                    if (p[0])
                   4022:                    {
                   4023:                        if (p[0] != ',')
                   4024:                        {
                   4025:                            EMSG2("'langmap': Extra characters after semicolon: %s", p);
                   4026:                            return;
                   4027:                        }
                   4028:                        ++p;
                   4029:                    }
                   4030:                    break;
                   4031:                }
                   4032:            }
                   4033:        }
                   4034:    }
                   4035: }
                   4036: #endif
                   4037:
                   4038: /*
                   4039:  * Return TRUE if format option 'x' is in effect.
                   4040:  * Take care of no formatting when 'paste' is set.
                   4041:  */
                   4042:    int
                   4043: has_format_option(x)
                   4044:    int     x;
                   4045: {
                   4046:    if (p_paste)
                   4047:        return FALSE;
                   4048:    return (vim_strchr(curbuf->b_p_fo, x) != NULL);
                   4049: }
                   4050:
                   4051: /*
                   4052:  * Return TRUE if "x" is present in 'shortmess' option, or
                   4053:  * 'shortmess' contains 'a' and "x" is present in SHM_A.
                   4054:  */
                   4055:    int
                   4056: shortmess(x)
                   4057:    int     x;
                   4058: {
                   4059:    return (vim_strchr(p_shm, x) != NULL || (vim_strchr(p_shm, 'a') != NULL &&
                   4060:                                       vim_strchr((char_u *)SHM_A, x) != NULL));
                   4061: }
                   4062:
                   4063: /*
                   4064:  * set_paste_option() - Called after p_paste was set or reset.
                   4065:  */
                   4066:    static void
                   4067: paste_option_changed()
                   4068: {
                   4069:    static int      old_p_paste = FALSE;
                   4070:    static int      save_sm = 0;
                   4071:    static int      save_ru = 0;
                   4072: #ifdef RIGHTLEFT
                   4073:    static int      save_ri = 0;
                   4074:    static int      save_hkmap = 0;
                   4075: #endif
                   4076:    BUF             *buf;
                   4077:
                   4078:    if (p_paste)
                   4079:    {
                   4080:        /*
                   4081:         * Paste switched from off to on.
                   4082:         * Save the current values, so they can be restored later.
                   4083:         */
                   4084:        if (!old_p_paste)
                   4085:        {
                   4086:            /* save options for each buffer */
                   4087:            for (buf = firstbuf; buf != NULL; buf = buf->b_next)
                   4088:            {
                   4089:                buf->b_p_tw_save = buf->b_p_tw;
                   4090:                buf->b_p_wm_save = buf->b_p_wm;
                   4091:                buf->b_p_ai_save = buf->b_p_ai;
                   4092: #ifdef SMARTINDENT
                   4093:                buf->b_p_si_save = buf->b_p_si;
                   4094: #endif
                   4095: #ifdef CINDENT
                   4096:                buf->b_p_cin_save = buf->b_p_cin;
                   4097: #endif
                   4098: #ifdef LISPINDENT
                   4099:                buf->b_p_lisp_save = buf->b_p_lisp;
                   4100: #endif
                   4101:            }
                   4102:
                   4103:            /* save global options */
                   4104:            save_sm = p_sm;
                   4105:            save_ru = p_ru;
                   4106: #ifdef RIGHTLEFT
                   4107:            save_ri = p_ri;
                   4108:            save_hkmap = p_hkmap;
                   4109: #endif
                   4110:        }
                   4111:
                   4112:        /*
                   4113:         * Always set the option values, also when 'paste' is set when it is
                   4114:         * already on.
                   4115:         */
                   4116:        /* set options for each buffer */
                   4117:        for (buf = firstbuf; buf != NULL; buf = buf->b_next)
                   4118:        {
                   4119:            buf->b_p_tw = 0;        /* textwidth is 0 */
                   4120:            buf->b_p_wm = 0;        /* wrapmargin is 0 */
                   4121:            buf->b_p_ai = 0;        /* no auto-indent */
                   4122: #ifdef SMARTINDENT
                   4123:            buf->b_p_si = 0;        /* no smart-indent */
                   4124: #endif
                   4125: #ifdef CINDENT
                   4126:            buf->b_p_cin = 0;       /* no c indenting */
                   4127: #endif
                   4128: #ifdef LISPINDENT
                   4129:            buf->b_p_lisp = 0;      /* no lisp indenting */
                   4130: #endif
                   4131:        }
                   4132:
                   4133:        /* set global options */
                   4134:        p_sm = 0;                   /* no showmatch */
                   4135:        p_ru = 0;                   /* no ruler */
                   4136: #ifdef RIGHTLEFT
                   4137:        p_ri = 0;                   /* no reverse insert */
                   4138:        p_hkmap = 0;                /* no Hebrew keyboard */
                   4139: #endif
                   4140:    }
                   4141:
                   4142:    /*
                   4143:     * Paste switched from on to off: Restore saved values.
                   4144:     */
                   4145:    else if (old_p_paste)
                   4146:    {
                   4147:        /* restore options for each buffer */
                   4148:        for (buf = firstbuf; buf != NULL; buf = buf->b_next)
                   4149:        {
                   4150:            buf->b_p_tw = buf->b_p_tw_save;
                   4151:            buf->b_p_wm = buf->b_p_wm_save;
                   4152:            buf->b_p_ai = buf->b_p_ai_save;
                   4153: #ifdef SMARTINDENT
                   4154:            buf->b_p_si = buf->b_p_si_save;
                   4155: #endif
                   4156: #ifdef CINDENT
                   4157:            buf->b_p_cin = buf->b_p_cin_save;
                   4158: #endif
                   4159: #ifdef LISPINDENT
                   4160:            buf->b_p_lisp = buf->b_p_lisp_save;
                   4161: #endif
                   4162:        }
                   4163:
                   4164:        /* restore global options */
                   4165:        p_sm = save_sm;
                   4166:        p_ru = save_ru;
                   4167: #ifdef RIGHTLEFT
                   4168:        p_ri = save_ri;
                   4169:        p_hkmap = save_hkmap;
                   4170: #endif
                   4171:    }
                   4172:
                   4173:    old_p_paste = p_paste;
                   4174: }
                   4175:
                   4176: /*
                   4177:  * p_compatible_set() - Called when p_cp has been set.
                   4178:  */
                   4179:    static void
                   4180: p_compatible_set()
                   4181: {
                   4182:    p_bs = 0;                       /* normal backspace */
                   4183:                                    /* backspace and space do not wrap */
                   4184:    set_string_option((char_u *)"ww", -1, (char_u *)"", TRUE);
                   4185:    p_bk = 0;                       /* no backup file */
                   4186:                    /* Use textwidth for formatting, don't format comments */
                   4187:    set_string_option((char_u *)"fo", -1, (char_u *)FO_DFLT_VI, TRUE);
                   4188:                                    /* all compatible flags on */
                   4189:    set_string_option((char_u *)"cpo", -1, (char_u *)CPO_ALL, TRUE);
                   4190:    set_string_option((char_u *)"isk", -1, (char_u *)"@,48-57,_", TRUE);
                   4191:                                    /* no short messages */
                   4192:    set_string_option((char_u *)"shm", -1, (char_u *)"", TRUE);
                   4193: #ifdef DIGRAPHS
                   4194:    p_dg = 0;                       /* no digraphs */
                   4195: #endif /* DIGRAPHS */
                   4196:    p_ek = 0;                       /* no ESC keys in insert mode */
                   4197:    curbuf->b_p_et = 0;             /* no expansion of tabs */
                   4198:    p_gd = 0;                       /* /g is not default for :s */
                   4199:    p_hi = 0;                       /* no history */
                   4200:    p_scs = 0;                      /* no ignore case switch */
                   4201:    p_im = 0;                       /* do not start in insert mode */
                   4202:    p_js = 1;                       /* insert 2 spaces after period */
                   4203:    curbuf->b_p_ml = 0;             /* no modelines */
                   4204:    p_more = 0;                     /* no -- more -- for listings */
                   4205:    p_ru = 0;                       /* no ruler */
                   4206: #ifdef RIGHTLEFT
                   4207:    p_ri = 0;                       /* no reverse insert */
                   4208:    p_hkmap = 0;                    /* no Hebrew keyboard mapping */
                   4209: #endif
                   4210:    p_sj = 1;                       /* no scrolljump */
                   4211:    p_so = 0;                       /* no scrolloff */
                   4212:    p_sr = 0;                       /* do not round indent to shiftwidth */
                   4213:    p_sc = 0;                       /* no showcommand */
                   4214:    p_smd = 0;                      /* no showmode */
                   4215: #ifdef SMARTINDENT
                   4216:    curbuf->b_p_si = 0;             /* no smartindent */
                   4217: #endif
                   4218: #ifdef CINDENT
                   4219:    curbuf->b_p_cin = 0;            /* no C indenting */
                   4220: #endif
                   4221:    p_sta = 0;                      /* no smarttab */
                   4222:    p_sol = TRUE;                   /* Move cursor to start-of-line */
                   4223:    p_ta = 0;                       /* no automatic textmode detection */
                   4224:    curbuf->b_p_tw = 0;             /* no automatic line wrap */
                   4225:    p_to = 0;                       /* no tilde operator */
                   4226:    p_ttimeout = 0;                 /* no terminal timeout */
                   4227:    p_tr = 0;                       /* tag file names not relative */
                   4228:    p_ul = 0;                       /* no multilevel undo */
                   4229:    p_uc = 0;                       /* no autoscript file */
                   4230:    p_wb = 0;                       /* no backup file */
                   4231:    if (p_wc == TAB)
                   4232:        p_wc = Ctrl('E');           /* normal use for TAB */
                   4233:    init_chartab();                 /* make b_p_isk take effect */
                   4234: }
                   4235:
                   4236: /*
                   4237:  * fill_breakat_flags() -- called when 'breakat' changes value.
                   4238:  */
                   4239:    static void
                   4240: fill_breakat_flags()
                   4241: {
                   4242:    char_u      *c;
                   4243:    int         i;
                   4244:
                   4245:    for (i = 0; i < 256; i++)
                   4246:        breakat_flags[i] = FALSE;
                   4247:
                   4248:    if (p_breakat != NULL)
                   4249:        for (c = p_breakat; *c; c++)
                   4250:            breakat_flags[*c] = TRUE;
                   4251: }