Newer
Older
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
{
requires_py_version = 2;
break;
}
if (STRCMP("# requires python 3.x", IObuff) == 0)
{
requires_py_version = 3;
break;
}
}
fclose(file);
}
return requires_py_version;
}
/*
* Source a python file using the requested python version.
*/
static void
source_pyx_file(exarg_T *eap, char_u *fname)
{
exarg_T ex;
int v = requires_py_version(fname);
# if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
init_pyxversion();
# endif
if (v == 0)
{
# if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
/* user didn't choose a preference, 'pyx' is used */
v = p_pyx;
# elif defined(FEAT_PYTHON)
v = 2;
# elif defined(FEAT_PYTHON3)
v = 3;
# endif
}
/*
* now source, if required python version is not supported show
* unobtrusive message.
*/
if (eap == NULL)
vim_memset(&ex, 0, sizeof(ex));
else
ex = *eap;
ex.arg = fname;
ex.cmd = (char_u *)(v == 2 ? "pyfile" : "pyfile3");
if (v == 2)
{
# ifdef FEAT_PYTHON
ex_pyfile(&ex);
# else
vim_snprintf((char *)IObuff, IOSIZE,
_("W20: Required python version 2.x not supported, ignoring file: %s"),
fname);
MSG(IObuff);
# endif
return;
}
else
{
# ifdef FEAT_PYTHON3
ex_py3file(&ex);
# else
vim_snprintf((char *)IObuff, IOSIZE,
_("W21: Required python version 3.x not supported, ignoring file: %s"),
fname);
MSG(IObuff);
# endif
return;
}
}
/*
* ":pyxfile {fname}"
*/
void
ex_pyxfile(exarg_T *eap)
{
source_pyx_file(eap, eap->arg);
}
/*
* ":pyx"
*/
void
ex_pyx(exarg_T *eap)
{
# if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
init_pyxversion();
if (p_pyx == 2)
ex_python(eap);
else
ex_py3(eap);
# elif defined(FEAT_PYTHON)
ex_python(eap);
# elif defined(FEAT_PYTHON3)
ex_py3(eap);
# endif
}
/*
* ":pyxdo"
*/
void
ex_pyxdo(exarg_T *eap)
{
# if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
init_pyxversion();
if (p_pyx == 2)
ex_pydo(eap);
else
ex_py3do(eap);
# elif defined(FEAT_PYTHON)
ex_pydo(eap);
# elif defined(FEAT_PYTHON3)
ex_py3do(eap);
# endif
}
#endif
/*
* ":source {fname}"
*/
void
{
#ifdef FEAT_BROWSE
if (cmdmod.browse)
{
char_u *fname = NULL;
fname = do_browse(0, (char_u *)_("Source Vim script"), eap->arg,
NULL, NULL, BROWSE_FILTER_MACROS, NULL);
if (fname != NULL)
{
cmd_source(fname, eap);
vim_free(fname);
}
}
else
#endif
cmd_source(eap->arg, eap);
}
static void
{
if (*fname == NUL)
EMSG(_(e_argreq));
else if (eap != NULL && eap->forceit)
* Need to execute the commands directly. This is required at least
* for:
* - ":g" command busy
* - after ":argdo", ":windo" or ":bufdo"
* - another command follows
* - inside a loop
*/
openscript(fname, global_busy || listcmd_busy || eap->nextcmd != NULL
#ifdef FEAT_EVAL
|| eap->cstack->cs_idx >= 0
#endif
);
/* ":source" read ex commands */
else if (do_source(fname, FALSE, DOSO_NONE) == FAIL)
EMSG2(_(e_notopen), fname);
}
/*
* ":source" and associated commands.
*/
/*
* Structure used to store info for each sourced file.
* It is shared between do_source() and getsourceline().
* This is required, because it needs to be handed to do_cmdline() and
* sourcing can be done recursively.
*/
struct source_cookie
{
FILE *fp; /* opened file for sourcing */
char_u *nextline; /* if not NULL: line that was read ahead */
int finished; /* ":finish" used */
#if defined(USE_CRNL) || defined(USE_CR)
int fileformat; /* EOL_UNKNOWN, EOL_UNIX or EOL_DOS */
int error; /* TRUE if LF found after CR-LF */
#endif
#ifdef FEAT_EVAL
linenr_T breakpoint; /* next line with breakpoint or zero */
char_u *fname; /* name of sourced file */
int dbg_tick; /* debug_tick when breakpoint was set */
int level; /* top nesting level of sourced file */
#endif
#ifdef FEAT_MBYTE
vimconv_T conv; /* type of conversion */
#endif
};
#ifdef FEAT_EVAL
/*
* Return the address holding the next breakpoint line for a source cookie.
*/
linenr_T *
{
return &((struct source_cookie *)cookie)->breakpoint;
}
/*
* Return the address holding the debug tick for a source cookie.
*/
int *
{
return &((struct source_cookie *)cookie)->dbg_tick;
}
/*
* Return the nesting level for a source cookie.
*/
int
{
return ((struct source_cookie *)cookie)->level;
}
#endif
static char_u *get_one_sourceline(struct source_cookie *sp);
#if (defined(WIN32) && defined(FEAT_CSCOPE)) || defined(HAVE_FD_CLOEXEC)
# define USE_FOPEN_NOINH
/*
* Special function to open a file without handle inheritance.
* When possible the handle is closed on exec().
int fd_tmp = mch_open(filename, O_RDONLY | O_BINARY | O_NOINHERIT, 0);
# else
int fd_tmp = mch_open(filename, O_RDONLY, 0);
# ifdef HAVE_FD_CLOEXEC
{
int fdflags = fcntl(fd_tmp, F_GETFD);
if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0)
return fdopen(fd_tmp, READBIN);
}
#endif
/*
* do_source: Read the file "fname" and execute its lines as EX commands.
*
* This function may be called recursively!
*
* return FAIL if file could not be opened, OK otherwise
*/
int
do_source(
char_u *fname,
int check_other, /* check for .vimrc and _vimrc */
int is_vimrc) /* DOSO_ value */
{
struct source_cookie cookie;
char_u *save_sourcing_name;
linenr_T save_sourcing_lnum;
char_u *p;
char_u *fname_exp;
int retval = FAIL;
#ifdef FEAT_EVAL
scid_T save_current_SID;
static scid_T last_current_SID = 0;
void *save_funccalp;
int save_debug_break_level = debug_break_level;
int stat_ok;
# endif
#endif
#ifdef STARTUPTIME
struct timeval tv_rel;
struct timeval tv_start;
#endif
#ifdef FEAT_PROFILE
proftime_T wait_start;
#endif
p = expand_env_save(fname);
if (p == NULL)
return retval;
fname_exp = fix_fname(p);
vim_free(p);
if (fname_exp == NULL)
return retval;
if (mch_isdir(fname_exp))
{
smsg((char_u *)_("Cannot source a directory: \"%s\""), fname);
/* Apply SourceCmd autocommands, they should get the file and source it. */
if (has_autocmd(EVENT_SOURCECMD, fname_exp, NULL)
&& apply_autocmds(EVENT_SOURCECMD, fname_exp, fname_exp,
FALSE, curbuf))
/* Apply SourcePre autocommands, they may get the file. */
apply_autocmds(EVENT_SOURCEPRE, fname_exp, fname_exp, FALSE, curbuf);
cookie.fp = fopen_noinh_readbin((char *)fname_exp);
#else
cookie.fp = mch_fopen((char *)fname_exp, READBIN);
#endif
if (cookie.fp == NULL && check_other)
{
/*
* Try again, replacing file name ".vimrc" by "_vimrc" or vice versa,
* and ".exrc" by "_exrc" or vice versa.
*/
p = gettail(fname_exp);
if ((*p == '.' || *p == '_')
&& (STRICMP(p + 1, "vimrc") == 0
|| STRICMP(p + 1, "gvimrc") == 0
|| STRICMP(p + 1, "exrc") == 0))
{
if (*p == '_')
*p = '.';
else
*p = '_';
cookie.fp = fopen_noinh_readbin((char *)fname_exp);
#else
cookie.fp = mch_fopen((char *)fname_exp, READBIN);
#endif
}
}
if (cookie.fp == NULL)
{
if (p_verbose > 0)
{
smsg((char_u *)_("could not source \"%s\""), fname);
else
smsg((char_u *)_("line %ld: could not source \"%s\""),
}
goto theend;
}
/*
* The file exists.
* - In verbose mode, give a message.
* - For a vimrc file, may want to set 'compatible', call vimrc_found().
*/
if (p_verbose > 1)
{
smsg((char_u *)_("sourcing \"%s\""), fname);
else
smsg((char_u *)_("line %ld: sourcing \"%s\""),
if (is_vimrc == DOSO_VIMRC)
vimrc_found(fname_exp, (char_u *)"MYVIMRC");
else if (is_vimrc == DOSO_GVIMRC)
vimrc_found(fname_exp, (char_u *)"MYGVIMRC");
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
#ifdef USE_CRNL
/* If no automatic file format: Set default to CR-NL. */
if (*p_ffs == NUL)
cookie.fileformat = EOL_DOS;
else
cookie.fileformat = EOL_UNKNOWN;
cookie.error = FALSE;
#endif
#ifdef USE_CR
/* If no automatic file format: Set default to CR. */
if (*p_ffs == NUL)
cookie.fileformat = EOL_MAC;
else
cookie.fileformat = EOL_UNKNOWN;
cookie.error = FALSE;
#endif
cookie.nextline = NULL;
cookie.finished = FALSE;
#ifdef FEAT_EVAL
/*
* Check if this script has a breakpoint.
*/
cookie.breakpoint = dbg_find_breakpoint(TRUE, fname_exp, (linenr_T)0);
cookie.fname = fname_exp;
cookie.dbg_tick = debug_tick;
cookie.level = ex_nesting_level;
#endif
/*
* Keep the sourcing name/lnum, for recursive calls.
*/
save_sourcing_name = sourcing_name;
sourcing_name = fname_exp;
save_sourcing_lnum = sourcing_lnum;
sourcing_lnum = 0;
#ifdef STARTUPTIME
if (time_fd != NULL)
time_push(&tv_rel, &tv_start);
prof_child_enter(&wait_start); /* entering a child now */
# endif
/* Don't use local function variables, if called from a function.
* Also starts profiling timer for nested script. */
save_funccalp = save_funccal();
/*
* Check if this script was sourced before to finds its SID.
* If it's new, generate a new SID.
*/
save_current_SID = current_SID;
# ifdef UNIX
stat_ok = (mch_stat((char *)fname_exp, &st) >= 0);
# endif
for (current_SID = script_items.ga_len; current_SID > 0; --current_SID)
{
si = &SCRIPT_ITEM(current_SID);
if (si->sn_name != NULL
/* Compare dev/ino when possible, it catches symbolic
* links. Also compare file names, the inode may change
* when the file was edited. */
&& (si->sn_dev == st.st_dev
&& si->sn_ino == st.st_ino)) ||
if (current_SID == 0)
{
current_SID = ++last_current_SID;
if (ga_grow(&script_items, (int)(current_SID - script_items.ga_len))
== FAIL)
goto almosttheend;
while (script_items.ga_len < current_SID)
++script_items.ga_len;
SCRIPT_ITEM(script_items.ga_len).sn_name = NULL;
# ifdef FEAT_PROFILE
SCRIPT_ITEM(script_items.ga_len).sn_prof_on = FALSE;
si = &SCRIPT_ITEM(current_SID);
si->sn_name = fname_exp;
fname_exp = NULL;
# ifdef UNIX
if (stat_ok)
{
si->sn_dev = st.st_dev;
si->sn_ino = st.st_ino;
}
else
/* Allocate the local script variables to use for this script. */
new_script_vars(current_SID);
}
{
int forceit;
/* Check if we do profiling for this script. */
if (!si->sn_prof_on && has_profiling(TRUE, si->sn_name, &forceit))
{
script_do_profile(si);
si->sn_pr_force = forceit;
}
if (si->sn_prof_on)
{
++si->sn_pr_count;
profile_start(&si->sn_pr_start);
profile_zero(&si->sn_pr_children);
}
}
# endif
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
#ifdef FEAT_MBYTE
cookie.conv.vc_type = CONV_NONE; /* no conversion */
/* Read the first line so we can check for a UTF-8 BOM. */
firstline = getsourceline(0, (void *)&cookie, 0);
if (firstline != NULL && STRLEN(firstline) >= 3 && firstline[0] == 0xef
&& firstline[1] == 0xbb && firstline[2] == 0xbf)
{
/* Found BOM; setup conversion, skip over BOM and recode the line. */
convert_setup(&cookie.conv, (char_u *)"utf-8", p_enc);
p = string_convert(&cookie.conv, firstline + 3, NULL);
if (p == NULL)
p = vim_strsave(firstline + 3);
if (p != NULL)
{
vim_free(firstline);
firstline = p;
}
}
#endif
/*
* Call do_cmdline, which will call getsourceline() to get the lines.
*/
do_cmdline(firstline, getsourceline, (void *)&cookie,
DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_REPEAT);
retval = OK;
{
/* Get "si" again, "script_items" may have been reallocated. */
si = &SCRIPT_ITEM(current_SID);
if (si->sn_prof_on)
{
profile_end(&si->sn_pr_start);
profile_sub_wait(&wait_start, &si->sn_pr_start);
profile_add(&si->sn_pr_total, &si->sn_pr_start);
profile_self(&si->sn_pr_self, &si->sn_pr_start,
&si->sn_pr_children);
#endif
if (got_int)
EMSG(_(e_interr));
sourcing_name = save_sourcing_name;
sourcing_lnum = save_sourcing_lnum;
if (p_verbose > 1)
{
smsg((char_u *)_("finished sourcing %s"), fname);
smsg((char_u *)_("continuing in %s"), sourcing_name);
if (time_fd != NULL)
{
vim_snprintf((char *)IObuff, IOSIZE, "sourcing %s", fname);
time_msg((char *)IObuff, &tv_start);
time_pop(&tv_rel);
}
#endif
#ifdef FEAT_EVAL
/*
* After a "finish" in debug mode, need to break at first command of next
* sourced file.
*/
if (save_debug_break_level > ex_nesting_level
&& debug_break_level == ex_nesting_level)
++debug_break_level;
#endif
#ifdef FEAT_EVAL
almosttheend:
current_SID = save_current_SID;
restore_funccal(save_funccalp);
# ifdef FEAT_PROFILE
prof_child_exit(&wait_start); /* leaving a child now */
# endif
#endif
fclose(cookie.fp);
vim_free(cookie.nextline);
#ifdef FEAT_MBYTE
convert_setup(&cookie.conv, NULL, NULL);
#endif
theend:
vim_free(fname_exp);
return retval;
}
#if defined(FEAT_EVAL) || defined(PROTO)
for (i = 1; i <= script_items.ga_len && !got_int; ++i)
if (SCRIPT_ITEM(i).sn_name != NULL)
{
home_replace(NULL, SCRIPT_ITEM(i).sn_name,
NameBuff, MAXPATHL, TRUE);
smsg((char_u *)"%3d: %s", i, NameBuff);
}
# if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
/*
* Fix slashes in the list of script names for 'shellslash'.
*/
void
for (i = 1; i <= script_items.ga_len; ++i)
if (SCRIPT_ITEM(i).sn_name != NULL)
slash_adjust(SCRIPT_ITEM(i).sn_name);
}
# endif
/*
* Get a pointer to a script name. Used for ":verbose set".
*/
char_u *
return (char_u *)_("environment variable");
if (id == SID_ERROR)
return (char_u *)_("error handler");
# if defined(EXITFREE) || defined(PROTO)
void
{
int i;
for (i = script_items.ga_len; i > 0; --i)
vim_free(SCRIPT_ITEM(i).sn_name);
ga_clear(&script_items);
}
# endif
#endif
#if defined(USE_CR) || defined(PROTO)
# if defined(__MSL__) && (__MSL__ >= 22)
/*
* Newer version of the Metrowerks library handle DOS and UNIX files
* without help.
* Test with earlier versions, MSL 2.2 is the library supplied with
* Codewarrior Pro 2.
*/
char *
{
return fgets(s, n, stream);
}
# else
/*
* Version of fgets() which also works for lines ending in a <CR> only
* (Macintosh format).
* For older versions of the Metrowerks library.
* At least CodeWarrior 9 needed this code.
*/
char *
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
{
int c = 0;
int char_read = 0;
while (!feof(stream) && c != '\r' && c != '\n' && char_read < n - 1)
{
c = fgetc(stream);
s[char_read++] = c;
/* If the file is in DOS format, we need to skip a NL after a CR. I
* thought it was the other way around, but this appears to work... */
if (c == '\n')
{
c = fgetc(stream);
if (c != '\r')
ungetc(c, stream);
}
}
s[char_read] = 0;
if (char_read == 0)
return NULL;
if (feof(stream) && char_read == 1)
return NULL;
return s;
}
# endif
#endif
/*
* Get one full line from a sourced file.
* Called by do_cmdline() when it's called from do_source().
*
* Return a pointer to the line in allocated memory.
* Return NULL for end-of-file or some error.
*/
char_u *
getsourceline(int c UNUSED, void *cookie, int indent UNUSED)
{
struct source_cookie *sp = (struct source_cookie *)cookie;
char_u *line;
#ifdef FEAT_EVAL
/* If breakpoints have been added/deleted need to check for it. */
if (sp->dbg_tick < debug_tick)
{
sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
sp->dbg_tick = debug_tick;
}
#endif
/*
* Get current line. If there is a read-ahead line, use it, otherwise get
* one now.
*/
if (sp->finished)
line = NULL;
else if (sp->nextline == NULL)
line = get_one_sourceline(sp);
else
{
line = sp->nextline;
sp->nextline = NULL;
++sourcing_lnum;
if (line != NULL && do_profiling == PROF_YES)
/* Only concatenate lines starting with a \ when 'cpoptions' doesn't
* contain the 'C' flag. */
if (line != NULL && (vim_strchr(p_cpo, CPO_CONCAT) == NULL))
{
/* compensate for the one line read-ahead */
--sourcing_lnum;
/* Get the next line and concatenate it when it starts with a
* backslash. We always need to read the next line, keep it in
* sp->nextline. */
sp->nextline = get_one_sourceline(sp);
if (sp->nextline != NULL && *(p = skipwhite(sp->nextline)) == '\\')
ga_concat(&ga, line);
ga_concat(&ga, p + 1);
for (;;)
{
vim_free(sp->nextline);
sp->nextline = get_one_sourceline(sp);
if (sp->nextline == NULL)
break;
p = skipwhite(sp->nextline);
if (*p != '\\')
break;
/* Adjust the growsize to the current length to speed up
* concatenating many lines. */
if (ga.ga_len > 400)
{
if (ga.ga_len > 8000)
ga.ga_growsize = 8000;
else
ga.ga_growsize = ga.ga_len;
}
ga_concat(&ga, p + 1);
}
ga_append(&ga, NUL);
}
}
#ifdef FEAT_MBYTE
if (line != NULL && sp->conv.vc_type != CONV_NONE)
{
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
/* Convert the encoding of the script line. */
s = string_convert(&sp->conv, line, NULL);
if (s != NULL)
{
vim_free(line);
line = s;
}
}
#endif
#ifdef FEAT_EVAL
/* Did we encounter a breakpoint? */
if (sp->breakpoint != 0 && sp->breakpoint <= sourcing_lnum)
{
dbg_breakpoint(sp->fname, sourcing_lnum);
/* Find next breakpoint. */
sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
sp->dbg_tick = debug_tick;
}
#endif
return line;
}
static char_u *
{
garray_T ga;
int len;
int c;
char_u *buf;
#ifdef USE_CRNL
int has_cr; /* CR-LF found */
#endif
#ifdef USE_CR
char_u *scan;
#endif
int have_read = FALSE;
/* use a growarray to store the sourced line */
/*
* Loop until there is a finished line (or end-of-file).
*/
sourcing_lnum++;
for (;;)
{
/* make room to read at least 120 (more) characters */
if (ga_grow(&ga, 120) == FAIL)
break;
buf = (char_u *)ga.ga_data;
#ifdef USE_CR
if (sp->fileformat == EOL_MAC)
{
if (fgets_cr((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
sp->fp) == NULL)
if (fgets((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
sp->fp) == NULL)
len = ga.ga_len + (int)STRLEN(buf + ga.ga_len);
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
#ifdef USE_CRNL
/* Ignore a trailing CTRL-Z, when in Dos mode. Only recognize the
* CTRL-Z by its own, or after a NL. */
if ( (len == 1 || (len >= 2 && buf[len - 2] == '\n'))
&& sp->fileformat == EOL_DOS
&& buf[len - 1] == Ctrl_Z)
{
buf[len - 1] = NUL;
break;
}
#endif
#ifdef USE_CR
/* If the read doesn't stop on a new line, and there's
* some CR then we assume a Mac format */
if (sp->fileformat == EOL_UNKNOWN)
{
if (buf[len - 1] != '\n' && vim_strchr(buf, '\r') != NULL)
sp->fileformat = EOL_MAC;
else
sp->fileformat = EOL_UNIX;
}
if (sp->fileformat == EOL_MAC)
{
scan = vim_strchr(buf, '\r');
if (scan != NULL)
{
*scan = '\n';
if (*(scan + 1) != 0)
{
*(scan + 1) = 0;
fseek(sp->fp, (long)(scan - buf - len + 1), SEEK_CUR);
}
}
len = STRLEN(buf);
}
#endif
have_read = TRUE;
ga.ga_len = len;
/* If the line was longer than the buffer, read more. */
if (ga.ga_maxlen - ga.ga_len == 1 && buf[len - 1] != '\n')
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
continue;
if (len >= 1 && buf[len - 1] == '\n') /* remove trailing NL */
{
#ifdef USE_CRNL
has_cr = (len >= 2 && buf[len - 2] == '\r');
if (sp->fileformat == EOL_UNKNOWN)
{
if (has_cr)
sp->fileformat = EOL_DOS;
else
sp->fileformat = EOL_UNIX;
}
if (sp->fileformat == EOL_DOS)
{
if (has_cr) /* replace trailing CR */
{
buf[len - 2] = '\n';
--len;
--ga.ga_len;
}
else /* lines like ":map xx yy^M" will have failed */
{
if (!sp->error)
msg_source(HL_ATTR(HLF_W));
EMSG(_("W15: Warning: Wrong line separator, ^M may be missing"));
sp->error = TRUE;
sp->fileformat = EOL_UNIX;
}
}
#endif
/* The '\n' is escaped if there is an odd number of ^V's just
* before it, first set "c" just before the 'V's and then check
* len&c parities (is faster than ((len-c)%2 == 0)) -- Acevedo */
for (c = len - 2; c >= 0 && buf[c] == Ctrl_V; c--)
;
if ((len & 1) != (c & 1)) /* escaped NL, read more */
{
sourcing_lnum++;
continue;
}
buf[len - 1] = NUL; /* remove the NL */