2014年11.28开始看张中庆的Apache源码全景分析,主要是想了解一下服务器端是如何对HTTP协议进行响应的。为此安装了ctags,用来协助vim读源码。使用ctags -R命令会生成一个tags文件,不知是ctags哪里出现了小bug,在生成文件tags中,会有这样的行:
APR_DECLARE srclib/apr/atomic/unix/ia32.c /^APR_DECLARE(apr_status_t) apr_atomic_init(apr_pool_t *p)$/;" f
APR_DECLARE srclib/apr/atomic/unix/ia32.c /^APR_DECLARE(apr_uint32_t) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val)$/;" f
正确的写法应该是如下这样,应该把函数名放在最前面:
apr_atomic_init srclib/apr/atomic/unix/ia32.c /^APR_DECLARE(apr_status_t) apr_atomic_init(apr_pool_t *p)$/;" f
apr_atomic_add32 srclib/apr/atomic/unix/ia32.c /^APR_DECLARE(apr_uint32_t) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val)$/;" f
不仅仅要纠正函数名没有放在一行的最前面这个错误 ,在这个错误纠正后,还要对整个tags文件中的行排序,因为ctags是按顺序搜索函数名、变量名的。比如如说,你纠正过函数名没有放在最前面这个错误后,文件是这个样子的:
bmm_ccc ........
cqe_kkkkk ......
ammm ......
当你搜索ammm这个函数的时候,从文件第一行开始搜索,即bmm_ccc ....,此时的b已经大于a了,搜索就会立即停止。所以还要对文件的行进行排序。
我写了两个比较拙劣的小程序纠正了上面所列的两点错误。
-----------------------------------------------------------(1)纠正函数名位置错误的程序:--------------------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
//判断是否是合法函数名,是返回true,否则返回false
bool functionname_legal(char *name)
{
if( ((*name >= 'a') && (*name <= 'z'))||((*name >= 'A') && (*name <= 'z'))
||(*name == '_'))
return true;
else
return false;
}
//判断是否是c文件,是返回true,否返回false
bool is_cfile(char *line)
{
char *line_point = line;
while(*line_point != '\n')
{
if((*line_point == '.') &&(*(line_point + 1) == 'c'))
{
return true;
}
else
{
line_point++;
}
}
return false;
}
//判断一行中是否存在‘/^’字符
bool slash_exist(char *line)
{
char *line_point = line;
while(*line_point != '\n')
{
if((*line_point == '/') && (*(line_point + 1) == '^'))
{
return true;
}
else
{
line_point++;
}
}
return false;
}
//判断一行中的第一个单词和 /^后的第一个单词是否相同
bool are_words_same(char *line)
{
char *line_point = line;
char *first_word = line;
char *second_word;
while(*line_point != '^')
{
line_point++;
}
line_point++;
if((*line_point == ' ') || (*line_point == '\t'))
{
line_point++;
}
second_word = line_point;
while((*first_word != ' ') && (*first_word != '\t'))
{
if(*first_word == *second_word)
{
first_word++;
second_word++;
}
else
{
return false;
}
}
return true;
}
//计算一行中字符串个数
int line_length(char *line)
{
char *line_point = line;
int counter = 0;
while(*line_point != '\n')
{
counter++;
line_point++;
}
counter += 2;//'\n\0'也算在内
return counter;
}
//将第一个单词换成函数名
void change_firstword_to_functionname(char *line)
{
char *line_point = line;
//提取函数名
while((*line_point != ')') && (*line_point != '\n'))
{
line_point++;
}
if(*line_point == '\n')
{
return;
}
else if(*line_point == ')')
{
line_point++;
}
if((*line_point == ' ')||(*line_point == '\t'))
{
line_point++;
if(!functionname_legal(line_point))//函数名非法
{
return;
}
else
{
char *function_name = line_point;
char *function_name_point = function_name;
char *first_word = line;
char *first_word_point = first_word;
int functionname_length = 0;
int firstword_length = 0;
while(*function_name != '(')
{
functionname_length++;
function_name++;
}
while((*first_word != ' ') && (*first_word != '\t'))
{
firstword_length++;
first_word++;
}
if(functionname_length == firstword_length)
{
int i;
for(i = 0; i < firstword_length; i++)
{
*first_word_point = *function_name_point;
first_word_point++;
function_name_point++;
}
}
else if(functionname_length < firstword_length)
{
int i;
for(i = 0; i < functionname_length; i++)
{
*first_word_point = *function_name_point;
first_word_point++;
function_name_point++;
}
int line_len = line_length(line);
int tail = line_len - firstword_length;
int offset = firstword_length - functionname_length;
for(i = functionname_length; i < tail; i++)
{
*first_word_point = *(first_word_point + offset);
first_word_point++;
}
}
else
{
int line_len = line_length(line);
int offset = functionname_length - firstword_length;
char *functionname = malloc(functionname_length);
int i;
for(i = 0; i < functionname_length; i++)
{
functionname = *function_name_point;
function_name_point++;
}
for(i = line_len - 1; i >= firstword_length; i--)
{
first_word_point[i + offset] = first_word_point;
}
for(i = 0; i < functionname_length; i++)
{
first_word_point = functionname;
}
}
}
}
}
int main()
{
FILE *fsrc = fopen(&quot;/home/xiahuixia/study/code/tag&quot;, &quot;r&quot;); //这行的文件名为需要纠正的文件名
FILE *fdet = fopen(&quot;/home/xiahuixia/study/code/tags&quot;, &quot;w+&quot;); //将纠正后的字符全部保存到这个文件中
if(fsrc == NULL)
{
printf(&quot;open source file failed\n&quot;);
}
else
{
printf(&quot;open source file success\n&quot;);
}
if(fdet == NULL)
{
printf(&quot;open destination file failed\n&quot;);
}
else
{
printf(&quot;open destination file success\n&quot;);
}
int count = 0;
while(!feof(fsrc))
{
count++;
printf(&quot;line is %d\n&quot;, count);
char line_buffer[20000];
fgets(line_buffer, 20000, fsrc);
if(is_cfile(line_buffer) == true)
{
if(slash_exist(line_buffer) == true)
{
if(are_words_same(line_buffer) == true)
{
change_firstword_to_functionname(line_buffer);
//int line_len = line_length(line_buffer);
//int num = fwrite(line_buffer, 1, line_len, fdet);
//printf(&quot;%d %s\n&quot;, num,&quot;words same,change firstword&quot;);
}
}
}
//int line_len = line_length(line_buffer);
//int num = fwrite(line_buffer, 1, line_len, fdet);
// printf(&quot;%d %s\n&quot;, num,&quot;not cfile&quot;);
// printf(&quot;fputs is ready\n&quot;);
fputs(line_buffer, fdet);
printf(&quot;%s&quot;,line_buffer);
//printf(&quot;fputs is over\n&quot;);
}
printf(&quot;last line is %d\n&quot;,count);
fclose(fsrc);
fclose(fdet);
exit(0);
}
-----------------------------------------------------(2)对纠正过函数名位置的文件进行排序------------------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
//计算文件filename的行数
int countFileRows(char *filename)
{
FILE *file = fopen(filename, &quot;r&quot;);
int count = 0;
while(!feof(file))
{
char buffer[20000];
fgets(buffer, 20000, file);
count++;
}
fclose(file);
return count - 1;
}
struct CELL{
char c;
int sequenceBeforeSort;//排序前在文件中的行数
int sequence;//排序后应该在文件中的行数
int col;
bool endOfLine;
};
void cellSeqAndEndOfLineInitialize(struct CELL *cell, int numbers)
{
int i;
for(i = 0; i < numbers; i++)
{
cell.sequenceBeforeSort = cell.sequence = i;
cell.endOfLine = false;
}
}
void cellCharInitialize(FILE *file, struct CELL *cell, int sequence_begin, int sequence_end, int col)
{
//FILE *file = fopen(fileName, &quot;r&quot;);
char buffer[20000];
int j,i;
if(file == NULL)
{
printf(&quot;can't open from %d to %d col:%d\n&quot;, sequence_begin, sequence_end, col );
printf(&quot;%d %c\n&quot;, cell[sequence_begin].sequenceBeforeSort, cell[sequence_begin].c);
int k;
for(k = sequence_begin; k <=sequence_end; k++)
{
cell[k].endOfLine = true;
}
return;
}
//printf(&quot;cellCharinitial col is %d\n&quot;,col);
//printf(&quot;cellcharinitialize sequencebeforesort-----------------------\n&quot;);
for(j = sequence_begin; j <= sequence_end; j++)
{
//printf(&quot;sequencebefore:%d-----sequence%d &quot;, cell[j].sequenceBeforeSort, cell[j].sequence);
fseek(file, 0, SEEK_SET);
for(i = 0; i < cell[j].sequenceBeforeSort; i++)
{
fgets(buffer, 20000, file);
}
fseek(file, col, SEEK_CUR);
char tmp;
tmp = fgetc(file);
if((tmp == '\n')||(tmp == EOF) || (tmp == '\t') || (tmp == ' '))
{
cell[j].endOfLine = true;
}
cell[j].c = tmp;
cell[j].col = col;
}
//printf(&quot;endCharinitial-------------------------------------------------\n&quot;)
}
//交换cell1 cell2
void swap(struct CELL *cell, int cell1, int cell2)
{
int tmpSequence = cell[cell1].sequence;
cell[cell1].sequence = cell[cell2].sequence;
cell[cell2].sequence = tmpSequence;
struct CELL tmp;
tmp = cell[cell1];
cell[cell1] = cell[cell2];
cell[cell2] = tmp;
}
void q_sort(struct CELL *cell, int left, int right)//使用快排思想
{
char c = cell[right].c;
int i = left;
int j;
for(j = left; j < right; j++)
{
if(cell[j].c < c)
{
swap(cell, j, i);
i++;
}
}
swap(cell, i, right);
if(left < i - 1)
{
q_sort(cell, left, i - 1);
}
if(i + 1 < right)
{
q_sort(cell, i + 1, right);
}
}
/*
void lineSort(char *, struct CELL *, int, int, int);
void subSort(char chr, int row_begin, int row_end, int col, char *fileName, struct CELL *cell)
{
int sub_row_begin = 0;
int sub_row_end = 0;
char c;
int i;
for(i = row_begin; i <= row_end; i++)
{
c = cell.c;
if(c == chr )
{
sub_row_begin = i;
sub_row_end = sub_row_begin;
i++;
while( (i <= row_end) &&(cell.c == chr))
{
sub_row_end++;
i++;
}
break;
}
}
if(sub_row_end - sub_row_begin > 0)
{
printf(&quot;subsort from: %d to %d\n&quot;, sub_row_begin, sub_row_end);
printf(&quot;sequencebeforesort:&quot;);
int i;
for(i = sub_row_begin; i <= sub_row_end; i++)
{
printf(&quot;%d &quot;, cell.sequence);
}
printf(&quot;\n&quot;);
col++;
cellCharInitialize(fileName, cell, sub_row_begin, sub_row_end, col);
lineSort(fileName, cell, sub_row_begin, sub_row_end, col);
}
}*/
void lineSort(FILE *file, struct CELL *cell, int row_begin, int row_end, int col)
{
int sub_row_begin = -1;
int sub_row_end = -1;
int i;
int flag = 0;
for(i = row_begin; i <= row_end; i++)
{
if(cell.endOfLine == false)
{
if(flag == 0)
{
sub_row_begin = sub_row_end = i;
flag = 1;
}
else
{
sub_row_end++;
}
}
else if(cell.endOfLine == true)
{
int k;
for(k = row_begin; k< i; k++)
{
if(cell[k].endOfLine == false)
{
swap(cell, k, i);
sub_row_begin = k + 1;
break;
}
}
}
}
/*printf(&quot;linebefore q_sort--%d to %d-----------------------------------------------------\n&quot;, sub_row_begin, sub_row_end);
int q;
if(sub_row_begin < sub_row_end)
{
for(q = sub_row_begin; q <= sub_row_end; q++)
{
printf(&quot;char:%c sequencebeforesort:%d sequence:%d col:%d\n&quot;, cell[q].c, cell[q].sequenceBeforeSort, cell[q].sequence, cell[q].col);
}
}*/
if( sub_row_begin < sub_row_end)
{
q_sort(cell, sub_row_begin, sub_row_end);
printf(&quot;after -------------------qsort from: %d to: %d from column: %d---\n&quot;, sub_row_begin, sub_row_end, col);
/*int p;
for(p = sub_row_begin; p <= sub_row_end; p++)
{
printf(&quot;char:%c sequencebeforesort:%d sequence:%d col:%d\n&quot;,cell[p].c, cell[p].sequenceBeforeSort,cell[p].sequence,cell[p].col);
}
printf(&quot;\n&quot;);*/
char c;
int subsub_row_begin;
int subsub_row_end;
for(i = sub_row_begin; i <= sub_row_end; i++)
{
subsub_row_begin = i;
c = cell.c;
int j = i + 1;
while((j <= sub_row_end) && (cell[j].c == c))
{
j++;
}
subsub_row_end = j - 1;
if(subsub_row_end > subsub_row_begin)
{
int sub_col = col + 1;
cellCharInitialize(file, cell, subsub_row_begin, subsub_row_end, sub_col);
lineSort(file, cell, subsub_row_begin, subsub_row_end, sub_col);
}
i = j - 1;
}
/*
for(c = 'A'; c <= 'Z' ; c++)
{
subSort(c, sub_row_begin, sub_row_end, col, fileName, cell);
}
subSort('_', sub_row_begin, sub_row_end, col, fileName, cell);
for(c = 'a'; c <= 'z'; c++)
{
subSort(c, sub_row_begin, sub_row_end, col, fileName, cell);
} */
}
}
void printFileAfterSort(char *file1, char *file2, struct CELL *cell, int size)
{
FILE *fileOpen = fopen(file1, &quot;r&quot;);
if(fileOpen == NULL)
{
printf(&quot;can't open %s\n&quot;, file1);
}
FILE *fileWrite = fopen(file2, &quot;w&quot;);
if(fileWrite == NULL)
{
printf(&quot;can't open %s\n&quot;, file2);
}
int i;
char buffer[20000];
for(i = 0 ; i < size; i++)
{
fseek(fileOpen, 0, SEEK_SET);
int sequence = cell.sequenceBeforeSort;
int j;
for(j = 0; j <= sequence; j++)
{
fgets(buffer, 20000, fileOpen);
}
fputs(buffer, fileWrite);
printf(&quot;第%d行 &quot;, i);
}
}
int main()
{
char *fileOpen = &quot;/home/xiahuixia/study/code/beforesort&quot;;
char *fileWrite = &quot;/home/xiahuixia/study/code/aftersort&quot;;
int fileRows = countFileRows(fileOpen);
printf(&quot;fileRows is %d\n&quot;, fileRows);
struct CELL *cell = malloc(sizeof(struct CELL) * fileRows);
cellSeqAndEndOfLineInitialize(cell, fileRows);
FILE *file = fopen(fileOpen, &quot;r&quot;);
cellCharInitialize(file, cell, 0, fileRows - 1, 0);
lineSort(file, cell, 0, fileRows - 1, 0);
printFileAfterSort(fileOpen, fileWrite, cell, fileRows);
}
完。 |