mirror of
https://github.com/libretro/RetroArch
synced 2025-01-29 00:32:49 +00:00
(libretro-common) Start documenting leaf functon calls in function documentation
(libretro-common) docs - document when string has to be non-NULL or else UB (undefined behavior) (libretro-common) stdstring.c - string_hex_to_unsigned - make strlen call unneeded
This commit is contained in:
parent
20c4407928
commit
c7a1d83675
@ -279,9 +279,7 @@ bool core_backup_get_backup_crc(char *backup_path, uint32_t *crc)
|
||||
goto error;
|
||||
|
||||
/* Convert to an integer */
|
||||
*crc = (uint32_t)string_hex_to_unsigned(crc_str);
|
||||
|
||||
if (*crc == 0)
|
||||
if ((*crc = (uint32_t)string_hex_to_unsigned(crc_str)) == 0)
|
||||
goto error;
|
||||
|
||||
string_list_free(metadata_list);
|
||||
|
@ -371,9 +371,7 @@ static bool core_updater_list_set_crc(
|
||||
if (!entry || string_is_empty(crc_str))
|
||||
return false;
|
||||
|
||||
crc = (uint32_t)string_hex_to_unsigned(crc_str);
|
||||
|
||||
if (crc == 0)
|
||||
if ((crc = (uint32_t)string_hex_to_unsigned(crc_str)) == 0)
|
||||
return false;
|
||||
|
||||
entry->crc = crc;
|
||||
|
@ -82,7 +82,11 @@ struct path_linked_list* path_linked_list_new(void)
|
||||
return paths_list;
|
||||
}
|
||||
|
||||
/* Free the entire linked list */
|
||||
/**
|
||||
* path_linked_list_free:
|
||||
*
|
||||
* Free the entire linked list
|
||||
**/
|
||||
void path_linked_list_free(struct path_linked_list *in_path_linked_list)
|
||||
{
|
||||
struct path_linked_list *node_tmp = (struct path_linked_list*)in_path_linked_list;
|
||||
@ -99,11 +103,14 @@ void path_linked_list_free(struct path_linked_list *in_path_linked_list)
|
||||
}
|
||||
|
||||
/**
|
||||
* path_linked_list_add_path:
|
||||
*
|
||||
* Add a node to the linked list with this path
|
||||
* If the first node's path if it's not yet set the path
|
||||
* on this node instead
|
||||
**/
|
||||
void path_linked_list_add_path(struct path_linked_list *in_path_linked_list, char *path)
|
||||
void path_linked_list_add_path(struct path_linked_list *in_path_linked_list,
|
||||
char *path)
|
||||
{
|
||||
/* If the first item does not have a path this is
|
||||
a list which has just been created, so we just fill
|
||||
@ -142,9 +149,9 @@ void path_linked_list_add_path(struct path_linked_list *in_path_linked_list, cha
|
||||
* Find delimiter of an archive file. Only the first '#'
|
||||
* after a compression extension is considered.
|
||||
*
|
||||
* Returns: pointer to the delimiter in the path if it contains
|
||||
* @return pointer to the delimiter in the path if it contains
|
||||
* a path inside a compressed file, otherwise NULL.
|
||||
*/
|
||||
**/
|
||||
const char *path_get_archive_delim(const char *path)
|
||||
{
|
||||
char buf[5];
|
||||
@ -198,8 +205,8 @@ const char *path_get_archive_delim(const char *path)
|
||||
* Gets extension of file. Only '.'s
|
||||
* after the last slash are considered.
|
||||
*
|
||||
* Returns: extension part from the path.
|
||||
*/
|
||||
* @return extension part from the path.
|
||||
**/
|
||||
const char *path_get_extension(const char *path)
|
||||
{
|
||||
const char *ext;
|
||||
@ -216,12 +223,12 @@ const char *path_get_extension(const char *path)
|
||||
* text after and including the last '.'.
|
||||
* Only '.'s after the last slash are considered.
|
||||
*
|
||||
* Returns:
|
||||
* @return
|
||||
* 1) If path has an extension, returns path with the
|
||||
* extension removed.
|
||||
* 2) If there is no extension, returns NULL.
|
||||
* 3) If path is empty or NULL, returns NULL
|
||||
*/
|
||||
**/
|
||||
char *path_remove_extension(char *path)
|
||||
{
|
||||
char *last = !string_is_empty(path)
|
||||
@ -239,7 +246,7 @@ char *path_remove_extension(char *path)
|
||||
*
|
||||
* Checks if path is a compressed file.
|
||||
*
|
||||
* Returns: true (1) if path is a compressed file, otherwise false (0).
|
||||
* @return true if path is a compressed file, otherwise false.
|
||||
**/
|
||||
bool path_is_compressed_file(const char* path)
|
||||
{
|
||||
@ -286,6 +293,17 @@ void fill_pathname(char *out_path, const char *in_path,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* find_last_slash:
|
||||
* @str : path
|
||||
* @size : size of path
|
||||
*
|
||||
* Find last slash in path. Tries to find
|
||||
* a backslash on Windows too which takes precedence
|
||||
* over regular slash.
|
||||
|
||||
* @return pointer to last slash/backslash found in @str.
|
||||
**/
|
||||
char *find_last_slash(const char *str)
|
||||
{
|
||||
const char *slash = strrchr(str, '/');
|
||||
@ -362,7 +380,7 @@ size_t fill_pathname_dir(char *in_dir, const char *in_basename,
|
||||
*
|
||||
* Copies basename of @in_path into @out_path.
|
||||
*
|
||||
* @return length of the string copied into @out
|
||||
* @return Length of the string copied into @out
|
||||
**/
|
||||
size_t fill_pathname_base(char *out, const char *in_path, size_t size)
|
||||
{
|
||||
@ -398,7 +416,8 @@ void fill_pathname_basedir(char *out_dir,
|
||||
*
|
||||
* Copies only the parent directory name of @in_dir into @out_dir.
|
||||
* The two buffers must not overlap. Removes trailing '/'.
|
||||
* Returns true on success, false if a slash was not found in the path.
|
||||
*
|
||||
* @return true on success, false if a slash was not found in the path.
|
||||
**/
|
||||
bool fill_pathname_parent_dir_name(char *out_dir,
|
||||
const char *in_dir, size_t size)
|
||||
@ -446,7 +465,8 @@ bool fill_pathname_parent_dir_name(char *out_dir,
|
||||
*
|
||||
* Copies parent directory of @in_dir into @out_dir.
|
||||
* Assumes @in_dir is a directory. Keeps trailing '/'.
|
||||
* If the path was already at the root directory, @out_dir will be an empty string.
|
||||
* If the path was already at the root directory,
|
||||
* @out_dir will be an empty string.
|
||||
**/
|
||||
void fill_pathname_parent_dir(char *out_dir,
|
||||
const char *in_dir, size_t size)
|
||||
@ -506,16 +526,15 @@ void fill_str_dated_filename(char *out_filename,
|
||||
|
||||
rtime_localtime(&cur_time, &tm_);
|
||||
|
||||
strlcpy(out_filename, in_str, size);
|
||||
if (string_is_empty(ext))
|
||||
{
|
||||
strftime(format, sizeof(format), "-%y%m%d-%H%M%S", &tm_);
|
||||
strlcpy(out_filename, in_str, size);
|
||||
strlcat(out_filename, format, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
strftime(format, sizeof(format), "-%y%m%d-%H%M%S.", &tm_);
|
||||
strlcpy(out_filename, in_str, size);
|
||||
strlcat(out_filename, format, size);
|
||||
strlcat(out_filename, ext, size);
|
||||
}
|
||||
@ -584,7 +603,7 @@ void path_parent_dir(char *path, size_t len)
|
||||
*
|
||||
* Get basename from @path.
|
||||
*
|
||||
* Returns: basename from path.
|
||||
* @return basename from path.
|
||||
**/
|
||||
const char *path_basename(const char *path)
|
||||
{
|
||||
@ -604,6 +623,15 @@ const char *path_basename(const char *path)
|
||||
}
|
||||
|
||||
/* Specialized version */
|
||||
/**
|
||||
* path_basename_nocompression:
|
||||
* @path : path
|
||||
*
|
||||
* Specialized version of path_basename().
|
||||
* Get basename from @path.
|
||||
*
|
||||
* @return basename from path.
|
||||
**/
|
||||
const char *path_basename_nocompression(const char *path)
|
||||
{
|
||||
/* We cut at the last slash */
|
||||
@ -619,7 +647,7 @@ const char *path_basename_nocompression(const char *path)
|
||||
*
|
||||
* Checks if @path is an absolute path or a relative path.
|
||||
*
|
||||
* Returns: true if path is absolute, false if path is relative.
|
||||
* @return true if path is absolute, false if path is relative.
|
||||
**/
|
||||
bool path_is_absolute(const char *path)
|
||||
{
|
||||
@ -655,7 +683,7 @@ bool path_is_absolute(const char *path)
|
||||
*
|
||||
* Relative paths are rebased on the current working dir.
|
||||
*
|
||||
* Returns: @buf if successful, NULL otherwise.
|
||||
* @return @buf if successful, NULL otherwise.
|
||||
* Note: Not implemented on consoles
|
||||
* Note: Symlinks are only resolved on Unix-likes
|
||||
* Note: The current working dir might not be what you expect,
|
||||
@ -921,9 +949,9 @@ size_t fill_pathname_join_delim(char *out_path, const char *dir,
|
||||
size_t copied;
|
||||
/* behavior of strlcpy is undefined if dst and src overlap */
|
||||
if (out_path == dir)
|
||||
copied = strlen(dir);
|
||||
copied = strlen(dir);
|
||||
else
|
||||
copied = strlcpy(out_path, dir, size);
|
||||
copied = strlcpy(out_path, dir, size);
|
||||
|
||||
out_path[copied] = delim;
|
||||
out_path[copied+1] = '\0';
|
||||
@ -1060,28 +1088,53 @@ void fill_pathname_abbreviate_special(char *out_path,
|
||||
retro_assert(strlcpy(out_path, in_path, size) < size);
|
||||
}
|
||||
|
||||
/* Changes the slashes to the correct kind for the os
|
||||
* So forward slash on linux and backslash on Windows */
|
||||
/**
|
||||
* pathname_conform_slashes_to_os:
|
||||
*
|
||||
* @path : path
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* Changes the slashes to the correct kind for the os
|
||||
* So forward slash on linux and backslash on Windows
|
||||
**/
|
||||
void pathname_conform_slashes_to_os(char *path)
|
||||
{
|
||||
/* Conform slashes to os standard so we get proper matching */
|
||||
char* p;
|
||||
char *p;
|
||||
for (p = path; *p; p++)
|
||||
if (*p == '/' || *p == '\\')
|
||||
*p = PATH_DEFAULT_SLASH_C();
|
||||
}
|
||||
|
||||
/* Change all shashes to forward so they are more portable between Windows and Linux */
|
||||
/**
|
||||
* pathname_make_slashes_portable:
|
||||
* @path : path
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* Change all slashes to forward so they are more
|
||||
* portable between Windows and Linux
|
||||
**/
|
||||
void pathname_make_slashes_portable(char *path)
|
||||
{
|
||||
/* Conform slashes to os standard so we get proper matching */
|
||||
char* p;
|
||||
char *p;
|
||||
for (p = path; *p; p++)
|
||||
if (*p == '/' || *p == '\\')
|
||||
*p = '/';
|
||||
}
|
||||
|
||||
/* Get the number of slashes in a path, returns an integer */
|
||||
/**
|
||||
* get_pathname_num_slashes:
|
||||
* @in_path : input path
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* Get the number of slashes in a path.
|
||||
*
|
||||
* @return number of slashes found in @in_path.
|
||||
**/
|
||||
static int get_pathname_num_slashes(const char *in_path)
|
||||
{
|
||||
int num_slashes = 0;
|
||||
@ -1098,11 +1151,18 @@ static int get_pathname_num_slashes(const char *in_path)
|
||||
return num_slashes;
|
||||
}
|
||||
|
||||
/* Fills the supplied path with either the abbreviated path or the relative path, which ever
|
||||
* one is has less depth / number of slashes
|
||||
* If lengths of abbreviated and relative paths are the same the relative path will be used
|
||||
* in_path can be an absolute, relative or abbreviated path */
|
||||
void fill_pathname_abbreviated_or_relative(char *out_path, const char *in_refpath, const char *in_path, size_t size)
|
||||
/**
|
||||
* fill_pathname_abbreviated_or_relative:
|
||||
*
|
||||
* Fills the supplied path with either the abbreviated path or
|
||||
* the relative path, which ever one has less depth / number of slashes
|
||||
*
|
||||
* If lengths of abbreviated and relative paths are the same,
|
||||
* the relative path will be used
|
||||
* @in_path can be an absolute, relative or abbreviated path
|
||||
**/
|
||||
void fill_pathname_abbreviated_or_relative(char *out_path,
|
||||
const char *in_refpath, const char *in_path, size_t size)
|
||||
{
|
||||
char in_path_conformed[PATH_MAX_LENGTH];
|
||||
char in_refpath_conformed[PATH_MAX_LENGTH];
|
||||
@ -1111,15 +1171,13 @@ void fill_pathname_abbreviated_or_relative(char *out_path, const char *in_refpat
|
||||
char relative_path[PATH_MAX_LENGTH];
|
||||
char abbreviated_path[PATH_MAX_LENGTH];
|
||||
|
||||
in_path_conformed[0] = '\0';
|
||||
in_refpath_conformed[0] = '\0';
|
||||
expanded_path[0] = '\0';
|
||||
absolute_path[0] = '\0';
|
||||
relative_path[0] = '\0';
|
||||
abbreviated_path[0] = '\0';
|
||||
|
||||
strcpy_literal(in_path_conformed, in_path);
|
||||
strcpy_literal(in_refpath_conformed, in_refpath);
|
||||
strlcpy(in_path_conformed, in_path, sizeof(in_path_conformed));
|
||||
strlcpy(in_refpath_conformed, in_refpath, sizeof(in_refpath_conformed));
|
||||
|
||||
pathname_conform_slashes_to_os(in_path_conformed);
|
||||
pathname_conform_slashes_to_os(in_refpath_conformed);
|
||||
|
@ -103,12 +103,12 @@ bool path_is_compressed_file(const char *path);
|
||||
* path_get_archive_delim:
|
||||
* @path : path
|
||||
*
|
||||
* Gets delimiter of an archive file. Only the first '#'
|
||||
* Find delimiter of an archive file. Only the first '#'
|
||||
* after a compression extension is considered.
|
||||
*
|
||||
* Returns: pointer to the delimiter in the path if it contains
|
||||
* a compressed file, otherwise NULL.
|
||||
*/
|
||||
* @return pointer to the delimiter in the path if it contains
|
||||
* a path inside a compressed file, otherwise NULL.
|
||||
**/
|
||||
const char *path_get_archive_delim(const char *path);
|
||||
|
||||
/**
|
||||
@ -118,8 +118,12 @@ const char *path_get_archive_delim(const char *path);
|
||||
* Gets extension of file. Only '.'s
|
||||
* after the last slash are considered.
|
||||
*
|
||||
* Returns: extension part from the path.
|
||||
*/
|
||||
* Hidden non-leaf function cost:
|
||||
* - calls string_is_empty
|
||||
* - calls strrchr
|
||||
*
|
||||
* @return extension part from the path.
|
||||
**/
|
||||
const char *path_get_extension(const char *path);
|
||||
|
||||
/**
|
||||
@ -130,7 +134,10 @@ const char *path_get_extension(const char *path);
|
||||
* text after and including the last '.'.
|
||||
* Only '.'s after the last slash are considered.
|
||||
*
|
||||
* Returns:
|
||||
* Hidden non-leaf function cost:
|
||||
* - calls strrchr
|
||||
*
|
||||
* @return
|
||||
* 1) If path has an extension, returns path with the
|
||||
* extension removed.
|
||||
* 2) If there is no extension, returns NULL.
|
||||
@ -144,9 +151,26 @@ char *path_remove_extension(char *path);
|
||||
*
|
||||
* Get basename from @path.
|
||||
*
|
||||
* Returns: basename from path.
|
||||
* Hidden non-leaf function cost:
|
||||
* - Calls path_get_archive_delim()
|
||||
* - can call find_last_slash once if it returns NULL
|
||||
*
|
||||
* @return basename from path.
|
||||
**/
|
||||
const char *path_basename(const char *path);
|
||||
|
||||
/**
|
||||
* path_basename_nocompression:
|
||||
* @path : path
|
||||
*
|
||||
* Specialized version of path_basename().
|
||||
* Get basename from @path.
|
||||
*
|
||||
* Hidden non-leaf function cost:
|
||||
* - Calls find_last_slash
|
||||
*
|
||||
* @return basename from path.
|
||||
**/
|
||||
const char *path_basename_nocompression(const char *path);
|
||||
|
||||
/**
|
||||
@ -179,7 +203,7 @@ void path_parent_dir(char *path, size_t len);
|
||||
*
|
||||
* Relative paths are rebased on the current working dir.
|
||||
*
|
||||
* Returns: @buf if successful, NULL otherwise.
|
||||
* @return @buf if successful, NULL otherwise.
|
||||
* Note: Not implemented on consoles
|
||||
* Note: Symlinks are only resolved on Unix-likes
|
||||
* Note: The current working dir might not be what you expect,
|
||||
@ -202,7 +226,8 @@ char *path_resolve_realpath(char *buf, size_t size, bool resolve_symlinks);
|
||||
*
|
||||
* E.g. path /a/b/e/f.cgp with base /a/b/c/d/ turns into ../../e/f.cgp
|
||||
**/
|
||||
size_t path_relative_to(char *out, const char *path, const char *base, size_t size);
|
||||
size_t path_relative_to(char *out, const char *path, const char *base,
|
||||
size_t size);
|
||||
|
||||
/**
|
||||
* path_is_absolute:
|
||||
@ -210,7 +235,7 @@ size_t path_relative_to(char *out, const char *path, const char *base, size_t si
|
||||
*
|
||||
* Checks if @path is an absolute path or a relative path.
|
||||
*
|
||||
* Returns: true if path is absolute, false if path is relative.
|
||||
* @return true if path is absolute, false if path is relative.
|
||||
**/
|
||||
bool path_is_absolute(const char *path);
|
||||
|
||||
@ -234,6 +259,11 @@ bool path_is_absolute(const char *path);
|
||||
* out_path = "/foo/bar/baz/boo.asm"
|
||||
* E.g.: in_path = "/foo/bar/baz/boo.c", replace = "" =>
|
||||
* out_path = "/foo/bar/baz/boo"
|
||||
*
|
||||
* Hidden non-leaf function cost:
|
||||
* - calls strlcpy 2x
|
||||
* - calls strrchr
|
||||
* - calls strlcat
|
||||
*/
|
||||
void fill_pathname(char *out_path, const char *in_path,
|
||||
const char *replace, size_t size);
|
||||
@ -249,6 +279,12 @@ void fill_pathname(char *out_path, const char *in_path,
|
||||
*
|
||||
* E.g.:
|
||||
* out_filename = "RetroArch-{month}{day}-{Hours}{Minutes}.{@ext}"
|
||||
*
|
||||
* Hidden non-leaf function cost:
|
||||
* - Calls rtime_localtime()
|
||||
* - Calls strftime
|
||||
* - Calls strlcat
|
||||
*
|
||||
**/
|
||||
size_t fill_dated_filename(char *out_filename,
|
||||
const char *ext, size_t size);
|
||||
@ -265,17 +301,31 @@ size_t fill_dated_filename(char *out_filename,
|
||||
*
|
||||
* E.g.:
|
||||
* out_filename = "RetroArch-{year}{month}{day}-{Hour}{Minute}{Second}.{@ext}"
|
||||
*
|
||||
* Hidden non-leaf function cost:
|
||||
* - Calls time
|
||||
* - Calls rtime_localtime
|
||||
* - Calls strlcpy
|
||||
* - Calls string_is_empty
|
||||
* - Calls strftime
|
||||
* - Calls strlcat at least 2x
|
||||
**/
|
||||
void fill_str_dated_filename(char *out_filename,
|
||||
const char *in_str, const char *ext, size_t size);
|
||||
|
||||
/**
|
||||
* find_last_slash:
|
||||
* @str : input path
|
||||
* @str : path
|
||||
* @size : size of path
|
||||
*
|
||||
* Gets a pointer to the last slash in the input path.
|
||||
* Find last slash in path. Tries to find
|
||||
* a backslash on Windows too which takes precedence
|
||||
* over regular slash.
|
||||
|
||||
* Hidden non-leaf function cost:
|
||||
* - calls strrchr
|
||||
*
|
||||
* Returns: a pointer to the last slash in the input path.
|
||||
* @return pointer to last slash/backslash found in @str.
|
||||
**/
|
||||
char *find_last_slash(const char *str);
|
||||
|
||||
@ -295,6 +345,11 @@ char *find_last_slash(const char *str);
|
||||
*
|
||||
* E.g..: in_dir = "/tmp/some_dir", in_basename = "/some_content/foo.c",
|
||||
* replace = ".asm" => in_dir = "/tmp/some_dir/foo.c.asm"
|
||||
*
|
||||
* Hidden non-leaf function cost:
|
||||
* - Calls fill_pathname_slash()
|
||||
* - Calls path_basename()
|
||||
* - Calls strlcat 2x
|
||||
**/
|
||||
size_t fill_pathname_dir(char *in_dir, const char *in_basename,
|
||||
const char *replace, size_t size);
|
||||
@ -306,6 +361,12 @@ size_t fill_pathname_dir(char *in_dir, const char *in_basename,
|
||||
* @size : size of output path
|
||||
*
|
||||
* Copies basename of @in_path into @out_path.
|
||||
*
|
||||
* Hidden non-leaf function cost:
|
||||
* - Calls path_basename()
|
||||
* - Calls strlcpy
|
||||
*
|
||||
* @return length of the string copied into @out
|
||||
**/
|
||||
size_t fill_pathname_base(char *out_path, const char *in_path, size_t size);
|
||||
|
||||
@ -318,6 +379,10 @@ size_t fill_pathname_base(char *out_path, const char *in_path, size_t size);
|
||||
* Copies base directory of @in_path into @out_path.
|
||||
* If in_path is a path without any slashes (relative current directory),
|
||||
* @out_path will get path "./".
|
||||
*
|
||||
* Hidden non-leaf function cost:
|
||||
* - Calls strlcpy
|
||||
* - Calls path_basedir()
|
||||
**/
|
||||
void fill_pathname_basedir(char *out_path, const char *in_path, size_t size);
|
||||
|
||||
@ -329,7 +394,13 @@ void fill_pathname_basedir(char *out_path, const char *in_path, size_t size);
|
||||
*
|
||||
* Copies only the parent directory name of @in_dir into @out_dir.
|
||||
* The two buffers must not overlap. Removes trailing '/'.
|
||||
* Returns true on success, false if a slash was not found in the path.
|
||||
*
|
||||
* Hidden non-leaf function cost:
|
||||
* - Calls strdup
|
||||
* - Calls find_last_slash x times
|
||||
* - Can call strlcpy
|
||||
*
|
||||
* @return true on success, false if a slash was not found in the path.
|
||||
**/
|
||||
bool fill_pathname_parent_dir_name(char *out_dir,
|
||||
const char *in_dir, size_t size);
|
||||
@ -343,6 +414,11 @@ bool fill_pathname_parent_dir_name(char *out_dir,
|
||||
* Copies parent directory of @in_dir into @out_dir.
|
||||
* Assumes @in_dir is a directory. Keeps trailing '/'.
|
||||
* If the path was already at the root directory, @out_dir will be an empty string.
|
||||
*
|
||||
* Hidden non-leaf function cost:
|
||||
* - Can call strlcpy if (@out_dir != @in_dir)
|
||||
* - Calls strlen if (@out_dir == @in_dir)
|
||||
* - Calls path_parent_dir()
|
||||
**/
|
||||
void fill_pathname_parent_dir(char *out_dir,
|
||||
const char *in_dir, size_t size);
|
||||
@ -372,6 +448,11 @@ void fill_pathname_resolve_relative(char *out_path, const char *in_refpath,
|
||||
* Joins a directory (@dir) and path (@path) together.
|
||||
* Makes sure not to get two consecutive slashes
|
||||
* between directory and path.
|
||||
*
|
||||
* Hidden non-leaf function cost:
|
||||
* - calls strlcpy
|
||||
* - calls fill_pathname_slash()
|
||||
* - calls strlcat
|
||||
**/
|
||||
size_t fill_pathname_join(char *out_path, const char *dir,
|
||||
const char *path, size_t size);
|
||||
@ -391,6 +472,11 @@ size_t fill_pathname_join_special_ext(char *out_path,
|
||||
*
|
||||
* Joins a directory (@dir) and path (@path) together
|
||||
* using the given delimiter (@delim).
|
||||
*
|
||||
* Hidden non-leaf function cost:
|
||||
* - can call strlen
|
||||
* - can call strlcpy
|
||||
* - can call strlcat
|
||||
**/
|
||||
size_t fill_pathname_join_delim(char *out_path, const char *dir,
|
||||
const char *path, const char delim, size_t size);
|
||||
@ -401,10 +487,40 @@ void fill_pathname_expand_special(char *out_path,
|
||||
void fill_pathname_abbreviate_special(char *out_path,
|
||||
const char *in_path, size_t size);
|
||||
|
||||
void fill_pathname_abbreviated_or_relative(char *out_path, const char *in_refpath, const char *in_path, size_t size);
|
||||
/**
|
||||
* fill_pathname_abbreviated_or_relative:
|
||||
*
|
||||
* Fills the supplied path with either the abbreviated path or
|
||||
* the relative path, which ever one has less depth / number of slashes
|
||||
*
|
||||
* If lengths of abbreviated and relative paths are the same,
|
||||
* the relative path will be used
|
||||
* @in_path can be an absolute, relative or abbreviated path
|
||||
**/
|
||||
void fill_pathname_abbreviated_or_relative(char *out_path,
|
||||
const char *in_refpath, const char *in_path, size_t size);
|
||||
|
||||
/**
|
||||
* pathname_conform_slashes_to_os:
|
||||
*
|
||||
* @path : path
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* Changes the slashes to the correct kind for the os
|
||||
* So forward slash on linux and backslash on Windows
|
||||
**/
|
||||
void pathname_conform_slashes_to_os(char *path);
|
||||
|
||||
/**
|
||||
* pathname_make_slashes_portable:
|
||||
* @path : path
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* Change all slashes to forward so they are more
|
||||
* portable between Windows and Linux
|
||||
**/
|
||||
void pathname_make_slashes_portable(char *path);
|
||||
|
||||
/**
|
||||
@ -422,8 +538,8 @@ void path_basedir_wrapper(char *path);
|
||||
*
|
||||
* Checks if character (@c) is a slash.
|
||||
*
|
||||
* Returns: true (1) if character is a slash, otherwise false (0).
|
||||
*/
|
||||
* @return true if character is a slash, otherwise false.
|
||||
**/
|
||||
#ifdef _WIN32
|
||||
#define PATH_CHAR_IS_SLASH(c) (((c) == '/') || ((c) == '\\'))
|
||||
#else
|
||||
@ -435,8 +551,8 @@ void path_basedir_wrapper(char *path);
|
||||
*
|
||||
* Gets the default slash separator.
|
||||
*
|
||||
* Returns: default slash separator.
|
||||
*/
|
||||
* @return default slash separator.
|
||||
**/
|
||||
#ifdef _WIN32
|
||||
#define PATH_DEFAULT_SLASH() "\\"
|
||||
#define PATH_DEFAULT_SLASH_C() '\\'
|
||||
@ -452,6 +568,11 @@ void path_basedir_wrapper(char *path);
|
||||
*
|
||||
* Assumes path is a directory. Appends a slash
|
||||
* if not already there.
|
||||
|
||||
* Hidden non-leaf function cost:
|
||||
* - calls find_last_slash()
|
||||
* - can call strlcat once if it returns false
|
||||
* - calls strlen
|
||||
**/
|
||||
void fill_pathname_slash(char *path, size_t size);
|
||||
|
||||
@ -467,7 +588,7 @@ void fill_pathname_home_dir(char *buf, size_t size);
|
||||
*
|
||||
* Create directory on filesystem.
|
||||
*
|
||||
* Returns: true (1) if directory could be created, otherwise false (0).
|
||||
* @return true if directory could be created, otherwise false.
|
||||
**/
|
||||
bool path_mkdir(const char *dir);
|
||||
|
||||
@ -477,7 +598,7 @@ bool path_mkdir(const char *dir);
|
||||
*
|
||||
* Checks if path is a directory.
|
||||
*
|
||||
* Returns: true (1) if path is a directory, otherwise false (0).
|
||||
* @return true if path is a directory, otherwise false.
|
||||
*/
|
||||
bool path_is_directory(const char *path);
|
||||
|
||||
|
@ -92,16 +92,20 @@ static INLINE bool string_ends_with_size(const char *str, const char *suffix,
|
||||
|
||||
static INLINE bool string_ends_with(const char *str, const char *suffix)
|
||||
{
|
||||
if (!str || !suffix)
|
||||
return false;
|
||||
return string_ends_with_size(str, suffix, strlen(str), strlen(suffix));
|
||||
return str && suffix && string_ends_with_size(str, suffix, strlen(str), strlen(suffix));
|
||||
}
|
||||
|
||||
/* Returns the length of 'str' (c.f. strlen()), but only
|
||||
/**
|
||||
* strlen_size:
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* @return the length of 'str' (c.f. strlen()), but only
|
||||
* checks the first 'size' characters
|
||||
* - If 'str' is NULL, returns 0
|
||||
* - If 'str' is not NULL and no '\0' character is found
|
||||
* in the first 'size' characters, returns 'size' */
|
||||
* in the first 'size' characters, returns 'size'
|
||||
**/
|
||||
static INLINE size_t strlen_size(const char *str, size_t size)
|
||||
{
|
||||
size_t i = 0;
|
||||
@ -158,16 +162,30 @@ char *string_ucwords(char *s);
|
||||
char *string_replace_substring(const char *in, const char *pattern,
|
||||
const char *by);
|
||||
|
||||
/* Remove leading whitespaces */
|
||||
/**
|
||||
* string_trim_whitespace_left:
|
||||
*
|
||||
* Remove leading whitespaces
|
||||
**/
|
||||
char *string_trim_whitespace_left(char *const s);
|
||||
|
||||
/* Remove trailing whitespaces */
|
||||
/**
|
||||
* string_trim_whitespace_right:
|
||||
*
|
||||
* Remove trailing whitespaces
|
||||
**/
|
||||
char *string_trim_whitespace_right(char *const s);
|
||||
|
||||
/* Remove leading and trailing whitespaces */
|
||||
/**
|
||||
* string_trim_whitespace:
|
||||
*
|
||||
* Remove leading and trailing whitespaces
|
||||
**/
|
||||
char *string_trim_whitespace(char *const s);
|
||||
|
||||
/*
|
||||
/**
|
||||
* word_wrap:
|
||||
*
|
||||
* Wraps string specified by 'src' to destination buffer
|
||||
* specified by 'dst' and 'dst_size'.
|
||||
* This function assumes that all glyphs in the string
|
||||
@ -184,11 +202,13 @@ char *string_trim_whitespace(char *const s);
|
||||
* compatibility with word_wrap_wideglyph().
|
||||
* @param max_lines max lines of destination string.
|
||||
* 0 means no limit.
|
||||
*/
|
||||
**/
|
||||
void word_wrap(char *dst, size_t dst_size, const char *src,
|
||||
int line_width, int wideglyph_width, unsigned max_lines);
|
||||
|
||||
/*
|
||||
/**
|
||||
* word_wrap_wideglyph:
|
||||
*
|
||||
* Wraps string specified by 'src' to destination buffer
|
||||
* specified by 'dst' and 'dst_size'.
|
||||
* This function assumes that all glyphs in the string
|
||||
@ -219,14 +239,17 @@ void word_wrap(char *dst, size_t dst_size, const char *src,
|
||||
* would be 200
|
||||
* @param max_lines max lines of destination string.
|
||||
* 0 means no limit.
|
||||
*/
|
||||
**/
|
||||
void word_wrap_wideglyph(char *dst, size_t dst_size, const char *src,
|
||||
int line_width, int wideglyph_width, unsigned max_lines);
|
||||
|
||||
/* Splits string into tokens seperated by 'delim'
|
||||
/**
|
||||
* string_tokenize:
|
||||
*
|
||||
* Splits string into tokens seperated by @delim
|
||||
* > Returned token string must be free()'d
|
||||
* > Returns NULL if token is not found
|
||||
* > After each call, 'str' is set to the position after the
|
||||
* > After each call, @str is set to the position after the
|
||||
* last found token
|
||||
* > Tokens *include* empty strings
|
||||
* Usage example:
|
||||
@ -239,48 +262,118 @@ void word_wrap_wideglyph(char *dst, size_t dst_size, const char *src,
|
||||
* free(token);
|
||||
* token = NULL;
|
||||
* }
|
||||
*/
|
||||
**/
|
||||
char* string_tokenize(char **str, const char *delim);
|
||||
|
||||
/* Removes every instance of character 'c' from 'str' */
|
||||
/**
|
||||
* string_remove_all_chars:
|
||||
* @str : input string (must be non-NULL, otherwise UB)
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* Removes every instance of character @c from @str
|
||||
**/
|
||||
void string_remove_all_chars(char *str, char c);
|
||||
|
||||
/* Replaces every instance of character 'find' in 'str'
|
||||
* with character 'replace' */
|
||||
/**
|
||||
* string_replace_all_chars:
|
||||
* @str : input string (must be non-NULL, otherwise UB)
|
||||
* @find : character to find
|
||||
* @replace : character to replace @find with
|
||||
*
|
||||
* Hidden non-leaf function cost:
|
||||
* - Calls strchr (in a loop)
|
||||
*
|
||||
* Replaces every instance of character @find in @str
|
||||
* with character @replace
|
||||
**/
|
||||
void string_replace_all_chars(char *str, char find, char replace);
|
||||
|
||||
/* Converts string to unsigned integer.
|
||||
* Returns 0 if string is invalid */
|
||||
/**
|
||||
* string_to_unsigned:
|
||||
* @str : input string
|
||||
*
|
||||
* Converts string to unsigned integer.
|
||||
*
|
||||
* @return 0 if string is invalid, otherwise > 0
|
||||
**/
|
||||
unsigned string_to_unsigned(const char *str);
|
||||
|
||||
/* Converts hexadecimal string to unsigned integer.
|
||||
/**
|
||||
* string_hex_to_unsigned:
|
||||
* @str : input string (must be non-NULL, otherwise UB)
|
||||
*
|
||||
* Converts hexadecimal string to unsigned integer.
|
||||
* Handles optional leading '0x'.
|
||||
* Returns 0 if string is invalid */
|
||||
*
|
||||
* @return 0 if string is invalid, otherwise > 0
|
||||
**/
|
||||
unsigned string_hex_to_unsigned(const char *str);
|
||||
|
||||
char *string_init(const char *src);
|
||||
|
||||
void string_set(char **string, const char *src);
|
||||
|
||||
/* Get the total number of occurrences of a character in the given string. */
|
||||
/**
|
||||
* string_count_occurrences_single_character:
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* Get the total number of occurrences of character @c in @str.
|
||||
*
|
||||
* @return Total number of occurrences of character @c
|
||||
*/
|
||||
int string_count_occurrences_single_character(const char *str, char c);
|
||||
|
||||
/* Replaces all spaces with the given character. */
|
||||
/**
|
||||
* string_replace_whitespace_with_single_character:
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* Replaces all spaces with given character @c.
|
||||
**/
|
||||
void string_replace_whitespace_with_single_character(char *str, char c);
|
||||
|
||||
/* Replaces multiple spaces with a single space in a string. */
|
||||
/**
|
||||
* string_replace_multi_space_with_single_space:
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* Replaces multiple spaces with a single space in a string.
|
||||
**/
|
||||
void string_replace_multi_space_with_single_space(char *str);
|
||||
|
||||
/* Remove all spaces from the given string. */
|
||||
/**
|
||||
* string_remove_all_whitespace:
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* Remove all spaces from the given string.
|
||||
**/
|
||||
void string_remove_all_whitespace(char *str_trimmed, const char *str);
|
||||
|
||||
/* Retrieve the last occurance of the given character in a string. */
|
||||
int string_index_last_occurance(const char *str, char c);
|
||||
|
||||
/* Find the position of a substring in a string. */
|
||||
/**
|
||||
* string_find_index_substring_string:
|
||||
* @str : input string (must be non-NULL, otherwise UB)
|
||||
* @substr : substring to find in @str
|
||||
*
|
||||
* Hidden non-leaf function cost:
|
||||
* - Calls strstr
|
||||
*
|
||||
* Find the position of substring @substr in string @str.
|
||||
**/
|
||||
int string_find_index_substring_string(const char *str, const char *substr);
|
||||
|
||||
/* Strips non-ASCII characters from a string. */
|
||||
/**
|
||||
* string_copy_only_ascii:
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* Strips non-ASCII characters from a string.
|
||||
**/
|
||||
void string_copy_only_ascii(char *str_stripped, const char *str);
|
||||
|
||||
extern const unsigned char lr_char_props[256];
|
||||
|
@ -136,7 +136,11 @@ char *string_replace_substring(const char *in,
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Remove leading whitespaces */
|
||||
/**
|
||||
* string_trim_whitespace_left:
|
||||
*
|
||||
* Remove leading whitespaces
|
||||
**/
|
||||
char *string_trim_whitespace_left(char *const s)
|
||||
{
|
||||
if (s && *s)
|
||||
@ -157,7 +161,11 @@ char *string_trim_whitespace_left(char *const s)
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Remove trailing whitespaces */
|
||||
/**
|
||||
* string_trim_whitespace_right:
|
||||
*
|
||||
* Remove trailing whitespaces
|
||||
**/
|
||||
char *string_trim_whitespace_right(char *const s)
|
||||
{
|
||||
if (s && *s)
|
||||
@ -177,7 +185,11 @@ char *string_trim_whitespace_right(char *const s)
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Remove leading and trailing whitespaces */
|
||||
/**
|
||||
* string_trim_whitespace:
|
||||
*
|
||||
* Remove leading and trailing whitespaces
|
||||
**/
|
||||
char *string_trim_whitespace(char *const s)
|
||||
{
|
||||
string_trim_whitespace_right(s); /* order matters */
|
||||
@ -186,7 +198,28 @@ char *string_trim_whitespace(char *const s)
|
||||
return s;
|
||||
}
|
||||
|
||||
void word_wrap(char *dst, size_t dst_size, const char *src, int line_width, int wideglyph_width, unsigned max_lines)
|
||||
/**
|
||||
* word_wrap:
|
||||
*
|
||||
* Wraps string specified by 'src' to destination buffer
|
||||
* specified by 'dst' and 'dst_size'.
|
||||
* This function assumes that all glyphs in the string
|
||||
* have an on-screen pixel width similar to that of
|
||||
* regular Latin characters - i.e. it will not wrap
|
||||
* correctly any text containing so-called 'wide' Unicode
|
||||
* characters (e.g. CJK languages, emojis, etc.).
|
||||
*
|
||||
* @param dst pointer to destination buffer.
|
||||
* @param dst_size size of destination buffer.
|
||||
* @param src pointer to input string.
|
||||
* @param line_width max number of characters per line.
|
||||
* @param wideglyph_width not used, but is necessary to keep
|
||||
* compatibility with word_wrap_wideglyph().
|
||||
* @param max_lines max lines of destination string.
|
||||
* 0 means no limit.
|
||||
**/
|
||||
void word_wrap(char *dst, size_t dst_size, const char *src,
|
||||
int line_width, int wideglyph_width, unsigned max_lines)
|
||||
{
|
||||
char *lastspace = NULL;
|
||||
unsigned counter = 0;
|
||||
@ -261,7 +294,43 @@ void word_wrap(char *dst, size_t dst_size, const char *src, int line_width, int
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
void word_wrap_wideglyph(char *dst, size_t dst_size, const char *src, int line_width, int wideglyph_width, unsigned max_lines)
|
||||
/**
|
||||
* word_wrap_wideglyph:
|
||||
*
|
||||
* Wraps string specified by 'src' to destination buffer
|
||||
* specified by 'dst' and 'dst_size'.
|
||||
* This function assumes that all glyphs in the string
|
||||
* are:
|
||||
* - EITHER 'non-wide' Unicode glyphs, with an on-screen
|
||||
* pixel width similar to that of regular Latin characters
|
||||
* - OR 'wide' Unicode glyphs (e.g. CJK languages, emojis, etc.)
|
||||
* with an on-screen pixel width defined by 'wideglyph_width'
|
||||
* Note that wrapping may occur in inappropriate locations
|
||||
* if 'src' string contains 'wide' Unicode characters whose
|
||||
* on-screen pixel width deviates greatly from the set
|
||||
* 'wideglyph_width' value.
|
||||
*
|
||||
* @param dst pointer to destination buffer.
|
||||
* @param dst_size size of destination buffer.
|
||||
* @param src pointer to input string.
|
||||
* @param line_width max number of characters per line.
|
||||
* @param wideglyph_width effective width of 'wide' Unicode glyphs.
|
||||
* the value here is normalised relative to the
|
||||
* typical on-screen pixel width of a regular
|
||||
* Latin character:
|
||||
* - a regular Latin character is defined to
|
||||
* have an effective width of 100
|
||||
* - wideglyph_width = 100 * (wide_character_pixel_width / latin_character_pixel_width)
|
||||
* - e.g. if 'wide' Unicode characters in 'src'
|
||||
* have an on-screen pixel width twice that of
|
||||
* regular Latin characters, wideglyph_width
|
||||
* would be 200
|
||||
* @param max_lines max lines of destination string.
|
||||
* 0 means no limit.
|
||||
**/
|
||||
void word_wrap_wideglyph(char *dst, size_t dst_size,
|
||||
const char *src, int line_width,
|
||||
int wideglyph_width, unsigned max_lines)
|
||||
{
|
||||
char *lastspace = NULL;
|
||||
char *lastwideglyph = NULL;
|
||||
@ -310,7 +379,7 @@ void word_wrap_wideglyph(char *dst, size_t dst_size, const char *src, int line_w
|
||||
break;
|
||||
|
||||
if (*src == ' ')
|
||||
lastspace = dst; /* Remember the location of the whitespace */
|
||||
lastspace = dst; /* Remember the location of the whitespace */
|
||||
else if (*src == '\n')
|
||||
{
|
||||
/* If newlines embedded in the input,
|
||||
@ -330,7 +399,7 @@ void word_wrap_wideglyph(char *dst, size_t dst_size, const char *src, int line_w
|
||||
{
|
||||
/* Remember the location of the first byte
|
||||
* whose length as UTF-8 >= 3*/
|
||||
lastwideglyph = dst;
|
||||
lastwideglyph = dst;
|
||||
counter_normalized += additional_counter_normalized;
|
||||
}
|
||||
|
||||
@ -349,9 +418,9 @@ void word_wrap_wideglyph(char *dst, size_t dst_size, const char *src, int line_w
|
||||
/* Insert newline character */
|
||||
*lastwideglyph = '\n';
|
||||
lines++;
|
||||
src -= dst - lastwideglyph;
|
||||
dst = lastwideglyph + 1;
|
||||
lastwideglyph = NULL;
|
||||
src -= dst - lastwideglyph;
|
||||
dst = lastwideglyph + 1;
|
||||
lastwideglyph = NULL;
|
||||
|
||||
/* Early return if remaining src string
|
||||
* length is less than line width */
|
||||
@ -367,9 +436,9 @@ void word_wrap_wideglyph(char *dst, size_t dst_size, const char *src, int line_w
|
||||
* with newline character */
|
||||
*lastspace = '\n';
|
||||
lines++;
|
||||
src -= dst - lastspace - 1;
|
||||
dst = lastspace + 1;
|
||||
lastspace = NULL;
|
||||
src -= dst - lastspace - 1;
|
||||
dst = lastspace + 1;
|
||||
lastspace = NULL;
|
||||
|
||||
/* Early return if remaining src string
|
||||
* length is less than line width */
|
||||
@ -385,10 +454,13 @@ void word_wrap_wideglyph(char *dst, size_t dst_size, const char *src, int line_w
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
/* Splits string into tokens seperated by 'delim'
|
||||
/**
|
||||
* string_tokenize:
|
||||
*
|
||||
* Splits string into tokens seperated by @delim
|
||||
* > Returned token string must be free()'d
|
||||
* > Returns NULL if token is not found
|
||||
* > After each call, 'str' is set to the position after the
|
||||
* > After each call, @str is set to the position after the
|
||||
* last found token
|
||||
* > Tokens *include* empty strings
|
||||
* Usage example:
|
||||
@ -401,7 +473,7 @@ void word_wrap_wideglyph(char *dst, size_t dst_size, const char *src, int line_w
|
||||
* free(token);
|
||||
* token = NULL;
|
||||
* }
|
||||
*/
|
||||
**/
|
||||
char* string_tokenize(char **str, const char *delim)
|
||||
{
|
||||
/* Taken from https://codereview.stackexchange.com/questions/216956/strtok-function-thread-safe-supports-empty-tokens-doesnt-change-string# */
|
||||
@ -440,42 +512,53 @@ char* string_tokenize(char **str, const char *delim)
|
||||
return token;
|
||||
}
|
||||
|
||||
/* Removes every instance of character 'c' from 'str' */
|
||||
/**
|
||||
* string_remove_all_chars:
|
||||
* @str : input string (must be non-NULL, otherwise UB)
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* Removes every instance of character @c from @str
|
||||
**/
|
||||
void string_remove_all_chars(char *str, char c)
|
||||
{
|
||||
char *read_ptr = NULL;
|
||||
char *write_ptr = NULL;
|
||||
|
||||
if (string_is_empty(str))
|
||||
return;
|
||||
|
||||
read_ptr = str;
|
||||
write_ptr = str;
|
||||
char *read_ptr = str;
|
||||
char *write_ptr = str;
|
||||
|
||||
while (*read_ptr != '\0')
|
||||
{
|
||||
*write_ptr = *read_ptr++;
|
||||
write_ptr += (*write_ptr != c) ? 1 : 0;
|
||||
if (*write_ptr != c)
|
||||
write_ptr++;
|
||||
}
|
||||
|
||||
*write_ptr = '\0';
|
||||
}
|
||||
|
||||
/* Replaces every instance of character 'find' in 'str'
|
||||
* with character 'replace' */
|
||||
/**
|
||||
* string_replace_all_chars:
|
||||
* @str : input string (must be non-NULL, otherwise UB)
|
||||
* @find : character to find
|
||||
* @replace : character to replace @find with
|
||||
*
|
||||
* Replaces every instance of character @find in @str
|
||||
* with character @replace
|
||||
**/
|
||||
void string_replace_all_chars(char *str, char find, char replace)
|
||||
{
|
||||
if (!string_is_empty(str))
|
||||
{
|
||||
char *str_ptr = str;
|
||||
while ((str_ptr = strchr(str_ptr, find)))
|
||||
*str_ptr++ = replace;
|
||||
}
|
||||
|
||||
char *str_ptr = str;
|
||||
while ((str_ptr = strchr(str_ptr, find)))
|
||||
*str_ptr++ = replace;
|
||||
}
|
||||
|
||||
/* Converts string to unsigned integer.
|
||||
* Returns 0 if string is invalid */
|
||||
/**
|
||||
* string_to_unsigned:
|
||||
* @str : input string
|
||||
*
|
||||
* Converts string to unsigned integer.
|
||||
*
|
||||
* @return 0 if string is invalid, otherwise > 0
|
||||
**/
|
||||
unsigned string_to_unsigned(const char *str)
|
||||
{
|
||||
const char *ptr = NULL;
|
||||
@ -492,25 +575,33 @@ unsigned string_to_unsigned(const char *str)
|
||||
return (unsigned)strtoul(str, NULL, 10);
|
||||
}
|
||||
|
||||
/* Converts hexadecimal string to unsigned integer.
|
||||
/**
|
||||
* string_hex_to_unsigned:
|
||||
* @str : input string (must be non-NULL, otherwise UB)
|
||||
*
|
||||
* Converts hexadecimal string to unsigned integer.
|
||||
* Handles optional leading '0x'.
|
||||
* Returns 0 if string is invalid */
|
||||
*
|
||||
* @return 0 if string is invalid, otherwise > 0
|
||||
**/
|
||||
unsigned string_hex_to_unsigned(const char *str)
|
||||
{
|
||||
const char *hex_str = str;
|
||||
const char *ptr = NULL;
|
||||
|
||||
if (string_is_empty(str))
|
||||
return 0;
|
||||
|
||||
/* Remove leading '0x', if required */
|
||||
if (strlen(str) >= 2)
|
||||
if (str[0] != '\0' && str[1] != '\0')
|
||||
{
|
||||
if ( (str[0] == '0') &&
|
||||
((str[1] == 'x') ||
|
||||
(str[1] == 'X')))
|
||||
{
|
||||
hex_str = str + 2;
|
||||
|
||||
if (string_is_empty(hex_str))
|
||||
if (string_is_empty(hex_str))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
/* Check for valid characters */
|
||||
@ -524,7 +615,13 @@ unsigned string_hex_to_unsigned(const char *str)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total number of occurrences of a character in the given string.
|
||||
* string_count_occurrences_single_character:
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* Get the total number of occurrences of character @c in @str.
|
||||
*
|
||||
* @return Total number of occurrences of character @c
|
||||
*/
|
||||
int string_count_occurrences_single_character(const char *str, char c)
|
||||
{
|
||||
@ -538,8 +635,12 @@ int string_count_occurrences_single_character(const char *str, char c)
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces all spaces with the given character.
|
||||
*/
|
||||
* string_replace_whitespace_with_single_character:
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* Replaces all spaces with given character @c.
|
||||
**/
|
||||
void string_replace_whitespace_with_single_character(char *str, char c)
|
||||
{
|
||||
for (; *str; str++)
|
||||
@ -548,8 +649,12 @@ void string_replace_whitespace_with_single_character(char *str, char c)
|
||||
}
|
||||
|
||||
/**
|
||||
* string_replace_multi_space_with_single_space:
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* Replaces multiple spaces with a single space in a string.
|
||||
*/
|
||||
**/
|
||||
void string_replace_multi_space_with_single_space(char *str)
|
||||
{
|
||||
char *str_trimmed = str;
|
||||
@ -568,8 +673,12 @@ void string_replace_multi_space_with_single_space(char *str)
|
||||
}
|
||||
|
||||
/**
|
||||
* string_remove_all_whitespace:
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* Remove all spaces from the given string.
|
||||
*/
|
||||
**/
|
||||
void string_remove_all_whitespace(char *str_trimmed, const char *str)
|
||||
{
|
||||
for (; *str; str++)
|
||||
@ -589,22 +698,27 @@ int string_index_last_occurance(const char *str, char c)
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the position of a substring in a string.
|
||||
*/
|
||||
* string_find_index_substring_string:
|
||||
* @str : input string (must be non-NULL, otherwise UB)
|
||||
* @substr : substring to find in @str
|
||||
*
|
||||
* Find the position of substring @substr in string @str.
|
||||
**/
|
||||
int string_find_index_substring_string(const char *str, const char *substr)
|
||||
{
|
||||
if (!string_is_empty(str))
|
||||
{
|
||||
const char *pos = strstr(str, substr);
|
||||
|
||||
if (pos)
|
||||
return pos - str;
|
||||
}
|
||||
|
||||
const char *pos = strstr(str, substr);
|
||||
if (pos)
|
||||
return pos - str;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Strips non-ASCII characters from a string. */
|
||||
/**
|
||||
* string_copy_only_ascii:
|
||||
*
|
||||
* Leaf function.
|
||||
*
|
||||
* Strips non-ASCII characters from a string.
|
||||
**/
|
||||
void string_copy_only_ascii(char *str_stripped, const char *str)
|
||||
{
|
||||
for (; *str; str++)
|
||||
|
Loading…
x
Reference in New Issue
Block a user