1 /* $OpenBSD: merge.c,v 1.9 2014/10/10 08:15:25 otto 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 44 /* 45 * Using getopt(3) and not rcs_getopt() because merge(1) 46 * allows spaces between options and their arguments. 47 * Thus staying compatible with former implementation. 48 */ 49 while ((ch = getopt(argc, argv, "AEeL:pqV")) != -1) { 50 switch(ch) { 51 case 'A': 52 /* 53 * kept for compatibility 54 */ 55 break; 56 case 'E': 57 flags |= MERGE_EFLAG; 58 flags |= MERGE_OFLAG; 59 break; 60 case 'e': 61 flags |= MERGE_EFLAG; 62 break; 63 case 'L': 64 if (3 <= labels) 65 errx(D_ERROR, "too many -L options"); 66 label[labels++] = optarg; 67 break; 68 case 'p': 69 flags |= PIPEOUT; 70 break; 71 case 'q': 72 flags |= QUIET; 73 break; 74 case 'V': 75 printf("%s\n", rcs_version); 76 exit(0); 77 default: 78 (usage)(); 79 } 80 } 81 argc -= optind; 82 argv += optind; 83 84 if (argc != 3) { 85 warnx("%s arguments", (argc < 3) ? "not enough" : "too many"); 86 (usage)(); 87 } 88 89 for (; labels < 3; labels++) 90 label[labels] = argv[labels]; 91 92 /* XXX handle labels */ 93 if ((bp = merge_diff3(argv, flags)) == NULL) 94 errx(D_ERROR, "failed to merge"); 95 96 if (diff3_conflicts != 0) 97 status = D_OVERLAPS; 98 else 99 status = 0; 100 101 if (flags & PIPEOUT) 102 buf_write_fd(bp, STDOUT_FILENO); 103 else { 104 /* XXX */ 105 if (buf_write(bp, argv[0], 0644) < 0) 106 warnx("buf_write failed"); 107 } 108 buf_free(bp); 109 110 return (status); 111 } 112 113 __dead void 114 merge_usage(void) 115 { 116 (void)fprintf(stderr, 117 "usage: merge [-EepqV] [-L label] file1 file2 file3\n"); 118 119 exit(D_ERROR); 120 } 121