mirror of
https://github.com/neovim/neovim.git
synced 2025-10-01 07:28:34 +00:00
refactor(fileio): remove API shell layer encouraging unnecessary allocations
Functions like file_open_new() and file_open_fd_new() which just is a wrapper around the real functions but with an extra xmalloc/xfree around is an anti-pattern. If the caller really needs to allocate a FileDescriptor as a heap object, it can do that directly. FileDescriptor by itself is pretty much a pointer, or rather two: the OS fd index and a pointer to a buffer. So most of the time an extra pointer layer is just wasteful. In the case of scriptin[curscript] in getchar.c, curscript used to mean in practice: N+1 open scripts when curscript>0 zero or one open scripts when curscript==0 Which means scriptin[0] had to be compared to NULL to disambiguate the curscript=0 case. Instead, use curscript==-1 to mean that are no script, then all pointer comparisons dissappear and we can just use an array of structs without extra pointers.
This commit is contained in:
@@ -129,59 +129,15 @@ int file_open_fd(FileDescriptor *const ret_fp, const int fd, const int flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Like file_open(), but allocate and return ret_fp
|
||||
///
|
||||
/// @param[out] error Error code, or 0 on success. @see os_strerror()
|
||||
/// @param[in] fname File name to open.
|
||||
/// @param[in] flags Flags, @see FileOpenFlags.
|
||||
/// @param[in] mode Permissions for the newly created file (ignored if flags
|
||||
/// does not have kFileCreate\*).
|
||||
///
|
||||
/// @return [allocated] Opened file or NULL in case of error.
|
||||
FileDescriptor *file_open_new(int *const error, const char *const fname, const int flags,
|
||||
const int mode)
|
||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
FileDescriptor *const fp = xmalloc(sizeof(*fp));
|
||||
if ((*error = file_open(fp, fname, flags, mode)) != 0) {
|
||||
xfree(fp);
|
||||
return NULL;
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
|
||||
/// Like file_open_fd(), but allocate and return ret_fp
|
||||
///
|
||||
/// @param[out] error Error code, or 0 on success. @see os_strerror()
|
||||
/// @param[in] fd File descriptor to wrap.
|
||||
/// @param[in] flags Flags, @see FileOpenFlags.
|
||||
/// @param[in] mode Permissions for the newly created file (ignored if flags
|
||||
/// does not have FILE_CREATE\*).
|
||||
///
|
||||
/// @return [allocated] Opened file or NULL in case of error.
|
||||
FileDescriptor *file_open_fd_new(int *const error, const int fd, const int flags)
|
||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
FileDescriptor *const fp = xmalloc(sizeof(*fp));
|
||||
if ((*error = file_open_fd(fp, fd, flags)) != 0) {
|
||||
xfree(fp);
|
||||
return NULL;
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
|
||||
/// Opens standard input as a FileDescriptor.
|
||||
FileDescriptor *file_open_stdin(void)
|
||||
FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
int file_open_stdin(FileDescriptor *fp)
|
||||
FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
int error;
|
||||
FileDescriptor *const stdin_dup = file_open_fd_new(&error, os_open_stdin_fd(),
|
||||
kFileReadOnly|kFileNonBlocking);
|
||||
assert(stdin_dup != NULL);
|
||||
int error = file_open_fd(fp, os_open_stdin_fd(), kFileReadOnly|kFileNonBlocking);
|
||||
if (error != 0) {
|
||||
ELOG("failed to open stdin: %s", os_strerror(error));
|
||||
}
|
||||
return stdin_dup;
|
||||
return error;
|
||||
}
|
||||
|
||||
/// Close file and free its buffer
|
||||
@@ -202,20 +158,6 @@ int file_close(FileDescriptor *const fp, const bool do_fsync)
|
||||
return flush_error;
|
||||
}
|
||||
|
||||
/// Close and free file obtained using file_open_new()
|
||||
///
|
||||
/// @param[in,out] fp File to close.
|
||||
/// @param[in] do_fsync If true, use fsync() to write changes to disk.
|
||||
///
|
||||
/// @return 0 or error code.
|
||||
int file_free(FileDescriptor *const fp, const bool do_fsync)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
const int ret = file_close(fp, do_fsync);
|
||||
xfree(fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Flush file modifications to disk
|
||||
///
|
||||
/// @param[in,out] fp File to work with.
|
||||
|
Reference in New Issue
Block a user