1 /* $OpenBSD: merge.c,v 1.10 2016/08/26 09:02:54 guenther 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 <time.h> 31 #include <unistd.h> 32 33 #include "rcsprog.h" 34 #include "diff.h" 35 36 int 37 merge_main(int argc, char **argv) 38 { 39 int ch, flags, labels, status; 40 const char *label[3]; 41 BUF *bp; 42 43 flags = labels = 0; 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 } 81 } 82 argc -= optind; 83 argv += optind; 84 85 if (argc != 3) { 86 warnx("%s arguments", (argc < 3) ? "not enough" : "too many"); 87 (usage)(); 88 } 89 90 for (; labels < 3; labels++) 91 label[labels] = argv[labels]; 92 93 /* XXX handle labels */ 94 if ((bp = merge_diff3(argv, flags)) == NULL) 95 errx(D_ERROR, "failed to merge"); 96 97 if (diff3_conflicts != 0) 98 status = D_OVERLAPS; 99 else 100 status = 0; 101 102 if (flags & PIPEOUT) 103 buf_write_fd(bp, STDOUT_FILENO); 104 else { 105 /* XXX */ 106 if (buf_write(bp, argv[0], 0644) < 0) 107 warnx("buf_write failed"); 108 } 109 buf_free(bp); 110 111 return (status); 112 } 113 114 __dead void 115 merge_usage(void) 116 { 117 (void)fprintf(stderr, 118 "usage: merge [-EepqV] [-L label] file1 file2 file3\n"); 119 120 exit(D_ERROR); 121 } 122