Replace GNU RCS ident with a BSD license ident
Rationale: ident(1) is useful out of RCS, lot of scripts are using ident(1) and failing when base is built WITHOUT_RCS. This version is: - fully compatible with RCS 5.7 ident. - fully compatible with RCS 5.9 ident. - passes all ident test from GNU RCS 5.9 test suite This version has support for: svn extension for the Keyword id (double colon and # before last $) Différences with GNU RCS ident: - no long options as found in GNU RCS 5.9 (but not commented there). - '-V' reports nothing but has been added for compatibility. Differential Revision: https://reviews.freebsd.org/D3200 Reviewed by: pfg
This commit is contained in:
parent
da6c24e123
commit
c048a83f51
@ -528,6 +528,8 @@
|
||||
..
|
||||
gzip
|
||||
..
|
||||
ident
|
||||
..
|
||||
join
|
||||
..
|
||||
jot
|
||||
|
@ -1,3 +1,5 @@
|
||||
SUBDIR= lib ci co ident merge rcs rcsclean rcsdiff rcsmerge rlog rcsfreeze
|
||||
# $FreeBSD$
|
||||
|
||||
SUBDIR= lib ci co merge rcs rcsclean rcsdiff rcsmerge rlog rcsfreeze
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
@ -1,8 +0,0 @@
|
||||
PROG= ident
|
||||
SRCS= ident.c
|
||||
CFLAGS+= -I${.CURDIR}/../lib
|
||||
LDADD= ${LIBRCS}
|
||||
DPADD= ${LIBRCS}
|
||||
|
||||
.include "../../Makefile.inc"
|
||||
.include <bsd.prog.mk>
|
@ -1,19 +0,0 @@
|
||||
# $FreeBSD$
|
||||
# Autogenerated - do NOT edit!
|
||||
|
||||
DIRDEPS = \
|
||||
gnu/lib/csu \
|
||||
gnu/lib/libgcc \
|
||||
gnu/usr.bin/rcs/lib \
|
||||
include \
|
||||
include/xlocale \
|
||||
lib/${CSU_DIR} \
|
||||
lib/libc \
|
||||
lib/libcompiler_rt \
|
||||
|
||||
|
||||
.include <dirdeps.mk>
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# local dependencies - needed for -jN in clean tree
|
||||
.endif
|
@ -1,182 +0,0 @@
|
||||
.de Id
|
||||
.ds Rv \\$3
|
||||
.ds Dt \\$4
|
||||
.ds iD \\$3 \\$4 \\$5 \\$6 \\$7
|
||||
..
|
||||
.Id $FreeBSD$
|
||||
.ds r \&\s-1RCS\s0
|
||||
.ds u \&\s-1UTC\s0
|
||||
.if n .ds - \%--
|
||||
.if t .ds - \(em
|
||||
.TH IDENT 1 \*(Dt GNU
|
||||
.SH NAME
|
||||
ident \- identify RCS keyword strings in files
|
||||
.SH SYNOPSIS
|
||||
.B ident
|
||||
[
|
||||
.B \-q
|
||||
] [
|
||||
.B \-V
|
||||
] [
|
||||
.I file
|
||||
\&.\|.\|. ]
|
||||
.SH DESCRIPTION
|
||||
.B ident
|
||||
searches for all instances of the pattern
|
||||
.BI $ keyword : "\ text\ " $
|
||||
in the named files or, if no files are named, the standard input.
|
||||
.PP
|
||||
These patterns are normally inserted automatically by the \*r command
|
||||
.BR co (1),
|
||||
but can also be inserted manually.
|
||||
The option
|
||||
.B \-q
|
||||
suppresses
|
||||
the warning given if there are no patterns in a file.
|
||||
The option
|
||||
.B \-V
|
||||
prints
|
||||
.BR ident 's
|
||||
version number.
|
||||
.PP
|
||||
.B ident
|
||||
works on text files as well as object files and dumps.
|
||||
For example, if the C program in
|
||||
.B f.c
|
||||
contains
|
||||
.IP
|
||||
.ft 3
|
||||
#include <stdio.h>
|
||||
.br
|
||||
static char const rcsid[] =
|
||||
.br
|
||||
\&"$\&Id: f.c,v \*(iD $\&";
|
||||
.br
|
||||
int main() { return printf(\&"%s\en\&", rcsid) == EOF; }
|
||||
.ft P
|
||||
.LP
|
||||
and
|
||||
.B f.c
|
||||
is compiled into
|
||||
.BR f.o ,
|
||||
then the command
|
||||
.IP
|
||||
.B "ident f.c f.o"
|
||||
.LP
|
||||
will output
|
||||
.nf
|
||||
.IP
|
||||
.ft 3
|
||||
f.c:
|
||||
$\&Id: f.c,v \*(iD $
|
||||
f.o:
|
||||
$\&Id: f.c,v \*(iD $
|
||||
.ft
|
||||
.fi
|
||||
.PP
|
||||
If a C program defines a string like
|
||||
.B rcsid
|
||||
above but does not use it,
|
||||
.BR lint (1)
|
||||
may complain, and some C compilers will optimize away the string.
|
||||
The most reliable solution is to have the program use the
|
||||
.B rcsid
|
||||
string, as shown in the example above.
|
||||
.PP
|
||||
.B ident
|
||||
finds all instances of the
|
||||
.BI $ keyword : "\ text\ " $
|
||||
pattern, even if
|
||||
.I keyword
|
||||
is not actually an \*r-supported keyword.
|
||||
This gives you information about nonstandard keywords like
|
||||
.BR $\&XConsortium$ .
|
||||
.SH KEYWORDS
|
||||
Here is the list of keywords currently maintained by
|
||||
.BR co (1).
|
||||
All times are given in Coordinated Universal Time (\*u,
|
||||
sometimes called \&\s-1GMT\s0) by default, but if the files
|
||||
were checked out with
|
||||
.BR co 's
|
||||
.BI \-z zone
|
||||
option, times are given with a numeric time zone indication appended.
|
||||
.TP
|
||||
.B $\&Author$
|
||||
The login name of the user who checked in the revision.
|
||||
.TP
|
||||
.B $\&Date$
|
||||
The date and time the revision was checked in.
|
||||
.TP
|
||||
.B $\&Header$
|
||||
A standard header containing the full pathname of the \*r file, the
|
||||
revision number, the date and time, the author, the state,
|
||||
and the locker (if locked).
|
||||
.TP
|
||||
.B $\&Id$
|
||||
Same as
|
||||
.BR $\&Header$ ,
|
||||
except that the \*r filename is without a path.
|
||||
.TP
|
||||
.B $\&Locker$
|
||||
The login name of the user who locked the revision (empty if not locked).
|
||||
.TP
|
||||
.B $\&Log$
|
||||
The log message supplied during checkin.
|
||||
For
|
||||
.BR ident 's
|
||||
purposes, this is equivalent to
|
||||
.BR $\&RCSfile$ .
|
||||
.TP
|
||||
.B $\&Name$
|
||||
The symbolic name used to check out the revision, if any.
|
||||
.TP
|
||||
.B $\&RCSfile$
|
||||
The name of the \*r file without a path.
|
||||
.TP
|
||||
.B $\&Revision$
|
||||
The revision number assigned to the revision.
|
||||
.TP
|
||||
.B $\&Source$
|
||||
The full pathname of the \*r file.
|
||||
.TP
|
||||
.B $\&State$
|
||||
The state assigned to the revision with the
|
||||
.B \-s
|
||||
option of
|
||||
.BR rcs (1)
|
||||
or
|
||||
.BR ci (1).
|
||||
.PP
|
||||
.BR co (1)
|
||||
represents the following characters in keyword values by escape sequences
|
||||
to keep keyword strings well-formed.
|
||||
.LP
|
||||
.RS
|
||||
.nf
|
||||
.ne 6
|
||||
.ta \w'newline 'u
|
||||
\f2char escape sequence\fP
|
||||
tab \f3\et\fP
|
||||
newline \f3\en\fP
|
||||
space \f3\e040
|
||||
$ \e044
|
||||
\e \e\e\fP
|
||||
.fi
|
||||
.RE
|
||||
.SH IDENTIFICATION
|
||||
Author: Walter F. Tichy.
|
||||
.br
|
||||
Manual Page Revision: \*(Rv; Release Date: \*(Dt.
|
||||
.br
|
||||
Copyright \(co 1982, 1988, 1989 Walter F. Tichy.
|
||||
.br
|
||||
Copyright \(co 1990, 1992, 1993 Paul Eggert.
|
||||
.SH "SEE ALSO"
|
||||
ci(1), co(1), rcs(1), rcsdiff(1), rcsintro(1), rcsmerge(1), rlog(1),
|
||||
rcsfile(5)
|
||||
.br
|
||||
Walter F. Tichy,
|
||||
\*r\*-A System for Version Control,
|
||||
.I "Software\*-Practice & Experience"
|
||||
.BR 15 ,
|
||||
7 (July 1985), 637-654.
|
@ -1,270 +0,0 @@
|
||||
/* Identify RCS keyword strings in files. */
|
||||
|
||||
/* Copyright 1982, 1988, 1989 Walter Tichy
|
||||
Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
|
||||
Distributed under license by the Free Software Foundation, Inc.
|
||||
|
||||
This file is part of RCS.
|
||||
|
||||
RCS 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, or (at your option)
|
||||
any later version.
|
||||
|
||||
RCS 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 RCS; see the file COPYING.
|
||||
If not, write to the Free Software Foundation,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Report problems and direct all questions to:
|
||||
|
||||
rcs-bugs@cs.purdue.edu
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* Revision 5.9 1995/06/16 06:19:24 eggert
|
||||
* Update FSF address.
|
||||
*
|
||||
* Revision 5.8 1995/06/01 16:23:43 eggert
|
||||
* (exiterr, reportError): New functions, needed for DOS and OS/2 ports.
|
||||
* (scanfile): Use them.
|
||||
*
|
||||
* Revision 5.7 1994/03/20 04:52:58 eggert
|
||||
* Remove `exiting' from identExit.
|
||||
*
|
||||
* Revision 5.6 1993/11/09 17:40:15 eggert
|
||||
* Add -V.
|
||||
*
|
||||
* Revision 5.5 1993/11/03 17:42:27 eggert
|
||||
* Test for char == EOF, not char < 0.
|
||||
*
|
||||
* Revision 5.4 1992/01/24 18:44:19 eggert
|
||||
* lint -> RCS_lint
|
||||
*
|
||||
* Revision 5.3 1991/09/10 22:15:46 eggert
|
||||
* Open files with FOPEN_R, not FOPEN_R_WORK,
|
||||
* because they might be executables, not working files.
|
||||
*
|
||||
* Revision 5.2 1991/08/19 03:13:55 eggert
|
||||
* Report read errors immediately.
|
||||
*
|
||||
* Revision 5.1 1991/02/25 07:12:37 eggert
|
||||
* Don't report empty keywords. Check for I/O errors.
|
||||
*
|
||||
* Revision 5.0 1990/08/22 08:12:37 eggert
|
||||
* Don't limit output to known keywords.
|
||||
* Remove arbitrary limits and lint. Ansify and Posixate.
|
||||
*
|
||||
* Revision 4.5 89/05/01 15:11:54 narten
|
||||
* changed copyright header to reflect current distribution rules
|
||||
*
|
||||
* Revision 4.4 87/10/23 17:09:57 narten
|
||||
* added exit(0) so exit return code would be non random
|
||||
*
|
||||
* Revision 4.3 87/10/18 10:23:55 narten
|
||||
* Updating version numbers. Changes relative to 1.1 are actually relative
|
||||
* to 4.1
|
||||
*
|
||||
* Revision 1.3 87/07/09 09:20:52 trinkle
|
||||
* Added check to make sure there is at least one arg before comparing argv[1]
|
||||
* with "-q". This necessary on machines that don't allow dereferncing null
|
||||
* pointers (i.e. Suns).
|
||||
*
|
||||
* Revision 1.2 87/03/27 14:21:47 jenkins
|
||||
* Port to suns
|
||||
*
|
||||
* Revision 4.1 83/05/10 16:31:02 wft
|
||||
* Added option -q and input from reading stdin.
|
||||
* Marker matching is now done with trymatch() (independent of keywords).
|
||||
*
|
||||
* Revision 3.4 83/02/18 17:37:49 wft
|
||||
* removed printing of new line after last file.
|
||||
*
|
||||
* Revision 3.3 82/12/04 12:48:55 wft
|
||||
* Added LOCKER.
|
||||
*
|
||||
* Revision 3.2 82/11/28 18:24:17 wft
|
||||
* removed Suffix; added ungetc to avoid skipping over trailing KDELIM.
|
||||
*
|
||||
* Revision 3.1 82/10/13 15:58:51 wft
|
||||
* fixed type of variables receiving from getc() (char-->int).
|
||||
*/
|
||||
|
||||
#include "rcsbase.h"
|
||||
|
||||
static int match P((FILE*));
|
||||
static int scanfile P((FILE*,char const*,int));
|
||||
static void reportError P((char const*));
|
||||
|
||||
mainProg(identId, "ident", "$FreeBSD$")
|
||||
/* Ident searches the named files for all occurrences
|
||||
* of the pattern $@: text $ where @ is a keyword.
|
||||
*/
|
||||
|
||||
{
|
||||
FILE *fp;
|
||||
int quiet = 0;
|
||||
int status = EXIT_SUCCESS;
|
||||
char const *a;
|
||||
|
||||
while ((a = *++argv) && *a=='-')
|
||||
while (*++a)
|
||||
switch (*a) {
|
||||
case 'q':
|
||||
quiet = 1;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
VOID printf("RCS version %s\n", RCS_version_string);
|
||||
quiet = -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
VOID fprintf(stderr,
|
||||
"ident: usage: ident -{qV} [file...]\n"
|
||||
);
|
||||
exitmain(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (0 <= quiet)
|
||||
if (!a)
|
||||
VOID scanfile(stdin, (char*)0, quiet);
|
||||
else
|
||||
do {
|
||||
if (!(fp = fopen(a, FOPEN_RB))) {
|
||||
reportError(a);
|
||||
status = EXIT_FAILURE;
|
||||
} else if (
|
||||
scanfile(fp, a, quiet) != 0
|
||||
|| (argv[1] && putchar('\n') == EOF)
|
||||
)
|
||||
break;
|
||||
} while ((a = *++argv));
|
||||
|
||||
if (ferror(stdout) || fclose(stdout)!=0) {
|
||||
reportError("standard output");
|
||||
status = EXIT_FAILURE;
|
||||
}
|
||||
exitmain(status);
|
||||
}
|
||||
|
||||
#if RCS_lint
|
||||
# define exiterr identExit
|
||||
#endif
|
||||
void
|
||||
exiterr()
|
||||
{
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static void
|
||||
reportError(s)
|
||||
char const *s;
|
||||
{
|
||||
int e = errno;
|
||||
VOID fprintf(stderr, "%s error: ", cmdid);
|
||||
errno = e;
|
||||
perror(s);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
scanfile(file, name, quiet)
|
||||
register FILE *file;
|
||||
char const *name;
|
||||
int quiet;
|
||||
/* Function: scan an open file with descriptor file for keywords.
|
||||
* Return -1 if there's a write error; exit immediately on a read error.
|
||||
*/
|
||||
{
|
||||
register int c;
|
||||
|
||||
if (name) {
|
||||
VOID printf("%s:\n", name);
|
||||
if (ferror(stdout))
|
||||
return -1;
|
||||
} else
|
||||
name = "standard input";
|
||||
c = 0;
|
||||
while (c != EOF || ! (feof(file)|ferror(file))) {
|
||||
if (c == KDELIM) {
|
||||
if ((c = match(file)))
|
||||
continue;
|
||||
if (ferror(stdout))
|
||||
return -1;
|
||||
quiet = true;
|
||||
}
|
||||
c = getc(file);
|
||||
}
|
||||
if (ferror(file) || fclose(file) != 0) {
|
||||
reportError(name);
|
||||
/*
|
||||
* The following is equivalent to exit(EXIT_FAILURE), but we invoke
|
||||
* exiterr to keep lint happy. The DOS and OS/2 ports need exiterr.
|
||||
*/
|
||||
VOID fflush(stderr);
|
||||
VOID fflush(stdout);
|
||||
exiterr();
|
||||
}
|
||||
if (!quiet)
|
||||
VOID fprintf(stderr, "%s warning: no id keywords in %s\n", cmdid, name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
match(fp) /* group substring between two KDELIM's; then do pattern match */
|
||||
register FILE *fp;
|
||||
{
|
||||
char line[BUFSIZ];
|
||||
register int c;
|
||||
register char * tp;
|
||||
|
||||
tp = line;
|
||||
while ((c = getc(fp)) != VDELIM) {
|
||||
if (c == EOF && feof(fp) | ferror(fp))
|
||||
return c;
|
||||
switch (ctab[c]) {
|
||||
case LETTER: case Letter: case DIGIT:
|
||||
*tp++ = c;
|
||||
if (tp < line+sizeof(line)-4)
|
||||
break;
|
||||
/* fall into */
|
||||
default:
|
||||
return c ? c : '\n'/* anything but 0 or KDELIM or EOF */;
|
||||
}
|
||||
}
|
||||
if (tp == line)
|
||||
return c;
|
||||
*tp++ = c;
|
||||
if ((c = getc(fp)) != ' ')
|
||||
return c ? c : '\n';
|
||||
*tp++ = c;
|
||||
while( (c = getc(fp)) != KDELIM ) {
|
||||
if (c == EOF && feof(fp) | ferror(fp))
|
||||
return c;
|
||||
switch (ctab[c]) {
|
||||
default:
|
||||
*tp++ = c;
|
||||
if (tp < line+sizeof(line)-2)
|
||||
break;
|
||||
/* fall into */
|
||||
case NEWLN: case UNKN:
|
||||
return c ? c : '\n';
|
||||
}
|
||||
}
|
||||
if (tp[-1] != ' ')
|
||||
return c;
|
||||
*tp++ = c; /*append trailing KDELIM*/
|
||||
*tp = '\0';
|
||||
VOID printf(" %c%s\n", KDELIM, line);
|
||||
return 0;
|
||||
}
|
@ -6316,7 +6316,6 @@ OLD_FILES+=usr/share/man/man8/rwhod.8.gz
|
||||
.if ${MK_RCS} == no
|
||||
OLD_FILES+=usr/bin/ci
|
||||
OLD_FILES+=usr/bin/co
|
||||
OLD_FILES+=usr/bin/ident
|
||||
OLD_FILES+=usr/bin/merge
|
||||
OLD_FILES+=usr/bin/rcs
|
||||
OLD_FILES+=usr/bin/rcsclean
|
||||
@ -6327,7 +6326,6 @@ OLD_FILES+=usr/bin/rlog
|
||||
OLD_FILES+=usr/sbin/etcupdate
|
||||
OLD_FILES+=usr/share/man/man1/ci.1.gz
|
||||
OLD_FILES+=usr/share/man/man1/co.1.gz
|
||||
OLD_FILES+=usr/share/man/man1/ident.1.gz
|
||||
OLD_FILES+=usr/share/man/man1/merge.1.gz
|
||||
OLD_FILES+=usr/share/man/man1/rcs.1.gz
|
||||
OLD_FILES+=usr/share/man/man1/rcsclean.1.gz
|
||||
|
@ -64,6 +64,7 @@ SUBDIR= ${_addr2line} \
|
||||
hexdump \
|
||||
${_iconv} \
|
||||
id \
|
||||
ident \
|
||||
ipcrm \
|
||||
ipcs \
|
||||
join \
|
||||
|
13
usr.bin/ident/Makefile
Normal file
13
usr.bin/ident/Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include <src.opts.mk>
|
||||
|
||||
PROG= ident
|
||||
|
||||
LIBADD= sbuf
|
||||
|
||||
.if ${MK_TESTS} != "no"
|
||||
SUBDIR+= tests
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
68
usr.bin/ident/ident.1
Normal file
68
usr.bin/ident/ident.1
Normal file
@ -0,0 +1,68 @@
|
||||
.\" Copyright (c) 2015 Baptiste Daroussin <bapt@FreeBSD.org>
|
||||
.\" 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.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd Jul 25, 2015
|
||||
.Dt IDENT 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ident
|
||||
.Nd identify RCS keyword string in files
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl q
|
||||
.Op Fl V
|
||||
.Op Ar File Ns s
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility searches for all instances of the pattern
|
||||
.Sq $keyword: text$
|
||||
in
|
||||
.Ar files .
|
||||
.Pp
|
||||
If no arguments are passed, then
|
||||
.Nm
|
||||
parses the standard input.
|
||||
.Pp
|
||||
.Em keyword
|
||||
must only be composed of alphanumeric values in the C locale, followed by
|
||||
.Sq \&:
|
||||
and a space.
|
||||
.Pp
|
||||
These options are supported:
|
||||
.Bl -tag -width "XXX"
|
||||
.It Fl q
|
||||
Quiet mode: suppress warnings if no pattern found.
|
||||
.It Fl V
|
||||
Do nothing, added for compatibility with GNU ident.
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std ident
|
||||
.Sh AUTHORS
|
||||
This version of the
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Baptiste Daroussin Aq Mt bapt@FreeBSD.org .
|
173
usr.bin/ident/ident.c
Normal file
173
usr.bin/ident/ident.c
Normal file
@ -0,0 +1,173 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 Baptiste Daroussin <bapt@FreeBSD.org>
|
||||
* 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
|
||||
* in this position and unchanged.
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/sbuf.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <xlocale.h>
|
||||
|
||||
static bool
|
||||
parse_id(FILE *fp, struct sbuf *buf, locale_t l)
|
||||
{
|
||||
int c;
|
||||
bool isid = false;
|
||||
bool subversion = false;
|
||||
|
||||
sbuf_putc(buf, '$');
|
||||
while ((c = fgetc(fp)) != EOF) {
|
||||
sbuf_putc(buf, c);
|
||||
if (!isid) {
|
||||
if (c == '$') {
|
||||
sbuf_clear(buf);
|
||||
sbuf_putc(buf, '$');
|
||||
continue;
|
||||
}
|
||||
if (c == ':') {
|
||||
c = fgetc(fp);
|
||||
/* accept :: for subversion compatibility */
|
||||
if (c == ':') {
|
||||
subversion = true;
|
||||
sbuf_putc(buf, c);
|
||||
c = fgetc(fp);
|
||||
}
|
||||
if (c == ' ') {
|
||||
sbuf_putc(buf, c);
|
||||
isid = true;
|
||||
continue;
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (!isalpha_l(c, l))
|
||||
return (false);
|
||||
} else {
|
||||
if (c == '\n')
|
||||
return (false);
|
||||
if (c == '$') {
|
||||
sbuf_finish(buf);
|
||||
/* should end with a space */
|
||||
c = sbuf_data(buf)[sbuf_len(buf) - 2];
|
||||
if (!subversion) {
|
||||
if (c != ' ')
|
||||
return (0);
|
||||
} else if (subversion) {
|
||||
if (c != ' ' && c != '#')
|
||||
return (0);
|
||||
}
|
||||
printf(" %s\n", sbuf_data(buf));
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
static int
|
||||
scan(FILE *fp, const char *name, bool quiet)
|
||||
{
|
||||
int c;
|
||||
bool hasid = false;
|
||||
struct sbuf *id = sbuf_new_auto();
|
||||
locale_t l;
|
||||
|
||||
l = newlocale(LC_ALL_MASK, "C", NULL);
|
||||
|
||||
if (name != NULL)
|
||||
printf("%s:\n", name);
|
||||
|
||||
while ((c = fgetc(fp)) != EOF) {
|
||||
if (c == '$') {
|
||||
sbuf_clear(id);
|
||||
if (parse_id(fp, id, l))
|
||||
hasid = true;
|
||||
}
|
||||
}
|
||||
sbuf_delete(id);
|
||||
freelocale(l);
|
||||
|
||||
if (!hasid) {
|
||||
if (!quiet)
|
||||
fprintf(stderr, "%s warning: no id keywords in %s\n",
|
||||
getprogname(), name ? name : "standard input");
|
||||
|
||||
return (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
bool quiet = false;
|
||||
int ch, i;
|
||||
int ret = EXIT_SUCCESS;
|
||||
FILE *fp;
|
||||
|
||||
while ((ch = getopt(argc, argv, "qV")) != -1) {
|
||||
switch (ch) {
|
||||
case 'q':
|
||||
quiet = true;
|
||||
break;
|
||||
case 'V':
|
||||
/* Do nothing, compat with GNU rcs's ident */
|
||||
return (EXIT_SUCCESS);
|
||||
default:
|
||||
errx(EXIT_FAILURE, "usage: %s [-q] [-V] [file...]",
|
||||
getprogname());
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc == 0)
|
||||
return (scan(stdin, NULL, quiet));
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
fp = fopen(argv[i], "r");
|
||||
if (fp == NULL) {
|
||||
warn("%s", argv[i]);
|
||||
ret = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
if (scan(fp, argv[i], quiet) != EXIT_SUCCESS)
|
||||
ret = EXIT_FAILURE;
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
11
usr.bin/ident/tests/Makefile
Normal file
11
usr.bin/ident/tests/Makefile
Normal file
@ -0,0 +1,11 @@
|
||||
# $FreeBSD$
|
||||
|
||||
TESTSDIR= ${TESTSBASE}/usr.bin/ident
|
||||
|
||||
ATF_TESTS_SH= ident
|
||||
FILES= test.in \
|
||||
test.out \
|
||||
testnoid
|
||||
FILESDIR= ${TESTSDIR}
|
||||
|
||||
.include <bsd.test.mk>
|
16
usr.bin/ident/tests/ident.sh
Executable file
16
usr.bin/ident/tests/ident.sh
Executable file
@ -0,0 +1,16 @@
|
||||
# $FreeBSD$
|
||||
|
||||
atf_test_case ident
|
||||
ident_body() {
|
||||
atf_check -o file:$(atf_get_srcdir)/test.out \
|
||||
ident < $(atf_get_srcdir)/test.in
|
||||
atf_check -o match:'Foo.*' -s exit:1 \
|
||||
-e inline:"ident warning: no id keywords in $(atf_get_srcdir)/testnoid\n" \
|
||||
ident $(atf_get_srcdir)/test.in $(atf_get_srcdir)/testnoid
|
||||
atf_check -o match:'Foo.*' -s exit:1 \
|
||||
ident -q $(atf_get_srcdir)/test.in $(atf_get_srcdir)/testnoid
|
||||
}
|
||||
atf_init_test_cases()
|
||||
{
|
||||
atf_add_test_case ident
|
||||
}
|
15
usr.bin/ident/tests/test.in
Normal file
15
usr.bin/ident/tests/test.in
Normal file
@ -0,0 +1,15 @@
|
||||
# tranditional
|
||||
$Foo: bar $ (OK traditional)
|
||||
$$Foo: bar $
|
||||
$$Fo$o: bar $
|
||||
$Fo$o: bar $
|
||||
$ Foo : bar $ (WRONG -- NON ALPHANUM BEFORE :)
|
||||
$ Foo : bar $ (WRONG -- NON ALPHANUM BEFORE :)
|
||||
$Foo: bar $ (WRONG -- NO SPACE AFTER :)
|
||||
$Foo:bar $ (WRONG -- NO SPACE AFTER :)
|
||||
$Foo: bar$ (WRONG -- NO SPACE BEFORE $))
|
||||
# Subversion like
|
||||
$Bar:: baz$ (WRONG -- NO SPACE BEFORE $)
|
||||
$Bar:: baz $ (OK -- SPACE BEFORE $)
|
||||
$Qux:: frobby zow#$ (OK -- HASH BEFORE $)' '
|
||||
|
6
usr.bin/ident/tests/test.out
Normal file
6
usr.bin/ident/tests/test.out
Normal file
@ -0,0 +1,6 @@
|
||||
$Foo: bar $
|
||||
$Foo: bar $
|
||||
$o: bar $
|
||||
$o: bar $
|
||||
$Bar:: baz $
|
||||
$Qux:: frobby zow#$
|
0
usr.bin/ident/tests/testnoid
Normal file
0
usr.bin/ident/tests/testnoid
Normal file
Loading…
Reference in New Issue
Block a user