3 * $XConsortium: merge_c.c /main/4 1996/10/02 13:38:19 drk $
5 * @(#)merge_c.c 1.9 27 Mar 1995 cde_app_builder/src/abmf
7 * RESTRICTED CONFIDENTIAL INFORMATION:
9 * The information in this document is subject to special
10 * restrictions in a confidential disclosure agreement between
11 * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
12 * document outside HP, IBM, Sun, USL, SCO, or Univel without
13 * Sun's specific written approval. This document and all copies
14 * and derivative works thereof must be returned or destroyed at
17 * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
23 * merge_c.c - merge C source files with "magic" comments
30 /*************************************************************************
32 ** Constants (#define and const) **
34 **************************************************************************/
36 /*************************************************************************
38 ** Private Functions (C declarations and macros) **
40 **************************************************************************/
42 static int merge_files_by_segment(
49 File *mergedFileOutPtr,
53 static int match_all_segments(CSegArray newSegs, CSegArray oldSegs);
55 static CSeg match_segment(
57 CSegArray oldSegArray,
62 /*************************************************************************
66 **************************************************************************/
68 /*************************************************************************
70 ** Function Definitions **
72 **************************************************************************/
80 File *mergedFileOutPtr,
85 int rc = 0; /* return code */
86 CSegArray newSegs = NULL;
87 CSegArray oldSegs = NULL;
88 File mergedFile = NULL;
89 File deltaFile = NULL;
100 fp = util_fopen_locked("merge-old", "w");
102 off = ftell(oldFile);
103 while ((c = fgetc(oldFile)) != EOF)
108 fseek(oldFile, off, SEEK_SET);
113 fp = util_fopen_locked("merge-new", "w");
115 off = ftell(newFile);
116 while ((c = fgetc(newFile)) != EOF)
121 fseek(newFile, off, SEEK_SET);
128 rc = abmfP_parse_c_file(oldFile, &oldSegs);
129 return_if_err(rc,rc);
133 rc = abmfP_parse_c_file(newFile, &newSegs);
134 return_if_err(rc,rc);
137 rc = merge_files_by_segment(
138 oldFile, oldSegs, oldFileName,
139 newFile, newSegs, newFileName,
148 *mergedFileOutPtr = mergedFile;
149 if (deltaFileOutPtr != NULL)
151 *deltaFileOutPtr = deltaFile;
156 cseg_array_destroy(oldSegs);
157 cseg_array_destroy(newSegs);
163 * Merges segments in C files
165 * Assumes: all segments and user segments are sorted by beginning offset.
168 merge_files_by_segment(
175 File *mergedFileOutPtr,
176 File *deltaFileOutPtr
179 int return_value = 0;
180 int numSegsChanged = 0;
182 long oldFileOffset = 0;
183 long nextModOffset = 0;
184 long nextDeltaOffset = 0;
185 File mergedFile = NULL;
186 File deltaFile = NULL;
187 CUserSeg oldUserSeg = NULL;
188 CUserSeg newUserSeg = NULL;
190 *mergedFileOutPtr = NULL;
191 *deltaFileOutPtr = NULL;
193 numSegsChanged = match_all_segments(oldSegs, newSegs);
194 if (numSegsChanged < 1)
199 mergedFile = tmpfile();
200 if (deltaFileOutPtr != NULL)
202 deltaFile = tmpfile();
207 oldUserSeg = oldSegs->firstUserSeg;
208 while ((oldUserSeg != NULL) && (oldUserSeg->clientData == NULL))
210 oldUserSeg = oldUserSeg->next;
212 assert(oldUserSeg != NULL); /* at least one change exists */
213 nextModOffset = oldUserSeg->offset;
214 while ((c = fgetc(oldFile)) != EOF)
217 if (oldFileOffset == (nextModOffset+1))
219 newUserSeg = ((CUserSeg)(oldUserSeg->clientData));
220 if ( (deltaFile != NULL)
221 && (!util_streq(oldUserSeg->text, newUserSeg->text)) )
224 "\n========================================\n");
226 "----- FROM (old file, line %ld) -----\n"
228 oldUserSeg->line, oldUserSeg->text);
230 "----- TO (new file, line %ld) -----\n"
232 newUserSeg->line, newUserSeg->text);
237 fputs(newUserSeg->text, mergedFile);
238 oldFileOffset = oldUserSeg->offset + oldUserSeg->length;
239 fseek(oldFile, oldFileOffset, SEEK_SET);
241 oldUserSeg = oldUserSeg->next;
242 while ((oldUserSeg != NULL) && (oldUserSeg->clientData == NULL))
244 oldUserSeg = oldUserSeg->next;
246 nextModOffset = (oldUserSeg == NULL? -1:oldUserSeg->offset);
250 fputc(c, mergedFile);
254 (*mergedFileOutPtr) = mergedFile;
255 (*deltaFileOutPtr) = deltaFile;
261 * Sets clientData to point to corresponding segments and user segments, IFF
262 * the segments have changed.
264 * Returns the # of user segments that have actually changed.
267 match_all_segments(CSegArray oldSegs, CSegArray newSegs)
271 BOOL segChanged = FALSE;
272 int userSegChangeCount = 0;
273 int userSegCount = 0;
276 for (i = 0; i < oldSegs->numSegs; ++i)
278 oldSeg = &(oldSegs->segs[i]);
279 newSeg = match_segment(oldSeg, oldSegs, newSegs);
281 oldSeg->clientData = NULL;
285 for (userSegCount = 0;
286 (userSegCount < oldSeg->userSegs.numSegs)
287 && (userSegCount < newSeg->userSegs.numSegs);
290 if (!util_streq(oldSeg->userSegs.segs[userSegCount].text,
291 newSeg->userSegs.segs[userSegCount].text))
294 ++userSegChangeCount;
296 oldSeg->userSegs.segs[userSegCount].clientData =
297 &(newSeg->userSegs.segs[userSegCount]);
300 #ifdef BOGUS /* (debugging stuff) */
301 printf("[%s] %ld -> %ld\n",
302 oldSeg->userSegs.segs[userSegCount].clientData == NULL?
304 oldSeg->userSegs.segs[userSegCount].line,
305 newSeg->userSegs.segs[userSegCount].line);
311 oldSeg->clientData = (void *)newSeg;
315 return userSegChangeCount;
322 CSegArray oldSegArray,
323 CSegArray newSegArray
327 int oldSegIndex = -1;
329 int newSegIndex = -1;
334 if (oldSeg->type == CSEG_GLOBAL)
337 * Global segments are unnamed - find number of segment
340 for (i = 0; i < oldSegArray->numSegs; ++i)
342 if (oldSegArray->segs[i].type == CSEG_GLOBAL)
346 if (&(oldSegArray->segs[i]) == oldSeg)
353 /* these asserts check to see if seg is in array at all */
354 assert(oldSegNum >= 0);
355 assert((oldSegIndex >= 0) && (oldSegIndex < oldSegArray->numSegs));
359 * Find matching segment in new array
362 for (i = 0; i < newSegArray->numSegs; ++i)
364 if (newSegArray->segs[i].type == CSEG_GLOBAL)
368 if (oldSegNum == newSegNum)
373 if (newSegNum != oldSegNum)
379 newSeg = &(newSegArray->segs[newSegIndex]);
383 /* Not global - find segment by name */
384 for (i = 0; i < newSegArray->numSegs; ++i)
386 if (util_streq(oldSeg->name, newSegArray->segs[i].name))
388 newSeg = &(newSegArray->segs[i]);
401 main (int argc, char *argv[])
403 int rc = 0; /* return code */
404 STRING newFileName = NULL;
406 STRING oldFileName = NULL;
408 File mergedFile = NULL;
409 File deltaFile = NULL;
412 util_init(&argc, &argv);
415 fprintf(stderr, "Usage: %s <old-file> <new-file>\n", argv[0]);
418 oldFileName = argv[1];
419 newFileName = argv[2];
424 oldFile = util_fopen_locked(oldFileName, "r");
430 newFile = util_fopen_locked(newFileName, "r");
440 rc = abmfP_merge_c_files(
441 oldFile, oldFileName,
442 newFile, newFileName,
446 if ((rc >= 0) && (mergedFile == NULL))
448 printf("No changes found.\n");
451 if (deltaFile != NULL)
455 sprintf(name, "%s.delta", oldFileName);
456 printf("writing %s\n", name);
458 f = util_fopen_locked(name, "w");
465 while ((c = fgetc(deltaFile)) != EOF)
469 util_fclose(deltaFile);
473 if (mergedFile != NULL)
477 sprintf(name, "%s.merge", oldFileName);
478 printf("writing %s\n", name);
480 f = util_fopen_locked(name, "w");
487 while ((c = fgetc(mergedFile)) != EOF)
491 util_fclose(mergedFile);
495 util_fclose(oldFile);
496 util_fclose(newFile);