CnUnix

[알림판목록 I] [알림판목록 II] [글목록][이 전][다 음]
[ 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, 
&regs);
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;
}

[알림판목록 I] [알림판목록 II] [글 목록][이 전][다 음]
키 즈 는 열 린 사 람 들 의 모 임 입 니 다.