Browse Source

Preliminary support for find nodes.

tags/release-0.6.18
Vreixo Formoso 12 years ago
parent
commit
cb47296913
6 changed files with 285 additions and 1 deletions
  1. +1
    -0
      .bzrignore
  2. +6
    -0
      Makefile.am
  3. +59
    -0
      demo/find.c
  4. +182
    -0
      libisofs/find.c
  5. +37
    -0
      libisofs/libisofs.h
  6. +0
    -1
      libisofs/node.c

+ 1
- 0
.bzrignore View File

@@ -38,3 +38,4 @@ demo/isogrow
doc/html
doc/doxygen.conf
libisofs-1.pc
demo/find

+ 6
- 0
Makefile.am View File

@@ -16,6 +16,7 @@ libisofs_libisofs_la_SOURCES = \
libisofs/node.c \
libisofs/tree.h \
libisofs/tree.c \
libisofs/find.c \
libisofs/image.h \
libisofs/image.c \
libisofs/fsource.h \
@@ -65,6 +66,7 @@ noinst_PROGRAMS = \
demo/cat \
demo/catbuffer \
demo/tree \
demo/find \
demo/ecma119tree \
demo/iso \
demo/isoread \
@@ -89,6 +91,10 @@ demo_tree_CPPFLAGS = -Ilibisofs
demo_tree_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS)
demo_tree_SOURCES = demo/tree.c

demo_find_CPPFLAGS = -Ilibisofs
demo_find_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS)
demo_find_SOURCES = demo/find.c

demo_ecma119tree_CPPFLAGS = -Ilibisofs
demo_ecma119tree_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS)
demo_ecma119tree_SOURCES = demo/ecma119_tree.c


+ 59
- 0
demo/find.c View File

@@ -0,0 +1,59 @@
/*
* Little program that import a directory, find matching nodes and prints the
* resulting iso tree.
*/

#include "libisofs.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

static void
print_dir(IsoDir *dir)
{
IsoDirIter *iter;
IsoNode *node;
IsoFindCondition *cond;
cond = iso_new_find_conditions_name("*a*");
iso_dir_find_children(dir, cond, &iter);
while (iso_dir_iter_next(iter, &node) == 1) {
printf(" %s\n", iso_node_get_name(node));
}
iso_dir_iter_free(iter);
}

int main(int argc, char **argv)
{
int result;
IsoImage *image;
if (argc != 2) {
printf ("You need to specify a valid path\n");
return 1;
}

iso_init();
iso_set_msgs_severities("NEVER", "ALL", "");
result = iso_image_new("volume_id", &image);
if (result < 0) {
printf ("Error creating image\n");
return 1;
}
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[1]);
if (result < 0) {
printf ("Error adding directory %d\n", result);
return 1;
}
print_dir(iso_image_get_root(image));
iso_image_unref(image);
iso_finish();
return 0;
}

+ 182
- 0
libisofs/find.c View File

@@ -0,0 +1,182 @@
/*
* Copyright (c) 2008 Vreixo Formoso
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. See COPYING file for details.
*/

#include "libisofs.h"
#include "node.h"

#include <fnmatch.h>
#include <string.h>

struct iso_find_condition
{
/*
* Check whether the given node matches this condition.
*
* @param cond
* The condition to check
* @param node
* The node that should be checked
* @return
* 1 if the node matches the condition, 0 if not
*/
int (*matches)(IsoFindCondition *cond, IsoNode *node);
/**
* Free condition specific data
*/
void (*free)(IsoFindCondition*);
/** condition specific data */
void *data;
};

struct find_iter_data
{
IsoDirIter *iter;
IsoFindCondition *cond;
};

static
int find_iter_next(IsoDirIter *iter, IsoNode **node)
{
int ret;
IsoNode *n;
struct find_iter_data *data = iter->data;
while ((ret = iso_dir_iter_next(data->iter, &n)) == 1) {
if (data->cond->matches(data->cond, n)) {
*node = n;
break;
}
}
return ret;
}

static
int find_iter_has_next(IsoDirIter *iter)
{
struct find_iter_data *data = iter->data;
/*
* FIXME wrong implementation!!!! the underlying iter may have more nodes,
* but they may not match find conditions
*/
return iso_dir_iter_has_next(data->iter);
}

static
void find_iter_free(IsoDirIter *iter)
{
struct find_iter_data *data = iter->data;
data->cond->free(data->cond);
free(data->cond);
iso_dir_iter_free(data->iter);
free(iter->data);
}

static
int find_iter_take(IsoDirIter *iter)
{
struct find_iter_data *data = iter->data;
return iso_dir_iter_take(data->iter);
}

static
int find_iter_remove(IsoDirIter *iter)
{
struct find_iter_data *data = iter->data;
return iso_dir_iter_remove(data->iter);
}

static
struct iso_dir_iter_iface find_iter_class = {
find_iter_next,
find_iter_has_next,
find_iter_free,
find_iter_take,
find_iter_remove
};

int iso_dir_find_children(IsoDir* dir, IsoFindCondition *cond,
IsoDirIter **iter)
{
int ret;
IsoDirIter *children;
IsoDirIter *it;
struct find_iter_data *data;

if (dir == NULL || cond == NULL || iter == NULL) {
return ISO_NULL_POINTER;
}
it = malloc(sizeof(IsoDirIter));
if (it == NULL) {
return ISO_OUT_OF_MEM;
}
data = malloc(sizeof(struct find_iter_data));
if (data == NULL) {
free(it);
return ISO_OUT_OF_MEM;
}
ret = iso_dir_get_children(dir, &children);
if (ret < 0) {
free(it);
free(data);
return ret;
}

it->class = &find_iter_class;
it->dir = (IsoDir*)dir;
data->iter = children;
data->cond = cond;
it->data = data;

*iter = it;
return ISO_SUCCESS;
}

/*************** find by name wildcard condition *****************/

static
int cond_name_matches(IsoFindCondition *cond, IsoNode *node)
{
char *pattern = (char*) cond->data;
int ret = fnmatch(pattern, node->name, 0);
return ret == 0 ? 1 : 0;
}

static
void cond_name_free(IsoFindCondition *cond)
{
free(cond->data);
}

/**
* Create a new condition that checks if a the node name matches the given
* wildcard.
*
* @param wildcard
* @result
* The created IsoFindCondition, NULL on error.
*
* @since 0.6.4
*/
IsoFindCondition *iso_new_find_conditions_name(const char *wildcard)
{
IsoFindCondition *cond;
if (wildcard == NULL) {
return NULL;
}
cond = malloc(sizeof(IsoFindCondition));
if (cond == NULL) {
return NULL;
}
cond->data = strdup(wildcard);
cond->free = cond_name_free;
cond->matches = cond_name_matches;
return cond;
}

+ 37
- 0
libisofs/libisofs.h View File

@@ -2164,6 +2164,43 @@ int iso_dir_iter_take(IsoDirIter *iter);
*/
int iso_dir_iter_remove(IsoDirIter *iter);


/**
* @since 0.6.4
*/
typedef struct iso_find_condition IsoFindCondition;

/**
* Create a new condition that checks if a the node name matches the given
* wildcard.
*
* @param wildcard
* @result
* The created IsoFindCondition, NULL on error.
*
* @since 0.6.4
*/
IsoFindCondition *iso_new_find_conditions_name(const char *wildcard);

/**
* Find all directory children that match the given condition.
*
* @param dir
* Directory where we will search children.
* @param cond
* Condition that the children must match in order to be returned.
* It will be free together with the iterator. Remember to delete it
* if this function return error.
* @param iter
* Iterator that returns only the children that match condition.
* @return
* 1 on success, < 0 on error
*
* @since 0.6.4
*/
int iso_dir_find_children(IsoDir* dir, IsoFindCondition *cond,
IsoDirIter **iter);

/**
* Get the destination of a node.
* The returned string belongs to the node and should not be modified nor


+ 0
- 1
libisofs/node.c View File

@@ -616,7 +616,6 @@ struct iso_dir_iter_iface iter_class = {
iter_remove
};


int iso_dir_get_children(const IsoDir *dir, IsoDirIter **iter)
{
IsoDirIter *it;


Loading…
Cancel
Save