哪位师兄能给两个用C写的合一算法(unify)实例,晚上就结贴,一分不少

narason 2003-05-08 08:57:14
为了应付明天的作业,先谢谢你们了,内容同上
...全文
152 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
yizhenfeng 2003-05-08
  • 打赏
  • 举报
回复

程序二

/* 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);
yizhenfeng 2003-05-08
  • 打赏
  • 举报
回复
/* hash some C/C++ code after unifying */
static void unify(unsigned char *p, size_t size)
{
size_t ofs;
unsigned char q;
int i;

build_table();

for (ofs=0; ofs<size;) {
if (p[ofs] == '#') {
if ((size-ofs) > 2 && p[ofs+1] == ' ' && isdigit(p[ofs+2])) {
do {
ofs++;
} while (ofs < size && p[ofs] != '\n');
ofs++;
} else {
do {
pushchar(p[ofs]);
ofs++;
} while (ofs < size && p[ofs] != '\n');
pushchar('\n');
ofs++;
}
continue;
}

if (tokens[p[ofs]].type & C_ALPHA) {
do {
pushchar(p[ofs]);
ofs++;
} while (ofs < size &&
(tokens[p[ofs]].type & (C_ALPHA|C_DIGIT)));
pushchar('\n');
continue;
}

if (tokens[p[ofs]].type & C_DIGIT) {
do {
pushchar(p[ofs]);
ofs++;
} while (ofs < size &&
((tokens[p[ofs]].type & C_DIGIT) || p[ofs] == '.'));
if (ofs < size && (p[ofs] == 'x' || p[ofs] == 'X')) {
do {
pushchar(p[ofs]);
ofs++;
} while (ofs < size && (tokens[p[ofs]].type & C_HEX));
}
if (ofs < size && (p[ofs] == 'E' || p[ofs] == 'e')) {
pushchar(p[ofs]);
ofs++;
while (ofs < size &&
(tokens[p[ofs]].type & (C_DIGIT|C_SIGN))) {
pushchar(p[ofs]);
ofs++;
}
}
while (ofs < size && (tokens[p[ofs]].type & C_FLOAT)) {
pushchar(p[ofs]);
ofs++;
}
pushchar('\n');
continue;
}

if (tokens[p[ofs]].type & C_SPACE) {
do {
ofs++;
} while (ofs < size && (tokens[p[ofs]].type & C_SPACE));
continue;
}

if (tokens[p[ofs]].type & C_QUOTE) {
q = p[ofs];
pushchar(p[ofs]);
do {
ofs++;
while (ofs < size-1 && p[ofs] == '\\') {
pushchar(p[ofs]);
pushchar(p[ofs+1]);
ofs+=2;
}
pushchar(p[ofs]);
} while (ofs < size && p[ofs] != q);
pushchar('\n');
ofs++;
continue;
}

if (tokens[p[ofs]].type & C_TOKEN) {
q = p[ofs];
for (i=0;i<tokens[q].num_toks;i++) {
unsigned char *s = (unsigned char *)tokens[q].toks[i];
int len = strlen((char *)s);
if (size >= ofs+len && memcmp(&p[ofs], s, len) == 0) {
int j;
for (j=0;s[j];j++) {
pushchar(s[j]);
ofs++;
}
pushchar('\n');
break;
}
}
if (i < tokens[q].num_toks) {
continue;
}
}

pushchar(p[ofs]);
pushchar('\n');
ofs++;
}
pushchar(0);
}


/* hash a file that consists of preprocessor output, but remove any line
number information from the hash
*/
int unify_hash(const char *fname)
{
int fd;
struct stat st;
char *map;

fd = open(fname, O_RDONLY);
if (fd == -1 || fstat(fd, &st) != 0) {
cc_log("Failed to open preprocessor output %s\n", fname);
stats_update(STATS_PREPROCESSOR);
return -1;
}

/* we use mmap() to make it easy to handle arbitrarily long
lines in preprocessor output. I have seen lines of over
100k in length, so this is well worth it */
map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (map == (char *)-1) {
cc_log("Failed to mmap %s\n", fname);
return -1;
}
close(fd);

/* pass it through the unifier */
unify((unsigned char *)map, st.st_size);

munmap(map, st.st_size);

return 0;
}
yizhenfeng 2003-05-08
  • 打赏
  • 举报
回复

#include "ccache.h"

static char *s_tokens[] = {
"...", ">>=", "<<=", "+=", "-=", "*=", "/=", "%=", "&=", "^=",
"|=", ">>", "<<", "++", "--", "->", "&&", "||", "<=", ">=",
"==", "!=", ";", "{", "<%", "}", "%>", ",", ":", "=",
"(", ")", "[", "<:", "]", ":>", ".", "&", "!", "~",
"-", "+", "*", "/", "%", "<", ">", "^", "|", "?",
0
};

#define C_ALPHA 1
#define C_SPACE 2
#define C_TOKEN 4
#define C_QUOTE 8
#define C_DIGIT 16
#define C_HEX 32
#define C_FLOAT 64
#define C_SIGN 128

static struct {
unsigned char type;
unsigned char num_toks;
char *toks[7];
} tokens[256];

/* build up the table used by the unifier */
static void build_table(void)
{
unsigned char c;
int i;
static int done;

if (done) return;
done = 1;

memset(tokens, 0, sizeof(tokens));
for (c=0;c<128;c++) {
if (isalpha(c) || c == '_') tokens[c].type |= C_ALPHA;
if (isdigit(c)) tokens[c].type |= C_DIGIT;
if (isspace(c)) tokens[c].type |= C_SPACE;
if (isxdigit(c)) tokens[c].type |= C_HEX;
}
tokens['\''].type |= C_QUOTE;
tokens['"'].type |= C_QUOTE;
tokens['l'].type |= C_FLOAT;
tokens['L'].type |= C_FLOAT;
tokens['f'].type |= C_FLOAT;
tokens['F'].type |= C_FLOAT;
tokens['U'].type |= C_FLOAT;
tokens['u'].type |= C_FLOAT;

tokens['-'].type |= C_SIGN;
tokens['+'].type |= C_SIGN;

for (i=0;s_tokens[i];i++) {
c = s_tokens[i][0];
tokens[c].type |= C_TOKEN;
tokens[c].toks[tokens[c].num_toks] = s_tokens[i];
tokens[c].num_toks++;
}
}

/* buffer up characters before hashing them */
static void pushchar(unsigned char c)
{
static unsigned char buf[64];
static int len;

if (c == 0) {
if (len > 0) {
hash_buffer((char *)buf, len);
len = 0;
}
hash_buffer(NULL, 0);
return;
}

buf[len++] = c;
if (len == 64) {
hash_buffer((char *)buf, len);
len = 0;
}
}

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧