diff options
author | Christian Neukirchen <chneukirchen@gmail.com> | 2014-07-30 18:25:14 +0200 |
---|---|---|
committer | Christian Neukirchen <chneukirchen@gmail.com> | 2014-07-31 16:00:16 +0200 |
commit | d6872925c8b6b13b59a1ece32416aa8ef9c12c70 (patch) | |
tree | f9d4d6c4152241476dbd1eb3c8765908c065b147 /src/usr.bin/lam | |
download | outils-d6872925c8b6b13b59a1ece32416aa8ef9c12c70.tar.gz outils-d6872925c8b6b13b59a1ece32416aa8ef9c12c70.tar.xz outils-d6872925c8b6b13b59a1ece32416aa8ef9c12c70.zip |
initial import of OpenBSD tools
Diffstat (limited to 'src/usr.bin/lam')
-rw-r--r-- | src/usr.bin/lam/Makefile | 5 | ||||
-rw-r--r-- | src/usr.bin/lam/lam.1 | 124 | ||||
-rw-r--r-- | src/usr.bin/lam/lam.c | 231 |
3 files changed, 360 insertions, 0 deletions
diff --git a/src/usr.bin/lam/Makefile b/src/usr.bin/lam/Makefile new file mode 100644 index 0000000..956087c --- /dev/null +++ b/src/usr.bin/lam/Makefile @@ -0,0 +1,5 @@ +# $OpenBSD: Makefile,v 1.3 1997/09/21 11:49:24 deraadt Exp $ + +PROG= lam + +.include <bsd.prog.mk> diff --git a/src/usr.bin/lam/lam.1 b/src/usr.bin/lam/lam.1 new file mode 100644 index 0000000..80a7846 --- /dev/null +++ b/src/usr.bin/lam/lam.1 @@ -0,0 +1,124 @@ +.\" $OpenBSD: lam.1,v 1.8 2009/08/16 09:41:08 sobrado Exp $ +.\" $NetBSD: lam.1,v 1.4 2002/02/08 01:36:25 ross Exp $ +.\" +.\" Copyright (c) 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)lam.1 8.1 (Berkeley) 6/6/93 +.\" +.Dd $Mdocdate: August 16 2009 $ +.Dt LAM 1 +.Os +.Sh NAME +.Nm lam +.Nd laminate files +.Sh SYNOPSIS +.Nm +.Op Fl f Ar min.max +.Op Fl p Ar min.max +.Op Fl s Ar sepstring +.Op Fl t Ar c +.Ar +.Sh DESCRIPTION +.Nm +copies the named files side by side onto the standard output. +The +.Em n Ns -th +input lines from the input +.Ar files +are considered fragments of the single long +.Em n Ns -th +output line into which they are assembled. +The name +.Dq \&- +means the standard input, and may be repeated. +.Pp +Normally, each option affects only the +.Ar file +after it. +If the option letter is capitalized it affects all subsequent files +until it appears again uncapitalized. +The options are described below. +.Bl -tag -width "-s sepstring" +.It Fl f Ar min.max +Print line fragments according to the format string +.Ar min.max , +where +.Ar min +is the minimum field width and +.Ar max +the maximum field width. +If +.Ar min +begins with a zero, zeros will be added to make up the field width, +and if it begins with a +.Sq \&- , +the fragment will be left-adjusted +within the field. +.It Fl p Ar min.max +Like +.Fl f , +but pad this file's field when end-of-file is reached +and other files are still active. +.It Fl s Ar sepstring +Print +.Ar sepstring +before printing line fragments from the next file. +This option may appear after the last file. +.It Fl t Ar c +The input line terminator is +.Ar c +instead of a newline. +The newline normally appended to each output line is omitted. +.El +.Pp +To print files simultaneously for easy viewing use +.Xr pr 1 . +.Sh EXAMPLES +Join four files together along each line: +.Pp +.Dl $ lam file1 file2 file3 file4 +.Pp +Merge the lines from four different files: +.Bd -literal -offset indent +$ lam file1 \-S "\e +" file2 file3 file4 +.Ed +.Pp +Join every two lines of a file: +.Pp +.Dl $ lam \- \- \*(Lt file +.Pp +A form letter with substitutions keyed by +.Sq \&@ +can be done with: +.Pp +.Dl $ lam \-t @ letter changes +.Sh SEE ALSO +.Xr join 1 , +.Xr pr 1 , +.Xr printf 1 diff --git a/src/usr.bin/lam/lam.c b/src/usr.bin/lam/lam.c new file mode 100644 index 0000000..8787795 --- /dev/null +++ b/src/usr.bin/lam/lam.c @@ -0,0 +1,231 @@ +/* $OpenBSD: lam.c,v 1.16 2013/11/20 21:22:17 deraadt Exp $ */ +/* $NetBSD: lam.c,v 1.2 1994/11/14 20:27:42 jtc Exp $ */ + +/*- + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * lam - laminate files + * Author: John Kunze, UCB + */ + +#include <sys/param.h> + +#include <ctype.h> +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define BIGBUFSIZ 5 * BUFSIZ + +struct openfile { /* open file structure */ + FILE *fp; /* file pointer */ + short eof; /* eof flag */ + short pad; /* pad flag for missing columns */ + char eol; /* end of line character */ + char *sepstring; /* string to print before each line */ + char *format; /* printf(3) style string spec. */ +} input[NOFILE_MAX + 1]; /* last one is for the last -s arg. */ +#define INPUTSIZE sizeof(input) / sizeof(*input) + +int numfiles; /* number of open files */ +int nofinalnl; /* normally append \n to each output line */ +char line[BIGBUFSIZ]; +char *linep; + +void usage(void); +char *gatherline(struct openfile *); +void getargs(int, char *[]); +char *pad(struct openfile *); + +int +main(int argc, char *argv[]) +{ + int i; + + /* Process arguments, set numfiles to file argument count. */ + getargs(argc, argv); + if (numfiles == 0) + usage(); + /* Concatenate lines from each file, then print. */ + for (;;) { + linep = line; + /* + * For each file that has a line to print, numfile is + * incremented. Thus if numfiles is 0, we are done. + */ + numfiles = 0; + for (i = 0; i < INPUTSIZE - 1 && input[i].fp != NULL; i++) + linep = gatherline(&input[i]); + if (numfiles == 0) + exit(0); + fputs(line, stdout); + /* Print terminating -s argument. */ + fputs(input[i].sepstring, stdout); + if (!nofinalnl) + putchar('\n'); + } +} + +void +getargs(int argc, char *argv[]) +{ + struct openfile *ip = input; + char *p; + int ch, P, S, F, T; + size_t siz; + + P = S = F = T = 0; /* capitalized options */ + while (optind < argc) { + switch (ch = getopt(argc, argv, "F:f:P:p:S:s:T:t:")) { + case 'F': case 'f': + F = (ch == 'F'); + /* Validate format string argument. */ + for (p = optarg; *p != '\0'; p++) + if (!isdigit((unsigned char)*p) && + *p != '.' && *p != '-') + errx(1, "%s: invalid width specified", + optarg); + /* '%' + width + 's' + '\0' */ + siz = p - optarg + 3; + if ((p = realloc(ip->format, siz)) == NULL) + err(1, NULL); + snprintf(p, siz, "%%%ss", optarg); + ip->format = p; + break; + case 'P': case 'p': + P = (ch == 'P'); + ip->pad = 1; + break; + case 'S': case 's': + S = (ch == 'S'); + ip->sepstring = optarg; + break; + case 'T': case 't': + T = (ch == 'T'); + if (strlen(optarg) != 1) + usage(); + ip->eol = optarg[0]; + nofinalnl = 1; + break; + case -1: + if (optind >= argc) + break; /* to support "--" */ + /* This is a file, not a flag. */ + ++numfiles; + if (numfiles >= INPUTSIZE) + errx(1, "too many files"); + if (strcmp(argv[optind], "-") == 0) + ip->fp = stdin; + else if ((ip->fp = fopen(argv[optind], "r")) == NULL) + err(1, "%s", argv[optind]); + ip->pad = P; + if (ip->sepstring == NULL) + ip->sepstring = S ? (ip-1)->sepstring : ""; + if (ip->format == NULL) + ip->format = (P || F) ? (ip-1)->format : "%s"; + if (ip->eol == '\0') + ip->eol = T ? (ip-1)->eol : '\n'; + ip++; + optind++; + break; + default: + usage(); + /* NOTREACHED */ + } + } + ip->fp = NULL; + if (ip->sepstring == NULL) + ip->sepstring = ""; +} + +char * +pad(struct openfile *ip) +{ + size_t n; + char *lp = linep; + + n = strlcpy(lp, ip->sepstring, line + sizeof(line) - lp); + lp += (n < line + sizeof(line) - lp) ? n : strlen(lp); + if (ip->pad) { + n = snprintf(lp, line + sizeof(line) - lp, ip->format, ""); + if (n > 0) + lp += (n < line + sizeof(line) - lp) ? n : strlen(lp); + } + return (lp); +} + +/* + * Grab line from file, appending to linep. Increments numfiles if file + * is still open. + */ +char * +gatherline(struct openfile *ip) +{ + size_t n; + char s[BUFSIZ]; + char *p; + char *lp = linep; + char *end = s + BUFSIZ - 1; + int c; + + if (ip->eof) + return (pad(ip)); + for (p = s; (c = fgetc(ip->fp)) != EOF && p < end; p++) + if ((*p = c) == ip->eol) + break; + *p = '\0'; + if (c == EOF) { + ip->eof = 1; + if (ip->fp == stdin) + fclose(stdin); + return (pad(ip)); + } + /* Something will be printed. */ + numfiles++; + n = strlcpy(lp, ip->sepstring, line + sizeof(line) - lp); + lp += (n < line + sizeof(line) - lp) ? n : strlen(lp); + n = snprintf(lp, line + sizeof(line) - lp, ip->format, s); + if (n > 0) + lp += (n < line + sizeof(line) - lp) ? n : strlen(lp); + return (lp); +} + +void +usage(void) +{ + extern char *__progname; + + fprintf(stderr, + "usage: %s [-f min.max] [-p min.max] [-s sepstring] [-t c] file ...\n", + __progname); + exit(1); +} |