home *** CD-ROM | disk | FTP | other *** search
- /*
- * The merged diff format added by Chip Rosenthal <chip@chinacat.unicom.com>
- */
-
- #include "diff.h"
-
- #define TABSTOP 8 /* must be a power of two (e.g. 4, 8, etc.) */
-
- #define Fput3(FP,S1,S2,S3) \
- ( fputs((S1),(FP)), fputs((S2),(FP)), fputs((S3),(FP)), putc('\n',(FP)) )
-
- #define Strncpy(OUT,IN,LEN) \
- ( (OUT)[(LEN)] = '\0', strncpy((OUT),(IN),(LEN)) )
-
- static int field_width;
- static char *field0_buf, *field1_buf, *tmp_buf;
-
- static void print_merged_hunk();
- static void expand_field();
-
- extern struct change *find_change();
-
-
- void print_merged_script(script)
- struct change *script;
- {
-
- /*
- * Figure out how big a field to print the file differences in.
- */
- field_width = ( line_width - (sizeof("-+-")-1) ) / 2;
- if ( field_width < 1 ) {
- fputs("diff: bad field width specified\n",stderr);
- exit(1);
- }
-
- /*
- * Create the space for formatting.
- */
- field0_buf = (char*) xmalloc((unsigned)field_width+1);
- field1_buf = (char*) xmalloc((unsigned)field_width+1);
- tmp_buf = (char*) xmalloc((unsigned)field_width+1);
-
- /*
- * Print the header.
- */
- expand_field(tmp_buf, (char*)NULL, field_width, '-'),
- Fput3(outfile, tmp_buf, "-+-", tmp_buf);
-
- (void) Strncpy(tmp_buf, files[0].name, field_width);
- expand_field(field0_buf, tmp_buf, field_width, ' '),
- (void) Strncpy(tmp_buf, files[1].name, field_width);
- expand_field(field1_buf, tmp_buf, field_width, ' '),
- Fput3(outfile, field0_buf, " | ", field1_buf);
-
- /*
- * Print the hunks.
- */
- print_script(script, find_change, print_merged_hunk);
-
- /*
- * Print the trailer.
- */
- expand_field(tmp_buf, (char*)NULL, field_width, '-'),
- Fput3(outfile, tmp_buf, "-+-", tmp_buf);
-
- free(field0_buf);
- free(field1_buf);
- free(tmp_buf);
- }
-
-
- static void print_merged_hunk(hunk)
- struct change *hunk;
- {
- int first0, last0, first1, last1, deletes, inserts, tr_first, tr_last, len;
- char *action;
- register int i0, i1;
-
- /*
- * Determine range of line numbers involved in each file.
- */
- analyze_hunk(hunk, &first0, &last0, &first1, &last1, &deletes, &inserts);
- if ( deletes > 0 && inserts > 0 )
- action = "change";
- else if ( deletes > 0 )
- action = "delete";
- else if ( inserts > 0 )
- action = "insert";
- else
- return;
-
- /*
- * Print the header for this hunk.
- */
- translate_range(&files[0], first0, last0, &tr_first, &tr_last);
- if ( tr_last > tr_first )
- (void) sprintf(tmp_buf, "--- %s at %d-%d ", action, tr_first, tr_last);
- else
- (void) sprintf(tmp_buf, "--- %s at %d ", action, tr_last);
- expand_field(field0_buf, tmp_buf, field_width, '-');
-
- translate_range(&files[1], first1, last1, &tr_first, &tr_last);
- if ( tr_last > tr_first )
- (void) sprintf(tmp_buf, " %d-%d ", tr_first, tr_last);
- else
- (void) sprintf(tmp_buf, " %d ", tr_last);
- expand_field(field1_buf, tmp_buf, field_width, '-');
-
- Fput3(outfile, field0_buf, "-+-", field1_buf);
-
- /*
- * Format and print each line in this hunk.
- */
- for ( i0 = first0, i1 = first1 ; i0 <= last0 || i1 <= last1 ; ++i0, ++i1 ) {
-
- if ( i0 <= last0 ) {
- len = ( files[0].linbuf[i0].length < field_width ?
- files[0].linbuf[i0].length : field_width );
- Strncpy(tmp_buf, files[0].linbuf[i0].text, len);
- expand_field(field0_buf, tmp_buf, field_width, ' ');
- } else {
- expand_field(field0_buf, (char*)NULL, field_width, ' ');
- }
-
- if ( i1 <= last1 ) {
- len = ( files[1].linbuf[i1].length < field_width ?
- files[1].linbuf[i1].length : field_width );
- Strncpy(tmp_buf, files[1].linbuf[i1].text, len);
- expand_field(field1_buf, tmp_buf, field_width, ' ');
- } else {
- expand_field(field1_buf, (char*)NULL, field_width, ' ');
- }
-
- Fput3(outfile, field0_buf, " | ", field1_buf);
-
- }
-
- }
-
-
- /*
- * The expand_field() routine performs two functions. First, it goes
- * through "inbuf" and reformats the line doing stuff like expanding
- * tabs and stripping out newlines. Second, it expands the text to
- * "fieldlen" characters, using the "padchar" to fill to this length.
- * If the "inbuf" is NULL, we just generate a string of the "padchar".
- */
- static void expand_field(outbuf,inbuf,fieldlen,padchar)
- char *outbuf;
- char *inbuf;
- int fieldlen;
- int padchar;
- {
- int currcol;
-
- /*
- * If no string was passed to us, make one of the full field length.
- */
- if ( inbuf == NULL ) {
- while ( --fieldlen >= 0 )
- *outbuf++ = padchar;
- *outbuf = '\0';
- return;
- }
-
- /*
- * Go through the string doing translations (tab expansion, etc.).
- */
- currcol = 1;
- while ( *inbuf != '\0' && fieldlen > 0 ) {
- if ( *inbuf == '\t' ) {
- do {
- *outbuf++ = ' ';
- } while ( --fieldlen >= 0 && !( currcol++ & TABSTOP ) ) ;
- ++inbuf;
- } else if ( isascii(*inbuf) && isprint(*inbuf) ) {
- *outbuf++ = *inbuf++;
- ++currcol;
- --fieldlen;
- } else {
- ++inbuf; /* elide this character */
- }
- }
-
- /*
- * Finally, pad it out to the required length.
- */
- while ( --fieldlen >= 0 )
- *outbuf++ = padchar;
- *outbuf = '\0';
- }
-