[Cmake-commits] [cmake-commits] hoffman committed err.c NONE 1.1 err.h NONE 1.1 lafe_platform.h NONE 1.1 line_reader.c NONE 1.1 line_reader.h NONE 1.1 matching.c NONE 1.1 matching.h NONE 1.1 pathmatch.c NONE 1.1 pathmatch.h NONE 1.1

cmake-commits at cmake.org cmake-commits at cmake.org
Fri Oct 30 13:10:53 EDT 2009


Update of /cvsroot/CMake/CMake/Utilities/cmlibarchive/libarchive_fe
In directory public:/mounts/ram/cvs-serv26614/Utilities/cmlibarchive/libarchive_fe

Added Files:
	err.c err.h lafe_platform.h line_reader.c line_reader.h 
	matching.c matching.h pathmatch.c pathmatch.h 
Log Message:
Switch to using libarchive from libtar for cpack and cmake -E tar

This allows for a built in bzip and zip capability, so external tools 
will not be needed for these packagers.  The cmake -E tar xf should be
able to handle all compression types now as well.



--- NEW FILE: line_reader.c ---
/*-
 * Copyright (c) 2008 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer
 *    in this position and unchanged.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "lafe_platform.h"
__FBSDID("$FreeBSD$");

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "err.h"
#include "line_reader.h"

#if defined(_WIN32) && !defined(__CYGWIN__)
#define strdup _strdup
#endif

/*
 * Read lines from file and do something with each one.  If option_null
 * is set, lines are terminated with zero bytes; otherwise, they're
 * terminated with newlines.
 *
 * This uses a self-sizing buffer to handle arbitrarily-long lines.
 */
struct lafe_line_reader {
    FILE *f;
    char *buff, *buff_end, *line_start, *line_end, *p;
    char *pathname;
    size_t buff_length;
    int nullSeparator; /* Lines separated by null, not CR/CRLF/etc. */
    int ret;
};

struct lafe_line_reader *
lafe_line_reader(const char *pathname, int nullSeparator)
{
    struct lafe_line_reader *lr;

    lr = calloc(1, sizeof(*lr));
    if (lr == NULL)
        lafe_errc(1, ENOMEM, "Can't open %s", pathname);

    lr->nullSeparator = nullSeparator;
    lr->pathname = strdup(pathname);

    if (strcmp(pathname, "-") == 0)
        lr->f = stdin;
    else
        lr->f = fopen(pathname, "r");
    if (lr->f == NULL)
        lafe_errc(1, errno, "Couldn't open %s", pathname);
    lr->buff_length = 8192;
    lr->buff = malloc(lr->buff_length);
    if (lr->buff == NULL)
        lafe_errc(1, ENOMEM, "Can't read %s", pathname);
    lr->line_start = lr->line_end = lr->buff_end = lr->buff;

    return (lr);
}

const char *
lafe_line_reader_next(struct lafe_line_reader *lr)
{
    size_t bytes_wanted, bytes_read, new_buff_size;
    char *line_start, *p;

    for (;;) {
        /* If there's a line in the buffer, return it immediately. */
        while (lr->line_end < lr->buff_end) {
            if (lr->nullSeparator) {
                if (*lr->line_end == '\0') {
                    line_start = lr->line_start;
                    lr->line_start = lr->line_end + 1;
                    lr->line_end = lr->line_start;
                    return (line_start);
                }
            } else if (*lr->line_end == '\x0a' || *lr->line_end == '\x0d') {
                *lr->line_end = '\0';
                line_start = lr->line_start;
                lr->line_start = lr->line_end + 1;
                lr->line_end = lr->line_start;
                if (line_start[0] != '\0')
                    return (line_start);
            }
            lr->line_end++;
        }

        /* If we're at end-of-file, process the final data. */
        if (lr->f == NULL) {
            /* If there's more text, return one last line. */
            if (lr->line_end > lr->line_start) {
                *lr->line_end = '\0';
                line_start = lr->line_start;
                lr->line_start = lr->line_end + 1;
                lr->line_end = lr->line_start;
                return (line_start);
            }
            /* Otherwise, we're done. */
            return (NULL);
        }

        /* Buffer only has part of a line. */
        if (lr->line_start > lr->buff) {
            /* Move a leftover fractional line to the beginning. */
            memmove(lr->buff, lr->line_start,
                lr->buff_end - lr->line_start);
            lr->buff_end -= lr->line_start - lr->buff;
            lr->line_end -= lr->line_start - lr->buff;
            lr->line_start = lr->buff;
        } else {
            /* Line is too big; enlarge the buffer. */
            new_buff_size = lr->buff_length * 2;
            if (new_buff_size <= lr->buff_length)
                lafe_errc(1, ENOMEM,
                    "Line too long in %s", lr->pathname);
            lr->buff_length = new_buff_size;
            p = realloc(lr->buff, new_buff_size);
            if (p == NULL)
                lafe_errc(1, ENOMEM,
                    "Line too long in %s", lr->pathname);
            lr->buff_end = p + (lr->buff_end - lr->buff);
            lr->line_end = p + (lr->line_end - lr->buff);
            lr->line_start = lr->buff = p;
        }

        /* Get some more data into the buffer. */
        bytes_wanted = lr->buff + lr->buff_length - lr->buff_end;
        bytes_read = fread(lr->buff_end, 1, bytes_wanted, lr->f);
        lr->buff_end += bytes_read;

        if (ferror(lr->f))
            lafe_errc(1, errno, "Can't read %s", lr->pathname);
        if (feof(lr->f)) {
            if (lr->f != stdin)
                fclose(lr->f);
            lr->f = NULL;
        }
    }
}

void
lafe_line_reader_free(struct lafe_line_reader *lr)
{
    free(lr->buff);
    free(lr->pathname);
    free(lr);
}

--- NEW FILE: err.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer
 *    in this position and unchanged.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "lafe_platform.h"
__FBSDID("$FreeBSD$");

#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif

#include "err.h"

const char *lafe_progname;

static void
lafe_vwarnc(int code, const char *fmt, va_list ap)
{
    fprintf(stderr, "%s: ", lafe_progname);
    vfprintf(stderr, fmt, ap);
    if (code != 0)
        fprintf(stderr, ": %s", strerror(code));
    fprintf(stderr, "\n");
}

void
lafe_warnc(int code, const char *fmt, ...)
{
    va_list ap;

    va_start(ap, fmt);
    lafe_vwarnc(code, fmt, ap);
    va_end(ap);
}

void
lafe_errc(int eval, int code, const char *fmt, ...)
{
    va_list ap;

    va_start(ap, fmt);
    lafe_vwarnc(code, fmt, ap);
    va_end(ap);
    exit(eval);
}

--- NEW FILE: err.h ---
/*-
 * Copyright (c) 2009 Joerg Sonnenberger
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef LAFE_ERR_H
#define LAFE_ERR_H

extern const char *lafe_progname;

void    lafe_warnc(int code, const char *fmt, ...);
void    lafe_errc(int eval, int code, const char *fmt, ...);

#endif

--- NEW FILE: line_reader.h ---
/*-
 * Copyright (c) 2009 Joerg Sonnenberger
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef LAFE_LINE_READER_H
#define LAFE_LINE_READER_H

struct lafe_line_reader;

struct lafe_line_reader *lafe_line_reader(const char *, int nullSeparator);
const char *lafe_line_reader_next(struct lafe_line_reader *);
void    lafe_line_reader_free(struct lafe_line_reader *);

#endif

--- NEW FILE: matching.h ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer
 *    in this position and unchanged.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $FreeBSD$
 */

#ifndef MATCHING_H
#define MATCHING_H

struct lafe_matching;

int lafe_exclude(struct lafe_matching **matching, const char *pattern);
int lafe_exclude_from_file(struct lafe_matching **matching,
                   const char *pathname);
int lafe_include(struct lafe_matching **matching, const char *pattern);
int lafe_include_from_file(struct lafe_matching **matching,
                   const char *pathname, int nullSeparator);

int lafe_excluded(struct lafe_matching *, const char *pathname);
void    lafe_cleanup_exclusions(struct lafe_matching **);
int lafe_unmatched_inclusions(struct lafe_matching *);
int lafe_unmatched_inclusions_warn(struct lafe_matching *, const char *msg);

#endif

--- NEW FILE: pathmatch.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer
 *    in this position and unchanged.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "lafe_platform.h"
__FBSDID("$FreeBSD$");

#ifdef HAVE_STRING_H
#include <string.h>
#endif

#include "pathmatch.h"

/*
 * Check whether a character 'c' is matched by a list specification [...]:
 *    * Leading '!' negates the class.
 *    * <char>-<char> is a range of characters
 *    * \<char> removes any special meaning for <char>
 *
 * Some interesting boundary cases:
 *   a-d-e is one range (a-d) followed by two single characters - and e.
 *   \a-\d is same as a-d
 *   a\-d is three single characters: a, d, -
 *   Trailing - is not special (so [a-] is two characters a and -).
 *   Initial - is not special ([a-] is same as [-a] is same as [\\-a])
 *   This function never sees a trailing \.
 *   [] always fails
 *   [!] always succeeds
 */
static int
pm_list(const char *start, const char *end, const char c, int flags)
{
    const char *p = start;
    char rangeStart = '\0', nextRangeStart;
    int match = 1, nomatch = 0;

    /* This will be used soon... */
    (void)flags; /* UNUSED */

    /* If this is a negated class, return success for nomatch. */
    if (*p == '!' && p < end) {
        match = 0;
        nomatch = 1;
        ++p;
    }

    while (p < end) {
        nextRangeStart = '\0';
        switch (*p) {
        case '-':
            /* Trailing or initial '-' is not special. */
            if ((rangeStart == '\0') || (p == end - 1)) {
                if (*p == c)
                    return (match);
            } else {
                char rangeEnd = *++p;
                if (rangeEnd == '\\')
                    rangeEnd = *++p;
                if ((rangeStart <= c) && (c <= rangeEnd))
                    return (match);
            }
            break;
        case '\\':
            ++p;
            /* Fall through */
        default:
            if (*p == c)
                return (match);
            nextRangeStart = *p; /* Possible start of range. */
        }
        rangeStart = nextRangeStart;
        ++p;
    }
    return (nomatch);
}

/*
 * If s is pointing to "./", ".//", "./././" or the like, skip it.
 */
static const char *
pm_slashskip(const char *s) {
    while ((*s == '/')
        || (s[0] == '.' && s[1] == '/')
        || (s[0] == '.' && s[1] == '\0'))
        ++s;
    return (s);
}

static int
pm(const char *p, const char *s, int flags)
{
    const char *end;

    /*
     * Ignore leading './', './/', '././', etc.
     */
    if (s[0] == '.' && s[1] == '/')
        s = pm_slashskip(s + 1);
    if (p[0] == '.' && p[1] == '/')
        p = pm_slashskip(p + 1);

    for (;;) {
        switch (*p) {
        case '\0':
            if (s[0] == '/') {
                if (flags & PATHMATCH_NO_ANCHOR_END)
                    return (1);
                /* "dir" == "dir/" == "dir/." */
                s = pm_slashskip(s);
            }
            return (*s == '\0');
            break;
        case '?':
            /* ? always succeds, unless we hit end of 's' */
            if (*s == '\0')
                return (0);
            break;
        case '*':
            /* "*" == "**" == "***" ... */
            while (*p == '*')
                ++p;
            /* Trailing '*' always succeeds. */
            if (*p == '\0')
                return (1);
            while (*s) {
                if (lafe_pathmatch(p, s, flags))
                    return (1);
                ++s;
            }
            return (0);
            break;
        case '[':
            /*
             * Find the end of the [...] character class,
             * ignoring \] that might occur within the class.
             */
            end = p + 1;
            while (*end != '\0' && *end != ']') {
                if (*end == '\\' && end[1] != '\0')
                    ++end;
                ++end;
            }
            if (*end == ']') {
                /* We found [...], try to match it. */
                if (!pm_list(p + 1, end, *s, flags))
                    return (0);
                p = end; /* Jump to trailing ']' char. */
                break;
            } else
                /* No final ']', so just match '['. */
                if (*p != *s)
                    return (0);
            break;
        case '\\':
            /* Trailing '\\' matches itself. */
            if (p[1] == '\0') {
                if (*s != '\\')
                    return (0);
            } else {
                ++p;
                if (*p != *s)
                    return (0);
            }
            break;
        case '/':
            if (*s != '/' && *s != '\0')
                return (0);
            /* Note: pattern "/\./" won't match "/";
             * pm_slashskip() correctly stops at backslash. */
            p = pm_slashskip(p);
            s = pm_slashskip(s);
            if (*p == '\0' && (flags & PATHMATCH_NO_ANCHOR_END))
                return (1);
            --p; /* Counteract the increment below. */
            --s;
            break;
        case '$':
            /* '$' is special only at end of pattern and only
             * if PATHMATCH_NO_ANCHOR_END is specified. */
            if (p[1] == '\0' && (flags & PATHMATCH_NO_ANCHOR_END)){
                /* "dir" == "dir/" == "dir/." */
                return (*pm_slashskip(s) == '\0');
            }
            /* Otherwise, '$' is not special. */
            /* FALL THROUGH */
        default:
            if (*p != *s)
                return (0);
            break;
        }
        ++p;
        ++s;
    }
}

/* Main entry point. */
int
lafe_pathmatch(const char *p, const char *s, int flags)
{
    /* Empty pattern only matches the empty string. */
    if (p == NULL || *p == '\0')
        return (s == NULL || *s == '\0');

    /* Leading '^' anchors the start of the pattern. */
    if (*p == '^') {
        ++p;
        flags &= ~PATHMATCH_NO_ANCHOR_START;
    }

    if (*p == '/' && *s != '/')
        return (0);

    /* Certain patterns and file names anchor implicitly. */
    if (*p == '*' || *p == '/' || *p == '/') {
        while (*p == '/')
            ++p;
        while (*s == '/')
            ++s;
        return (pm(p, s, flags));
    }

    /* If start is unanchored, try to match start of each path element. */
    if (flags & PATHMATCH_NO_ANCHOR_START) {
        for ( ; s != NULL; s = strchr(s, '/')) {
            if (*s == '/')
                s++;
            if (pm(p, s, flags))
                return (1);
        }
        return (0);
    }

    /* Default: Match from beginning. */
    return (pm(p, s, flags));
}

--- NEW FILE: pathmatch.h ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer
 *    in this position and unchanged.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $FreeBSD$
 */

#ifndef LAFE_PATHMATCH_H
#define LAFE_PATHMATCH_H

/* Don't anchor at beginning unless the pattern starts with "^" */
#define PATHMATCH_NO_ANCHOR_START   1
/* Don't anchor at end unless the pattern ends with "$" */
#define PATHMATCH_NO_ANCHOR_END     2

/* Note that "^" and "$" are not special unless you set the corresponding
 * flag above. */

int lafe_pathmatch(const char *p, const char *s, int flags);

#endif

--- NEW FILE: matching.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "lafe_platform.h"
__FBSDID("$FreeBSD: src/usr.bin/cpio/matching.c,v 1.2 2008/06/21 02:20:20 kientzle Exp $");

#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif

#include "err.h"
#include "line_reader.h"
#include "matching.h"
#include "pathmatch.h"

struct match {
    struct match     *next;
    int       matches;
    char          pattern[1];
};

struct lafe_matching {
    struct match     *exclusions;
    int       exclusions_count;
    struct match     *inclusions;
    int       inclusions_count;
    int       inclusions_unmatched_count;
};

static void add_pattern(struct match **list, const char *pattern);
static void initialize_matching(struct lafe_matching **);
static int  match_exclusion(struct match *, const char *pathname);
static int  match_inclusion(struct match *, const char *pathname);

/*
 * The matching logic here needs to be re-thought.  I started out to
 * try to mimic gtar's matching logic, but it's not entirely
 * consistent.  In particular 'tar -t' and 'tar -x' interpret patterns
 * on the command line as anchored, but --exclude doesn't.
 */

/*
 * Utility functions to manage exclusion/inclusion patterns
 */

int
lafe_exclude(struct lafe_matching **matching, const char *pattern)
{

    if (*matching == NULL)
        initialize_matching(matching);
    add_pattern(&((*matching)->exclusions), pattern);
    (*matching)->exclusions_count++;
    return (0);
}

int
lafe_exclude_from_file(struct lafe_matching **matching, const char *pathname)
{
    struct lafe_line_reader *lr;
    const char *p;
    int ret = 0;

    lr = lafe_line_reader(pathname, '\n');
    while ((p = lafe_line_reader_next(lr)) != NULL) {
        if (lafe_exclude(matching, p) != 0)
            ret = -1;
    }
    lafe_line_reader_free(lr);
    return (ret);
}

int
lafe_include(struct lafe_matching **matching, const char *pattern)
{

    if (*matching == NULL)
        initialize_matching(matching);
    add_pattern(&((*matching)->inclusions), pattern);
    (*matching)->inclusions_count++;
    (*matching)->inclusions_unmatched_count++;
    return (0);
}

int
lafe_include_from_file(struct lafe_matching **matching, const char *pathname,
    int nullSeparator)
{
    struct lafe_line_reader *lr;
    const char *p;
    int ret = 0;

    lr = lafe_line_reader(pathname, nullSeparator);
    while ((p = lafe_line_reader_next(lr)) != NULL) {
        if (lafe_include(matching, p) != 0)
            ret = -1;
    }
    lafe_line_reader_free(lr);
    return (ret);
}

static void
add_pattern(struct match **list, const char *pattern)
{
    struct match *match;
    size_t len;

    len = strlen(pattern);
    match = malloc(sizeof(*match) + len + 1);
    if (match == NULL)
        lafe_errc(1, errno, "Out of memory");
    strcpy(match->pattern, pattern);
    /* Both "foo/" and "foo" should match "foo/bar". */
    if (len && match->pattern[len - 1] == '/')
        match->pattern[strlen(match->pattern)-1] = '\0';
    match->next = *list;
    *list = match;
    match->matches = 0;
}


int
lafe_excluded(struct lafe_matching *matching, const char *pathname)
{
    struct match *match;
    struct match *matched;

    if (matching == NULL)
        return (0);

    /* Exclusions take priority */
    for (match = matching->exclusions; match != NULL; match = match->next){
        if (match_exclusion(match, pathname))
            return (1);
    }

    /* Then check for inclusions */
    matched = NULL;
    for (match = matching->inclusions; match != NULL; match = match->next){
        if (match_inclusion(match, pathname)) {
            /*
             * If this pattern has never been matched,
             * then we're done.
             */
            if (match->matches == 0) {
                match->matches++;
                matching->inclusions_unmatched_count--;
                return (0);
            }
            /*
             * Otherwise, remember the match but keep checking
             * in case we can tick off an unmatched pattern.
             */
            matched = match;
        }
    }
    /*
     * We didn't find a pattern that had never been matched, but
     * we did find a match, so count it and exit.
     */
    if (matched != NULL) {
        matched->matches++;
        return (0);
    }

    /* If there were inclusions, default is to exclude. */
    if (matching->inclusions != NULL)
        return (1);

    /* No explicit inclusions, default is to match. */
    return (0);
}

/*
 * This is a little odd, but it matches the default behavior of
 * gtar.  In particular, 'a*b' will match 'foo/a1111/222b/bar'
 *
 */
static int
match_exclusion(struct match *match, const char *pathname)
{
    return (lafe_pathmatch(match->pattern,
            pathname,
            PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END));
}

/*
 * Again, mimic gtar:  inclusions are always anchored (have to match
 * the beginning of the path) even though exclusions are not anchored.
 */
static int
match_inclusion(struct match *match, const char *pathname)
{
#if 0
    return (lafe_pathmatch(match->pattern, pathname, 0));
#else
    return (lafe_pathmatch(match->pattern, pathname, PATHMATCH_NO_ANCHOR_END));
#endif  
}

void
lafe_cleanup_exclusions(struct lafe_matching **matching)
{
    struct match *p, *q;

    if (*matching == NULL)
        return;

    for (p = (*matching)->inclusions; p != NULL; ) {
        q = p;
        p = p->next;
        free(q);
    }

    for (p = (*matching)->exclusions; p != NULL; ) {
        q = p;
        p = p->next;
        free(q);
    }

    free(*matching);
    *matching = NULL;
}

static void
initialize_matching(struct lafe_matching **matching)
{
    *matching = calloc(sizeof(**matching), 1);
    if (*matching == NULL)
        lafe_errc(1, errno, "No memory");
}

int
lafe_unmatched_inclusions(struct lafe_matching *matching)
{

    if (matching == NULL)
        return (0);
    return (matching->inclusions_unmatched_count);
}

int
lafe_unmatched_inclusions_warn(struct lafe_matching *matching, const char *msg)
{
    struct match *p;

    if (matching == NULL)
        return (0);

    for (p = matching->inclusions; p != NULL; p = p->next) {
        if (p->matches == 0)
            lafe_warnc(0, "%s: %s", p->pattern, msg);
    }

    return (matching->inclusions_unmatched_count);
}

--- NEW FILE: lafe_platform.h ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $FreeBSD: src/usr.bin/cpio/cpio_platform.h,v 1.2 2008/12/06 07:15:42 kientzle Exp $
 */

/*
 * This header is the first thing included in any of the libarchive_fe
 * source files.  As far as possible, platform-specific issues should
 * be dealt with here and not within individual source files.
 */

#ifndef LAFE_PLATFORM_H_INCLUDED
#define LAFE_PLATFORM_H_INCLUDED

#if defined(PLATFORM_CONFIG_H)
/* Use hand-built config.h in environments that need it. */
#include PLATFORM_CONFIG_H
#else
/* Read config.h or die trying. */
#include "config.h"
#endif

/* No non-FreeBSD platform will have __FBSDID, so just define it here. */
#ifdef __FreeBSD__
#include <sys/cdefs.h>  /* For __FBSDID */
#elif !defined(__FBSDID)
/* Just leaving this macro replacement empty leads to a dangling semicolon. */
#define __FBSDID(a)     struct _undefined_hack
#endif

#endif



More information about the Cmake-commits mailing list