From c048a83f5192d293094d4e0bec4ebdbd005e0bae Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sun, 26 Jul 2015 11:21:36 +0000 Subject: [PATCH] Replace GNU RCS ident with a BSD license ident MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- etc/mtree/BSD.tests.dist | 2 + gnu/usr.bin/rcs/Makefile | 4 +- gnu/usr.bin/rcs/ident/Makefile | 8 - gnu/usr.bin/rcs/ident/Makefile.depend | 19 -- gnu/usr.bin/rcs/ident/ident.1 | 182 --------------- gnu/usr.bin/rcs/ident/ident.c | 270 ----------------------- tools/build/mk/OptionalObsoleteFiles.inc | 2 - usr.bin/Makefile | 1 + usr.bin/ident/Makefile | 13 ++ usr.bin/ident/ident.1 | 68 ++++++ usr.bin/ident/ident.c | 173 +++++++++++++++ usr.bin/ident/tests/Makefile | 11 + usr.bin/ident/tests/ident.sh | 16 ++ usr.bin/ident/tests/test.in | 15 ++ usr.bin/ident/tests/test.out | 6 + usr.bin/ident/tests/testnoid | 0 16 files changed, 308 insertions(+), 482 deletions(-) delete mode 100644 gnu/usr.bin/rcs/ident/Makefile delete mode 100644 gnu/usr.bin/rcs/ident/Makefile.depend delete mode 100644 gnu/usr.bin/rcs/ident/ident.1 delete mode 100644 gnu/usr.bin/rcs/ident/ident.c create mode 100644 usr.bin/ident/Makefile create mode 100644 usr.bin/ident/ident.1 create mode 100644 usr.bin/ident/ident.c create mode 100644 usr.bin/ident/tests/Makefile create mode 100755 usr.bin/ident/tests/ident.sh create mode 100644 usr.bin/ident/tests/test.in create mode 100644 usr.bin/ident/tests/test.out create mode 100644 usr.bin/ident/tests/testnoid diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist index a8634362286b..d16bb4759f1f 100644 --- a/etc/mtree/BSD.tests.dist +++ b/etc/mtree/BSD.tests.dist @@ -528,6 +528,8 @@ .. gzip .. + ident + .. join .. jot diff --git a/gnu/usr.bin/rcs/Makefile b/gnu/usr.bin/rcs/Makefile index 4a9fd0838a07..d6a960b729f2 100644 --- a/gnu/usr.bin/rcs/Makefile +++ b/gnu/usr.bin/rcs/Makefile @@ -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 diff --git a/gnu/usr.bin/rcs/ident/Makefile b/gnu/usr.bin/rcs/ident/Makefile deleted file mode 100644 index f28f8d3c5b71..000000000000 --- a/gnu/usr.bin/rcs/ident/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -PROG= ident -SRCS= ident.c -CFLAGS+= -I${.CURDIR}/../lib -LDADD= ${LIBRCS} -DPADD= ${LIBRCS} - -.include "../../Makefile.inc" -.include diff --git a/gnu/usr.bin/rcs/ident/Makefile.depend b/gnu/usr.bin/rcs/ident/Makefile.depend deleted file mode 100644 index cab8f8fe15db..000000000000 --- a/gnu/usr.bin/rcs/ident/Makefile.depend +++ /dev/null @@ -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 - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/gnu/usr.bin/rcs/ident/ident.1 b/gnu/usr.bin/rcs/ident/ident.1 deleted file mode 100644 index 253a2ce72724..000000000000 --- a/gnu/usr.bin/rcs/ident/ident.1 +++ /dev/null @@ -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 -.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. diff --git a/gnu/usr.bin/rcs/ident/ident.c b/gnu/usr.bin/rcs/ident/ident.c deleted file mode 100644 index 9b8bf57365ec..000000000000 --- a/gnu/usr.bin/rcs/ident/ident.c +++ /dev/null @@ -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; -} diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index b3ba0ce98e32..bcee64f870cd 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -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 diff --git a/usr.bin/Makefile b/usr.bin/Makefile index fd786025fa78..cf5604c79a06 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -64,6 +64,7 @@ SUBDIR= ${_addr2line} \ hexdump \ ${_iconv} \ id \ + ident \ ipcrm \ ipcs \ join \ diff --git a/usr.bin/ident/Makefile b/usr.bin/ident/Makefile new file mode 100644 index 000000000000..49798e8251fe --- /dev/null +++ b/usr.bin/ident/Makefile @@ -0,0 +1,13 @@ +# $FreeBSD$ + +.include + +PROG= ident + +LIBADD= sbuf + +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif + +.include diff --git a/usr.bin/ident/ident.1 b/usr.bin/ident/ident.1 new file mode 100644 index 000000000000..183a578e3309 --- /dev/null +++ b/usr.bin/ident/ident.1 @@ -0,0 +1,68 @@ +.\" Copyright (c) 2015 Baptiste Daroussin +.\" 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 . diff --git a/usr.bin/ident/ident.c b/usr.bin/ident/ident.c new file mode 100644 index 000000000000..155148c2ab67 --- /dev/null +++ b/usr.bin/ident/ident.c @@ -0,0 +1,173 @@ +/*- + * Copyright (c) 2015 Baptiste Daroussin + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +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); +} diff --git a/usr.bin/ident/tests/Makefile b/usr.bin/ident/tests/Makefile new file mode 100644 index 000000000000..cc29bb8c6f8e --- /dev/null +++ b/usr.bin/ident/tests/Makefile @@ -0,0 +1,11 @@ +# $FreeBSD$ + +TESTSDIR= ${TESTSBASE}/usr.bin/ident + +ATF_TESTS_SH= ident +FILES= test.in \ + test.out \ + testnoid +FILESDIR= ${TESTSDIR} + +.include diff --git a/usr.bin/ident/tests/ident.sh b/usr.bin/ident/tests/ident.sh new file mode 100755 index 000000000000..5a3118254bfa --- /dev/null +++ b/usr.bin/ident/tests/ident.sh @@ -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 +} diff --git a/usr.bin/ident/tests/test.in b/usr.bin/ident/tests/test.in new file mode 100644 index 000000000000..634943833ce5 --- /dev/null +++ b/usr.bin/ident/tests/test.in @@ -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 $)' ' + diff --git a/usr.bin/ident/tests/test.out b/usr.bin/ident/tests/test.out new file mode 100644 index 000000000000..36cccc9b2098 --- /dev/null +++ b/usr.bin/ident/tests/test.out @@ -0,0 +1,6 @@ + $Foo: bar $ + $Foo: bar $ + $o: bar $ + $o: bar $ + $Bar:: baz $ + $Qux:: frobby zow#$ diff --git a/usr.bin/ident/tests/testnoid b/usr.bin/ident/tests/testnoid new file mode 100644 index 000000000000..e69de29bb2d1