summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntti-Juhani Kaijanaho <ajk@debian.org>2006-01-28 22:33:02 +0100
committerAntti-Juhani Kaijanaho <ajk@debian.org>2006-01-28 22:33:02 +0100
commit95cd00fbe60769c79bd24f109f982f4eff18751e (patch)
treeb81a1b6935f2f20090582de2bf69d0fd0f324a55
parent389733d0f7f73f1d1c33b2974657be7888507111 (diff)
downloaddctrl-tools-95cd00fbe60769c79bd24f109f982f4eff18751e.tar.gz
Import 2.8
-rw-r--r--Makefile7
-rw-r--r--debian/changelog34
-rw-r--r--debian/control2
-rw-r--r--debian/rules3
-rw-r--r--fsaf.c7
-rw-r--r--fsaf.h5
-rw-r--r--grep-dctrl.1.cp4
-rw-r--r--grep-dctrl.c2
-rw-r--r--msg.h2
-rw-r--r--para_bundle.c4
-rw-r--r--po/ca.po46
-rw-r--r--po/de.po46
-rw-r--r--po/fi.po46
-rw-r--r--po/fr.po46
-rw-r--r--po/it.po46
-rw-r--r--po/pt_BR.po49
-rw-r--r--sync-available.820
-rw-r--r--tbl-dctrl.1203
-rw-r--r--tbl-dctrl.c420
19 files changed, 934 insertions, 58 deletions
diff --git a/Makefile b/Makefile
index 2f64ae9..d55ddc1 100644
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,7 @@ libobj = misc.o msg.o predicate.o util.o fsaf.o paragraph.o \
fieldtrie.o rc.o strutil.o getaline.o fnutil.o para_pool.o \
ifile.o para_bundle.o sorter.o version.o
-obj = $(libobj) grep-dctrl.o sort-dctrl.o
+obj = $(libobj) grep-dctrl.o sort-dctrl.o tbl-dctrl.o
src = $(obj:.o=.c)
LDLIBS = -L. -ldctrl
@@ -27,7 +27,8 @@ LDLIBS = -L. -ldctrl
# List of translated languages is given in langs.mk
include langs.mk
-all : grep-dctrl sort-dctrl sync-available grep-dctrl.1 sort-dctrl.1 mo
+all : grep-dctrl sort-dctrl tbl-dctrl sync-available \
+ grep-dctrl.1 sort-dctrl.1 mo
pot : po/dctrl-tools.pot
@@ -39,6 +40,8 @@ grep-dctrl : grep-dctrl.o libdctrl.a
sort-dctrl : sort-dctrl.o libdctrl.a
+tbl-dctrl : tbl-dctrl.o libdctrl.a
+
% : %.o
$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS)
diff --git a/debian/changelog b/debian/changelog
index db8b1ef..2d53c46 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,18 @@
+dctrl-tools (2.8) experimental; urgency=low
+
+ * Merge 2.6.7 (no po/ merge).
+ * New program tbl-dctrl.
+ Closes: #191144 (Would be great if it could print desired field values
+ all in one line, per package)
+ [Reported by Carlos Sousa]
+ * tbl-dctrl.1: New manpage.
+ * Give FSAF objects knowledge of the file name, so that we know which
+ file each paragraph came from.
+ * para_bundle.c (bundle_slurp): The correct error sentinel for file
+ descriptors is -1, not 0.
+
+ -- Antti-Juhani Kaijanaho <ajk@debian.org> Thu, 21 Jul 2005 21:32:42 +0300
+
dctrl-tools (2.7) experimental; urgency=low
* Merge 2.6.0.
@@ -19,6 +34,25 @@ dctrl-tools (2.7) experimental; urgency=low
-- Antti-Juhani Kaijanaho <ajk@debian.org> Thu, 9 Jun 2005 00:40:13 +0300
+grep-dctrl (2.6.7) unstable; urgency=low
+
+ * fr.po: Update by Nicolas Bertolissio.
+ Closes: #314893 (French translation update of gettext debconf template)
+ (Nothing to do with debconf regardless of the bug title)
+ * msg.h: Fix progname type.
+ Closes: #314601 (FTBFS (amd64/gcc-4.0): conflicting types for 'progname')
+ [Reported by Andreas Jochens]
+ * grep-dctrl.1.cp: Fix "preceding" typo.
+ Closes: #311032 *'man grep-dctrl' typo: "predecing")
+ [Reported by A Costa]
+ * sync-available.8: Miscellaneous fixes.
+ Closes: #312630 (sync-available(8) thinks it is update-avail(8))
+ [Reported by Antti-Juhani Kaijanaho]
+ Closes: #312766 ('man sync-available' typo: "aquisition")
+ [Reported by A Costa]
+
+ -- Antti-Juhani Kaijanaho <ajk@debian.org> Mon, 11 Jul 2005 18:26:46 +0300
+
grep-dctrl (2.6.6) unstable; urgency=low
* Go to unstable again.
diff --git a/debian/control b/debian/control
index 88d9717..4786135 100644
--- a/debian/control
+++ b/debian/control
@@ -26,6 +26,8 @@ Description: Command-line tools to process Debian package information
grep-aptavail - Grep the APT available database
.
sort-dctrl - Sort dctrl-format files
+ .
+ tbl-dctrl - Tabularize dctrl-format files
.
sync-available - Sync the dpkg available database with
the apt database
diff --git a/debian/rules b/debian/rules
index c776296..c743d69 100644
--- a/debian/rules
+++ b/debian/rules
@@ -50,6 +50,7 @@ debian/stamp/binary/dctrl-tools: debian/stamp/build
$(install_dir) $(sbindir)
$(install_script) sync-available $(sbindir)
$(install_dir) $(bindir)
+ $(install_exec) tbl-dctrl $(bindir)
$(install_exec) sort-dctrl $(bindir)
$(install_exec) grep-dctrl $(bindir)
set -e ; for dest in $(aliases) ; do \
@@ -62,6 +63,8 @@ debian/stamp/binary/dctrl-tools: debian/stamp/build
$(install_dir) $(man1dir)
$(install_nonex) sort-dctrl.1 $(man1dir)/
$(gzip) $(man1dir)/sort-dctrl.1
+ $(install_nonex) tbl-dctrl.1 $(man1dir)/
+ $(gzip) $(man1dir)/tbl-dctrl.1
$(install_nonex) grep-dctrl.1 $(man1dir)/
$(gzip) $(man1dir)/grep-dctrl.1
set -e ; for dest in $(aliases) ; do \
diff --git a/fsaf.c b/fsaf.c
index 7d44e70..9406d36 100644
--- a/fsaf.c
+++ b/fsaf.c
@@ -1,5 +1,5 @@
/* dctrl-tools - Debian control file inspection tools
- Copyright (C) 2003 Antti-Juhani Kaijanaho
+ Copyright (C) 2003, 2005 Antti-Juhani Kaijanaho
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
@@ -35,11 +35,13 @@
#define READAHEAD 1
-FSAF * fsaf_fdopen(int fd)
+FSAF * fsaf_fdopen(int fd, char const *fname)
{
FSAF * rv = malloc(sizeof *rv);
if (rv == 0) { errno = ENOMEM; return 0; }
+ rv->fname = strdup(fname);
+ if (rv->fname == NULL) { errno = ENOMEM; free(rv); return 0; }
rv->fd = fd;
rv->eof_mark = (size_t)(-1);
rv->buf = 0;
@@ -91,6 +93,7 @@ void fsaf_close(FSAF * fp)
return;
}
#endif
+ free(fp->fname);
free(fp->buf);
free(fp);
}
diff --git a/fsaf.h b/fsaf.h
index 2700007..56e8eb9 100644
--- a/fsaf.h
+++ b/fsaf.h
@@ -1,5 +1,5 @@
/* dctrl-tools - Debian control file inspection tools
- Copyright (C) 2003 Antti-Juhani Kaijanaho
+ Copyright (C) 2003, 2005 Antti-Juhani Kaijanaho
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
@@ -27,6 +27,7 @@
/* FAST (MOSTLY) SEQUENTIAL-ACCESS FILE LAYER */
struct fsaf_private {
+ char *fname;
int fd;
char * buf;
size_t buf_capacity;
@@ -44,7 +45,7 @@ typedef struct fsaf_private FSAF;
/* Open a FSAF for the given fd. Only read access is supported for
* now. The whole file is initially valid. */
-FSAF * fsaf_fdopen(int fd);
+FSAF * fsaf_fdopen(int fd, char const *fname);
/* Close the given FSAF. This DOES NOT close the underlying fd. */
void fsaf_close(FSAF *);
diff --git a/grep-dctrl.1.cp b/grep-dctrl.1.cp
index 4a34aaf..346115f 100644
--- a/grep-dctrl.1.cp
+++ b/grep-dctrl.1.cp
@@ -1,4 +1,4 @@
-.TH GREP-DCTRL 1 2005-06-08 "Debian Project" "Debian user's manual"
+.TH GREP-DCTRL 1 2005-07-11 "Debian Project" "Debian user's manual"
\" Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
\" Antti-Juhani Kaijanaho <gaia@iki.fi>
\" This program is free software; you can redistribute it and/or modify
@@ -191,7 +191,7 @@ option, if any, the last field being the default.
.IP "\-n, \-\-no\-field\-names"
Suppress field names when showing specified fields, only their bodies
are shown. Each field is printed in its original form without the
-field name, the colon after it and any whitespace predecing the start
+field name, the colon after it and any whitespace preceding the start
of the body.
.IP "\-v, \-\-invert\-match"
Instead of showing all the paragraphs that match, show those paragraphs
diff --git a/grep-dctrl.c b/grep-dctrl.c
index c93c721..5a6c1b6 100644
--- a/grep-dctrl.c
+++ b/grep-dctrl.c
@@ -770,7 +770,7 @@ int main (int argc, char * argv[])
if (!chk_ifile(fname, fd)) break;
- FSAF * fp = fsaf_fdopen(fd);
+ FSAF * fp = fsaf_fdopen(fd, fname.s);
para_parser_t pp;
para_parser_init(&pp, fp, true);
para_t para;
diff --git a/msg.h b/msg.h
index 6a46991..352da98 100644
--- a/msg.h
+++ b/msg.h
@@ -58,7 +58,7 @@ do_msg(int severity)
inline static char const *
get_progname(void)
{
- extern const char progname [];
+ extern char progname [];
return progname;
}
diff --git a/para_bundle.c b/para_bundle.c
index e469523..5740c55 100644
--- a/para_bundle.c
+++ b/para_bundle.c
@@ -22,12 +22,12 @@
void bundle_slurp(struct para_bundle * pb, struct ifile ifi)
{
int fd = open_ifile(ifi);
- if (fd == 0) {
+ if (fd == -1) {
record_error();
return;
}
- FSAF * f = fsaf_fdopen(fd);
+ FSAF * f = fsaf_fdopen(fd, ifi.s);
if (f == 0) fatal_enomem(0);
struct srcfile * sf = malloc(sizeof *sf);
diff --git a/po/ca.po b/po/ca.po
index 6c4e853..1a4ae78 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: dctrl-tools\n"
"Report-Msgid-Bugs-To: ajk@debian.org\n"
-"POT-Creation-Date: 2005-06-09 00:22+0300\n"
+"POT-Creation-Date: 2005-07-20 13:08+0300\n"
"PO-Revision-Date: 2004-02-09 10:16+0100\n"
"Last-Translator: Jordi Mallach <jordi@debian.org>\n"
"Language-Team: Catalan <debian-l10n-catalan@lists.debian.org>\n"
@@ -133,11 +133,11 @@ msgstr "grep-dctrl -- cerca patrons en fitxers de control de Debian"
msgid "Show the testing banner."
msgstr "Mostra l'avís de prova."
-#: grep-dctrl.c:106 sort-dctrl.c:36
+#: grep-dctrl.c:106 sort-dctrl.c:36 tbl-dctrl.c:38
msgid "LEVEL"
msgstr "NIVELL"
-#: grep-dctrl.c:106 sort-dctrl.c:36
+#: grep-dctrl.c:106 sort-dctrl.c:36 tbl-dctrl.c:38
msgid "Set debugging level to LEVEL."
msgstr "Estableix el nivell de depuració a NIVELL."
@@ -204,7 +204,7 @@ msgstr "Utilitza NOMFITXER com el fitxer de configuració."
msgid "Do an exact match."
msgstr "Fes una coincidència exacta."
-#: grep-dctrl.c:119 sort-dctrl.c:35
+#: grep-dctrl.c:119 sort-dctrl.c:35 tbl-dctrl.c:37
msgid "Print out the copyright license."
msgstr "Mostra la llicència del copyright."
@@ -246,6 +246,7 @@ msgid "Debug option parsing."
msgstr "Depura l'anàlisi d'opcions."
#: grep-dctrl.c:129 grep-dctrl.c:130 sort-dctrl.c:37 sort-dctrl.c:38
+#: tbl-dctrl.c:39 tbl-dctrl.c:40
#, fuzzy
msgid "Do no output to stdout."
msgstr "No mostra res a l'eixida estàndard"
@@ -259,11 +260,11 @@ msgstr "el predicat és massa complex"
msgid "inconsistent atom modifiers"
msgstr "els modificadors d'àtom no són consistents"
-#: grep-dctrl.c:409 sort-dctrl.c:99
+#: grep-dctrl.c:409 sort-dctrl.c:99 tbl-dctrl.c:278
msgid "no such log level"
msgstr "aquest nivell de registre no existeix"
-#: grep-dctrl.c:509 sort-dctrl.c:111
+#: grep-dctrl.c:509 sort-dctrl.c:111 tbl-dctrl.c:290
msgid "too many file names"
msgstr "hi ha massa noms de fitxers"
@@ -348,6 +349,39 @@ msgstr ""
msgid "sort-dctrl -- sort Debian control files"
msgstr "grep-dctrl -- cerca patrons en fitxers de control de Debian"
+#: tbl-dctrl.c:35
+msgid "DELIM"
+msgstr ""
+
+#: tbl-dctrl.c:35
+msgid "Specify a delimiter."
+msgstr ""
+
+#: tbl-dctrl.c:36
+msgid "SPEC"
+msgstr ""
+
+#: tbl-dctrl.c:36
+msgid "Append the specified column."
+msgstr ""
+
+#: tbl-dctrl.c:264
+msgid "invalid column length"
+msgstr ""
+
+#: tbl-dctrl.c:311
+#, fuzzy
+msgid "tbl-dctrl -- tabularize Debian control files"
+msgstr "grep-dctrl -- cerca patrons en fitxers de control de Debian"
+
+#: tbl-dctrl.c:325
+msgid "bad multibyte character"
+msgstr ""
+
+#, fuzzy
+#~ msgid "pretty-dctrl -- pretty-print Debian control files"
+#~ msgstr "grep-dctrl -- cerca patrons en fitxers de control de Debian"
+
#~ msgid "invalid numeric pattern"
#~ msgstr "el patró numèric és invàlid"
diff --git a/po/de.po b/po/de.po
index efeaa56..9bc3105 100644
--- a/po/de.po
+++ b/po/de.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: dctrl-tools\n"
"Report-Msgid-Bugs-To: ajk@debian.org\n"
-"POT-Creation-Date: 2005-06-09 00:22+0300\n"
+"POT-Creation-Date: 2005-07-20 13:08+0300\n"
"PO-Revision-Date: 2004-07-23 15:28+0200\n"
"Last-Translator: Gerfried Fuchs <alfie@debian.org>\n"
"Language-Team: German <debian-l10n-german@lists.debian.org>\n"
@@ -133,11 +133,11 @@ msgstr "grep-dctrl -- durchsucht Debian-Control-Dateien"
msgid "Show the testing banner."
msgstr "Zeigt den Testing-Banner."
-#: grep-dctrl.c:106 sort-dctrl.c:36
+#: grep-dctrl.c:106 sort-dctrl.c:36 tbl-dctrl.c:38
msgid "LEVEL"
msgstr "EBENE"
-#: grep-dctrl.c:106 sort-dctrl.c:36
+#: grep-dctrl.c:106 sort-dctrl.c:36 tbl-dctrl.c:38
msgid "Set debugging level to LEVEL."
msgstr "Setzt Debugging-Ebene auf EBENE."
@@ -200,7 +200,7 @@ msgstr "Verwendet FNAME als Konfigurationsdatei."
msgid "Do an exact match."
msgstr "Führt eine exakte Übereinstimmung durch."
-#: grep-dctrl.c:119 sort-dctrl.c:35
+#: grep-dctrl.c:119 sort-dctrl.c:35 tbl-dctrl.c:37
msgid "Print out the copyright license."
msgstr "Gibt die Copyright-Lizenz aus."
@@ -242,6 +242,7 @@ msgid "Debug option parsing."
msgstr "Optionenverarbeitung debuggen."
#: grep-dctrl.c:129 grep-dctrl.c:130 sort-dctrl.c:37 sort-dctrl.c:38
+#: tbl-dctrl.c:39 tbl-dctrl.c:40
msgid "Do no output to stdout."
msgstr "Keine Ausgabe auf die Standardausgabe."
@@ -253,11 +254,11 @@ msgstr "Eigenschaft ist zu lang"
msgid "inconsistent atom modifiers"
msgstr "Inkonsistener Atom-Modifikator"
-#: grep-dctrl.c:409 sort-dctrl.c:99
+#: grep-dctrl.c:409 sort-dctrl.c:99 tbl-dctrl.c:278
msgid "no such log level"
msgstr "Keine solche Log-Ebene"
-#: grep-dctrl.c:509 sort-dctrl.c:111
+#: grep-dctrl.c:509 sort-dctrl.c:111 tbl-dctrl.c:290
msgid "too many file names"
msgstr "Zu viele Dateinamen"
@@ -334,6 +335,39 @@ msgstr ""
msgid "sort-dctrl -- sort Debian control files"
msgstr "sort-dctrl -- sortiert Debian-Control-Dateien"
+#: tbl-dctrl.c:35
+msgid "DELIM"
+msgstr ""
+
+#: tbl-dctrl.c:35
+msgid "Specify a delimiter."
+msgstr ""
+
+#: tbl-dctrl.c:36
+msgid "SPEC"
+msgstr ""
+
+#: tbl-dctrl.c:36
+msgid "Append the specified column."
+msgstr ""
+
+#: tbl-dctrl.c:264
+msgid "invalid column length"
+msgstr ""
+
+#: tbl-dctrl.c:311
+#, fuzzy
+msgid "tbl-dctrl -- tabularize Debian control files"
+msgstr "grep-dctrl -- durchsucht Debian-Control-Dateien"
+
+#: tbl-dctrl.c:325
+msgid "bad multibyte character"
+msgstr ""
+
+#, fuzzy
+#~ msgid "pretty-dctrl -- pretty-print Debian control files"
+#~ msgstr "grep-dctrl -- durchsucht Debian-Control-Dateien"
+
#~ msgid "invalid numeric pattern"
#~ msgstr "Ungültiges numerisches Muster"
diff --git a/po/fi.po b/po/fi.po
index ff98a27..2352202 100644
--- a/po/fi.po
+++ b/po/fi.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: dctrl-tools\n"
"Report-Msgid-Bugs-To: ajk@debian.org\n"
-"POT-Creation-Date: 2005-06-09 00:22+0300\n"
+"POT-Creation-Date: 2005-07-20 13:08+0300\n"
"PO-Revision-Date: 2004-07-08 18:29+0300\n"
"Last-Translator: Antti-Juhani Kaijanaho <ajk@debian.org>\n"
"Language-Team: Finnish <debian-l10n-finnish@lists.debian.org>\n"
@@ -133,11 +133,11 @@ msgstr "grep-dctrl -- hae Debianin kontrollitiedostoista"
msgid "Show the testing banner."
msgstr "Näytä testausviesti."
-#: grep-dctrl.c:106 sort-dctrl.c:36
+#: grep-dctrl.c:106 sort-dctrl.c:36 tbl-dctrl.c:38
msgid "LEVEL"
msgstr "TASO"
-#: grep-dctrl.c:106 sort-dctrl.c:36
+#: grep-dctrl.c:106 sort-dctrl.c:36 tbl-dctrl.c:38
msgid "Set debugging level to LEVEL."
msgstr "Aseta vianetsintätasoksi TASO."
@@ -200,7 +200,7 @@ msgstr "Käytä TIEDNIMI-tiedostoa asetustiedostona."
msgid "Do an exact match."
msgstr "Käytä täsmällistä hakua."
-#: grep-dctrl.c:119 sort-dctrl.c:35
+#: grep-dctrl.c:119 sort-dctrl.c:35 tbl-dctrl.c:37
msgid "Print out the copyright license."
msgstr "Tulosta tekijänoikeuslisenssi."
@@ -242,6 +242,7 @@ msgid "Debug option parsing."
msgstr "Testaa valitsimien jäsennyst�."
#: grep-dctrl.c:129 grep-dctrl.c:130 sort-dctrl.c:37 sort-dctrl.c:38
+#: tbl-dctrl.c:39 tbl-dctrl.c:40
msgid "Do no output to stdout."
msgstr "Älä tulosta mitään vakiotulostevirtaan"
@@ -253,11 +254,11 @@ msgstr "predikaatti on liian pitkä"
msgid "inconsistent atom modifiers"
msgstr "ristitiitaiset atomin määritteet"
-#: grep-dctrl.c:409 sort-dctrl.c:99
+#: grep-dctrl.c:409 sort-dctrl.c:99 tbl-dctrl.c:278
msgid "no such log level"
msgstr "ei sellaista seurantatasoa ole"
-#: grep-dctrl.c:509 sort-dctrl.c:111
+#: grep-dctrl.c:509 sort-dctrl.c:111 tbl-dctrl.c:290
msgid "too many file names"
msgstr "liikaa tiedostonimiä"
@@ -335,6 +336,39 @@ msgstr ""
msgid "sort-dctrl -- sort Debian control files"
msgstr "grep-dctrl -- hae Debianin kontrollitiedostoista"
+#: tbl-dctrl.c:35
+msgid "DELIM"
+msgstr ""
+
+#: tbl-dctrl.c:35
+msgid "Specify a delimiter."
+msgstr ""
+
+#: tbl-dctrl.c:36
+msgid "SPEC"
+msgstr ""
+
+#: tbl-dctrl.c:36
+msgid "Append the specified column."
+msgstr ""
+
+#: tbl-dctrl.c:264
+msgid "invalid column length"
+msgstr ""
+
+#: tbl-dctrl.c:311
+#, fuzzy
+msgid "tbl-dctrl -- tabularize Debian control files"
+msgstr "grep-dctrl -- hae Debianin kontrollitiedostoista"
+
+#: tbl-dctrl.c:325
+msgid "bad multibyte character"
+msgstr ""
+
+#, fuzzy
+#~ msgid "pretty-dctrl -- pretty-print Debian control files"
+#~ msgstr "grep-dctrl -- hae Debianin kontrollitiedostoista"
+
#~ msgid "invalid numeric pattern"
#~ msgstr "rikkinäinen lukuhakuehto"
diff --git a/po/fr.po b/po/fr.po
index f784a70..05fc9cc 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: dctrl-tools 2.0\n"
"Report-Msgid-Bugs-To: ajk@debian.org\n"
-"POT-Creation-Date: 2005-06-09 00:22+0300\n"
+"POT-Creation-Date: 2005-07-20 13:08+0300\n"
"PO-Revision-Date: 2004-07-03 23:48+0200\n"
"Last-Translator: Nicolas Bertolissio <nico.bertol@free.fr>\n"
"Language-Team: French <debian-l10n-french@lists.debian.org>\n"
@@ -133,11 +133,11 @@ msgstr "grep-dctrl -- sélection dans des fichiers de contrôle Debian"
msgid "Show the testing banner."
msgstr "Afficher la bannière de test"
-#: grep-dctrl.c:106 sort-dctrl.c:36
+#: grep-dctrl.c:106 sort-dctrl.c:36 tbl-dctrl.c:38
msgid "LEVEL"
msgstr "NIVEAU"
-#: grep-dctrl.c:106 sort-dctrl.c:36
+#: grep-dctrl.c:106 sort-dctrl.c:36 tbl-dctrl.c:38
msgid "Set debugging level to LEVEL."
msgstr "Sélectionner le niveau de débogage NIVEAU"
@@ -201,7 +201,7 @@ msgstr "Utiliser FICHIER comme fichier de configuration"
msgid "Do an exact match."
msgstr "Rechercher une correspondance exacte"
-#: grep-dctrl.c:119 sort-dctrl.c:35
+#: grep-dctrl.c:119 sort-dctrl.c:35 tbl-dctrl.c:37
msgid "Print out the copyright license."
msgstr "Afficher la licence"
@@ -243,6 +243,7 @@ msgid "Debug option parsing."
msgstr "Déboguer l'analyse des options"
#: grep-dctrl.c:129 grep-dctrl.c:130 sort-dctrl.c:37 sort-dctrl.c:38
+#: tbl-dctrl.c:39 tbl-dctrl.c:40
msgid "Do no output to stdout."
msgstr "Pas de sortie sur la sortie standard"
@@ -255,11 +256,11 @@ msgstr "le prédicat est trop complexe"
msgid "inconsistent atom modifiers"
msgstr "modificateurs d'atome incohérents"
-#: grep-dctrl.c:409 sort-dctrl.c:99
+#: grep-dctrl.c:409 sort-dctrl.c:99 tbl-dctrl.c:278
msgid "no such log level"
msgstr "niveau de journalisation inexistant"
-#: grep-dctrl.c:509 sort-dctrl.c:111
+#: grep-dctrl.c:509 sort-dctrl.c:111 tbl-dctrl.c:290
msgid "too many file names"
msgstr "trop de noms de fichiers"
@@ -345,6 +346,39 @@ msgstr ""
msgid "sort-dctrl -- sort Debian control files"
msgstr "grep-dctrl -- sélection dans des fichiers de contrôle Debian"
+#: tbl-dctrl.c:35
+msgid "DELIM"
+msgstr ""
+
+#: tbl-dctrl.c:35
+msgid "Specify a delimiter."
+msgstr ""
+
+#: tbl-dctrl.c:36
+msgid "SPEC"
+msgstr ""
+
+#: tbl-dctrl.c:36
+msgid "Append the specified column."
+msgstr ""
+
+#: tbl-dctrl.c:264
+msgid "invalid column length"
+msgstr ""
+
+#: tbl-dctrl.c:311
+#, fuzzy
+msgid "tbl-dctrl -- tabularize Debian control files"
+msgstr "grep-dctrl -- sélection dans des fichiers de contrôle Debian"
+
+#: tbl-dctrl.c:325
+msgid "bad multibyte character"
+msgstr ""
+
+#, fuzzy
+#~ msgid "pretty-dctrl -- pretty-print Debian control files"
+#~ msgstr "grep-dctrl -- sélection dans des fichiers de contrôle Debian"
+
#~ msgid "invalid numeric pattern"
#~ msgstr "motif numérique invalide"
diff --git a/po/it.po b/po/it.po
index 35cf355..278211e 100644
--- a/po/it.po
+++ b/po/it.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: dctrl-tools 2.7\n"
"Report-Msgid-Bugs-To: ajk@debian.org\n"
-"POT-Creation-Date: 2005-06-09 00:22+0300\n"
+"POT-Creation-Date: 2005-07-20 13:08+0300\n"
"PO-Revision-Date: 2004-07-20 15:28+0200\n"
"Last-Translator: Danilo Piazzalunga <danilopiazza@libero.it>\n"
"Language-Team: Italian <tp@lists.linux.it>\n"
@@ -136,11 +136,11 @@ msgstr "grep-dctrl -- ricerca attraverso i file di controllo di Debian"
msgid "Show the testing banner."
msgstr "Mostra l'avviso fastidioso."
-#: grep-dctrl.c:106 sort-dctrl.c:36
+#: grep-dctrl.c:106 sort-dctrl.c:36 tbl-dctrl.c:38
msgid "LEVEL"
msgstr "LIVELLO"
-#: grep-dctrl.c:106 sort-dctrl.c:36
+#: grep-dctrl.c:106 sort-dctrl.c:36 tbl-dctrl.c:38
msgid "Set debugging level to LEVEL."
msgstr "Imposta il livello di debug a LIVELLO."
@@ -209,7 +209,7 @@ msgstr "Usa NOMEFILE come file di configurazione."
msgid "Do an exact match."
msgstr "Cerca solo corrispondenze esatte."
-#: grep-dctrl.c:119 sort-dctrl.c:35
+#: grep-dctrl.c:119 sort-dctrl.c:35 tbl-dctrl.c:37
msgid "Print out the copyright license."
msgstr "Mostra la licenza."
@@ -251,6 +251,7 @@ msgid "Debug option parsing."
msgstr "Fa il debug dell'analisi delle opzioni."
#: grep-dctrl.c:129 grep-dctrl.c:130 sort-dctrl.c:37 sort-dctrl.c:38
+#: tbl-dctrl.c:39 tbl-dctrl.c:40
msgid "Do no output to stdout."
msgstr "Non invia output verso stdout."
@@ -263,11 +264,11 @@ msgstr "il predicato è troppo lungo"
msgid "inconsistent atom modifiers"
msgstr "modificatori di atomi incoerenti"
-#: grep-dctrl.c:409 sort-dctrl.c:99
+#: grep-dctrl.c:409 sort-dctrl.c:99 tbl-dctrl.c:278
msgid "no such log level"
msgstr "livello di log inesistente"
-#: grep-dctrl.c:509 sort-dctrl.c:111
+#: grep-dctrl.c:509 sort-dctrl.c:111 tbl-dctrl.c:290
msgid "too many file names"
msgstr "troppi nomi di file"
@@ -346,6 +347,39 @@ msgstr ""
msgid "sort-dctrl -- sort Debian control files"
msgstr "sort-dctrl -- ordina i file di controllo di Debian"
+#: tbl-dctrl.c:35
+msgid "DELIM"
+msgstr ""
+
+#: tbl-dctrl.c:35
+msgid "Specify a delimiter."
+msgstr ""
+
+#: tbl-dctrl.c:36
+msgid "SPEC"
+msgstr ""
+
+#: tbl-dctrl.c:36
+msgid "Append the specified column."
+msgstr ""
+
+#: tbl-dctrl.c:264
+msgid "invalid column length"
+msgstr ""
+
+#: tbl-dctrl.c:311
+#, fuzzy
+msgid "tbl-dctrl -- tabularize Debian control files"
+msgstr "grep-dctrl -- ricerca attraverso i file di controllo di Debian"
+
+#: tbl-dctrl.c:325
+msgid "bad multibyte character"
+msgstr ""
+
+#, fuzzy
+#~ msgid "pretty-dctrl -- pretty-print Debian control files"
+#~ msgstr "grep-dctrl -- ricerca attraverso i file di controllo di Debian"
+
#~ msgid "invalid numeric pattern"
#~ msgstr "modello di ricerca numerico errato"
diff --git a/po/pt_BR.po b/po/pt_BR.po
index 8528402..41a0cb2 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: grep-dctrl tools\n"
"Report-Msgid-Bugs-To: ajk@debian.org\n"
-"POT-Creation-Date: 2005-06-09 00:22+0300\n"
+"POT-Creation-Date: 2005-07-20 13:08+0300\n"
"PO-Revision-Date: 2005-01-15 22:23-0300\n"
"Last-Translator: Mauricio Bomfim Cruz Vieira <mauricio.vieira@gmail.com>\n"
"Language-Team: Brazilian Portuguese <debian-l10n-portuguese@lists.debian."
@@ -137,11 +137,11 @@ msgstr ""
msgid "Show the testing banner."
msgstr "Mostra a mensagem de aviso teste."
-#: grep-dctrl.c:106 sort-dctrl.c:36
+#: grep-dctrl.c:106 sort-dctrl.c:36 tbl-dctrl.c:38
msgid "LEVEL"
msgstr "NÍVEL"
-#: grep-dctrl.c:106 sort-dctrl.c:36
+#: grep-dctrl.c:106 sort-dctrl.c:36 tbl-dctrl.c:38
msgid "Set debugging level to LEVEL."
msgstr "Ajusta o nível de depuração para NÍVEL."
@@ -208,7 +208,7 @@ msgstr "Use ARQUIVO como o arquivo de configuração."
msgid "Do an exact match."
msgstr "Faz um casamento exato."
-#: grep-dctrl.c:119 sort-dctrl.c:35
+#: grep-dctrl.c:119 sort-dctrl.c:35 tbl-dctrl.c:37
msgid "Print out the copyright license."
msgstr "Imprime a licença de copyright."
@@ -250,6 +250,7 @@ msgid "Debug option parsing."
msgstr "Depura leitura das opções."
#: grep-dctrl.c:129 grep-dctrl.c:130 sort-dctrl.c:37 sort-dctrl.c:38
+#: tbl-dctrl.c:39 tbl-dctrl.c:40
msgid "Do no output to stdout."
msgstr "Não imprime a saída na saída padrão."
@@ -261,11 +262,11 @@ msgstr "predicado é muito longo"
msgid "inconsistent atom modifiers"
msgstr "modificadores atômicos inconsistentes"
-#: grep-dctrl.c:409 sort-dctrl.c:99
+#: grep-dctrl.c:409 sort-dctrl.c:99 tbl-dctrl.c:278
msgid "no such log level"
msgstr "não existe este nível de log"
-#: grep-dctrl.c:509 sort-dctrl.c:111
+#: grep-dctrl.c:509 sort-dctrl.c:111 tbl-dctrl.c:290
msgid "too many file names"
msgstr "muitos nomes de arquivos"
@@ -346,6 +347,42 @@ msgid "sort-dctrl -- sort Debian control files"
msgstr ""
"grep-dctrl -- busca por expressões regulares em arquivos de controle Debian"
+#: tbl-dctrl.c:35
+msgid "DELIM"
+msgstr ""
+
+#: tbl-dctrl.c:35
+msgid "Specify a delimiter."
+msgstr ""
+
+#: tbl-dctrl.c:36
+msgid "SPEC"
+msgstr ""
+
+#: tbl-dctrl.c:36
+msgid "Append the specified column."
+msgstr ""
+
+#: tbl-dctrl.c:264
+msgid "invalid column length"
+msgstr ""
+
+#: tbl-dctrl.c:311
+#, fuzzy
+msgid "tbl-dctrl -- tabularize Debian control files"
+msgstr ""
+"grep-dctrl -- busca por expressões regulares em arquivos de controle Debian"
+
+#: tbl-dctrl.c:325
+msgid "bad multibyte character"
+msgstr ""
+
+#, fuzzy
+#~ msgid "pretty-dctrl -- pretty-print Debian control files"
+#~ msgstr ""
+#~ "grep-dctrl -- busca por expressões regulares em arquivos de controle "
+#~ "Debian"
+
#~ msgid "invalid numeric pattern"
#~ msgstr "padrão numérico invalido "
diff --git a/sync-available.8 b/sync-available.8
index 3ee70c1..a8fbbf9 100644
--- a/sync-available.8
+++ b/sync-available.8
@@ -1,5 +1,5 @@
-.TH UPDATE-AVAIL 8 2004-07-11 "Debian Project" "Debian administrator's manual"
-\" Copyright (C) 2004 Antti-Juhani Kaijanaho <gaia@iki.fi>
+.TH SYNC\-AVAILABLE 8 2005-07-11 "Debian Project" "Debian administrator's manual"
+\" Copyright (C) 2004, 2005 Antti-Juhani Kaijanaho <gaia@iki.fi>
\" 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
\" the Free Software Foundation; either version 2 of the License, or
@@ -15,30 +15,30 @@
\" the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
\" Boston, MA 02111-1307, USA.
.SH NAME
-update-avail \- sync dpkg's available database with apt's database
+sync\-available \- sync dpkg's available database with apt's database
.SH SYNOPSIS
-.B update-avail
+.B sync\-available
.sp
-.B update-avail --version
+.B sync\-available --version
.sp
-.B update-avail --help
+.B sync\-available --help
.SH DESCRIPTION
This program updates the
.BR dpkg (8)
available database with the data in the
.BR apt (8)
package database. This is required for
-.BR grep-available (1)
+.BR grep\-available (1)
and other similar programs to give up-to-date results.
.PP
The same functionality is available through
.BR dselect (8),
when it is configured to use
.BR apt (8)
-as its aquisition method. However, this program does not require that
+as its acquisition method. However, this program does not require that
.BR dselect (8)
is installed.
-.SH EXIT STATUS
+.SH "EXIT STATUS"
The program exits with status code 0 if all went well, and a non-zero
status code otherwise.
.SH OPTIONS
@@ -57,4 +57,4 @@ Kaijanaho <ajk@debian.org>.
.BR apt (8),
.BR dpkg (8),
.BR dselect (8),
-.BR grep-available (1)
+.BR grep\-available (1)
diff --git a/tbl-dctrl.1 b/tbl-dctrl.1
new file mode 100644
index 0000000..928b2bc
--- /dev/null
+++ b/tbl-dctrl.1
@@ -0,0 +1,203 @@
+.TH tbl\-dctrl 1 2005-07-21 "Debian Project" "Debian administrator's manual"
+\" Copyright (C) 2005 Antti-Juhani Kaijanaho <ajk@debian.org>
+\" 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
+\" the Free Software Foundation; either version 2 of the License, or
+\" (at your option) any later version.
+\"
+\" This program is distributed in the hope that it will be useful,
+\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+\" GNU General Public License for more details.
+\"
+\" You should have received a copy of the GNU General Public License
+\" along with this program; see the file COPYING. If not, write to
+\" the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+\" Boston, MA 02111-1307, USA.
+.SH NAME
+tbl\-dctrl \- generate tabular representations of data in dctrl format
+.SH SYNOPSIS
+.B tbl\-dctrl
+[
+.I options
+]
+.B \-c
+.IR column\-specification " ..."
+[
+.I filename
+] ...
+.sp
+.B tbl\-dctrl
+.B \-\-version
+.sp
+.B tbl\-dctrl
+.B \-\-help
+.SH DESCRIPTION
+.B tbl\-dctrl
+creates tabular representations of data given to it in Debian control
+file format.
+.PP
+By default,
+.B tbl\-dctrl
+reads the whole database, looking for the longest entry in each
+requested column; it then outputs a table, with borders and column
+titles, where each column is just wide enough to fit the longest
+entry.
+.
+Most of this behaviour can be customized as described below.
+.PP
+A column is requested by specifying the
+.BR \-c " (" \-\-column )
+switch with a column specification.
+.
+The simplest kind of a column specification consists solely of the name
+of a field.
+.
+In such a case,
+.B tbl\-dctrl
+will include in the output a column whose title is the literal column
+specification and whose data is drawn from fields with that name.
+.
+At least one column must be requested.
+.PP
+There are two optional additions one can make to a column
+specification.
+.
+Prefixing the field name with some text followed by an equality sign
+(for example,
+.BR "\-c 'Package name=Package'" )
+modifies the column in such a way that the text before the equality
+sign is used as the column title, while the text after the equality
+sign is used as the name of the field from which data is drawn.
+.
+One can also append a colon followed by a positive whole number to the
+field name. In such a case, the number after the colon specifies the
+width of the column.
+.
+These two additions can be used separately or together.
+.
+If there are more than one colon, the last one is significant.
+.
+If there are more than one equals sign, the first one is significant.
+.
+Other colons and equals signs are used simply as data.
+.
+Note that the whole column specification must be given to
+.B tbl\-dctrl
+as one argument, so if it contains spaces, it must be quoted for the
+shell.
+.PP
+If all requested columns have a specified width,
+.B tbl\-dctrl
+will produce output immediately, not waiting for the whole input to be
+read in.
+.SH OPTIONS
+.TP
+.BI \-d " DELIMITER, " \-\-delimiter= DELIMITER
+Instead of drawing nice borders to the table, use the specified
+delimiter string to delimit columns in a row.
+.TP
+.BI \-l " LEVEL, " \-\-errorlevel= LEVEL
+Set debugging level to LEVEL. LEVEL is one of "fatal", "important",
+"informational" and "debug", but the last may not be available,
+depending on the compile-time options. These categories are given
+here in order; every message that is emitted when "fatal" is in
+effect, will be emitted in the "important" error level, and so on.
+The default is "important".
+.TP
+.BI \-V ", " \-\-version
+Print out version information.
+.TP
+.BI \-C ", " \-\-copying
+Print out the copyright license. This produces much output; be sure
+to redirect or pipe it somewhere (such as your favourite pager).
+.TP
+.Bi \-h ", " \-\-help
+Print out a help summary.
+.SH OPERANDS
+.B tbl\-dctrl
+will read its input from the files named on the command line,
+in the specified order.
+.
+A file called
+.B \-
+represents the program's standard input stream.
+.
+If no files are named, the program behaves as if
+.B \-
+alone had been named, that is, input is read from the standard input
+stream.
+.SH STDIN
+The standard input stream may be used as input as specified above in
+the OPERANDS section.
+.SH "INPUT FILES"
+All input to
+.B tbl\-dctrl
+is in the format of a Debian control file.
+.PP
+A Debian control (dctrl) file is a semistructured single-table
+database stored in a machine-parseable text file.
+.
+Such a database consists of a set of records; each record is a mapping
+from field names to field content.
+.
+Textually, records are separated by empty lines, while each field is
+encoded as one or more nonempty lines inside a record.
+.
+A field starts with its name, followed by a colon, followed by the
+field content.
+.
+The colon must reside on the first line of the field, and the first
+line must start with no whitespace.
+.
+Subsequent lines, in contrast, always start with linear whitespace
+(one or more space or tab characters).
+.PP
+When input is read from multiple files, a record separator is implicit
+between two adjacent files.
+.SH "ENVIRONMENT VARIABLES"
+The standard locale environment, specifically its character set
+setting, affects the interpretation of input and output as character
+streams.
+.SH "ASYNCHRONOUS EVENTS"
+Standard Unix signals have their usual meaning.
+.SH STDOUT
+All output is sent to the standard output stream.
+.
+The output is a tabular representation of the input database restricted
+to the specified fields. Logically, the output is a table; when the
+.B \-d
+option is used, this table is represented simply by separating columns
+in each row by the specified delimiter; when the option is not used, a
+frame is drawn around the table. The order of the columns is the same
+as the order of the column specifications on the command line.
+.SH "OUTPUT FILES"
+There are no output files.
+.SH "EXIT STATUS"
+This utility exits with 0 when successful. It uses a nonzero exit
+code inconsistently when an error is noticed (this is a bug).
+.SH "CONSEQUENCES OF ERRORS"
+In case of errors in the input, the output will be partially or
+completely garbage. In case of errors in invocation, the program will
+refuse to fnction.
+.SH "EXAMPLES"
+The following command line pipe outputs a table of all packages, with
+their maintainer data, sorted by the maintainer data, that have no
+content:
+.nf
+% grep\-available \-FInstalled\-Size \-\-eq 0 | sort\-dctrl \-kMaintainer \- |
+ tbl\-dctrl \-cPackage \-cMaintainer
+.fi
+.SH "SEE ALSO"
+.BR ara (1),
+.BR apt\-cache (1),
+.BR dpkg (8),
+.BR dpkg\-awk (1),
+.BR dpkg\-query (1),
+.BR grep\-dctrl (1),
+.BR sort\-dctrl (1)
+.SH AUTHOR
+The
+.B tbl\-dctrl
+program and this manual page were written by Antti-Juhani Kaijanaho.
+
diff --git a/tbl-dctrl.c b/tbl-dctrl.c
new file mode 100644
index 0000000..641e9fa
--- /dev/null
+++ b/tbl-dctrl.c
@@ -0,0 +1,420 @@
+/* dctrl-tools - Debian control file inspection tools
+ Copyright (C) 2005 Antti-Juhani Kaijanaho
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <argp.h>
+#include <locale.h>
+#include <stdlib.h>
+#include "misc.h"
+#include "msg.h"
+#include "i18n.h"
+#include "ifile.h"
+#include "para_bundle.h"
+#include "sorter.h"
+
+#define OPT_SILENT 256
+
+const char * argp_program_version = "tbl-dctrl (dctrl-tools) " VERSION;
+const char * argp_program_bug_address = MAINTAINER;
+
+static struct argp_option options[] = {
+ { "delimiter", 'd', N_("DELIM"), 0, N_("Specify a delimiter.") },
+ { "column", 'c', N_("SPEC"), 0, N_("Append the specified column.") },
+ { "copying", 'C', 0, 0, N_("Print out the copyright license.") },
+ { "errorlevel", 'l', N_("LEVEL"), 0, N_("Set debugging level to LEVEL.") },
+ { "quiet", 'q', 0, 0, N_("Do no output to stdout.") },
+ { "silent", OPT_SILENT, 0, 0, N_("Do no output to stdout.") },
+ { 0 }
+};
+
+#define MAX_FNAMES 4096
+#define MAX_COLUMNS 4096
+
+struct arguments {
+ char *delim; // NULL if not specced
+ /* True iff some column lengths are unknown and need to be
+ * calculated. */
+ _Bool need_preprocessing;
+ /* Number of columns specified */
+ size_t num_columns;
+ /* Number of file names seen. */
+ size_t num_fnames;
+ /* Columns specified on the command line. */
+ struct column {
+ char *heading;
+ size_t field_inx;
+ size_t column_width;
+ } columns[MAX_COLUMNS];
+ /* File names seen on the command line. */
+ struct ifile fname[MAX_FNAMES];
+};
+
+#define INSERT(c) do { \
+ if (len >= max) { \
+ max *= 2; \
+ rv = realloc(rv, max); \
+ if (rv == NULL) fatal_enomem(NULL); \
+ } \
+ rv[len++] = (c); \
+} while (0)
+
+size_t linewrap(char **res, char const *orig, size_t orig_len,
+ size_t col_width)
+{
+ assert(col_width > 0);
+
+ size_t max = 16;
+ char *rv = malloc(max);
+ size_t len = 0;
+
+ size_t ll = 0;
+ size_t bpo = 0, bpr = 0;
+
+ size_t num_lines = 1;
+
+ mblen(NULL, 0);
+ for (size_t i = 0; i < orig_len; /**/) {
+ if (ll == col_width) {
+ if (rv[bpr] == '\n') {
+ // no suitable breakpoint on this line,
+ // break here
+ } else {
+ assert(bpr < len);
+ len = bpr;
+ assert(bpo < i);
+ i = bpo;
+ }
+ ll = 0;
+ INSERT('\n');
+ num_lines++;
+ continue;
+ }
+ if (orig[i] == ' ' || orig[i] == '\t') {
+ // record this breakpoint
+ bpo = i;
+ bpr = len;
+ }
+ int n = mblen(orig + i, orig_len - i);
+ if (n <= 0) break;
+ for (size_t j = 0; j < n; j++) INSERT(orig[i+j]);
+ i += n;
+ ll++;
+ }
+ INSERT('\0');
+ *res = rv;
+ return num_lines;
+}
+
+
+void print_line(struct arguments *args,
+ struct fsaf_read_rv const columns[/*args->num_columns*/])
+{
+ struct print_line_data {
+ char *wrapped;
+ size_t wrapped_len;
+ size_t inx;
+ } data[args->num_columns];
+ size_t num_lines = 0;
+ for (size_t i = 0; i < args->num_columns; i++) {
+ size_t n = linewrap(&data[i].wrapped,
+ columns[i].b, columns[i].len,
+ args->columns[i].column_width);
+ if (n > num_lines) num_lines = n;
+ data[i].inx = 0;
+ data[i].wrapped_len = strlen(data[i].wrapped);
+ }
+ for (size_t i = 0; i < num_lines; i++) {
+ for (size_t j = 0; j < args->num_columns; j++) {
+ if (args->delim == NULL) {
+ fputs("| ", stdout);
+ } else if (j > 0) {
+ fputs(args->delim, stdout);
+ }
+ mblen(NULL, 0);
+ size_t k;
+ size_t m = 0;
+ for (k = data[j].inx;
+ k < data[j].wrapped_len;
+ /**/) {
+ if (data[j].wrapped[k] == '\n') {
+ k++;
+ break;
+ }
+ int n = mblen(data[j].wrapped + k,
+ data[j].wrapped_len - k);
+ for (int l = 0; l < n; l++) {
+ putchar(data[j].wrapped[k+l]);
+ }
+ if (n <= 0) n = 1;
+ k += n;
+ m++;
+ }
+
+ if (args->delim == NULL) {
+ while (m < args->columns[j].column_width) {
+ m++;
+ putchar(' ');
+ }
+ putchar(' ');
+ }
+ data[j].inx = k;
+ }
+ if (args->delim == NULL) fputs("|", stdout);
+ putchar('\n');
+ }
+ for (size_t i = 0; i < args->num_columns; i++) free(data[i].wrapped);
+}
+
+void print_head(struct arguments *args)
+{
+ if (args->delim == NULL) {
+ for (size_t i = 0; i < args->num_columns; i++) {
+ putchar('+');
+ for (size_t j = 0;
+ j < args->columns[i].column_width + 2;
+ j++) {
+ putchar('=');
+ }
+ }
+ putchar('+');
+ putchar('\n');
+ }
+
+ struct fsaf_read_rv columns[args->num_columns];
+ for (size_t i = 0; i < args->num_columns; i++) {
+ columns[i].b = args->columns[i].heading;
+ columns[i].len = strlen(columns[i].b);
+ }
+ print_line(args, columns);
+
+ if (args->delim == NULL) {
+ for (size_t i = 0; i < args->num_columns; i++) {
+ putchar('+');
+ for (size_t j = 0; j < args->columns[i].column_width + 2; j++) {
+ putchar('-');
+ }
+ }
+ putchar('+');
+ putchar('\n');
+ }
+}
+
+void print_foot(struct arguments *args)
+{
+ if (args->delim != NULL) return;
+ for (size_t i = 0; i < args->num_columns; i++) {
+ putchar('+');
+ for (size_t j = 0; j < args->columns[i].column_width + 2; j++) {
+ putchar('=');
+ }
+ }
+ putchar('+');
+ putchar('\n');
+}
+
+void handle_para(struct arguments *args, struct paragraph *para)
+{
+ struct fsaf_read_rv columns[args->num_columns];
+ for (size_t i = 0; i < args->num_columns; i++) {
+ columns[i] = get_field(para, args->columns[i].field_inx);
+ }
+ print_line(args, columns);
+}
+
+static error_t parse_opt (int key, char * arg, struct argp_state * state)
+{
+ struct arguments * args = state->input;
+ switch (key) {
+ case 'C':
+ if (!to_stdout (COPYING)) fail();
+ exit(0);
+ case 'c': {
+ char *carg = strdup(arg);
+ if (carg == NULL) fatal_enomem(0);
+ char *lens = strrchr(carg, ':');
+ if (lens != NULL) *(lens++) = '\0'; else lens = "";
+ char *fn = strchr(carg, '=');
+ if (fn != NULL) *(fn++) = '\0';
+ struct column *col = &args->columns[args->num_columns];
+ col->heading = carg;
+ col->field_inx = fieldtrie_insert(fn == NULL ? carg : fn);
+ size_t n = 0;
+ _Bool err = 0;
+ for (char const *p = lens; *p != '\0'; p++) {
+ if (!('0' <= *p && *p <= '9')) {
+ err = 1;
+ continue;
+ }
+ n = n * 10 + (*p - '0');
+ }
+ if (err) message(L_IMPORTANT, _("invalid column length"), NULL);
+ col->column_width = n > 0 ? n : -1;
+ if (n == 0) args->need_preprocessing = 1;
+ args->num_columns++;
+ }
+ break;
+ case 'd':
+ args->delim = strdup(arg);
+ if (args->delim == NULL) fatal_enomem(NULL);
+ break;
+ case 'l': {
+ int ll = str2loglevel(arg);
+ if (ll < 0)
+ {
+ message(L_FATAL, _("no such log level"), arg);
+ fail();
+ }
+ set_loglevel(ll);
+ debug_message("parse_opt: l", 0);
+ }
+ break;
+ case ARGP_KEY_ARG:
+ debug_message("parse_opt: argument", 0);
+ {
+ char const * s;
+ if (args->num_fnames >= MAX_FNAMES) {
+ message(L_FATAL, _("too many file names"), 0);
+ fail();
+ }
+ s = strdup(arg);
+ if (s == 0) fatal_enomem(0);
+ args->fname[args->num_fnames++] =
+ (struct ifile){ .mode = m_read, .s = s };
+ }
+ break;
+ case ARGP_KEY_END:
+ case ARGP_KEY_ARGS: case ARGP_KEY_INIT: case ARGP_KEY_SUCCESS:
+ case ARGP_KEY_ERROR: case ARGP_KEY_FINI: case ARGP_KEY_NO_ARGS:
+ debug_message("parse_opt: ignored", 0);
+ break;
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+static char progdoc [] =
+N_("tbl-dctrl -- tabularize Debian control files");
+
+static struct argp argp = { options, parse_opt, 0, progdoc };
+
+static size_t mbs_len(char const *mbs, size_t n, char const *fname)
+{
+ if (n == (size_t)(-1)) n = strlen(mbs);
+ size_t len = 0;
+ mblen(NULL, 0);
+ for (size_t k = 0; k < n;/**/) {
+ if (mbs[k] == '\n') break;
+ len++;
+ int delta = mblen(mbs + k, n - k);
+ if (delta <= 0) {
+ message(L_IMPORTANT, _("bad multibyte character"),
+ fname);
+ k++;
+ } else {
+ k += delta;
+ }
+ }
+ return len;
+}
+
+int main(int argc, char * argv[])
+{
+ setlocale(LC_ALL, "");
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ fieldtrie_init();
+
+ static struct arguments args;
+
+ //keys_init(&args.keys);
+ msg_set_progname(argv[0]);
+ argp_parse (&argp, argc, argv, ARGP_IN_ORDER, 0, &args);
+
+ if (args.num_fnames == 0) {
+ args.fname[args.num_fnames++] = (struct ifile){
+ .mode = m_read, .s = "-"
+ };
+ }
+
+ if (args.need_preprocessing) {
+ struct para_bundle pb;
+
+ bundle_init(&pb);
+
+ for (size_t i = 0; i < args.num_fnames; i++) {
+ bundle_slurp(&pb, args.fname[i]);
+ }
+
+ size_t n = fieldtrie_count();
+ size_t lens[n];
+ for (size_t i = 0; i < n; i++) lens[i] = 0;
+
+ for (size_t i = 0; i < pb.num_paras; i++) {
+ struct paragraph *p = pb.paras[i];
+ assert(p->nfields == n);
+ for (size_t j = 0; j < p->nfields; j++) {
+ struct fsaf_read_rv r = get_field(p, j);
+ size_t len = mbs_len(r.b, r.len,
+ p->common->fp->fname);
+ if (len > lens[j]) lens[j] = len;
+ }
+ }
+ for (size_t i = 0; i < args.num_columns; i++) {
+ size_t width = args.columns[i].column_width;
+ size_t headw = mbs_len(args.columns[i].heading, -1, 0);
+ if (width == (size_t)(-1)) width = lens[i];
+ if (headw > width) width = headw;
+ args.columns[i].column_width = width;
+ }
+ print_head(&args);
+ for (size_t i = 0; i < pb.num_paras; i++) {
+ handle_para(&args, pb.paras[i]);
+ }
+ print_foot(&args);
+ } else {
+ print_head(&args);
+ for (size_t i = 0; i < args.num_fnames; ++i) {
+ int fd;
+ struct ifile fname = args.fname[i];
+
+ if (fname.mode == m_error) continue;
+
+ fd = open_ifile(fname);
+ if (fd == -1) break;
+
+ if (!chk_ifile(fname, fd)) break;
+
+ FSAF * fp = fsaf_fdopen(fd, fname.s);
+ para_parser_t pp;
+ para_parser_init(&pp, fp, true);
+ para_t para;
+ para_init(&pp, &para);
+ while (1) {
+ para_parse_next(&para);
+ if (para_eof(&pp)) break;
+ handle_para(&args, &para);
+ }
+
+ close_ifile(fname, fd);
+ }
+ print_foot(&args);
+ }
+
+ return 0;
+}