Importing usr.bin/mkstr

No Minix-specific changes needed.

Change-Id: I58a8e61dc300d9f54588526613dbc7aa54bf627b
This commit is contained in:
Thomas Cort 2013-10-29 11:02:13 -04:00
parent 3179b9b918
commit 69ccf97d12
6 changed files with 462 additions and 1 deletions

View File

@ -407,6 +407,7 @@
./usr/bin/mkdir minix-sys
./usr/bin/mkfifo minix-sys
./usr/bin/mkproto minix-sys obsolete
./usr/bin/mkstr minix-sys
./usr/bin/mktemp minix-sys
./usr/bin/more minix-sys
./usr/bin/mt minix-sys
@ -1992,6 +1993,7 @@
./usr/man/man1/mkfs.1 minix-sys obsolete
./usr/man/man1/mkfs.mfs.1 minix-sys
./usr/man/man1/mkproto.1 minix-sys
./usr/man/man1/mkstr.1 minix-sys
./usr/man/man1/mktemp.1 minix-sys
./usr/man/man1/more.1 minix-sys
./usr/man/man1/mount.1 minix-sys

View File

@ -188,6 +188,7 @@
2010/07/07 21:24:34,usr.bin/man
2013/10/25 12:00:00,usr.bin/mesg
2010/10/15 05:46:48,usr.bin/mkdep
2012/10/17 12:00:00,usr.bin/mkstr
2009/08/15 20:44:56,usr.bin/mktemp
2012/10/17 12:00:00,usr.bin/nbperf
2013/10/10 12:00:00,usr.bin/nice

View File

@ -16,7 +16,7 @@ SUBDIR= asa \
ldd leave \
lock login logname lorder m4 \
machine make man mesg \
mkdep mktemp \
mkdep mkstr mktemp \
\
nbperf newgrp nice nl nohup nvi \
passwd paste pathchk pr \

6
usr.bin/mkstr/Makefile Normal file
View File

@ -0,0 +1,6 @@
# $NetBSD: Makefile,v 1.3 1995/09/28 06:22:18 tls Exp $
# @(#)Makefile 8.1 (Berkeley) 6/6/93
PROG= mkstr
.include <bsd.prog.mk>

131
usr.bin/mkstr/mkstr.1 Normal file
View File

@ -0,0 +1,131 @@
.\" $NetBSD: mkstr.1,v 1.12 2012/05/12 14:52:57 reed Exp $
.\"
.\" Copyright (c) 1980, 1990, 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.
.\"
.\" @(#)mkstr.1 8.1 (Berkeley) 6/6/93
.\"
.Dd June 6, 1993
.Dt MKSTR 1
.Os
.Sh NAME
.Nm mkstr
.Nd create an error message file by massaging C source
.Sh SYNOPSIS
.Nm
.Op Fl
.Ar messagefile
.Ar prefix file ...
.Sh DESCRIPTION
.Nm
creates files containing error messages extracted from C source,
and restructures the same C source, to use the created error message
file.
The intent of
.Nm
was to reduce the size of large programs and
reduce swapping (see
.Sx BUGS
section below).
.Pp
.Nm
processes each of the specified
.Ar files ,
placing a restructured version of the input in a file whose name
consists of the specified
.Ar prefix
and the original name.
A typical usage of
.Nm
is
.Bd -literal -offset indent
mkstr pistrings xx *.c
.Ed
.Pp
This command causes all the error messages from the C source
files in the current directory to be placed in the file
.Ar pistrings
and restructured copies of the sources to be placed in
files whose names are prefixed with
.Ar \&xx .
.Pp
Options:
.Bl -tag -width indent
.It Fl
Error messages are placed at the end of the specified
message file for recompiling part of a large
.Nm
ed
program.
.El
.Pp
.Nm
finds error messages in the source by
searching for the string
.Li \&`error("'
in the input stream.
Each time it occurs, the C string starting at the
.Sq \&"\&
is stored
in the message file followed by a null character and a new-line character;
The new source is restructured with
.Xr lseek 2
pointers into the error message file for retrieval.
.Bd -literal -offset indent
char efilname = "/usr/lib/pi_strings";
int efil = -1;
error(a1, a2, a3, a4)
\&{
char buf[256];
if (efil \*[Lt] 0) {
efil = open(efilname, 0);
if (efil \*[Lt] 0) {
oops:
perror(efilname);
exit 1 ;
}
}
if (lseek(efil, a1, 0) \*[Lt] 0 || read(efil, buf, 256) \*[Le] 0)
goto oops;
printf(buf, a2, a3, a4);
}
.Ed
.Sh SEE ALSO
.Xr xstr 1 ,
.Xr lseek 2
.Sh HISTORY
.Nm
appeared in
.Bx 1 .
.Sh BUGS
.Nm
was intended for the limited architecture of the PDP-11 family.
Very few programs actually use it.
It is not an efficient method, the error messages
should be stored in the program text.

321
usr.bin/mkstr/mkstr.c Normal file
View File

@ -0,0 +1,321 @@
/* $NetBSD: mkstr.c,v 1.16 2012/03/20 20:34:58 matt Exp $ */
/*
* Copyright (c) 1980, 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.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1980, 1993\
The Regents of the University of California. All rights reserved.");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)mkstr.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: mkstr.c,v 1.16 2012/03/20 20:34:58 matt Exp $");
#endif
#endif /* not lint */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ungetchar(c) ungetc(c, stdin)
/*
* mkstr - create a string error message file by massaging C source
*
* Bill Joy UCB August 1977
*
* Modified March 1978 to hash old messages to be able to recompile
* without addding messages to the message file (usually)
*
* Based on an earlier program conceived by Bill Joy and Chuck Haley
*
* Program to create a string error message file
* from a group of C programs. Arguments are the name
* of the file where the strings are to be placed, the
* prefix of the new files where the processed source text
* is to be placed, and the files to be processed.
*
* The program looks for 'error("' in the source stream.
* Whenever it finds this, the following characters from the '"'
* to a '"' are replaced by 'seekpt' where seekpt is a
* pointer into the error message file.
* If the '(' is not immediately followed by a '"' no change occurs.
*
* The optional '-' causes strings to be added at the end of the
* existing error message file for recompilation of single routines.
*/
FILE *mesgread, *mesgwrite;
char *progname;
const char usagestr[] = "usage: %s [ - ] mesgfile prefix file ...\n";
char name[100], *np;
void process(void);
int main(int, char **);
int match(const char *);
int octdigit(char);
void inithash(void);
long hashit(const char *, char, long);
void copystr(void);
int fgetNUL(char *, int, FILE *);
int
main(int argc, char *argv[])
{
char addon = 0;
argc--, progname = *argv++;
if (argc > 1 && argv[0][0] == '-')
addon++, argc--, argv++;
if (argc < 3)
fprintf(stderr, usagestr, progname), exit(1);
mesgwrite = fopen(argv[0], addon ? "a" : "w");
if (mesgwrite == NULL)
perror(argv[0]), exit(1);
mesgread = fopen(argv[0], "r");
if (mesgread == NULL)
perror(argv[0]), exit(1);
inithash();
argc--, argv++;
strlcpy(name, argv[0], sizeof(name));
np = name + strlen(name);
argc--, argv++;
do {
strlcpy(np, argv[0], sizeof(name) - (np - name));
if (freopen(name, "w", stdout) == NULL)
perror(name), exit(1);
if (freopen(argv[0], "r", stdin) == NULL)
perror(argv[0]), exit(1);
process();
argc--, argv++;
} while (argc > 0);
exit(0);
}
void
process(void)
{
int c;
for (;;) {
c = getchar();
if (c == EOF)
return;
if (c != 'e') {
putchar(c);
continue;
}
if (match("error(")) {
printf("error(");
c = getchar();
if (c != '"')
putchar(c);
else
copystr();
}
}
}
int
match(const char *ocp)
{
const char *cp;
int c;
for (cp = ocp + 1; *cp; cp++) {
c = getchar();
if (c != *cp) {
while (ocp < cp)
putchar(*ocp++);
ungetchar(c);
return (0);
}
}
return (1);
}
void
copystr(void)
{
int c, ch;
char buf[512];
char *cp = buf;
for (;;) {
c = getchar();
if (c == EOF)
break;
switch (c) {
case '"':
*cp++ = 0;
goto out;
case '\\':
c = getchar();
switch (c) {
case 'b':
c = '\b';
break;
case 't':
c = '\t';
break;
case 'r':
c = '\r';
break;
case 'n':
c = '\n';
break;
case '\n':
continue;
case 'f':
c = '\f';
break;
case '0':
c = 0;
break;
case '\\':
break;
default:
if (!octdigit(c))
break;
c -= '0';
ch = getchar();
if (!octdigit(ch))
break;
c <<= 7, c += ch - '0';
ch = getchar();
if (!octdigit(ch))
break;
c <<= 3, c+= ch - '0', ch = -1;
break;
}
}
*cp++ = c;
}
out:
*cp = 0;
printf("%ld", hashit(buf, 1, 0));
}
int
octdigit(char c)
{
return (c >= '0' && c <= '7');
}
void
inithash(void)
{
char buf[512];
long mesgpt = 0;
rewind(mesgread);
while (fgetNUL(buf, sizeof buf, mesgread) != 0) {
hashit(buf, 0, mesgpt);
mesgpt += strlen(buf) + 2;
}
}
#define NBUCKETS 511
struct hash {
long hval;
long hpt;
struct hash *hnext;
} *bucket[NBUCKETS];
long
hashit(const char *str, char really, long fakept)
{
int i;
struct hash *hp;
char buf[512];
long hashval = 0;
const char *cp;
#ifdef __GNUC__
hp = NULL; /* XXX gcc */
#endif
if (really)
fflush(mesgwrite);
for (cp = str; *cp;)
hashval = (hashval << 1) + *cp++;
i = hashval % NBUCKETS;
if (i < 0)
i += NBUCKETS;
if (really != 0)
for (hp = bucket[i]; hp != 0; hp = hp->hnext)
if (hp->hval == hashval) {
fseek(mesgread, hp->hpt, 0);
fgetNUL(buf, sizeof buf, mesgread);
/*
fprintf(stderr, "Got (from %ld) %s\n", hp->hpt, buf);
*/
if (strcmp(buf, str) == 0)
break;
}
if (!really || hp == 0) {
hp = (struct hash *) calloc(1, sizeof *hp);
hp->hnext = bucket[i];
hp->hval = hashval;
hp->hpt = really ? ftell(mesgwrite) : fakept;
if (really) {
fwrite(str, sizeof (char), strlen(str) + 1, mesgwrite);
fwrite("\n", sizeof (char), 1, mesgwrite);
}
bucket[i] = hp;
}
/*
fprintf(stderr, "%s hashed to %ld at %ld\n", str, hp->hval, hp->hpt);
*/
return (hp->hpt);
}
#include <sys/types.h>
#include <sys/stat.h>
int
fgetNUL(char *obuf, int rmdr, FILE *file)
{
int c;
char *buf = obuf;
while (--rmdr > 0 && (c = getc(file)) != 0 && c != EOF)
*buf++ = c;
*buf++ = 0;
getc(file);
return ((feof(file) || ferror(file)) ? 0 : 1);
}