Import plist-utils as pkgtools/plist-utils

The plist-utils suite aims to facilitate management of PLIST entries.
It handles PLIST options and variables, and is especially useful for
keeping PLISTs of packages with quickly changing file-lists, such
as those closely tracking upstream development branch, up to date.

Import approved by <wiz>.
This commit is contained in:
kamil 2016-10-01 18:37:15 +00:00
parent af802aac94
commit 784c9830b5
15 changed files with 1012 additions and 0 deletions

View file

@ -0,0 +1,4 @@
The plist-utils suite aims to facilitate management of PLIST entries.
It handles PLIST options and variables, and is especially useful for
keeping PLISTs of packages with quickly changing file-lists, such
as those closely tracking upstream development branch, up to date.

View file

@ -0,0 +1,21 @@
# $NetBSD: Makefile,v 1.1 2016/10/01 18:37:15 kamil Exp $
#
PKGNAME= plist-utils-20160731
CATEGORIES= pkgtools
MAINTAINER= pkgsrc-users@NetBSD.org
#HOMEPAGE=
COMMENT= Utility to facilitate management of PLIST files
LICENSE= 2-clause-bsd
USE_BSD_MAKEFILE= yes
USE_TOOLS= nroff
INSTALLATION_DIRS+= bin ${PKGMANDIR}/man1
PKGSRC_LOCKTYPE= none # avoid "bootstrapping problem"
do-extract:
${CP} -R ${FILESDIR} ${WRKSRC}
.include "../../mk/bsd.pkg.mk"

View file

@ -0,0 +1,7 @@
@comment $NetBSD: PLIST,v 1.1 2016/10/01 18:37:15 kamil Exp $
bin/plist-add
bin/plist-del
bin/plist-sort
man/man1/plist-add.1
man/man1/plist-del.1
man/man1/plist-sort.1

View file

@ -0,0 +1,8 @@
1. Recognize ${KEY} and replace in keys with VALUE
Spawn a command like:
make show-var VARNAME=KEY
And get the KEY value
2. Port to !NetBSD platforms with libnbcompat
3. Use popular precomputed ${KEYS} used in PLISTs like ${PKGBASE}

View file

@ -0,0 +1,14 @@
# $NetBSD: Makefile,v 1.1 2016/10/01 18:37:15 kamil Exp $
PROGS= plist-sort plist-add plist-del
SRCS.plist-sort= plist_getline.c plist_tree.c sort.c
MAN.plist-sort= plist-sort.1
SRCS.plist-add= plist_getline.c plist_tree.c add.c
MAN.plist-add= plist-add.1
SRCS.plist-del= plist_getline.c plist_tree.c del.c
MAN.plist-del= plist-del.1
.include <bsd.prog.mk>

View file

@ -0,0 +1,116 @@
/* $NetBSD: add.c,v 1.1 2016/10/01 18:37:15 kamil Exp $ */
/*-
* Copyright (c) 2016 The NetBSD Foundation, Inc.
* 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``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
* COPYRIGHT HOLDERS OR CONTRIBUTORS 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 <sys/cdefs.h>
__RCSID("$NetBSD: add.c,v 1.1 2016/10/01 18:37:15 kamil Exp $");
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "plist_getline.h"
#include "plist_tree.h"
int
main(int argc, char **argv)
{
int ch;
int iflag = 0;
char *buffer;
FILE *stream;
char *firstline;
int i;
setprogname(argv[0]);
while((ch = getopt(argc, argv, "i")) != -1) {
switch (ch) {
case 'i':
iflag = 1;
break;
default:
errx(EXIT_FAILURE, "Invalid parameter specified");
/* NOTREACHED */
}
}
argc -= optind;
argv += optind;
if (argc < 2)
errx(EXIT_FAILURE, "Missing arguments");
plist_tree_init();
/* No files specified - read from a file */
stream = fopen(argv[0], "r");
if (!stream) {
err(EXIT_FAILURE, "fopen");
}
/* Read entries and put into tree */
/* The first line is special */
if ((buffer = plist_getline(stream)) != NULL) {
firstline = buffer;
}
while ((buffer = plist_getline(stream)) != NULL) {
plist_tree_insert(buffer);
free(buffer);
}
/* Add entries from command line */
for (i = 1; i < argc; i++) {
plist_tree_insert(argv[i]);
}
/* Prepare for write */
if (iflag > 0) { /* If there is in-place mode, reopen the file */
/* Truncate file to 0 */
stream = freopen(argv[0], "w", stream);
if (!stream)
err(EXIT_FAILURE, "open");
/* Is this needed? */
rewind(stream);
} else { /* Set stream to stdout */
stream = stdout;
}
fprintf(stream, "%s\n", firstline);
plist_tree_dump(stream);
return EXIT_SUCCESS;
}

View file

@ -0,0 +1,116 @@
/* $NetBSD: del.c,v 1.1 2016/10/01 18:37:15 kamil Exp $ */
/*-
* Copyright (c) 2016 The NetBSD Foundation, Inc.
* 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``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
* COPYRIGHT HOLDERS OR CONTRIBUTORS 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 <sys/cdefs.h>
__RCSID("$NetBSD: del.c,v 1.1 2016/10/01 18:37:15 kamil Exp $");
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "plist_getline.h"
#include "plist_tree.h"
int
main(int argc, char **argv)
{
int ch;
int iflag = 0;
char *buffer;
FILE *stream;
char *firstline;
int i;
setprogname(argv[0]);
while((ch = getopt(argc, argv, "i")) != -1) {
switch (ch) {
case 'i':
iflag = 1;
break;
default:
errx(EXIT_FAILURE, "Invalid parameter specified");
/* NOTREACHED */
}
}
argc -= optind;
argv += optind;
if (argc < 2)
errx(EXIT_FAILURE, "Missing arguments");
plist_tree_init();
/* No files specified - read from a file */
stream = fopen(argv[0], "r");
if (!stream) {
err(EXIT_FAILURE, "fopen");
}
/* Read entries and put into tree */
/* The first line is special */
if ((buffer = plist_getline(stream)) != NULL) {
firstline = buffer;
}
while ((buffer = plist_getline(stream)) != NULL) {
plist_tree_insert(buffer);
free(buffer);
}
/* Add entries from command line */
for (i = 1; i < argc; i++) {
plist_tree_remove(argv[i]);
}
/* Prepare for write */
if (iflag > 0) { /* If there is in-place mode, reopen the file */
/* Truncate file to 0 */
stream = freopen(argv[0], "w", stream);
if (!stream)
err(EXIT_FAILURE, "open");
/* Is this needed? */
rewind(stream);
} else { /* Set stream to stdout */
stream = stdout;
}
fprintf(stream, "%s\n", firstline);
plist_tree_dump(stream);
return EXIT_SUCCESS;
}

View file

@ -0,0 +1,68 @@
.\" $NetBSD: plist-add.1,v 1.1 2016/10/01 18:37:15 kamil Exp $
.\"
.\" Copyright (c) 2016 The NetBSD Foundation, Inc.
.\" 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
.\" ``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
.\" COPYRIGHT HOLDERS OR CONTRIBUTORS 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.
.\"
.Dd September 18, 2016
.Dt PLIST-ADD 1
.Os
.Sh NAME
.Nm plist-add
.Sh SYNOPSIS
.Nm
.Op Fl i
.Ar PLIST
.Ar file
.Op Ar
.Sh DESCRIPTION
The
.Nm
utility adds entries regarding
.Ar file
to
.Ar PLIST .
Afterwards, it sorts the output.
If
.Fl i
is given,
.Nm
modifies the
.Ar PLIST
in place.
Otherwise it outputs to standard output.
.Sh EXIT STATUS
.Ex -std plist-add
.Sh HISTORY
The
.Nm
utility appeared in pkgsrc-2016Q4.
.Sh AUTHORS
.An -nosplit
The
.Nm
utility was written by
.An Kamil Rytarowski .

View file

@ -0,0 +1,67 @@
.\" $NetBSD: plist-del.1,v 1.1 2016/10/01 18:37:15 kamil Exp $
.\"
.\" Copyright (c) 2016 The NetBSD Foundation, Inc.
.\" 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
.\" ``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
.\" COPYRIGHT HOLDERS OR CONTRIBUTORS 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.
.\"
.Dd September 18, 2016
.Dt PLIST-DEL 1
.Os
.Sh NAME
.Nm plist-del
.Sh SYNOPSIS
.Nm
.Op Fl i
.Ar file
.Op Ar
.Sh DESCRIPTION
The
.Nm
utility removes entries regarding
.Ar file
from the
.Ar PLIST .
Afterwards, it sorts the output.
If
.Fl i
is given,
.Nm
modifies the
.Ar PLIST
in place.
Otherwise it outputs to standard output.
.Sh EXIT STATUS
.Ex -std plist-del
.Sh HISTORY
The
.Nm
utility appeared in pkgsrc-2016Q4.
.Sh AUTHORS
.An -nosplit
The
.Nm
utility was written by
.An Kamil Rytarowski .

View file

@ -0,0 +1,64 @@
.\" $NetBSD: plist-sort.1,v 1.1 2016/10/01 18:37:15 kamil Exp $
.\"
.\" Copyright (c) 2016 The NetBSD Foundation, Inc.
.\" 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
.\" ``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
.\" COPYRIGHT HOLDERS OR CONTRIBUTORS 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.
.\"
.Dd September 18, 2016
.Dt PLIST-SORT 1
.Os
.Sh NAME
.Nm plist-sort
.Sh SYNOPSIS
.Nm
.Op Fl i
.Op Ar file
.Sh DESCRIPTION
The
.Nm
utility sorts entries in
.Ar file
as if all PLIST variables and options were already substituted.
If
.Fl i
is given,
.Nm
modifies the
.Ar PLIST
in place.
Otherwise it outputs to standard output.
.Sh EXIT STATUS
.Ex -std plist-sort
.Sh HISTORY
The
.Nm
utility appeared in pkgsrc-2016Q4.
.Sh AUTHORS
.An -nosplit
The
.Nm
utility was written by
.An Kamil Rytarowski .

View file

@ -0,0 +1,80 @@
/* $NetBSD: plist_getline.c,v 1.1 2016/10/01 18:37:15 kamil Exp $ */
/*-
* Copyright (c) 2016 The NetBSD Foundation, Inc.
* 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``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
* COPYRIGHT HOLDERS OR CONTRIBUTORS 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 <sys/cdefs.h>
__RCSID("$NetBSD: plist_getline.c,v 1.1 2016/10/01 18:37:15 kamil Exp $");
#include <assert.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static size_t lineno;
char *
plist_getline(FILE *stream)
{
char *buf, *lbuf;
size_t len;
assert(stream);
repeat:
if ((buf = fgetln(stream, &len)) != NULL) {
++lineno;
if (len == 0) {
warnx("Empty line at %d -- skipped", lineno);
goto repeat;
}
/* Handle proper line with the \n ending */
if (buf[len - 1] == '\n') {
buf[len - 1] = '\0';
lbuf = strndup(buf, len);
if (lbuf == NULL)
err(EXIT_FAILURE, "strndup");
} else { /* Handle line without the \n ending */
lbuf = strndup(buf, len + 1);
if (lbuf == NULL)
err(EXIT_FAILURE, "strndup");
lbuf[len] = '\0';
}
return lbuf;
}
if (ferror(stream))
err(EXIT_FAILURE, "ferror");
assert(feof(stream));
return NULL;
}

View file

@ -0,0 +1,40 @@
/* $NetBSD: plist_getline.h,v 1.1 2016/10/01 18:37:15 kamil Exp $ */
/*-
* Copyright (c) 2016 The NetBSD Foundation, Inc.
* 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``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
* COPYRIGHT HOLDERS OR CONTRIBUTORS 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 __PLIST_UTILS_PLIST_GETLINE_H__
#define __PLIST_UTILS_PLIST_GETLINE_H__
#include <stdio.h>
char *
plist_getline(FILE *stream);
#endif /* __PLIST_UTILS_PLIST_GETLINE_H__ */

View file

@ -0,0 +1,244 @@
/* $NetBSD: plist_tree.c,v 1.1 2016/10/01 18:37:15 kamil Exp $ */
/*-
* Copyright (c) 2016 The NetBSD Foundation, Inc.
* 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``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
* COPYRIGHT HOLDERS OR CONTRIBUTORS 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 <sys/cdefs.h>
__RCSID("$NetBSD: plist_tree.c,v 1.1 2016/10/01 18:37:15 kamil Exp $");
#include <sys/param.h>
#include <sys/types.h>
#include <sys/rbtree.h>
#include <assert.h>
#include <regex.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>
struct plist_pair_entry {
char *first; /* key */
char *second; /* value */
rb_node_t pair_node;
};
static int
plist_compare_key(void *ctx, const void *n1, const void *keyp)
{
const char *a1;
const char *a2;
assert(n1);
assert(keyp);
assert(((const char *)keyp)[0]);
assert(((struct plist_pair_entry*)n1)->first);
assert(((struct plist_pair_entry*)n1)->first[0]);
a1 = ((struct plist_pair_entry*)n1)->first;
a2 = (const char *)keyp;
return strcmp(a1, a2);
}
static int
plist_compare_nodes(void *ctx, const void *n1, const void *n2)
{
const char *key2;
assert(n1);
assert(n2);
assert(((struct plist_pair_entry*)n2)->first);
assert(((struct plist_pair_entry*)n2)->first[0]);
key2 = ((struct plist_pair_entry*)n2)->first;
return plist_compare_key(ctx, n1, key2);
}
static const rb_tree_ops_t plist_tree_ops = {
.rbto_compare_nodes = plist_compare_nodes,
.rbto_compare_key = plist_compare_key,
.rbto_node_offset = offsetof(struct plist_pair_entry, pair_node),
.rbto_context = NULL,
};
/* plist_tree_singleton */
static struct plist_tree_type {
rb_tree_t plist_tree;
rb_tree_t plist_vars_tree;
int initialized;
regex_t plist_regex_options;
} plist_tree_singleton = {
.initialized = 0
};
void
plist_tree_init(void)
{
int ret;
assert(plist_tree_singleton.initialized == 0);
rb_tree_init(&plist_tree_singleton.plist_tree, &plist_tree_ops);
rb_tree_init(&plist_tree_singleton.plist_vars_tree, &plist_tree_ops);
#define MAX_ERROR_MSG 0x1000
#define REGEX_STRING_PLIST "\\${PLIST.[^}]*}"
if ((ret = regcomp(&plist_tree_singleton.plist_regex_options,
REGEX_STRING_PLIST, REG_EXTENDED)) != 0) {
char error_message[MAX_ERROR_MSG];
regerror(ret, &plist_tree_singleton.plist_regex_options,
error_message, MAX_ERROR_MSG);
errx(EXIT_FAILURE, "Regex error compiling '%s': %s\n",
REGEX_STRING_PLIST, error_message);
}
plist_tree_singleton.initialized = 1;
}
char *
get_key(const char *entry)
{
char *copy;
size_t n = 0;
char *s;
regmatch_t rm[10];
int ret;
size_t i;
assert(entry);
/* 1. Strip all ${PLIST.option}-like strings */
ret = regexec(&plist_tree_singleton.plist_regex_options, entry,
__arraycount(rm), rm, 0);
if (!ret) { /* Something found! */
/* Set pointer just after the matched string */
for(i = 0; i < __arraycount(rm); i++) {
if (rm[i].rm_so == -1)
break;
n = rm[i].rm_eo;
}
}
/* Set copy that now contains an entry with removed '${PLIST.*}' */
copy = strdup(entry + n);
if (copy == NULL)
err(EXIT_FAILURE, "strdup");
return copy;
}
int
plist_tree_insert(const char *entry)
{
struct plist_pair_entry *pair;
struct plist_pair_entry *opair;
assert(plist_tree_singleton.initialized == 1);
assert(entry);
assert(entry[0]);
pair = malloc(sizeof(*pair));
if (pair == NULL)
err(EXIT_FAILURE, "malloc");
pair->first = get_key(entry);
if (pair->first == NULL)
err(EXIT_FAILURE, "malloc");
pair->second = strndup(entry, MAXPATHLEN * 2);
if (pair->second == NULL)
err(EXIT_FAILURE, "malloc");
opair = rb_tree_insert_node(&plist_tree_singleton.plist_tree, pair);
if (opair != pair) {
warnx("Duplicate entry detected key='%s' value='%s' "
"(okey='%s' ovalue='%s') -- skipping",
pair->first, pair->second, opair->first, opair->second);
free(pair->first);
free(pair->second);
free(pair);
return -1;
}
return 0;
}
int
plist_tree_remove(const char *entry)
{
struct plist_pair_entry *pair;
assert(plist_tree_singleton.initialized == 1);
assert(entry);
pair = rb_tree_find_node(&plist_tree_singleton.plist_tree, entry);
if (pair == NULL) {
warnx("Cannot remove entry='%s' -- not found", entry);
return -1;
}
assert(pair->first);
assert(pair->first[0]);
assert(pair->second);
assert(pair->second[0]);
rb_tree_remove_node(&plist_tree_singleton.plist_tree, pair);
free(pair->first);
free(pair->second);
free(pair);
return 0;
}
int
plist_tree_dump(FILE *stream)
{
struct plist_pair_entry *pair;
assert(stream);
assert(plist_tree_singleton.initialized == 1);
RB_TREE_FOREACH(pair, &plist_tree_singleton.plist_tree) {
assert(pair);
assert(pair->first);
assert(pair->first[0]);
assert(pair->second);
assert(pair->second[0]);
fprintf(stream, "%s\n", pair->second);
}
return 0;
}

View file

@ -0,0 +1,49 @@
/* $NetBSD: plist_tree.h,v 1.1 2016/10/01 18:37:15 kamil Exp $ */
/*-
* Copyright (c) 2016 The NetBSD Foundation, Inc.
* 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``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
* COPYRIGHT HOLDERS OR CONTRIBUTORS 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 __PLIST_UTILS_PLIST_TREE_H__
#define __PLIST_UTILS_PLIST_TREE_H__
#include <stdio.h>
void
plist_tree_init(void);
int
plist_tree_insert(const char *entry);
int
plist_tree_remove(const char *entry);
int
plist_tree_dump(FILE *stream);
#endif /* __PLIST_UTILS_PLIST_TREE_H__ */

View file

@ -0,0 +1,114 @@
/* $NetBSD: sort.c,v 1.1 2016/10/01 18:37:15 kamil Exp $ */
/*-
* Copyright (c) 2016 The NetBSD Foundation, Inc.
* 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``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
* COPYRIGHT HOLDERS OR CONTRIBUTORS 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 <sys/cdefs.h>
__RCSID("$NetBSD: sort.c,v 1.1 2016/10/01 18:37:15 kamil Exp $");
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "plist_getline.h"
#include "plist_tree.h"
int
main(int argc, char **argv)
{
int ch;
int iflag = 0;
char *buffer;
FILE *stream;
char *firstline;
setprogname(argv[0]);
while((ch = getopt(argc, argv, "i")) != -1) {
switch (ch) {
case 'i':
iflag = 1;
break;
default:
errx(EXIT_FAILURE, "Invalid parameter specified");
/* NOTREACHED */
}
}
argc -= optind;
argv += optind;
if (iflag > 0 && argc < 0)
errx(EXIT_FAILURE, "Missing file-name for the in-place option");
plist_tree_init();
/* No files specified - read from stdin */
if (argc == 0)
stream = stdin;
else { /* Alternatively read from the given file */
stream = fopen(argv[0], "r");
if (!stream) {
err(EXIT_FAILURE, "fopen");
}
}
/* Read entries and put into tree */
/* The first line is special */
if ((buffer = plist_getline(stream)) != NULL) {
firstline = buffer;
}
while ((buffer = plist_getline(stream)) != NULL) {
plist_tree_insert(buffer);
free(buffer);
}
/* Prepare for write */
if (iflag > 0) { /* If there is in-place mode, reopen the file */
/* Truncate file to 0 */
stream = freopen(argv[0], "w", stream);
if (!stream)
err(EXIT_FAILURE, "open");
/* Is this needed? */
rewind(stream);
} else { /* Set stream to stdout */
stream = stdout;
}
fprintf(stream, "%s\n", firstline);
plist_tree_dump(stream);
return EXIT_SUCCESS;
}