diff options
Diffstat (limited to 'src')
36 files changed, 884 insertions, 885 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 1637374459..7c05ec7d44 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -20,10 +20,6 @@ #include "nvim/window.h" #include "nvim/undo.h" -// Find a window that contains "buf" and switch to it. -// If there is no such window, use the current window and change "curbuf". -// Caller must initialize save_curbuf to NULL. -// restore_win_for_buf() MUST be called later! static void switch_to_win_for_buf(buf_T *buf, win_T **save_curwinp, tabpage_T **save_curtabp, @@ -33,14 +29,15 @@ static void restore_win_for_buf(win_T *save_curwin, tabpage_T *save_curtab, buf_T *save_curbuf); -// Check if deleting lines made the cursor position invalid. -// Changed the lines from "lo" to "hi" and added "extra" lines (negative if -// deleted). static void fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra); -// Normalizes 0-based indexes to buffer line numbers static int64_t normalize_index(buf_T *buf, int64_t index); +/// Gets the buffer line count +/// +/// @param buffer The buffer handle +/// @param[out] err Details of an error that may have occurred +/// @return The line count Integer buffer_get_length(Buffer buffer, Error *err) { buf_T *buf = find_buffer(buffer, err); @@ -52,6 +49,12 @@ Integer buffer_get_length(Buffer buffer, Error *err) return buf->b_ml.ml_line_count; } +/// Gets a buffer line +/// +/// @param buffer The buffer handle +/// @param index The line index +/// @param[out] err Details of an error that may have occurred +/// @return The line string String buffer_get_line(Buffer buffer, Integer index, Error *err) { String rv = {.size = 0}; @@ -66,18 +69,38 @@ String buffer_get_line(Buffer buffer, Integer index, Error *err) return rv; } +/// Sets a buffer line +/// +/// @param buffer The buffer handle +/// @param index The line index +/// @param line The new line. +/// @param[out] err Details of an error that may have occurred void buffer_set_line(Buffer buffer, Integer index, String line, Error *err) { StringArray array = {.items = &line, .size = 1}; buffer_set_slice(buffer, index, index, true, true, array, err); } +/// Deletes a buffer line +/// +/// @param buffer The buffer handle +/// @param index The line index +/// @param[out] err Details of an error that may have occurred void buffer_del_line(Buffer buffer, Integer index, Error *err) { StringArray array = ARRAY_DICT_INIT; buffer_set_slice(buffer, index, index, true, true, array, err); } +/// Retrieves a line range from the buffer +/// +/// @param buffer The buffer handle +/// @param start The first line index +/// @param end The last line index +/// @param include_start True if the slice includes the `start` parameter +/// @param include_end True if the slice includes the `end` parameter +/// @param[out] err Details of an error that may have occurred +/// @return An array of lines StringArray buffer_get_slice(Buffer buffer, Integer start, Integer end, @@ -128,6 +151,16 @@ end: return rv; } +/// Replaces a line range on the buffer +/// +/// @param buffer The buffer handle +/// @param start The first line index +/// @param end The last line index +/// @param include_start True if the slice includes the `start` parameter +/// @param include_end True if the slice includes the `end` parameter +/// @param lines An array of lines to use as replacement(A 0-length array +/// will simply delete the line range) +/// @param[out] err Details of an error that may have occurred void buffer_set_slice(Buffer buffer, Integer start, Integer end, @@ -251,6 +284,12 @@ end: try_end(err); } +/// Gets a buffer variable +/// +/// @param buffer The buffer handle +/// @param name The variable name +/// @param[out] err Details of an error that may have occurred +/// @return The variable value Object buffer_get_var(Buffer buffer, String name, Error *err) { buf_T *buf = find_buffer(buffer, err); @@ -262,6 +301,13 @@ Object buffer_get_var(Buffer buffer, String name, Error *err) return dict_get_value(buf->b_vars, name, err); } +/// Sets a buffer variable. Passing 'nil' as value deletes the variable. +/// +/// @param buffer The buffer handle +/// @param name The variable name +/// @param value The variable value +/// @param[out] err Details of an error that may have occurred +/// @return The old value Object buffer_set_var(Buffer buffer, String name, Object value, Error *err) { buf_T *buf = find_buffer(buffer, err); @@ -273,6 +319,12 @@ Object buffer_set_var(Buffer buffer, String name, Object value, Error *err) return dict_set_value(buf->b_vars, name, value, err); } +/// Gets a buffer option value +/// +/// @param buffer The buffer handle +/// @param name The option name +/// @param[out] err Details of an error that may have occurred +/// @return The option value Object buffer_get_option(Buffer buffer, String name, Error *err) { buf_T *buf = find_buffer(buffer, err); @@ -284,6 +336,13 @@ Object buffer_get_option(Buffer buffer, String name, Error *err) return get_option_from(buf, SREQ_BUF, name, err); } +/// Sets a buffer option value. Passing 'nil' as value deletes the option(only +/// works if there's a global fallback) +/// +/// @param buffer The buffer handle +/// @param name The option name +/// @param value The option value +/// @param[out] err Details of an error that may have occurred void buffer_set_option(Buffer buffer, String name, Object value, Error *err) { buf_T *buf = find_buffer(buffer, err); @@ -295,6 +354,11 @@ void buffer_set_option(Buffer buffer, String name, Object value, Error *err) set_option_to(buf, SREQ_BUF, name, value, err); } +/// Gets the buffer number +/// +/// @param buffer The buffer handle +/// @param[out] err Details of an error that may have occurred +/// @return The buffer number Integer buffer_get_number(Buffer buffer, Error *err) { Integer rv = 0; @@ -307,6 +371,11 @@ Integer buffer_get_number(Buffer buffer, Error *err) return buf->b_fnum; } +/// Gets the full file name for the buffer +/// +/// @param buffer The buffer handle +/// @param[out] err Details of an error that may have occurred +/// @return The buffer name String buffer_get_name(Buffer buffer, Error *err) { String rv = STRING_INIT; @@ -319,6 +388,11 @@ String buffer_get_name(Buffer buffer, Error *err) return cstr_to_string((char *)buf->b_ffname); } +/// Sets the full file name for a buffer +/// +/// @param buffer The buffer handle +/// @param name The buffer name +/// @param[out] err Details of an error that may have occurred void buffer_set_name(Buffer buffer, String name, Error *err) { buf_T *buf = find_buffer(buffer, err); @@ -347,17 +421,34 @@ void buffer_set_name(Buffer buffer, String name, Error *err) } } +/// Checks if a buffer is valid +/// +/// @param buffer The buffer handle +/// @return true if the buffer is valid, false otherwise Boolean buffer_is_valid(Buffer buffer) { Error stub = {.set = false}; return find_buffer(buffer, &stub) != NULL; } +/// Inserts a sequence of lines to a buffer at a certain index +/// +/// @param buffer The buffer handle +/// @param lnum Insert the lines after `lnum`. If negative, it will append +/// to the end of the buffer. +/// @param lines An array of lines +/// @param[out] err Details of an error that may have occurred void buffer_insert(Buffer buffer, Integer lnum, StringArray lines, Error *err) { buffer_set_slice(buffer, lnum, lnum, false, true, lines, err); } +/// Return a tuple (row,col) representing the position of the named mark +/// +/// @param buffer The buffer handle +/// @param name The mark's name +/// @param[out] err Details of an error that may have occurred +/// @return The (row, col) tuple Position buffer_get_mark(Buffer buffer, String name, Error *err) { Position rv = POSITION_INIT; @@ -395,6 +486,10 @@ Position buffer_get_mark(Buffer buffer, String name, Error *err) return rv; } +// Find a window that contains "buf" and switch to it. +// If there is no such window, use the current window and change "curbuf". +// Caller must initialize save_curbuf to NULL. +// restore_win_for_buf() MUST be called later! static void switch_to_win_for_buf(buf_T *buf, win_T **save_curwinp, tabpage_T **save_curtabp, @@ -419,6 +514,9 @@ static void restore_win_for_buf(win_T *save_curwin, } } +// Check if deleting lines made the cursor position invalid. +// Changed the lines from "lo" to "hi" and added "extra" lines (negative if +// deleted). static void fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra) { if (curwin->w_cursor.lnum >= lo) { @@ -438,6 +536,7 @@ static void fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra) invalidate_botline(); } +// Normalizes 0-based indexes to buffer line numbers static int64_t normalize_index(buf_T *buf, int64_t index) { // Fix if < 0 diff --git a/src/nvim/api/buffer.h b/src/nvim/api/buffer.h index 52a3b7cdb3..c68ff5561e 100644 --- a/src/nvim/api/buffer.h +++ b/src/nvim/api/buffer.h @@ -6,45 +6,14 @@ #include "nvim/api/private/defs.h" -/// Gets the buffer line count -/// -/// @param buffer The buffer handle -/// @param[out] err Details of an error that may have occurred -/// @return The line count Integer buffer_get_length(Buffer buffer, Error *err); -/// Gets a buffer line -/// -/// @param buffer The buffer handle -/// @param index The line index -/// @param[out] err Details of an error that may have occurred -/// @return The line string String buffer_get_line(Buffer buffer, Integer index, Error *err); -/// Sets a buffer line -/// -/// @param buffer The buffer handle -/// @param index The line index -/// @param line The new line. -/// @param[out] err Details of an error that may have occurred void buffer_set_line(Buffer buffer, Integer index, String line, Error *err); -/// Deletes a buffer line -/// -/// @param buffer The buffer handle -/// @param index The line index -/// @param[out] err Details of an error that may have occurred void buffer_del_line(Buffer buffer, Integer index, Error *err); -/// Retrieves a line range from the buffer -/// -/// @param buffer The buffer handle -/// @param start The first line index -/// @param end The last line index -/// @param include_start True if the slice includes the `start` parameter -/// @param include_end True if the slice includes the `end` parameter -/// @param[out] err Details of an error that may have occurred -/// @return An array of lines StringArray buffer_get_slice(Buffer buffer, Integer start, Integer end, @@ -52,16 +21,6 @@ StringArray buffer_get_slice(Buffer buffer, Boolean include_end, Error *err); -/// Replaces a line range on the buffer -/// -/// @param buffer The buffer handle -/// @param start The first line index -/// @param end The last line index -/// @param include_start True if the slice includes the `start` parameter -/// @param include_end True if the slice includes the `end` parameter -/// @param lines An array of lines to use as replacement(A 0-length array -/// will simply delete the line range) -/// @param[out] err Details of an error that may have occurred void buffer_set_slice(Buffer buffer, Integer start, Integer end, @@ -70,82 +29,24 @@ void buffer_set_slice(Buffer buffer, StringArray replacement, Error *err); -/// Gets a buffer variable -/// -/// @param buffer The buffer handle -/// @param name The variable name -/// @param[out] err Details of an error that may have occurred -/// @return The variable value Object buffer_get_var(Buffer buffer, String name, Error *err); -/// Sets a buffer variable. Passing 'nil' as value deletes the variable. -/// -/// @param buffer The buffer handle -/// @param name The variable name -/// @param value The variable value -/// @param[out] err Details of an error that may have occurred -/// @return The old value Object buffer_set_var(Buffer buffer, String name, Object value, Error *err); -/// Gets a buffer option value -/// -/// @param buffer The buffer handle -/// @param name The option name -/// @param[out] err Details of an error that may have occurred -/// @return The option value Object buffer_get_option(Buffer buffer, String name, Error *err); -/// Sets a buffer option value. Passing 'nil' as value deletes the option(only -/// works if there's a global fallback) -/// -/// @param buffer The buffer handle -/// @param name The option name -/// @param value The option value -/// @param[out] err Details of an error that may have occurred void buffer_set_option(Buffer buffer, String name, Object value, Error *err); -/// Gets the buffer number -/// -/// @param buffer The buffer handle -/// @param[out] err Details of an error that may have occurred -/// @return The buffer number Integer buffer_get_number(Buffer buffer, Error *err); -/// Gets the full file name for the buffer -/// -/// @param buffer The buffer handle -/// @param[out] err Details of an error that may have occurred -/// @return The buffer name String buffer_get_name(Buffer buffer, Error *err); -/// Sets the full file name for a buffer -/// -/// @param buffer The buffer handle -/// @param name The buffer name -/// @param[out] err Details of an error that may have occurred void buffer_set_name(Buffer buffer, String name, Error *err); -/// Checks if a buffer is valid -/// -/// @param buffer The buffer handle -/// @return true if the buffer is valid, false otherwise Boolean buffer_is_valid(Buffer buffer); -/// Inserts a sequence of lines to a buffer at a certain index -/// -/// @param buffer The buffer handle -/// @param lnum Insert the lines after `lnum`. If negative, it will append -/// to the end of the buffer. -/// @param lines An array of lines -/// @param[out] err Details of an error that may have occurred void buffer_insert(Buffer buffer, Integer lnum, StringArray lines, Error *err); -/// Return a tuple (row,col) representing the position of the named mark -/// -/// @param buffer The buffer handle -/// @param name The mark's name -/// @param[out] err Details of an error that may have occurred -/// @return The (row, col) tuple Position buffer_get_mark(Buffer buffer, String name, Error *err); #endif // NVIM_API_BUFFER_H diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index c9bc849af0..2183b77cfa 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -15,12 +15,6 @@ #include "nvim/option.h" #include "nvim/option_defs.h" -/// Recursion helper for the `vim_to_object`. This uses a pointer table -/// to avoid infinite recursion due to cyclic references -/// -/// @param obj The source object -/// @param lookup Lookup table containing pointers to all processed objects -/// @return The converted value static Object vim_to_object_rec(typval_T *obj, PMap(ptr_t) *lookup); static bool object_to_vim(Object obj, typval_T *tv, Error *err); @@ -39,11 +33,17 @@ static void set_option_value_err(char *key, int opt_flags, Error *err); +/// Start block that may cause vimscript exceptions void try_start() { ++trylevel; } +/// End try block, set the error message if any and return true if an error +/// occurred. +/// +/// @param err Pointer to the stack-allocated error object +/// @return true if an error occurred bool try_end(Error *err) { --trylevel; @@ -81,6 +81,11 @@ bool try_end(Error *err) return err->set; } +/// Recursively expands a vimscript value in a dict +/// +/// @param dict The vimscript dict +/// @param key The key +/// @param[out] err Details of an error that may have occurred Object dict_get_value(dict_T *dict, String key, Error *err) { Object rv = OBJECT_INIT; @@ -101,6 +106,14 @@ Object dict_get_value(dict_T *dict, String key, Error *err) return rv; } +/// Set a value in a dict. Objects are recursively expanded into their +/// vimscript equivalents. Passing 'nil' as value deletes the key. +/// +/// @param dict The vimscript dict +/// @param key The key +/// @param value The new value +/// @param[out] err Details of an error that may have occurred +/// @return the old value, if any Object dict_set_value(dict_T *dict, String key, Object value, Error *err) { Object rv = OBJECT_INIT; @@ -164,6 +177,14 @@ Object dict_set_value(dict_T *dict, String key, Object value, Error *err) return rv; } +/// Gets the value of a global or local(buffer, window) option. +/// +/// @param from If `type` is `SREQ_WIN` or `SREQ_BUF`, this must be a pointer +/// to the window or buffer. +/// @param type One of `SREQ_GLOBAL`, `SREQ_WIN` or `SREQ_BUF` +/// @param name The option name +/// @param[out] err Details of an error that may have occurred +/// @return the option value Object get_option_from(void *from, int type, String name, Error *err) { Object rv = OBJECT_INIT; @@ -207,6 +228,13 @@ Object get_option_from(void *from, int type, String name, Error *err) return rv; } +/// Sets the value of a global or local(buffer, window) option. +/// +/// @param to If `type` is `SREQ_WIN` or `SREQ_BUF`, this must be a pointer +/// to the window or buffer. +/// @param type One of `SREQ_GLOBAL`, `SREQ_WIN` or `SREQ_BUF` +/// @param name The option name +/// @param[out] err Details of an error that may have occurred void set_option_to(void *to, int type, String name, Object value, Error *err) { if (name.size == 0) { @@ -274,6 +302,11 @@ cleanup: free(key); } +/// Convert a vim object to an `Object` instance, recursively expanding +/// Arrays/Dictionaries. +/// +/// @param obj The source object +/// @return The converted value Object vim_to_object(typval_T *obj) { Object rv; @@ -285,6 +318,11 @@ Object vim_to_object(typval_T *obj) return rv; } +/// Finds the pointer for a window number +/// +/// @param window the window number +/// @param[out] err Details of an error that may have occurred +/// @return the window pointer buf_T *find_buffer(Buffer buffer, Error *err) { buf_T *rv = handle_get_buffer(buffer); @@ -296,6 +334,11 @@ buf_T *find_buffer(Buffer buffer, Error *err) return rv; } +/// Finds the pointer for a window number +/// +/// @param window the window number +/// @param[out] err Details of an error that may have occurred +/// @return the window pointer win_T * find_window(Window window, Error *err) { win_T *rv = handle_get_window(window); @@ -307,6 +350,11 @@ win_T * find_window(Window window, Error *err) return rv; } +/// Finds the pointer for a tabpage number +/// +/// @param tabpage the tabpage number +/// @param[out] err Details of an error that may have occurred +/// @return the tabpage pointer tabpage_T * find_tab(Tabpage tabpage, Error *err) { tabpage_T *rv = handle_get_tabpage(tabpage); @@ -422,6 +470,12 @@ static bool object_to_vim(Object obj, typval_T *tv, Error *err) return true; } +/// Recursion helper for the `vim_to_object`. This uses a pointer table +/// to avoid infinite recursion due to cyclic references +/// +/// @param obj The source object +/// @param lookup Lookup table containing pointers to all processed objects +/// @return The converted value static Object vim_to_object_rec(typval_T *obj, PMap(ptr_t) *lookup) { Object rv = OBJECT_INIT; diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h index 04b128d3f1..b70cc55d42 100644 --- a/src/nvim/api/private/helpers.h +++ b/src/nvim/api/private/helpers.h @@ -13,78 +13,24 @@ err->set = true; \ } while (0) -/// Start block that may cause vimscript exceptions void try_start(void); -/// End try block, set the error message if any and return true if an error -/// occurred. -/// -/// @param err Pointer to the stack-allocated error object -/// @return true if an error occurred bool try_end(Error *err); -/// Recursively expands a vimscript value in a dict -/// -/// @param dict The vimscript dict -/// @param key The key -/// @param[out] err Details of an error that may have occurred Object dict_get_value(dict_T *dict, String key, Error *err); -/// Set a value in a dict. Objects are recursively expanded into their -/// vimscript equivalents. Passing 'nil' as value deletes the key. -/// -/// @param dict The vimscript dict -/// @param key The key -/// @param value The new value -/// @param[out] err Details of an error that may have occurred -/// @return the old value, if any Object dict_set_value(dict_T *dict, String key, Object value, Error *err); -/// Gets the value of a global or local(buffer, window) option. -/// -/// @param from If `type` is `SREQ_WIN` or `SREQ_BUF`, this must be a pointer -/// to the window or buffer. -/// @param type One of `SREQ_GLOBAL`, `SREQ_WIN` or `SREQ_BUF` -/// @param name The option name -/// @param[out] err Details of an error that may have occurred -/// @return the option value Object get_option_from(void *from, int type, String name, Error *err); -/// Sets the value of a global or local(buffer, window) option. -/// -/// @param to If `type` is `SREQ_WIN` or `SREQ_BUF`, this must be a pointer -/// to the window or buffer. -/// @param type One of `SREQ_GLOBAL`, `SREQ_WIN` or `SREQ_BUF` -/// @param name The option name -/// @param[out] err Details of an error that may have occurred void set_option_to(void *to, int type, String name, Object value, Error *err); -/// Convert a vim object to an `Object` instance, recursively expanding -/// Arrays/Dictionaries. -/// -/// @param obj The source object -/// @return The converted value Object vim_to_object(typval_T *obj); -/// Finds the pointer for a window number -/// -/// @param window the window number -/// @param[out] err Details of an error that may have occurred -/// @return the window pointer buf_T *find_buffer(Buffer buffer, Error *err); -/// Finds the pointer for a window number -/// -/// @param window the window number -/// @param[out] err Details of an error that may have occurred -/// @return the window pointer win_T * find_window(Window window, Error *err); -/// Finds the pointer for a tabpage number -/// -/// @param tabpage the tabpage number -/// @param[out] err Details of an error that may have occurred -/// @return the tabpage pointer tabpage_T * find_tab(Tabpage tabpage, Error *err); /// Copies a C string into a String (binary safe string, characters + length) diff --git a/src/nvim/api/tabpage.c b/src/nvim/api/tabpage.c index ce52466d12..8d92b01cf9 100644 --- a/src/nvim/api/tabpage.c +++ b/src/nvim/api/tabpage.c @@ -8,6 +8,11 @@ #include "nvim/api/private/helpers.h" #include "nvim/memory.h" +/// Gets the number of windows in a tabpage +/// +/// @param tabpage The tabpage +/// @param[out] err Details of an error that may have occurred +/// @return The number of windows in `tabpage` WindowArray tabpage_get_windows(Tabpage tabpage, Error *err) { WindowArray rv = ARRAY_DICT_INIT; @@ -40,6 +45,12 @@ WindowArray tabpage_get_windows(Tabpage tabpage, Error *err) return rv; } +/// Gets a tabpage variable +/// +/// @param tabpage The tab page handle +/// @param name The variable name +/// @param[out] err Details of an error that may have occurred +/// @return The variable value Object tabpage_get_var(Tabpage tabpage, String name, Error *err) { tabpage_T *tab = find_tab(tabpage, err); @@ -51,6 +62,13 @@ Object tabpage_get_var(Tabpage tabpage, String name, Error *err) return dict_get_value(tab->tp_vars, name, err); } +/// Sets a tabpage variable. Passing 'nil' as value deletes the variable. +/// +/// @param tabpage handle +/// @param name The variable name +/// @param value The variable value +/// @param[out] err Details of an error that may have occurred +/// @return The tab page handle Object tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err) { tabpage_T *tab = find_tab(tabpage, err); @@ -62,6 +80,11 @@ Object tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err) return dict_set_value(tab->tp_vars, name, value, err); } +/// Gets the current window in a tab page +/// +/// @param tabpage The tab page handle +/// @param[out] err Details of an error that may have occurred +/// @return The Window handle Window tabpage_get_window(Tabpage tabpage, Error *err) { Window rv = 0; @@ -87,6 +110,10 @@ Window tabpage_get_window(Tabpage tabpage, Error *err) } } +/// Checks if a tab page is valid +/// +/// @param tabpage The tab page handle +/// @return true if the tab page is valid, false otherwise Boolean tabpage_is_valid(Tabpage tabpage) { Error stub = {.set = false}; diff --git a/src/nvim/api/tabpage.h b/src/nvim/api/tabpage.h index dddcecbdbd..a7c1eac19d 100644 --- a/src/nvim/api/tabpage.h +++ b/src/nvim/api/tabpage.h @@ -6,41 +6,12 @@ #include "nvim/api/private/defs.h" -/// Gets the number of windows in a tabpage -/// -/// @param tabpage The tabpage -/// @param[out] err Details of an error that may have occurred -/// @return The number of windows in `tabpage` -WindowArray tabpage_get_windows(Tabpage tabpage, Error *err); - -/// Gets a tabpage variable -/// -/// @param tabpage The tab page handle -/// @param name The variable name -/// @param[out] err Details of an error that may have occurred -/// @return The variable value Object tabpage_get_var(Tabpage tabpage, String name, Error *err); -/// Sets a tabpage variable. Passing 'nil' as value deletes the variable. -/// -/// @param tabpage handle -/// @param name The variable name -/// @param value The variable value -/// @param[out] err Details of an error that may have occurred -/// @return The tab page handle Object tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err); -/// Gets the current window in a tab page -/// -/// @param tabpage The tab page handle -/// @param[out] err Details of an error that may have occurred -/// @return The Window handle Window tabpage_get_window(Tabpage tabpage, Error *err); -/// Checks if a tab page is valid -/// -/// @param tabpage The tab page handle -/// @return true if the tab page is valid, false otherwise Boolean tabpage_is_valid(Tabpage tabpage); #endif // NVIM_API_TABPAGE_H diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 39e2c32d6d..a1aa6b2d79 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -22,20 +22,20 @@ #define LINE_BUFFER_SIZE 4096 -/// Writes a message to vim output or error buffer. The string is split -/// and flushed after each newline. Incomplete lines are kept for writing -/// later. -/// -/// @param message The message to write -/// @param to_err True if it should be treated as an error message(use -/// `emsg` instead of `msg` to print each line) static void write_msg(String message, bool to_err); +/// Send keys to vim input buffer, simulating user input. +/// +/// @param str The keys to send void vim_push_keys(String str) { abort(); } +/// Executes an ex-mode command str +/// +/// @param str The command str +/// @param[out] err Details of an error that may have occurred void vim_command(String str, Error *err) { // We still use 0-terminated strings, so we must convert. @@ -48,6 +48,13 @@ void vim_command(String str, Error *err) try_end(err); } +/// Evaluates the expression str using the vim internal expression +/// evaluator (see |expression|). +/// Dictionaries and lists are recursively expanded. +/// +/// @param str The expression str +/// @param[out] err Details of an error that may have occurred +/// @return The expanded object Object vim_eval(String str, Error *err) { Object rv; @@ -67,6 +74,12 @@ Object vim_eval(String str, Error *err) return rv; } +/// Calculates the number of display cells `str` occupies, tab is counted as +/// one cell. +/// +/// @param str Some text +/// @param[out] err Details of an error that may have occurred +/// @return The number of cells Integer vim_strwidth(String str, Error *err) { if (str.size > INT_MAX) { @@ -80,6 +93,9 @@ Integer vim_strwidth(String str, Error *err) return rv; } +/// Returns a list of paths contained in 'runtimepath' +/// +/// @return The list of paths StringArray vim_list_runtime_paths(void) { StringArray rv = ARRAY_DICT_INIT; @@ -117,6 +133,10 @@ StringArray vim_list_runtime_paths(void) return rv; } +/// Changes vim working directory +/// +/// @param dir The new working directory +/// @param[out] err Details of an error that may have occurred void vim_change_directory(String dir, Error *err) { if (dir.size >= MAXPATHL) { @@ -141,56 +161,102 @@ void vim_change_directory(String dir, Error *err) try_end(err); } +/// Return the current line +/// +/// @param[out] err Details of an error that may have occurred +/// @return The current line string String vim_get_current_line(Error *err) { return buffer_get_line(curbuf->handle, curwin->w_cursor.lnum - 1, err); } +/// Sets the current line +/// +/// @param line The line contents +/// @param[out] err Details of an error that may have occurred void vim_set_current_line(String line, Error *err) { buffer_set_line(curbuf->handle, curwin->w_cursor.lnum - 1, line, err); } +/// Delete the current line +/// +/// @param[out] err Details of an error that may have occurred void vim_del_current_line(Error *err) { buffer_del_line(curbuf->handle, curwin->w_cursor.lnum - 1, err); } +/// Gets a global variable +/// +/// @param name The variable name +/// @param[out] err Details of an error that may have occurred +/// @return The variable value Object vim_get_var(String name, Error *err) { return dict_get_value(&globvardict, name, err); } +/// Sets a global variable. Passing 'nil' as value deletes the variable. +/// +/// @param name The variable name +/// @param value The variable value +/// @param[out] err Details of an error that may have occurred +/// @return the old value if any Object vim_set_var(String name, Object value, Error *err) { return dict_set_value(&globvardict, name, value, err); } +/// Gets a vim variable +/// +/// @param name The variable name +/// @param[out] err Details of an error that may have occurred +/// @return The variable value Object vim_get_vvar(String name, Error *err) { return dict_get_value(&vimvardict, name, err); } +/// Get an option value string +/// +/// @param name The option name +/// @param[out] err Details of an error that may have occurred +/// @return The option value Object vim_get_option(String name, Error *err) { return get_option_from(NULL, SREQ_GLOBAL, name, err); } +/// Sets an option value +/// +/// @param name The option name +/// @param value The new option value +/// @param[out] err Details of an error that may have occurred void vim_set_option(String name, Object value, Error *err) { set_option_to(NULL, SREQ_GLOBAL, name, value, err); } +/// Write a message to vim output buffer +/// +/// @param str The message void vim_out_write(String str) { write_msg(str, false); } +/// Write a message to vim error buffer +/// +/// @param str The message void vim_err_write(String str) { write_msg(str, true); } +/// Gets the current list of buffer handles +/// +/// @return The number of buffers BufferArray vim_get_buffers(void) { BufferArray rv = ARRAY_DICT_INIT; @@ -213,11 +279,18 @@ BufferArray vim_get_buffers(void) return rv; } +/// Return the current buffer +/// +/// @reqturn The buffer handle Buffer vim_get_current_buffer(void) { return curbuf->handle; } +/// Sets the current buffer +/// +/// @param id The buffer handle +/// @param[out] err Details of an error that may have occurred void vim_set_current_buffer(Buffer buffer, Error *err) { buf_T *buf = find_buffer(buffer, err); @@ -241,6 +314,9 @@ void vim_set_current_buffer(Buffer buffer, Error *err) try_end(err); } +/// Gets the current list of window handles +/// +/// @return The number of windows WindowArray vim_get_windows(void) { WindowArray rv = ARRAY_DICT_INIT; @@ -261,11 +337,17 @@ WindowArray vim_get_windows(void) return rv; } +/// Return the current window +/// +/// @return The window handle Window vim_get_current_window(void) { return curwin->handle; } +/// Sets the current window +/// +/// @param handle The window handle void vim_set_current_window(Window window, Error *err) { win_T *win = find_window(window, err); @@ -288,6 +370,9 @@ void vim_set_current_window(Window window, Error *err) try_end(err); } +/// Gets the current list of tabpage handles +/// +/// @return The number of tab pages TabpageArray vim_get_tabpages(void) { TabpageArray rv = ARRAY_DICT_INIT; @@ -310,11 +395,18 @@ TabpageArray vim_get_tabpages(void) return rv; } +/// Return the current tab page +/// +/// @return The tab page handle Tabpage vim_get_current_tabpage(void) { return curtab->handle; } +/// Sets the current tab page +/// +/// @param handle The tab page handle +/// @param[out] err Details of an error that may have occurred void vim_set_current_tabpage(Tabpage tabpage, Error *err) { tabpage_T *tp = find_tab(tabpage, err); @@ -328,6 +420,10 @@ void vim_set_current_tabpage(Tabpage tabpage, Error *err) try_end(err); } +/// Subscribes to event broadcasts +/// +/// @param channel_id The channel id(passed automatically by the dispatcher) +/// @param event The event type string void vim_subscribe(uint64_t channel_id, String event) { size_t length = (event.size < EVENT_MAXLEN ? event.size : EVENT_MAXLEN); @@ -337,6 +433,10 @@ void vim_subscribe(uint64_t channel_id, String event) channel_subscribe(channel_id, e); } +/// Unsubscribes to event broadcasts +/// +/// @param channel_id The channel id(passed automatically by the dispatcher) +/// @param event The event type string void vim_unsubscribe(uint64_t channel_id, String event) { size_t length = (event.size < EVENT_MAXLEN ? event.size : EVENT_MAXLEN); @@ -346,6 +446,13 @@ void vim_unsubscribe(uint64_t channel_id, String event) channel_unsubscribe(channel_id, e); } +/// Writes a message to vim output or error buffer. The string is split +/// and flushed after each newline. Incomplete lines are kept for writing +/// later. +/// +/// @param message The message to write +/// @param to_err True if it should be treated as an error message(use +/// `emsg` instead of `msg` to print each line) static void write_msg(String message, bool to_err) { static int pos = 0; diff --git a/src/nvim/api/vim.h b/src/nvim/api/vim.h index 4d1ac9023e..426acf7f50 100644 --- a/src/nvim/api/vim.h +++ b/src/nvim/api/vim.h @@ -6,165 +6,58 @@ #include "nvim/api/private/defs.h" -/// Send keys to vim input buffer, simulating user input. -/// -/// @param str The keys to send void vim_push_keys(String str); -/// Executes an ex-mode command str -/// -/// @param str The command str -/// @param[out] err Details of an error that may have occurred void vim_command(String str, Error *err); -/// Evaluates the expression str using the vim internal expression -/// evaluator (see |expression|). -/// Dictionaries and lists are recursively expanded. -/// -/// @param str The expression str -/// @param[out] err Details of an error that may have occurred -/// @return The expanded object Object vim_eval(String str, Error *err); -/// Calculates the number of display cells `str` occupies, tab is counted as -/// one cell. -/// -/// @param str Some text -/// @param[out] err Details of an error that may have occurred -/// @return The number of cells Integer vim_strwidth(String str, Error *err); -/// Returns a list of paths contained in 'runtimepath' -/// -/// @return The list of paths StringArray vim_list_runtime_paths(void); -/// Changes vim working directory -/// -/// @param dir The new working directory -/// @param[out] err Details of an error that may have occurred void vim_change_directory(String dir, Error *err); -/// Return the current line -/// -/// @param[out] err Details of an error that may have occurred -/// @return The current line string String vim_get_current_line(Error *err); -/// Delete the current line -/// -/// @param[out] err Details of an error that may have occurred void vim_del_current_line(Error *err); -/// Sets the current line -/// -/// @param line The line contents -/// @param[out] err Details of an error that may have occurred void vim_set_current_line(String line, Error *err); -/// Gets a global variable -/// -/// @param name The variable name -/// @param[out] err Details of an error that may have occurred -/// @return The variable value Object vim_get_var(String name, Error *err); -/// Sets a global variable. Passing 'nil' as value deletes the variable. -/// -/// @param name The variable name -/// @param value The variable value -/// @param[out] err Details of an error that may have occurred -/// @return the old value if any Object vim_set_var(String name, Object value, Error *err); -/// Gets a vim variable -/// -/// @param name The variable name -/// @param[out] err Details of an error that may have occurred -/// @return The variable value Object vim_get_vvar(String name, Error *err); -/// Get an option value string -/// -/// @param name The option name -/// @param[out] err Details of an error that may have occurred -/// @return The option value Object vim_get_option(String name, Error *err); -/// Sets an option value -/// -/// @param name The option name -/// @param value The new option value -/// @param[out] err Details of an error that may have occurred void vim_set_option(String name, Object value, Error *err); -/// Write a message to vim output buffer -/// -/// @param str The message void vim_out_write(String str); -/// Write a message to vim error buffer -/// -/// @param str The message void vim_err_write(String str); -/// Gets the current list of buffer handles -/// -/// @return The number of buffers BufferArray vim_get_buffers(void); -/// Return the current buffer -/// -/// @reqturn The buffer handle Buffer vim_get_current_buffer(void); -/// Sets the current buffer -/// -/// @param id The buffer handle -/// @param[out] err Details of an error that may have occurred void vim_set_current_buffer(Buffer buffer, Error *err); -/// Gets the current list of window handles -/// -/// @return The number of windows WindowArray vim_get_windows(void); -/// Return the current window -/// -/// @return The window handle Window vim_get_current_window(void); -/// Sets the current window -/// -/// @param handle The window handle void vim_set_current_window(Window window, Error *err); -/// Gets the current list of tabpage handles -/// -/// @return The number of tab pages TabpageArray vim_get_tabpages(void); -/// Return the current tab page -/// -/// @return The tab page handle Tabpage vim_get_current_tabpage(void); -/// Sets the current tab page -/// -/// @param handle The tab page handle -/// @param[out] err Details of an error that may have occurred void vim_set_current_tabpage(Tabpage tabpage, Error *err); -/// Subscribes to event broadcasts -/// -/// @param channel_id The channel id(passed automatically by the dispatcher) -/// @param event The event type string void vim_subscribe(uint64_t channel_id, String event); -/// Unsubscribes to event broadcasts -/// -/// @param channel_id The channel id(passed automatically by the dispatcher) -/// @param event The event type string void vim_unsubscribe(uint64_t channel_id, String event); #endif // NVIM_API_VIM_H diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index fd13557e3b..2b81afdb0c 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -12,6 +12,11 @@ #include "nvim/misc2.h" +/// Gets the current buffer in a window +/// +/// @param window The window handle +/// @param[out] err Details of an error that may have occurred +/// @return The buffer handle Buffer window_get_buffer(Window window, Error *err) { win_T *win = find_window(window, err); @@ -23,6 +28,11 @@ Buffer window_get_buffer(Window window, Error *err) return win->w_buffer->handle; } +/// Gets the cursor position in the window +/// +/// @param window The window handle +/// @param[out] err Details of an error that may have occurred +/// @return the (row, col) tuple Position window_get_cursor(Window window, Error *err) { Position rv = {.row = 0, .col = 0}; @@ -36,6 +46,11 @@ Position window_get_cursor(Window window, Error *err) return rv; } +/// Sets the cursor position in the window +/// +/// @param window The window handle +/// @param pos the (row, col) tuple representing the new position +/// @param[out] err Details of an error that may have occurred void window_set_cursor(Window window, Position pos, Error *err) { win_T *win = find_window(window, err); @@ -67,6 +82,11 @@ void window_set_cursor(Window window, Position pos, Error *err) update_screen(VALID); } +/// Gets the window height +/// +/// @param window The window handle +/// @param[out] err Details of an error that may have occurred +/// @return the height in rows Integer window_get_height(Window window, Error *err) { win_T *win = find_window(window, err); @@ -78,6 +98,12 @@ Integer window_get_height(Window window, Error *err) return win->w_height; } +/// Sets the window height. This will only succeed if the screen is split +/// horizontally. +/// +/// @param window The window handle +/// @param height the new height in rows +/// @param[out] err Details of an error that may have occurred void window_set_height(Window window, Integer height, Error *err) { win_T *win = find_window(window, err); @@ -99,6 +125,11 @@ void window_set_height(Window window, Integer height, Error *err) try_end(err); } +/// Gets the window width +/// +/// @param window The window handle +/// @param[out] err Details of an error that may have occurred +/// @return the width in columns Integer window_get_width(Window window, Error *err) { win_T *win = find_window(window, err); @@ -110,6 +141,12 @@ Integer window_get_width(Window window, Error *err) return win->w_width; } +/// Sets the window width. This will only succeed if the screen is split +/// vertically. +/// +/// @param window The window handle +/// @param width the new width in columns +/// @param[out] err Details of an error that may have occurred void window_set_width(Window window, Integer width, Error *err) { win_T *win = find_window(window, err); @@ -131,6 +168,12 @@ void window_set_width(Window window, Integer width, Error *err) try_end(err); } +/// Gets a window variable +/// +/// @param window The window handle +/// @param name The variable name +/// @param[out] err Details of an error that may have occurred +/// @return The variable value Object window_get_var(Window window, String name, Error *err) { win_T *win = find_window(window, err); @@ -142,6 +185,13 @@ Object window_get_var(Window window, String name, Error *err) return dict_get_value(win->w_vars, name, err); } +/// Sets a window variable. Passing 'nil' as value deletes the variable. +/// +/// @param window The window handle +/// @param name The variable name +/// @param value The variable value +/// @param[out] err Details of an error that may have occurred +/// @return The old value Object window_set_var(Window window, String name, Object value, Error *err) { win_T *win = find_window(window, err); @@ -153,6 +203,12 @@ Object window_set_var(Window window, String name, Object value, Error *err) return dict_set_value(win->w_vars, name, value, err); } +/// Gets a window option value +/// +/// @param window The window handle +/// @param name The option name +/// @param[out] err Details of an error that may have occurred +/// @return The option value Object window_get_option(Window window, String name, Error *err) { win_T *win = find_window(window, err); @@ -164,6 +220,13 @@ Object window_get_option(Window window, String name, Error *err) return get_option_from(win, SREQ_WIN, name, err); } +/// Sets a window option value. Passing 'nil' as value deletes the option(only +/// works if there's a global fallback) +/// +/// @param window The window handle +/// @param name The option name +/// @param value The option value +/// @param[out] err Details of an error that may have occurred void window_set_option(Window window, String name, Object value, Error *err) { win_T *win = find_window(window, err); @@ -175,6 +238,11 @@ void window_set_option(Window window, String name, Object value, Error *err) set_option_to(win, SREQ_WIN, name, value, err); } +/// Gets the window position in display cells. First position is zero. +/// +/// @param window The window handle +/// @param[out] err Details of an error that may have occurred +/// @return The (row, col) tuple with the window position Position window_get_position(Window window, Error *err) { Position rv; @@ -188,6 +256,11 @@ Position window_get_position(Window window, Error *err) return rv; } +/// Gets the window tab page +/// +/// @param window The window handle +/// @param[out] err Details of an error that may have occurred +/// @return The tab page that contains the window Tabpage window_get_tabpage(Window window, Error *err) { Tabpage rv = 0; @@ -200,6 +273,10 @@ Tabpage window_get_tabpage(Window window, Error *err) return rv; } +/// Checks if a window is valid +/// +/// @param window The window handle +/// @return true if the window is valid, false otherwise Boolean window_is_valid(Window window) { Error stub = {.set = false}; diff --git a/src/nvim/api/window.h b/src/nvim/api/window.h index 4c036ff5d7..694558fca8 100644 --- a/src/nvim/api/window.h +++ b/src/nvim/api/window.h @@ -6,109 +6,32 @@ #include "nvim/api/private/defs.h" -/// Gets the current buffer in a window -/// -/// @param window The window handle -/// @param[out] err Details of an error that may have occurred -/// @return The buffer handle Buffer window_get_buffer(Window window, Error *err); -/// Gets the cursor position in the window -/// -/// @param window The window handle -/// @param[out] err Details of an error that may have occurred -/// @return the (row, col) tuple Position window_get_cursor(Window window, Error *err); -/// Sets the cursor position in the window -/// -/// @param window The window handle -/// @param pos the (row, col) tuple representing the new position -/// @param[out] err Details of an error that may have occurred void window_set_cursor(Window window, Position pos, Error *err); -/// Gets the window height -/// -/// @param window The window handle -/// @param[out] err Details of an error that may have occurred -/// @return the height in rows Integer window_get_height(Window window, Error *err); -/// Sets the window height. This will only succeed if the screen is split -/// horizontally. -/// -/// @param window The window handle -/// @param height the new height in rows -/// @param[out] err Details of an error that may have occurred void window_set_height(Window window, Integer height, Error *err); -/// Gets the window width -/// -/// @param window The window handle -/// @param[out] err Details of an error that may have occurred -/// @return the width in columns Integer window_get_width(Window window, Error *err); -/// Sets the window width. This will only succeed if the screen is split -/// vertically. -/// -/// @param window The window handle -/// @param width the new width in columns -/// @param[out] err Details of an error that may have occurred void window_set_width(Window window, Integer width, Error *err); -/// Gets a window variable -/// -/// @param window The window handle -/// @param name The variable name -/// @param[out] err Details of an error that may have occurred -/// @return The variable value Object window_get_var(Window window, String name, Error *err); -/// Sets a window variable. Passing 'nil' as value deletes the variable. -/// -/// @param window The window handle -/// @param name The variable name -/// @param value The variable value -/// @param[out] err Details of an error that may have occurred -/// @return The old value Object window_set_var(Window window, String name, Object value, Error *err); -/// Gets a window option value -/// -/// @param window The window handle -/// @param name The option name -/// @param[out] err Details of an error that may have occurred -/// @return The option value Object window_get_option(Window window, String name, Error *err); -/// Sets a window option value. Passing 'nil' as value deletes the option(only -/// works if there's a global fallback) -/// -/// @param window The window handle -/// @param name The option name -/// @param value The option value -/// @param[out] err Details of an error that may have occurred void window_set_option(Window window, String name, Object value, Error *err); -/// Gets the window position in display cells. First position is zero. -/// -/// @param window The window handle -/// @param[out] err Details of an error that may have occurred -/// @return The (row, col) tuple with the window position Position window_get_position(Window window, Error *err); -/// Gets the window tab page -/// -/// @param window The window handle -/// @param[out] err Details of an error that may have occurred -/// @return The tab page that contains the window Tabpage window_get_tabpage(Window window, Error *err); -/// Checks if a window is valid -/// -/// @param window The window handle -/// @return true if the window is valid, false otherwise Boolean window_is_valid(Window window); #endif // NVIM_API_WINDOW_H diff --git a/src/nvim/memory.c b/src/nvim/memory.c index 238a6791c0..17d4a1ba8c 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -63,6 +63,14 @@ static void try_to_free_memory() trying_to_free = false; } +/// malloc() wrapper +/// +/// try_malloc() is a malloc() wrapper that tries to free some memory before +/// trying again. +/// +/// @see {try_to_free_memory} +/// @param size +/// @return pointer to allocated space. NULL if out of memory void *try_malloc(size_t size) { void *ret = malloc(size); @@ -80,6 +88,12 @@ void *try_malloc(size_t size) return ret; } +/// try_malloc() wrapper that shows an out-of-memory error message to the user +/// before returning NULL +/// +/// @see {try_malloc} +/// @param size +/// @return pointer to allocated space. NULL if out of memory void *verbose_try_malloc(size_t size) { void *ret = try_malloc(size); @@ -89,6 +103,14 @@ void *verbose_try_malloc(size_t size) return ret; } +/// malloc() wrapper that never returns NULL +/// +/// xmalloc() succeeds or gracefully aborts when out of memory. +/// Before aborting try to free some memory and call malloc again. +/// +/// @see {try_to_free_memory} +/// @param size +/// @return pointer to allocated space. Never NULL void *xmalloc(size_t size) { void *ret = try_malloc(size); @@ -100,6 +122,12 @@ void *xmalloc(size_t size) return ret; } +/// calloc() wrapper +/// +/// @see {xmalloc} +/// @param count +/// @param size +/// @return pointer to allocated space. Never NULL void *xcalloc(size_t count, size_t size) { void *ret = calloc(count, size); @@ -121,6 +149,11 @@ void *xcalloc(size_t count, size_t size) return ret; } +/// realloc() wrapper +/// +/// @see {xmalloc} +/// @param size +/// @return pointer to reallocated space. Never NULL void *xrealloc(void *ptr, size_t size) { void *ret = realloc(ptr, size); @@ -142,6 +175,11 @@ void *xrealloc(void *ptr, size_t size) return ret; } +/// xmalloc() wrapper that allocates size + 1 bytes and zeroes the last byte +/// +/// @see {xmalloc} +/// @param size +/// @return pointer to allocated space. Never NULL void *xmallocz(size_t size) { size_t total_size = size + 1; @@ -158,17 +196,62 @@ void *xmallocz(size_t size) return ret; } +/// Allocates (len + 1) bytes of memory, duplicates `len` bytes of +/// `data` to the allocated memory, zero terminates the allocated memory, +/// and returns a pointer to the allocated memory. If the allocation fails, +/// the program dies. +/// +/// @see {xmalloc} +/// @param data Pointer to the data that will be copied +/// @param len number of bytes that will be copied void *xmemdupz(const void *data, size_t len) { return memcpy(xmallocz(len), data, len); } +/// The xstpcpy() function shall copy the string pointed to by src (including +/// the terminating NUL character) into the array pointed to by dst. +/// +/// The xstpcpy() function shall return a pointer to the terminating NUL +/// character copied into the dst buffer. This is the only difference with +/// strcpy(), which returns dst. +/// +/// WARNING: If copying takes place between objects that overlap, the behavior is +/// undefined. +/// +/// This is the Neovim version of stpcpy(3) as defined in POSIX 2008. We +/// don't require that supported platforms implement POSIX 2008, so we +/// implement our own version. +/// +/// @param dst +/// @param src char *xstpcpy(char *restrict dst, const char *restrict src) { const size_t len = strlen(src); return (char *)memcpy(dst, src, len + 1) + len; } +/// The xstpncpy() function shall copy not more than n bytes (bytes that follow +/// a NUL character are not copied) from the array pointed to by src to the +/// array pointed to by dst. +/// +/// If a NUL character is written to the destination, the xstpncpy() function +/// shall return the address of the first such NUL character. Otherwise, it +/// shall return &dst[maxlen]. +/// +/// WARNING: If copying takes place between objects that overlap, the behavior is +/// undefined. +/// +/// WARNING: xstpncpy will ALWAYS write maxlen bytes. If src is shorter than +/// maxlen, zeroes will be written to the remaining bytes. +/// +/// TODO(aktau): I don't see a good reason to have this last behaviour, and +/// it is potentially wasteful. Could we perhaps deviate from the standard +/// and not zero the rest of the buffer? +/// +/// @param dst +/// @param src +/// @param maxlen char *xstpncpy(char *restrict dst, const char *restrict src, size_t maxlen) { const char *p = memchr(src, '\0', maxlen); @@ -183,6 +266,17 @@ char *xstpncpy(char *restrict dst, const char *restrict src, size_t maxlen) } } +/// xstrlcpy - Copy a %NUL terminated string into a sized buffer +/// +/// Compatible with *BSD strlcpy: the result is always a valid +/// NUL-terminated string that fits in the buffer (unless, +/// of course, the buffer size is zero). It does not pad +/// out the result like strncpy() does. +/// +/// @param dst Where to copy the string to +/// @param src Where to copy the string from +/// @param size Size of destination buffer +/// @return Length of the source string (i.e.: strlen(src)) size_t xstrlcpy(char *restrict dst, const char *restrict src, size_t size) { size_t ret = strlen(src); @@ -196,6 +290,11 @@ size_t xstrlcpy(char *restrict dst, const char *restrict src, size_t size) return ret; } +/// strdup() wrapper +/// +/// @see {xmalloc} +/// @param str 0-terminated string that will be copied +/// @return pointer to a copy of the string char *xstrdup(const char *str) { char *ret = strdup(str); @@ -212,12 +311,23 @@ char *xstrdup(const char *str) return ret; } +/// strndup() wrapper +/// +/// @see {xmalloc} +/// @param str 0-terminated string that will be copied +/// @return pointer to a copy of the string char *xstrndup(const char *str, size_t len) { char *p = memchr(str, '\0', len); return xmemdupz(str, p ? (size_t)(p - str) : len); } +/// Duplicates a chunk of memory using xmalloc +/// +/// @see {xmalloc} +/// @param data pointer to the chunk +/// @param len size of the chunk +/// @return a pointer void *xmemdup(const void *data, size_t len) { return memcpy(xmalloc(len), data, len); diff --git a/src/nvim/memory.h b/src/nvim/memory.h index accf293176..fc3b4ac52b 100644 --- a/src/nvim/memory.h +++ b/src/nvim/memory.h @@ -5,145 +5,35 @@ #include "nvim/types.h" #include "nvim/vim.h" -/// malloc() wrapper -/// -/// try_malloc() is a malloc() wrapper that tries to free some memory before -/// trying again. -/// -/// @see {try_to_free_memory} -/// @param size -/// @return pointer to allocated space. NULL if out of memory void *try_malloc(size_t size) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1); -/// try_malloc() wrapper that shows an out-of-memory error message to the user -/// before returning NULL -/// -/// @see {try_malloc} -/// @param size -/// @return pointer to allocated space. NULL if out of memory void *verbose_try_malloc(size_t size) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1); -/// malloc() wrapper that never returns NULL -/// -/// xmalloc() succeeds or gracefully aborts when out of memory. -/// Before aborting try to free some memory and call malloc again. -/// -/// @see {try_to_free_memory} -/// @param size -/// @return pointer to allocated space. Never NULL void *xmalloc(size_t size) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1) FUNC_ATTR_NONNULL_RET; -/// calloc() wrapper -/// -/// @see {xmalloc} -/// @param count -/// @param size -/// @return pointer to allocated space. Never NULL void *xcalloc(size_t count, size_t size) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE_PROD(1, 2) FUNC_ATTR_NONNULL_RET; -/// realloc() wrapper -/// -/// @see {xmalloc} -/// @param size -/// @return pointer to reallocated space. Never NULL void *xrealloc(void *ptr, size_t size) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALLOC_SIZE(2) FUNC_ATTR_NONNULL_RET; -/// xmalloc() wrapper that allocates size + 1 bytes and zeroes the last byte -/// -/// @see {xmalloc} -/// @param size -/// @return pointer to allocated space. Never NULL void *xmallocz(size_t size) FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_RET; -/// Allocates (len + 1) bytes of memory, duplicates `len` bytes of -/// `data` to the allocated memory, zero terminates the allocated memory, -/// and returns a pointer to the allocated memory. If the allocation fails, -/// the program dies. -/// -/// @see {xmalloc} -/// @param data Pointer to the data that will be copied -/// @param len number of bytes that will be copied void *xmemdupz(const void *data, size_t len) FUNC_ATTR_NONNULL_RET; -/// strdup() wrapper -/// -/// @see {xmalloc} -/// @param str 0-terminated string that will be copied -/// @return pointer to a copy of the string char * xstrdup(const char *str) FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET; -/// strndup() wrapper -/// -/// @see {xmalloc} -/// @param str 0-terminated string that will be copied -/// @return pointer to a copy of the string char * xstrndup(const char *str, size_t len) FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET; -/// The xstpcpy() function shall copy the string pointed to by src (including -/// the terminating NUL character) into the array pointed to by dst. -/// -/// The xstpcpy() function shall return a pointer to the terminating NUL -/// character copied into the dst buffer. This is the only difference with -/// strcpy(), which returns dst. -/// -/// WARNING: If copying takes place between objects that overlap, the behavior is -/// undefined. -/// -/// This is the Neovim version of stpcpy(3) as defined in POSIX 2008. We -/// don't require that supported platforms implement POSIX 2008, so we -/// implement our own version. -/// -/// @param dst -/// @param src char *xstpcpy(char *restrict dst, const char *restrict src); -/// The xstpncpy() function shall copy not more than n bytes (bytes that follow -/// a NUL character are not copied) from the array pointed to by src to the -/// array pointed to by dst. -/// -/// If a NUL character is written to the destination, the xstpncpy() function -/// shall return the address of the first such NUL character. Otherwise, it -/// shall return &dst[maxlen]. -/// -/// WARNING: If copying takes place between objects that overlap, the behavior is -/// undefined. -/// -/// WARNING: xstpncpy will ALWAYS write maxlen bytes. If src is shorter than -/// maxlen, zeroes will be written to the remaining bytes. -/// -/// TODO(aktau): I don't see a good reason to have this last behaviour, and -/// it is potentially wasteful. Could we perhaps deviate from the standard -/// and not zero the rest of the buffer? -/// -/// @param dst -/// @param src -/// @param maxlen char *xstpncpy(char *restrict dst, const char *restrict src, size_t maxlen); -/// xstrlcpy - Copy a %NUL terminated string into a sized buffer -/// -/// Compatible with *BSD strlcpy: the result is always a valid -/// NUL-terminated string that fits in the buffer (unless, -/// of course, the buffer size is zero). It does not pad -/// out the result like strncpy() does. -/// -/// @param dst Where to copy the string to -/// @param src Where to copy the string from -/// @param size Size of destination buffer -/// @return Length of the source string (i.e.: strlen(src)) size_t xstrlcpy(char *restrict dst, const char *restrict src, size_t size); -/// Duplicates a chunk of memory using xmalloc -/// -/// @see {xmalloc} -/// @param data pointer to the chunk -/// @param len size of the chunk -/// @return a pointer void *xmemdup(const void *data, size_t len) FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET; diff --git a/src/nvim/os/channel.c b/src/nvim/os/channel.c index 6fd7cdbb7e..5886620990 100644 --- a/src/nvim/os/channel.c +++ b/src/nvim/os/channel.c @@ -49,6 +49,7 @@ static void close_cb(uv_handle_t *handle); static WBuffer *serialize_event(char *type, typval_T *data); static Channel *register_channel(void); +/// Initializes the module void channel_init() { channels = pmap_new(uint64_t)(); @@ -56,6 +57,7 @@ void channel_init() msgpack_sbuffer_init(&msgpack_event_buffer); } +/// Teardown the module void channel_teardown() { if (!channels) { @@ -69,6 +71,10 @@ void channel_teardown() }); } +/// Creates an API channel by starting a job and connecting to its +/// stdin/stdout. stderr is forwarded to the editor error stream. +/// +/// @param argv The argument vector for the process void channel_from_job(char **argv) { Channel *channel = register_channel(); @@ -76,6 +82,10 @@ void channel_from_job(char **argv) channel->data.job_id = job_start(argv, channel, job_out, job_err, NULL); } +/// Creates an API channel from a libuv stream representing a tcp or +/// pipe/socket client connection +/// +/// @param stream The established connection void channel_from_stream(uv_stream_t *stream) { Channel *channel = register_channel(); @@ -91,6 +101,13 @@ void channel_from_stream(uv_stream_t *stream) channel->data.streams.uv = stream; } +/// Sends event/data to channel +/// +/// @param id The channel id. If 0, the event will be sent to all +/// channels that have subscribed to the event type +/// @param type The event type, an arbitrary string +/// @param obj The event data +/// @return True if the data was sent successfully, false otherwise. bool channel_send_event(uint64_t id, char *type, typval_T *data) { Channel *channel = NULL; @@ -107,6 +124,10 @@ bool channel_send_event(uint64_t id, char *type, typval_T *data) return true; } +/// Subscribes to event broadcasts +/// +/// @param id The channel id +/// @param event The event type string void channel_subscribe(uint64_t id, char *event) { Channel *channel; @@ -125,6 +146,10 @@ void channel_subscribe(uint64_t id, char *event) pmap_put(cstr_t)(channel->subscribed_events, event_string, event_string); } +/// Unsubscribes to event broadcasts +/// +/// @param id The channel id +/// @param event The event type string void channel_unsubscribe(uint64_t id, char *event) { Channel *channel; diff --git a/src/nvim/os/channel.h b/src/nvim/os/channel.h index b88cd2445f..47182594b1 100644 --- a/src/nvim/os/channel.h +++ b/src/nvim/os/channel.h @@ -2,49 +2,24 @@ #define NVIM_OS_CHANNEL_H #include <uv.h> +#include <msgpack.h> #include "nvim/vim.h" #define EVENT_MAXLEN 512 -/// Initializes the module void channel_init(void); -/// Teardown the module void channel_teardown(void); -/// Creates an API channel from a libuv stream representing a tcp or -/// pipe/socket client connection -/// -/// @param stream The established connection void channel_from_stream(uv_stream_t *stream); -/// Creates an API channel by starting a job and connecting to its -/// stdin/stdout. stderr is forwarded to the editor error stream. -/// -/// @param argv The argument vector for the process void channel_from_job(char **argv); -/// Sends event/data to channel -/// -/// @param id The channel id. If 0, the event will be sent to all -/// channels that have subscribed to the event type -/// @param type The event type, an arbitrary string -/// @param obj The event data -/// @return True if the data was sent successfully, false otherwise. bool channel_send_event(uint64_t id, char *type, typval_T *data); -/// Subscribes to event broadcasts -/// -/// @param id The channel id -/// @param event The event type string void channel_subscribe(uint64_t id, char *event); -/// Unsubscribes to event broadcasts -/// -/// @param id The channel id -/// @param event The event type string void channel_unsubscribe(uint64_t id, char *event); #endif // NVIM_OS_CHANNEL_H - diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index e7cfb8b176..6d20028c05 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -51,6 +51,9 @@ char *os_getenvname_at_index(size_t index) } +/// Get the process ID of the Neovim process. +/// +/// @return the process ID. int64_t os_get_pid() { #ifdef _WIN32 @@ -60,6 +63,10 @@ int64_t os_get_pid() #endif } +/// Get the hostname of the machine runing Neovim. +/// +/// @param hostname Buffer to store the hostname. +/// @param len Length of `hostname`. void os_get_hostname(char *hostname, size_t len) { #ifdef HAVE_SYS_UTSNAME_H diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 861e1b46c5..a67e13ead1 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -14,7 +14,11 @@ static bool is_executable_in_path(const char_u *name); // Many fs functions from libuv return that value on success. static const int kLibuvSuccess = 0; -int os_chdir(const char *path) { +/// Change to the given directory. +/// +/// @return `0` on success, a libuv error code on failure. +int os_chdir(const char *path) +{ if (p_verbose >= 5) { verbose_enter(); smsg((char_u *)"chdir(%s)", path); @@ -23,6 +27,11 @@ int os_chdir(const char *path) { return uv_chdir(path); } +/// Get the name of current directory. +/// +/// @param buf Buffer to store the directory name. +/// @param len Length of `buf`. +/// @return `OK` for success, `FAIL` for failure. int os_dirname(char_u *buf, size_t len) { assert(buf && len); @@ -35,6 +44,9 @@ int os_dirname(char_u *buf, size_t len) return OK; } +/// Check if the given path is a directory or not. +/// +/// @return `true` if `fname` is a directory. bool os_isdir(const char_u *name) { int32_t mode = os_getperm(name); @@ -49,6 +61,14 @@ bool os_isdir(const char_u *name) return true; } +/// Check if the given path represents an executable file. +/// +/// @return `true` if `name` is executable and +/// - can be found in $PATH, +/// - is relative to current dir or +/// - is absolute. +/// +/// @return `false` otherwise. bool os_can_exe(const char_u *name) { // If it's an absolute or relative path don't need to use $PATH. @@ -125,6 +145,9 @@ static bool is_executable_in_path(const char_u *name) return false; } +/// Get stat information for a file. +/// +/// @return OK on success, FAIL if an failure occured. int os_stat(const char_u *name, uv_stat_t *statbuf) { uv_fs_t request; @@ -140,6 +163,9 @@ int os_stat(const char_u *name, uv_stat_t *statbuf) return FAIL; } +/// Get the file permissions for a given file. +/// +/// @return `-1` when `name` doesn't exist. int32_t os_getperm(const char_u *name) { uv_stat_t statbuf; @@ -150,6 +176,9 @@ int32_t os_getperm(const char_u *name) } } +/// Set the permission of a file. +/// +/// @return `OK` for success, `FAIL` for failure. int os_setperm(const char_u *name, int perm) { uv_fs_t request; @@ -164,6 +193,9 @@ int os_setperm(const char_u *name, int perm) return FAIL; } +/// Check if a file exists. +/// +/// @return `true` if `name` exists. bool os_file_exists(const char_u *name) { uv_stat_t statbuf; @@ -174,11 +206,19 @@ bool os_file_exists(const char_u *name) return false; } +/// Check if a file is readonly. +/// +/// @return `true` if `name` is readonly. bool os_file_is_readonly(const char *name) { return access(name, W_OK) != 0; } +/// Check if a file is writable. +/// +/// @return `0` if `name` is not writable, +/// @return `1` if `name` is writable, +/// @return `2` for a directory which we have rights to write into. int os_file_is_writable(const char *name) { if (access(name, W_OK) == 0) { @@ -190,6 +230,10 @@ int os_file_is_writable(const char *name) return 0; } +/// Get the size of a file in bytes. +/// +/// @param[out] size pointer to an off_t to put the size into. +/// @return `true` for success, `false` for failure. bool os_get_file_size(const char *name, off_t *size) { uv_stat_t statbuf; @@ -200,6 +244,9 @@ bool os_get_file_size(const char *name, off_t *size) return false; } +/// Rename a file or directory. +/// +/// @return `OK` for success, `FAIL` for failure. int os_rename(const char_u *path, const char_u *new_path) { uv_fs_t request; @@ -214,6 +261,9 @@ int os_rename(const char_u *path, const char_u *new_path) return FAIL; } +/// Make a directory. +/// +/// @return `0` for success, non-zero for failure. int os_mkdir(const char *path, int32_t mode) { uv_fs_t request; @@ -222,6 +272,9 @@ int os_mkdir(const char *path, int32_t mode) return result; } +/// Remove a directory. +/// +/// @return `0` for success, non-zero for failure. int os_rmdir(const char *path) { uv_fs_t request; @@ -230,6 +283,9 @@ int os_rmdir(const char *path) return result; } +/// Remove a file. +/// +/// @return `0` for success, non-zero for failure. int os_remove(const char *path) { uv_fs_t request; @@ -238,6 +294,11 @@ int os_remove(const char *path) return result; } +/// Get the file information for a given path +/// +/// @param file_descriptor File descriptor of the file. +/// @param[out] file_info Pointer to a FileInfo to put the information in. +/// @return `true` on sucess, `false` for failure. bool os_get_file_info(const char *path, FileInfo *file_info) { if (os_stat((char_u *)path, &(file_info->stat)) == OK) { @@ -246,6 +307,11 @@ bool os_get_file_info(const char *path, FileInfo *file_info) return false; } +/// Get the file information for a given path without following links +/// +/// @param path Path to the file. +/// @param[out] file_info Pointer to a FileInfo to put the information in. +/// @return `true` on sucess, `false` for failure. bool os_get_file_info_link(const char *path, FileInfo *file_info) { uv_fs_t request; @@ -258,6 +324,11 @@ bool os_get_file_info_link(const char *path, FileInfo *file_info) return false; } +/// Get the file information for a given file descriptor +/// +/// @param file_descriptor File descriptor of the file. +/// @param[out] file_info Pointer to a FileInfo to put the information in. +/// @return `true` on sucess, `false` for failure. bool os_get_file_info_fd(int file_descriptor, FileInfo *file_info) { uv_fs_t request; @@ -270,6 +341,9 @@ bool os_get_file_info_fd(int file_descriptor, FileInfo *file_info) return false; } +/// Compare the inodes of two FileInfos +/// +/// @return `true` if the two FileInfos represent the same file. bool os_file_info_id_equal(FileInfo *file_info_1, FileInfo *file_info_2) { return file_info_1->stat.st_ino == file_info_2->stat.st_ino diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index a673a6c8b8..95afa95d61 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -124,6 +124,10 @@ void os_breakcheck() fill_input_buf(false); } +/// Test whether a file descriptor refers to a terminal. +/// +/// @param fd File descriptor. +/// @return `true` if file descriptor refers to a terminal. bool os_isatty(int fd) { return uv_guess_handle(fd) == UV_TTY; diff --git a/src/nvim/os/input.h b/src/nvim/os/input.h index 298df04578..57602336d5 100644 --- a/src/nvim/os/input.h +++ b/src/nvim/os/input.h @@ -13,10 +13,6 @@ int os_inchar(uint8_t *, int, int32_t, int); bool os_char_avail(void); void os_breakcheck(void); -/// Test whether a file descriptor refers to a terminal. -/// -/// @param fd File descriptor. -/// @return `true` if file descriptor refers to a terminal. bool os_isatty(int fd); #endif // NVIM_OS_INPUT_H diff --git a/src/nvim/os/job.c b/src/nvim/os/job.c index c4a9c85d1d..d19e009421 100644 --- a/src/nvim/os/job.c +++ b/src/nvim/os/job.c @@ -69,12 +69,14 @@ static void exit_cb(uv_process_t *proc, int64_t status, int term_signal); static void close_cb(uv_handle_t *handle); static void emit_exit_event(Job *job); +/// Initializes job control resources void job_init() { uv_disable_stdio_inheritance(); uv_prepare_init(uv_default_loop(), &job_prepare); } +/// Releases job control resources and terminates running jobs void job_teardown() { // 20 tries will give processes about 1 sec to exit cleanly @@ -121,6 +123,19 @@ void job_teardown() } } +/// Tries to start a new job. +/// +/// @param argv Argument vector for the process. The first item is the +/// executable to run. +/// @param data Caller data that will be associated with the job +/// @param stdout_cb Callback that will be invoked when data is available +/// on stdout +/// @param stderr_cb Callback that will be invoked when data is available +/// on stderr +/// @param exit_cb Callback that will be invoked when the job exits +/// @return The job id if the job started successfully. If the the first item / +/// of `argv`(the program) could not be executed, -1 will be returned. +// 0 will be returned if the job table is full. int job_start(char **argv, void *data, rstream_cb stdout_cb, @@ -212,6 +227,12 @@ int job_start(char **argv, return job->id; } +/// Terminates a job. This is a non-blocking operation, but if the job exists +/// it's guaranteed to succeed(SIGKILL will eventually be sent) +/// +/// @param id The job id +/// @return true if the stop request was successfully sent, false if the job +/// id is invalid(probably because it has already stopped) bool job_stop(int id) { Job *job = find_job(id); @@ -225,6 +246,14 @@ bool job_stop(int id) return true; } +/// Writes data to the job's stdin. This is a non-blocking operation, it +/// returns when the write request was sent. +/// +/// @param id The job id +/// @param data Buffer containing the data to be written +/// @param len Size of the data +/// @return true if the write request was successfully sent, false if the job +/// id is invalid(probably because it has already stopped) bool job_write(int id, char *data, uint32_t len) { Job *job = find_job(id); @@ -242,6 +271,9 @@ bool job_write(int id, char *data, uint32_t len) return true; } +/// Runs the read callback associated with the job exit event +/// +/// @param event Object containing data necessary to invoke the callback void job_exit_event(Event event) { Job *job = event.data.job; @@ -265,11 +297,19 @@ void job_exit_event(Event event) } } +/// Get the job id +/// +/// @param job A pointer to the job +/// @return The job id int job_id(Job *job) { return job->id; } +/// Get data associated with a job +/// +/// @param job A pointer to the job +/// @return The job data void *job_data(Job *job) { return job->data; diff --git a/src/nvim/os/job.h b/src/nvim/os/job.h index 4ddbc75807..3d4c14a14a 100644 --- a/src/nvim/os/job.h +++ b/src/nvim/os/job.h @@ -13,65 +13,24 @@ #include "nvim/os/event_defs.h" #include "nvim/os/rstream_defs.h" -/// Initializes job control resources void job_init(void); -/// Releases job control resources and terminates running jobs void job_teardown(void); -/// Tries to start a new job. -/// -/// @param argv Argument vector for the process. The first item is the -/// executable to run. -/// @param data Caller data that will be associated with the job -/// @param stdout_cb Callback that will be invoked when data is available -/// on stdout -/// @param stderr_cb Callback that will be invoked when data is available -/// on stderr -/// @param exit_cb Callback that will be invoked when the job exits. This is -/// optional. -/// @return The job id if the job started successfully. If the the first item / -/// of `argv`(the program) could not be executed, -1 will be returned. -// 0 will be returned if the job table is full. int job_start(char **argv, void *data, rstream_cb stdout_cb, rstream_cb stderr_cb, job_exit_cb exit_cb); -/// Terminates a job. This is a non-blocking operation, but if the job exists -/// it's guaranteed to succeed(SIGKILL will eventually be sent) -/// -/// @param id The job id -/// @return true if the stop request was successfully sent, false if the job -/// id is invalid(probably because it has already stopped) bool job_stop(int id); -/// Writes data to the job's stdin. This is a non-blocking operation, it -/// returns when the write request was sent. -/// -/// @param id The job id -/// @param data Buffer containing the data to be written -/// @param len Size of the data -/// @return true if the write request was successfully sent, false if the job -/// id is invalid(probably because it has already stopped) bool job_write(int id, char *data, uint32_t len); -/// Runs the read callback associated with the job exit event -/// -/// @param event Object containing data necessary to invoke the callback void job_exit_event(Event event); -/// Get the job id -/// -/// @param job A pointer to the job -/// @return The job id int job_id(Job *job); -/// Get data associated with a job -/// -/// @param job A pointer to the job -/// @return The job data void *job_data(Job *job); #endif // NVIM_OS_JOB_H diff --git a/src/nvim/os/mem.c b/src/nvim/os/mem.c index 6c8b49d04e..5e483c0c3d 100644 --- a/src/nvim/os/mem.c +++ b/src/nvim/os/mem.c @@ -4,7 +4,9 @@ #include "nvim/os/os.h" -uint64_t os_get_total_mem_kib(void) { +/// Get the total system physical memory in KiB. +uint64_t os_get_total_mem_kib(void) +{ // Convert bytes to KiB. return uv_get_total_memory() >> 10; } diff --git a/src/nvim/os/os.h b/src/nvim/os/os.h index fa040d29bd..73e09e5012 100644 --- a/src/nvim/os/os.h +++ b/src/nvim/os/os.h @@ -4,101 +4,41 @@ #include "nvim/vim.h" -/// Change to the given directory. -/// -/// @return `0` on success, a libuv error code on failure. int os_chdir(const char *path); -/// Get the name of current directory. -/// -/// @param buf Buffer to store the directory name. -/// @param len Length of `buf`. -/// @return `OK` for success, `FAIL` for failure. int os_dirname(char_u *buf, size_t len); -/// Check if the given path is a directory or not. -/// -/// @return `true` if `fname` is a directory. bool os_isdir(const char_u *name); -/// Check if the given path represents an executable file. -/// -/// @return `true` if `name` is executable and -/// - can be found in $PATH, -/// - is relative to current dir or -/// - is absolute. -/// -/// @return `false` otherwise. bool os_can_exe(const char_u *name); -/// Get the file permissions for a given file. -/// -/// @return `-1` when `name` doesn't exist. int32_t os_getperm(const char_u *name); -/// Set the permission of a file. -/// -/// @return `OK` for success, `FAIL` for failure. int os_setperm(const char_u *name, int perm); -/// Check if a file exists. -/// -/// @return `true` if `name` exists. bool os_file_exists(const char_u *name); -/// Check if a file is readonly. -/// -/// @return `true` if `name` is readonly. bool os_file_is_readonly(const char *name); -/// Check if a file is writable. -/// -/// @return `0` if `name` is not writable, -/// @return `1` if `name` is writable, -/// @return `2` for a directory which we have rights to write into. int os_file_is_writable(const char *name); -/// Get the size of a file in bytes. -/// -/// @param[out] size pointer to an off_t to put the size into. -/// @return `true` for success, `false` for failure. bool os_get_file_size(const char *name, off_t *size); -/// Rename a file or directory. -/// -/// @return `OK` for success, `FAIL` for failure. int os_rename(const char_u *path, const char_u *new_path); -/// Make a directory. -/// -/// @return `0` for success, non-zero for failure. int os_mkdir(const char *path, int32_t mode); -/// Remove a directory. -/// -/// @return `0` for success, non-zero for failure. int os_rmdir(const char *path); -/// Remove a file. -/// -/// @return `0` for success, non-zero for failure. int os_remove(const char *path); -/// Get the total system physical memory in KiB. uint64_t os_get_total_mem_kib(void); const char *os_getenv(const char *name); int os_setenv(const char *name, const char *value, int overwrite); char *os_getenvname_at_index(size_t index); -/// Get the process ID of the Neovim process. -/// -/// @return the process ID. int64_t os_get_pid(void); -/// Get the hostname of the machine runing Neovim. -/// -/// @param hostname Buffer to store the hostname. -/// @param len Length of `hostname`. void os_get_hostname(char *hostname, size_t len); int os_get_usernames(garray_T *usernames); @@ -106,9 +46,6 @@ int os_get_user_name(char *s, size_t len); int os_get_uname(uid_t uid, char *s, size_t len); char *os_get_user_directory(const char *name); -/// Get stat information for a file. -/// -/// @return OK on success, FAIL if an failure occured. int os_stat(const char_u *name, uv_stat_t *statbuf); /// Struct which encapsulates stat information. @@ -117,30 +54,12 @@ typedef struct { uv_stat_t stat; } FileInfo; -/// Get the file information for a given path -/// -/// @param file_descriptor File descriptor of the file. -/// @param[out] file_info Pointer to a FileInfo to put the information in. -/// @return `true` on sucess, `false` for failure. bool os_get_file_info(const char *path, FileInfo *file_info); -/// Get the file information for a given path without following links -/// -/// @param path Path to the file. -/// @param[out] file_info Pointer to a FileInfo to put the information in. -/// @return `true` on sucess, `false` for failure. bool os_get_file_info_link(const char *path, FileInfo *file_info); -/// Get the file information for a given file descriptor -/// -/// @param file_descriptor File descriptor of the file. -/// @param[out] file_info Pointer to a FileInfo to put the information in. -/// @return `true` on sucess, `false` for failure. bool os_get_file_info_fd(int file_descriptor, FileInfo *file_info); -/// Compare the inodes of two FileInfos -/// -/// @return `true` if the two FileInfos represent the same file. bool os_file_info_id_equal(FileInfo *file_info_1, FileInfo *file_info_2); #endif // NVIM_OS_OS_H diff --git a/src/nvim/os/rstream.c b/src/nvim/os/rstream.c index 4e6fc55d3b..be37204de6 100644 --- a/src/nvim/os/rstream.c +++ b/src/nvim/os/rstream.c @@ -34,6 +34,18 @@ static void fread_idle_cb(uv_idle_t *); static void close_cb(uv_handle_t *handle); static void emit_read_event(RStream *rstream, bool eof); +/// Creates a new RStream instance. A RStream encapsulates all the boilerplate +/// necessary for reading from a libuv stream. +/// +/// @param cb A function that will be called whenever some data is available +/// for reading with `rstream_read` +/// @param buffer_size Size in bytes of the internal buffer. +/// @param data Some state to associate with the `RStream` instance +/// @param async Flag that specifies if the callback should only be called +/// outside libuv event loop(When processing async events with +/// KE_EVENT). Only the RStream instance reading user input should set +/// this to false +/// @return The newly-allocated `RStream` instance RStream * rstream_new(rstream_cb cb, size_t buffer_size, void *data, @@ -54,6 +66,9 @@ RStream * rstream_new(rstream_cb cb, return rv; } +/// Frees all memory allocated for a RStream instance +/// +/// @param rstream The `RStream` instance void rstream_free(RStream *rstream) { if (rstream->free_handle) { @@ -68,12 +83,21 @@ void rstream_free(RStream *rstream) free(rstream); } +/// Sets the underlying `uv_stream_t` instance +/// +/// @param rstream The `RStream` instance +/// @param stream The new `uv_stream_t` instance void rstream_set_stream(RStream *rstream, uv_stream_t *stream) { handle_set_rstream((uv_handle_t *)stream, rstream); rstream->stream = stream; } +/// Sets the underlying file descriptor that will be read from. Only pipes +/// and regular files are supported for now. +/// +/// @param rstream The `RStream` instance +/// @param file The file descriptor void rstream_set_file(RStream *rstream, uv_file file) { rstream->file_type = uv_guess_handle(file); @@ -111,11 +135,18 @@ void rstream_set_file(RStream *rstream, uv_file file) rstream->free_handle = true; } +/// Tests if the stream is backed by a regular file +/// +/// @param rstream The `RStream` instance +/// @return True if the underlying file descriptor represents a regular file bool rstream_is_regular_file(RStream *rstream) { return rstream->file_type == UV_FILE; } +/// Starts watching for events from a `RStream` instance. +/// +/// @param rstream The `RStream` instance void rstream_start(RStream *rstream) { if (rstream->file_type == UV_FILE) { @@ -126,6 +157,9 @@ void rstream_start(RStream *rstream) } } +/// Stops watching for events from a `RStream` instance. +/// +/// @param rstream The `RStream` instance void rstream_stop(RStream *rstream) { if (rstream->file_type == UV_FILE) { @@ -135,6 +169,12 @@ void rstream_stop(RStream *rstream) } } +/// Reads data from a `RStream` instance into a buffer. +/// +/// @param rstream The `RStream` instance +/// @param buffer The buffer which will receive the data +/// @param count Number of bytes that `buffer` can accept +/// @return The number of bytes copied into `buffer` size_t rstream_read(RStream *rstream, char *buf, size_t count) { size_t read_count = rstream->wpos - rstream->rpos; @@ -167,11 +207,18 @@ size_t rstream_read(RStream *rstream, char *buf, size_t count) return read_count; } +/// Returns the number of bytes available for reading from `rstream` +/// +/// @param rstream The `RStream` instance +/// @return The number of bytes available size_t rstream_available(RStream *rstream) { return rstream->wpos - rstream->rpos; } +/// Runs the read callback associated with the rstream +/// +/// @param event Object containing data necessary to invoke the callback void rstream_read_event(Event event) { RStream *rstream = event.data.rstream.ptr; diff --git a/src/nvim/os/rstream.h b/src/nvim/os/rstream.h index 5afa864f04..b93430ebcf 100644 --- a/src/nvim/os/rstream.h +++ b/src/nvim/os/rstream.h @@ -8,74 +8,27 @@ #include "nvim/os/event_defs.h" #include "nvim/os/rstream_defs.h" -/// Creates a new RStream instance. A RStream encapsulates all the boilerplate -/// necessary for reading from a libuv stream. -/// -/// @param cb A function that will be called whenever some data is available -/// for reading with `rstream_read` -/// @param buffer_size Size in bytes of the internal buffer. -/// @param data Some state to associate with the `RStream` instance -/// @param async Flag that specifies if the callback should only be called -/// outside libuv event loop(When processing async events with -/// KE_EVENT). Only the RStream instance reading user input should set -/// this to false -/// @return The newly-allocated `RStream` instance RStream * rstream_new(rstream_cb cb, size_t buffer_size, void *data, bool async); -/// Frees all memory allocated for a RStream instance -/// -/// @param rstream The `RStream` instance void rstream_free(RStream *rstream); -/// Sets the underlying `uv_stream_t` instance -/// -/// @param rstream The `RStream` instance -/// @param stream The new `uv_stream_t` instance void rstream_set_stream(RStream *rstream, uv_stream_t *stream); -/// Sets the underlying file descriptor that will be read from. Only pipes -/// and regular files are supported for now. -/// -/// @param rstream The `RStream` instance -/// @param file The file descriptor void rstream_set_file(RStream *rstream, uv_file file); -/// Tests if the stream is backed by a regular file -/// -/// @param rstream The `RStream` instance -/// @return True if the underlying file descriptor represents a regular file bool rstream_is_regular_file(RStream *rstream); -/// Starts watching for events from a `RStream` instance. -/// -/// @param rstream The `RStream` instance void rstream_start(RStream *rstream); -/// Stops watching for events from a `RStream` instance. -/// -/// @param rstream The `RStream` instance void rstream_stop(RStream *rstream); -/// Reads data from a `RStream` instance into a buffer. -/// -/// @param rstream The `RStream` instance -/// @param buffer The buffer which will receive the data -/// @param count Number of bytes that `buffer` can accept -/// @return The number of bytes copied into `buffer` size_t rstream_read(RStream *rstream, char *buffer, size_t count); -/// Returns the number of bytes available for reading from `rstream` -/// -/// @param rstream The `RStream` instance -/// @return The number of bytes available size_t rstream_available(RStream *rstream); -/// Runs the read callback associated with the rstream -/// -/// @param event Object containing data necessary to invoke the callback void rstream_read_event(Event event); #endif // NVIM_OS_RSTREAM_H diff --git a/src/nvim/os/server.c b/src/nvim/os/server.c index 4aac2babc6..18a941a264 100644 --- a/src/nvim/os/server.c +++ b/src/nvim/os/server.c @@ -46,6 +46,7 @@ static void connection_cb(uv_stream_t *server, int status); static void free_client(uv_handle_t *handle); static void free_server(uv_handle_t *handle); +/// Initializes the module void server_init() { servers = pmap_new(cstr_t)(); @@ -59,6 +60,7 @@ void server_init() server_start((char *)os_getenv("NEOVIM_LISTEN_ADDRESS")); } +/// Teardown the server module void server_teardown() { if (!servers) { @@ -76,6 +78,15 @@ void server_teardown() }); } +/// Starts listening on arbitrary tcp/unix addresses specified by +/// `endpoint` for API calls. The type of socket used(tcp or unix/pipe) will +/// be determined by parsing `endpoint`: If it's a valid tcp address in the +/// 'ip:port' format, then it will be tcp socket, else it will be a unix +/// socket or named pipe. +/// +/// @param endpoint Address of the server. Either a 'ip:port' string or an +/// arbitrary identifier(trimmed to 256 bytes) for the unix socket or +/// named pipe. void server_start(char *endpoint) { char addr[ADDRESS_MAX_SIZE]; @@ -175,6 +186,9 @@ void server_start(char *endpoint) pmap_put(cstr_t)(servers, addr, server); } +/// Stops listening on the address specified by `endpoint`. +/// +/// @param endpoint Address of the server. void server_stop(char *endpoint) { Server *server; diff --git a/src/nvim/os/server.h b/src/nvim/os/server.h index f6270b42e9..9023dd8b3d 100644 --- a/src/nvim/os/server.h +++ b/src/nvim/os/server.h @@ -1,26 +1,12 @@ #ifndef NVIM_OS_SERVER_H #define NVIM_OS_SERVER_H -/// Initializes the module void server_init(); -/// Teardown the server module void server_teardown(); -/// Starts listening on arbitrary tcp/unix addresses specified by -/// `endpoint` for API calls. The type of socket used(tcp or unix/pipe) will -/// be determined by parsing `endpoint`: If it's a valid tcp address in the -/// 'ip:port' format, then it will be tcp socket, else it will be a unix -/// socket or named pipe. -/// -/// @param endpoint Address of the server. Either a 'ip:port' string or an -/// arbitrary identifier(trimmed to 256 bytes) for the unix socket or -/// named pipe. void server_start(char *endpoint); -/// Stops listening on the address specified by `endpoint`. -/// -/// @param endpoint Address of the server. void server_stop(char *endpoint); #endif // NVIM_OS_SERVER_H diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index 8e49f8f2bb..5e02c3504b 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -31,33 +31,12 @@ typedef struct { garray_T ga; } ProcessData; -/// Parses a command string into a sequence of words, taking quotes into -/// consideration. -/// -/// @param str The command string to be parsed -/// @param argv The vector that will be filled with copies of the parsed -/// words. It can be NULL if the caller only needs to count words. -/// @return The number of words parsed. static int tokenize(char_u *str, char **argv); -/// Calculates the length of a shell word. -/// -/// @param str A pointer to the first character of the word -/// @return The offset from `str` at which the word ends. static int word_length(char_u *command); -/// Queues selected range for writing to the child process stdin. -/// -/// @param req The structure containing information to peform the write static void write_selection(uv_write_t *req); -/// Cleanup memory and restore state modified by `os_call_shell`. -/// -/// @param data State shared by all functions collaborating with -/// `os_call_shell`. -/// @param opts Process spawning options, containing some allocated memory -/// @param shellopts Options passed to `os_call_shell`. Used for deciding -/// if/which messages are displayed. static int proc_cleanup_exit(ProcessData *data, uv_process_options_t *opts, int shellopts); @@ -67,6 +46,14 @@ static void read_cb(uv_stream_t *stream, ssize_t cnt, const uv_buf_t *buf); static void write_cb(uv_write_t *req, int status); static void exit_cb(uv_process_t *proc, int64_t status, int term_signal); +/// Builds the argument vector for running the shell configured in `sh` +/// ('shell' option), optionally with a command that will be passed with `shcf` +/// ('shellcmdflag'). +/// +/// @param cmd Command string. If NULL it will run an interactive shell. +/// @param extra_shell_opt Extra argument to the shell. If NULL it is ignored +/// @return A newly allocated argument vector. It must be freed with +/// `shell_free_argv` when no longer needed. char ** shell_build_argv(char_u *cmd, char_u *extra_shell_opt) { int i; @@ -94,6 +81,9 @@ char ** shell_build_argv(char_u *cmd, char_u *extra_shell_opt) return rv; } +/// Releases the memory allocated by `shell_build_argv`. +/// +/// @param argv The argument vector. void shell_free_argv(char **argv) { char **p = argv; @@ -112,6 +102,13 @@ void shell_free_argv(char **argv) free(argv); } +/// Calls the user shell for running a command, interactive session or +/// wildcard expansion. It uses the shell set in the `sh` option. +/// +/// @param cmd The command to be executed. If NULL it will run an interactive +/// shell +/// @param opts Various options that control how the shell will work +/// @param extra_shell_arg Extra argument to be passed to the shell int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg) { uv_stdio_container_t proc_stdio[3]; @@ -247,6 +244,13 @@ int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg) return proc_cleanup_exit(&pdata, &proc_opts, opts); } +/// Parses a command string into a sequence of words, taking quotes into +/// consideration. +/// +/// @param str The command string to be parsed +/// @param argv The vector that will be filled with copies of the parsed +/// words. It can be NULL if the caller only needs to count words. +/// @return The number of words parsed. static int tokenize(char_u *str, char **argv) { int argc = 0, len; @@ -270,6 +274,10 @@ static int tokenize(char_u *str, char **argv) return argc; } +/// Calculates the length of a shell word. +/// +/// @param str A pointer to the first character of the word +/// @return The offset from `str` at which the word ends. static int word_length(char_u *str) { char_u *p = str; @@ -296,6 +304,9 @@ static int word_length(char_u *str) /// event loop starts. If we don't(by writing in chunks returned by `ml_get`) /// the buffer being modified might get modified by reading from the process /// before we finish writing. +/// Queues selected range for writing to the child process stdin. +/// +/// @param req The structure containing information to peform the write static void write_selection(uv_write_t *req) { ProcessData *pdata = (ProcessData *)req->data; @@ -429,6 +440,13 @@ static void write_cb(uv_write_t *req, int status) pdata->exited++; } +/// Cleanup memory and restore state modified by `os_call_shell`. +/// +/// @param data State shared by all functions collaborating with +/// `os_call_shell`. +/// @param opts Process spawning options, containing some allocated memory +/// @param shellopts Options passed to `os_call_shell`. Used for deciding +/// if/which messages are displayed. static int proc_cleanup_exit(ProcessData *proc_data, uv_process_options_t *proc_opts, int shellopts) diff --git a/src/nvim/os/shell.h b/src/nvim/os/shell.h index 226ef97579..a63fed7277 100644 --- a/src/nvim/os/shell.h +++ b/src/nvim/os/shell.h @@ -17,28 +17,10 @@ typedef enum { kShellOptHideMess = 128, ///< previously a global variable from os_unix.c } ShellOpts; -/// Builds the argument vector for running the shell configured in `sh` -/// ('shell' option), optionally with a command that will be passed with `shcf` -/// ('shellcmdflag'). -/// -/// @param cmd Command string. If NULL it will run an interactive shell. -/// @param extra_shell_opt Extra argument to the shell. If NULL it is ignored -/// @return A newly allocated argument vector. It must be freed with -/// `shell_free_argv` when no longer needed. char ** shell_build_argv(char_u *cmd, char_u *extra_shell_arg); -/// Releases the memory allocated by `shell_build_argv`. -/// -/// @param argv The argument vector. void shell_free_argv(char **argv); -/// Calls the user shell for running a command, interactive session or -/// wildcard expansion. It uses the shell set in the `sh` option. -/// -/// @param cmd The command to be executed. If NULL it will run an interactive -/// shell -/// @param opts Various options that control how the shell will work -/// @param extra_shell_arg Extra argument to be passed to the shell int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg); #endif // NVIM_OS_SHELL_H diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c index 2a607de36d..66f9405510 100644 --- a/src/nvim/os/time.c +++ b/src/nvim/os/time.c @@ -13,17 +13,26 @@ static uv_cond_t delay_cond; static void microdelay(uint64_t ms); +/// Initializes the time module void time_init() { uv_mutex_init(&delay_mutex); uv_cond_init(&delay_cond); } +/// Sleeps for a certain amount of milliseconds +/// +/// @param milliseconds Number of milliseconds to sleep +/// @param ignoreinput If true, allow a SIGINT to interrupt us void os_delay(uint64_t milliseconds, bool ignoreinput) { os_microdelay(milliseconds * 1000, ignoreinput); } +/// Sleeps for a certain amount of microseconds +/// +/// @param microseconds Number of microseconds to sleep +/// @param ignoreinput If true, allow a SIGINT to interrupt us void os_microdelay(uint64_t microseconds, bool ignoreinput) { int old_tmode; @@ -61,6 +70,9 @@ static void microdelay(uint64_t microseconds) uv_mutex_unlock(&delay_mutex); } +/// Portable version of POSIX localtime_r() +/// +/// @return NULL in case of error struct tm *os_localtime_r(const time_t *clock, struct tm *result) { #ifdef UNIX @@ -75,6 +87,11 @@ return result; #endif } +/// Obtains the current UNIX timestamp and adjusts it to local time +/// +/// @param result Pointer to a 'struct tm' where the result should be placed +/// @return A pointer to a 'struct tm' in the current time zone (the 'result' +/// argument) or NULL in case of error struct tm *os_get_localtime(struct tm *result) { struct timeval tv; diff --git a/src/nvim/os/time.h b/src/nvim/os/time.h index 02fd77551e..3b185825be 100644 --- a/src/nvim/os/time.h +++ b/src/nvim/os/time.h @@ -4,31 +4,14 @@ #include <stdint.h> #include <stdbool.h> -/// Initializes the time module void time_init(void); -/// Sleeps for a certain amount of milliseconds -/// -/// @param milliseconds Number of milliseconds to sleep -/// @param ignoreinput If true, allow a SIGINT to interrupt us void os_delay(uint64_t milliseconds, bool ignoreinput); -/// Sleeps for a certain amount of microseconds -/// -/// @param microseconds Number of microseconds to sleep -/// @param ignoreinput If true, allow a SIGINT to interrupt us void os_microdelay(uint64_t microseconds, bool ignoreinput); -/// Portable version of POSIX localtime_r() -/// -/// @return NULL in case of error struct tm *os_localtime_r(const time_t *clock, struct tm *result); -/// Obtains the current UNIX timestamp and adjusts it to local time -/// -/// @param result Pointer to a 'struct tm' where the result should be placed -/// @return A pointer to a 'struct tm' in the current time zone (the 'result' -/// argument) or NULL in case of error struct tm *os_get_localtime(struct tm *result); #endif // NVIM_OS_TIME_H diff --git a/src/nvim/os/uv_helpers.c b/src/nvim/os/uv_helpers.c index f8371c04c2..fa81fcdcc6 100644 --- a/src/nvim/os/uv_helpers.c +++ b/src/nvim/os/uv_helpers.c @@ -15,6 +15,10 @@ typedef struct { static HandleData *init(uv_handle_t *handle); +/// Gets the RStream instance associated with a libuv handle +/// +/// @param handle libuv handle +/// @return the RStream pointer RStream *handle_get_rstream(uv_handle_t *handle) { RStream *rv = init(handle)->rstream; @@ -22,11 +26,19 @@ RStream *handle_get_rstream(uv_handle_t *handle) return rv; } +/// Associates a RStream instance with a libuv handle +/// +/// @param handle libuv handle +/// @param rstream the RStream pointer void handle_set_rstream(uv_handle_t *handle, RStream *rstream) { init(handle)->rstream = rstream; } +/// Gets the WStream instance associated with a libuv handle +/// +/// @param handle libuv handle +/// @return the WStream pointer WStream *handle_get_wstream(uv_handle_t *handle) { WStream *rv = init(handle)->wstream; @@ -34,12 +46,20 @@ WStream *handle_get_wstream(uv_handle_t *handle) return rv; } +/// Associates a WStream instance with a libuv handle +/// +/// @param handle libuv handle +/// @param wstream the WStream pointer void handle_set_wstream(uv_handle_t *handle, WStream *wstream) { HandleData *data = init(handle); data->wstream = wstream; } +/// Gets the Job instance associated with a libuv handle +/// +/// @param handle libuv handle +/// @return the Job pointer Job *handle_get_job(uv_handle_t *handle) { Job *rv = init(handle)->job; @@ -47,6 +67,10 @@ Job *handle_get_job(uv_handle_t *handle) return rv; } +/// Associates a Job instance with a libuv handle +/// +/// @param handle libuv handle +/// @param job the Job pointer void handle_set_job(uv_handle_t *handle, Job *job) { init(handle)->job = job; diff --git a/src/nvim/os/uv_helpers.h b/src/nvim/os/uv_helpers.h index 03fd64457f..ea797ba9f0 100644 --- a/src/nvim/os/uv_helpers.h +++ b/src/nvim/os/uv_helpers.h @@ -7,40 +7,16 @@ #include "nvim/os/rstream_defs.h" #include "nvim/os/job_defs.h" -/// Gets the RStream instance associated with a libuv handle -/// -/// @param handle libuv handle -/// @return the RStream pointer RStream *handle_get_rstream(uv_handle_t *handle); -/// Associates a RStream instance with a libuv handle -/// -/// @param handle libuv handle -/// @param rstream the RStream pointer void handle_set_rstream(uv_handle_t *handle, RStream *rstream); -/// Gets the WStream instance associated with a libuv handle -/// -/// @param handle libuv handle -/// @return the WStream pointer WStream *handle_get_wstream(uv_handle_t *handle); -/// Associates a WStream instance with a libuv handle -/// -/// @param handle libuv handle -/// @param wstream the WStream pointer void handle_set_wstream(uv_handle_t *handle, WStream *wstream); -/// Gets the Job instance associated with a libuv handle -/// -/// @param handle libuv handle -/// @return the Job pointer Job *handle_get_job(uv_handle_t *handle); -/// Associates a Job instance with a libuv handle -/// -/// @param handle libuv handle -/// @param job the Job pointer void handle_set_job(uv_handle_t *handle, Job *job); #endif // NVIM_OS_UV_HELPERS_H diff --git a/src/nvim/os/wstream.c b/src/nvim/os/wstream.c index 57afdd0e8f..b5c396b50c 100644 --- a/src/nvim/os/wstream.c +++ b/src/nvim/os/wstream.c @@ -32,6 +32,11 @@ typedef struct { static void write_cb(uv_write_t *req, int status); +/// Creates a new WStream instance. A WStream encapsulates all the boilerplate +/// necessary for writing to a libuv stream. +/// +/// @param maxmem Maximum amount memory used by this `WStream` instance. +/// @return The newly-allocated `WStream` instance WStream * wstream_new(size_t maxmem) { WStream *rv = xmalloc(sizeof(WStream)); @@ -44,6 +49,9 @@ WStream * wstream_new(size_t maxmem) return rv; } +/// Frees all memory allocated for a WStream instance +/// +/// @param wstream The `WStream` instance void wstream_free(WStream *wstream) { if (!wstream->pending_reqs) { @@ -53,12 +61,23 @@ void wstream_free(WStream *wstream) } } +/// Sets the underlying `uv_stream_t` instance +/// +/// @param wstream The `WStream` instance +/// @param stream The new `uv_stream_t` instance void wstream_set_stream(WStream *wstream, uv_stream_t *stream) { handle_set_wstream((uv_handle_t *)stream, wstream); wstream->stream = stream; } +/// Queues data for writing to the backing file descriptor of a `WStream` +/// instance. This will fail if the write would cause the WStream use more +/// memory than specified by `maxmem`. +/// +/// @param wstream The `WStream` instance +/// @param buffer The buffer which contains data to be written +/// @return false if the write failed bool wstream_write(WStream *wstream, WBuffer *buffer) { WriteData *data; @@ -87,6 +106,15 @@ bool wstream_write(WStream *wstream, WBuffer *buffer) return true; } +/// Creates a WBuffer object for holding output data. Instances of this +/// object can be reused across WStream instances, and the memory is freed +/// automatically when no longer needed(it tracks the number of references +/// internally) +/// +/// @param data Data stored by the WBuffer +/// @param size The size of the data array +/// @param copy If true, the data will be copied into the WBuffer +/// @return The allocated WBuffer instance WBuffer *wstream_new_buffer(char *data, size_t size, bool copy) { WBuffer *rv = xmalloc(sizeof(WBuffer)); diff --git a/src/nvim/os/wstream.h b/src/nvim/os/wstream.h index 1f61f6afd0..e133ef1385 100644 --- a/src/nvim/os/wstream.h +++ b/src/nvim/os/wstream.h @@ -7,42 +7,14 @@ #include "nvim/os/wstream_defs.h" -/// Creates a new WStream instance. A WStream encapsulates all the boilerplate -/// necessary for writing to a libuv stream. -/// -/// @param maxmem Maximum amount memory used by this `WStream` instance. -/// @return The newly-allocated `WStream` instance WStream * wstream_new(size_t maxmem); -/// Frees all memory allocated for a WStream instance -/// -/// @param wstream The `WStream` instance void wstream_free(WStream *wstream); -/// Sets the underlying `uv_stream_t` instance -/// -/// @param wstream The `WStream` instance -/// @param stream The new `uv_stream_t` instance void wstream_set_stream(WStream *wstream, uv_stream_t *stream); -/// Queues data for writing to the backing file descriptor of a `WStream` -/// instance. This will fail if the write would cause the WStream use more -/// memory than specified by `maxmem`. -/// -/// @param wstream The `WStream` instance -/// @param buffer The buffer which contains data to be written -/// @return false if the write failed bool wstream_write(WStream *wstream, WBuffer *buffer); -/// Creates a WBuffer object for holding output data. Instances of this -/// object can be reused across WStream instances, and the memory is freed -/// automatically when no longer needed(it tracks the number of references -/// internally) -/// -/// @param data Data stored by the WBuffer -/// @param size The size of the data array -/// @param copy If true, the data will be copied into the WBuffer -/// @return The allocated WBuffer instance WBuffer *wstream_new_buffer(char *data, size_t size, bool copy); #endif // NVIM_OS_WSTREAM_H diff --git a/src/nvim/path.c b/src/nvim/path.c index 1222b97fd6..26d89e0058 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -33,6 +33,13 @@ static int path_get_absolute_path(char_u *fname, char_u *buf, int len, int force); +/// Compare two file names. +/// +/// @param s1 First file name. Environment variables in this name will be +/// expanded. +/// @param s2 Second file name. +/// @param checkname When both files don't exist, only compare their names. +/// @return Enum of type FileComparison. @see FileComparison. FileComparison path_full_compare(char_u *s1, char_u *s2, int checkname) { assert(s1 && s2); @@ -64,6 +71,14 @@ FileComparison path_full_compare(char_u *s1, char_u *s2, int checkname) return kDifferentFiles; } +/// Get the tail of a path: the file name. +/// +/// @param fname A file path. +/// @return +/// - Empty string, if fname is NULL. +/// - The position of the last path separator + 1. (i.e. empty string, if +/// fname ends in a slash). +/// - Never NULL. char_u *path_tail(char_u *fname) { if (fname == NULL) { @@ -82,6 +97,15 @@ char_u *path_tail(char_u *fname) return tail; } +/// Get pointer to tail of "fname", including path separators. +/// +/// Takes care of "c:/" and "//". That means `path_tail_with_sep("dir///file.txt")` +/// will return a pointer to `"///file.txt"`. +/// @param fname A file path. (Must be != NULL.) +/// @return +/// - Pointer to the last path separator of `fname`, if there is any. +/// - `fname` if it contains no path separator. +/// - Never NULL. char_u *path_tail_with_sep(char_u *fname) { assert(fname != NULL); @@ -95,6 +119,11 @@ char_u *path_tail_with_sep(char_u *fname) return tail; } +/// Get the next path component of a path name. +/// +/// @param fname A file path. (Must be != NULL.) +/// @return Pointer to first found path separator + 1. +/// An empty string, if `fname` doesn't contain a path separator, char_u *path_next_component(char_u *fname) { assert(fname != NULL); @@ -1678,6 +1707,14 @@ int flags; /* EW_* flags */ } #endif +/// Try to find a shortname by comparing the fullname with the current +/// directory. +/// +/// @param full_path The full path of the file. +/// @return +/// - Pointer into `full_path` if shortened. +/// - `full_path` unchanged if no shorter name is possible. +/// - NULL if `full_path` is NULL. char_u *path_shorten_fname_if_possible(char_u *full_path) { char_u *dirname = xmalloc(MAXPATHL); @@ -1693,6 +1730,13 @@ char_u *path_shorten_fname_if_possible(char_u *full_path) return p; } +/// Try to find a shortname by comparing the fullname with `dir_name`. +/// +/// @param full_path The full path of the file. +/// @param dir_name The directory to shorten relative to. +/// @return +/// - Pointer into `full_path` if shortened. +/// - NULL if no shorter name is possible. char_u *path_shorten_fname(char_u *full_path, char_u *dir_name) { if (full_path == NULL) { @@ -1711,18 +1755,18 @@ char_u *path_shorten_fname(char_u *full_path, char_u *dir_name) return p + 1; } -/* - * Invoke expand_wildcards() for one pattern. - * Expand items like "%:h" before the expansion. - * Returns OK or FAIL. - */ -int -expand_wildcards_eval ( - char_u **pat, /* pointer to input pattern */ - int *num_file, /* resulting number of files */ - char_u ***file, /* array of resulting files */ - int flags /* EW_DIR, etc. */ -) +/// Invoke expand_wildcards() for one pattern +/// +/// One should expand items like "%:h" before the expansion. +/// +/// @param[in] pat Pointer to the input pattern. +/// @param[out] num_file Resulting number of files. +/// @param[out] file Array of resulting files. +/// @param[in] flags Flags passed to expand_wildcards(). +/// +/// @return OK or FAIL. +int expand_wildcards_eval(char_u **pat, int *num_file, char_u ***file, + int flags) { int ret = FAIL; char_u *eval_pat = NULL; @@ -1853,6 +1897,10 @@ int match_suffix(char_u *fname) return setsuflen != 0; } +/// Get the absolute name of the given relative directory. +/// +/// @param directory Directory name, relative to current directory. +/// @return `FAIL` for failure, `OK` for success. int path_full_dir_name(char *directory, char *buffer, int len) { int SUCCESS = 0; @@ -1894,6 +1942,7 @@ int path_full_dir_name(char *directory, char *buffer, int len) } // Append to_append to path with a slash in between. +// Append to_append to path with a slash in between. int append_path(char *path, const char *to_append, int max_len) { int current_length = STRLEN(path); @@ -1963,6 +2012,10 @@ static int path_get_absolute_path(char_u *fname, char_u *buf, int len, int force return append_path((char *) buf, (char *) end_of_path, len); } +/// Check if the given file is absolute. +/// +/// This just checks if the file name starts with '/' or '~'. +/// @return `TRUE` if "fname" is absolute. int path_is_absolute_path(const char_u *fname) { return *fname == '/' || *fname == '~'; diff --git a/src/nvim/path.h b/src/nvim/path.h index 9272922c8a..d376cdfca9 100644 --- a/src/nvim/path.h +++ b/src/nvim/path.h @@ -14,41 +14,12 @@ typedef enum file_comparison { kEqualFileNames = 7 ///< Both don't exist and file names are same. } FileComparison; -/// Compare two file names. -/// -/// @param s1 First file name. Environment variables in this name will be -/// expanded. -/// @param s2 Second file name. -/// @param checkname When both files don't exist, only compare their names. -/// @return Enum of type FileComparison. @see FileComparison. FileComparison path_full_compare(char_u *s1, char_u *s2, int checkname); -/// Get the tail of a path: the file name. -/// -/// @param fname A file path. -/// @return -/// - Empty string, if fname is NULL. -/// - The position of the last path separator + 1. (i.e. empty string, if -/// fname ends in a slash). -/// - Never NULL. char_u *path_tail(char_u *fname); -/// Get pointer to tail of "fname", including path separators. -/// -/// Takes care of "c:/" and "//". That means `path_tail_with_sep("dir///file.txt")` -/// will return a pointer to `"///file.txt"`. -/// @param fname A file path. (Must be != NULL.) -/// @return -/// - Pointer to the last path separator of `fname`, if there is any. -/// - `fname` if it contains no path separator. -/// - Never NULL. char_u *path_tail_with_sep(char_u *fname); -/// Get the next path component of a path name. -/// -/// @param fname A file path. (Must be != NULL.) -/// @return Pointer to first found path separator + 1. -/// An empty string, if `fname` doesn't contain a path separator, char_u *path_next_component(char_u *fname); int vim_ispathsep(int c); @@ -84,23 +55,8 @@ int same_directory(char_u *f1, char_u *f2); int pathcmp(const char *p, const char *q, int maxlen); int mch_expandpath(garray_T *gap, char_u *path, int flags); -/// Try to find a shortname by comparing the fullname with the current -/// directory. -/// -/// @param full_path The full path of the file. -/// @return -/// - Pointer into `full_path` if shortened. -/// - `full_path` unchanged if no shorter name is possible. -/// - NULL if `full_path` is NULL. char_u *path_shorten_fname_if_possible(char_u *full_path); -/// Try to find a shortname by comparing the fullname with `dir_name`. -/// -/// @param full_path The full path of the file. -/// @param dir_name The directory to shorten relative to. -/// @return -/// - Pointer into `full_path` if shortened. -/// - NULL if no shorter name is possible. char_u *path_shorten_fname(char_u *full_path, char_u *dir_name); int expand_wildcards_eval(char_u **pat, int *num_file, char_u ***file, @@ -110,19 +66,10 @@ int expand_wildcards(int num_pat, char_u **pat, int *num_file, char_u * int flags); int match_suffix(char_u *fname); -/// Get the absolute name of the given relative directory. -/// -/// @param directory Directory name, relative to current directory. -/// @return `FAIL` for failure, `OK` for success. int path_full_dir_name(char *directory, char *buffer, int len); -// Append to_append to path with a slash in between. int append_path(char *path, const char *to_append, int max_len); -/// Check if the given file is absolute. -/// -/// This just checks if the file name starts with '/' or '~'. -/// @return `TRUE` if "fname" is absolute. int path_is_absolute_path(const char_u *fname); #endif |