| [ CnUnix ] in KIDS 글 쓴 이(By): LEEIDE (jjunior) 날 짜 (Date): 2002년 4월 1일 월요일 오후 04시 07분 06초 제 목(Title): [질문] GNU Regular expression (재작성) 안녕하세요. GNU regular expression matching 함수로 프로그램을 개발하고 있습니다. 아래의 예제프로그램은 argv[1]의 패턴을 argv[2]의 파일에서 찾아 매치된 패턴을 출력해주는 테스트 프로그램입니다. 아래의 프로그램에서는 잘 돌아가는 패턴 매칭이 실제 개발하는 프로그램에 붙이면 re_compile_pattern 함수에서 프로그램 스택을 깨버리는 일이 발생합니다. re_compile_pattern이라는 함수는 GNU regular expression에서 패턴을 컴파일하는 함수이고, libc.a, libc_p.a에 각각 정의되어 있습니다. 링크시에 libc.a에서 링크가 되는것으로 추정됩니다. (단, re_match, re_compile_pattern 함수는 glibc에는 기본적으로 들어가 있지 않는데, linux 배포판에만 들어가 있는것 같습니다. 사용 시스템은 Redhat 7.1이고 gcc는 3.0.2 입니다.) 왜 독립으로는 잘 돌아가던 함수가 스택을 깨버리는지 알수가 없어서 고민중입니다. GNU 정규식 프로그래밍을 해보신 분의 도움을 급히 구합니다. 미리 감사드립니다. 좋은 하루 되십시요. #include <stdio.h> #include <sys/types.h> #include <regex.h> #include <limits.h> #include <stdlib.h> #define BUFFER_SIZE 4096 static const char *re_error_msg[] = { NULL, /* REG_NOERROR */ "No match", /* REG_NOMATCH */ "Invalid regular expression", /* REG_BADPAT */ "Invalid collation character", /* REG_ECOLLATE */ "Invalid character class name", /* REG_ECTYPE */ "Trailing backslash", /* REG_EESCAPE */ "Invalid back reference", /* REG_ESUBREG */ "Unmatched [ or [^", /* REG_EBRACK */ "Unmatched ( or \\(", /* REG_EPAREN */ "Unmatched \\{", /* REG_EBRACE */ "Invalid content of \\{\\}", /* REG_BADBR */ "Invalid range end", /* REG_ERANGE */ "Memory exhausted", /* REG_ESPACE */ "Invalid preceding regular expression", /* REG_BADRPT */ "Premature end of regular expression", /* REG_EEND */ "Regular expression too big", /* REG_ESIZE */ "Unmatched ) or \\)", /* REG_ERPAREN */ }; void print_pattern_info (pattern, pattern_buffer_ptr) const char *pattern; struct re_pattern_buffer *pattern_buffer_ptr; { printf(" Pattern: `%s'.\n", pattern); printf(" Compiled pattern: \n"); printf("\tbuffer : %s\n", pattern_buffer_ptr->buffer); printf("\tallocated : %ld\n", pattern_buffer_ptr->allocated); printf("\tused : %ld\n", pattern_buffer_ptr->used); printf("\tsyntax : ?\n"); printf("\tfastmap : %s\n", pattern_buffer_ptr->fastmap); printf("\ttranslate : %s\n", pattern_buffer_ptr->translate); printf("\tre_nsub : %d\n", pattern_buffer_ptr->re_nsub); printf("\tcan_be_null : %d\n", pattern_buffer_ptr->can_be_null); printf("\tregs_allocated : %d\n", pattern_buffer_ptr->can_be_null); printf("\tfastmap_accurate : %d\n", pattern_buffer_ptr->fastmap_accurate); printf("\tno_sub : %d\n", pattern_buffer_ptr->no_sub); printf("\tnot_bol : %d\n", pattern_buffer_ptr->not_bol); printf("\tnot_eol : %d\n", pattern_buffer_ptr->not_eol); printf("\tnewline_anchor : %d\n", pattern_buffer_ptr->newline_anchor); } void grep( const char* pattern, FILE* f ) { char buffer[BUFFER_SIZE], b2[BUFFER_SIZE]; struct re_pattern_buffer pat_buffer; struct re_registers regs; reg_syntax_t syntax; int iRet, i; const char *error; printf("pattern : %s\n", pattern); error = re_compile_pattern(pattern, strlen(pattern), &pat_buffer); if (error != NULL) { printf("error : %s\n", error); return; } print_pattern_info(pattern, &pat_buffer); // pat_buffer.no_sub = 1; // pat_buffer.not_bol = 1; // pat_buffer.not_eol = 1; pat_buffer.newline_anchor = 0; // syntax = re_set_syntax(RE_SYNTAX_EGREP); // syntax = re_set_syntax(_RE_SYNTAX_POSIX_COMMON); re_set_syntax(_RE_SYNTAX_POSIX_COMMON); // pat_buffer.syntax = syntax; while( fgets( buffer, BUFFER_SIZE, f ) != NULL ) { if (buffer[strlen(buffer)-1] == '\n') buffer[strlen(buffer)-1] = '\0'; if (strlen(buffer) == 0) continue; printf("Buffer : %s\n", buffer); iRet = re_match(&pat_buffer, buffer, strlen(buffer), 0, ®s); printf("=======================================\n"); print_pattern_info(pattern, &pat_buffer); printf("---------------------------------------\n"); switch (iRet) { case -1 : printf("\tNo match found.\n"); break; case -2 : printf("\tInternal Error occurred\n"); break; default : printf("\tTotal %d characters matched.\n", iRet); for(i=0; regs.start[i] != -1; i++) { strncpy(b2, buffer+regs.start[i], regs.end[i]-regs.start[i]); b2[regs.end[i]-regs.start[i]] = '\0'; printf("\tb2[%d] : |%s|\n", i, b2); printf("\t(%d, %d)\n", regs.start[i], regs.end[i]); } break; } printf("=======================================\n\n\n"); } regfree( &pat_buffer ); return; } int main(int argc, char *argv[]) { FILE *fp; if (argc == 3) { if ( (fp = fopen(argv[2], "r")) == NULL) { fprintf(stderr, "Error: Can't open input file(%s)\n", argv[2]); exit(0); } grep(argv[1], fp); } else { fprintf(stderr, "Usage : %s <pattern> <input file>\n", argv[0]); exit(0); } return 0; } |