xref: /openbsd-src/usr.bin/rcs/ident.c (revision 099bc3622b4e1de69ecf60616221f4e660477a82)
1*099bc362Sguenther /*	$OpenBSD: ident.c,v 1.32 2016/08/26 09:02:54 guenther Exp $	*/
2c6e1ac21Sjoris /*
3c6e1ac21Sjoris  * Copyright (c) 2005 Xavier Santolaria <xsa@openbsd.org>
4c6e1ac21Sjoris  * All rights reserved.
5c6e1ac21Sjoris  *
6c6e1ac21Sjoris  * Redistribution and use in source and binary forms, with or without
7c6e1ac21Sjoris  * modification, are permitted provided that the following conditions
8c6e1ac21Sjoris  * are met:
9c6e1ac21Sjoris  *
10c6e1ac21Sjoris  * 1. Redistributions of source code must retain the above copyright
11c6e1ac21Sjoris  *    notice, this list of conditions and the following disclaimer.
12c6e1ac21Sjoris  * 2. The name of the author may not be used to endorse or promote products
13c6e1ac21Sjoris  *    derived from this software without specific prior written permission.
14c6e1ac21Sjoris  *
15c6e1ac21Sjoris  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16c6e1ac21Sjoris  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17c6e1ac21Sjoris  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18c6e1ac21Sjoris  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19c6e1ac21Sjoris  * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20c6e1ac21Sjoris  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21c6e1ac21Sjoris  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22c6e1ac21Sjoris  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23c6e1ac21Sjoris  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24c6e1ac21Sjoris  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25c6e1ac21Sjoris  */
26c6e1ac21Sjoris 
274781e2faSxsa #include <ctype.h>
284781e2faSxsa #include <err.h>
294781e2faSxsa #include <stdio.h>
304781e2faSxsa #include <stdlib.h>
31*099bc362Sguenther #include <time.h>
324781e2faSxsa #include <unistd.h>
33c6e1ac21Sjoris 
34c6e1ac21Sjoris #include "rcsprog.h"
35c6e1ac21Sjoris 
36c15aa039Sxsa #define KEYDELIM	'$'	/* keywords delimiter */
37c15aa039Sxsa #define VALDELIM	':'	/* values delimiter */
38c6e1ac21Sjoris 
39cf1aeb06Sjoris static int found = 0;
40913586deSxsa static int flags = 0;
41c6e1ac21Sjoris 
4230bf5e11Sxsa static void	ident_file(const char *, FILE *);
4330bf5e11Sxsa static void	ident_line(FILE *);
44c6e1ac21Sjoris 
45c6e1ac21Sjoris int
ident_main(int argc,char ** argv)46c6e1ac21Sjoris ident_main(int argc, char **argv)
47c6e1ac21Sjoris {
4874fdd43aSray 	int i, ch, status;
49c6e1ac21Sjoris 	FILE *fp;
50c6e1ac21Sjoris 
5174fdd43aSray 	status = 0;
5274fdd43aSray 
53a2b34663Sjoris 	while ((ch = rcs_getopt(argc, argv, "qV")) != -1) {
54c6e1ac21Sjoris 		switch(ch) {
55c6e1ac21Sjoris 		case 'q':
56913586deSxsa 			flags |= QUIET;
57c6e1ac21Sjoris 			break;
58c6e1ac21Sjoris 		case 'V':
59c6e1ac21Sjoris 			printf("%s\n", rcs_version);
60c6e1ac21Sjoris 			exit(0);
61c6e1ac21Sjoris 		default:
62c6e1ac21Sjoris 			(usage)();
63c6e1ac21Sjoris 		}
64c6e1ac21Sjoris 	}
65c6e1ac21Sjoris 
66a2b34663Sjoris 	argc -= rcs_optind;
67a2b34663Sjoris 	argv += rcs_optind;
68c6e1ac21Sjoris 
6996b8bf5aSxsa 	if (argc == 0)
70c6e1ac21Sjoris 		ident_file(NULL, stdin);
7196b8bf5aSxsa 	else {
72c6e1ac21Sjoris 		for (i = 0; i < argc; i++) {
73c6e1ac21Sjoris 			if ((fp = fopen(argv[i], "r")) == NULL) {
7482ca7eaaSxsa 				warn("%s", argv[i]);
7574fdd43aSray 				status = 1;
76c6e1ac21Sjoris 				continue;
77c6e1ac21Sjoris 			}
78c6e1ac21Sjoris 
79c6e1ac21Sjoris 			ident_file(argv[i], fp);
8082ca7eaaSxsa 			(void)fclose(fp);
8174fdd43aSray 			if (i != argc - 1)
8274fdd43aSray 				printf("\n");
83c6e1ac21Sjoris 		}
84c6e1ac21Sjoris 	}
85c6e1ac21Sjoris 
8674fdd43aSray 	return (status);
87c6e1ac21Sjoris }
88c6e1ac21Sjoris 
89c6e1ac21Sjoris 
9030bf5e11Sxsa static void
ident_file(const char * filename,FILE * fp)91c6e1ac21Sjoris ident_file(const char *filename, FILE *fp)
92c6e1ac21Sjoris {
93c6e1ac21Sjoris 	int c;
94c6e1ac21Sjoris 
95c344b8d6Sxsa 	if (filename != NULL)
96c6e1ac21Sjoris 		printf("%s:\n", filename);
97c344b8d6Sxsa 	else
9884eee8cfSsobrado 		filename = "standard input";
99c6e1ac21Sjoris 
1007249ec9bSderaadt 	for (c = 0; c != EOF; c = getc(fp)) {
1017249ec9bSderaadt 		if (feof(fp) || ferror(fp))
102c6e1ac21Sjoris 			break;
103c6e1ac21Sjoris 		if (c == KEYDELIM)
104c6e1ac21Sjoris 			ident_line(fp);
105c6e1ac21Sjoris 	}
106c6e1ac21Sjoris 
107913586deSxsa 	if (found == 0 && !(flags & QUIET))
108c344b8d6Sxsa 		fprintf(stderr, "ident warning: no id keywords in %s\n",
109c344b8d6Sxsa 		    filename);
110c344b8d6Sxsa 
111c344b8d6Sxsa 	found = 0;
112c6e1ac21Sjoris }
113c6e1ac21Sjoris 
11430bf5e11Sxsa static void
ident_line(FILE * fp)115c6e1ac21Sjoris ident_line(FILE *fp)
116c6e1ac21Sjoris {
117c6e1ac21Sjoris 	int c;
1188958bb4aSjoris 	BUF *bp;
1198958bb4aSjoris 	size_t len;
120c6e1ac21Sjoris 
1210ee14128Sray 	bp = buf_alloc(512);
122c6e1ac21Sjoris 
123c6e1ac21Sjoris 	while ((c = getc(fp)) != VALDELIM) {
1249d739794Sray 		if (c == EOF)
1258958bb4aSjoris 			goto out;
126c6e1ac21Sjoris 
127c6e1ac21Sjoris 		if (isalpha(c))
1287bb3ddb0Sray 			buf_putc(bp, c);
129c6e1ac21Sjoris 		else
1308958bb4aSjoris 			goto out;
131c6e1ac21Sjoris 	}
132c6e1ac21Sjoris 
1337bb3ddb0Sray 	buf_putc(bp, VALDELIM);
134c6e1ac21Sjoris 
135c6e1ac21Sjoris 	while ((c = getc(fp)) != KEYDELIM) {
1369d739794Sray 		if (c == EOF)
1378958bb4aSjoris 			goto out;
138c6e1ac21Sjoris 
139c6e1ac21Sjoris 		if (c == '\n')
1408958bb4aSjoris 			goto out;
141c6e1ac21Sjoris 
1427bb3ddb0Sray 		buf_putc(bp, c);
143c6e1ac21Sjoris 	}
144c6e1ac21Sjoris 
1457bb3ddb0Sray 	len = buf_len(bp);
1467bb3ddb0Sray 	if (buf_getc(bp, len - 1) != ' ')
1478958bb4aSjoris 		goto out;
148c6e1ac21Sjoris 
149c6e1ac21Sjoris 	/* append trailing KEYDELIM */
1507bb3ddb0Sray 	buf_putc(bp, c);
15151c4a85dSray 
15251c4a85dSray 	/* Append newline for printing. */
1537bb3ddb0Sray 	buf_putc(bp, '\n');
15451c4a85dSray 	printf("     %c", KEYDELIM);
155fc4cb550Sray 	fflush(stdout);
1567bb3ddb0Sray 	buf_write_fd(bp, STDOUT_FILENO);
157c6e1ac21Sjoris 
158cf1aeb06Sjoris 	found++;
1598958bb4aSjoris out:
1607bb3ddb0Sray 	buf_free(bp);
161c6e1ac21Sjoris }
162c6e1ac21Sjoris 
163960e00beSotto __dead void
ident_usage(void)164c6e1ac21Sjoris ident_usage(void)
165c6e1ac21Sjoris {
16684eee8cfSsobrado 	fprintf(stderr, "usage: ident [-qV] [file ...]\n");
167960e00beSotto 
168960e00beSotto 	exit(1);
169c6e1ac21Sjoris }
170