📄 a.cpp
字号:
/* 92-12-22 @ftp.uu.net:/usenet/comp.sources.misc/volume25/unidiff/part01.Z */
/*
** unify.c - change a diff to/from a context diff from/to a unified diff.
**
** Version 1.1
**
** Author: Wayne Davison <davison@borland.com>
**
** Feel free to use this code in any way you desire.
*/
#include <stdio.h>
extern char *malloc();
#define FIND_NEXT 0
#define PARSE_UNIDIFF 1
#define UNI_LINES 2
#define PARSE_CDIFF 3
#define PARSE_OLD 4
#define CHECK_OLD 5
#define OLD_LINES 6
#define PARSE_NEW 7
#define NEW_LINES 8
#define strnEQ(s1,s2,n) (!strncmp(s1,s2,n))
#define strnNE(s1,s2,n) strncmp(s1,s2,n)
#define AtoL(cp,n) {n = atol(cp); while (*cp <= '9' && *cp >= '0') cp++; }
char buf[2048];
struct liner {
struct liner *link;
char type;
int num;
char str[1];
} root, *head = &root, *hold = &root, *line;
long o_first = 0, o_last = -1;
long n_first = 0, n_last = 0;
long o_start, o_end, o_line;
long n_start, n_end, n_line;
long line_num = 0;
int input_type = 0;
int output_type = 0;
int echo_comments = 0;
int strip_comments = 0;
int patch_format = 0;
int use_equals = 0;
int state = FIND_NEXT;
int found_index = 0;
char name[256] = { '\0' };
void ensure_name(), add_line(), generate_output();
int
main(argc, argv)
int argc;
char *argv[];
{
char type;
char ndiff; /* Equals '*' when we have a new-style context diff */
int odiff = 0;
char star_dash_plus = ' ';
FILE *fp_in = stdin;
while (--argc) {
if (**++argv == '-') {
while (*++*argv) {
switch (**argv) {
case '=': /* use '=' not ' ' in unified diffs */
use_equals = 1;
break;
case 'c': /* force context diff output */
output_type = 2;
break;
case 'e': /* echo comments to stderr */
echo_comments = 1;
break;
case 'o': /* old-style diff, no matter what */
odiff = 1;
break;
case 'p': /* generate patch format */
case 'P':
patch_format = 1;
break;
case 's': /* strip comment lines */
strip_comments = 1;
break;
case 'U': /* force patch-unified output */
patch_format = 1;
case 'u': /* force unified output */
output_type = 1;
break;
default:
fprintf(stderr, "Unknown option: '%c'\n", **argv);
exit(1);
}
}
} else {
if (fp_in != stdin) {
fprintf(stderr, "Only one filename allowed.\n", *argv);
exit(1);
}
if ((fp_in = fopen(*argv, "r")) == NULL) {
fprintf(stderr, "Unable to open '%s'.\n", *argv);
exit(1);
}
}
}
while (fgets(buf, sizeof buf, fp_in)) {
line_num++;
reprocess:
switch (state) {
case FIND_NEXT:
if (input_type < 2 && strnEQ(buf, "@@ -", 4)) {
input_type = 1;
if (!output_type) {
output_type = 2;
}
ensure_name();
state = PARSE_UNIDIFF;
goto reprocess;
}
if (!(input_type & 1) && strnEQ(buf, "********", 8)) {
input_type = 2;
if (!output_type) {
output_type = 1;
}
ensure_name();
state = PARSE_OLD;
break;
}
if (strnEQ(buf, "Index: ", 7)) {
found_index = 1;
printf("%s", buf);
} else if (strnEQ(buf, "Prereq: ", 8)) {
printf("%s", buf);
} else if (strnEQ(buf, "*** ", 4)
|| strnEQ(buf, "--- ", 4)
|| strnEQ(buf, "+++ ", 4)) {
if (!found_index) {
char *cp;
int len;
for (cp=buf+4,len=0; *cp>' ' && len<255; cp++,len++) {
;
}
if (!*name || len < strlen(name)) {
strncpy(name, buf+4, len);
name[len] = '\0';
}
}
if (!patch_format) {
if (output_type == 1 && (*buf == '+'
|| *buf == '-' && star_dash_plus != '*')
|| output_type == 2 && (*buf == '*'
|| *buf == '-' && star_dash_plus == '*')) {
printf("%s", buf);
} else if (*buf == '*' || *buf == '+') {
printf("---%s", buf+3);
} else if (*buf == '-' && star_dash_plus == '*') {
printf("+++%s", buf+3);
} else {
printf("***%s", buf+3);
}
star_dash_plus = *buf;
}
} else if (patch_format
&& (strnEQ(buf, "Only in ", 8) || strnEQ(buf, "Common subdir", 13)
|| strnEQ(buf, "diff -", 6) || strnEQ(buf, "Binary files", 12))) {
if (echo_comments) {
fprintf(stderr, "%s%s", strip_comments ? "" : "!!! ", buf);
}
} else {
if (echo_comments) {
fprintf(stderr, "%s", buf);
}
if (!strip_comments) {
printf("%s", buf);
}
}
break;
case PARSE_UNIDIFF:
{
char *cp;
if (strnNE(buf, "@@ -", 4)) {
found_index = 0;
*name = '\0';
state = FIND_NEXT;
goto reprocess;
}
cp = buf+4;
AtoL(cp, o_start);
if (*cp++ == ',') {
AtoL(cp, o_end);
cp++;
} else {
o_end = 1;
}
if (*cp++ != '+') {
goto bad_header;
}
AtoL(cp, n_start);
if (*cp++ == ',') {
AtoL(cp, n_end);
cp++;
} else {
n_end = 1;
}
if (*cp != '@') {
bad_header:
fprintf(stderr, "Invalid unified diff header at line %ld.\n",
line_num);
exit(1);
}
o_end = (o_start ? o_start + o_end - 1 : 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -