coan 4.2.4
The File Tree component internals.
Collaboration diagram for The File Tree component internals.:

Data Structures

struct  file_tree

Files

file  file_tree.c

Defines

#define PARENT_PENDING   ((void *)-1)
#define IS_UNLINKED(ftree)   ((ftree)->parent == PARENT_PENDING)
#define IS_ROOT(ftree)   ((ftree)->parent == NULL)
#define IS_FILE(ftree)   ((ftree)->children == NULL)
#define IS_DIR(ftree)   (!IS_FILE(ftree))
#define COUNT_FILES(flags)   (((flags) & FT_COUNT_FILES) == FT_COUNT_FILES)
#define COUNT_FILES_ONLY(flags)   (((flags) & FT_COUNT_ALL) == FT_COUNT_FILES)
#define COUNT_DIRS(flags)   (((flags) & FT_COUNT_DIRS) == FT_COUNT_DIRS)
#define COUNT_DIRS_ONLY(flags)   (((flags) & FT_COUNT_ALL) == FT_COUNT_DIRS)
#define COUNT_ALL(flags)   (((flags) & FT_COUNT_ALL) == FT_COUNT_ALL)
#define COUNT_CHILDREN(flags)   (((flags) & FT_COUNT_CHILDREN) == FT_COUNT_CHILDREN)

Functions

static bool null_filter (char const *leafname)
static void null_callback (file_tree_h ft, char const *name, file_tree_traverse_state_t context)
static file_tree_h new_node (char const *leafname, size_t len)
static file_tree_h new_file_node (char const *leafname, file_filter_t filter)
static file_tree_h get_parent (file_tree_h child)
static void link_in (file_tree_h parent, file_tree_h child)
static void file_tree_add_symlink (file_tree_h root, fs_dir_t parent, char const *symlink, file_tree_callback_t callback)
static file_tree_h new_dir_node (file_tree_h root, char const *leafname, fs_dir_t dir, file_filter_t filter, file_tree_callback_t callback)
static file_tree_h get_root (file_tree_h ft)
static file_tree_h seek_child (file_tree_h node, char const *childname)
static file_tree_h seek (file_tree_h ft, char const **path)
static file_tree_h deepen (file_tree_h ft, char const **path)
static void traverse (file_tree_h ft, file_tree_callback_t callback, char *path_start, char *path_end)
static void file_tree_add_canon (file_tree_h root, char const *path, file_tree_callback_t callback)
static void file_tree_init (file_tree_h ft)
static void file_tree_copy_init (file_tree_h dest, file_tree_const_h src)
static void file_tree_finis (file_tree_h ft)

Define Documentation

#define COUNT_ALL (   flags)    (((flags) & FT_COUNT_ALL) == FT_COUNT_ALL)

flags for file_tree_count() specify that both directories and files are to be counted.

Definition at line 99 of file file_tree.c.

#define COUNT_CHILDREN (   flags)    (((flags) & FT_COUNT_CHILDREN) == FT_COUNT_CHILDREN)

flags for file_tree_count() specify that only the immediate children of the file tree are to be counted

Definition at line 105 of file file_tree.c.

Referenced by file_tree_count().

#define COUNT_DIRS (   flags)    (((flags) & FT_COUNT_DIRS) == FT_COUNT_DIRS)

flags for file_tree_count() specify that directories are to be counted.

Definition at line 89 of file file_tree.c.

Referenced by file_tree_count().

#define COUNT_DIRS_ONLY (   flags)    (((flags) & FT_COUNT_ALL) == FT_COUNT_DIRS)

flags for file_tree_count() specify that only directories are to be counted.

Definition at line 94 of file file_tree.c.

#define COUNT_FILES (   flags)    (((flags) & FT_COUNT_FILES) == FT_COUNT_FILES)

flags for file_tree_count() specify that files are to be counted.

Definition at line 79 of file file_tree.c.

Referenced by file_tree_count().

#define COUNT_FILES_ONLY (   flags)    (((flags) & FT_COUNT_ALL) == FT_COUNT_FILES)

flags for file_tree_count() specify that only files are to be counted.

Definition at line 84 of file file_tree.c.

#define IS_DIR (   ftree)    (!IS_FILE(ftree))

A file tree represents a directory if it does not represent a file.

Definition at line 73 of file file_tree.c.

Referenced by file_tree_child(), file_tree_count(), and traverse().

#define IS_FILE (   ftree)    ((ftree)->children == NULL)

A file tree represents a file if it has no list of children (not even an empty list).

Definition at line 68 of file file_tree.c.

#define IS_ROOT (   ftree)    ((ftree)->parent == NULL)

A file tree is a root node if it has no parent

Definition at line 63 of file file_tree.c.

Referenced by file_tree_copy_init(), file_tree_count(), file_tree_equal(), file_tree_finis(), file_tree_is_empty(), file_tree_name(), get_parent(), get_root(), link_in(), and seek().

#define IS_UNLINKED (   ftree)    ((ftree)->parent == PARENT_PENDING)

Test whether a file tree is not yet linked to its parent.

Definition at line 59 of file file_tree.c.

Referenced by get_parent().

#define PARENT_PENDING   ((void *)-1)

Value of the parent field in struct file_tree indicating the the true value has yet to be set.

Definition at line 54 of file file_tree.c.

Referenced by new_node().


Function Documentation

static file_tree_h deepen ( file_tree_h  ft,
char const **  path 
) [static]

Deepen a file tree by linking additional nodes to represent successive directory components of a path.

Parameters:
ftThe file tree to be deepened.
pathPointer to the path to be parsed.
Returns:
The final node that has been added to the file tree. The address of the final element of the parsed path is stored at path.

Definition at line 418 of file file_tree.c.

References file_tree::children, file_tree_dispose(), link_in(), new_node(), PATH_DELIM, and ptr_vector_new().

Referenced by file_tree_add_canon().

Here is the call graph for this function:

static void file_tree_add_canon ( file_tree_h  root,
char const *  path,
file_tree_callback_t  callback 
) [static]

Add the filtered contents of a canonical path to a file tree.

The function is the same as file_tree_add() with the restriction that the path parameter must be an absolute real path (not a symbolic link).

Definition at line 480 of file file_tree.c.

References deepen(), file_tree_add_symlink(), file_tree::filter, fs_close_dir(), FS_IS_SLINK, fs_obj_type(), fs_open_dir(), fs_read_dir(), fs_split_filename(), FT_AT_FILE, get_root(), file_tree::leafname, link_in(), new_dir_node(), new_file_node(), null_callback(), seek(), seek_child(), and file_tree::var.

Referenced by file_tree_add(), and file_tree_add_symlink().

Here is the call graph for this function:

static void file_tree_add_symlink ( file_tree_h  root,
fs_dir_t  dir,
char const *  symlink,
file_tree_callback_t  callback 
) [static]

Add the filtered contents of a symbolic link to a file tree.

Parameters:
rootThe file tree to which a symbolic link is to be added.
dirNULL, or the handle of the directory being traversed when the symlink was found.
symlinkThe absolute name of the symlink.
callbackThe file_tree_callback_t to be invoked if symlink is found to contain any files that should be added to root.
Returns:
True if the symlink is found to be eligible for addition to the file tree, else false.

When a symbolic link is found among the inputs, it can represent a "jump" from one ostensible position in the filesystem to an arbitrary other position.

The basic approach for handling such a jump is to "start from scratch", calling file_tree_add_canon() on the resolved real pathname R of the symbolic link.

There is one snag with this approach. R might lie beneath some directory D that is still in play at the time when we wish to call file_tree_add_canon(R), i.e. we are in the process of traversing D and have not yet linked it into the input file tree. In this case a call to file_tree_add_canon(R) would force D to be linked while we are trying to determine whether it should be; and if we finally decided that D should be linked, we will end up linking it twice.

The addition of a depuplication precautions to the linkage logic simply to cater for symbolic links would have very poor cost-benefit. Instead, we just determine whether R is a subdirectory of any of the directories that are in play when we encounter the symlink, by backtracking from the directory in which we found the symlink and comparing the successive directory pathnames with R until either we find one that is a parent of R or reach the root of of the directories currently open for traversal. Only if R is not found found to lie under any of the open directories is it necessary to call file_tree_add_canon(R), because otherwise R has either already been traversed or it is going to be traversed within the active call to file_tree_add_canon().

Definition at line 598 of file file_tree.c.

References file_tree_add_canon(), fs_cur_dir_entry(), fs_get_parent(), fs_path_comp(), fs_real_path(), GRIPE_SYMLINK, and report().

Referenced by file_tree_add(), file_tree_add_canon(), and new_dir_node().

Here is the call graph for this function:

static void file_tree_copy_init ( file_tree_h  dest,
file_tree_const_h  src 
) [static]

Initialise a file tree set from another

Parameters:
destThe file tree to initialise. Is assumed to control only unitialised storage.
srcThe file tree to be copied.

dest is initialised as a copy of src

Definition at line 645 of file file_tree.c.

References clone(), file_tree_copy(), file_tree::files, file_tree::filter, IS_ROOT, file_tree::leafname, link_in(), ptr_vector_begin_const(), ptr_vector_end_const(), and file_tree::var.

Referenced by file_tree_copy().

Here is the call graph for this function:

static void file_tree_finis ( file_tree_h  ft) [static]

Finalise a file tree, releasing the resources of all contained objects

Definition at line 669 of file file_tree.c.

References file_tree::children, IS_ROOT, file_tree::leafname, ptr_vector_dispose(), and file_tree::var.

Referenced by file_tree_dispose().

Here is the call graph for this function:

static void file_tree_init ( file_tree_h  ft) [static]

Initialise a file tree.

Parameters:
ftThe file tree to initialise. Is assumed to control only unitialised storage.

Definition at line 631 of file file_tree.c.

References file_tree::filter, null_filter(), and file_tree::var.

Referenced by file_tree_new().

Here is the call graph for this function:

static file_tree_h get_parent ( file_tree_h  child) [static]

Return the parent of a file tree.

Parameters:
childThe file tree whose parent is required.
Returns:
The parent of child, if any; NULL if child is a root node or is not yet linked.

Definition at line 201 of file file_tree.c.

References IS_ROOT, IS_UNLINKED, and file_tree::parent.

Referenced by link_in().

static file_tree_h get_root ( file_tree_h  ft) [static]

Return the root node of a file tree

Definition at line 309 of file file_tree.c.

References IS_ROOT, and file_tree::parent.

Referenced by file_tree_add_canon().

static void link_in ( file_tree_h  parent,
file_tree_h  child 
) [static]

Link a child node to its parent node in a file tree.

Parameters:
parentThe parent node.
childThe child node.

child is added to the children of child->parent and parent is assigned as the parent of child

Definition at line 216 of file file_tree.c.

References file_tree::children, file_tree_dispose(), file_tree::files, get_parent(), IS_ROOT, file_tree::parent, ptr_vector_append(), and ptr_vector_new().

Referenced by deepen(), file_tree_add_canon(), file_tree_copy_init(), and new_dir_node().

Here is the call graph for this function:

static file_tree_h new_dir_node ( file_tree_h  root,
char const *  leafname,
fs_dir_t  dir,
file_filter_t  filter,
file_tree_callback_t  callback 
) [static]

Construct a new file tree node to represent a directory

Parameters:
rootThe root node of the file tree in which the new node will potentially be added.
leafnameThe name of the new node.
dirHandle to the directory of which leafname is the leafname.
filterA pointer to a function that shall be applied to the names of files (not directories) under dir to accept or reject them for inclusion under the new node.
callbackNULL, or a file_tree_callback_t to be called at entry and exit for each directory node constructed and for each file added.
Returns:
If any files are found recursively under dir that satisfy filter then a new node is returned representing the directory together with all such files and the subdirectories that contain them.

Definition at line 263 of file file_tree.c.

References file_tree::children, file_tree_add_symlink(), file_tree_dispose(), file_tree::files, fs_close_dir(), fs_cur_dir_entry(), FS_IS_SLINK, fs_obj_type(), fs_open_dir(), fs_read_dir(), FT_AT_FILE, FT_ENTERING_DIR, FT_LEAVING_DIR, link_in(), new_file_node(), new_node(), and ptr_vector_new().

Referenced by file_tree_add_canon().

Here is the call graph for this function:

static file_tree_h new_file_node ( char const *  leafname,
file_filter_t  filter 
) [static]

Construct a new file tree node to represent a file.

Parameters:
leafnameThe name of the new node.
filterPointer to a function that shall be applied to leafname to accept or reject it for constructing a node.
Returns:
iIf leafname satisfies filter then a new node is returned; else NULL.

Definition at line 182 of file file_tree.c.

References file_tree::files, file_tree::filter, and new_node().

Referenced by file_tree_add_canon(), and new_dir_node().

Here is the call graph for this function:

static file_tree_h new_node ( char const *  leafname,
size_t  len 
) [static]

Construct a new file tree node.

Parameters:
leafnamePointer to the name of the new node.
lenThe length of the name at leafname. If 0, strlen(leafname) is used.
Returns:
The new node.

Definition at line 158 of file file_tree.c.

References callocate(), file_tree::leafname, file_tree::parent, PARENT_PENDING, file_tree::var, and zallocate().

Referenced by deepen(), new_dir_node(), and new_file_node().

Here is the call graph for this function:

static void null_callback ( file_tree_h  ft,
char const *  name,
file_tree_traverse_state_t  context 
) [static]

The default callback function for a file tree traversals where none is specified. It does nothing.

Definition at line 142 of file file_tree.c.

Referenced by file_tree_add_canon().

static bool null_filter ( char const *  leafname) [static]

The default filter function for a file tree to which no filter is attached. It accepts all files.

Definition at line 132 of file file_tree.c.

Referenced by file_tree_init().

static file_tree_h seek ( file_tree_h  ft,
char const **  path 
) [static]

Search for a path in a file tree.

Parameters:
ftThe file tree to be searched.
pathPointer to the path to be searched for.
Returns:
The deepest node in tree to which any initial subpath of *path is a key. The unmatched reminder of the path will be stored at path.

If the path at *path is relative then then it is assumed to be relative to a path that is a key to the parent of ft. If *path is absolute then the function returns seek(root,path), where root is the root node of ft.

Definition at line 363 of file file_tree.c.

References file_tree::children, fs_absolute_path, fs_path_type(), fs_windows_path, IS_ROOT, file_tree::leafname, PATH_DELIM, ptr_vector_begin(), ptr_vector_end(), and file_tree::var.

Referenced by file_tree_add_canon().

Here is the call graph for this function:

static file_tree_h seek_child ( file_tree_h  node,
char const *  childname 
) [static]

Seek a node within a file tree by name.

Parameters:
nodeThe file tree within which to search.
childnameThe name of the child node to search for.
Returns:
The file tree node that has the name childname, if found, else NULL.

Definition at line 325 of file file_tree.c.

References file_tree::children, ptr_vector_begin(), and ptr_vector_end().

Referenced by file_tree_add_canon().

Here is the call graph for this function:

static void traverse ( file_tree_h  ft,
file_tree_callback_t  callback,
char *  path_start,
char *  path_end 
) [static]

Recursively traverse a file ft, executing a callback at each node.

Parameters:
ftThe file tree to traverse.
callbackThe callback to execute at each node.
path_startPointer to the full pathname of ft
path_endPointer just past the end of the full pathname of ft.

callback is executed at each file node reached, passing the full pathname of the file and the flag FT_AT_FILE. It is executed at entry and exit for each directory node, passing the full pathname of the directory and FT_ENTERING_DIR or FT_LEAVING_DIR respectively.

Definition at line 449 of file file_tree.c.

References file_tree::children, FT_AT_FILE, FT_ENTERING_DIR, FT_LEAVING_DIR, IS_DIR, file_tree::leafname, PATH_DELIM, ptr_vector_begin(), ptr_vector_end(), and file_tree::var.

Referenced by file_tree_traverse().

Here is the call graph for this function:

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines