xref: /openbsd-src/usr.bin/rcs/ident.c (revision 43003dfe3ad45d1698bed8a37f2b0f5b14f20d4f)
1 /*	$OpenBSD: ident.c,v 1.25 2007/09/09 17:22:34 ray 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 <string.h>
32 #include <unistd.h>
33 
34 #include "rcsprog.h"
35 
36 #define KEYDELIM	'$'	/* keywords delimiter */
37 #define VALDELIM	':'	/* values delimiter */
38 
39 static int found = 0;
40 static int flags = 0;
41 
42 static void	ident_file(const char *, FILE *);
43 static void	ident_line(FILE *);
44 
45 int
46 ident_main(int argc, char **argv)
47 {
48 	int i, ch, status;
49 	FILE *fp;
50 
51 	status = 0;
52 
53 	while ((ch = rcs_getopt(argc, argv, "qV")) != -1) {
54 		switch(ch) {
55 		case 'q':
56 			flags |= QUIET;
57 			break;
58 		case 'V':
59 			printf("%s\n", rcs_version);
60 			exit(0);
61 		default:
62 			(usage)();
63 			exit(1);
64 		}
65 	}
66 
67 	argc -= rcs_optind;
68 	argv += rcs_optind;
69 
70 	if (argc == 0)
71 		ident_file(NULL, stdin);
72 	else {
73 		for (i = 0; i < argc; i++) {
74 			if ((fp = fopen(argv[i], "r")) == NULL) {
75 				warn("%s", argv[i]);
76 				status = 1;
77 				continue;
78 			}
79 
80 			ident_file(argv[i], fp);
81 			(void)fclose(fp);
82 			if (i != argc - 1)
83 				printf("\n");
84 		}
85 	}
86 
87 	return (status);
88 }
89 
90 
91 static void
92 ident_file(const char *filename, FILE *fp)
93 {
94 	int c;
95 
96 	if (filename != NULL)
97 		printf("%s:\n", filename);
98 	else
99 		filename = "standard output";
100 
101 	for (c = 0; c != EOF; c = getc(fp)) {
102 		if (feof(fp) || ferror(fp))
103 			break;
104 		if (c == KEYDELIM)
105 			ident_line(fp);
106 	}
107 
108 	if (found == 0 && !(flags & QUIET))
109 		fprintf(stderr, "ident warning: no id keywords in %s\n",
110 		    filename);
111 
112 	found = 0;
113 }
114 
115 static void
116 ident_line(FILE *fp)
117 {
118 	int c;
119 	BUF *bp;
120 	size_t len;
121 
122 	bp = rcs_buf_alloc(512, BUF_AUTOEXT);
123 
124 	while ((c = getc(fp)) != VALDELIM) {
125 		if (c == EOF)
126 			goto out;
127 
128 		if (isalpha(c))
129 			rcs_buf_putc(bp, c);
130 		else
131 			goto out;
132 	}
133 
134 	rcs_buf_putc(bp, VALDELIM);
135 
136 	while ((c = getc(fp)) != KEYDELIM) {
137 		if (c == EOF)
138 			goto out;
139 
140 		if (c == '\n')
141 			goto out;
142 
143 		rcs_buf_putc(bp, c);
144 	}
145 
146 	len = rcs_buf_len(bp);
147 	if (rcs_buf_getc(bp, len - 1) != ' ')
148 		goto out;
149 
150 	/* append trailing KEYDELIM */
151 	rcs_buf_putc(bp, c);
152 
153 	/* Append newline for printing. */
154 	rcs_buf_putc(bp, '\n');
155 	printf("     %c", KEYDELIM);
156 	fflush(stdout);
157 	rcs_buf_write_fd(bp, STDOUT_FILENO);
158 
159 	found++;
160 out:
161 	if (bp != NULL)
162 		rcs_buf_free(bp);
163 }
164 
165 void
166 ident_usage(void)
167 {
168 	fprintf(stderr, "usage: ident [-qV] file ...\n");
169 }
170