[Dctrl-tools-devel] CVS dctrl-tools
CVS User ajk
ajk at haydn.debian.org
Thu Jul 21 09:53:18 UTC 2005
Update of /cvsroot/dctrl-tools/dctrl-tools
In directory haydn:/tmp/cvs-serv18832
Modified Files:
Makefile fsaf.c fsaf.h grep-dctrl.c para_bundle.c
Added Files:
tbl-dctrl.c
Log Message:
new program tbl-dctrl and assorted fixes
--- /cvsroot/dctrl-tools/dctrl-tools/Makefile 2005/06/08 21:33:54 1.25
+++ /cvsroot/dctrl-tools/dctrl-tools/Makefile 2005/07/21 09:53:18 1.26
@@ -19,7 +19,7 @@
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 @@
# 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 @@
sort-dctrl : sort-dctrl.o libdctrl.a
+tbl-dctrl : tbl-dctrl.o libdctrl.a
+
% : %.o
$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS)
--- /cvsroot/dctrl-tools/dctrl-tools/fsaf.c 2004/07/15 17:07:57 1.5
+++ /cvsroot/dctrl-tools/dctrl-tools/fsaf.c 2005/07/21 09:53:18 1.6
@@ -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 @@
return;
}
#endif
+ free(fp->fname);
free(fp->buf);
free(fp);
}
--- /cvsroot/dctrl-tools/dctrl-tools/fsaf.h 2004/07/15 17:07:57 1.5
+++ /cvsroot/dctrl-tools/dctrl-tools/fsaf.h 2005/07/21 09:53:18 1.6
@@ -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 @@
/* 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 *);
--- /cvsroot/dctrl-tools/dctrl-tools/grep-dctrl.c 2005/06/08 18:13:29 1.31
+++ /cvsroot/dctrl-tools/dctrl-tools/grep-dctrl.c 2005/07/21 09:53:18 1.32
@@ -770,7 +770,7 @@
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;
--- /cvsroot/dctrl-tools/dctrl-tools/para_bundle.c 2004/08/02 04:19:57 1.2
+++ /cvsroot/dctrl-tools/dctrl-tools/para_bundle.c 2005/07/21 09:53:18 1.3
@@ -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);
--- /cvsroot/dctrl-tools/dctrl-tools/tbl-dctrl.c 2005/07/21 09:53:18 NONE
+++ /cvsroot/dctrl-tools/dctrl-tools/tbl-dctrl.c 2005/07/21 09:53:18 1.1
/* 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;
[37 lines skipped]
More information about the Dctrl-tools-devel
mailing list