#include <stdio.h> #include <string.h> #include <sys/types.h> #include <regex.h> #include <assert.h>
#define MAX_LINE_NUMBER 256 #define EBUFLEN 128 #define BUFLEN 1024 #define SUBSLEN 5
typedef struct _taginfo { char* func_name; // Function name char* file_name; // which file the tag is unsigned int line_num; // line number where the function is in the file
char reserverd[4]; } taginfo;
typedef struct _taglist { taginfo tag; struct _taglist *tag_next; unsigned int tag_num; } taglist;
// list head
static taglist *local_taglist;
void usage(char* program) { printf("Usage: %s filename pattren\n", program); }
/* * Function: create a list head node. * Output: a list */ taglist* create_list(void) { taglist *list; list = (taglist*)malloc(sizeof(taglist)); if(list == NULL) { printf("malloc memory failed!\n"); return NULL; }
list->tag.func_name = NULL; list->tag.file_name = NULL; list->tag_next = NULL; list->tag_num = 0;
return list; }
/* * Function: Insert a new node with taginfo to a list * Input: list -- head node pointer of the list * tag -- a new list node */ int insert_list(taginfo *tag, taglist** list) { assert(tag != NULL); assert(list != NULL); taglist *temp, *local_list; int len;
local_list = *list; temp = local_list->tag_next; local_list->tag_next = (taglist*)malloc(sizeof(taglist));
// set tag info
local_list->tag_next->tag.func_name = tag->func_name; local_list->tag_next->tag.file_name = tag->file_name; local_list->tag_next->tag.line_num = tag->line_num; local_list->tag_next->tag_next = temp; local_list->tag_next->tag_num = local_list->tag_num + 1;
local_list->tag_num++; local_list = temp = NULL; return 0; }
/* * Function: Print a list. */ void output_taglist(taglist *list) { taglist *loop; int i;
printf("Function Name\tFile Name\tLine number\n"); for(i = 0,loop = list->tag_next; i < list->tag_num; i++) { printf("%s\t", loop->tag.func_name); printf("%s\t", loop->tag.file_name); printf("%d\n", loop->tag.line_num); loop = loop->tag_next; }
loop = NULL; }
/* * Function: free memory */ int cleanup_taglist(taglist **list) { taglist *loop = *list; taglist *temp;
while(loop != NULL) { if (loop->tag.func_name != NULL) free(loop->tag.func_name); if (loop->tag.file_name != NULL) free(loop->tag.file_name); temp = loop->tag_next; loop->tag_next = NULL; free(loop); loop = temp; }
loop = NULL; return 0; }
/* * Function: Check a string whether matched certain pattern. If matched, fill * with store_tag, otherwise leave store_tag NULL. * Input: str -- a string * pattern -- regular-expression pattern * Output: store_tag -- where the matched string are stored to */ int check_matched(const char *str, taginfo *store_tag, const char* pattern) { regex_t re; int i, err, len; char errbuf[EBUFLEN]; char matched[BUFLEN]; regmatch_t subs[SUBSLEN];
assert(str != NULL); assert(store_tag != NULL);
store_tag->func_name = NULL; err = regcomp(&re, pattern, REG_EXTENDED); if(err) { len = regerror(err, &re, errbuf, sizeof(errbuf)); printf("error: regcomp: %s\n", errbuf); return 1; }
err = regexec(&re, str, (size_t)SUBSLEN, subs, 0); if (err == REG_OKAY) { len = subs[0].rm_eo - subs[0].rm_so + 1; store_tag->func_name = (char*)malloc(len * sizeof(char)); memcpy(store_tag->func_name, str+subs[0].rm_so, len); store_tag->func_name[len-1] = '\0'; }
regfree(&re);
return 0; }
/* * Function: Setup a tag list based on certain regular-expression pattern. * Input: filename -- input file name * pattern -- regular-expression pattern * Output: taglist -- a tag list */ taglist* setup_taglist(char *filename, const char* pattern) { char line[MAX_LINE_NUMBER]; unsigned int row, len; FILE *fp; taginfo tag; taglist *list = NULL;
fp = fopen(filename, "r"); if (fp == NULL) { printf("Open %s failed!\n", filename); return NULL; }
list = create_list(); if (list == NULL) { printf("Create list failed!\n"); return NULL; }
rewind(fp); row = 1; fgets(line, MAX_LINE_NUMBER, fp); while(!feof(fp)) { //printf("%d %s", row, line);
//tag = (taginfo*)malloc(sizeof(taginfo));
check_matched(line, &tag, pattern); if (tag.func_name != NULL) { // insert new taginf to taglist
tag.line_num = row; len = strlen(filename) + 1; tag.file_name = (char*) malloc(len * sizeof(char)); memcpy(tag.file_name, filename, len); tag.file_name[len-1] = '\0'; insert_list(&tag, &list); tag.file_name = NULL; tag.func_name = NULL; }
//output_taglist(list);
fgets(line, MAX_LINE_NUMBER, fp); ++row; }
fclose(fp); return list; }
int main (int argc, char** argv) { char *filename, *pattern; int result;
if(argc != 3) { usage(argv[0]); exit(1); }
filename = argv[1]; pattern = argv[2]; local_taglist = setup_taglist(filename, pattern); if (local_taglist == NULL) { printf("Setup taglist failed! Try again\n"); exit(1); }
output_taglist(local_taglist);
cleanup_taglist(&local_taglist);
return 0; }
|