|
|
1.1 root 1: /*
2: * rcsmerge operation
3: */
4: #ifndef lint
5: static char rcsid[]=
6: "$Header: /usr/src/local/bin/rcs/src/RCS/rcsmerge.c,v 4.5 89/05/01 15:13:16 narten Exp $ Purdue CS";
7: #endif
8: /*****************************************************************************
9: * join 2 revisions with respect to a third
10: *****************************************************************************
11: */
12:
13: /* Copyright (C) 1982, 1988, 1989 Walter Tichy
14: * All rights reserved.
15: *
16: * Redistribution and use in source and binary forms are permitted
17: * provided that the above copyright notice and this paragraph are
18: * duplicated in all such forms and that any documentation,
19: * advertising materials, and other materials related to such
20: * distribution and use acknowledge that the software was developed
21: * by Walter Tichy.
22: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
23: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
24: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
25: *
26: * Report all problems and direct all questions to:
27: * [email protected]
28: *
29:
30:
31:
32:
33:
34:
35:
36: */
37:
38:
39:
40: /* $Log: rcsmerge.c,v $
41: * Revision 4.5 89/05/01 15:13:16 narten
42: * changed copyright header to reflect current distribution rules
43: *
44: * Revision 4.4 88/11/08 12:00:47 narten
45: * changes from [email protected] (Paul Eggert)
46: *
47: * Revision 4.4 88/08/09 19:13:13 eggert
48: * Beware merging into a readonly file.
49: * Beware merging a revision to itself (no change).
50: * Use execv(), not system(); yield exit status like diff(1)'s.
51: *
52: * Revision 4.3 87/10/18 10:38:02 narten
53: * Updating version numbers. Changes relative to version 1.1
54: * actually relative to 4.1
55: *
56: * Revision 1.3 87/09/24 14:00:31 narten
57: * Sources now pass through lint (if you ignore printf/sprintf/fprintf
58: * warnings)
59: *
60: * Revision 1.2 87/03/27 14:22:36 jenkins
61: * Port to suns
62: *
63: * Revision 1.1 84/01/23 14:50:36 kcs
64: * Initial revision
65: *
66: * Revision 4.1 83/03/28 11:14:57 wft
67: * Added handling of default branch.
68: *
69: * Revision 3.3 82/12/24 15:29:00 wft
70: * Added call to catchsig().
71: *
72: * Revision 3.2 82/12/10 21:32:02 wft
73: * Replaced getdelta() with gettree(); improved error messages.
74: *
75: * Revision 3.1 82/11/28 19:27:44 wft
76: * Initial revision.
77: *
78: */
79: #include "rcsbase.h"
80: #ifndef lint
81: static char rcsbaseid[] = RCSBASE;
82: #endif
83: static char co[] = CO;
84: static char merge[] = MERGE;
85:
86: extern int cleanup(); /* cleanup after signals */
87: extern char * mktempfile(); /*temporary file name generator */
88: extern struct hshentry * genrevs(); /*generate delta numbers */
89: extern int nerror; /*counter for errors */
90:
91: char *RCSfilename;
92: char *workfilename;
93: char * temp1file, * temp2file;
94:
95: main (argc, argv)
96: int argc; char **argv;
97: {
98: char * cmdusage;
99: int revnums; /* counter for revision numbers given */
100: int tostdout;
101: int nochange;
102: char * rev1, * rev2; /*revision numbers*/
103: char commarg[revlength+3];
104: char numericrev[revlength]; /* holds expanded revision number */
105: struct hshentry * gendeltas[hshsize];/*stores deltas to be generated*/
106: struct hshentry * target;
107:
108: catchints();
109: cmdid = "rcsmerge";
110: cmdusage = "command format:\n rcsmerge -p -rrev1 -rrev2 file\n rcsmerge -p -rrev1 file";
111: revnums=0;tostdout=false;nochange=false;
112:
113: while (--argc,++argv, argc>=1 && ((*argv)[0] == '-')) {
114: switch ((*argv)[1]) {
115: case 'p':
116: tostdout=true;
117: /* falls into -r */
118: case 'r':
119: if ((*argv)[2]!='\0') {
120: if (revnums==0) {
121: rev1= *argv+2; revnums=1;
122: } elif (revnums==1) {
123: rev2= *argv+2; revnums=2;
124: } else {
125: faterror("too many revision numbers");
126: }
127: } /* do nothing for empty -r or -p */
128: break;
129:
130: default:
131: faterror("unknown option: %s\n%s", *argv,cmdusage);
132: };
133: } /* end of option processing */
134:
135: if (argc<1) faterror("No input file\n%s",cmdusage);
136: if (revnums<1) faterror("no base revision number given");
137:
138: /* now handle all filenames */
139:
140: if (pairfilenames(argc,argv,true,false)==1) {
141:
142: if (argc>2 || (argc==2&&argv[1]!=nil))
143: warn("too many arguments");
144: diagnose("RCS file: %s",RCSfilename);
145: if (!(access(workfilename,tostdout?4:6)==0))
146: nowork();
147:
148: if (!trysema(RCSfilename,false)) goto end; /* give up */
149:
150: gettree(); /* reads in the delta tree */
151:
152: if (Head==nil) faterror("no revisions present");
153:
154:
155: if (!expandsym(rev1,numericrev)) goto end;
156: if (!(target=genrevs(numericrev, (char *)nil, (char *)nil, (char *)nil,gendeltas))) goto end;
157: rev1=target->num;
158: if (revnums==1) /*get default for rev2 */
159: rev2=Dbranch!=nil?Dbranch->num:Head->num;
160: if (!expandsym(rev2,numericrev)) goto end;
161: if (!(target=genrevs(numericrev, (char *)nil, (char *)nil, (char *)nil,gendeltas))) goto end;
162: rev2=target->num;
163:
164: if (strcmp(rev1,rev2) == 0) {
165: diagnose("Merging revision %s to itself (no change)",
166: rev1
167: );
168: nochange = true;
169: if (tostdout) {
170: FILE *w = fopen(workfilename,"r");
171: if (w==NULL)
172: nowork();
173: fastcopy(w,stdout);
174: }
175: goto end;
176: }
177:
178: temp1file=mktempfile("/tmp/",TMPFILE1);
179: temp2file=mktempfile("/tmp/",TMPFILE2);
180:
181: diagnose("retrieving revision %s",rev1);
182: VOID sprintf(commarg,"-p%s",rev1);
183: if (run((char*)nil,temp1file, co,"-q",commarg,RCSfilename,(char*)nil)){
184: faterror("co failed");
185: }
186: diagnose("retrieving revision %s",rev2);
187: VOID sprintf(commarg,"-p%s",rev2);
188: if (run((char*)nil,temp2file, co,"-q",commarg,RCSfilename,(char*)nil)){
189: faterror("co failed");
190: }
191: diagnose("Merging differences between %s and %s into %s%s",
192: rev1, rev2, workfilename,
193: tostdout?"; result to stdout":"");
194:
195: if (
196: tostdout
197: ? run((char*)nil,(char*)nil,merge,"-p",workfilename,temp1file,temp2file,workfilename,rev2,(char*)nil)
198: : run((char*)nil,(char*)nil,merge, workfilename,temp1file,temp2file,workfilename,rev2,(char*)nil)) {
199: faterror("merge failed");
200: }
201: }
202:
203: end:
204: VOID cleanup();
205: exit(2*(nerror!=0) + nochange);
206:
207: }
208:
209:
210: nowork()
211: {
212: faterror("Can't open %s",workfilename);
213: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.