diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/misc2.c | 495 | ||||
| -rw-r--r-- | src/misc2.h | 23 | ||||
| -rw-r--r-- | src/strings.c | 536 | ||||
| -rw-r--r-- | src/strings.h | 26 | 
4 files changed, 562 insertions, 518 deletions
| diff --git a/src/misc2.c b/src/misc2.c index d946bd66f5..06a4764250 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -592,92 +592,6 @@ int leftcol_changed(void)  }  /* - * Copy "string" into newly allocated memory. - */ -char_u *vim_strsave(char_u *string) -{ -  char_u      *p; -  unsigned len; - -  len = (unsigned)STRLEN(string) + 1; -  p = alloc(len); -  if (p != NULL) -    memmove(p, string, (size_t)len); -  return p; -} - -/* - * Copy up to "len" bytes of "string" into newly allocated memory and - * terminate with a NUL. - * The allocated memory always has size "len + 1", also when "string" is - * shorter. - */ -char_u *vim_strnsave(char_u *string, int len) -{ -  char_u      *p; - -  p = alloc((unsigned)(len + 1)); -  STRNCPY(p, string, len); -  p[len] = NUL; -  return p; -} - -/* - * Same as vim_strsave(), but any characters found in esc_chars are preceded - * by a backslash. - */ -char_u *vim_strsave_escaped(char_u *string, char_u *esc_chars) -{ -  return vim_strsave_escaped_ext(string, esc_chars, '\\', FALSE); -} - -/* - * Same as vim_strsave_escaped(), but when "bsl" is TRUE also escape - * characters where rem_backslash() would remove the backslash. - * Escape the characters with "cc". - */ -char_u *vim_strsave_escaped_ext(char_u *string, char_u *esc_chars, int cc, int bsl) -{ -  char_u      *p; -  char_u      *p2; -  char_u      *escaped_string; -  unsigned length; -  int l; - -  /* -   * First count the number of backslashes required. -   * Then allocate the memory and insert them. -   */ -  length = 1;                           /* count the trailing NUL */ -  for (p = string; *p; p++) { -    if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) { -      length += l;                      /* count a multibyte char */ -      p += l - 1; -      continue; -    } -    if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p))) -      ++length;                         /* count a backslash */ -    ++length;                           /* count an ordinary char */ -  } -  escaped_string = alloc(length); -  p2 = escaped_string; -  for (p = string; *p; p++) { -    if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) { -      memmove(p2, p, (size_t)l); -      p2 += l; -      p += l - 1;                     /* skip multibyte char  */ -      continue; -    } -    if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p))) -      *p2++ = cc; -    *p2++ = *p; -  } -  *p2 = NUL; - -  return escaped_string; -} - -/*   * Return TRUE when 'shell' has "csh" in the tail.   */  int csh_like_shell(void) @@ -686,243 +600,6 @@ int csh_like_shell(void)  }  /* - * Escape "string" for use as a shell argument with system(). - * This uses single quotes, except when we know we need to use double quotes - * (MS-Windows without 'shellslash' set). - * Escape a newline, depending on the 'shell' option. - * When "do_special" is true also replace "!", "%", "#" and things starting - * with "<" like "<cfile>". - * When "do_newline" is false do not escape newline unless it is csh shell. - * Returns the result in allocated memory. - */ -char_u *vim_strsave_shellescape(char_u *string, bool do_special, bool do_newline) -{ -  unsigned length; -  char_u      *p; -  char_u      *d; -  char_u      *escaped_string; -  int l; -  int csh_like; - -  /* Only csh and similar shells expand '!' within single quotes.  For sh and -   * the like we must not put a backslash before it, it will be taken -   * literally.  If do_special is set the '!' will be escaped twice. -   * Csh also needs to have "\n" escaped twice when do_special is set. */ -  csh_like = csh_like_shell(); - -  /* First count the number of extra bytes required. */ -  length = (unsigned)STRLEN(string) + 3;    /* two quotes and a trailing NUL */ -  for (p = string; *p != NUL; mb_ptr_adv(p)) { -    if (*p == '\'') -      length += 3;                      /* ' => '\'' */ -    if ((*p == '\n' && (csh_like || do_newline)) -        || (*p == '!' && (csh_like || do_special))) { -      ++length;                         /* insert backslash */ -      if (csh_like && do_special) -        ++length;                       /* insert backslash */ -    } -    if (do_special && find_cmdline_var(p, &l) >= 0) { -      ++length;                         /* insert backslash */ -      p += l - 1; -    } -  } - -  /* Allocate memory for the result and fill it. */ -  escaped_string = alloc(length); -  d = escaped_string; - -  /* add opening quote */ -  *d++ = '\''; - -  for (p = string; *p != NUL; ) { -    if (*p == '\'') { -      *d++ = '\''; -      *d++ = '\\'; -      *d++ = '\''; -      *d++ = '\''; -      ++p; -      continue; -    } -    if ((*p == '\n' && (csh_like || do_newline)) -        || (*p == '!' && (csh_like || do_special))) { -      *d++ = '\\'; -      if (csh_like && do_special) -        *d++ = '\\'; -      *d++ = *p++; -      continue; -    } -    if (do_special && find_cmdline_var(p, &l) >= 0) { -      *d++ = '\\';                    /* insert backslash */ -      while (--l >= 0)                /* copy the var */ -        *d++ = *p++; -      continue; -    } - -    MB_COPY_CHAR(p, d); -  } - -  /* add terminating quote and finish with a NUL */ -  *d++ = '\''; -  *d = NUL; - -  return escaped_string; -} - -/* - * Like vim_strsave(), but make all characters uppercase. - * This uses ASCII lower-to-upper case translation, language independent. - */ -char_u *vim_strsave_up(char_u *string) -{ -  char_u *p1; - -  p1 = vim_strsave(string); -  vim_strup(p1); -  return p1; -} - -/* - * Like vim_strnsave(), but make all characters uppercase. - * This uses ASCII lower-to-upper case translation, language independent. - */ -char_u *vim_strnsave_up(char_u *string, int len) -{ -  char_u *p1; - -  p1 = vim_strnsave(string, len); -  vim_strup(p1); -  return p1; -} - -/* - * ASCII lower-to-upper case translation, language independent. - */ -void vim_strup(char_u *p) -{ -  char_u  *p2; -  int c; - -  if (p != NULL) { -    p2 = p; -    while ((c = *p2) != NUL) -      *p2++ = (c < 'a' || c > 'z') ? c : (c - 0x20); -  } -} - -/* - * Make string "s" all upper-case and return it in allocated memory. - * Handles multi-byte characters as well as possible. - * Returns NULL when out of memory. - */ -char_u *strup_save(char_u *orig) -{ -  char_u      *p; -  char_u      *res; - -  res = p = vim_strsave(orig); - -  if (res != NULL) -    while (*p != NUL) { -      int l; - -      if (enc_utf8) { -        int c, uc; -        int newl; -        char_u  *s; - -        c = utf_ptr2char(p); -        uc = utf_toupper(c); - -        /* Reallocate string when byte count changes.  This is rare, -         * thus it's OK to do another malloc()/free(). */ -        l = utf_ptr2len(p); -        newl = utf_char2len(uc); -        if (newl != l) { -          s = alloc((unsigned)STRLEN(res) + 1 + newl - l); -          memmove(s, res, p - res); -          STRCPY(s + (p - res) + newl, p + l); -          p = s + (p - res); -          vim_free(res); -          res = s; -        } - -        utf_char2bytes(uc, p); -        p += newl; -      } else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) -        p += l;                 /* skip multi-byte character */ -      else { -        *p = TOUPPER_LOC(*p);         /* note that toupper() can be a macro */ -        p++; -      } -    } - -  return res; -} - -/* - * copy a space a number of times - */ -void copy_spaces(char_u *ptr, size_t count) -{ -  size_t i = count; -  char_u      *p = ptr; - -  while (i--) -    *p++ = ' '; -} - -/* - * Copy a character a number of times. - * Does not work for multi-byte characters! - */ -void copy_chars(char_u *ptr, size_t count, int c) -{ -  size_t i = count; -  char_u      *p = ptr; - -  while (i--) -    *p++ = c; -} - -/* - * delete spaces at the end of a string - */ -void del_trailing_spaces(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; -} - -/* - * Like strncpy(), but always terminate the result with one NUL. - * "to" must be "len + 1" long! - */ -void vim_strncpy(char_u *to, char_u *from, size_t len) -{ -  STRNCPY(to, from, len); -  to[len] = NUL; -} - -/* - * Like strcat(), but make sure the result fits in "tosize" bytes and is - * always NUL terminated. - */ -void vim_strcat(char_u *to, char_u *from, size_t tosize) -{ -  size_t tolen = STRLEN(to); -  size_t fromlen = STRLEN(from); - -  if (tolen + fromlen + 1 > tosize) { -    memmove(to + tolen, from, tosize - tolen - 1); -    to[tosize - 1] = NUL; -  } else -    STRCPY(to + tolen, from); -} - -/*   * Isolate one part of a string option where parts are separated with   * "sep_chars".   * The part is copied into "buf[maxlen]". @@ -969,143 +646,6 @@ void vim_free(void *x)    }  } -#if (!defined(HAVE_STRCASECMP) && !defined(HAVE_STRICMP)) || defined(PROTO) -/* - * Compare two strings, ignoring case, using current locale. - * Doesn't work for multi-byte characters. - * return 0 for match, < 0 for smaller, > 0 for bigger - */ -int vim_stricmp(char *s1, char *s2) -{ -  int i; - -  for (;; ) { -    i = (int)TOLOWER_LOC(*s1) - (int)TOLOWER_LOC(*s2); -    if (i != 0) -      return i;                             /* 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, using current locale. - * Doesn't work for multi-byte characters. - * return 0 for match, < 0 for smaller, > 0 for bigger - */ -int vim_strnicmp(char *s1, char *s2, size_t len) -{ -  int i; - -  while (len > 0) { -    i = (int)TOLOWER_LOC(*s1) - (int)TOLOWER_LOC(*s2); -    if (i != 0) -      return i;                             /* 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 from 128 to 255 correctly.  It also doesn't return a - * pointer to the NUL at the end of the string. - */ -char_u *vim_strchr(char_u *string, int c) -{ -  char_u      *p; -  int b; - -  p = string; -  if (enc_utf8 && c >= 0x80) { -    while (*p != NUL) { -      if (utf_ptr2char(p) == c) -        return p; -      p += (*mb_ptr2len)(p); -    } -    return NULL; -  } -  if (enc_dbcs != 0 && c > 255) { -    int n2 = c & 0xff; - -    c = ((unsigned)c >> 8) & 0xff; -    while ((b = *p) != NUL) { -      if (b == c && p[1] == n2) -        return p; -      p += (*mb_ptr2len)(p); -    } -    return NULL; -  } -  if (has_mbyte) { -    while ((b = *p) != NUL) { -      if (b == c) -        return p; -      p += (*mb_ptr2len)(p); -    } -    return NULL; -  } -  while ((b = *p) != NUL) { -    if (b == c) -      return p; -    ++p; -  } -  return NULL; -} - -/* - * Version of strchr() that only works for bytes and handles unsigned char - * strings with characters above 128 correctly. It also doesn't return a - * pointer to the NUL at the end of the string. - */ -char_u *vim_strbyte(char_u *string, int c) -{ -  char_u      *p = string; - -  while (*p != NUL) { -    if (*p == c) -      return p; -    ++p; -  } -  return NULL; -} - -/* - * Search for last occurrence of "c" in "string". - * Return NULL if not found. - * Does not handle multi-byte char for "c"! - */ -char_u *vim_strrchr(char_u *string, int c) -{ -  char_u      *retval = NULL; -  char_u      *p = string; - -  while (*p) { -    if (*p == c) -      retval = p; -    mb_ptr_adv(p); -  } -  return retval; -} - -/* - * Vim has its own isspace() function, because on some machines isspace() - * can't handle characters above 128. - */ -int vim_isspace(int x) -{ -  return (x >= 9 && x <= 13) || x == ' '; -} -  /*   * Return the current end-of-line type: EOL_DOS, EOL_UNIX or EOL_MAC.   */ @@ -1334,21 +874,6 @@ int vim_chdir(char_u *new_dir)    return r;  } -/* - * Sort an array of strings. - */ -static int -sort_compare(const void *s1, const void *s2); - -static int sort_compare(const void *s1, const void *s2) -{ -  return STRCMP(*(char **)s1, *(char **)s2); -} - -void sort_strings(char_u **files, int count) -{ -  qsort((void *)files, (size_t)count, sizeof(char_u *), sort_compare); -}  /*   * Print an error message with one or two "%s" and one or two string arguments. @@ -1496,23 +1021,3 @@ void put_time(FILE *fd, time_t the_time)      }    }  } - - - -#if (defined(FEAT_MBYTE) && defined(FEAT_QUICKFIX)) \ -  || defined(FEAT_SPELL) || defined(PROTO) -/* - * Return TRUE if string "s" contains a non-ASCII character (128 or higher). - * When "s" is NULL FALSE is returned. - */ -int has_non_ascii(char_u *s) -{ -  char_u      *p; - -  if (s != NULL) -    for (p = s; *p != NUL; ++p) -      if (*p >= 128) -        return TRUE; -  return FALSE; -} -#endif diff --git a/src/misc2.h b/src/misc2.h index e73bbfaddf..7567b11e60 100644 --- a/src/misc2.h +++ b/src/misc2.h @@ -24,32 +24,10 @@ void check_cursor_col_win(win_T *win);  void check_cursor(void);  void adjust_cursor_col(void);  int leftcol_changed(void); -char_u *vim_strsave(char_u *string); -char_u *vim_strnsave(char_u *string, int len); -char_u *vim_strsave_escaped(char_u *string, char_u *esc_chars); -char_u *vim_strsave_escaped_ext(char_u *string, char_u *esc_chars, -                                int cc, -                                int bsl);  int csh_like_shell(void); -char_u *vim_strsave_shellescape(char_u *string, bool do_special, bool do_newline); -char_u *vim_strsave_up(char_u *string); -char_u *vim_strnsave_up(char_u *string, int len); -void vim_strup(char_u *p); -char_u *strup_save(char_u *orig); -void copy_spaces(char_u *ptr, size_t count); -void copy_chars(char_u *ptr, size_t count, int c); -void del_trailing_spaces(char_u *ptr); -void vim_strncpy(char_u *to, char_u *from, size_t len); -void vim_strcat(char_u *to, char_u *from, size_t tosize);  int copy_option_part(char_u **option, char_u *buf, int maxlen,                       char *sep_chars);  void vim_free(void *x); -int vim_stricmp(char *s1, char *s2); -int vim_strnicmp(char *s1, char *s2, size_t len); -char_u *vim_strchr(char_u *string, int c); -char_u *vim_strbyte(char_u *string, int c); -char_u *vim_strrchr(char_u *string, int c); -int vim_isspace(int x);  int get_fileformat(buf_T *buf);  int get_fileformat_force(buf_T *buf, exarg_T *eap);  void set_fileformat(int t, int opt_flags); @@ -59,7 +37,6 @@ int get_real_state(void);  int vim_chdirfile(char_u *fname);  int illegal_slash(char *name);  int vim_chdir(char_u *new_dir); -void sort_strings(char_u **files, int count);  int emsg3(char_u *s, char_u *a1, char_u *a2);  int emsgn(char_u *s, int64_t n);  int get2c(FILE *fd); diff --git a/src/strings.c b/src/strings.c new file mode 100644 index 0000000000..f9c4e2f1db --- /dev/null +++ b/src/strings.c @@ -0,0 +1,536 @@ +#include <string.h> + +#include "vim.h" +#include "strings.h" +#include "misc2.h" +#include "file_search.h" +#include "blowfish.h" +#include "buffer.h" +#include "charset.h" +#include "diff.h" +#include "edit.h" +#include "eval.h" +#include "ex_cmds.h" +#include "ex_docmd.h" +#include "ex_getln.h" +#include "fileio.h" +#include "fold.h" +#include "getchar.h" +#include "mark.h" +#include "mbyte.h" +#include "memfile.h" +#include "memline.h" +#include "memory.h" +#include "message.h" +#include "misc1.h" +#include "move.h" +#include "option.h" +#include "ops.h" +#include "os_unix.h" +#include "path.h" +#include "quickfix.h" +#include "regexp.h" +#include "screen.h" +#include "search.h" +#include "spell.h" +#include "syntax.h" +#include "tag.h" +#include "term.h" +#include "ui.h" +#include "window.h" +#include "os/os.h" +#include "os/shell.h" + +/* + * Copy "string" into newly allocated memory. + */ +char_u *vim_strsave(char_u *string) +{ +  char_u      *p; +  unsigned len; + +  len = (unsigned)STRLEN(string) + 1; +  p = alloc(len); +  if (p != NULL) +    memmove(p, string, (size_t)len); +  return p; +} + +/* + * Copy up to "len" bytes of "string" into newly allocated memory and + * terminate with a NUL. + * The allocated memory always has size "len + 1", also when "string" is + * shorter. + */ +char_u *vim_strnsave(char_u *string, int len) +{ +  char_u      *p; + +  p = alloc((unsigned)(len + 1)); +  STRNCPY(p, string, len); +  p[len] = NUL; +  return p; +} + +/* + * Same as vim_strsave(), but any characters found in esc_chars are preceded + * by a backslash. + */ +char_u *vim_strsave_escaped(char_u *string, char_u *esc_chars) +{ +  return vim_strsave_escaped_ext(string, esc_chars, '\\', FALSE); +} + +/* + * Same as vim_strsave_escaped(), but when "bsl" is TRUE also escape + * characters where rem_backslash() would remove the backslash. + * Escape the characters with "cc". + */ +char_u *vim_strsave_escaped_ext(char_u *string, char_u *esc_chars, int cc, int bsl) +{ +  char_u      *p; +  char_u      *p2; +  char_u      *escaped_string; +  unsigned length; +  int l; + +  /* +   * First count the number of backslashes required. +   * Then allocate the memory and insert them. +   */ +  length = 1;                           /* count the trailing NUL */ +  for (p = string; *p; p++) { +    if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) { +      length += l;                      /* count a multibyte char */ +      p += l - 1; +      continue; +    } +    if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p))) +      ++length;                         /* count a backslash */ +    ++length;                           /* count an ordinary char */ +  } +  escaped_string = alloc(length); +  p2 = escaped_string; +  for (p = string; *p; p++) { +    if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) { +      memmove(p2, p, (size_t)l); +      p2 += l; +      p += l - 1;                     /* skip multibyte char  */ +      continue; +    } +    if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p))) +      *p2++ = cc; +    *p2++ = *p; +  } +  *p2 = NUL; + +  return escaped_string; +} + +/* + * Escape "string" for use as a shell argument with system(). + * This uses single quotes, except when we know we need to use double quotes + * (MS-Windows without 'shellslash' set). + * Escape a newline, depending on the 'shell' option. + * When "do_special" is true also replace "!", "%", "#" and things starting + * with "<" like "<cfile>". + * When "do_newline" is false do not escape newline unless it is csh shell. + * Returns the result in allocated memory. + */ +char_u *vim_strsave_shellescape(char_u *string, bool do_special, bool do_newline) +{ +  unsigned length; +  char_u      *p; +  char_u      *d; +  char_u      *escaped_string; +  int l; +  int csh_like; + +  /* Only csh and similar shells expand '!' within single quotes.  For sh and +   * the like we must not put a backslash before it, it will be taken +   * literally.  If do_special is set the '!' will be escaped twice. +   * Csh also needs to have "\n" escaped twice when do_special is set. */ +  csh_like = csh_like_shell(); + +  /* First count the number of extra bytes required. */ +  length = (unsigned)STRLEN(string) + 3;    /* two quotes and a trailing NUL */ +  for (p = string; *p != NUL; mb_ptr_adv(p)) { +    if (*p == '\'') +      length += 3;                      /* ' => '\'' */ +    if ((*p == '\n' && (csh_like || do_newline)) +        || (*p == '!' && (csh_like || do_special))) { +      ++length;                         /* insert backslash */ +      if (csh_like && do_special) +        ++length;                       /* insert backslash */ +    } +    if (do_special && find_cmdline_var(p, &l) >= 0) { +      ++length;                         /* insert backslash */ +      p += l - 1; +    } +  } + +  /* Allocate memory for the result and fill it. */ +  escaped_string = alloc(length); +  d = escaped_string; + +  /* add opening quote */ +  *d++ = '\''; + +  for (p = string; *p != NUL; ) { +    if (*p == '\'') { +      *d++ = '\''; +      *d++ = '\\'; +      *d++ = '\''; +      *d++ = '\''; +      ++p; +      continue; +    } +    if ((*p == '\n' && (csh_like || do_newline)) +        || (*p == '!' && (csh_like || do_special))) { +      *d++ = '\\'; +      if (csh_like && do_special) +        *d++ = '\\'; +      *d++ = *p++; +      continue; +    } +    if (do_special && find_cmdline_var(p, &l) >= 0) { +      *d++ = '\\';                    /* insert backslash */ +      while (--l >= 0)                /* copy the var */ +        *d++ = *p++; +      continue; +    } + +    MB_COPY_CHAR(p, d); +  } + +  /* add terminating quote and finish with a NUL */ +  *d++ = '\''; +  *d = NUL; + +  return escaped_string; +} + +/* + * Like vim_strsave(), but make all characters uppercase. + * This uses ASCII lower-to-upper case translation, language independent. + */ +char_u *vim_strsave_up(char_u *string) +{ +  char_u *p1; + +  p1 = vim_strsave(string); +  vim_strup(p1); +  return p1; +} + +/* + * Like vim_strnsave(), but make all characters uppercase. + * This uses ASCII lower-to-upper case translation, language independent. + */ +char_u *vim_strnsave_up(char_u *string, int len) +{ +  char_u *p1; + +  p1 = vim_strnsave(string, len); +  vim_strup(p1); +  return p1; +} + +/* + * ASCII lower-to-upper case translation, language independent. + */ +void vim_strup(char_u *p) +{ +  char_u  *p2; +  int c; + +  if (p != NULL) { +    p2 = p; +    while ((c = *p2) != NUL) +      *p2++ = (c < 'a' || c > 'z') ? c : (c - 0x20); +  } +} + +/* + * Make string "s" all upper-case and return it in allocated memory. + * Handles multi-byte characters as well as possible. + * Returns NULL when out of memory. + */ +char_u *strup_save(char_u *orig) +{ +  char_u      *p; +  char_u      *res; + +  res = p = vim_strsave(orig); + +  if (res != NULL) +    while (*p != NUL) { +      int l; + +      if (enc_utf8) { +        int c, uc; +        int newl; +        char_u  *s; + +        c = utf_ptr2char(p); +        uc = utf_toupper(c); + +        /* Reallocate string when byte count changes.  This is rare, +         * thus it's OK to do another malloc()/free(). */ +        l = utf_ptr2len(p); +        newl = utf_char2len(uc); +        if (newl != l) { +          s = alloc((unsigned)STRLEN(res) + 1 + newl - l); +          memmove(s, res, p - res); +          STRCPY(s + (p - res) + newl, p + l); +          p = s + (p - res); +          vim_free(res); +          res = s; +        } + +        utf_char2bytes(uc, p); +        p += newl; +      } else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) +        p += l;                 /* skip multi-byte character */ +      else { +        *p = TOUPPER_LOC(*p);         /* note that toupper() can be a macro */ +        p++; +      } +    } + +  return res; +} + +/* + * copy a space a number of times + */ +void copy_spaces(char_u *ptr, size_t count) +{ +  size_t i = count; +  char_u      *p = ptr; + +  while (i--) +    *p++ = ' '; +} + +/* + * Copy a character a number of times. + * Does not work for multi-byte characters! + */ +void copy_chars(char_u *ptr, size_t count, int c) +{ +  size_t i = count; +  char_u      *p = ptr; + +  while (i--) +    *p++ = c; +} + +/* + * delete spaces at the end of a string + */ +void del_trailing_spaces(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; +} + +/* + * Like strncpy(), but always terminate the result with one NUL. + * "to" must be "len + 1" long! + */ +void vim_strncpy(char_u *to, char_u *from, size_t len) +{ +  STRNCPY(to, from, len); +  to[len] = NUL; +} + +/* + * Like strcat(), but make sure the result fits in "tosize" bytes and is + * always NUL terminated. + */ +void vim_strcat(char_u *to, char_u *from, size_t tosize) +{ +  size_t tolen = STRLEN(to); +  size_t fromlen = STRLEN(from); + +  if (tolen + fromlen + 1 > tosize) { +    memmove(to + tolen, from, tosize - tolen - 1); +    to[tosize - 1] = NUL; +  } else +    STRCPY(to + tolen, from); +} + +#if (!defined(HAVE_STRCASECMP) && !defined(HAVE_STRICMP)) || defined(PROTO) +/* + * Compare two strings, ignoring case, using current locale. + * Doesn't work for multi-byte characters. + * return 0 for match, < 0 for smaller, > 0 for bigger + */ +int vim_stricmp(char *s1, char *s2) +{ +  int i; + +  for (;; ) { +    i = (int)TOLOWER_LOC(*s1) - (int)TOLOWER_LOC(*s2); +    if (i != 0) +      return i;                             /* 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, using current locale. + * Doesn't work for multi-byte characters. + * return 0 for match, < 0 for smaller, > 0 for bigger + */ +int vim_strnicmp(char *s1, char *s2, size_t len) +{ +  int i; + +  while (len > 0) { +    i = (int)TOLOWER_LOC(*s1) - (int)TOLOWER_LOC(*s2); +    if (i != 0) +      return i;                             /* 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 from 128 to 255 correctly.  It also doesn't return a + * pointer to the NUL at the end of the string. + */ +char_u *vim_strchr(char_u *string, int c) +{ +  char_u      *p; +  int b; + +  p = string; +  if (enc_utf8 && c >= 0x80) { +    while (*p != NUL) { +      if (utf_ptr2char(p) == c) +        return p; +      p += (*mb_ptr2len)(p); +    } +    return NULL; +  } +  if (enc_dbcs != 0 && c > 255) { +    int n2 = c & 0xff; + +    c = ((unsigned)c >> 8) & 0xff; +    while ((b = *p) != NUL) { +      if (b == c && p[1] == n2) +        return p; +      p += (*mb_ptr2len)(p); +    } +    return NULL; +  } +  if (has_mbyte) { +    while ((b = *p) != NUL) { +      if (b == c) +        return p; +      p += (*mb_ptr2len)(p); +    } +    return NULL; +  } +  while ((b = *p) != NUL) { +    if (b == c) +      return p; +    ++p; +  } +  return NULL; +} + +/* + * Version of strchr() that only works for bytes and handles unsigned char + * strings with characters above 128 correctly. It also doesn't return a + * pointer to the NUL at the end of the string. + */ +char_u *vim_strbyte(char_u *string, int c) +{ +  char_u      *p = string; + +  while (*p != NUL) { +    if (*p == c) +      return p; +    ++p; +  } +  return NULL; +} + +/* + * Search for last occurrence of "c" in "string". + * Return NULL if not found. + * Does not handle multi-byte char for "c"! + */ +char_u *vim_strrchr(char_u *string, int c) +{ +  char_u      *retval = NULL; +  char_u      *p = string; + +  while (*p) { +    if (*p == c) +      retval = p; +    mb_ptr_adv(p); +  } +  return retval; +} + +/* + * Vim has its own isspace() function, because on some machines isspace() + * can't handle characters above 128. + */ +int vim_isspace(int x) +{ +  return (x >= 9 && x <= 13) || x == ' '; +} + +/* + * Sort an array of strings. + */ +static int +sort_compare(const void *s1, const void *s2); + +static int sort_compare(const void *s1, const void *s2) +{ +  return STRCMP(*(char **)s1, *(char **)s2); +} + +void sort_strings(char_u **files, int count) +{ +  qsort((void *)files, (size_t)count, sizeof(char_u *), sort_compare); +} + +#if (defined(FEAT_MBYTE) && defined(FEAT_QUICKFIX)) \ +  || defined(FEAT_SPELL) || defined(PROTO) +/* + * Return TRUE if string "s" contains a non-ASCII character (128 or higher). + * When "s" is NULL FALSE is returned. + */ +int has_non_ascii(char_u *s) +{ +  char_u      *p; + +  if (s != NULL) +    for (p = s; *p != NUL; ++p) +      if (*p >= 128) +        return TRUE; +  return FALSE; +} +#endif diff --git a/src/strings.h b/src/strings.h new file mode 100644 index 0000000000..bd34d870ea --- /dev/null +++ b/src/strings.h @@ -0,0 +1,26 @@ +#ifndef NEOVIM_STRINGS_H +#define NEOVIM_STRINGS_H +char_u *vim_strsave(char_u *string); +char_u *vim_strnsave(char_u *string, int len); +char_u *vim_strsave_escaped(char_u *string, char_u *esc_chars); +char_u *vim_strsave_escaped_ext(char_u *string, char_u *esc_chars, +                                int cc, +                                int bsl); +char_u *vim_strsave_shellescape(char_u *string, bool do_special, bool do_newline); +char_u *vim_strsave_up(char_u *string); +char_u *vim_strnsave_up(char_u *string, int len); +void vim_strup(char_u *p); +char_u *strup_save(char_u *orig); +void copy_spaces(char_u *ptr, size_t count); +void copy_chars(char_u *ptr, size_t count, int c); +void del_trailing_spaces(char_u *ptr); +void vim_strncpy(char_u *to, char_u *from, size_t len); +void vim_strcat(char_u *to, char_u *from, size_t tosize); +int vim_stricmp(char *s1, char *s2); +int vim_strnicmp(char *s1, char *s2, size_t len); +char_u *vim_strchr(char_u *string, int c); +char_u *vim_strbyte(char_u *string, int c); +char_u *vim_strrchr(char_u *string, int c); +int vim_isspace(int x); +void sort_strings(char_u **files, int count); +#endif | 
