Permalink
Browse files

From Roman Neuhauser: Rework textual options handling.

   * New functions archive_{read,write}_set_{format,filter}_option accept
     three strings: module name, option name, value.
     This is a better match for C clients of the library, who want
     to set one option at a time anyway for better error handling.
   * archive_{read,write}_set_options still accept a single string
     with possibly multiple options, but are now much simpler internally
     because they build on the above.
   * New tests for all of the above.
   * Update a lot of tests to give good coverage of the new functions.

SVN-Revision: 3026
  • Loading branch information...
1 parent 76949fa commit 11e7a909f561bc62272d6c512bfcf1f599036fcb @kientzle kientzle committed Mar 18, 2011
Showing with 1,407 additions and 709 deletions.
  1. +12 −0 Makefile.am
  2. +4 −0 libarchive/CMakeLists.txt
  3. +29 −24 libarchive/archive.h
  4. +164 −0 libarchive/archive_options.c
  5. +47 −0 libarchive/archive_options_private.h
  6. +0 −3 libarchive/archive_private.h
  7. +2 −52 libarchive/archive_read.3
  8. +0 −112 libarchive/archive_read.c
  9. +199 −0 libarchive/archive_read_set_options.3
  10. +148 −0 libarchive/archive_read_set_options.c
  11. +0 −192 libarchive/archive_util.c
  12. +1 −2 libarchive/archive_write_set_format_iso9660.c
  13. +1 −1 libarchive/archive_write_set_format_mtree.c
  14. +1 −1 libarchive/archive_write_set_format_xar.c
  15. +3 −3 libarchive/archive_write_set_format_zip.c
  16. +118 −19 libarchive/archive_write_set_options.3
  17. +64 −242 libarchive/archive_write_set_options.c
  18. +8 −0 libarchive/test/CMakeLists.txt
  19. +55 −0 libarchive/test/test_archive_read_set_filter_option.c
  20. +67 −0 libarchive/test/test_archive_read_set_format_option.c
  21. +69 −0 libarchive/test/test_archive_read_set_option.c
  22. +79 −0 libarchive/test/test_archive_read_set_options.c
  23. +55 −0 libarchive/test/test_archive_write_set_filter_option.c
  24. +67 −0 libarchive/test/test_archive_write_set_format_option.c
  25. +69 −0 libarchive/test/test_archive_write_set_option.c
  26. +79 −0 libarchive/test/test_archive_write_set_options.c
  27. +1 −1 libarchive/test/test_read_format_isojoliet_bz2.c
  28. +1 −1 libarchive/test/test_read_format_isojoliet_versioned.c
  29. +8 −8 libarchive/test/test_write_compress_bzip2.c
  30. +12 −8 libarchive/test/test_write_compress_gzip.c
  31. +8 −8 libarchive/test/test_write_compress_lzip.c
  32. +8 −8 libarchive/test/test_write_compress_lzma.c
  33. +8 −8 libarchive/test/test_write_compress_xz.c
  34. +4 −2 libarchive/test/test_write_format_iso9660.c
  35. +3 −3 libarchive/test/test_write_format_iso9660_boot.c
  36. +5 −3 libarchive/test/test_write_format_iso9660_filename.c
  37. +2 −2 libarchive/test/test_write_format_iso9660_zisofs.c
  38. +2 −2 libarchive/test/test_write_format_mtree.c
  39. +3 −3 libarchive/test/test_write_format_zip.c
  40. +1 −1 libarchive/test/test_write_format_zip_no_compression.c
View
@@ -100,6 +100,8 @@ libarchive_la_SOURCES= \
libarchive/archive_entry_strmode.c \
libarchive/archive_entry_xattr.c \
libarchive/archive_hash.h \
+ libarchive/archive_options.c \
+ libarchive/archive_options_private.h \
libarchive/archive_platform.h \
libarchive/archive_private.h \
libarchive/archive_rb.c \
@@ -117,6 +119,7 @@ libarchive_la_SOURCES= \
libarchive/archive_read_open_filename.c \
libarchive/archive_read_open_memory.c \
libarchive/archive_read_private.h \
+ libarchive/archive_read_set_options.c \
libarchive/archive_read_support_compression_all.c \
libarchive/archive_read_support_compression_bzip2.c \
libarchive/archive_read_support_compression_compress.c \
@@ -199,6 +202,7 @@ libarchive_man_MANS= \
libarchive/archive_entry_time.3 \
libarchive/archive_read.3 \
libarchive/archive_read_disk.3 \
+ libarchive/archive_read_set_options.3 \
libarchive/archive_util.3 \
libarchive/archive_write.3 \
libarchive/archive_write_disk.3 \
@@ -244,6 +248,14 @@ libarchive_test_SOURCES= \
libarchive/test/test_archive_read_close_twice_open_filename.c \
libarchive/test/test_archive_read_next_header_empty.c \
libarchive/test/test_archive_set_error.c \
+ libarchive/test/test_archive_read_set_filter_option.c \
+ libarchive/test/test_archive_read_set_format_option.c \
+ libarchive/test/test_archive_read_set_option.c \
+ libarchive/test/test_archive_read_set_options.c \
+ libarchive/test/test_archive_write_set_filter_option.c \
+ libarchive/test/test_archive_write_set_format_option.c \
+ libarchive/test/test_archive_write_set_option.c \
+ libarchive/test/test_archive_write_set_options.c \
libarchive/test/test_bad_fd.c \
libarchive/test/test_compat_bzip2.c \
libarchive/test/test_compat_cpio.c \
@@ -26,6 +26,8 @@ SET(libarchive_SOURCES
archive_entry_strmode.c
archive_entry_xattr.c
archive_hash.h
+ archive_options.c
+ archive_options_private.h
archive_platform.h
archive_private.h
archive_rb.c
@@ -43,6 +45,7 @@ SET(libarchive_SOURCES
archive_read_open_filename.c
archive_read_open_memory.c
archive_read_private.h
+ archive_read_set_options.c
archive_read_support_compression_all.c
archive_read_support_compression_bzip2.c
archive_read_support_compression_compress.c
@@ -113,6 +116,7 @@ SET(libarchive_MANS
archive_entry_time.3
archive_read.3
archive_read_disk.3
+ archive_read_set_options.3
archive_util.3
archive_write.3
archive_write_disk.3
View
@@ -439,15 +439,21 @@ __LA_DECL int archive_read_data_into_fd(struct archive *, int fd);
/*
* Set read options.
*/
-/* Apply option string to the format only. */
-__LA_DECL int archive_read_set_format_options(struct archive *_a,
- const char *s);
-/* Apply option string to the filter only. */
-__LA_DECL int archive_read_set_filter_options(struct archive *_a,
- const char *s);
+/* Apply option to the format only. */
+__LA_DECL int archive_read_set_format_option(struct archive *_a,
+ const char *m, const char *o,
+ const char *v);
+/* Apply option to the filter only. */
+__LA_DECL int archive_read_set_filter_option(struct archive *_a,
+ const char *m, const char *o,
+ const char *v);
+/* Apply option to both the format and the filter. */
+__LA_DECL int archive_read_set_option(struct archive *_a,
+ const char *m, const char *o,
+ const char *v);
/* Apply option string to both the format and the filter. */
__LA_DECL int archive_read_set_options(struct archive *_a,
- const char *s);
+ const char *opts);
/*-
* Convenience function to recreate the current entry (whose header
@@ -643,24 +649,23 @@ __LA_DECL int archive_write_finish(struct archive *);
#endif
/*
- * Set write options. Note that there's really no reason to use
- * anything but archive_write_set_options(). The others should probably
- * all be deprecated and eventually removed.
+ * Set write options.
*/
-/* Apply option string to both the format and all filters. */
-__LA_DECL int archive_write_set_options(struct archive *_a,
- const char *s);
-/* Apply option string to the format only. */
-__LA_DECL int archive_write_set_format_options(struct archive *_a,
- const char *s);
-/* Apply option string to all matching filters. */
-__LA_DECL int archive_write_set_filter_options(struct archive *_a,
- const char *s);
-#if ARCHIVE_VERSION_NUMBER < 4000000
-/* Deprecated synonym for archive_write_set_filter_options. */
-__LA_DECL int archive_write_set_compressor_options(struct archive *_a,
- const char *s);
-#endif
+/* Apply option to the format only. */
+__LA_DECL int archive_write_set_format_option(struct archive *_a,
+ const char *m, const char *o,
+ const char *v);
+/* Apply option to the filter only. */
+__LA_DECL int archive_write_set_filter_option(struct archive *_a,
+ const char *m, const char *o,
+ const char *v);
+/* Apply option to both the format and the filter. */
+__LA_DECL int archive_write_set_option(struct archive *_a,
+ const char *m, const char *o,
+ const char *v);
+/* Apply option string to both the format and the filter. */
+__LA_DECL int archive_write_set_options(struct archive *_a,
+ const char *opts);
/*-
* ARCHIVE_WRITE_DISK API
@@ -0,0 +1,164 @@
+/*-
+ * Copyright (c) 2011 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 "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#include "archive_options_private.h"
+
+static const char *
+parse_option(const char **str,
+ const char **mod, const char **opt, const char **val);
+
+int
+_archive_set_option(struct archive *a,
+ const char *m, const char *o, const char *v,
+ int magic, const char *fn, option_handler use_option)
+{
+ const char *mp, *op, *vp;
+
+ archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
+
+ mp = m != NULL && m[0] == '\0' ? NULL : m;
+ op = o != NULL && o[0] == '\0' ? NULL : o;
+ vp = v != NULL && v[0] == '\0' ? NULL : v;
+
+ if (op == NULL && vp == NULL)
+ return (ARCHIVE_OK);
+ if (op == NULL)
+ return (ARCHIVE_FAILED);
+
+ return use_option(a, mp, op, vp);
+}
+
+int
+_archive_set_either_option(struct archive *a, const char *m, const char *o, const char *v,
+ option_handler use_format_option, option_handler use_filter_option)
+{
+ int r1, r2;
+
+ if (o == NULL && v == NULL)
+ return (ARCHIVE_OK);
+ if (o == NULL)
+ return (ARCHIVE_FAILED);
+
+ r1 = use_format_option(a, m, o, v);
+ if (r1 == ARCHIVE_FATAL)
+ return (ARCHIVE_FATAL);
+
+ r2 = use_filter_option(a, m, o, v);
+ if (r2 == ARCHIVE_FATAL)
+ return (ARCHIVE_FATAL);
+
+ return r1 > r2 ? r1 : r2;
+}
+
+int
+_archive_set_options(struct archive *a, const char *options,
+ int magic, const char *fn, option_handler use_option)
+{
+ int allok = 1, anyok = 0, r;
+ char *data;
+ const char *s, *mod, *opt, *val;
+
+ archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
+
+ if (options == NULL || options[0] == '\0')
+ return ARCHIVE_OK;
+
+ data = (char *)malloc(strlen(options) + 1);
+ strcpy(data, options);
+ s = (const char *)data;
+
+ do {
+ mod = opt = val = NULL;
+
+ parse_option(&s, &mod, &opt, &val);
+
+ r = use_option(a, mod, opt, val);
+ if (r == ARCHIVE_FATAL) {
+ free(data);
+ return (ARCHIVE_FATAL);
+ }
+ if (r == ARCHIVE_OK)
+ anyok = 1;
+ else
+ allok = 0;
+ } while (s != NULL);
+
+ free(data);
+ return allok ? ARCHIVE_OK : anyok ? ARCHIVE_WARN : ARCHIVE_FAILED;
+}
+
+static const char *
+parse_option(const char **s, const char **m, const char **o, const char **v)
+{
+ const char *end, *mod, *opt, *val;
+ char *p;
+
+ end = NULL;
+ mod = NULL;
+ opt = *s;
+ val = "1";
+
+ p = strchr(opt, ',');
+
+ if (p != NULL) {
+ *p = '\0';
+ end = ((const char *)p) + 1;
+ }
+
+ if (0 == strlen(opt)) {
+ *s = end;
+ *m = NULL;
+ *o = NULL;
+ *v = NULL;
+ return end;
+ }
+
+ p = strchr(opt, ':');
+ if (p != NULL) {
+ *p = '\0';
+ mod = opt;
+ opt = ++p;
+ }
+
+ p = strchr(opt, '=');
+ if (p != NULL) {
+ *p = '\0';
+ val = ++p;
+ } else if (opt[0] == '!') {
+ ++opt;
+ val = NULL;
+ }
+
+ *s = end;
+ *m = mod;
+ *o = opt;
+ *v = val;
+
+ return end;
+}
+
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2011 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 "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#include "archive_private.h"
+
+typedef int (*option_handler)(struct archive *a,
+ const char *mod, const char *opt, const char *val);
+
+int
+_archive_set_option(struct archive *a,
+ const char *mod, const char *opt, const char *val,
+ int magic, const char *fn, option_handler use_option);
+
+int
+_archive_set_options(struct archive *a, const char *options,
+ int magic, const char *fn, option_handler use_option);
+
+int
+_archive_set_either_option(struct archive *a,
+ const char *m, const char *o, const char *v,
+ option_handler use_format_option, option_handler use_filter_option);
+
@@ -139,9 +139,6 @@ int __archive_check_magic(struct archive *, unsigned int magic,
void __archive_errx(int retvalue, const char *msg) __LA_DEAD;
-int __archive_parse_options(const char *p, const char *fn,
- int keysize, char *key, int valsize, char *val);
-
int __archive_mktemp(const char *tmpdir);
int __archive_clean(struct archive *);
Oops, something went wrong.

0 comments on commit 11e7a90

Please sign in to comment.