1 /* $OpenBSD: merge.c,v 1.6 2007/04/26 21:49:33 sobrado Exp $ */ 2 /* 3 * Copyright (c) 2006 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 <err.h> 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <unistd.h> 31 32 #include "rcsprog.h" 33 #include "diff.h" 34 35 int 36 merge_main(int argc, char **argv) 37 { 38 int ch, flags, labels, status; 39 const char *label[3]; 40 BUF *bp; 41 42 flags = labels = 0; 43 status = D_ERROR; 44 45 /* 46 * Using getopt(3) and not rcs_getopt() because merge(1) 47 * allows spaces between options and their arguments. 48 * Thus staying compatible with former implementation. 49 */ 50 while ((ch = getopt(argc, argv, "AEeL:pqV")) != -1) { 51 switch(ch) { 52 case 'A': 53 /* 54 * kept for compatibility 55 */ 56 break; 57 case 'E': 58 flags |= MERGE_EFLAG; 59 flags |= MERGE_OFLAG; 60 break; 61 case 'e': 62 flags |= MERGE_EFLAG; 63 break; 64 case 'L': 65 if (3 <= labels) 66 errx(D_ERROR, "too many -L options"); 67 label[labels++] = optarg; 68 break; 69 case 'p': 70 flags |= PIPEOUT; 71 break; 72 case 'q': 73 flags |= QUIET; 74 break; 75 case 'V': 76 printf("%s\n", rcs_version); 77 exit(0); 78 default: 79 (usage)(); 80 exit(D_ERROR); 81 } 82 } 83 argc -= optind; 84 argv += optind; 85 86 if (argc != 3) { 87 warnx("%s arguments", (argc < 3) ? "not enough" : "too many"); 88 (usage)(); 89 exit(D_ERROR); 90 } 91 92 for (; labels < 3; labels++) 93 label[labels] = argv[labels]; 94 95 /* XXX handle labels */ 96 if ((bp = merge_diff3(argv, flags)) == NULL) 97 errx(D_ERROR, "failed to merge"); 98 99 if (diff3_conflicts != 0) 100 status = D_OVERLAPS; 101 else 102 status = 0; 103 104 if (flags & PIPEOUT) 105 rcs_buf_write_fd(bp, STDOUT_FILENO); 106 else { 107 /* XXX */ 108 if (rcs_buf_write(bp, argv[0], 0644) < 0) 109 warnx("rcs_buf_write failed"); 110 } 111 rcs_buf_free(bp); 112 113 return (status); 114 } 115 116 void 117 merge_usage(void) 118 { 119 (void)fprintf(stderr, 120 "usage: merge [-EepqV] [-L label] file1 file2 file3\n"); 121 } 122