📄 misc2.c
字号:
size_t size;
{
void *p;
mem_pre_free(&ptr);
mem_pre_alloc_s(&size);
p = realloc(ptr, size);
mem_post_alloc(&p, size);
return p;
}
#endif
/*
* Avoid repeating the error message many times (they take 1 second each).
* Did_outofmem_msg is reset when a character is read.
*/
void
do_outofmem_msg()
{
if (!did_outofmem_msg)
{
emsg(e_outofmem);
did_outofmem_msg = TRUE;
}
}
/*
* copy a string into newly allocated memory
*/
char_u *
vim_strsave(string)
char_u *string;
{
char_u *p;
unsigned len;
len = STRLEN(string) + 1;
p = alloc(len);
if (p != NULL)
mch_memmove(p, string, (size_t)len);
return p;
}
char_u *
vim_strnsave(string, len)
char_u *string;
int len;
{
char_u *p;
p = alloc((unsigned)(len + 1));
if (p != NULL)
{
STRNCPY(p, string, len);
p[len] = NUL;
}
return p;
}
/*
* like vim_strnsave(), but remove backslashes from the string.
*/
char_u *
vim_strnsave_esc(string, len)
char_u *string;
int len;
{
char_u *p1, *p2;
p1 = alloc((unsigned) (len + 1));
if (p1 != NULL)
{
STRNCPY(p1, string, len);
p1[len] = NUL;
for (p2 = p1; *p2; ++p2)
if (*p2 == '\\' && *(p2 + 1) != NUL)
STRCPY(p2, p2 + 1);
}
return p1;
}
/*
* Same as vim_strsave(), but any characters found in esc_chars are preceded
* by a backslash.
*/
char_u *
vim_strsave_escaped(string, esc_chars)
char_u *string;
char_u *esc_chars;
{
char_u *p;
char_u *p2;
char_u *escaped_string;
unsigned length;
/*
* First count the number of backslashes required.
* Then allocate the memory and insert them.
*/
length = 1; /* count the trailing '/' and NUL */
for (p = string; *p; p++)
{
if (vim_strchr(esc_chars, *p) != NULL)
++length; /* count a backslash */
++length; /* count an ordinary char */
}
escaped_string = alloc(length);
if (escaped_string != NULL)
{
p2 = escaped_string;
for (p = string; *p; p++)
{
if (vim_strchr(esc_chars, *p) != NULL)
*p2++ = '\\';
*p2++ = *p;
}
*p2 = NUL;
}
return escaped_string;
}
/*
* like vim_strsave(), but make all characters uppercase.
*/
char_u *
vim_strsave_up(string)
char_u *string;
{
char_u *p1;
p1 = vim_strsave(string);
vim_strup(p1);
return p1;
}
/*
* like vim_strnsave(), but make all characters uppercase.
*/
char_u *
vim_strnsave_up(string, len)
char_u *string;
int len;
{
char_u *p1;
p1 = vim_strnsave(string, len);
vim_strup(p1);
return p1;
}
static void
vim_strup(p)
char_u *p;
{
char_u *p2;
int c;
if (p != NULL)
{
p2 = p;
while ((c = *p2) != NUL)
*p2++ = TO_UPPER(c);
}
}
/*
* copy a number of spaces
*/
void
copy_spaces(ptr, count)
char_u *ptr;
size_t count;
{
size_t i = count;
char_u *p = ptr;
while (i--)
*p++ = ' ';
}
/*
* delete spaces at the end of a string
*/
void
del_trailing_spaces(ptr)
char_u *ptr;
{
char_u *q;
q = ptr + STRLEN(ptr);
while (--q > ptr && vim_iswhite(q[0]) && q[-1] != '\\' &&
q[-1] != Ctrl('V'))
*q = NUL;
}
/*
* vim_strncpy()
*
* This is here because strncpy() does not guarantee successful results when
* the to and from strings overlap. It is only currently called from nextwild()
* which copies part of the command line to another part of the command line.
* This produced garbage when expanding files etc in the middle of the command
* line (on my terminal, anyway) -- webb.
*/
void
vim_strncpy(to, from, len)
char_u *to;
char_u *from;
int len;
{
int i;
if (to <= from)
{
while (len-- && *from)
*to++ = *from++;
if (len >= 0)
*to = *from; /* Copy NUL */
}
else
{
for (i = 0; i < len; i++)
{
to++;
if (*from++ == NUL)
{
i++;
break;
}
}
for (; i > 0; i--)
*--to = *--from;
}
}
/*
* Isolate one part of a string option where parts are separated with commas.
* The part is copied into buf[maxlen].
* "*option" is advanced to the next part.
* The length is returned.
*/
int
copy_option_part(option, buf, maxlen, sep_chars)
char_u **option;
char_u *buf;
int maxlen;
char *sep_chars;
{
int len = 0;
char_u *p = *option;
/* skip '.' at start of option part, for 'suffixes' */
if (*p == '.')
buf[len++] = *p++;
while (*p && vim_strchr((char_u *)sep_chars, *p) == NULL)
{
/*
* Skip backslash before a separator character and space.
*/
if (p[0] == '\\' && vim_strchr((char_u *)sep_chars, p[1]) != NULL)
++p;
if (len < maxlen - 1)
buf[len++] = *p;
++p;
}
buf[len] = NUL;
p = skip_to_option_part(p); /* p points to next file name */
*option = p;
return len;
}
/*
* replacement for free() that ignores NULL pointers
*/
void
vim_free(x)
void *x;
{
if (x != NULL)
{
#ifdef MEM_PROFILE
mem_pre_free(&x);
#endif
free(x);
}
}
#ifndef HAVE_MEMSET
void *
vim_memset(ptr, c, size)
void *ptr;
int c;
size_t size;
{
char *p = ptr;
while (size-- > 0)
*p++ = c;
return ptr;
}
#endif
#ifdef VIM_MEMCMP
/*
* Return zero when "b1" and "b2" are the same for "len" bytes.
* Return non-zero otherwise.
*/
int
vim_memcmp(b1, b2, len)
void *b1;
void *b2;
size_t len;
{
char_u *p1 = (char_u *)b1, *p2 = (char_u *)b2;
for ( ; len > 0; --len)
{
if (*p1 != *p2)
return 1;
++p1;
++p2;
}
return 0;
}
#endif
#ifdef VIM_MEMMOVE
/*
* Version of memmove that handles overlapping source and destination.
* For systems that don't have a function that is guaranteed to do that (SYSV).
*/
void
mch_memmove(dst_arg, src_arg, len)
void *src_arg, *dst_arg;
size_t len;
{
/*
* A void doesn't have a size, we use char pointers.
*/
char *dst = dst_arg, *src = src_arg;
/* overlap, copy backwards */
if (dst > src && dst < src + len)
{
src +=len;
dst +=len;
while (len-- > 0)
*--dst = *--src;
}
else /* copy forwards */
while (len-- > 0)
*dst++ = *src++;
}
#endif
#if (!defined(HAVE_STRCASECMP) && !defined(HAVE_STRICMP)) || defined(PROTO)
/*
* Compare two strings, ignoring case.
* return 0 for match, 1 for difference
*/
int
vim_stricmp(s1, s2)
char *s1;
char *s2;
{
for (;;)
{
if (TO_LOWER(*s1) != TO_LOWER(*s2))
return 1; /* this character different */
if (*s1 == NUL)
break; /* strings match until NUL */
++s1;
++s2;
}
return 0; /* strings match */
}
#endif
#if (!defined(HAVE_STRNCASECMP) && !defined(HAVE_STRNICMP)) || defined(PROTO)
/*
* Compare two strings, for length "len", ignoring case.
* return 0 for match, 1 for difference
*/
int
vim_strnicmp(s1, s2, len)
char *s1;
char *s2;
size_t len;
{
while (len)
{
if (TO_LOWER(*s1) != TO_LOWER(*s2))
return 1; /* this character different */
if (*s1 == NUL)
break; /* strings match until NUL */
++s1;
++s2;
--len;
}
return 0; /* strings match */
}
#endif
/*
* Version of strchr() and strrchr() that handle unsigned char strings
* with characters above 128 correctly. Also it doesn't return a pointer to
* the NUL at the end of the string.
*/
char_u *
vim_strchr(string, n)
char_u *string;
int n;
{
char_u *p;
int c;
p = string;
while ((c = *p) != NUL)
{
if (c == n)
return p;
++p;
}
return NULL;
}
char_u *
vim_strrchr(string, n)
char_u *string;
int n;
{
char_u *retval = NULL;
while (*string)
{
if (*string == n)
retval = string;
++string;
}
return retval;
}
/*
* Vim's version of strpbrk(), in case it's missing.
* Don't generate a prototype for this, causes problems when it's not used.
*/
#ifndef PROTO
# ifndef HAVE_STRPBRK
# ifdef vim_strpbrk
# undef vim_strpbrk
# endif
char_u *
vim_strpbrk(s, charset)
char_u *s;
char_u *charset;
{
while (*s)
{
if (vim_strchr(charset, *s) != NULL)
return s;
++s;
}
return NULL;
}
# endif
#endif
/*
* Vim has its own isspace() function, because on some machines isspace()
* can't handle characters above 128.
*/
int
vim_isspace(x)
int x;
{
return ((x >= 9 && x <= 13) || x == ' ');
}
/************************************************************************
* Functions for hanlding growing arrays.
*/
/*
* Clear an allocated growing array.
*/
void
ga_clear(gap)
struct growarray *gap;
{
vim_free(gap->ga_data);
ga_init(gap);
}
/*
* Clear a growing array that contains a list of strings.
*/
void
ga_clear_strings(gap)
struct growarray *gap;
{
int i;
for (i = 0; i < gap->ga_len; ++i)
vim_free(((char_u **)(gap->ga_data))[i]);
ga_clear(gap);
}
/*
* Initialize a growing array. Don't forget to set ga_itemsize and
* ga_growsize! Or use ga_init2().
*/
void
ga_init(gap)
struct growarray *gap;
{
gap->ga_data = NULL;
gap->ga_room = 0;
gap->ga_len = 0;
}
void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -