mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 01:34:25 +00:00 
			
		
		
		
	Rename and refactor mch_FullName.
* Rename mch_FullName to mch_full_name to match the style guide. * Add mch_full_dir_name, which saves the absolute path of a given directory relative to cwd into a given buffer. * Add function append_path, which glues together two given paths with a slash. * Adapt moonscript coding style to the tests.
This commit is contained in:
		
				
					committed by
					
						
						Thiago de Arruda
					
				
			
			
				
	
			
			
			
						parent
						
							7e8c8cf5a1
						
					
				
				
					commit
					92a0374d7b
				
			@@ -2418,7 +2418,7 @@ void buflist_altfpos(win_T *win)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Return TRUE if 'ffname' is not the same file as current file.
 | 
			
		||||
 * Fname must have a full path (expanded by mch_FullName()).
 | 
			
		||||
 * Fname must have a full path (expanded by mch_full_name()).
 | 
			
		||||
 */
 | 
			
		||||
int otherfile(char_u *ffname)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -12467,7 +12467,7 @@ static void f_resolve(typval_T *argvars, typval_T *rettv)
 | 
			
		||||
          q[-1] = NUL;
 | 
			
		||||
          q = gettail(p);
 | 
			
		||||
        }
 | 
			
		||||
        if (q > p && !mch_isFullName(buf)) {
 | 
			
		||||
        if (q > p && !mch_is_full_name(buf)) {
 | 
			
		||||
          /* symlink is relative to directory of argument */
 | 
			
		||||
          cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1));
 | 
			
		||||
          if (cpy != NULL) {
 | 
			
		||||
 
 | 
			
		||||
@@ -3944,7 +3944,7 @@ expand_shellcmd (
 | 
			
		||||
  flags |= EW_FILE | EW_EXEC;
 | 
			
		||||
 | 
			
		||||
  /* For an absolute name we don't use $PATH. */
 | 
			
		||||
  if (mch_isFullName(pat))
 | 
			
		||||
  if (mch_is_full_name(pat))
 | 
			
		||||
    path = (char_u *)" ";
 | 
			
		||||
  else if ((pat[0] == '.' && (vim_ispathsep(pat[1])
 | 
			
		||||
                              || (pat[1] == '.' && vim_ispathsep(pat[2])))))
 | 
			
		||||
 
 | 
			
		||||
@@ -4769,7 +4769,7 @@ void shorten_fnames(int force)
 | 
			
		||||
        && !path_with_url(buf->b_fname)
 | 
			
		||||
        && (force
 | 
			
		||||
            || buf->b_sfname == NULL
 | 
			
		||||
            || mch_isFullName(buf->b_sfname))) {
 | 
			
		||||
            || mch_is_full_name(buf->b_sfname))) {
 | 
			
		||||
      vim_free(buf->b_sfname);
 | 
			
		||||
      buf->b_sfname = NULL;
 | 
			
		||||
      p = shorten_fname(buf->b_ffname, dirname);
 | 
			
		||||
 
 | 
			
		||||
@@ -3381,7 +3381,7 @@ int resolve_symlink(char_u *fname, char_u *buf)
 | 
			
		||||
     * portion of the filename (if any) and the path the symlink
 | 
			
		||||
     * points to.
 | 
			
		||||
     */
 | 
			
		||||
    if (mch_isFullName(buf))
 | 
			
		||||
    if (mch_is_full_name(buf))
 | 
			
		||||
      STRCPY(tmp, buf);
 | 
			
		||||
    else {
 | 
			
		||||
      char_u *tail;
 | 
			
		||||
 
 | 
			
		||||
@@ -7945,7 +7945,7 @@ static void expand_path_option(char_u *curdir, garray_T *gap)
 | 
			
		||||
    else if (path_with_url(buf))
 | 
			
		||||
      /* URL can't be used here */
 | 
			
		||||
      continue;
 | 
			
		||||
    else if (!mch_isFullName(buf)) {
 | 
			
		||||
    else if (!mch_is_full_name(buf)) {
 | 
			
		||||
      /* Expand relative path to their full path equivalent */
 | 
			
		||||
      len = (int)STRLEN(curdir);
 | 
			
		||||
      if (len + (int)STRLEN(buf) + 3 > MAXPATHL)
 | 
			
		||||
@@ -8086,7 +8086,7 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    if (mch_isFullName(path)) {
 | 
			
		||||
    if (mch_is_full_name(path)) {
 | 
			
		||||
      /*
 | 
			
		||||
       * Last resort: shorten relative to curdir if possible.
 | 
			
		||||
       * 'possible' means:
 | 
			
		||||
@@ -8375,7 +8375,7 @@ gen_expand_wildcards (
 | 
			
		||||
       */
 | 
			
		||||
      if (mch_has_exp_wildcard(p)) {
 | 
			
		||||
        if ((flags & EW_PATH)
 | 
			
		||||
            && !mch_isFullName(p)
 | 
			
		||||
            && !mch_is_full_name(p)
 | 
			
		||||
            && !(p[0] == '.'
 | 
			
		||||
                 && (vim_ispathsep(p[1])
 | 
			
		||||
                     || (p[1] == '.' && vim_ispathsep(p[2]))))
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										165
									
								
								src/os/fs.c
									
									
									
									
									
								
							
							
						
						
									
										165
									
								
								src/os/fs.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* vi:set ts=8 sts=4 sw=4:
 | 
			
		||||
/* vi:set ts=2 sts=2 sw=2:
 | 
			
		||||
 *
 | 
			
		||||
 * VIM - Vi IMproved	by Bram Moolenaar
 | 
			
		||||
 *
 | 
			
		||||
@@ -33,96 +33,129 @@ int mch_chdir(char *path) {
 | 
			
		||||
int mch_dirname(char_u *buf, int len)
 | 
			
		||||
{
 | 
			
		||||
  int errno;
 | 
			
		||||
  if ((errno = uv_cwd((char *)buf, len)) != 0) {
 | 
			
		||||
  if ((errno = uv_cwd((char *) buf, len)) != 0) {
 | 
			
		||||
      STRCPY(buf, uv_strerror(errno));
 | 
			
		||||
      return FAIL;
 | 
			
		||||
  }
 | 
			
		||||
  return OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * Get the absolute name of the given relative directory.
 | 
			
		||||
 *
 | 
			
		||||
 * parameter directory: Directory name, relative to current directory.
 | 
			
		||||
 * return FAIL for failure, OK for success
 | 
			
		||||
 */
 | 
			
		||||
int mch_full_dir_name(char *directory, char *buffer, int len)
 | 
			
		||||
{
 | 
			
		||||
  int retval = OK;
 | 
			
		||||
 | 
			
		||||
  if(0 == STRLEN(directory)) {
 | 
			
		||||
    return mch_dirname((char_u *) buffer, len);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  char old_dir[MAXPATHL];
 | 
			
		||||
 | 
			
		||||
  /* Get current directory name. */
 | 
			
		||||
  if (FAIL == mch_dirname((char_u *) old_dir, MAXPATHL)) {
 | 
			
		||||
    return FAIL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* We have to get back to the current dir at the end, check if that works. */
 | 
			
		||||
  if (0 != mch_chdir(old_dir)) {
 | 
			
		||||
    return FAIL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (0 != mch_chdir(directory)) {
 | 
			
		||||
    retval = FAIL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ((FAIL == retval) || (FAIL == mch_dirname((char_u *) buffer, len))) {
 | 
			
		||||
    retval = FAIL;
 | 
			
		||||
  }
 | 
			
		||||
   
 | 
			
		||||
  if (0 != mch_chdir(old_dir)) {
 | 
			
		||||
    /* That shouldn't happen, since we've tested if it works. */
 | 
			
		||||
    retval = FAIL;
 | 
			
		||||
    EMSG(_(e_prev_dir));
 | 
			
		||||
  }
 | 
			
		||||
  return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * Append to_append to path with a slash in between.
 | 
			
		||||
 */
 | 
			
		||||
int append_path(char *path, char *to_append, int max_len)
 | 
			
		||||
{
 | 
			
		||||
  int current_length = STRLEN(path);
 | 
			
		||||
  int to_append_length = STRLEN(to_append);
 | 
			
		||||
 | 
			
		||||
  /* Do not append empty strings. */
 | 
			
		||||
  if (0 == to_append_length)
 | 
			
		||||
    return OK;
 | 
			
		||||
 | 
			
		||||
  /* Do not append a dot. */
 | 
			
		||||
  if (STRCMP(to_append, ".") == 0)
 | 
			
		||||
    return OK;
 | 
			
		||||
 | 
			
		||||
  /* Glue both paths with a slash. */
 | 
			
		||||
  if (current_length > 0 && path[current_length-1] != '/') {
 | 
			
		||||
    current_length += 1; /* Count the trailing slash. */
 | 
			
		||||
 | 
			
		||||
    if (current_length > max_len)
 | 
			
		||||
      return FAIL;
 | 
			
		||||
 | 
			
		||||
    STRCAT(path, "/");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* +1 for the NUL at the end. */
 | 
			
		||||
  if (current_length + to_append_length +1 > max_len) {
 | 
			
		||||
    return FAIL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  STRCAT(path, to_append);
 | 
			
		||||
  return OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Get absolute file name into "buf[len]".
 | 
			
		||||
 *
 | 
			
		||||
 * parameter force: Also expand when the given path in fname is already
 | 
			
		||||
 * absolute.
 | 
			
		||||
 *
 | 
			
		||||
 * return FAIL for failure, OK for success
 | 
			
		||||
 */
 | 
			
		||||
int mch_FullName(
 | 
			
		||||
        char_u      *fname,
 | 
			
		||||
        char_u      *buf,
 | 
			
		||||
        int len,
 | 
			
		||||
        int force                       /* also expand when already absolute path */
 | 
			
		||||
        )
 | 
			
		||||
int mch_full_name(char_u *fname, char_u *buf, int len, int force)
 | 
			
		||||
{
 | 
			
		||||
  int l;
 | 
			
		||||
  char_u olddir[MAXPATHL];
 | 
			
		||||
  char_u      *p;
 | 
			
		||||
  int retval = OK;
 | 
			
		||||
 | 
			
		||||
  char_u *p;
 | 
			
		||||
  *buf = NUL;
 | 
			
		||||
 | 
			
		||||
  char relative_directory[len];
 | 
			
		||||
  char *end_of_path = (char *) fname;
 | 
			
		||||
 | 
			
		||||
  /* expand it if forced or not an absolute path */
 | 
			
		||||
  if (force || !mch_isFullName(fname)) {
 | 
			
		||||
    /*
 | 
			
		||||
     * If the file name has a path, change to that directory for a moment,
 | 
			
		||||
     * and then do the getwd() (and get back to where we were).
 | 
			
		||||
     * This will get the correct path name with "../" things.
 | 
			
		||||
     */
 | 
			
		||||
  if (force || !mch_is_full_name(fname)) {
 | 
			
		||||
    if ((p = vim_strrchr(fname, '/')) != NULL) {
 | 
			
		||||
 | 
			
		||||
      /* Only change directory when we are sure we can return to where
 | 
			
		||||
       * we are now.  After doing "su" chdir(".") might not work. */
 | 
			
		||||
      if ((mch_dirname(olddir, MAXPATHL) == FAIL
 | 
			
		||||
         || mch_chdir((char *)olddir) != 0)) {
 | 
			
		||||
        p = NULL;               /* can't get current dir: don't chdir */
 | 
			
		||||
        retval = FAIL;
 | 
			
		||||
      } else   {
 | 
			
		||||
        /* The directory is copied into buf[], to be able to remove
 | 
			
		||||
         * the file name without changing it (could be a string in
 | 
			
		||||
         * read-only memory) */
 | 
			
		||||
        if (p - fname >= len)
 | 
			
		||||
          retval = FAIL;
 | 
			
		||||
        else {
 | 
			
		||||
          vim_strncpy(buf, fname, p - fname);
 | 
			
		||||
          if (mch_chdir((char *)buf))
 | 
			
		||||
            retval = FAIL;
 | 
			
		||||
          else
 | 
			
		||||
            fname = p + 1;
 | 
			
		||||
          *buf = NUL;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (mch_dirname(buf, len) == FAIL) {
 | 
			
		||||
      retval = FAIL;
 | 
			
		||||
      *buf = NUL;
 | 
			
		||||
    }
 | 
			
		||||
    if (p != NULL) {
 | 
			
		||||
      l = mch_chdir((char *)olddir);
 | 
			
		||||
      if (l != 0)
 | 
			
		||||
        EMSG(_(e_prev_dir));
 | 
			
		||||
      STRNCPY(relative_directory, fname, p-fname);
 | 
			
		||||
      relative_directory[p-fname] = NUL;
 | 
			
		||||
      end_of_path = (char *) (p + 1);
 | 
			
		||||
    } else {
 | 
			
		||||
      relative_directory[0] = NUL;
 | 
			
		||||
      end_of_path = (char *) fname;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    l = STRLEN(buf);
 | 
			
		||||
    if (l >= len - 1)
 | 
			
		||||
      retval = FAIL;       /* no space for trailing "/" */
 | 
			
		||||
    else if (l > 0 && buf[l - 1] != '/' && *fname != NUL
 | 
			
		||||
             && STRCMP(fname, ".") != 0)
 | 
			
		||||
      STRCAT(buf, "/");
 | 
			
		||||
    if (FAIL == mch_full_dir_name(relative_directory, (char *) buf, len)) {
 | 
			
		||||
      return FAIL;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Catch file names which are too long. */
 | 
			
		||||
  if (retval == FAIL || (int)(STRLEN(buf) + STRLEN(fname)) >= len)
 | 
			
		||||
    return FAIL;
 | 
			
		||||
 | 
			
		||||
  /* Do not append ".", "/dir/." is equal to "/dir". */
 | 
			
		||||
  if (STRCMP(fname, ".") != 0)
 | 
			
		||||
    STRCAT(buf, fname);
 | 
			
		||||
 | 
			
		||||
  return OK;
 | 
			
		||||
  return append_path((char *) buf, (char *) end_of_path, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Return TRUE if "fname" does not depend on the current directory.
 | 
			
		||||
 */
 | 
			
		||||
int mch_isFullName(char_u *fname)
 | 
			
		||||
int mch_is_full_name(char_u *fname)
 | 
			
		||||
{
 | 
			
		||||
  return *fname == '/' || *fname == '~';
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
long_u mch_total_mem(int special);
 | 
			
		||||
int mch_chdir(char *path);
 | 
			
		||||
int mch_dirname(char_u *buf, int len);
 | 
			
		||||
int mch_FullName (char_u *fname, char_u *buf, int len, int force);
 | 
			
		||||
int mch_isFullName (char_u *fname);
 | 
			
		||||
int mch_full_name (char_u *fname, char_u *buf, int len, int force);
 | 
			
		||||
int mch_is_full_name (char_u *fname);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1364,7 +1364,7 @@ int mch_can_exe(char_u *name)
 | 
			
		||||
  int retval;
 | 
			
		||||
 | 
			
		||||
  /* If it's an absolute or relative path don't need to use $PATH. */
 | 
			
		||||
  if (mch_isFullName(name) || (name[0] == '.' && (name[1] == '/'
 | 
			
		||||
  if (mch_is_full_name(name) || (name[0] == '.' && (name[1] == '/'
 | 
			
		||||
                                                  || (name[1] == '.' &&
 | 
			
		||||
                                                      name[2] == '/'))))
 | 
			
		||||
    return executable_file(name);
 | 
			
		||||
 
 | 
			
		||||
@@ -4187,7 +4187,7 @@ static void syn_cmd_include(exarg_T *eap, int syncing)
 | 
			
		||||
   */
 | 
			
		||||
  eap->argt |= (XFILE | NOSPC);
 | 
			
		||||
  separate_nextcmd(eap);
 | 
			
		||||
  if (*eap->arg == '<' || *eap->arg == '$' || mch_isFullName(eap->arg)) {
 | 
			
		||||
  if (*eap->arg == '<' || *eap->arg == '$' || mch_is_full_name(eap->arg)) {
 | 
			
		||||
    /* For an absolute path, "$VIM/..." or "<sfile>.." we ":source" the
 | 
			
		||||
     * file.  Need to expand the file name first.  In other cases
 | 
			
		||||
     * ":runtime!" is used. */
 | 
			
		||||
 
 | 
			
		||||
@@ -5065,7 +5065,7 @@ int path_with_url(char_u *fname)
 | 
			
		||||
 */
 | 
			
		||||
int vim_isAbsName(char_u *name)
 | 
			
		||||
{
 | 
			
		||||
  return path_with_url(name) != 0 || mch_isFullName(name);
 | 
			
		||||
  return path_with_url(name) != 0 || mch_is_full_name(name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -5090,7 +5090,7 @@ vim_FullName (
 | 
			
		||||
 | 
			
		||||
  url = path_with_url(fname);
 | 
			
		||||
  if (!url)
 | 
			
		||||
    retval = mch_FullName(fname, buf, len, force);
 | 
			
		||||
    retval = mch_full_name(fname, buf, len, force);
 | 
			
		||||
  if (url || retval == FAIL) {
 | 
			
		||||
    /* something failed; use the file name (truncate when too long) */
 | 
			
		||||
    vim_strncpy(buf, fname, len - 1);
 | 
			
		||||
 
 | 
			
		||||
@@ -5,87 +5,195 @@ fs = cimport './src/fs.h'
 | 
			
		||||
cstr = ffi.typeof 'char[?]'
 | 
			
		||||
 | 
			
		||||
describe 'fs function', ->
 | 
			
		||||
 | 
			
		||||
  export OK = 1
 | 
			
		||||
  export FAIL = 0
 | 
			
		||||
 | 
			
		||||
  describe 'mch_dirname', ->
 | 
			
		||||
    ffi.cdef 'int mch_dirname(char *buf, int len);'
 | 
			
		||||
 | 
			
		||||
    mch_dirname = (buf, len) ->
 | 
			
		||||
      fs.mch_dirname buf, len
 | 
			
		||||
 | 
			
		||||
    OK = 1
 | 
			
		||||
    FAIL = 0
 | 
			
		||||
 | 
			
		||||
    before_each ->
 | 
			
		||||
      export len = string.len(lfs.currentdir()) + 1
 | 
			
		||||
      export len = (string.len lfs.currentdir!) + 1
 | 
			
		||||
      export buf = cstr len, ''
 | 
			
		||||
 | 
			
		||||
    it 'returns OK and writes current directory into the buffer if it is buffer
 | 
			
		||||
    is large enough', ->
 | 
			
		||||
      buf = ffi.new 'char[?]', len
 | 
			
		||||
    it 'returns OK and writes current directory into the buffer if it is large
 | 
			
		||||
    enough', ->
 | 
			
		||||
      eq OK, (mch_dirname buf, len)
 | 
			
		||||
      eq lfs.currentdir(), ffi.string(buf)
 | 
			
		||||
      eq lfs.currentdir!, (ffi.string buf)
 | 
			
		||||
 | 
			
		||||
    -- What kind of other failing cases are possible?
 | 
			
		||||
    it 'returns FAIL if the buffer is too small', ->
 | 
			
		||||
      buf = ffi.new 'char[?]', 0
 | 
			
		||||
      eq FAIL, (mch_dirname buf, 0)
 | 
			
		||||
      buf = cstr (len-1), ''
 | 
			
		||||
      eq FAIL, (mch_dirname buf, (len-1))
 | 
			
		||||
 | 
			
		||||
  describe 'mch_FullName', ->
 | 
			
		||||
    ffi.cdef 'int mch_FullName(char *fname, char *buf, int len, int force);'
 | 
			
		||||
  describe 'mch_full_dir_name', ->
 | 
			
		||||
    ffi.cdef 'int mch_full_dir_name(char *directory, char *buffer, int len);'
 | 
			
		||||
 | 
			
		||||
    mch_FullName = (filename, buffer, length, force) ->
 | 
			
		||||
      filename = cstr(string.len(filename) + 1, filename)
 | 
			
		||||
      fs.mch_FullName(filename, buffer, length, force)
 | 
			
		||||
 | 
			
		||||
    OK = 1
 | 
			
		||||
    FAIL = 0
 | 
			
		||||
    mch_full_dir_name = (directory, buffer, len) ->
 | 
			
		||||
      directory = cstr (string.len directory), directory
 | 
			
		||||
      fs.mch_full_dir_name(directory, buffer, len)
 | 
			
		||||
 | 
			
		||||
    before_each ->
 | 
			
		||||
      -- Create empty string buffer which will contain the resulting path
 | 
			
		||||
      export len = string.len(lfs.currentdir()) + 11
 | 
			
		||||
      export buffer = cstr(len, '')
 | 
			
		||||
      -- Create empty string buffer which will contain the resulting path.
 | 
			
		||||
      export len = (string.len lfs.currentdir!) + 22
 | 
			
		||||
      export buffer = cstr len, ''
 | 
			
		||||
 | 
			
		||||
    it 'failes if given filename contains non-existing directory', ->
 | 
			
		||||
      result = mch_FullName('nonexistingdir/test.file', buffer, len, 1)
 | 
			
		||||
    it 'returns the absolute directory name of a given relative one', ->
 | 
			
		||||
      result = mch_full_dir_name '..', buffer, len
 | 
			
		||||
      eq OK, result
 | 
			
		||||
      old_dir = lfs.currentdir!
 | 
			
		||||
      lfs.chdir '..'
 | 
			
		||||
      expected = lfs.currentdir!
 | 
			
		||||
      lfs.chdir old_dir
 | 
			
		||||
      eq expected, (ffi.string buffer)
 | 
			
		||||
 | 
			
		||||
    it 'returns the current directory name if the given string is empty', ->
 | 
			
		||||
      eq OK, (mch_full_dir_name '', buffer, len)
 | 
			
		||||
      eq lfs.currentdir!, (ffi.string buffer)
 | 
			
		||||
 | 
			
		||||
    it 'fails if the given directory does not exist', ->
 | 
			
		||||
      eq FAIL, mch_full_dir_name('does_not_exist', buffer, len)
 | 
			
		||||
 | 
			
		||||
    it 'works with a normal relative dir', ->
 | 
			
		||||
      lfs.mkdir('empty-test-directory')
 | 
			
		||||
      result = mch_full_dir_name('empty-test-directory', buffer, len)
 | 
			
		||||
      lfs.rmdir('empty-test-directory')
 | 
			
		||||
      eq lfs.currentdir! .. '/empty-test-directory', ffi.string(buffer)
 | 
			
		||||
      eq OK, result
 | 
			
		||||
 | 
			
		||||
  describe 'mch_full_name', ->
 | 
			
		||||
    ffi.cdef 'int mch_full_name(char *fname, char *buf, int len, int force);'
 | 
			
		||||
 | 
			
		||||
    mch_full_name = (filename, buffer, length, force) ->
 | 
			
		||||
      filename = cstr (string.len filename) + 1, filename
 | 
			
		||||
      fs.mch_full_name filename, buffer, length, force
 | 
			
		||||
 | 
			
		||||
    before_each ->
 | 
			
		||||
      -- Create empty string buffer which will contain the resulting path.
 | 
			
		||||
      export len = (string.len lfs.currentdir!) + 33
 | 
			
		||||
      export buffer = cstr len, ''
 | 
			
		||||
 | 
			
		||||
      -- Create a directory and an empty file inside in order to know some
 | 
			
		||||
      -- existing relative path.
 | 
			
		||||
      lfs.mkdir('empty-test-directory')
 | 
			
		||||
      lfs.touch('empty-test-directory/empty.file')
 | 
			
		||||
 | 
			
		||||
    after_each ->
 | 
			
		||||
      lfs.rmdir('empty-test-directory')
 | 
			
		||||
 | 
			
		||||
    it 'fails if given filename contains non-existing directory', ->
 | 
			
		||||
      force_expansion = 1
 | 
			
		||||
      result = mch_full_name 'non_existing_dir/test.file', buffer, len, force_expansion
 | 
			
		||||
      eq FAIL, result
 | 
			
		||||
 | 
			
		||||
    it 'concatenates given filename if it does not contain a slash', ->
 | 
			
		||||
      result = mch_FullName('test.file', buffer, len, 1)
 | 
			
		||||
      force_expansion = 1
 | 
			
		||||
      result = mch_full_name 'test.file', buffer, len, force_expansion
 | 
			
		||||
      expected = lfs.currentdir! .. '/test.file'
 | 
			
		||||
      eq expected, (ffi.string buffer)
 | 
			
		||||
      eq OK, result
 | 
			
		||||
      expected = lfs.currentdir() .. '/test.file'
 | 
			
		||||
      eq expected, ffi.string(buffer)
 | 
			
		||||
 | 
			
		||||
    it 'concatenates given filename if it is a directory but does not contain a
 | 
			
		||||
    slash', ->
 | 
			
		||||
      result = mch_FullName('..', buffer, len, 1)
 | 
			
		||||
      force_expansion = 1
 | 
			
		||||
      result = mch_full_name '..', buffer, len, force_expansion
 | 
			
		||||
      expected = lfs.currentdir! .. '/..'
 | 
			
		||||
      eq expected, (ffi.string buffer)
 | 
			
		||||
      eq OK, result
 | 
			
		||||
      expected = lfs.currentdir() .. '/..'
 | 
			
		||||
      eq expected, ffi.string(buffer)
 | 
			
		||||
 | 
			
		||||
    -- Is it possible for every developer to enter '..' directory while running
 | 
			
		||||
    -- the unit tests? Which other directory would be better?
 | 
			
		||||
    it 'enters given directory if possible and if path contains a slash', ->
 | 
			
		||||
      result = mch_FullName('../test.file', buffer, 200, 1)
 | 
			
		||||
    it 'enters given directory (instead of just concatenating the strings) if
 | 
			
		||||
    possible and if path contains a slash', ->
 | 
			
		||||
      force_expansion = 1
 | 
			
		||||
      result = mch_full_name '../test.file', buffer, len, force_expansion
 | 
			
		||||
      old_dir = lfs.currentdir!
 | 
			
		||||
      lfs.chdir '..'
 | 
			
		||||
      expected = lfs.currentdir! .. '/test.file'
 | 
			
		||||
      lfs.chdir old_dir
 | 
			
		||||
      eq expected, (ffi.string buffer)
 | 
			
		||||
      eq OK, result
 | 
			
		||||
      old_dir = lfs.currentdir()
 | 
			
		||||
      lfs.chdir('..')
 | 
			
		||||
      expected = lfs.currentdir() .. '/test.file'
 | 
			
		||||
      lfs.chdir(old_dir)
 | 
			
		||||
      eq expected, ffi.string(buffer)
 | 
			
		||||
 | 
			
		||||
  describe 'mch_isFullName', ->
 | 
			
		||||
    ffi.cdef 'int mch_isFullName(char *fname);'
 | 
			
		||||
    it 'just copies the path if it is already absolute and force=0', ->
 | 
			
		||||
      force_expansion = 0
 | 
			
		||||
      absolute_path = '/absolute/path'
 | 
			
		||||
      result = mch_full_name absolute_path, buffer, len, force_expansion
 | 
			
		||||
      eq absolute_path, (ffi.string buffer)
 | 
			
		||||
      eq OK, result
 | 
			
		||||
 | 
			
		||||
    mch_isFullName = (filename) ->
 | 
			
		||||
      filename = cstr(string.len(filename) + 1, filename)
 | 
			
		||||
      fs.mch_isFullName(filename)
 | 
			
		||||
    it 'fails when the path is relative to HOME', ->
 | 
			
		||||
      force_expansion = 1
 | 
			
		||||
      absolute_path = '~/home.file'
 | 
			
		||||
      result = mch_full_name absolute_path, buffer, len, force_expansion
 | 
			
		||||
      eq FAIL, result
 | 
			
		||||
 | 
			
		||||
    TRUE = 1
 | 
			
		||||
    FALSE = 0
 | 
			
		||||
    it 'works with some "normal" relative path with directories', ->
 | 
			
		||||
      force_expansion = 1
 | 
			
		||||
      result = mch_full_name 'empty-test-directory/empty.file', buffer, len, force_expansion
 | 
			
		||||
      eq OK, result
 | 
			
		||||
      eq lfs.currentdir! .. '/empty-test-directory/empty.file', (ffi.string buffer)
 | 
			
		||||
 | 
			
		||||
    it 'does not modify the given filename', ->
 | 
			
		||||
      force_expansion = 1
 | 
			
		||||
      filename = cstr 100, 'empty-test-directory/empty.file'
 | 
			
		||||
      result = fs.mch_full_name filename, buffer, len, force_expansion
 | 
			
		||||
      eq lfs.currentdir! .. '/empty-test-directory/empty.file', (ffi.string buffer)
 | 
			
		||||
      eq 'empty-test-directory/empty.file', (ffi.string filename)
 | 
			
		||||
      eq OK, result
 | 
			
		||||
 | 
			
		||||
  describe 'append_path', ->
 | 
			
		||||
    ffi.cdef 'int append_path(char *path, char *to_append, int max_len);'
 | 
			
		||||
 | 
			
		||||
    it 'joins given paths with a slash', ->
 | 
			
		||||
     path = cstr 100, 'path1'
 | 
			
		||||
     to_append = cstr 6, 'path2'
 | 
			
		||||
     eq OK, (fs.append_path path, to_append, 100)
 | 
			
		||||
     eq "path1/path2", (ffi.string path)
 | 
			
		||||
 | 
			
		||||
    it 'joins given paths without adding an unnecessary slash', ->
 | 
			
		||||
     path = cstr 100, 'path1/'
 | 
			
		||||
     to_append = cstr 6, 'path2'
 | 
			
		||||
     eq OK, fs.append_path path, to_append, 100
 | 
			
		||||
     eq "path1/path2", (ffi.string path)
 | 
			
		||||
 | 
			
		||||
    it 'fails if there is not enough space left for to_append', ->
 | 
			
		||||
      path = cstr 11, 'path1/'
 | 
			
		||||
      to_append = cstr 6, 'path2'
 | 
			
		||||
      eq FAIL, (fs.append_path path, to_append, 11)
 | 
			
		||||
 | 
			
		||||
    it 'does not append a slash if to_append is empty', ->
 | 
			
		||||
      path = cstr 6, 'path1'
 | 
			
		||||
      to_append = cstr 1, ''
 | 
			
		||||
      eq OK, (fs.append_path path, to_append, 6)
 | 
			
		||||
      eq 'path1', (ffi.string path)
 | 
			
		||||
 | 
			
		||||
    it 'does not append unnecessary dots', ->
 | 
			
		||||
      path = cstr 6, 'path1'
 | 
			
		||||
      to_append = cstr 2, '.'
 | 
			
		||||
      eq OK, (fs.append_path path, to_append, 6)
 | 
			
		||||
      eq 'path1', (ffi.string path)
 | 
			
		||||
 | 
			
		||||
    it 'copies to_append to path, if path is empty', ->
 | 
			
		||||
      path = cstr 7, ''
 | 
			
		||||
      to_append = cstr 7, '/path2'
 | 
			
		||||
      eq OK, (fs.append_path path, to_append, 7)
 | 
			
		||||
      eq '/path2', (ffi.string path)
 | 
			
		||||
 | 
			
		||||
  describe 'mch_is_full_name', ->
 | 
			
		||||
    ffi.cdef 'int mch_is_full_name(char *fname);'
 | 
			
		||||
 | 
			
		||||
    mch_is_full_name = (filename) ->
 | 
			
		||||
      filename = cstr (string.len filename) + 1, filename
 | 
			
		||||
      fs.mch_is_full_name filename
 | 
			
		||||
 | 
			
		||||
    it 'returns true if filename starts with a slash', ->
 | 
			
		||||
      eq TRUE, mch_isFullName('/some/directory/')
 | 
			
		||||
      eq OK, mch_is_full_name '/some/directory/'
 | 
			
		||||
 | 
			
		||||
    it 'returns true if filename starts with a tilde', ->
 | 
			
		||||
      eq TRUE, mch_isFullName('~/in/my/home~/directory')
 | 
			
		||||
      eq OK, mch_is_full_name '~/in/my/home~/directory'
 | 
			
		||||
 | 
			
		||||
    it 'returns false if filename starts not with slash nor tilde', ->
 | 
			
		||||
      eq FALSE, mch_isFullName('not/in/my/home~/directory')
 | 
			
		||||
      eq FAIL, mch_is_full_name 'not/in/my/home~/directory'
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user