如何阅读源代码(3)
2006-07-04 20:27:47 来源:WEB开发网在preserve.c中,这两个函数是成对出现的。get_history()读取文件中的数据,并将其记录到hist_开头的一些数组中去。而put_history()则是将一些数据记录到同样的数组中去。我们可以推测得知,hist_数组是全局变量(在函数中没有定义),也可以查找源代码验证。同样,我们可以找一找put_history()出现的地方,来验证刚才的推测是否正确。在webalizer.c的1311行,出现:month_update_exit(rec_tstamp); /* calculate exit pages */
write_month_html(); /* write monthly HTML file */
write_main_index(); /* write main HTML file */
put_history(); /* write history */
可以知道,推测是正确的。再往下读代码,if (incremental) /* incremental processing? */
{
if ((i=restore_state())) /* restore internal data structs */
{
/* Error: Unable to restore run data (error num) */
/* if (verbose) fprintf(stderr,"%s (%d) ",msg_bad_data,i); */
fprintf(stderr,"%s (%d) ",msg_bad_data,i);
exit(1);
}
......
}
同样,这也是处理命令行和做数据准备,而且和get_history(), put_history()有些类似,读者可以自己练习一下。下面,终于进入了程序的主体部分, 在做完了命令行分析,数据准备之后,开始从日志文件中读取数据并做分析了。/*********************************************/
/* MAIN PROCESS LOOP - read through log file */
/*********************************************/
while ( (gz_log)?(our_gzgets(gzlog_fp,buffer,BUFSIZE) != Z_NULL):
(fgets(buffer,BUFSIZE,log_fname?log_fp:stdin) != NULL))
我看到这里的时候,颇有一些不同意作者的这种写法。这一段while中的部分写的比较复杂而且效率不高。因为从程序推断和从他的代码看来,作者是想根据日志文件的类型不同来采用不同的方法读取文件,如果是gzip格式,则用our_gzgets来读取其中一行,如果是普通的文本文件格式,则用fgets()来读取。但是,这段代码是写在while循环中的,每次读取一行就要重复判断一次,明显是多余的而且降低了程序的性能。可以在while循环之前做一次这样的判断,然后就不用重复了。total_rec++;
if (strlen(buffer) == (BUFSIZE-1))
{
if (verbose)
{
fprintf(stderr,"%s",msg_big_rec);
if (debug_mode) fprintf(stderr,": %s",buffer);
else fprintf(stderr," ");
}
total_bad++; /* bump bad record counter */
/* get the rest of the record */
while ( (gz_log)?(our_gzgets(gzlog_fp,buffer,BUFSIZE)!=Z_NULL):
(fgets(buffer,BUFSIZE,log_fname?log_fp:stdin)!=NULL))
{
if (strlen(buffer) < BUFSIZE-1)
{
if (debug_mode && verbose) fprintf(stderr,"%s ",buffer);
break;
}
if (debug_mode && verbose) fprintf(stderr,"%s",buffer);
}
continue; /* go get next record if any */
}
更多精彩
赞助商链接