File: | src/usr.bin/cvs/getlog.c |
Warning: | line 321, column 2 Value stored to 'i' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: getlog.c,v 1.101 2017/06/01 08:08:24 joris Exp $ */ |
2 | /* |
3 | * Copyright (c) 2005, 2006 Xavier Santolaria <xsa@openbsd.org> |
4 | * Copyright (c) 2006 Joris Vink <joris@openbsd.org> |
5 | * |
6 | * Permission to use, copy, modify, and distribute this software for any |
7 | * purpose with or without fee is hereby granted, provided that the above |
8 | * copyright notice and this permission notice appear in all copies. |
9 | * |
10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
17 | */ |
18 | |
19 | #include <unistd.h> |
20 | #include <stdlib.h> |
21 | #include <string.h> |
22 | #include <errno(*__errno()).h> |
23 | #include <ctype.h> |
24 | |
25 | #include "cvs.h" |
26 | #include "remote.h" |
27 | |
28 | #define L_HEAD0x01 0x01 |
29 | #define L_HEAD_DESCR0x02 0x02 |
30 | #define L_NAME0x04 0x04 |
31 | #define L_NOTAGS0x08 0x08 |
32 | #define L_LOGINS0x10 0x10 |
33 | #define L_STATES0x20 0x20 |
34 | |
35 | #define LDATE_LATER0x01 0x01 |
36 | #define LDATE_EARLIER0x02 0x02 |
37 | #define LDATE_SINGLE0x04 0x04 |
38 | #define LDATE_RANGE0x08 0x08 |
39 | #define LDATE_INCLUSIVE0x10 0x10 |
40 | |
41 | void cvs_log_local(struct cvs_file *); |
42 | static void log_rev_print(struct rcs_delta *); |
43 | static char *push_date(char *dest, const char *); |
44 | static u_int date_select(RCSFILE *, char *); |
45 | |
46 | int runflags = 0; |
47 | char *logrev = NULL((void *)0); |
48 | char *logdate = NULL((void *)0); |
49 | char *slist = NULL((void *)0); |
50 | char *wlist = NULL((void *)0); |
51 | |
52 | struct cvs_cmd cvs_cmd_log = { |
53 | CVS_OP_LOG13, CVS_USE_WDIR0x01, "log", |
54 | { "lo" }, |
55 | "Print out history information for files", |
56 | "[-bhlNRt] [-d dates] [-r revisions] [-s states] [-w logins]", |
57 | "bd:hlNRr:s:tw:", |
58 | NULL((void *)0), |
59 | cvs_getlog |
60 | }; |
61 | |
62 | struct cvs_cmd cvs_cmd_rlog = { |
63 | CVS_OP_RLOG18, 0, "rlog", |
64 | { "rlo" }, |
65 | "Print out history information for files", |
66 | "[-bhlNRt] [-d dates] [-r revisions] [-s states] [-w logins]", |
67 | "bd:hlNRr:s:tw:", |
68 | NULL((void *)0), |
69 | cvs_getlog |
70 | }; |
71 | |
72 | int |
73 | cvs_getlog(int argc, char **argv) |
74 | { |
75 | int ch, flags, i; |
76 | char *arg = "."; |
77 | struct cvs_recursion cr; |
78 | |
79 | flags = CR_RECURSE_DIRS0x01; |
80 | |
81 | while ((ch = getopt(argc, argv, cvs_cmdop == CVS_OP_LOG13 ? |
82 | cvs_cmd_log.cmd_opts : cvs_cmd_rlog.cmd_opts)) != -1) { |
83 | switch (ch) { |
84 | case 'd': |
85 | logdate = push_date(logdate, optarg); |
86 | break; |
87 | case 'h': |
88 | runflags |= L_HEAD0x01; |
89 | break; |
90 | case 'l': |
91 | flags &= ~CR_RECURSE_DIRS0x01; |
92 | break; |
93 | case 'N': |
94 | runflags |= L_NOTAGS0x08; |
95 | break; |
96 | case 'R': |
97 | runflags |= L_NAME0x04; |
98 | break; |
99 | case 'r': |
100 | logrev = optarg; |
101 | break; |
102 | case 's': |
103 | runflags |= L_STATES0x20; |
104 | slist = optarg; |
105 | break; |
106 | case 't': |
107 | runflags |= L_HEAD_DESCR0x02; |
108 | break; |
109 | case 'w': |
110 | runflags |= L_LOGINS0x10; |
111 | wlist = optarg; |
112 | break; |
113 | default: |
114 | fatal("%s", cvs_cmdop == CVS_OP_LOG13 ? |
115 | cvs_cmd_log.cmd_synopsis : |
116 | cvs_cmd_rlog.cmd_synopsis); |
117 | } |
118 | } |
119 | |
120 | argc -= optind; |
121 | argv += optind; |
122 | |
123 | if (cvs_cmdop == CVS_OP_RLOG18) { |
124 | flags |= CR_REPO0x04; |
125 | |
126 | if (argc == 0) |
127 | return 0; |
128 | |
129 | for (i = 0; i < argc; i++) |
130 | if (argv[i][0] == '/') |
131 | fatal("Absolute path name is invalid: %s", |
132 | argv[i]); |
133 | } |
134 | |
135 | cr.enterdir = NULL((void *)0); |
136 | cr.leavedir = NULL((void *)0); |
137 | |
138 | if (cvsroot_is_remote()) { |
139 | cvs_client_connect_to_server(); |
140 | cr.fileproc = cvs_client_sendfile; |
141 | |
142 | if (logdate != NULL((void *)0)) |
143 | cvs_client_send_request("Argument -d%s", logdate); |
144 | |
145 | if (runflags & L_HEAD0x01) |
146 | cvs_client_send_request("Argument -h"); |
147 | |
148 | if (!(flags & CR_RECURSE_DIRS0x01)) |
149 | cvs_client_send_request("Argument -l"); |
150 | |
151 | if (runflags & L_NOTAGS0x08) |
152 | cvs_client_send_request("Argument -N"); |
153 | |
154 | if (runflags & L_NAME0x04) |
155 | cvs_client_send_request("Argument -R"); |
156 | |
157 | if (logrev != NULL((void *)0)) |
158 | cvs_client_send_request("Argument -r%s", logrev); |
159 | |
160 | if (runflags & L_STATES0x20) |
161 | cvs_client_send_request("Argument -s%s", slist); |
162 | |
163 | if (runflags & L_HEAD_DESCR0x02) |
164 | cvs_client_send_request("Argument -t"); |
165 | |
166 | if (runflags & L_LOGINS0x10) |
167 | cvs_client_send_request("Argument -w%s", wlist); |
168 | } else { |
169 | if (cvs_cmdop == CVS_OP_RLOG18 && |
170 | chdir(current_cvsroot->cr_dir) == -1) |
171 | fatal("cvs_getlog: %s", strerror(errno(*__errno()))); |
172 | |
173 | cr.fileproc = cvs_log_local; |
174 | } |
175 | |
176 | cr.flags = flags; |
177 | |
178 | if (cvs_cmdop == CVS_OP_LOG13 || cvsroot_is_local()) { |
179 | if (argc > 0) |
180 | cvs_file_run(argc, argv, &cr); |
181 | else |
182 | cvs_file_run(1, &arg, &cr); |
183 | } |
184 | |
185 | if (cvsroot_is_remote()) { |
186 | cvs_client_send_files(argv, argc); |
187 | cvs_client_senddir("."); |
188 | |
189 | cvs_client_send_request((cvs_cmdop == CVS_OP_RLOG18) ? |
190 | "rlog" : "log"); |
191 | |
192 | cvs_client_get_responses(); |
193 | } |
194 | |
195 | return (0); |
196 | } |
197 | |
198 | void |
199 | cvs_log_local(struct cvs_file *cf) |
200 | { |
201 | u_int nrev; |
202 | RCSNUM *rev; |
203 | struct rcs_sym *sym; |
204 | struct rcs_lock *lkp; |
205 | struct rcs_delta *rdp; |
206 | struct rcs_access *acp; |
207 | char numb[CVS_REV_BUFSZ32]; |
208 | |
209 | cvs_log(LP_TRACE4, "cvs_log_local(%s)", cf->file_path); |
210 | |
211 | cvs_file_classify(cf, cvs_directory_tag); |
212 | |
213 | if (cf->file_type == CVS_DIR1) { |
214 | if (verbosity > 1) |
215 | cvs_log(LP_ERR1, "Logging %s", cf->file_path); |
216 | return; |
217 | } |
218 | |
219 | if (cf->file_rcs == NULL((void *)0)) { |
220 | return; |
221 | } else if (cf->file_status == FILE_ADDED1) { |
222 | if (verbosity > 0) |
223 | cvs_log(LP_ERR1, "%s has been added, but not committed", |
224 | cf->file_path); |
225 | return; |
226 | } |
227 | |
228 | if (runflags & L_NAME0x04) { |
229 | cvs_printf("%s\n", cf->file_rpath); |
230 | return; |
231 | } |
232 | |
233 | if (logrev != NULL((void *)0)) |
234 | nrev = cvs_revision_select(cf->file_rcs, logrev); |
235 | else if (logdate != NULL((void *)0)) { |
236 | if ((nrev = date_select(cf->file_rcs, logdate)) == (u_int)-1) { |
237 | cvs_log(LP_ERR1, "invalid date: %s", logdate); |
238 | return; |
239 | } |
240 | } else |
241 | nrev = cf->file_rcs->rf_ndelta; |
242 | |
243 | cvs_printf("\nRCS file: %s", cf->file_rpath); |
244 | |
245 | if (cvs_cmdop != CVS_OP_RLOG18) |
246 | cvs_printf("\nWorking file: %s", cf->file_path); |
247 | |
248 | cvs_printf("\nhead:"); |
249 | if (cf->file_rcs->rf_head != NULL((void *)0)) |
250 | cvs_printf(" %s", rcsnum_tostr(cf->file_rcs->rf_head, |
251 | numb, sizeof(numb))); |
252 | |
253 | cvs_printf("\nbranch:"); |
254 | if (rcs_branch_get(cf->file_rcs) != NULL((void *)0)) { |
255 | cvs_printf(" %s", rcsnum_tostr(rcs_branch_get(cf->file_rcs), |
256 | numb, sizeof(numb))); |
257 | } |
258 | |
259 | cvs_printf("\nlocks: %s", (cf->file_rcs->rf_flags & RCS_SLOCK(1<<6)) |
260 | ? "strict" : ""); |
261 | TAILQ_FOREACH(lkp, &(cf->file_rcs->rf_locks), rl_list)for((lkp) = ((&(cf->file_rcs->rf_locks))->tqh_first ); (lkp) != ((void *)0); (lkp) = ((lkp)->rl_list.tqe_next) ) |
262 | cvs_printf("\n\t%s: %s", lkp->rl_name, |
263 | rcsnum_tostr(lkp->rl_num, numb, sizeof(numb))); |
264 | |
265 | cvs_printf("\naccess list:\n"); |
266 | TAILQ_FOREACH(acp, &(cf->file_rcs->rf_access), ra_list)for((acp) = ((&(cf->file_rcs->rf_access))->tqh_first ); (acp) != ((void *)0); (acp) = ((acp)->ra_list.tqe_next) ) |
267 | cvs_printf("\t%s\n", acp->ra_name); |
268 | |
269 | if (!(runflags & L_NOTAGS0x08)) { |
270 | cvs_printf("symbolic names:\n"); |
271 | TAILQ_FOREACH(sym, &(cf->file_rcs->rf_symbols), rs_list)for((sym) = ((&(cf->file_rcs->rf_symbols))->tqh_first ); (sym) != ((void *)0); (sym) = ((sym)->rs_list.tqe_next) ) { |
272 | rev = rcsnum_alloc(); |
273 | rcsnum_cpy(sym->rs_num, rev, 0); |
274 | if (RCSNUM_ISBRANCH(sym->rs_num)((sym->rs_num)->rn_len % 2)) |
275 | rcsnum_addmagic(rev); |
276 | |
277 | cvs_printf("\t%s: %s\n", sym->rs_name, |
278 | rcsnum_tostr(rev, numb, sizeof(numb))); |
279 | free(rev); |
280 | } |
281 | } |
282 | |
283 | cvs_printf("keyword substitution: %s\n", |
284 | cf->file_rcs->rf_expand == NULL((void *)0) ? "kv" : cf->file_rcs->rf_expand); |
285 | |
286 | cvs_printf("total revisions: %u", cf->file_rcs->rf_ndelta); |
287 | |
288 | if (cf->file_rcs->rf_head != NULL((void *)0) && |
289 | !(runflags & L_HEAD0x01) && !(runflags & L_HEAD_DESCR0x02)) |
290 | cvs_printf(";\tselected revisions: %u", nrev); |
291 | |
292 | cvs_printf("\n"); |
293 | |
294 | if (!(runflags & L_HEAD0x01) || (runflags & L_HEAD_DESCR0x02)) |
295 | cvs_printf("description:\n%s", cf->file_rcs->rf_desc); |
296 | |
297 | if (!(runflags & L_HEAD0x01) && !(runflags & L_HEAD_DESCR0x02)) { |
298 | TAILQ_FOREACH(rdp, &(cf->file_rcs->rf_delta), rd_list)for((rdp) = ((&(cf->file_rcs->rf_delta))->tqh_first ); (rdp) != ((void *)0); (rdp) = ((rdp)->rd_list.tqe_next) ) { |
299 | /* |
300 | * if selections are enabled verify that entry is |
301 | * selected. |
302 | */ |
303 | if ((logrev == NULL((void *)0) && logdate == NULL((void *)0)) || |
304 | (rdp->rd_flags & RCS_RD_SELECT0x02)) |
305 | log_rev_print(rdp); |
306 | } |
307 | } |
308 | |
309 | cvs_printf("%s\n", LOG_REVEND"============================================================================="); |
310 | } |
311 | |
312 | static void |
313 | log_rev_print(struct rcs_delta *rdp) |
314 | { |
315 | int i, found; |
316 | char numb[CVS_REV_BUFSZ32], timeb[CVS_TIME_BUFSZ64]; |
317 | struct cvs_argvector *sargv, *wargv; |
318 | struct rcs_branch *rb; |
319 | struct rcs_delta *nrdp; |
320 | |
321 | i = found = 0; |
Value stored to 'i' is never read | |
322 | |
323 | /* -s states */ |
324 | if (runflags & L_STATES0x20) { |
325 | sargv = cvs_strsplit(slist, ","); |
326 | for (i = 0; sargv->argv[i] != NULL((void *)0); i++) { |
327 | if (strcmp(rdp->rd_state, sargv->argv[i]) == 0) { |
328 | found++; |
329 | break; |
330 | } |
331 | found = 0; |
332 | } |
333 | cvs_argv_destroy(sargv); |
334 | } |
335 | |
336 | /* -w[logins] */ |
337 | if (runflags & L_LOGINS0x10) { |
338 | wargv = cvs_strsplit(wlist, ","); |
339 | for (i = 0; wargv->argv[i] != NULL((void *)0); i++) { |
340 | if (strcmp(rdp->rd_author, wargv->argv[i]) == 0) { |
341 | found++; |
342 | break; |
343 | } |
344 | found = 0; |
345 | } |
346 | cvs_argv_destroy(wargv); |
347 | } |
348 | |
349 | if ((runflags & (L_STATES0x20|L_LOGINS0x10)) && found == 0) |
350 | return; |
351 | |
352 | cvs_printf("%s\n", LOG_REVSEP"----------------------------"); |
353 | |
354 | rcsnum_tostr(rdp->rd_num, numb, sizeof(numb)); |
355 | cvs_printf("revision %s", numb); |
356 | |
357 | strftime(timeb, sizeof(timeb), "%Y/%m/%d %H:%M:%S", &rdp->rd_date); |
358 | cvs_printf("\ndate: %s; author: %s; state: %s;", |
359 | timeb, rdp->rd_author, rdp->rd_state); |
360 | |
361 | /* |
362 | * If we are a branch revision, the diff of this revision is stored |
363 | * in place. |
364 | * Otherwise, it is stored in the previous revision as a reversed diff. |
365 | */ |
366 | if (RCSNUM_ISBRANCHREV(rdp->rd_num)(!((rdp->rd_num)->rn_len % 2) && ((rdp->rd_num )->rn_len >= 4))) |
367 | nrdp = rdp; |
368 | else |
369 | nrdp = TAILQ_NEXT(rdp, rd_list)((rdp)->rd_list.tqe_next); |
370 | |
371 | /* |
372 | * We do not write diff stats for the first revision of the default |
373 | * branch, since it was not a diff but a full text. |
374 | */ |
375 | if (nrdp != NULL((void *)0) && rdp->rd_num->rn_len == nrdp->rd_num->rn_len) { |
376 | int added, removed; |
377 | rcs_delta_stats(nrdp, &added, &removed); |
378 | if (RCSNUM_ISBRANCHREV(rdp->rd_num)(!((rdp->rd_num)->rn_len % 2) && ((rdp->rd_num )->rn_len >= 4))) |
379 | cvs_printf(" lines: +%d -%d;", added, removed); |
380 | else |
381 | cvs_printf(" lines: +%d -%d;", removed, added); |
382 | } |
383 | |
384 | if (rdp->rd_commitid != NULL((void *)0)) |
385 | printf(" commitid: %s;", rdp->rd_commitid); |
386 | |
387 | cvs_printf("\n"); |
388 | |
389 | if (!TAILQ_EMPTY(&(rdp->rd_branches))(((&(rdp->rd_branches))->tqh_first) == ((void *)0))) { |
390 | cvs_printf("branches:"); |
391 | TAILQ_FOREACH(rb, &(rdp->rd_branches), rb_list)for((rb) = ((&(rdp->rd_branches))->tqh_first); (rb) != ((void *)0); (rb) = ((rb)->rb_list.tqe_next)) { |
392 | RCSNUM *branch; |
393 | branch = rcsnum_revtobr(rb->rb_num); |
394 | rcsnum_tostr(branch, numb, sizeof(numb)); |
395 | cvs_printf(" %s;", numb); |
396 | free(branch); |
397 | } |
398 | cvs_printf("\n"); |
399 | } |
400 | |
401 | cvs_printf("%s", rdp->rd_log); |
402 | } |
403 | |
404 | static char * |
405 | push_date(char *dest, const char *src) |
406 | { |
407 | size_t len; |
408 | |
409 | if (dest == NULL((void *)0)) |
410 | return (xstrdup(src)); |
411 | |
412 | /* 2 = ; and '\0' */ |
413 | len = strlen(dest) + strlen(src) + 2; |
414 | |
415 | dest[strlen(dest)] = ';'; |
416 | dest = xreallocarray(dest, len, 1); |
417 | strlcat(dest, src, len); |
418 | return (dest); |
419 | } |
420 | |
421 | static u_int |
422 | date_select(RCSFILE *file, char *date) |
423 | { |
424 | int i, nrev, flags; |
425 | struct rcs_delta *rdp; |
426 | struct cvs_argvector *args; |
427 | char *first, *last, delim; |
428 | time_t firstdate, lastdate, rcsdate; |
429 | |
430 | nrev = 0; |
431 | args = cvs_strsplit(date, ";"); |
432 | |
433 | for (i = 0; args->argv[i] != NULL((void *)0); i++) { |
434 | flags = 0; |
435 | firstdate = lastdate = -1; |
436 | |
437 | first = args->argv[i]; |
438 | last = strchr(args->argv[i], '<'); |
439 | if (last != NULL((void *)0)) { |
440 | delim = *last; |
441 | *last++ = '\0'; |
442 | |
443 | if (*last == '=') { |
444 | last++; |
445 | flags |= LDATE_INCLUSIVE0x10; |
446 | } |
447 | } else { |
448 | last = strchr(args->argv[i], '>'); |
449 | if (last != NULL((void *)0)) { |
450 | delim = *last; |
451 | *last++ = '\0'; |
452 | |
453 | if (*last == '=') { |
454 | last++; |
455 | flags |= LDATE_INCLUSIVE0x10; |
456 | } |
457 | } |
458 | } |
459 | |
460 | if (last == NULL((void *)0)) { |
461 | flags |= LDATE_SINGLE0x04; |
462 | if ((firstdate = date_parse(first)) == -1) |
463 | return -1; |
464 | delim = '\0'; |
465 | last = "\0"; |
466 | } else { |
467 | while (*last && isspace((unsigned char)*last)) |
468 | last++; |
469 | } |
470 | |
471 | if (delim == '>' && *last == '\0') { |
472 | flags |= LDATE_EARLIER0x02; |
473 | if ((firstdate = date_parse(first)) == -1) |
474 | return -1; |
475 | } |
476 | |
477 | if (delim == '>' && *first == '\0' && *last != '\0') { |
478 | flags |= LDATE_LATER0x01; |
479 | if ((firstdate = date_parse(last)) == -1) |
480 | return -1; |
481 | } |
482 | |
483 | if (delim == '<' && *last == '\0') { |
484 | flags |= LDATE_LATER0x01; |
485 | if ((firstdate = date_parse(first)) == -1) |
486 | return -1; |
487 | } |
488 | |
489 | if (delim == '<' && *first == '\0' && *last != '\0') { |
490 | flags |= LDATE_EARLIER0x02; |
491 | if ((firstdate = date_parse(last)) == -1) |
492 | return -1; |
493 | } |
494 | |
495 | if (*first != '\0' && *last != '\0') { |
496 | flags |= LDATE_RANGE0x08; |
497 | |
498 | if (delim == '<') { |
499 | firstdate = date_parse(first); |
500 | lastdate = date_parse(last); |
501 | } else { |
502 | firstdate = date_parse(last); |
503 | lastdate = date_parse(first); |
504 | } |
505 | if (firstdate == -1 || lastdate == -1) |
506 | return -1; |
507 | } |
508 | |
509 | TAILQ_FOREACH(rdp, &(file->rf_delta), rd_list)for((rdp) = ((&(file->rf_delta))->tqh_first); (rdp) != ((void *)0); (rdp) = ((rdp)->rd_list.tqe_next)) { |
510 | rcsdate = mktime(&(rdp->rd_date)); |
511 | |
512 | if (flags & LDATE_SINGLE0x04) { |
513 | if (rcsdate <= firstdate) { |
514 | rdp->rd_flags |= RCS_RD_SELECT0x02; |
515 | nrev++; |
516 | break; |
517 | } |
518 | } |
519 | |
520 | if (flags & LDATE_EARLIER0x02) { |
521 | if (rcsdate < firstdate) { |
522 | rdp->rd_flags |= RCS_RD_SELECT0x02; |
523 | nrev++; |
524 | continue; |
525 | } |
526 | |
527 | if (flags & LDATE_INCLUSIVE0x10 && |
528 | (rcsdate <= firstdate)) { |
529 | rdp->rd_flags |= RCS_RD_SELECT0x02; |
530 | nrev++; |
531 | continue; |
532 | } |
533 | } |
534 | |
535 | if (flags & LDATE_LATER0x01) { |
536 | if (rcsdate > firstdate) { |
537 | rdp->rd_flags |= RCS_RD_SELECT0x02; |
538 | nrev++; |
539 | continue; |
540 | } |
541 | |
542 | if (flags & LDATE_INCLUSIVE0x10 && |
543 | (rcsdate >= firstdate)) { |
544 | rdp->rd_flags |= RCS_RD_SELECT0x02; |
545 | nrev++; |
546 | continue; |
547 | } |
548 | } |
549 | |
550 | if (flags & LDATE_RANGE0x08) { |
551 | if ((rcsdate > firstdate) && |
552 | (rcsdate < lastdate)) { |
553 | rdp->rd_flags |= RCS_RD_SELECT0x02; |
554 | nrev++; |
555 | continue; |
556 | } |
557 | |
558 | if (flags & LDATE_INCLUSIVE0x10 && |
559 | ((rcsdate >= firstdate) && |
560 | (rcsdate <= lastdate))) { |
561 | rdp->rd_flags |= RCS_RD_SELECT0x02; |
562 | nrev++; |
563 | continue; |
564 | } |
565 | } |
566 | } |
567 | } |
568 | |
569 | cvs_argv_destroy(args); |
570 | |
571 | return (nrev); |
572 | } |