1 /* btdt.c --- been there done that
2
3 Copyright (C) 2010-2020 Thien-Thi Nguyen
4
5 This file is part of GNU RCS.
6
7 GNU RCS is free software: you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 GNU RCS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty
14 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 See the GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "base.h"
22 #include <string.h>
23 #include <stdlib.h>
24 #include "stat-time.h"
25 #include "timespec.h"
26 #include "b-complain.h"
27 #include "b-divvy.h"
28 #include "b-esds.h"
29 #include "b-feph.h"
30 #include "b-fro.h"
31 #include "b-grok.h"
32
33 /* This program serves as a collection of test-support commands
34 (to be invoked from the t??? files) for various components of
35 the RCS library. */
36
37 struct top *top;
38
39 exiting void
bad_args(char const * argv0)40 bad_args (char const *argv0)
41 {
42 fprintf (stderr, "%s: bad args (try %s --help)\n",
43 argv0, PROGRAM (invoke));
44 _Exit (EXIT_FAILURE);
45 }
46
47 #define MORE "\n\t\t"
48
49
50 /* ‘getoldkeys’ */
51
52 /* Print the keyword values found. */
53
54 char const getoldkeys_usage[] =
55 "WORKING-FILE";
56
57 void
getoldkeys_spew(char const * what,char * s)58 getoldkeys_spew (char const *what, char *s)
59 {
60 if (s)
61 printf ("%s: %zu \"%s\"\n", what, strlen (s), s);
62 }
63
64 int
getoldkeys_do_it(int argc,char * argv[VLA_ELEMS (argc)])65 getoldkeys_do_it (int argc, char *argv[VLA_ELEMS (argc)])
66 {
67 if (2 > argc)
68 bad_args (argv[0]);
69
70 MANI (filename) = argv[1];
71 getoldkeys (NULL);
72 printf ("valid: %s\n", PREV (valid) ? "true" : "false");
73 getoldkeys_spew ("revno", PREV (rev));
74 getoldkeys_spew ("date", PREV (date));
75 getoldkeys_spew ("author", PREV (author));
76 getoldkeys_spew ("name", PREV (name));
77 getoldkeys_spew ("state", PREV (state));
78 return EXIT_SUCCESS;
79 }
80
81
82 /* ‘grok_all’ */
83
84 /* Parse an RCS file and display different aspects of the result. */
85
86 char const grok_usage[] =
87 "RCS-FILE [ASPECT...]"
88 MORE "where ASPECT is one of:"
89 MORE " edits-order";
90
91 int
grok_do_it(int argc,char * argv[VLA_ELEMS (argc)])92 grok_do_it (int argc, char *argv[VLA_ELEMS (argc)])
93 {
94 int i;
95 struct fro *f;
96
97 REPO (filename) = argv[1]; /* FIXME: for ‘RERR’ */
98 if (! (f = fro_open (argv[1], "r", NULL)))
99 RERR ("cannot open %s", argv[1]);
100 if (! (REPO (r) = grok_all (SINGLE, f)))
101 RERR ("grok_all failed for %s", argv[1]);
102
103 for (i = 2; i < argc; i++)
104 {
105 struct delta *d;
106 char const *aspect = argv[i];
107
108 printf ("%s:\n", aspect);
109 if (STR_SAME ("edits-order", aspect))
110 for (struct wlink *ls = GROK (deltas); ls; ls = ls->next)
111 {
112 d = ls->entry;
113 printf ("%s\n", d->num);
114 }
115 else
116 bad_args (argv[0]);
117 }
118
119 return EXIT_SUCCESS;
120 }
121
122
123 /* xorlf */
124
125 /* XOR stdin with LF (aka '\n', 012, 0xA) to stdout. */
126
127 char const xorlf_usage[] =
128 "";
129
130 int
xorlf_do_it(int argc,char * argv[VLA_ELEMS (argc)]RCS_UNUSED)131 xorlf_do_it (int argc, char *argv[VLA_ELEMS (argc)] RCS_UNUSED)
132 {
133 int c;
134
135 while (EOF != (c = getchar ()))
136 putchar (c ^ 012);
137 return EXIT_SUCCESS;
138 }
139
140
141 /* mtimecmp */
142
143 /* Consider mtime of both FILE1 and FILE2 as M1 and M2.
144 If M1 < M2, display "-1" to stdout.
145 If M1 = M2, display "0" to stdout.
146 If M1 > M2, display "1" to stdout. */
147
148 char const mtimecmp_usage[] =
149 "FILE1 FILE2";
150
151 struct timespec
mtimecmp_grok(char const * filename)152 mtimecmp_grok (char const *filename)
153 {
154 struct stat st;
155
156 if (PROB (stat (filename, &st)))
157 {
158 fprintf (stderr, "mtimecmp: could not stat %s\n",
159 filename);
160 _Exit (EXIT_FAILURE);
161 }
162
163 return get_stat_mtime (&st);
164 }
165
166 int
mtimecmp_do_it(int argc,char * argv[VLA_ELEMS (argc)])167 mtimecmp_do_it (int argc, char *argv[VLA_ELEMS (argc)])
168 {
169 struct timespec m1, m2;
170 long int sign;
171
172 if (3 > argc)
173 bad_args (argv[0]);
174
175 m1 = mtimecmp_grok (argv[1]);
176 m2 = mtimecmp_grok (argv[2]);
177
178 sign = timespec_cmp (m1, m2);
179 if (0 > sign) sign = -1;
180 if (0 < sign) sign = 1;
181
182 printf ("%ld\n", sign);
183 return EXIT_SUCCESS;
184 }
185
186
187 typedef int (main_t) (int argc, char *argv[VLA_ELEMS (argc)]);
188
189 struct yeah
190 {
191 char const *component;
192 char const *usage;
193 main_t *whatever;
194 bool scram;
195 };
196
197 #define YEAH(comp,out) { #comp, comp ## _usage, comp ## _do_it, out }
198
199 struct yeah yeah[] =
200 {
201 YEAH (getoldkeys, true),
202 YEAH (grok, true),
203 YEAH (xorlf, true),
204 YEAH (mtimecmp, true),
205 };
206
207 #define NYEAH (sizeof (yeah) / sizeof (struct yeah))
208
209 int
main(int argc,char * argv[VLA_ELEMS (argc)])210 main (int argc, char *argv[VLA_ELEMS (argc)])
211 {
212 char const *me = "btdt";
213
214 if (STR_SAME ("--version", argv[1]))
215 {
216 printf ("btdt (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
217 printf ("Copyright (C) 2010-2020 Thien-Thi Nguyen\n");
218 printf ("License GPLv3+; GNU GPL version 3 or later"
219 " <http://gnu.org/licenses/gpl.html>\n\n");
220 argv[1] = "--help";
221 /* fall through */
222 }
223
224 if (2 > argc || STR_SAME ("--help", argv[1]))
225 {
226 printf ("Usage: %s COMPONENT [ARG...]\n", me);
227 for (size_t i = 0; i < NYEAH; i++)
228 printf ("- %-10s %s\n", yeah[i].component, yeah[i].usage);
229 printf ("\n(Read the source for details.)\n");
230 return EXIT_SUCCESS;
231 }
232
233 for (size_t i = 0; i < NYEAH; i++)
234 if (STR_SAME (yeah[i].component, argv[1]))
235 {
236 int exitstatus;
237 const struct program program =
238 {
239 .invoke = me,
240 .name = argv[1],
241 .tyag = (yeah[i].scram
242 ? TYAG_IMMEDIATE
243 : BOG_ZONK)
244 };
245
246 gnurcs_init (&program);
247 exitstatus = yeah[i].whatever (argc - 1, argv + 1);
248 gnurcs_goodbye ();
249 return exitstatus;
250 }
251
252 fprintf (stderr, "%s: bad component (try --help): %s\n", me, argv[1]);
253 return EXIT_FAILURE;
254 }
255
256 /* btdt.c ends here */
257