diff options
| author | Justin M. Keyes <justinkz@gmail.com> | 2015-10-30 12:45:34 -0400 | 
|---|---|---|
| committer | Justin M. Keyes <justinkz@gmail.com> | 2015-10-30 12:45:34 -0400 | 
| commit | d1cfaa0a55412758259f65837f4ff595204acd37 (patch) | |
| tree | 864943c778dc463d36c0e168d12225a2833eeece /src | |
| parent | 4abf108f4639af1c35bc0554a069d878a50fcea0 (diff) | |
| parent | 10080366b8975e827b64fda49a9686117c8c8f44 (diff) | |
| download | rneovim-d1cfaa0a55412758259f65837f4ff595204acd37.tar.gz rneovim-d1cfaa0a55412758259f65837f4ff595204acd37.tar.bz2 rneovim-d1cfaa0a55412758259f65837f4ff595204acd37.zip | |
Merge pull request #3553 from ZyX-I/fix-xdg-2
Some more fixes to XDG code
Diffstat (limited to 'src')
| -rw-r--r-- | src/nvim/eval.c | 7 | ||||
| -rw-r--r-- | src/nvim/ex_docmd.c | 4 | ||||
| -rw-r--r-- | src/nvim/memline.c | 2 | ||||
| -rw-r--r-- | src/nvim/option.c | 8 | ||||
| -rw-r--r-- | src/nvim/os/stdpaths.c | 8 | ||||
| -rw-r--r-- | src/nvim/undo.c | 172 | 
6 files changed, 120 insertions, 81 deletions
| diff --git a/src/nvim/eval.c b/src/nvim/eval.c index a1ac713a75..7685e422fc 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -16678,10 +16678,11 @@ static void f_undofile(typval_T *argvars, typval_T *rettv)        /* If there is no file name there will be no undo file. */        rettv->vval.v_string = NULL;      } else { -      char_u *ffname = (char_u *)FullName_save((char *)fname, FALSE); +      char *ffname = FullName_save((char *)fname, false); -      if (ffname != NULL) -        rettv->vval.v_string = u_get_undo_file_name(ffname, FALSE); +      if (ffname != NULL) { +        rettv->vval.v_string = (char_u *)u_get_undo_file_name(ffname, false); +      }        xfree(ffname);      }    } diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index e160281145..70cf5fd029 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -7193,7 +7193,7 @@ static void ex_wundo(exarg_T *eap)    char_u hash[UNDO_HASH_SIZE];    u_compute_hash(hash); -  u_write_undo(eap->arg, eap->forceit, curbuf, hash); +  u_write_undo((char *) eap->arg, eap->forceit, curbuf, hash);  }  static void ex_rundo(exarg_T *eap) @@ -7201,7 +7201,7 @@ static void ex_rundo(exarg_T *eap)    char_u hash[UNDO_HASH_SIZE];    u_compute_hash(hash); -  u_read_undo(eap->arg, hash, NULL); +  u_read_undo((char *) eap->arg, hash, NULL);  }  /* diff --git a/src/nvim/memline.c b/src/nvim/memline.c index dbb24e67a1..85f545f960 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -2990,7 +2990,7 @@ static void ml_lineadd(buf_T *buf, int count)   * If it worked returns OK and the resolved link in "buf[MAXPATHL]".   * Otherwise returns FAIL.   */ -int resolve_symlink(char_u *fname, char_u *buf) +int resolve_symlink(const char_u *fname, char_u *buf)  {    char_u tmp[MAXPATHL];    int ret; diff --git a/src/nvim/option.c b/src/nvim/option.c index f30d10d0bb..cc4df28837 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -685,9 +685,13 @@ void set_init_1(void)  #endif                       false); +  char *backupdir = stdpaths_user_data_subpath("backup", 0); +  const size_t backupdir_len = strlen(backupdir); +  backupdir = xrealloc(backupdir, backupdir_len + 3); +  memmove(backupdir + 2, backupdir, backupdir_len + 1); +  memmove(backupdir, ".,", 2);    set_string_default("viewdir", stdpaths_user_data_subpath("view", 0), true); -  set_string_default("backupdir", stdpaths_user_data_subpath("backup", 0), -                     true); +  set_string_default("backupdir", backupdir, true);    set_string_default("directory", stdpaths_user_data_subpath("swap", 2), true);    set_string_default("undodir", stdpaths_user_data_subpath("undo", 0), true);    // Set default for &runtimepath. All necessary expansions are performed in diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index ce374828f9..c9631a434c 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -25,7 +25,7 @@ static const char *const xdg_defaults[] = {    [kXDGConfigHome] = "$LOCALAPPDATA\\nvim\\config",    [kXDGDataHome]   = "$LOCALAPPDATA\\nvim\\data",    [kXDGCacheHome]  = "$LOCALAPPDATA\\nvim\\cache", -  [kXDGRuntimeDir] = "", +  [kXDGRuntimeDir] = NULL,    [kXDGConfigDirs] = NULL,    [kXDGDataDirs] = NULL,  #else @@ -33,7 +33,7 @@ static const char *const xdg_defaults[] = {    [kXDGConfigHome] = "~/.config",    [kXDGDataHome] = "~/.local/share",    [kXDGCacheHome] = "~/.cache", -  [kXDGRuntimeDir] = "", +  [kXDGRuntimeDir] = NULL,    [kXDGConfigDirs] = "/etc/xdg/",    [kXDGDataDirs] = "/usr/local/share/:/usr/share/",  #endif @@ -82,7 +82,7 @@ static char *get_xdg_home(const XDGVarType idx)  ///  /// @return [allocated] `$XDG_CONFIG_HOME/nvim/{fname}`  char *stdpaths_user_conf_subpath(const char *fname) -  FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL +  FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET  {    return concat_fnames_realloc(get_xdg_home(kXDGConfigHome), fname, true);  } @@ -95,7 +95,7 @@ char *stdpaths_user_conf_subpath(const char *fname)  /// @return [allocated] `$XDG_DATA_HOME/nvim/{fname}`  char *stdpaths_user_data_subpath(const char *fname,                                   const size_t trailing_pathseps) -  FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL +  FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET  {    char *ret = concat_fnames_realloc(get_xdg_home(kXDGDataHome), fname, true);    if (trailing_pathseps) { diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 2b0ffefa7e..d8158bf7cd 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -638,64 +638,89 @@ void u_compute_hash(char_u *hash)    sha256_finish(&ctx, hash);  } -/* - * Return an allocated string of the full path of the target undofile. - * When "reading" is TRUE find the file to read, go over all directories in - * 'undodir'. - * When "reading" is FALSE use the first name where the directory exists. - * Returns NULL when there is no place to write or no file to read. - */ -char_u *u_get_undo_file_name(char_u *buf_ffname, int reading) +/// Return an allocated string of the full path of the target undofile. +/// +/// @param[in]  buf_ffname  Full file name for which undo file location should +///                         be found. +/// @param[in]  reading  If true, find the file to read by traversing all of the +///                      directories in &undodir. If false use the first +///                      existing directory. If none of the directories in +///                      &undodir option exist then last directory in the list +///                      will be automatically created. +/// +/// @return [allocated] File name to read from/write to or NULL. +char *u_get_undo_file_name(const char *const buf_ffname, const bool reading) +  FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT  { -  char_u      *dirp; -  char_u dir_name[IOSIZE + 1]; -  char_u      *munged_name = NULL; -  char_u      *undo_file_name = NULL; -  char_u      *p; -  char_u      *ffname = buf_ffname; +  char *dirp; +  char dir_name[MAXPATHL + 1]; +  char *munged_name = NULL; +  char *undo_file_name = NULL; +  const char *ffname = buf_ffname;  #ifdef HAVE_READLINK -  char_u fname_buf[MAXPATHL]; +  char fname_buf[MAXPATHL];  #endif -  if (ffname == NULL) +  if (ffname == NULL) {      return NULL; +  }  #ifdef HAVE_READLINK -  /* Expand symlink in the file name, so that we put the undo file with the -   * actual file instead of with the symlink. */ -  if (resolve_symlink(ffname, fname_buf) == OK) +  // Expand symlink in the file name, so that we put the undo file with the +  // actual file instead of with the symlink. +  if (resolve_symlink((const char_u *)ffname, (char_u *)fname_buf) == OK) {      ffname = fname_buf; +  }  #endif -  /* Loop over 'undodir'.  When reading find the first file that exists. -   * When not reading use the first directory that exists or ".". */ -  dirp = p_udir; +  // Loop over 'undodir'.  When reading find the first file that exists. +  // When not reading use the first directory that exists or ".". +  dirp = (char *) p_udir;    while (*dirp != NUL) { -    size_t dir_len = copy_option_part(&dirp, dir_name, IOSIZE, ","); +    size_t dir_len = copy_option_part((char_u **)&dirp, (char_u *)dir_name, +                                      MAXPATHL, ",");      if (dir_len == 1 && dir_name[0] == '.') { -      /* Use same directory as the ffname, -       * "dir/name" -> "dir/.name.un~" */ -      undo_file_name = vim_strnsave(ffname, STRLEN(ffname) + 5); -      p = path_tail(undo_file_name); -      memmove(p + 1, p, STRLEN(p) + 1); -      *p = '.'; -      STRCAT(p, ".un~"); +      // Use same directory as the ffname, +      // "dir/name" -> "dir/.name.un~" +      const size_t ffname_len = strlen(ffname); +      undo_file_name = xmalloc(ffname_len + 6); +      memmove(undo_file_name, ffname, ffname_len + 1); +      char *const tail = (char *) path_tail((char_u *) undo_file_name); +      const size_t tail_len = strlen(tail); +      memmove(tail + 1, tail, tail_len + 1); +      *tail = '.'; +      memmove(tail + tail_len + 1, ".un~", sizeof(".un~"));      } else {        dir_name[dir_len] = NUL; -      if (os_isdir(dir_name)) { +      bool has_directory = os_isdir((char_u *)dir_name); +      if (!has_directory && *dirp == NUL && !reading) { +        // Last directory in the list does not exist, create it. +        int ret; +        char *failed_dir; +        if ((ret = os_mkdir_recurse(dir_name, 0755, &failed_dir)) != 0) { +          EMSG3(_("E926: Unable to create directory \"%s\" for undo file: %s"), +                failed_dir, os_strerror(ret)); +          xfree(failed_dir); +        } else { +          has_directory = true; +        } +      } +      if (has_directory) {          if (munged_name == NULL) { -          munged_name = vim_strsave(ffname); -          for (p = munged_name; *p != NUL; mb_ptr_adv(p)) -            if (vim_ispathsep(*p)) +          munged_name = xstrdup(ffname); +          for (char *p = munged_name; *p != NUL; mb_ptr_adv(p)) { +            if (vim_ispathsep(*p)) {                *p = '%'; +            } +          }          } -        undo_file_name = (char_u *)concat_fnames((char *)dir_name, (char *)munged_name, TRUE); +        undo_file_name = concat_fnames(dir_name, munged_name, true);        }      }      // When reading check if the file exists. -    if (undo_file_name != NULL && -        (!reading || os_file_exists(undo_file_name))) { +    if (undo_file_name != NULL +        && (!reading || os_file_exists((char_u *)undo_file_name))) {        break;      }      xfree(undo_file_name); @@ -706,7 +731,13 @@ char_u *u_get_undo_file_name(char_u *buf_ffname, int reading)    return undo_file_name;  } -static void corruption_error(char *mesg, char_u *file_name) +/// Display an error for corrupted undo file +/// +/// @param[in]  mesg  Identifier of the corruption kind. +/// @param[in]  file_name  File in which error occurred. +static void corruption_error(const char *const mesg, +                             const char *const file_name) +  FUNC_ATTR_NONNULL_ALL  {    EMSG3(_("E825: Corrupted undo file (%s): %s"), mesg, file_name);  } @@ -821,7 +852,8 @@ static bool serialize_uhp(bufinfo_T *bi, u_header_T *uhp)    return true;  } -static u_header_T *unserialize_uhp(bufinfo_T *bi, char_u *file_name) +static u_header_T *unserialize_uhp(bufinfo_T *bi, +                                   const char *file_name)  {    u_header_T *uhp = xmalloc(sizeof(u_header_T));    memset(uhp, 0, sizeof(u_header_T)); @@ -918,7 +950,8 @@ static bool serialize_uep(bufinfo_T *bi, u_entry_T *uep)    return true;  } -static u_entry_T *unserialize_uep(bufinfo_T * bi, bool *error, char_u *file_name) +static u_entry_T *unserialize_uep(bufinfo_T * bi, bool *error, +                                  const char *file_name)  {    u_entry_T *uep = xmalloc(sizeof(u_entry_T));    memset(uep, 0, sizeof(u_entry_T)); @@ -1000,19 +1033,20 @@ static void unserialize_visualinfo(bufinfo_T *bi, visualinfo_T *info)    info->vi_curswant = undo_read_4c(bi);  } -/* - * Write the undo tree in an undo file. - * When "name" is not NULL, use it as the name of the undo file. - * Otherwise use buf->b_ffname to generate the undo file name. - * "buf" must never be null, buf->b_ffname is used to obtain the original file - * permissions. - * "forceit" is TRUE for ":wundo!", FALSE otherwise. - * "hash[UNDO_HASH_SIZE]" must be the hash value of the buffer text. - */ -void u_write_undo(char_u *name, int forceit, buf_T *buf, char_u *hash) +/// Write the undo tree in an undo file. +/// +/// @param[in]  name  Name of the undo file or NULL if this function needs to +///                   generate the undo file name based on buf->b_ffname. +/// @param[in]  forceit  True for `:wundo!`, false otherwise. +/// @param[in]  buf  Buffer for which undo file is written. +/// @param[in]  hash  Hash value of the buffer text. Must have #UNDO_HASH_SIZE +///                   size. +void u_write_undo(const char *const name, const bool forceit, buf_T *const buf, +                  char_u *const hash) +  FUNC_ATTR_NONNULL_ARG(3, 4)  {    u_header_T  *uhp; -  char_u      *file_name; +  char *file_name;    int mark;  #ifdef U_DEBUG    int headers_written = 0; @@ -1024,7 +1058,7 @@ void u_write_undo(char_u *name, int forceit, buf_T *buf, char_u *hash)    bufinfo_T bi;    if (name == NULL) { -    file_name = u_get_undo_file_name(buf->b_ffname, FALSE); +    file_name = u_get_undo_file_name((char *) buf->b_ffname, false);      if (file_name == NULL) {        if (p_verbose > 0) {          verbose_enter(); @@ -1033,8 +1067,9 @@ void u_write_undo(char_u *name, int forceit, buf_T *buf, char_u *hash)        }        return;      } -  } else -    file_name = name; +  } else { +    file_name = (char *) name; +  }    /*     * Decide about the permission to use for the undo file.  If the buffer @@ -1054,10 +1089,10 @@ void u_write_undo(char_u *name, int forceit, buf_T *buf, char_u *hash)    /* If the undo file already exists, verify that it actually is an undo     * file, and delete it. */ -  if (os_file_exists(file_name)) { +  if (os_file_exists((char_u *)file_name)) {      if (name == NULL || !forceit) {        /* Check we can read it and it's an undo file. */ -      fd = os_open((char *)file_name, O_RDONLY, 0); +      fd = os_open(file_name, O_RDONLY, 0);        if (fd < 0) {          if (name != NULL || p_verbose > 0) {            if (name == NULL) @@ -1086,7 +1121,7 @@ void u_write_undo(char_u *name, int forceit, buf_T *buf, char_u *hash)          }        }      } -    os_remove((char *)file_name); +    os_remove(file_name);    }    /* If there is no undo information at all, quit here after deleting any @@ -1097,13 +1132,12 @@ void u_write_undo(char_u *name, int forceit, buf_T *buf, char_u *hash)      goto theend;    } -  fd = os_open((char *)file_name, -      O_CREAT|O_WRONLY|O_EXCL|O_NOFOLLOW, perm); +  fd = os_open(file_name, O_CREAT|O_WRONLY|O_EXCL|O_NOFOLLOW, perm);    if (fd < 0) {      EMSG2(_(e_not_open), file_name);      goto theend;    } -  (void)os_setperm(file_name, perm); +  (void)os_setperm((char_u *)file_name, perm);    if (p_verbose > 0) {      verbose_enter();      smsg(_("Writing undo file: %s"), file_name); @@ -1125,10 +1159,10 @@ void u_write_undo(char_u *name, int forceit, buf_T *buf, char_u *hash)    FileInfo file_info_new;    if (buf->b_ffname != NULL        && os_fileinfo((char *)buf->b_ffname, &file_info_old) -      && os_fileinfo((char *)file_name, &file_info_new) +      && os_fileinfo(file_name, &file_info_new)        && file_info_old.stat.st_gid != file_info_new.stat.st_gid        && os_fchown(fd, (uv_uid_t)-1, (uv_gid_t)file_info_old.stat.st_gid)) { -    os_setperm(file_name, (perm & 0707) | ((perm & 07) << 3)); +    os_setperm((char_u *)file_name, (perm & 0707) | ((perm & 07) << 3));    }  # ifdef HAVE_SELINUX    if (buf->b_ffname != NULL) @@ -1140,7 +1174,7 @@ void u_write_undo(char_u *name, int forceit, buf_T *buf, char_u *hash)    if (fp == NULL) {      EMSG2(_(e_not_open), file_name);      close(fd); -    os_remove((char *)file_name); +    os_remove(file_name);      goto theend;    } @@ -1209,7 +1243,7 @@ write_error:      /* For systems that support ACL: get the ACL from the original file. */      acl = mch_get_acl(buf->b_ffname); -    mch_set_acl(file_name, acl); +    mch_set_acl((char_u *)file_name, acl);      mch_free_acl(acl);    }  #endif @@ -1224,15 +1258,15 @@ theend:  /// a bit more verbose.  /// Otherwise use curbuf->b_ffname to generate the undo file name.  /// "hash[UNDO_HASH_SIZE]" must be the hash value of the buffer text. -void u_read_undo(char_u *name, char_u *hash, char_u *orig_name) +void u_read_undo(char *name, char_u *hash, char_u *orig_name)    FUNC_ATTR_NONNULL_ARG(2)  {    u_header_T **uhp_table = NULL;    char_u *line_ptr = NULL; -  char_u *file_name; +  char *file_name;    if (name == NULL) { -    file_name = u_get_undo_file_name(curbuf->b_ffname, TRUE); +    file_name = u_get_undo_file_name((char *) curbuf->b_ffname, true);      if (file_name == NULL) {        return;      } @@ -1256,7 +1290,7 @@ void u_read_undo(char_u *name, char_u *hash, char_u *orig_name)      }  #endif    } else { -    file_name = name; +    file_name = (char *) name;    }    if (p_verbose > 0) { @@ -1265,7 +1299,7 @@ void u_read_undo(char_u *name, char_u *hash, char_u *orig_name)      verbose_leave();    } -  FILE *fp = mch_fopen((char *)file_name, "r"); +  FILE *fp = mch_fopen(file_name, "r");    if (fp == NULL) {      if (name != NULL || p_verbose > 0) {        EMSG2(_("E822: Cannot open undo file for reading: %s"), file_name); | 
