Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package csvprintf for openSUSE:Factory checked in at 2021-02-26 21:59:27 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/csvprintf (Old) and /work/SRC/openSUSE:Factory/.csvprintf.new.2378 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "csvprintf" Fri Feb 26 21:59:27 2021 rev:5 rq:875174 version:1.1.0 Changes: -------- --- /work/SRC/openSUSE:Factory/csvprintf/csvprintf.changes 2018-08-02 15:00:56.604561081 +0200 +++ /work/SRC/openSUSE:Factory/.csvprintf.new.2378/csvprintf.changes 2021-02-26 21:59:29.815823217 +0100 @@ -1,0 +2,11 @@ +Thu Feb 25 16:09:55 UTC 2021 - Archie Cobbs <archie.co...@gmail.com> + +- Update to release 1.1.0 + - Added support for format strings containing column names + +------------------------------------------------------------------- +Thu Oct 17 17:02:27 UTC 2019 - Richard Brown <rbr...@suse.com> + +- Remove obsolete Groups tag (fate#326485) + +------------------------------------------------------------------- Old: ---- csvprintf-1.0.4.tar.gz New: ---- csvprintf-1.1.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ csvprintf.spec ++++++ --- /var/tmp/diff_new_pack.U2tFYQ/_old 2021-02-26 21:59:30.435823762 +0100 +++ /var/tmp/diff_new_pack.U2tFYQ/_new 2021-02-26 21:59:30.435823762 +0100 @@ -1,7 +1,7 @@ # # spec file for package csvprintf # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2021 SUSE LLC # Copyright 2010 Archie L. Cobbs <arc...@dellroad.org> # # All modifications and additions to the file contributed by third parties @@ -13,18 +13,18 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # Name: csvprintf -Version: 1.0.4 +Version: 1.1.0 Release: 0 Summary: Simple CSV file parser for the UNIX command line License: Apache-2.0 -Group: Productivity/Text/Utilities -Source: %{name}-%{version}.tar.gz -Url: http://csvprintf.googlecode.com/ +Group: Productivity/File utilities +Source: https://archie-public.s3.amazonaws.com/%{name}/%{name}-%{version}.tar.gz +URL: https://github.com/archiecobbs/csvprintf BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: gcc BuildRequires: make @@ -34,14 +34,14 @@ %description %{name} is a simple UNIX command line utility for parsing CSV files. -%{name} works just like the printf(1) command line utility. You -supply a printf(1) format string on the command line and each record -in the CSV file is formatted accordingly. Each format specifier in -the format string contains a column accessor to specify which CSV -column to use, so for example '%%3$d' would format the third column -as a decimal value. +%{name} works like the printf(1) command line utility: you supply a +printf(1) format string on the command line, and each row of the CSV file +is split into arguments and formatted accordingly. The format specifiers +in the format string contain numeric or symbolic column accessors to +specify which CSV column to format. -%{name} can also convert CSV files into XML documents and back. +%{name} can also convert CSV files into XML documents. The xml2csv +command converts XML documents so generated back into CSV files. %prep %setup -q ++++++ csvprintf-1.0.4.tar.gz -> csvprintf-1.1.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/csvprintf-1.0.4/CHANGES new/csvprintf-1.1.0/CHANGES --- old/csvprintf-1.0.4/CHANGES 2018-08-02 01:23:31.000000000 +0200 +++ new/csvprintf-1.1.0/CHANGES 2021-02-25 17:03:23.000000000 +0100 @@ -1,3 +1,7 @@ +Version 1.1.0 released February 25, 2021 + + - Added support for format strings containing column names + Version 1.0.4 released August 1, 2018 - Fixed "unexpected character" bug when line ends with QUOTE, CR diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/csvprintf-1.0.4/Makefile.in new/csvprintf-1.1.0/Makefile.in --- old/csvprintf-1.0.4/Makefile.in 2018-08-02 01:37:52.000000000 +0200 +++ new/csvprintf-1.1.0/Makefile.in 2021-02-25 17:04:13.000000000 +0100 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -674,7 +674,7 @@ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir @@ -700,7 +700,7 @@ @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir @@ -718,7 +718,7 @@ distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -728,7 +728,7 @@ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/csvprintf-1.0.4/aclocal.m4 new/csvprintf-1.1.0/aclocal.m4 --- old/csvprintf-1.0.4/aclocal.m4 2018-08-02 01:37:50.000000000 +0200 +++ new/csvprintf-1.1.0/aclocal.m4 2021-02-25 17:04:12.000000000 +0100 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15 -*- Autoconf -*- +# generated automatically by aclocal 1.15.1 -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002-2014 Free Software Foundation, Inc. +# Copyright (C) 2002-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -35,7 +35,7 @@ [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15], [], +m4_if([$1], [1.15.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15])dnl +[AM_AUTOMAKE_VERSION([1.15.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -110,7 +110,7 @@ # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -141,7 +141,7 @@ Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -332,7 +332,7 @@ # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -408,7 +408,7 @@ # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -605,7 +605,7 @@ done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -626,7 +626,7 @@ fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2014 Free Software Foundation, Inc. +# Copyright (C) 2003-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -647,7 +647,7 @@ # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -697,7 +697,7 @@ # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -738,7 +738,7 @@ # Obsolete and "removed" macros, that must however still report explicit # error messages when used, to smooth transition. # -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -765,7 +765,7 @@ # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -794,7 +794,7 @@ AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -841,7 +841,7 @@ # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -860,7 +860,7 @@ # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -941,7 +941,7 @@ rm -f conftest.file ]) -# Copyright (C) 2009-2014 Free Software Foundation, Inc. +# Copyright (C) 2009-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1001,7 +1001,7 @@ _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1029,7 +1029,7 @@ INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2014 Free Software Foundation, Inc. +# Copyright (C) 2006-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1048,7 +1048,7 @@ # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2014 Free Software Foundation, Inc. +# Copyright (C) 2004-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/csvprintf-1.0.4/config.h.in new/csvprintf-1.1.0/config.h.in --- old/csvprintf-1.0.4/config.h.in 2018-08-02 01:37:51.000000000 +0200 +++ new/csvprintf-1.1.0/config.h.in 2021-02-25 17:04:13.000000000 +0100 @@ -85,6 +85,9 @@ #undef _DARWIN_C_SOURCE /* GNU functions */ +#undef _DEFAULT_SOURCE + +/* GNU functions */ #undef _GNU_SOURCE /* XOpen functions */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/csvprintf-1.0.4/configure new/csvprintf-1.1.0/configure --- old/csvprintf-1.0.4/configure 2018-08-02 01:37:52.000000000 +0200 +++ new/csvprintf-1.1.0/configure 2021-02-25 17:04:14.000000000 +0100 @@ -1,7 +1,7 @@ #! /bin/sh # From configure.ac Id. # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for csvprintf - Simple CSV file parser for the UNIX command line 1.0.4. +# Generated by GNU Autoconf 2.69 for csvprintf - Simple CSV file parser for the UNIX command line 1.1.0. # # Report bugs to <https://github.com/archiecobbs/csvprintf>. # @@ -581,8 +581,8 @@ # Identity of this package. PACKAGE_NAME='csvprintf - Simple CSV file parser for the UNIX command line' PACKAGE_TARNAME='csvprintf' -PACKAGE_VERSION='1.0.4' -PACKAGE_STRING='csvprintf - Simple CSV file parser for the UNIX command line 1.0.4' +PACKAGE_VERSION='1.1.0' +PACKAGE_STRING='csvprintf - Simple CSV file parser for the UNIX command line 1.1.0' PACKAGE_BUGREPORT='https://github.com/archiecobbs/csvprintf' PACKAGE_URL='' @@ -1272,7 +1272,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures csvprintf - Simple CSV file parser for the UNIX command line 1.0.4 to adapt to many kinds of systems. +\`configure' configures csvprintf - Simple CSV file parser for the UNIX command line 1.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1338,7 +1338,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of csvprintf - Simple CSV file parser for the UNIX command line 1.0.4:";; + short | recursive ) echo "Configuration of csvprintf - Simple CSV file parser for the UNIX command line 1.1.0:";; esac cat <<\_ACEOF @@ -1432,7 +1432,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -csvprintf - Simple CSV file parser for the UNIX command line configure 1.0.4 +csvprintf - Simple CSV file parser for the UNIX command line configure 1.1.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1734,7 +1734,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by csvprintf - Simple CSV file parser for the UNIX command line $as_me 1.0.4, which was +It was created by csvprintf - Simple CSV file parser for the UNIX command line $as_me 1.1.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2597,7 +2597,7 @@ # Define the identity of the package. PACKAGE='csvprintf' - VERSION='1.0.4' + VERSION='1.1.0' cat >>confdefs.h <<_ACEOF @@ -2730,6 +2730,9 @@ # Compile flags for Linux +$as_echo "#define _DEFAULT_SOURCE 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h @@ -4909,7 +4912,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by csvprintf - Simple CSV file parser for the UNIX command line $as_me 1.0.4, which was +This file was extended by csvprintf - Simple CSV file parser for the UNIX command line $as_me 1.1.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4975,7 +4978,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -csvprintf - Simple CSV file parser for the UNIX command line config.status 1.0.4 +csvprintf - Simple CSV file parser for the UNIX command line config.status 1.1.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/csvprintf-1.0.4/configure.ac new/csvprintf-1.1.0/configure.ac --- old/csvprintf-1.0.4/configure.ac 2018-08-02 01:23:20.000000000 +0200 +++ new/csvprintf-1.1.0/configure.ac 2021-02-25 17:03:35.000000000 +0100 @@ -16,7 +16,7 @@ # under the License. # -AC_INIT([csvprintf - Simple CSV file parser for the UNIX command line], [1.0.4], [https://github.com/archiecobbs/csvprintf], [csvprintf]) +AC_INIT([csvprintf - Simple CSV file parser for the UNIX command line], [1.1.0], [https://github.com/archiecobbs/csvprintf], [csvprintf]) AC_CONFIG_AUX_DIR(scripts) AM_INIT_AUTOMAKE dnl AM_MAINTAINER_MODE @@ -29,6 +29,7 @@ AC_SUBST(CFLAGS) # Compile flags for Linux +AC_DEFINE(_DEFAULT_SOURCE, 1, GNU functions) AC_DEFINE(_GNU_SOURCE, 1, GNU functions) AC_DEFINE(_BSD_SOURCE, 1, BSD functions) AC_DEFINE(_XOPEN_SOURCE, 500, XOpen functions) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/csvprintf-1.0.4/csvprintf.1.in new/csvprintf-1.1.0/csvprintf.1.in --- old/csvprintf-1.0.4/csvprintf.1.in 2018-08-01 22:25:48.000000000 +0200 +++ new/csvprintf-1.1.0/csvprintf.1.in 2021-02-25 16:43:28.000000000 +0100 @@ -2,7 +2,7 @@ .\" .\" csvprintf - Simple CSV file parser for the UNIX command line .\" -.\" Copyright 2010 Archie L. Cobbs <arc...@dellroad.org> +.\" Copyright 2010 Archie L. Cobbs <archie.co...@gmail.com> .\" .\" Licensed under the Apache License, Version 2.0 (the "License"); you may .\" not use this file except in compliance with the License. You may obtain @@ -19,7 +19,7 @@ .Os .Sh NAME .Nm csvprintf -.Nd Simple CSV file parser for the UNIX command line +.Nd CSV file parser .Sh SYNOPSIS .Nm csvprintf .Bk -words @@ -43,7 +43,6 @@ .Nm csvprintf .Bk -words .Fl X -.Op Fl i .Op Fl q Ar char .Op Fl s Ar char .Op Fl f Ar file @@ -61,24 +60,37 @@ .Nm works like the .Xr printf 1 -command line utility. -You supply a +command line utility: you supply a .Xr printf 1 -format string on the command line and each record of the CSV file is formatted accordingly. -Each format specifier in the format string is required to start with a column accessor to specify which CSV column to use. +format string on the command line, and each row of the CSV file is split into arguments and formatted accordingly. +The format specifiers in the format string contain numeric or symbolic column accessors to specify which CSV column to format. .Pp -The column accessor is a sequence of decimal digits followed by the ``$'' character (the same accessor format supported by +A numeric column accessor is a sequence of decimal digits followed by the +.Pa $ +character (the same accessor format supported by .Xr printf 1 ) . So for example, -``%3$d'' +.Pa \(dq%3$d\(dq would format the third CSV column as a decimal value. -In addition, the ``%0$d'' specifier will print the number of columns in the record. +In addition, the +.Pa \(dq%0$d\(dq +specifier will print the number of columns in the record. +.Pp +When the +.Fl i +flag is given, the first row is assumed to contain column names and is not output. +This allows symbolic, instead of numeric, column accessors to be used. +A symbolic column accessor is the column name enclosed in curly braces. +.Pp +For example, if the first row is +.Pa FirstName,Lastname,IdNum +then the format string +.Pa \(dq%{IdNum}04d: %{LastName}s, %{FirstName}s\(dq +would be equivalent to the format string +.Pa \(dq%3$04d: %2$s, %1$s\(dq . .Pp -Under the hood, -.Nm -invokes the -.Xr printf 1 -executable on each CSV row it parses. +Specifying a column name that does not appear in the first row generates an error, +so the use of symbolic column accessors adds an extra consistency check. .Pp .Nm can also convert CSV files into XML documents. @@ -93,11 +105,13 @@ This option only affects XML mode. .It Fl f Read CSV input from the specified file. +.Pp By default (or if ``-'' is specified), .Nm reads from standard input. .It Fl i -Ignore the very first CSV record in the input (typically contains column names). +Assume the first CSV record contains column names. +Enable symbolic column accessors and omit that first record from the output. .It Fl q Specify an alternate CSV column quote character. The usual backslash escape sequences are accepted. @@ -138,6 +152,13 @@ .It Pa @pkgdatadir@/csv.xsl XSL transform that converts XML back into CSV format. .El +.Sh BUGS +.Pp +Under the hood, +.Nm +invokes the +.Xr printf 1 +executable on each CSV row it parses, which makes it relatively slow. .Sh SEE ALSO .Xr printf 1 , .Xr printf 3 . @@ -150,4 +171,4 @@ .%O http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm .Re .Sh AUTHOR -.An Archie L. Cobbs Aq arc...@dellroad.org +.An Archie L. Cobbs Aq archie.co...@gmail.com diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/csvprintf-1.0.4/gitrev.c new/csvprintf-1.1.0/gitrev.c --- old/csvprintf-1.0.4/gitrev.c 2018-08-02 01:38:03.000000000 +0200 +++ new/csvprintf-1.1.0/gitrev.c 2021-02-25 17:04:22.000000000 +0100 @@ -1 +1 @@ -const char *const csvprintf_version = "1.0.4"; +const char *const csvprintf_version = "1.1.0"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/csvprintf-1.0.4/main.c new/csvprintf-1.1.0/main.c --- old/csvprintf-1.0.4/main.c 2018-08-01 17:58:37.000000000 +0200 +++ new/csvprintf-1.1.0/main.c 2021-02-25 17:01:22.000000000 +0100 @@ -51,17 +51,20 @@ static int fsep = DEFAULT_FSEP_CHAR; static int parsechar(const char *str); -static int parsefmt(char *fmt, unsigned int **argsp); +static int parsefmt(char *fmt, const struct row *column_names, unsigned int **argsp); static int readcol(FILE *fp, struct row *row, int *linenum); static int readqcol(FILE *fp, struct col *col, int *linenum); static int readuqcol(FILE *fp, struct col *col, int *linenum); static int readch(FILE *fp, int collapse); +static void freerow(struct row *row); static void print_xml_tag_name(const char *tag, int linenum); static int decode_utf8(const char *const obuf, size_t olen, int *lenp, int linenum); static void convert_to_utf8(iconv_t icd, struct row *row, int linenum); static const char *escape_xml_char(int uchar); -static char *eatwidthprec(const char *fspec, const char *desc, char *s, int *nargs, unsigned int *args); -static char *eataccessor(const char *fspec, const char *desc, char *s, int *nargs, unsigned int *args); +static char *eatwidthprec(const char *fspec, const char *desc, const struct row *column_names, + char *s, int *nargs, unsigned int *args); +static char *eataccessor(const char *fspec, const char *desc, const struct row *column_names, + char *s, int *nargs, unsigned int *args); static void addcolumn(struct row *row, const struct col *col); static void addchar(struct col *col, int ch); static void trim(struct col *col); @@ -77,18 +80,19 @@ iconv_t icd = NULL; FILE *fp = NULL; struct row row; - struct row xml_tag_names; + struct row column_names; unsigned int *args = NULL; + int read_column_names = 0; + int first_row = 0; int nargs = 0; int file_done; int linenum; int xml = 0; // 1 = normal, 2 = use first row column names for XML tags - int skip = 0; int ch; // Initialize memset(&row, 0, sizeof(row)); - memset(&xml_tag_names, 0, sizeof(xml_tag_names)); + memset(&column_names, 0, sizeof(column_names)); // Parse command line while ((ch = getopt(argc, argv, "e:f:hiq:s:vxX")) != -1) { @@ -100,22 +104,22 @@ input = optarg; break; case 'i': - skip = 1; + read_column_names = 1; break; case 'x': xml = 1; break; case 'X': + read_column_names = 1; xml = 2; - skip = 1; break; case 'q': if ((quote = parsechar(optarg)) == -1) - errx(1, "invalid argument to `-%c'", ch); + errx(1, "invalid argument to \"-%c\"", ch); break; case 's': if ((fsep = parsechar(optarg)) == -1) - errx(1, "invalid argument to `-%c'", ch); + errx(1, "invalid argument to \"-%c\"", ch); break; case 'h': usage(); @@ -140,10 +144,13 @@ if (quote == fsep) err(1, "quote and field separators cannot be the same character"); - // Parse format string + // Get and (maybe) parse format string (non-XML only) if (!xml) { format = argv[0]; - nargs = parsefmt(format, &args); + + // Parse format string - unless we need to defer + if (!read_column_names) + nargs = parsefmt(format, NULL, &args); } // Open input @@ -162,6 +169,7 @@ // Read and parse input linenum = 1; + first_row = 1; for (file_done = 0; !file_done; ) { // Start parsing next row @@ -181,14 +189,18 @@ while (readcol(fp, &row, &linenum)) ; - // Skip first row? - if (skip) { - skip = 0; - if (xml == 2) { // copy and save first row for use as XML tag names + // Gather column names from first row, if configured + if (first_row && read_column_names) { + if (xml) convert_to_utf8(icd, &row, linenum); - memcpy(&xml_tag_names, &row, sizeof(row)); - memset(&row, 0, sizeof(row)); - } + memcpy(&column_names, &row, sizeof(row)); + memset(&row, 0, sizeof(row)); + + // If we had to defer parsing format string until we had the column names, do that now + if (!xml) + nargs = parsefmt(format, &column_names, &args); + + // Proceed goto next; } @@ -211,8 +223,8 @@ // Open XML tag printf(" <"); - if (col < xml_tag_names.num) - print_xml_tag_name(xml_tag_names.fields[col], linenum); + if (xml == 2 && col < column_names.num) + print_xml_tag_name(column_names.fields[col], linenum); else printf("col%d", col + 1); printf(">"); @@ -232,8 +244,8 @@ // Close XML tag printf("</"); - if (col < xml_tag_names.num) - print_xml_tag_name(xml_tag_names.fields[col], linenum); + if (xml == 2 && col < column_names.num) + print_xml_tag_name(column_names.fields[col], linenum); else printf("col%d", col + 1); printf(">\n"); @@ -284,10 +296,8 @@ next: // Free row memory - while (row.num > 0) - free(row.fields[--row.num]); - free(row.fields); - memset(&row, 0, sizeof(row)); + freerow(&row); + first_row = 0; } // XML closing @@ -299,6 +309,7 @@ // Clean up if (fp != stdin) fclose(fp); + freerow(&column_names); free(args); // Done @@ -519,7 +530,7 @@ return 1; if (isspace(ch)) continue; - errx(1, "line %d: unexpected character `%c'", *linenum, ch); + errx(1, "line %d: unexpected character \"%c\"", *linenum, ch); } if (escape) { if (ch == quote) @@ -633,7 +644,7 @@ } static int -parsefmt(char *fmt, unsigned int **argsp) +parsefmt(char *fmt, const struct row *column_names, unsigned int **argsp) { unsigned int *args; int nargs; @@ -655,14 +666,14 @@ char *const fspec = s; if (*s != '%' || *++s == '%') continue; - s = eataccessor(fspec, "format specification", s, &nargs, args); + s = eataccessor(fspec, "format specification", column_names, s, &nargs, args); while (*s != '\0' && strchr("#-+ 0", *s) != NULL) // eat up optional flags s++; - s = eatwidthprec(fspec, "field width for format specification", s, &nargs, args); + s = eatwidthprec(fspec, "field width for format specification", column_names, s, &nargs, args); if (*s == '.') - s = eatwidthprec(fspec, "precision for format specification", s + 1, &nargs, args); + s = eatwidthprec(fspec, "precision for format specification", column_names, s + 1, &nargs, args); if (*s == '\0') - errx(1, "truncated format specification starting at `%.20s...'", fspec); + errx(1, "truncated format specification starting at \"%.20s...\"", fspec); } // Done @@ -735,27 +746,56 @@ } static char * -eatwidthprec(const char *const fspec, const char *desc, char *s, int *nargs, unsigned int *args) +eatwidthprec(const char *const fspec, const char *desc, const struct row *column_names, char *s, int *nargs, unsigned int *args) { if (*s == '*') - return eataccessor(fspec, desc, s + 1, nargs, args); + return eataccessor(fspec, desc, column_names, s + 1, nargs, args); while (isdigit(*s)) // eat up numerical field width or precision s++; return s; } static char * -eataccessor(const char *const fspec, const char *desc, char *s, int *nargs, unsigned int *args) +eataccessor(const char *const fspec, const char *desc, const struct row *column_names, char *s, int *nargs, unsigned int *args) { char *const start = s; + const char *colname; + int namelen; + int argnum; + int i; - while (isdigit(*s)) - s++; - if (s == start || *s != '$') - errx(1, "missing required column accessor in %s starting at `%.20s...'", desc, fspec); - sscanf(start, "%u", args + *nargs); - (*nargs)++; - memmove(start, s + 1, strlen(s)); + if (*s == '{') { + if (column_names == NULL) + errx(1, "symbolic column accessors require \"-i\" flag in %s starting at \"%.20s...\"", desc, fspec); + colname = ++s; + while (*s != '}') { + if (*s++ == '\0') + errx(1, "malformed column accessor in %s starting at \"%.20s...\"", desc, fspec); + } + namelen = s++ - colname; + argnum = 0; + for (i = 0; i < column_names->num; i++) { + if (strncmp(colname, column_names->fields[i], namelen) == 0 && column_names->fields[i][namelen] == '\0') { + if (argnum != 0) { + errx(1, "ambiguous column name \"%.*s\" in symbolic column accessor in %s starting at \"%.20s...\"", + namelen, colname, desc, fspec); + } + argnum = i + 1; + } + } + if (argnum == 0) { + errx(1, "unknown column name \"%.*s\" in symbolic column accessor in %s starting at \"%.20s...\"", + namelen, colname, desc, fspec); + } + args[(*nargs)++] = argnum; + } else { + while (isdigit(*s)) + s++; + if (s == start || *s++ != '$') + errx(1, "missing required column accessor in %s starting at \"%.20s...\"", desc, fspec); + sscanf(start, "%u", &args[(*nargs)++]); + } + memmove(start, s, strlen(s) + 1); return start; } @@ -776,26 +816,34 @@ } static void +freerow(struct row *row) +{ + while (row->num > 0) + free(row->fields[--row->num]); + free(row->fields); + memset(row, 0, sizeof(*row)); +} + +static void usage(void) { fprintf(stderr, "Usage:\n"); - fprintf(stderr, " csvprintf [-i] [-q char] [-s char] [-f file] format\n"); - fprintf(stderr, " csvprintf [-i] [-q char] [-s char] [-f file] -x\n"); + fprintf(stderr, " csvprintf [options] format\n"); + fprintf(stderr, " csvprintf -x [options]\n"); + fprintf(stderr, " csvprintf -X [options]\n"); fprintf(stderr, " csvprintf -h\n"); fprintf(stderr, " csvprintf -v\n"); -// fprintf(stderr, "\n"); -// fprintf(stderr, "The `format' is a printf(1) format string with printf(3)-style `%%N$'\n"); -// fprintf(stderr, "column accessors; `%%0$d' retrieves the number of CSV fields in the row.\n"); -// fprintf(stderr, "\n"); fprintf(stderr, "Options:\n"); - fprintf(stderr, " -f\tRead CSV input from specified file (default stdin)\n"); - fprintf(stderr, " -i\tSkip over the first record in the CSV input\n"); - fprintf(stderr, " -q\tSpecify quote character (default `%c')\n", DEFAULT_QUOTE_CHAR); - fprintf(stderr, " -s\tSpecify field separator character (default `%c')\n", DEFAULT_FSEP_CHAR); - fprintf(stderr, " -x\tConvert input to XML (assumes ISO-8859-1 encoding of fields)\n"); - fprintf(stderr, " -h\tOutput this help message and exit\n"); - fprintf(stderr, " -v\tOutput version information and exit\n"); + fprintf(stderr, " -e encoding\tSpecify input character encoding (XML mode only; default ISO-8859-1)\n"); + fprintf(stderr, " -f input\tRead CSV input from specified file (default stdin)\n"); + fprintf(stderr, " -i\t\tAssume the first CSV record contains column names\n"); + fprintf(stderr, " -q char\tSpecify quote character (default `%c')\n", DEFAULT_QUOTE_CHAR); + fprintf(stderr, " -s char\tSpecify field separator character (default `%c')\n", DEFAULT_FSEP_CHAR); + fprintf(stderr, " -x\t\tConvert input to XML using numeric tags\n"); + fprintf(stderr, " -X\t\tConvert input to XML using column name tags (implies \"-i\")\n"); + fprintf(stderr, " -h\t\tOutput this help message and exit\n"); + fprintf(stderr, " -v\t\tOutput version information and exit\n"); } static void @@ -803,7 +851,7 @@ { fprintf(stderr, "%s version %s (%s)\n", PACKAGE_TARNAME, PACKAGE_VERSION, csvprintf_version); fprintf(stderr, "Copyright (C) 2010 Archie L. Cobbs\n"); - fprintf(stderr, "This is free software; see the source for copying conditions. There is NO\n"); + fprintf(stderr, "This is free software; see the source for copying conditions. There is NO\n"); fprintf(stderr, "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/csvprintf-1.0.4/scripts/compile new/csvprintf-1.1.0/scripts/compile --- old/csvprintf-1.0.4/scripts/compile 2018-08-02 01:37:51.000000000 +0200 +++ new/csvprintf-1.1.0/scripts/compile 2021-02-25 17:04:13.000000000 +0100 @@ -1,9 +1,9 @@ #! /bin/sh # Wrapper for compilers which do not understand '-c -o'. -scriptversion=2012-10-14.11; # UTC +scriptversion=2016-01-11.22; # UTC -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # Written by Tom Tromey <tro...@cygnus.com>. # # This program is free software; you can redistribute it and/or modify @@ -255,7 +255,8 @@ echo "compile $scriptversion" exit $? ;; - cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ + icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac @@ -342,6 +343,6 @@ # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/csvprintf-1.0.4/scripts/depcomp new/csvprintf-1.1.0/scripts/depcomp --- old/csvprintf-1.0.4/scripts/depcomp 2018-08-02 01:37:51.000000000 +0200 +++ new/csvprintf-1.1.0/scripts/depcomp 2021-02-25 17:04:13.000000000 +0100 @@ -1,9 +1,9 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2013-05-30.07; # UTC +scriptversion=2016-01-11.22; # UTC -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -786,6 +786,6 @@ # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/csvprintf-1.0.4/scripts/install-sh new/csvprintf-1.1.0/scripts/install-sh --- old/csvprintf-1.0.4/scripts/install-sh 2018-08-02 01:37:51.000000000 +0200 +++ new/csvprintf-1.1.0/scripts/install-sh 2021-02-25 17:04:13.000000000 +0100 @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2013-12-25.23; # UTC +scriptversion=2016-01-11.22; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -496,6 +496,6 @@ # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/csvprintf-1.0.4/scripts/missing new/csvprintf-1.1.0/scripts/missing --- old/csvprintf-1.0.4/scripts/missing 2018-08-02 01:37:51.000000000 +0200 +++ new/csvprintf-1.1.0/scripts/missing 2021-02-25 17:04:13.000000000 +0100 @@ -1,9 +1,9 @@ #! /bin/sh # Common wrapper for a few potentially missing GNU programs. -scriptversion=2013-10-28.13; # UTC +scriptversion=2016-01-11.22; # UTC -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard <pin...@iro.umontreal.ca>, 1996. # This program is free software; you can redistribute it and/or modify @@ -210,6 +210,6 @@ # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: