各位大哥大姐,小弟抗着代码误闯到了CSDN论坛,没想到到门前还摔了一跤,救救我吧!

davansy 2009-06-10 01:24:44
我学过一点C,丢人。昨天同学给我传了点代码过来,看得我是一头雾水,进而满脸汗水!下边的一些代码他是C语言还是C++生出来的?是C语言生出来的话,我也应该认识啊,可是我瞧着某些部位陌生。(吃素的菜鸟一个,少见多怪了!)其中有些问题我搞不太清楚,在代码中偷了一些空间,注释了一些我不太明白的地方。希望得到你们解惑,能否给我讲解一下函数的功能?谢谢啦!
/* cdiff - context diff Author: Larry Wall */

/* Cdiff - turns a regular diff into a new-style context diff
*
* Usage: cdiff file1 file2
*/

#define PATCHLEVEL 2

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <limits.h>
#include <stdio.h>

char buff[512];

FILE *inputfp, *oldfp, *newfp;

int oldmin, oldmax, newmin, newmax;
int oldbeg, oldend, newbeg, newend;
int preoldmax, prenewmax;
int preoldbeg, preoldend, prenewbeg, prenewend;
int oldwanted, newwanted;

char *oldhunk, *newhunk;
char *progname;
size_t oldsize, oldalloc, newsize, newalloc;/*C中一个分号代表这这行代码的结束,C语言室强类型语言,声明变量时应该声明它的类型才对。这里没有声明类型,C语言中一般编译环境默认类型是什么?*/

_PROTOTYPE(int main, (int argc, char **argv));/*这里我猜_PROTOTYPE是原型吧,最近看了一些关于javascript原型链的,另外前边还有下划线,是不是私有的意思?我从javascript中了解到私有这么一会事(javascript中的私有,也是引用其他语言的,不只到时不是引用这里的)。*/
_PROTOTYPE(void dumphunk, (void));
_PROTOTYPE(char *getold, (int targ));
_PROTOTYPE(char *getnew, (int targ));
_PROTOTYPE(void *xmalloc, (size_t size));
_PROTOTYPE(void *xrealloc, (void *ptr, size_t size));

#define Nullfp (FILE*)0
#define Nullch (char*)0
#define ENOUGH (NAME_MAX + PATH_MAX + 1)
#define CRC_END 12

int main(argc, argv)
int argc;
char **argv;
{
FILE *crcfp;
char *old, *new;
int context = 3;
struct stat statbuf;
register char *s;
char op;
char *newmark, *oldmark;
char sysbuf1[ENOUGH], sysbuf2[ENOUGH];
int len;
char *line;
int i;
int status;
/*这里可能少了一个花括号,上边从 char **argv;开始到这行注释的内容是不是结构体?*/
progname = argv[0];
oldalloc = 512;
oldhunk = (char *) xmalloc(oldalloc);
newalloc = 512;
newhunk = (char *) xmalloc(newalloc);

for (argc--, argv++; argc; argc--, argv++) {
if (argv[0][0] != '-') break;

if (argv[0][1] == 'c') context = atoi(argv[0] + 2);
}

if (argc != 2) {
fprintf(stderr, "Usage: cdiff old new\n");
exit(2);
}
old = argv[0];
new = argv[1];

oldfp = fopen(old, "r");
if (!oldfp) {
fprintf(stderr, "Can't open %s\n", old);
exit(2);
}
newfp = fopen(new, "r");
if (!newfp) {
fprintf(stderr, "Can't open %s\n", new);
exit(2);
}

/* Compute crcs by popen()ing crc and reading the output. Do this before
* popen()ing diff to do the work. popen() attempts to support multiple
* clients, but the 1.3-1.6.24b versions don't succeed.
*/
sprintf(sysbuf1, "crc %s", old);
crcfp = popen(sysbuf1, "r");
if (!crcfp) {
/* The only advantage of cdiff over diff is that it prints crcs, so
* give up easily if crc fails.
*/
fprintf(stderr, "Can't execute crc %s\n", old);
exit(2);
}
fgets(sysbuf1, sizeof(sysbuf1), crcfp);
sysbuf1[CRC_END] = '\0';
status = pclose(crcfp);
if (status != 0) {
fprintf(stderr, "crc %s returned bad status %d\n", old, status);
exit(2);
}
sprintf(sysbuf2, "crc %s", new);
crcfp = popen(sysbuf2, "r");
if (!crcfp) {
fprintf(stderr, "Can't execute crc %s\n", new);
exit(2);
}
fgets(sysbuf2, sizeof(sysbuf2), crcfp);
sysbuf2[CRC_END] = '\0';
status = pclose(crcfp);
if (status != 0) {
fprintf(stderr, "crc %s returned bad status %d\n", new, status);
exit(2);
}

sprintf(buff, "diff %s %s 2>/dev/null", old, new);
inputfp = popen(buff, "r");
if (!inputfp) {
fprintf(stderr, "Can't execute diff %s %s\n", old, new);
exit(2);
}

fstat(fileno(oldfp), &statbuf);
printf("*** %s crc=%s\t%s", old, sysbuf1, ctime(&statbuf.st_mtime));
fstat(fileno(newfp), &statbuf);
printf("--- %s crc=%s\t%s", new, sysbuf2, ctime(&statbuf.st_mtime));

preoldend = -1000;

while (fgets(buff, sizeof buff, inputfp) != Nullch) {
if (isdigit(*buff)) {
oldmin = atoi(buff);
for (s = buff; isdigit(*s); s++);
if (*s == ',') {
s++;
oldmax = atoi(s);
for (; isdigit(*s); s++);
} else {
oldmax = oldmin;
}
if (*s != 'a' && *s != 'd' && *s != 'c') {
fprintf(stderr, "Unparseable input: %s\n", s);
exit(2);
}
op = *s;
s++;
newmin = atoi(s);
for (; isdigit(*s); s++);
if (*s == ',') {
s++;
newmax = atoi(s);
for (; isdigit(*s); s++);
} else {
newmax = newmin;
}
if (*s != '\n' && *s != ' ') {
fprintf(stderr, "Unparseable input: %s\n", s);
exit(2);
}
newmark = oldmark = "! ";
if (op == 'a') {
oldmin++;
newmark = "+ ";
}
if (op == 'd') {
newmin++;
oldmark = "- ";
}
oldbeg = oldmin - context;
oldend = oldmax + context;
if (oldbeg < 1) oldbeg = 1;
newbeg = newmin - context;
newend = newmax + context;
if (newbeg < 1) newbeg = 1;

if (preoldend < oldbeg - 1) {
if (preoldend >= 0) {
dumphunk();
}
preoldbeg = oldbeg;
prenewbeg = newbeg;
oldwanted = newwanted = 0;
oldsize = newsize = 0;
} else { /* we want to append to previous hunk */
oldbeg = preoldmax + 1;
newbeg = prenewmax + 1;
}

for (i = oldbeg; i <= oldmax; i++) {
line = getold(i);
if (!line) {
oldend = oldmax = i - 1;
break;
}
len = strlen(line) + 2;
if (oldsize + len + 1 >= oldalloc) {
oldalloc *= 2;
oldhunk = (char *) xrealloc(oldhunk, oldalloc);
}
if (i >= oldmin) {
strcpy(oldhunk + oldsize, oldmark);
oldwanted++;
} else {
strcpy(oldhunk + oldsize, " ");
}
strcpy(oldhunk + oldsize + 2, line);
oldsize += len;
}
preoldmax = oldmax;
preoldend = oldend;

for (i = newbeg; i <= newmax; i++) {
line = getnew(i);
if (!line) {
newend = newmax = i - 1;
break;
}
len = strlen(line) + 2;
if (newsize + len + 1 >= newalloc) {
newalloc *= 2;
newhunk = (char *) xrealloc(newhunk, newalloc);
}
if (i >= newmin) {
strcpy(newhunk + newsize, newmark);
newwanted++;
} else {
strcpy(newhunk + newsize, " ");
}
strcpy(newhunk + newsize + 2, line);
newsize += len;
}
prenewmax = newmax;
prenewend = newend;
}
}

if (preoldend >= 0) {
dumphunk();
}
status = pclose(inputfp);
if (!WIFEXITED(status)) exit(2);
status = WEXITSTATUS(status);
return(status == 0 || status == 1 ? status : 2);
}

void dumphunk()
{
int i;
char *line;
int len;

for (i = preoldmax + 1; i <= preoldend; i++) {
line = getold(i);
if (!line) {
preoldend = i - 1;
break;
}
len = strlen(line) + 2;
if (oldsize + len + 1 >= oldalloc) {
oldalloc *= 2;
oldhunk = (char *) xrealloc(oldhunk, oldalloc);
}
strcpy(oldhunk + oldsize, " ");
strcpy(oldhunk + oldsize + 2, line);
oldsize += len;
}
for (i = prenewmax + 1; i <= prenewend; i++) {
line = getnew(i);
if (!line) {
prenewend = i - 1;
break;
}
len = strlen(line) + 2;
if (newsize + len + 1 >= newalloc) {
newalloc *= 2;
newhunk = (char *) xrealloc(newhunk, newalloc);
}
strcpy(newhunk + newsize, " ");
strcpy(newhunk + newsize + 2, line);
newsize += len;
}
printf("***************\n");
if (preoldbeg >= preoldend) {
printf("*** %d ****\n", preoldend);
} else {
printf("*** %d,%d ****\n", preoldbeg, preoldend);
}
if (oldwanted) {
printf("%s", oldhunk);
}
oldsize = 0;
*oldhunk = '\0';
if (prenewbeg >= prenewend) {
printf("--- %d ----\n", prenewend);
} else {
printf("--- %d,%d ----\n", prenewbeg, prenewend);
}
if (newwanted) {
printf("%s", newhunk);
}
newsize = 0;
*newhunk = '\0';
}

char *getold(targ)
int targ;
{
static int oldline = 0;

while (fgets(buff, sizeof buff, oldfp) != Nullch) {
oldline++;
if (oldline == targ) return buff;
}
return Nullch;
}

char *getnew(targ)
int targ;
{
static int newline = 0;

while (fgets(buff, sizeof buff, newfp) != Nullch) {
newline++;
if (newline == targ) return buff;
}
return Nullch;
}

void *xmalloc(size)
size_t size;
{
void *ptr;

ptr = malloc(size);
if (ptr == NULL) {
fprintf(stderr, "%s: out of memory\n", progname);
exit(2);
}
return(ptr);
}

void *xrealloc(ptr, size)
void *ptr;
size_t size;
{
ptr = realloc(ptr, size);
if (ptr == NULL) {
fprintf(stderr, "%s: out of memory\n", progname);
exit(2);
}
return(ptr);
}
...全文
117 19 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
guocai_yao 2009-06-10
  • 打赏
  • 举报
回复
太长了 只能帮顶
breezes2008 2009-06-10
  • 打赏
  • 举报
回复
模拟命令行模式下的命令。像copy file1 file2 ,只是功能不能。
太长,看不下去。
size_t 代表unsigned int 类型。像strlen函数返回类型就是size_t型。
如果没记错的话,还有个time_t表示unsigned long类型。
justlastone 2009-06-10
  • 打赏
  • 举报
回复
真长。。
javaboy_2008 2009-06-10
  • 打赏
  • 举报
回复
davansy 2009-06-10
  • 打赏
  • 举报
回复
,此代码是minix中一个小工具的源代码,写法肯定是很古老的了,不过我想要知道里边函数的具体功能,还请各位大哥大姐能有空帮我看看,给我讲解讲解它们的功能,小弟万分感谢!@
jhony_lee 2009-06-10
  • 打赏
  • 举报
回复
linux下的C了
night_mare 2009-06-10
  • 打赏
  • 举报
回复
这个应该是在linux跑的代码,看看头文件应该是这样的
  • 打赏
  • 举报
回复
太长了,帮顶
The_facE 2009-06-10
  • 打赏
  • 举报
回复
都是K&R风格的函数。
太长,头痛,不看了。
linren 2009-06-10
  • 打赏
  • 举报
回复
int main(argc, argv)
int argc;
char **argv;
{
…………
…………
}

上面是传统格式的函数
现在用的是现代格式的函数
「已注销」 2009-06-10
  • 打赏
  • 举报
回复
纯C代码
lambert_s 2009-06-10
  • 打赏
  • 举报
回复
太长了,看不下去了。。。
rivulettornado 2009-06-10
  • 打赏
  • 举报
回复
看头文件,应该是linux下的吧
davansy 2009-06-10
  • 打赏
  • 举报
回复
嗯,学了C语言过了级,今天看到代码,有些东西都没见过。学习学习.....
brookmill 2009-06-10
  • 打赏
  • 举报
回复
int main(argc, argv)
int argc;
char **argv;
{
……
}

这是二十多年前的函数定义的写法,相当于现在的
int main(int argc, char **argv)
{
……
}

/*这里可能少了一个花括号,上边从 char **argv;开始到这行注释的内容是不是结构体?*/
这里不缺花括号,都是正常的函数内部局部变量的声明。
brookmill 2009-06-10
  • 打赏
  • 举报
回复
size_t oldsize, oldalloc, newsize, newalloc;/*C中一个分号代表这这行代码的结束,C语言室强类型语言,声明变量时应该声明它的类型才对。这里没有声明类型,C语言中一般编译环境默认类型是什么?*/
size_t就是类型,一般是在某个系统头文件里用typedef定义的

_PROTOTYPE(int main, (int argc, char **argv));/*这里我猜_PROTOTYPE是原型吧,最近看了一些关于javascript原型链的,另外前边还有下划线,是不是私有的意思?我从javascript中了解到私有这么一会事(javascript中的私有,也是引用其他语言的,不只到时不是引用这里的)。*/
_PROTOTYPE多半是个宏定义,用于声明函数。不过我看不出这种做法有什么好处。
从它的用法来看,应该是展开成 int main(int argc, char **argv);
neohope 2009-06-10
  • 打赏
  • 举报
回复
c,但好像不是ansi

/* Cdiff - turns a regular diff into a new-style context diff
*
* Usage: cdiff file1 file2
*/

这里已经告诉你很明白了,比较两个文件的不同
traceless 2009-06-10
  • 打赏
  • 举报
回复
是C的范围,不涉及到C++方面的

代码好长
davansy 2009-06-10
  • 打赏
  • 举报
回复
小弟用饥渴的目光,跪求里面函数的功能,大哥大姐们给小弟指点指点迷津,小弟再谢!

70,023

社区成员

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

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