xref: /openbsd-src/usr.bin/rcs/ident.c (revision 91f110e064cd7c194e59e019b83bb7496c1c84d4)
1 /*	$OpenBSD: ident.c,v 1.29 2011/04/20 19:34:16 nicm Exp $	*/
2 /*
3  * Copyright (c) 2005 Xavier Santolaria <xsa@openbsd.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. The name of the author may not be used to endorse or promote products
13  *    derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include <ctype.h>
28 #include <err.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 
33 #include "rcsprog.h"
34 
35 #define KEYDELIM	'$'	/* keywords delimiter */
36 #define VALDELIM	':'	/* values delimiter */
37 
38 static int found = 0;
39 static int flags = 0;
40 
41 static void	ident_file(const char *, FILE *);
42 static void	ident_line(FILE *);
43 
44 int
45 ident_main(int argc, char **argv)
46 {
47 	int i, ch, status;
48 	FILE *fp;
49 
50 	status = 0;
51 
52 	while ((ch = rcs_getopt(argc, argv, "qV")) != -1) {
53 		switch(ch) {
54 		case 'q':
55 			flags |= QUIET;
56 			break;
57 		case 'V':
58 			printf("%s\n", rcs_version);
59 			exit(0);
60 		default:
61 			(usage)();
62 			exit(1);
63 		}
64 	}
65 
66 	argc -= rcs_optind;
67 	argv += rcs_optind;
68 
69 	if (argc == 0)
70 		ident_file(NULL, stdin);
71 	else {
72 		for (i = 0; i < argc; i++) {
73 			if ((fp = fopen(argv[i], "r")) == NULL) {
74 				warn("%s", argv[i]);
75 				status = 1;
76 				continue;
77 			}
78 
79 			ident_file(argv[i], fp);
80 			(void)fclose(fp);
81 			if (i != argc - 1)
82 				printf("\n");
83 		}
84 	}
85 
86 	return (status);
87 }
88 
89 
90 static void
91 ident_file(const char *filename, FILE *fp)
92 {
93 	int c;
94 
95 	if (filename != NULL)
96 		printf("%s:\n", filename);
97 	else
98 		filename = "standard input";
99 
100 	for (c = 0; c != EOF; c = getc(fp)) {
101 		if (feof(fp) || ferror(fp))
102 			break;
103 		if (c == KEYDELIM)
104 			ident_line(fp);
105 	}
106 
107 	if (found == 0 && !(flags & QUIET))
108 		fprintf(stderr, "ident warning: no id keywords in %s\n",
109 		    filename);
110 
111 	found = 0;
112 }
113 
114 static void
115 ident_line(FILE *fp)
116 {
117 	int c;
118 	BUF *bp;
119 	size_t len;
120 
121 	bp = buf_alloc(512);
122 
123 	while ((c = getc(fp)) != VALDELIM) {
124 		if (c == EOF)
125 			goto out;
126 
127 		if (isalpha(c))
128 			buf_putc(bp, c);
129 		else
130 			goto out;
131 	}
132 
133 	buf_putc(bp, VALDELIM);
134 
135 	while ((c = getc(fp)) != KEYDELIM) {
136 		if (c == EOF)
137 			goto out;
138 
139 		if (c == '\n')
140 			goto out;
141 
142 		buf_putc(bp, c);
143 	}
144 
145 	len = buf_len(bp);
146 	if (buf_getc(bp, len - 1) != ' ')
147 		goto out;
148 
149 	/* append trailing KEYDELIM */
150 	buf_putc(bp, c);
151 
152 	/* Append newline for printing. */
153 	buf_putc(bp, '\n');
154 	printf("     %c", KEYDELIM);
155 	fflush(stdout);
156 	buf_write_fd(bp, STDOUT_FILENO);
157 
158 	found++;
159 out:
160 	if (bp != NULL)
161 		buf_free(bp);
162 }
163 
164 void
165 ident_usage(void)
166 {
167 	fprintf(stderr, "usage: ident [-qV] [file ...]\n");
168 }
169